pkgsubmit.php 14.7 KB
Newer Older
1
<?php
pjmattal's avatar
pjmattal committed
2

Simo Leone's avatar
Simo Leone committed
3
set_include_path(get_include_path() . PATH_SEPARATOR . '../lib' . PATH_SEPARATOR . '../lang');
4
5
6
include("config.inc");

require('Archive/Tar.php');
Simo Leone's avatar
Simo Leone committed
7
require('Find.php');
pjmattal's avatar
pjmattal committed
8

eric's avatar
eric committed
9
10
include("aur.inc");         # access AUR common functions
include("submit_po.inc");   # use some form of this for i18n support
11
include("pkgfuncs.inc");    # package functions
12

eric's avatar
eric committed
13
14
set_lang();                 # this sets up the visitor's language
check_sid();                # see if they're still logged in
15
16
17
18
19
20
21
22
23
24
25
html_header("Submit");

?>

<div class="pgbox">
  <div class="pgboxtitle">
    <span class="f3"><?php print __("Submit"); ?></span>
  </div>
  <div class="pgboxbody">

<?php
eric's avatar
eric committed
26

Callan Barrett's avatar
Callan Barrett committed
27
if ($_COOKIE["AURSID"]):
28
29
  
	# Track upload errors
eric's avatar
eric committed
30
31
32
	$error = "";

	if ($_REQUEST["pkgsubmit"]) {
33
34
	  
		# Before processing, make sure we even have a file
35
36
		if ($_FILES['pfile']['size'] == 0){
			$error = __("Error - No file uploaded");
dsa's avatar
dsa committed
37
		}
38

39
40
		# Temporary dir to put the tarball contents
		$tempdir = UPLOAD_DIR . uid_from_sid($_COOKIE['AURSID']) . time();
41

eric's avatar
eric committed
42
		if (!$error) {
43
			if (!@mkdir($tempdir)) {
44
				$error = __("Could not create incoming directory: %s.",
45
					array($tempdir));
46
			} else {
47
				if (!@chdir($tempdir)) {
48
					$error = __("Could not change directory to %s.",
49
						array($tempdir));
50
				} else {
51
				  if ($_FILES['pfile']['name'] == "PKGBUILD") {
52
				    move_uploaded_file($_FILES['pfile']['tmp_name'], $tempdir . "/PKGBUILD");
53
				  } else {
54
55
56
57
  					$tar = new Archive_Tar($_FILES['pfile']['tmp_name']);
  					$extract = $tar->extract();
  					
  					if (!$extract) {
58
59
60
  						$error = __("Unknown file format for uploaded file.");
  					}
				  }
61
62
63
				}
			}
		}
eric's avatar
eric committed
64

65
		# Find the PKGBUILD
66
		if (!$error) {
67
68
		  $pkgbuild = File_Find::search('PKGBUILD', $tempdir);
		  
Callan Barrett's avatar
Callan Barrett committed
69
		  if (count($pkgbuild)) {
70
71
72
73
74
		    $pkgbuild = $pkgbuild[0];
		    $pkg_dir = dirname($pkgbuild);
		  } else {
		    $error = __("Error trying to unpack upload - PKGBUILD does not exist.");
		  }
75
		}
jchu's avatar
jchu committed
76

77
		# if no error, get list of directory contents and process PKGBUILD
Callan Barrett's avatar
Callan Barrett committed
78
79
		# TODO: This needs to be completely rewritten to support stuff like arrays
		# and variable substitution among other things.
80
		if (!$error) {
81
			# process PKGBIULD - remove line concatenation
eric's avatar
eric committed
82
			#
83
84
			$pkgbuild = array();
			$fp = fopen($pkg_dir."/PKGBUILD", "r");
85
86
87
88
			$line_no = 0;
			$lines = array();
			$continuation_line = 0;
			$current_line = "";
89
			while (!feof($fp)) {
90
				$line = trim(fgets($fp));
91
				$char_counts = count_chars($line, 0);
92
93
94
95
96
				if (substr($line, strlen($line)-1) == "\\") {
					# continue appending onto existing line_no
					#
					$current_line .= substr($line, 0, strlen($line)-1);
					$continuation_line = 1;
97
98
				} elseif ($char_counts[ord('(')] > $char_counts[ord(')')]) {
					# assumed continuation
99
100
101
102
					# continue appending onto existing line_no
					#
					$current_line .= $line . " ";
					$continuation_line = 1;
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
				} else {
					# maybe the last line in a continuation, or a standalone line?
					#
					if ($continuation_line) {
						# append onto existing line_no
						#
						$current_line .= $line;
						$lines[$line_no] = $current_line;
						$current_line = "";
					} else {
						# it's own line_no
						#
						$lines[$line_no] = $line;
					}
					$continuation_line = 0;
					$line_no++;
				}
			}
			fclose($fp);

123
124
125
126
			# Now process the lines and put any var=val lines into the
			# 'pkgbuild' array.	Also check to make sure it has the build()
			# function.
			#
127
128
			$seen_build_function = 0;
			while (list($k, $line) = each($lines)) {
jchu's avatar
jchu committed
129
				$lparts = explode("=", $line, 2);
130
				if (count($lparts) == 2) {
131
					# this is a variable/value pair, strip out
132
					# array parens and any quoting, except in pkgdesc
133
					# for pkgdesc, only remove start/end pairs of " or '
134
					if ($lparts[0]=="pkgdesc") {
135
136
137
138
139
140
141
142
143
144
145
						if ($lparts[1]{0} == '"' && 
								$lparts[1]{strlen($lparts[1])-1} == '"') {
							$pkgbuild[$lparts[0]] = substr($lparts[1], 1, -1);
						}
					 	elseif 
							($lparts[1]{0} == "'" && 
							 $lparts[1]{strlen($lparts[1])-1} == "'") {
							$pkgbuild[$lparts[0]] = substr($lparts[1], 1, -1);
						} else { 
							$pkgbuild[$lparts[0]] = $lparts[1];
					 	}
146
147
148
149
					} else {
						$pkgbuild[$lparts[0]] = str_replace(array("(",")","\"","'"), "",
								$lparts[1]);
					}
150
				} else {
151
					# either a comment, blank line, continued line, or build function
152
153
					#
					if (substr($lparts[0], 0, 5) == "build") {
154
						$seen_build_function = 1;
155
156
157
					}
				}
			}
eric's avatar
eric committed
158

159
			# some error checking on PKGBUILD contents - just make sure each
160
			# variable has a value.	This does not do any validity checking
161
			# on the values, or attempts to fix line continuation/wrapping.
eric's avatar
eric committed
162
			#
163
			if (!$seen_build_function) {
164
165
				$error = __("Missing build function in PKGBUILD.");
			}
Callan Barrett's avatar
Callan Barrett committed
166
167
168
169
170
171
172
			
			$req_vars = array("md5sums", "source", "url", "pkgdesc", "license", "pkgrel", "pkgver", "arch", "pkgname");
			foreach ($req_vars as $var) {
  			if (!array_key_exists($var, $pkgbuild)) {
  				$error = __("Missing " . $var . " variable in PKGBUILD.");
  			}
		  }
173
174
175
176
177
178
		}

		# TODO This is where other additional error checking can be
		# performed.	Examples: #md5sums == #sources?, md5sums of any
		# included files match?, install scriptlet file exists?
		#
179
180
181
		
		# Check for http:// or other protocol in url
		# 
182
		if (!$error) {
183
184
185
186
			$parsed_url = parse_url($pkgbuild['url']);
			if (!$parsed_url['scheme']) {
				$error = __("Package URL is missing a protocol (ie. http:// ,ftp://)");
			}
187
188
		}
			
189
190
191
		# Now, run through the pkgbuild array and do any $pkgname/$pkgver
		# substituions.
		#
Callan Barrett's avatar
Callan Barrett committed
192
		# TODO: run through and do ALL substitutions, to cover custom vars
193
194
195
196
197
		if (!$error) {
			$pkgname_var = $pkgbuild["pkgname"];
			$pkgver_var = $pkgbuild["pkgver"];
			$new_pkgbuild = array();
			while (list($k, $v) = each($pkgbuild)) {
198
199
200
201
				$v = str_replace('$pkgname', $pkgname_var, $v);
				$v = str_replace('${pkgname}', $pkgname_var, $v);
				$v = str_replace('$pkgver', $pkgver_var, $v);
				$v = str_replace('${pkgver}', $pkgver_var, $v);
202
203
204
				$new_pkgbuild[$k] = $v;
			}
		}
205

Callan Barrett's avatar
Callan Barrett committed
206
		# Now we've parsed the pkgbuild, let's move it to where it belongs
207
208
209
		if (!$error) {
			$pkg_name = str_replace("'", "", $pkgbuild['pkgname']);
			$pkg_name = escapeshellarg($pkg_name);
Callan Barrett's avatar
Callan Barrett committed
210
			$pkg_name = str_replace("'", "", $pkg_name);
211
212
213
            
			$presult = preg_match("/^[a-z0-9][a-z0-9\.+_-]*$/", $pkg_name);
			
Callan Barrett's avatar
Callan Barrett committed
214
			if (!$presult) {
215
216
217
218
219
				$error = __("Invalid name: only lowercase letters are allowed.");
			}
		}

		if (!$error) {
Callan Barrett's avatar
Callan Barrett committed
220
			# First, see if this package already exists, and if it can be overwritten
221
222
223
			$pkg_exists = package_exists($pkg_name);
			if (can_submit_pkg($pkg_name, $_COOKIE["AURSID"])) {
				if (file_exists(INCOMING_DIR . $pkg_name)) {
Callan Barrett's avatar
Callan Barrett committed
224
					# Blow away the existing file/dir and contents
225
226
227
					rm_rf(INCOMING_DIR . $pkg_name);
				}

Callan Barrett's avatar
Callan Barrett committed
228
229
230
231
				if (!@mkdir(INCOMING_DIR . $pkg_name)) {
					$error = __( "Could not create directory %s."
						         , INCOMING_DIR . $pkg_name
						         );
232
233
				}

234
        rename($pkg_dir, INCOMING_DIR . $pkg_name . "/" . $pkg_name);
235
			} else {
Callan Barrett's avatar
Callan Barrett committed
236
237
238
239
240
				$error = __( "You are not allowed to overwrite the %h%s%h package."
					         , "<b>"
					         , $pkg_name
					         , "</b>"
					         );
241
242
243
			}
		}

244
245
		# Re-tar the package for consistency's sake
		if (!$error) {
Callan Barrett's avatar
Callan Barrett committed
246
			if (!@chdir(INCOMING_DIR . $pkg_name)) {
247
				$error = __("Could not change directory to %s.",
Callan Barrett's avatar
Callan Barrett committed
248
					array(INCOMING_DIR . $pkg_name));
249
250
			}
		}
251
		
252
		if (!$error) {
253
254
255
256
		  $tar = new Archive_Tar($pkg_name . '.tar.gz');
		  $create = $tar->create(array($pkg_name));
		  
			if (!$create) {
257
258
259
				$error = __("Could not re-tar");
			}
		}
260
		
Callan Barrett's avatar
Callan Barrett committed
261
		# Whether it failed or not we can clean this out
262
263
		if (file_exists($tempdir)) {
			rm_rf($tempdir);
264
265
		}

Callan Barrett's avatar
Callan Barrett committed
266
		# Update the backend database
267
		if (!$error) {
Callan Barrett's avatar
Callan Barrett committed
268
		  
269
			$dbh = db_connect();
Callan Barrett's avatar
Callan Barrett committed
270
271
			
			# This is an overwrite of an existing package, the database ID
272
			# needs to be preserved so that any votes are retained.	However,
Callan Barrett's avatar
Callan Barrett committed
273
274
275
			# PackageDepends and PackageSources can be purged.
			
			$q = "SELECT * FROM Packages WHERE Name = '" . mysql_real_escape_string($new_pkgbuild['pkgname']) . "'";
276
277
278
279
280
			$result = db_query($q, $dbh);
			$pdata = mysql_fetch_assoc($result);

			if ($pdata) {

Callan Barrett's avatar
Callan Barrett committed
281
282
				# Flush out old data that will be replaced with new data
				$q = "DELETE FROM PackageDepends WHERE PackageID = " . $pdata["ID"];
283
				db_query($q, $dbh);
Callan Barrett's avatar
Callan Barrett committed
284
				$q = "DELETE FROM PackageSources WHERE PackageID = " . $pdata["ID"];
285
				db_query($q, $dbh);
286

Callan Barrett's avatar
Callan Barrett committed
287
288
289
290
291
292
293
294
295
				# If the package was a dummy, undummy it
				if ($pdata['DummyPkg']) {
				  $q = sprintf( "UPDATE Packages SET DummyPkg = 0, SubmitterUID = %d, MaintainerUID = %d, SubmittedTS = UNIX_TIMESTAMP() WHERE ID = %d"
				              , uid_from_sid($_COOKIE["AURSID"])
				              , uid_from_sid($_COOKIE["AURSID"])
				              , $pdata["ID"]
				              );

          db_query($q, $dbh);
296
				}
Callan Barrett's avatar
Callan Barrett committed
297
298
				
				# If a new category was chosen, change it to that
299
				if ($_POST['category'] > 1) {
Callan Barrett's avatar
Callan Barrett committed
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
				  $q = sprintf( "UPDATE Packages SET CategoryID = %d WHERE ID = %d"
				              , mysql_real_escape_string($_REQUEST['category'])
				              , $pdata["ID"]
				              );
				  
				  db_query($q, $dbh);
			  }
				
				# Update package data
				$q = sprintf( "UPDATE Packages SET ModifiedTS = UNIX_TIMESTAMP(), Name = '%s', Version = '%s-%s', License = '%s', Description = '%s', URL = '%s', LocationID = 2, FSPath = '%s', URLPath = '%s', OutOfDate = 0 WHERE ID = %d"
				            , mysql_real_escape_string($new_pkgbuild['pkgname'])
				            , mysql_real_escape_string($new_pkgbuild['pkgver'])
				            , mysql_real_escape_string($new_pkgbuild['pkgrel'])
				            , mysql_real_escape_string($new_pkgbuild['license'])
				            , mysql_real_escape_string($new_pkgbuild['pkgdesc'])
				            , mysql_real_escape_string($new_pkgbuild['url'])
				            , mysql_real_escape_string(INCOMING_DIR . $pkg_name . "/" . $pkg_name . ".tar.gz")
				            , mysql_real_escape_string(URL_DIR . $pkg_name . "/" . $pkg_name . ".tar.gz")
				            , $pdata["ID"]
				            );
				
				db_query($q, $dbh);
322

Callan Barrett's avatar
Callan Barrett committed
323
				# Update package depends
324
				$depends = explode(" ", $new_pkgbuild['depends']);
Callan Barrett's avatar
Callan Barrett committed
325
        foreach ($depends as $dep) {
326
					$q = "INSERT INTO PackageDepends (PackageID, DepPkgID, DepCondition) VALUES (";
Callan Barrett's avatar
Callan Barrett committed
327
328
					$deppkgname = preg_replace("/[<>]?=.*/", "", $dep);
          $depcondition = str_replace($deppkgname, "", $dep);
pjmattal's avatar
pjmattal committed
329
                    
Callan Barrett's avatar
Callan Barrett committed
330
          if ($deppkgname == "#") { break; }
pjmattal's avatar
pjmattal committed
331
                    
jchu's avatar
jchu committed
332
					$deppkgid = create_dummy($deppkgname, $_COOKIE['AURSID']);
Callan Barrett's avatar
Callan Barrett committed
333
          $q .= $pdata["ID"] . ", " . $deppkgid . ", '" . mysql_real_escape_string($depcondition) . "')";
jchu's avatar
jchu committed
334

Callan Barrett's avatar
Callan Barrett committed
335
        	db_query($q, $dbh);
336
				}
Callan Barrett's avatar
Callan Barrett committed
337
338
339
340
341
342
343
344
345

				# Insert sources
				$sources = explode(" ", $new_pkgbuild['source']);
				foreach ($sources as $src) {
					$q = "INSERT INTO PackageSources (PackageID, Source) VALUES (";
					$q .= $pdata["ID"] . ", '" . mysql_real_escape_string($src) . "')";
					db_query($q, $dbh);
			  }
			  
346
			} else {
Callan Barrett's avatar
Callan Barrett committed
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
			  
				# This is a brand new package
				$q = sprintf( "INSERT INTO Packages (Name, License, Version, CategoryID, Description, URL, LocationID, SubmittedTS, SubmitterUID, MaintainerUID, FSPath, URLPath) VALUES ('%s', '%s', '%s-%s', %d, '%s', '%s', 2, UNIX_TIMESTAMP(), %d, %d, '%s', '%s')"
				            , mysql_real_escape_string($new_pkgbuild['pkgname'])
				            , mysql_real_escape_string($new_pkgbuild['license'])
				            , mysql_real_escape_string($new_pkgbuild['pkgver'])
				            , mysql_real_escape_string($new_pkgbuild['pkgrel'])
				            , mysql_real_escape_string($_REQUEST['category'])
				            , mysql_real_escape_string($new_pkgbuild['pkgdesc'])
				            , mysql_real_escape_string($new_pkgbuild['url'])
				            , uid_from_sid($_COOKIE["AURSID"])
				            , uid_from_sid($_COOKIE["AURSID"])
				            , mysql_real_escape_string(INCOMING_DIR . $pkg_name . "/" . $pkg_name . ".tar.gz")
				            , mysql_real_escape_string(URL_DIR . $pkg_name . "/" . $pkg_name . ".tar.gz")
				            );
jchu's avatar
jchu committed
362

Callan Barrett's avatar
Callan Barrett committed
363
				$result = db_query($q, $dbh);
jchu's avatar
jchu committed
364
365
				$packageID = mysql_insert_id($dbh);

Callan Barrett's avatar
Callan Barrett committed
366
				# Update package depends
367
				$depends = explode(" ", $new_pkgbuild['depends']);
Callan Barrett's avatar
Callan Barrett committed
368
				foreach ($depends as $dep) {
Callan Barrett's avatar
Callan Barrett committed
369
					$q = "INSERT INTO PackageDepends (PackageID, DepPkgID, DepCondition) VALUES (";
Callan Barrett's avatar
Callan Barrett committed
370
371
					$deppkgname = preg_replace("/[<>]?=.*/", "", $dep);
					$depcondition = str_replace($deppkgname, "", $dep);
pjmattal's avatar
pjmattal committed
372
                    
Callan Barrett's avatar
Callan Barrett committed
373
374
375
          if ($deppkgname == "#") { break; }
          
          $deppkgid = create_dummy($deppkgname, $_COOKIE['AURSID']);
Callan Barrett's avatar
Callan Barrett committed
376
377
          $q .= $packageID . ", " . $deppkgid . ", '" . mysql_real_escape_string($depcondition) . "')";
        
jchu's avatar
jchu committed
378
					db_query($q, $dbh);
379
				}
jchu's avatar
jchu committed
380

Callan Barrett's avatar
Callan Barrett committed
381
382
383
384
385
386
387
388
				# Insert sources
				$sources = explode(" ", $new_pkgbuild['source']);
				foreach ($sources as $src) {
					$q = "INSERT INTO PackageSources (PackageID, Source) VALUES (";
					$q .= $packageID . ", '" . mysql_real_escape_string($src) . "')";
					db_query($q, $dbh);
			  }
			  
389
390
			}
		}
391
392

		chdir($_SERVER['DOCUMENT_ROOT']);
eric's avatar
eric committed
393
394
395
	}


Callan Barrett's avatar
Callan Barrett committed
396
	if (!$_REQUEST["pkgsubmit"] || $error):
397
		# User is not uploading, or there were errors uploading - then
eric's avatar
eric committed
398
		# give the visitor the default upload form
Callan Barrett's avatar
Callan Barrett committed
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
		if (ini_get("file_uploads")):
			if ($error):
?>

<span class='error'><?php print $error; ?></span><br />
<br />

<?php
			endif;
			if ($warning):
?>

<br><span class='error'><?php print $warning; ?></span><br />
<br />

<?php
			endif;
dsa's avatar
dsa committed
416
            
417
418
			$pkg_categories = pkgCategories();
			$pkg_locations = pkgLocations();
419
?>
420

421
422
423
424
425
426
427
428
429
<form action='/pkgsubmit.php' method='post' enctype='multipart/form-data'>
	<input type='hidden' name='pkgsubmit' value='1' />
	<table border='0' cellspacing='5'>
		<tr>
			<td span='f4' align='right'><?php print __("Package Category"); ?>:</td>
			<td span='f4' align='left'>
			<select name='category'>
				<option value='1'><?php print __("Select Category"); ?></option>
				<?php
Callan Barrett's avatar
Callan Barrett committed
430
431
432
					foreach ($pkg_categories as $num => $cat):
						print "<option value='" . $num . "'";
						if (isset($_POST['category']) && $_POST['category'] == $cat):
433
							print " selected='selected'";
Callan Barrett's avatar
Callan Barrett committed
434
435
436
						endif;
						print ">" . $cat . "</option>";
					endforeach;
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
				?>
			</select>
			</td>
		</tr>
		<tr>
			<td span='f4' align='right'><?php print __("Upload package file"); ?>:</td>
			<td span='f4' align='left'>
				<input type='file' name='pfile' size='30' />
			</td>
		</tr>
		<tr>
			<td align='left'>
				<input class='button' type='submit' value='<?php print __("Upload"); ?>' />
			</td>
		</tr>
	</table>
</form>

<?php
Callan Barrett's avatar
Callan Barrett committed
456
		else:
eric's avatar
eric committed
457
			print __("Sorry, uploads are not permitted by this server.");
Callan Barrett's avatar
Callan Barrett committed
458
459
460
461
462
463
464
?>

<br />

<?php
		endif;
	else:
465
		print __("Package upload successful.");
eric's avatar
eric committed
466

Callan Barrett's avatar
Callan Barrett committed
467
468
469
470
471
472
473
474
475
476
477
    if ($warning):
?>

<span class='warning'><?php print $warning; ?></span><br />
<br />

<?php
    endif;
	endif;
else:
	# Visitor is not logged in
eric's avatar
eric committed
478
	print __("You must create an account before you can upload packages.");
Callan Barrett's avatar
Callan Barrett committed
479
?>
480

Callan Barrett's avatar
Callan Barrett committed
481
482
483
484
<br />
	
<?php
endif;
485
486
487
488
489
490
?>

  </div>
</div>

<?php
tardo's avatar
tardo committed
491
html_footer(AUR_VERSION);
492

eric's avatar
eric committed
493
?>