added a apt repo updater... that doesnt work
[glcas.git] / plugins / repo.php
1 <?php
2 $URL_HANDLERS["*"] = "GLCASRepo";
3 global $CRON_CLASSES;
4 $CRON_CLASSES["GLCASRepo"] = "GLCASRepo";
5
6 class GLCASRepo {
7         function __construct($config)
8         {
9                 $this->config = $config;
10                 if($this->config->getConfigVar("storagelocation") == false) {
11                         global $WEB_ROOT_FS;
12                         $storloc = "$WEB_ROOT_FS/../var/glcas/cache/";
13                         if(!file_exists($storloc)) mkdir($storloc);
14                         $this->config->setConfigVar("storagelocation", realpath($storloc));
15                         $this->config->saveConfig();
16                         error_log("set storage location, $storloc");
17                 }
18         }
19         
20         function cron()
21         {
22                 //echo "<pre>";
23                 $uconf = unserialize($this->config->getConfigVar("repodata"));
24                 $repostore = $this->config->getConfigVar("storagelocation");
25                 //print_r($uconf);
26                 //echo "</pre>";
27                 
28                 foreach($uconf as $rkey => $repo) {
29                         echo "Repo $rkey: ".$repo["desc"]."<br>";
30                         if(!isset($repo["expiretime"])) {
31                                 echo " - Expire time not set, setting to 2 days by default<br>";
32                                 $uconf[$rkey]["expiretime"] = 2;
33                                 $repo["expiretime"] = 2;
34                                 $this->config->setConfigVar("repodata", serialize($uconf));
35                                 $this->config->saveConfig();                            
36                         }
37                         
38                         if(!isset($repo["repotype"])) {
39                                 echo "<font color=\"red\">Repo type not set for repo, setting to yum</font><br>";
40                                 $uconf[$rkey]["repotype"] = "YUM";
41                                 $this->config->setConfigVar("repodata", serialize($uconf));
42                                 $this->config->saveConfig();                            
43                         } else if($repo["repotype"] == "YUM") {
44                                 if(file_exists("$repostore/$rkey/repodata/repoupdate.lock")) {
45                                         echo " - <font color=\"red\">Repo locked for update</font><br>";
46                                         
47                                 }
48                                 
49                                 // we still do this next bit, even if its locked because it may be a stray file
50                                 echo " - Expire time is ".$repo["expiretime"]." days, checking repo<br>";
51                                 error_log("checking $repostore/$rkey/repodata/repomd.xml");
52                                 $tdiff = time() - filemtime("$repostore/$rkey/repodata/repomd.xml");
53                                 $maxtdiff = $repo["expiretime"] * 24 * 3600;
54                                 if($tdiff > $maxtdiff) {
55                                         echo " - <font color=\"green\">updating repo</font><br>";
56                                         $this->updateRepo($rkey);
57                                 } else {
58                                         echo " - not updating repo<br>";
59                                 }
60                         } else if($repo["repotype"] == "APT") {
61                                 if(file_exists("$repostore/$rkey/update.lock")) {
62                                         echo " - <font color=\"red\">Repo locaked for update</font><br>";
63                                 }
64                                 echo " - Expire time is ".$repo["expiretime"]." days, checking repo<br>";
65                                 $maxtdiff = $repo["expiretime"] * 24 * 3600;
66                                 $this->updateRepo($rkey);
67                         }
68                 }
69         }
70
71         function go($url)
72         {
73                 error_log("repo:go called");
74
75                 // figure out what we're doing
76                 switch($url) {
77                         case "list":
78                                 GLCASpageBuilder($this, "body");
79                                 break;
80                         default:
81                                 $this->getRepoForUrl($url);
82                 }
83         }
84
85         function body($url)
86         {
87                 // this is how this will work
88                 //$this->decodeUrl();
89                 if(strncasecmp("list", $url, 4)==0) {
90                         echo "i am the repo list";
91                         return;
92                 }
93                 echo "i am the repo, $url";
94         }
95
96
97         // TODO: rework this function
98         /*
99         * What i need to do is have a downloader function
100         * that can cope with lots of different shit
101         * but thats a pipe dream
102         *
103         * what *THIS* function needs to do is
104         * 1) figure out the repo
105         * 2) figure out the file in the repo
106         * 2.1) if its a directory, go to print directory
107         * 3) if the file exists, give it to the user (if a range is specified give the user the range)
108         * 4) if the file does not exist
109         *    - check if a tmp file exists
110         *    - attempt to get an exclusive flock
111         *    - if flock fails, donwload in progress
112         *    - if flock succeeds, truncate file and re-start download
113         *    - if a range request was made, send the range once available
114         *    - if range not available, sleep for 5 and check again.
115         *
116         * I dont want to code this from scratch, but i probably need to
117         */
118         function getRepoForUrl($url)
119         {
120                 $xurl = split("[/,]", $url);
121
122                 // first get the config
123                 $uconf = unserialize($this->config->getConfigVar("repodata"));
124                 $repostore = $this->config->getConfigVar("storagelocation");
125
126                 // preset matched to -1
127                 $matched = -1;
128
129                 // first we check for /repo/repoid as a url
130                 $startat = 0;
131                 if($xurl[0] == "repo") {
132                         $repid = $xurl[1];
133                         error_log("trying to get repo for repoid, $repid");
134                         if(isset($uconf[$repid])) {
135                                 $matched = ((int)($repid));
136                                 error_log("set matched, $matched, $repid");
137                                 $startat +=2;
138                         }
139                 }
140
141                 // now check for a prefix match
142                 $prematch = false;
143                 if($matched < 0) foreach($uconf as $key => $var) {
144                         $pre = $var["prefix"];
145                                 
146                         if($pre!="") {
147                                 //echo "Checking pre $pre against ".$xurl[0]."\n";
148                                 if(strcasecmp($pre, $xurl[0])==0) {
149                                         //echo "Matched pre\n";
150                                         $prematch = true;
151                                         $startat++;
152                                 }
153                         }
154                 }
155
156                 // next, check for a short url match
157                 if($matched < 0) foreach($uconf as $key => $var) {
158                         // if we matched a pre, then we check against the second url component
159                                 
160                         $short = $var["shorturl"];
161                                 
162                         if($short!="") {
163                                 //echo "Checking short $short against ".$xurl[$startat]."\n";
164                                 if(strcasecmp($xurl[$startat], $short)==0) {
165                                         //echo "Matched\n";
166                                         $matched = $key;
167                                         $startat++;
168                                 }
169                         }
170                 }
171
172                 // TODO: this deterministic bit
173                 // so far nothing has matched - what this next bit needs to do is try and "Determine" a repo from url
174                 // for eg, if a user gets /fedora/x86_64/os we need to return something appropriate
175                 if($matched < 0) {
176                         echo "No such repo<br>";
177                         header("HTTP/1.0 404 Not Found");
178                         return;
179                 }
180                 
181
182
183                 // something was matched, so now we reconstruct the file component of the url
184                 $file = "/";
185                 if(count($xurl) > $startat) for($i=$startat; $i < count($xurl); $i++) {
186                         $file .= "/".$xurl[$i];
187                 }
188
189                 // so, the ultimate url for the file we need is:
190                 $actualfile = "$repostore/$matched/$file";
191                 error_log("Atcualfile is $actualfile");
192                 
193                 // now check for a block in that repo
194                 if(isset($uconf[$matched]["blocklist"])) {
195                         foreach($uconf[$matched]["blocklist"] as $blockers) {
196                                 $rfile = ltrim($file, "/");
197                                 error_log("checking $blockers against $rfile");
198                                 if(preg_match("/$blockers/", $rfile) > 0) {
199                                         error_log("should block");
200                                         header("HTTP/1.0 404 Not Found");
201                                         return;
202                                 }
203                         }
204                 }
205                 
206                 // if its a directory, lets do a print
207                 if(is_dir($actualfile)) {
208                         $this->printDir($actualfile, $file, $url);
209                         return;
210                 }
211
212                 // check if the file exists and serve it up
213                 if(file_exists($actualfile) && !file_exists("$actualfile.size")) {
214                         $this->serveUpFile($actualfile, $matched);
215                         return;
216                 } else {
217                         // the file does not exist, we now need to go into "download" mode
218                         $remoteurl = $uconf[$matched]["url"]."/$file";
219                         $this->downloadAndServe($actualfile, $matched, $remoteurl);
220                         return;
221                 }
222         }
223
224         function serveUpFile($actualfile, $repoid)
225         {
226                 $uconf = unserialize($this->config->getConfigVar("repodata"));
227                 $repostore = $this->config->getConfigVar("storagelocation");
228
229                 // figure out the range header garbage that centos/redhat send
230                 if(isset($_SERVER["HTTP_RANGE"])) {
231                         // we're using ranges - screw you stupid installer
232                         $pr_range = preg_split("/[:\-=, ]+/", $_SERVER["HTTP_RANGE"]);
233                                 
234                         // cut up ranges
235                         $rangestart = $pr_range[1];
236                         $rangelength = $pr_range[2] - $pr_range[1] +1;
237                         $rangestr = $pr_range[1]."-".$pr_range[2];
238                         error_log("going ranges at $rangestart, $rangelength,".$rangesa[1].",".$rangesb[0]);
239                                 
240                         // now spit some headers
241                         header("HTTP/1.1 206 Partial Content");
242                         header("Content-Length: ".$rangelength);
243                                 
244
245                         header("Content-Range: bytes $rangestr/".filesize($actualfile));
246                                 
247                         // determine mime type
248                         $type = mime_content_type($actualfile);
249                                 
250                         // set mime type header
251                         header("Content-type: $type");
252                                 
253                         // open the local file (TODO: error check)
254                         $localfile = fopen($actualfile, "r");
255                         fseek($localfile, $rangestart, SEEK_SET);
256                                 
257                         // read in the data, god i hope its not big
258                         $data = fread($localfile, $rangelength);
259                                 
260                         // lastly, send data
261                         echo $data;
262                         flush();
263                                 
264                         // and close the file
265                         fclose($localfile);
266                         return;
267                 } else {
268
269                         // we're not using range's - good on you installer thingy
270                         header("Content-Length: ".filesize($actualfile));
271
272                         // set the mime type header
273                         $type = mime_content_type($actualfile);
274                         header("Content-type: $type");
275                                 
276                         // open the local file
277                         $localfile = fopen($actualfile, "r");
278                         if(!$localfile) {
279                                 error_log("normal upload went barf");
280                                 return;
281                         }
282                                 
283                         // iterate over its length, send 8k at a time
284                         while(!feof($localfile)) {
285                                 // read and send data
286                                 $data = fread($localfile, 32768);
287                                 echo $data;
288
289                                 // flush so the client sees the data
290                                 flush();
291                         }
292                                 
293                         // close the file
294                         fclose($localfile);
295                         return;
296                 }
297         }
298
299         // TODO: this is the function im working on
300         // the alternative to this function is that if a file is in the process of being
301         // downloaded, we simply serve from upstream... not a good idea tho unless we create
302         // a local proxy right here - this function is a race condition waiting to be had
303         // lets hope its a good one!
304         function downloadAndServe($filename, $repoid, $remoteurl)
305         {
306
307                 $this->startDownload($filename, $remoteurl);
308
309                 // give the proc a minute to get going
310                 sleep(2);
311                 clearstatcache();
312
313                 // get the configurations we need
314                 $uconf = unserialize($this->config->getConfigVar("repodata"));
315                 $repostore = $this->config->getConfigVar("storagelocation");
316
317
318
319                 // determine if we're ranged
320                 $ranged = false;
321                 $rangestart = 0;
322                 $rangelength = 0;
323                 $rangestr="";
324                 if(isset($_SERVER["HTTP_RANGE"])) {
325                         // we're using ranges - screw you stupid installer
326                                 
327                         $pr_range = preg_split("/[:\-=, ]+/", $_SERVER["HTTP_RANGE"]);
328                         error_log("got range ".$_SERVER["HTTP_RANGE"]." and ".print_r($pr_range, true));
329                                 
330                         // cut up ranges
331                         $rangestart = $pr_range[1];
332                         $rangelength = $pr_range[2] - $pr_range[1] +1;
333                         $rangestr = $pr_range[1]."-".$pr_range[2];
334                         error_log("going ranges at $rangestart, $rangelength, $rangestr");
335                         $ranged = true;
336                 }
337
338                 // open the local files
339
340                 // now, lets determine what state we're in
341                 // we're either - getting and sending
342                 // watching and sending
343                 // or a range (Getting and sending)
344                 // or a range (watching and sending)
345                 // TODO: it may be advicable to start the download as a seperate cli process rather then something goin on here
346                 // so it definitely cant be interrupted.
347                 
348                 // check for a 404 file and wait 2 if it exists - i should really check the timestamp for an updated
349                 // file, but thats too much effort for now: TODO: check timestamp on 404 file
350                 $slept = 0;
351                 while(!file_exists("$filename")) {
352                         clearstatcache();
353                         sleep(1);
354                         $slept += 1;
355                         error_log("Sleeping waiting for file");
356                         
357                         // if 404 file exists, we wait much less time
358                         if(file_exists("$filename.404") && $slept > 2) {
359                                 header("HTTP/1.0 404 Not Found");
360                                 return;
361                         }
362                         if($slept > 10) {
363                                 header("HTTP/1.0 404 Not Found");
364                                 return;
365                         } 
366                 }
367                 
368                 clearstatcache();
369                 if(is_dir($filename)) {
370                         
371                         header("Location: ".$_SERVER["REQUEST_URI"]."/");
372                         return;
373                 }
374                         
375
376                 // first, getting and sending - this is easy.
377                 if (!$ranged) {
378                                 
379                         $localfile = fopen($filename, "r");
380                                 
381                         // this is where the fun starts - but this one isnt too bad.
382                         error_log("OTHERDOWNLOAD: im another downloader, please work");
383                         if(file_exists("$filename.size")) $fsize = file_get_contents("$filename.size");
384                         else $fsize = filesize($filename);
385                         header("Content-Length: $fsize");
386                         $sgotten = 0;
387                         while(!feof($localfile)) {
388                                 $data = fread($localfile, 2048);
389                                 if(!$data) {
390                                         error_log("dollardata is pair shaped");
391                                 } else {
392                                         $sgotten += strlen($data);
393                                         if($sgotten > $fsize) {
394                                                 error_log("went plop at sgotten, $sgotten, $fsize");
395                                                 return;
396                                         }
397                                         echo $data;
398                                         flush();
399                                 }
400                         }
401                         fclose($localfile);
402                                 
403                         // need to think about this in pseudo code.
404                         // 1. close the file and wait for it to get to $sgotten + 2048 or $fsize
405                         $cursize = filesize($filename);                         
406                                 
407                         $upload_finished = false;
408                         while(!$upload_finished) {
409                                 while($cursize < $fsize && $cursize < ($sgotten+2048)) {
410                                         clearstatcache();
411                                         error_log("OTHERDOWNLOAD: halt, $cursize, $sgotten, $fsize");
412                                         // sleep until the the filesize is greater then what we're up to, or until the file is finished
413                                         sleep(1);
414                                         $cursize = filesize($filename);
415                                 }
416
417                                 error_log("OTHERDOWNLOAD: continue, $sgotten, $fsize");
418                                 // reopen local file - if it stopped existing, we need to deal with that
419                                 $localfile = fopen($filename, "r");
420
421                                 // UG, we need to ff, how could i forget that
422                                 fseek($localfile, $sgotten);
423
424                                 if(!$localfile) {
425                                         error_log("OTHERDOWNLOAD: something went plop");
426                                         return;
427                                 }
428
429                                 // now loop on the file until we have it at an eof
430                                 while(!feof($localfile)) {
431                                         $data = fread($localfile, 512);
432                                         if(!$data) {
433                                                 error_log("OTHERDOWNLOAD: dollar data went plop");
434                                         } else {
435                                                 $sgotten += strlen($data);
436                                                 echo $data;
437                                                 flush();
438                                         }
439                                 }
440                                 fclose($localfile);
441
442                                 if($sgotten >= $fsize) {
443                                         if($sgotten > $fsize) error_log("OTHERDOWNLOADER: finished but $sgotten, $fsize doesnt make senze");
444                                         $upload_finished = true;
445                                 }
446                                 // and we're done
447
448                         }
449                         error_log("OTHERDOWNLOADER: done with");
450                                 
451                         return;
452
453
454                                 
455                                 
456                         // Next painful bit
457                 } else {
458                         // and here too, yay, someone else is doing the
459                         // download, but we're the retards getting a range
460                         $sgotten = 0;
461                                 
462                         $sgatlen = $rangestart+$rangelength;
463                                 
464                         // the problem is here
465                         error_log("Downloader: going ranged as other");
466                         clearstatcache();
467                         if(file_exists($filename.".tmp.data.deleteme.size")) $contentlen = file_get_contents($filename.".tmp.data.deleteme.size");
468                         else $contentlen = filesize($filename);
469                         $contenttype = mime_content_type($filename);
470                         header("HTTP/1.1 206 Partial Content");
471                         header("Content-Length: $rangelength");
472                         header("Content-Range: bytes $rangestr/$contentlen");
473                         $contenttype = "Content-Type: application/x-rpm";
474                         
475                         error_log("$contenttype");
476                         header("$contenttype");
477                         
478                         
479                         clearstatcache();
480                                 
481                                 
482                         // first we wait until the file reaches $rangestart
483                         while(filesize("$filename") < $rangestart) {
484                                 sleep(1);
485                         }
486                                 
487                         // then we open the file and ff to rangestart
488                         $localfile = fopen($filename, "r");
489                         fseek($localfile, $rangestart);
490                                 
491                         $sgotten = 0;
492                         // need to think about this in pseudo code.
493                         // 1. close the file and wait for it to get to $sgotten + 2048 or $fsize
494                         $cursize = filesize($filename);
495                                 
496                                 
497                         $upload_finished = false;
498                         while(!$upload_finished) {
499                                 while($cursize < $sgatlen && $cursize < ($sgotten+2048)) {
500                                         clearstatcache();
501                                         error_log("OTHERDOWNLOAD: halt, $cursize, $sgotten, $contentlen");
502                                         // sleep until the the filesize is greater then what we're up to, or until the file is finished
503                                         sleep(1);
504                                         $cursize = filesize($filename);
505                                 }
506
507                                 error_log("OTHERDOWNLOAD: continue, $sgotten, $contentlen");
508                                 // reopen local file - if it stopped existing, we need to deal with that
509                                 $localfile = fopen($filename, "r");
510
511                                 // UG, we need to ff, how could i forget that
512                                 fseek($localfile, $sgotten+$rangestart);
513
514                                 if(!$localfile) {
515                                         error_log("OTHERDOWNLOAD: something went plop");
516                                         return;
517                                 }
518
519                                 // now loop on the file until we have it at sgatlen
520                                 while(!feof($localfile) && $sgotten < $rangelength) {
521                                         $left = $rangelength - $sgotten;
522                                         if($left > 512) $lenget = 512;
523                                         else $lenget = $left;
524                                         $data = fread($localfile, $lenget);
525                                         if(!$data) {
526                                                 error_log("OTHERDOWNLOAD: dollar data went plop");
527                                         } else {
528                                                 $sgotten += strlen($data);
529                                                 echo $data;
530                                                 flush();
531                                         }
532                                 }
533                                 fclose($localfile);
534
535                                 if($sgotten >= $rangelength) {
536                                         if($sgotten > $rangelength) error_log("OTHERDOWNLOADER: finished but $sgotten, $fsize doesnt make senze");
537                                         $upload_finished = true;
538                                 }
539                                 // and we're done
540
541                         }
542                         error_log("OTHERDOWNLOADER: done with");
543                                 
544                         return;
545                                 
546                 }
547
548
549                 return;
550         }
551
552         function startDownload($file, $url)
553         {
554                 
555                 error_log("background downloader, start");
556                 global $WEB_ROOT_FS, $URL_HANDLERS, $BASE_URL;
557                 if(file_exists("$WEB_ROOT_FS/../bin/downloadfile.php")) {
558                         $scall = "/usr/bin/php $WEB_ROOT_FS/../bin/downloadfile.php '$url' '$file' > /tmp/dllog 2>&1 &";
559                         system($scall);
560                 } else {
561                         error_log("cant find download helper... dieing");
562                 }
563         }
564
565         // this is a nightmare
566
567
568         function printDir($dir, $localfile, $baseurl)
569         {
570                 $localfile = preg_replace("/\/\/+/", "/", $localfile);
571                 $uri = $_SERVER["REQUEST_URI"];
572                 $content = "";
573                 if(is_dir($dir)) {
574                         $content .= "<html><head><title>Index of $localfile</title></head><body><h1>Index of $localfile</h1>";
575                         $content .= "<table>";
576                         $dh = opendir($dir);
577                         $dirn = 0;
578                         $filen = 0;
579                         while(($file = readdir($dh))!==false) {
580                                 if($file != "." && $file != "..") {
581                                         if(is_dir("$dir/$file")) {
582                                                 $dirlist[$dirn++] = "$file";
583                                         } else {
584                                                 $filelist[$filen++] = "$file";
585                                         }
586                                 }
587                         }
588                         if(isset($dirlist)) {
589                                 sort($dirlist);
590                                 foreach($dirlist as $dirs) {
591                                         $icon = "/icons/folder.png";
592                                         $content .= "<tr><td><img src=\"$icon\"></td><td><a href=\"$uri/$dirs\">$dirs</a></td><td></td></tr>";
593                                 }
594                         }
595                         if(isset($filelist)) {
596                                 sort($filelist);
597                                 foreach($filelist as $files) {
598                                         $fsize = filesize("$dir/$files");
599                                         $icon = "/icons/text.png";
600                                         $content .= "<tr><td><img src=\"$icon\"></td><td><a href=\"$uri/$files\">$files</a></td><td>$fsize</td></tr>";
601                                 }                               
602                         }
603                         $content .= "</table></body></html>";
604                                 
605                         GLCASpageBuilder(null, null, $content);
606                                 
607                 } else return false;
608         }
609         
610         function getRepoDetailsApt($url)
611         {
612                 $action1 = $url."/dists";
613                 
614                 // we just want to make sure it exists really
615                 error_log("in repo details apt for $url");
616                 if(!glcas_isRemoteDir($action1)) {
617                         //echo "I cant find any valid APT dists's at $url<br>";
618                         return false;
619                 }
620                 
621                 // ok, now scan for ubuntu dists as
622                 $kos = getKnownOSList();
623                 
624                 $repos = 0;
625                 $existing_repo["isrepo"] = true;
626                 foreach($kos["apt"] as $key => $val) {
627                         //echo "<br>$key, $val<br>";
628                         //echo "now check, $action1/$key";
629                         if(glcas_isRemoteDir($action1."/$key")) {
630                                 $existing_repos["knownrepo"][$repos]["name"] = $key;
631                                 //echo "Found Distro $val<br>";
632                                 if(glcas_fileExists($action1."/$key/Contents-amd64.gz")) $existing_repos["knownrepo"][$repos]["amd64"] = true;
633                                 else $existing_repos["knownrepo"][$repos]["amd64"] = false;
634                                 if(glcas_fileExists($action1."/$key/Contents-i386.gz")) $existing_repos["knownrepo"][$repos]["i386"] = true;
635                                 else $existing_repos["knownrepo"][$repos]["i386"] = false;
636                                 $repos++;
637                                 
638                         }
639                 }
640                 $existing_repos["nrepos"] = $repos;
641                 
642                 // TODO: these need to be "calculated"
643                 $existing_repos["distros"] = "Ubuntu, Debian";
644                 $existing_repos["versions"] = "8.04LTS, 9.10, 10.04LTS, 10.10, 11.04, 11.10";
645                 $existing_repos["arch"] = "x86_64, i386";
646                 
647                 
648                 return $existing_repos;
649
650         }
651
652         function getRepoDetailsYum($url, $ismirrorlist=false)
653         {
654                 $actionurl = $url."/repodata/repomd.xml";
655
656                 error_log("Getting for action of $actionurl");
657
658                 $ld = file_get_contents($actionurl);
659
660                 // so here we try and get what this repository provides (os, version, arch), for yum this
661                 // should come straight off the url... i.e. centos/6.0/os/x86_64/ (centos, 6.0, base os, 64bit arch)
662
663                 if(!$ld) return false;
664
665                 // ok, now we tokenize the url and try and guess at the content
666                 $spurl = explode("/", $url);
667
668                 // first, find the OS
669                 $kos = getKnownOSList();
670                 $glt["OS"] = "unknown";
671                 $glt["verison"] = "unknown";
672                 $glt["arch"] = "unknown";
673                 $glt["other"] = "unknown";
674                 foreach($spurl as $comp) {
675                                 
676                         // find a name
677                         foreach($kos["os"]["short"] as $kosname => $koslong) {
678                                 //error_log("Comparing $kosname and $koslong with $comp");
679                                 if(strcasecmp($kosname, $comp) == 0) {
680                                         //error_log("got $kosname, $koslong for $comp in $url");
681                                         //echo "<pre>inone\n"; print_r($koslong); echo "</pre>";
682                                         $glt["OS"] = $koslong;
683                                 }
684                         }
685                                 
686                         // find a version, we assume its going to be something [numbers] and a . (optional)
687                         if(preg_match("/^[0-9.]+$/", $comp)>0) {
688                                 //error_log("version match of $comp");
689                                 $glt["version"] = $comp;
690                         }
691                                 
692                         // now architecture, this can be either i?86 or x86_64 - can also be arm or otherwise, but lets just go with this for now
693                         foreach($kos["arch"] as $archinter => $archname ) {
694                                 //error_log("Comparing $archinter, $archname with $comp");
695                                 if(strcasecmp($archname, $comp) == 0) {
696                                         //error_log("arch match of $archname with $comp");
697                                         $glt["arch"] = $archname;
698                                 }
699                         }
700                                 
701                         // other is a bt harder, we really have to guess at this one
702                         if(strcasecmp("os", $comp) == 0) $glt["other"] = "OS";
703                         if(strcasecmp("update", $comp) == 0) $glt["other"] = "Updates";
704                         if(strcasecmp("updates", $comp) == 0) $glt["other"] = "Updates";
705                         if(strcasecmp("everything", $comp) == 0) $glt["other"] = "OS";
706                 }
707
708                         
709                 return $glt;
710         }
711
712         function deleteRepo($rkey)
713         {
714                 $uconf = $this->config->getConfigVar("repodata");
715                 $repostore = $this->config->getConfigVar("storagelocation");
716
717                 if($uconf !== false) {
718                         $conf = unserialize($uconf);
719                         foreach($conf as $key => $vla) {
720                                 if($key == $rkey) {
721                                         unset($conf["$rkey"]);
722                                         $nconf = serialize($conf);
723                                         system("rm -rf $repostore/$key");
724                                         error_log("remove repo as $rkey");
725                                         $this->config->setConfigVar("repodata", $nconf);
726                                         $this->config->saveConfig();
727                                 }
728                         }
729                 }
730         }
731
732         function addRepo($desc, $os, $version, $arch, $other, $shorturl, $prefix, $repurl, $repotype, $init, $expiretime, $blocklist=null)
733         {
734                 $uconf = $this->config->getConfigVar("repodata");
735
736                 $cs["desc"] = $desc;
737                 $cs["os"] = $os;
738                 $cs["version"] = $version;
739                 $cs["arch"] = $arch;
740                 $cs["other"] = $other;
741                 $cs["shorturl"] = $shorturl;
742                 $cs["prefix"] = $prefix;
743                 $cs["url"] = $repurl;
744                 $cs["repotype"] = $repotype;
745                 $cs["expiretime"] = $expiretime;
746                 if($blocklist != null) {
747                         $cs["blocklist"] = $blocklist;
748                 }
749
750
751                 $ckey = 0;
752                 if($uconf !== false) {
753                         $conf = unserialize($uconf);
754                         foreach($conf as $key => $val) {
755                                 $ckey = $key;
756                         }
757                         $ckey++;
758                 }
759
760                 $conf[$ckey] = $cs;
761
762                 $nconf = serialize($conf);
763
764                 error_log("add repo as $ckey");
765                 $this->config->setConfigVar("repodata", $nconf);
766                 $this->config->saveConfig();
767
768                 // now create the base structure in the repo
769                 $repostore = $this->config->getConfigVar("storagelocation");
770
771
772                 // now call update repo
773                 if($init) $this->updateRepoYum($ckey);
774         }
775
776         function updateRepo($repokey)
777         {
778                 // we only do yum yet
779                 $repod = $this->getRepo($repokey);
780                 
781                 error_log("in update repo");
782
783                 if($repod["repotype"] == "YUM") $this->updateRepoYum($repokey);
784                 if($repod["repotype"] == "APT") $this->updateRepoApt($repokey);
785         }
786         
787         function updateRepoApt($repokey)
788         {
789                 $repostore = $this->config->getConfigVar("storagelocation");
790
791                 $repod = $this->getRepo($repokey);
792
793                 $repourl = $repod["url"];
794
795                 if(!file_exists("$repostore/$repokey")) {
796                         mkdir("$repostore/$repokey");
797                 }
798
799                 error_log("background apt repo update, start");
800                 global $WEB_ROOT_FS, $URL_HANDLERS, $BASE_URL;
801                 if(file_exists("$WEB_ROOT_FS/../bin/downloadfile.php")) {
802                         $scall = "/usr/bin/php $WEB_ROOT_FS/../bin/updateaptrepo.php '$repourl' '$repostore/$repokey/' > /tmp/updateaptrepo.$repokey.log 2>&1 &";
803                         system($scall);
804                 } else {
805                         error_log("cant find download apt helper... dieing");
806                 }
807         }
808
809         function updateRepoYum($repokey)
810         {
811                 $repostore = $this->config->getConfigVar("storagelocation");
812
813                 $repod = $this->getRepo($repokey);
814
815                 $repourl = $repod["url"];
816
817                 if(!file_exists("$repostore/$repokey")) {
818                         mkdir("$repostore/$repokey");
819                 }
820
821                 if(!file_exists("$repostore/$repokey/repodata")) {
822                         mkdir("$repostore/$repokey/repodata");
823                 }
824                 
825                 error_log("background yum repo update, start");
826                 global $WEB_ROOT_FS, $URL_HANDLERS, $BASE_URL;
827                 if(file_exists("$WEB_ROOT_FS/../bin/downloadfile.php")) {
828                         $scall = "/usr/bin/php $WEB_ROOT_FS/../bin/updateyumrepo.php '$repourl' '$repostore/$repokey/' > /tmp/updateyumrepo.$repokey.log 2>&1 &";
829                         system($scall);
830                 } else {
831                         error_log("cant find download yum helper... dieing");
832                 }
833                 
834
835                 //ignore_user_abort(true);
836         }
837
838         function getRepo($id)
839         {
840                 $uconf = $this->config->getConfigVar("repodata");
841                 if($uconf !== false) {
842                         $lconf = unserialize($uconf);
843                         return $lconf[$id];
844                 } else return false;
845
846         }
847
848         function getRepos()
849         {
850                 $uconf = $this->config->getConfigVar("repodata");
851                 if($uconf !== false) {
852                         return unserialize($uconf);
853                 } else return false;
854
855         }
856
857         private $config;
858 }
859
860 ?>