Code

Added command info
[gosa.git] / gosa-core / update-gosa
1 #!/usr/bin/php
2 <?php
3 /*
4  * This code is part of GOsa (http://www.gosa-project.org)
5  * Copyright (C) 2003-2010 GONICUS GmbH
6  *
7  * ID: $$Id: main.php 9254 2008-03-03 15:57:49Z cajus $$
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
24 define ("GOSA_HOME", dirname(__FILE__));
25 define ("LOCALE_DIR", GOSA_HOME."/locale");
26 define ("PLUGSTATE_DIR", GOSA_HOME."/state");
28 function print_usage()
29 {
30         ?>
31 update-gosa - class cache updated and plugin manager for GOsa
32 Usage: update-gosa install dsc     Install the plugin using the dsc information
33                                    placed in the plugin source directory.
35        update-gosa remove plugin   Remove the plugin named "plugin" from
36                                    the current configuration.
38        update-gosa list           Lists installed plugins
40        update-gosa rescan-i18n     Rebuilds the translations
42        update-gosa rescan-images   Rebuilds the themes master image
44        update-gosa rescan-classes  Rebuilds the class list
45        
46        update-gosa                 Shortcut for rescan-classes and rescan-i18n
47 <?php
48         exit (1);
49 }
52 function rmdirRecursive($path, $followLinks=false) {
53   $dir= opendir($path);
54   while($entry= readdir($dir)) {
55     if(is_file($path."/".$entry) || ((!$followLinks) && is_link($path."/".$entry))) {
56       unlink($path."/".$entry);
57     } elseif (is_dir($path."/".$entry) && $entry!='.' && $entry!='..') {
58       rmdirRecursive($path."/".$entry);
59     }
60   }
61   closedir($dir);
62   return rmdir($path);
63 }
66 function get_themes()
67 {
68   $themes= array();
69   $d = dir(GOSA_HOME."/html/themes");
70   while (false !== ($entry = $d->read())) {
71     if ($entry[0] != '.') {
72       $themes[]= basename($entry);
73     }
74   }
75   $d->close();
77   return $themes;
78 }
80 /* Function to include all class_ files starting at a given directory base */
81 function get_classes($folder= ".")
82 {
83   static $base_dir= "";
84   static $result= array();
86   if ($base_dir == ""){
87     if ($folder == "."){
88       $base_dir= getcwd();
89     } else {
90       $base_dir= $folder;
91     }
92   }
94   $currdir=getcwd();
95   if ($folder){
96     chdir("$folder");
97   }
99   $dh = opendir(".");
100   while(is_resource($dh) && false !== ($file = readdir($dh))){
102     if (preg_match("/.*\.svn.*/", $file) ||
103         preg_match("/.*smarty.*/i",$file) ||
104         preg_match("/.*\.tpl.*/",$file) ||
105         ($file==".") ||($file =="..")){
106       continue;
107     }
109     /* Recurse through all "common" directories */
110     if (is_dir($file) && !file_exists("{$file}/excludeFromAutoLoad")){
111       get_classes($file);
112       continue;
113     }
115     /* Only take care about .inc and .php files... */
116     if (!(preg_match('/\.php$/', $file) || preg_match('/\.inc$/', $file))){
117       continue;
118     }
120     /* Include existing class_ files */
121     $contents= file($file);
122     foreach($contents as $line){
123       $line= chop($line);
124       if (preg_match('/^\s*class\s*\w.*$/', $line)){
125         $class= preg_replace('/^\s*class\s*(\w+).*$/', '\1', $line);
126         $result[$class]= preg_replace("%$base_dir/%", "", "$currdir/$folder/$file");
127       }
128     }
129   }
131   @closedir($dh);
132   chdir($currdir);
134   return ($result);
138 function rescan_classes()
140         echo "Updating class cache...\n";
141         $class_mapping= get_classes();
142         $filename= GOSA_HOME."/include/class_location.inc";
144         /* Sanity checks */
145         if (!file_exists($filename) || is_writable($filename)) {
147             if (!$handle= fopen($filename, 'w')) {
148                  echo "Cannot open file \"$filename\" - aborted\n";
149                  exit (1);
150             }
152         } else {
153             echo "File \"$filename\" is not writable - aborted\n";
154             exit (2);
155         }
157         fwrite ($handle, "<?php\n\$class_mapping= array(\n");
158         foreach ($class_mapping as $key => $value){
159           fwrite ($handle, "                \"$key\" => \"$value\",\n");
160         }
161         fwrite ($handle, " );\n");
163         fclose($handle);
167 function rescan_i18n()
169         echo "Updating internationalization...\n";
170         $languages= array();
171         $size= strlen(LOCALE_DIR);
173         /* Get all available messages.po files, sort them for languages */
174         $dir= new RecursiveDirectoryIterator(LOCALE_DIR);
175         $all= new RecursiveIteratorIterator($dir);
176         foreach ( $all as $element ){
177                 if ($element->isFile() && preg_match('/\/LC_MESSAGES\/messages.po$/', $element->getPathname())){
178                         $lang= preg_replace('/^.*\/([^\/]+)\/LC_MESSAGES\/.*$/', '\1', $element);
179                         if (!isset($languages[$lang])){
180                                 $languages[$lang]= array();
181                         }
182                         $languages[$lang][]= substr($element->getPathName(), $size+1);
183                 }
184         }
186         /* For each language, merge the target .mo to the compiled directory. */
187         foreach ($languages as $language => $po_files){
188                 if (!is_dir(LOCALE_DIR."/compiled/${language}/LC_MESSAGES")){
189                         if (!mkdir (LOCALE_DIR."/compiled/${language}/LC_MESSAGES", 0755, TRUE)){
190                                 echo "Failed to create '".LOCALE_DIR."/compiled/${language}/LC_MESSAGES'- aborted";
191                                 exit (3);
192                         }
193                 }
195                 /* Cat all these po files into one single file */
196                 system ("(cd ".LOCALE_DIR." && msgcat --use-first ".implode(" ", $po_files)." > compiled/${language}/LC_MESSAGES/messages.po)", $val);
197                 if ($val != 0){
198                         echo "Merging of message files failed - aborted";
199                         exit (4);
200                 }
201                 system ("(cd ".LOCALE_DIR."/compiled/${language}/LC_MESSAGES && msgfmt -o messages.mo messages.po && rm messages.po)", $val);
202                 if ($val != 0){
203                         echo "Compiling of message files failed - aborted";
204                         exit (5);
205                 }
206         }
208         echo "! Warning: you may need to reload your webservice!\n";
212 function rescan_guide()
214         $master_guide= "doc/guide.xml";
215         echo "Updating Online Help Index...\n";
216         $master_guide_content="<?xml version=\"1.0\"?>\n".
217                 "<!--\n".
218                 "\tWARNING:\n".
219                 "\tThis file is automatically generated by update-online-help.\n".
220                 "\tIf you want to add entries, use doc/core/guide.xml or doc/plugins/\"Appropriate Plugin Directory\"/guide.xml.\n".
221                 "\tThen execute update-online-help to merge them into this file.\n".
222                 "-->\n\n".
223                 "<!--\n".
224                 "\tThis xml file specifies which class is documented in which help file.\n".
225                 "\tIf isset ( \$_SESSION['current_class_for_help'] ) then open the helpfile which is\n".
226                 "\tspecified for this class below.\n".
227                 "-->\n\n".
228                 "<!--\n".
229                 "\t<ENTRY NAME='class name' VALUE='displayed text' PATH='path to helpfiles' FILE='path to htmlfile' />\n".
230                 "\tLeave blank to display message \"There is no helpfile specified for this class.\"\n".
231                 "-->\n".
232                 "<ENTRIES>\n";
234         $guide= 'doc/core/guide.xml';
235         if(file_exists($guide) && is_readable($guide)) {
236                 $master_guide_content.= file_get_contents($guide);
237         }
238         
239         if(file_exists('doc/plugins')) {
240                 $plugins= scandir('doc/plugins');
241                 foreach($plugins as $key => $plugin) {
242                         if($plugin != '.' && $plugin != '..') {
243                                 if(is_dir('doc/plugins/'.$plugin)) {
244                                         $guide= 'doc/plugins/'.$plugin.'/guide.xml';
245                                         if(file_exists($guide) && is_readable($guide)) {
246                                                 $master_guide_content.= file_get_contents($guide);
247                                         }
248                                 }
249                         }
250                 }
251         }
253         $master_guide_content.= "</ENTRIES>";
254         
255         $master_guide_content= preg_replace("/[ \t][ \t]*/", " ", $master_guide_content);
257         if((file_exists($master_guide) && is_writable($master_guide)) || is_writable('doc')) {
258                 file_put_contents($master_guide, $master_guide_content);
259         }
264 function parse_ini($file)
266         global $description, $provides, $depends, $versions, $conflicts;
268         $res= "";
269         if (file_exists($file)){
270                 $tmp= parse_ini_file($file, TRUE);
272                 if (isset($tmp['gosa-plugin'])){
273                         $plugin= &$tmp['gosa-plugin'];
274                         if (isset($plugin['name'])&& isset($plugin['description'])){
275                                 $res= $plugin['name'];
276                                 $description[$res]= $plugin['description'];
277                                 $versions[$res]= $plugin['version'];
278                                 $provides[$res]= $res;
279                                 if (isset($plugin['depends'])){
280                                         $depends[$res]= explode(',', preg_replace('/\s+/', '', $plugin['depends']));
281                                 }
282                                 if (isset($plugin['conflicts'])){
283                                         $conflicts[$res]= explode(',', preg_replace('/\s+/', '', $plugin['conflicts']));
284                                 }
285                         }
286                 }
287         }
289         return $res;
293 function dependency_check()
295         global $description, $provides, $depends;
297         foreach ($depends as $name => $pl_depends){
298                 foreach ($pl_depends as $pl){
299                         if (!in_array($pl, $provides)){
300                                 echo "! Error: plugin '$name' depends on '$pl' which is not provided by any plugin\n\n";
301                                 exit (1);
302                         }
303                 }
304         }
308 function load_plugins()
310         if (!is_dir(PLUGSTATE_DIR)){
311                 if (!mkdir (PLUGSTATE_DIR, 0755, TRUE)){
312                         echo "Cannot create plugstate dir '".PLUGSTATE_DIR."' - aborted\n";
313                         exit (2);
314                 }
315         }
316         $dir= new DirectoryIterator(PLUGSTATE_DIR);
317         foreach ($dir as $entry){
318                 if ($dir->isDir() && !preg_match('/^\./', $dir->__toString())){
319                         $file= $dir->getPathName()."/plugin.dsc";
320                         if (parse_ini($file) == ""){
321                                 echo "! Warning: plugin ".$dir->getPathName()." is missing declarations\n";
322                         }
323                 }
324         }
328 function list_plugins()
330         global $description, $versions;
331         $count= 0;
333         /* Load plugin list */
334         load_plugins();
336         /* Show plugins */
337         foreach ($description as $name => $dsc){
338                 if ($count == 0){
339                         echo "Plugin\t\t|Version |Description\n";
340                         echo "----------------------------------------------------------------------------\n";
341                 }
342                 $ver= $versions[$name];
343                 echo "$name\t\t|$ver\t |$dsc\n";
344                 $count++;
345         }
347         /* Yell about non existing plugins... */
348         if ($count == 0){
349                 echo "No plugins found...\n\n";
350         } else {
351                 # Check for dependencies
352                 dependency_check();
353                 echo "\n";
354         }
358 function install_plugin($file)
360         global $description, $provides, $depends, $conflicts;
362         /* Load plugin list */
363         load_plugins();
365         /* Load .dsc file */
366         if (file_exists($file)){
367                 $tmp= parse_ini_file($file, TRUE);
369                 if (isset($tmp['gosa-plugin'])){
370                         $plugin= &$tmp['gosa-plugin'];
371                         if (isset($plugin['name'])&& isset($plugin['description'])){
372                                 $name= $plugin['name'];
373                                 $description= $plugin['description'];
374                                 $depends= array();
375                                 if (isset($plugin['depends'])){
376                                         $depends= explode(',', preg_replace('/\s+/', '', $plugin['depends']));
377                                 }
379                                 /* Already installed? */
380                                 if (isset($provides[$name])){
381                                         echo "! Error: plugin already installed\n\n";
382                                         exit (3);
383                                 }
385                                 /* Check if dependencies are fullfilled */
386                                 foreach ($depends as $dep){
387                                         $found= false;
388                                         foreach ($provides as $provide => $dummy){
389                                                 if ($dep == $provide){
390                                                         $found= true;
391                                                         break;
392                                                 }
393                                         }
394                                         if (!$found){
395                                                 echo "! Error: plugin depends on '$dep', but this is not installed\n\n";
396                                                 exit (3);
397                                         }
398                                 }
400                                 /* Check for conflicts */
401                                 foreach ($conflicts as $conf){
402                                         if (!in_array($conf, $provides)){
403                                                 echo "! Warning: plugin conflicts with '$conf'\n\n";
404                                         }
405                                 }
407                                 /* Create plugstate directory and touch plugin.lst */
408                                 if (!mkdir (PLUGSTATE_DIR."/$name", 0755, TRUE)){
409                                         echo "Failed to create '".PLUGSTATE_DIR."/$name - aborted";
410                                         exit (3);
411                                 }
412                                 if (!$handle= fopen(PLUGSTATE_DIR."/$name/plugin.lst", 'w')) {
413                                         echo "Cannot open file '$filename' - aborted\n";
414                                         exit (1);
415                                 }
417                                 echo "Installing plugin '$name'...\n";
419                                 /* Copy and fill plugin.lst */
420                                 $path= dirname($file);
421                                 $dir= new RecursiveDirectoryIterator($path);
422                                 $all= new RecursiveIteratorIterator($dir);
423                                 foreach ( $all as $entry ){
424                                         $source= $path."/".substr($entry->getPathName(), strlen($path) + 1);
426                                         /* Skip description - it belongs to the state dir */
427                                         if (preg_match('/\/plugin.dsc$/', $source)){
428                                                 copy ($source, PLUGSTATE_DIR."/$name/plugin.dsc");
429                                                 continue;
430                                         }
432                                         /* Skip well known directories */
433                                         if (preg_match('/^\.+$/', $source) || preg_match('/\/\.svn\//', $source)) {
434                                                 continue;
435                                         }
437                                         /* Calculate destination */
438                                         if (preg_match("%^.*locale/%", $source)){
439                                                 $dest= GOSA_HOME."/locale/plugins/$name/".preg_replace("%^.*locale/%", "", $source);
440                                         } elseif (preg_match("%^.*help/%", $source)) {
441                                                 $dest= GOSA_HOME."/doc/plugins/$name/".preg_replace("%^.*help/%", "", $source);
442                                         } elseif (preg_match("%^.*html/%", $source)) {
443                                                 $dest= GOSA_HOME."/html/plugins/$name/".preg_replace("%^.*html/%", "", $source);
444                                         } else {
445                                                 $dest= GOSA_HOME."/plugins/".substr($entry->getPathName(), strlen($path) + 1);
446                                         }
448                                         /* Destination exists in case of directories? */
449                                         if ($entry->isDir()){
450                                                 if (!is_dir($dest)){
451                                                         mkdir($dest, 0755, TRUE);
452                                                         fwrite ($handle, "$dest\n");
453                                                 }
454                                         } else {
455                                                 if (!is_dir(dirname($dest))){
456                                                         mkdir(dirname($dest), 0755, TRUE);
457                                                         fwrite ($handle, dirname($dest)."\n");
458                                                 }
459                                         }
461                                         /* Copy files */
462                                         if ($entry->isFile()){
463                                                 copy ($source, $dest);
464                                         }
466                                         /* Note what we did... */
467                                         fwrite ($handle, "$dest\n");
468                                 }
470                                 fclose($handle);
471                         }
472                 }
473         }
474         
475         /* Update caches */
476         rescan_classes();
477         rescan_i18n();
478         rescan_guide();
482 function remove_plugin($name)
484         global $description, $depends;
486         /* Load plugin list */
487         load_plugins();
489         /* Present? */
490         if (!isset($description[$name])){
491                 echo "! Error: cannot find a plugin named '$name'\n\n";
492                 exit (1);
493         }
495         /* Depends? */
496         foreach ($depends as $sname => $pl_depends){
497                 if (in_array($name, $pl_depends)){
498                         echo "! Error: plugin '$sname' depends on '$name' - cannot remove it\n\n";
499                         exit (1);
500                 }
501         }
503         /* Load information */
504         if (!file_exists(PLUGSTATE_DIR."/$name/plugin.lst")){
505                 echo "! Error: cannot remove plugin '$name' - no install history found\n\n";
506                 exit (1);
507         }
509         echo "Removing plugin '$name'...\n";
510         $contents= file(PLUGSTATE_DIR."/$name/plugin.lst");
511         $cnv= array();
512         foreach($contents as $line){
513                 $entry= chop($line);
514                 $cnv[strlen($entry).":$entry"]= $entry;
515         }
516         krsort($cnv);
518         /* Remove files first */
519         clearstatcache();
520         foreach ($cnv as $entry){
521                 if (is_dir($entry)){
522                         rmdir($entry);
523                         continue;
524                 }
525                 if (file_exists($entry)){
526                         unlink($entry);
527                 }
528         }
530         /* Remove state directory for plugin */
531         rmdirRecursive(PLUGSTATE_DIR."/$name");
533         /* Update caches */
534         rescan_classes();
535         rescan_i18n();
536         rescan_guide();
540 function rescan_images($path, $theme)
542   $widths= array();
543   $heights= array();
544   $paths= array();
545   $posX= array();
546   $posY= array();
547   $baseLength= strlen($path);
548   $heightStats= array();
549   $warnings= array();
550   $checksums= array();
551   $styles= array();
552   $duplicates= array();
554   echo "Updating master image for theme '$theme'...";
556   // Check for image magick convert
557   if (!function_exists("imageFilter")){
558     exec("which convert", $res, $ret);
559     if ($ret != 0) {
560       die("Your system has no bundled gd support for imageFilter function. Please install imagemagick in order to use an external command.\n");
561     }
562   }
563   
564   // Scan for images in the given path
565   flush();
566   foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $fileInfo) {
567   
568       // We're only interested in png files
569       $indexPath= substr($fileInfo->getPathname(), $baseLength + 1);
570       $path= $fileInfo->getPathname();
571       if (preg_match('/\.png$/', $indexPath) && !preg_match('/\.svn/', $path) && !preg_match('/themes\/[^\/]+\/images\/img.png$/', $path)){
572   
573          // Grey image if it is not already one
574          if (preg_match('/grey/', $indexPath)) {
575            echo "!";
576            $warnings[]= "! Warning: skipped possible *grey* image $path";
577            flush();
578            continue;
579          }
581          // New image if it is not already one
582          if (preg_match('/new/', $indexPath) && !preg_match('/new\.png$/', $indexPath)) {
583            echo "!";
584            $warnings[]= "! Warning: skipped possible *new* image $path";
585            flush();
586            continue;
587          }
589          // Catch available themes
590          if (preg_match('/themes\//', $indexPath) && !preg_match('/themes\/'.$theme.'\//', $indexPath)) {
591            continue;
592          }
594          // Load image
595          $img= imageCreateFromPng($path);
596          $width= imageSX($img);
597          $height= imageSY($img);
598          imageDestroy($img);
599          $greyIndexPath= preg_replace('/\.png$/', '-grey.png', $indexPath);
601          // Is this image already there?
602          $checksum= md5_file($path);
603          if (in_array($checksum, $checksums)) {
604            $warnings[]= "! Warning: images $indexPath seems to be a duplicate of ".array_search($checksum, $checksums);
605            $duplicates[$indexPath]= array_search($checksum, $checksums);
606            $duplicates[$greyIndexPath]= preg_replace('/\.png$/', '-grey.png', array_search($checksum, $checksums));
607            continue;
608          } else {
609            $checksums[$indexPath]= $checksum;
610          }
612          // Ordinary image
613          $widths[$indexPath]= $width;
614          $heights[$indexPath]= $height;
615          $paths[$indexPath]= $path;
617          // Grey image
618          $widths[$greyIndexPath]= $width;
619          $heights[$greyIndexPath]= $height;
620          $paths[$greyIndexPath]= $path;
622          // Feed height statistics
623          if (!isset($heightStats[$height])) {
624            $heightStats[$height]= 1;
625          } else {
626            $heightStats[$height]++;
627          }
628       }
629   
630     echo ".";
631     flush();
632   }
633   echo "\n";
635   // Do some stupid height calculation
636   arsort($heightStats, SORT_NUMERIC);
637   reset($heightStats);
638   $popular= current($heightStats);
640   krsort($heightStats);
641   reset($heightStats);
642   $max= current($heightStats);
644   $maxHeight= (floor($max / $popular) + 1) * $popular * 6;
645   
646   // Sort to get biggest values
647   arsort($widths, SORT_NUMERIC);
648   reset($widths);
649   echo "Calculating master image dimensions: ";
650   flush();
651   
652   // Build container image
653   $cursorX= 0;
654   $cursorY= 0;
655   $colWidth= 0;
656   $rowHeight= 0;
657   $colX= 0;
658   $colY= 0;
659   $maxY= 0;
660   $maxX= 0;
662   // Walk thru width sorted images
663   foreach ($widths as $imagePath => $imageWidth) {
664     $imageHeight= $heights[$imagePath];
666     // First element in this column
667     if ($colWidth == 0) {
668       $colWidth= $imageWidth;
669     }
671     // First element in this row
672     if ($rowHeight < $imageHeight) {
673       $rowHeight= $imageHeight;
674     }
676     // Does the image match here?
677     if ($cursorX + $imageWidth > $colX + $colWidth) {
679       if ($cursorY + $imageHeight >= $maxHeight) {
681         // Reached max height, move to the next column
682         $colX+= $colWidth;
683         $cursorX= $colX;
684         $colWidth= $imageWidth;
685         $rowHeight= $imageHeight;
686         $colY= $cursorY= 0;
688       } else {
690         // Next row
691         $colY+= $rowHeight;
692         $cursorY= $colY;
693         $cursorX= $colX;
694         $rowHeight= $imageHeight;
695       }
697       $maxY=($colY + $imageHeight > $maxY)?$colY+$imageHeight:$maxY;
698     }
700     // Save calculated position
701     $posX[$imagePath]= $cursorX;
702     $posY[$imagePath]= $cursorY;
704     // Move X cursor to the next position
705     $cursorX+= $imageWidth;
707     $maxX=($colX+$imageWidth > $maxX)?$colX+$imageWidth:$maxX;
708   }
709   
710   // Print maximum dimensions
711   echo $maxY."x".$maxX."\n";
712   echo "Processing";
713   flush();
715   // Create result image
716   $dst= imageCreateTrueColor($maxX, $maxY);
717   imageAlphaBlending($dst, true);
718   $transparent = imagecolorallocatealpha($dst, 0, 0, 0, 127);
719   imageFill($dst, 0, 0, $transparent);
720   imageSaveAlpha($dst, true);
722   // Finally assemble picture
723   foreach ($heights as $imagePath => $imageHeight) {
724     $imageWidth= $widths[$imagePath];
725     $x= $posX[$imagePath];
726     $y= $posY[$imagePath];
728     // Insert source image...
730     // Eventually convert it to grey before
731     if (preg_match('/-grey\.png$/', $imagePath)) {
732       if (!function_exists("imageFilter")){
733         exec("convert ".$paths[$imagePath]." -colorspace Gray /tmp/grey-converted.png");
734         $src= imageCreateFromPng("/tmp/grey-converted.png");
735       } else {
736         $src= imageCreateFromPng($paths[$imagePath]);
737         imageFilter($src, IMG_FILTER_GRAYSCALE);
738       }
739     } else {
740       $src= imageCreateFromPng($paths[$imagePath]);
741     }
743     // Merge image
744     imageCopyResampled($dst, $src, $x, $y, 0, 0, $imageWidth, $imageHeight, $imageWidth, $imageHeight);
745     imageDestroy($src);
747     // Store style
748     $styles[$imagePath]= "background-position:-".$x."px -".$y."px;width:".$imageWidth."px;height:".$imageHeight."px";
750     echo ".";
751     flush();
752   }
754   /* Add duplicates */
755   foreach ($duplicates as $imagePath => $realPath) {
756     $styles[$imagePath]= $styles[$realPath];
757   }
759   imagePNG($dst, GOSA_HOME."/html/themes/$theme/images/img.png", 9);
760   imageDestroy($dst);
762   // Show warnings images
763   foreach ($warnings as $warn) {
764     echo "$warn\n";
765   }
767   // Write styles
768   echo "Writing styles...";
769   $fp = fopen(GOSA_HOME."/ihtml/themes/$theme/img.styles", 'w');
770   fwrite($fp, serialize($styles));
771   fclose($fp);
773   echo "\n";
777 /* Fill global values */
778 $description= $provides= $depends= $versions= $conflicts= array();
780 /* Action specified? */
781 if ($argc < 2){
782         rescan_classes();
783         rescan_i18n();
784         rescan_guide();
785     foreach (get_themes() as $theme) {
786       rescan_images(GOSA_HOME."/html", $theme);
787     }
788     exit (0);
791 switch ($argv[1]){
792         case 'install':
793                 if (isset($argv[2])){
794                         install_plugin($argv[2]);
795                 } else {
796                         echo "Usage: update-gosa install dsc-file\n\n";
797                         exit (1);
798                 }
799                 break;
800         case 'list':
801                 list_plugins();
802                 break;
803         case 'remove':
804                 if (isset($argv[2])){
805                         remove_plugin($argv[2]);
806                 } else {
807                         echo "Usage: update-gosa remove plugin-name\n\n";
808                         exit (1);
809                 }
810                 break;
811         case 'rescan-i18n':
812                 rescan_i18n();
813                 break;
814         case 'rescan-classes':
815                 rescan_classes();
816                 break;
817         case 'rescan-images':
818                 foreach (get_themes() as $theme) {
819                   rescan_images("html", $theme);
820                 }
821                 break;
822         default:
823                 echo "Error: Supplied command not known\n\n";
824                 print_usage();
825                 break;
829 ?>