Code

Do not remove invalid user accounts.
[gosa.git] / include / class_ppdManager.inc
1 <?php
3 class ppdManager
4 {
5         var $path= "";
6         var $cachedList= array();
7         var $timestamps = array();
9         function ppdManager($path)
10         {
11                 if(is_dir($path)){
12                 $this->path= $path;
13                 }else{
14                         print_red(sprintf(_("PPD manager : The specified path '%s' doesn't exists."),$path));
15                         return (false);
16                 }
17         }
20         function findPPD($path)
21         {
22                 $list= array();
23                 $currentDir= getcwd();
25                 $dh = opendir($path);
26                 while(false !== ($file = readdir($dh))){
28                         /* Skip well known files */
29                         if( $file == '.' || $file == '..'){
30                                 continue;
31                         }
33                         /* Recurse through all "common" directories */
34                         if(is_dir($path.'/'.$file)){
35                                 $list= array_merge($list, $this->findPPD($path.'/'.$file));
36                                 continue;
37                         }
39                         /* Check for PPD extension */
40                         if (preg_match('/\.ppd$/i', $file)){
41                                 $list[]= $path.'/'.$file;
42                         }
43                 }
45                 closedir($dh);
46                 chdir ($currentDir);
47                 return ($list);
48         }
51         function updateAttribute($file, $section, $attribute, $value)
52         {
53                 $fsection= false;
54                 $fattribute= false;
55                 $section= preg_replace('/^\*/', '', $section);
56                 $attribute= preg_replace('/^\*/', '', $attribute);
58                 $rp= @fopen($file, "r");
59                 $wp= @fopen("$file.tmp", "w");
61                 
63                 while (!feof($rp)){
64                         $lines[]= fgets($rp, 1024);
65                 }
67                 $ret = "";
68                 $done =false;
69                 foreach($lines as $nr => $line){
70         
71                         if (preg_match("/\*OpenGroup:*\s+\**$section\/*/", $line)){
72                 $fsection= true;
73                                 $ret .=$line; 
74                 continue;
75             }
77                         /* Change model name .. */
78                         if ((preg_match("/^\*".$attribute.":*\s+/",$line)) && ($attribute == "ModelName")){
79                                 $line= "*$attribute: \"$value\"\n";
80                                 $done =true;
81                         }
83                         if (($fsection) && ($section != "NO_SECTION")){
84                                 if (preg_match("/^\*CloseGroup:*\s+\**$section\/*/", $line)){
85                                         $fsection= false;
86                                         $ret .=$line; 
87                                         continue;
88                                 }
91                                 if (preg_match("/^\*OpenUI:*\s+\**$attribute\/*/", $line)){
92                                         $fattribute= true;
93                                         $ret .= $line; 
94                                         continue;
95                                 }
97                                 if ($fattribute){
98                                         if (preg_match("/^\*CloseUI:*\s+\**$attribute\/*/", $line)){
99                                                 $fattribute= false;
100                                                 $ret .= $line; 
101                                                 continue;
102                                         }
104                                         if (preg_match("/^\*Default$attribute:*\s+/", $line)){
105                                                 $line= "*Default$attribute: $value\n";
106                                                 $done =true;
107                                         }
108                                 }
109                         }else{
110                                 if (preg_match("/^\*OpenUI:*\s+\**$attribute\/*/", $line)){
111                                         $fattribute= true;
112                                         $ret .= $line; 
113                                         continue;
114                                 }
116                                 if ($fattribute){
117                                         if (preg_match("/^\*CloseUI:*\s+\**$attribute\/*/", $line)){
118                                                 $fattribute= false;
119                                                 $ret .= $line; 
120                                                 continue;
121                                         }
123                                         if (preg_match("/^\*Default$attribute:*\s+/", $line)){
124                                                 $line= "*Default$attribute: $value\n";
125                                                 $done =true;
126                                         }
127                                 }
128                         }
129                         $ret .=$line; 
130                 }
132                 fwrite($wp,$ret);
133                 
134                 fclose($wp);
135                 fclose($rp);
137                 copy("$file.tmp", "$file");
138                 unlink("$file.tmp");
139         }
142         function saveProperties($ppdFile, $properties)
143         {
144                 if(!is_readable($ppdFile)){
145                         print_red(sprintf(_("Specified ppd file '%s' can't be opened for reading."),$ppdFile));
146                 }elseif(!is_writeable(preg_replace("#(^.*/).*$#","\\1",$ppdFile.".tmp"))){
147                         print_red(sprintf(_("The required tmp file file '%s' can't be opened for writing."),$ppdFile.".tmp"));
148                 }else{
149                         foreach ($properties as $name => $section){
150                                 foreach ($section as $attribute => $value){
151                                         if (is_array($value)){
152                                                 $this->updateAttribute($ppdFile, $name, $attribute, $value['_default']);
153                                         }
154                                 }
155                         }
156                 }
157         }
159         function loadProperties($ppdFile)
160         {
161                 $group= "";
162                 $option= "";
163                 $properties= array();
165                 $fh= fopen ($ppdFile, 'r');
166                 while (!feof($fh)) {
168                         /* Read line */
169                         $line= fgets($fh, 256);
170                         if (strlen($line) >= 256){
171                                 trigger_error(_('Parsing PPD file %s failed - line too long. Trailing characters have been ignored'), E_USER_WARNING);
172                         }
174                         /* Trigger for option groups */
175                         if (preg_match('/^\*OpenGroup:/i', $line)){
177                                 /* Sanity checks */
178                                 if ($group != ""){
179                                         trigger_error(_('Nested groups are not supported!'), E_USER_WARNING);
180                                         continue;
181                                 }
182                                 if (in_array($group, $properties)){
183                                         trigger_error(_('Group name not unique!'), E_USER_WARNING);
184                                         continue;
185                                 }
187                                 // TODO: Symbol values are not supported yet!
188                                 if (preg_match('/\^/', $line)){
189                                         trigger_error(_('Symbol values are not supported yet!'), E_USER_WARNING);
190                                 }
191                                 $complete= preg_replace('@^\*OpenGroup:\s+(.*)$@i', '\1', $line);
192                                 $complete= trim($complete, '"');
193                                 if (preg_match('@/@', $complete)){
194                                         $group= trim(preg_replace('@^\*OpenGroup:\s+"?([^/]+)/.*$@i', '\1', $line));
195                                         $name = preg_replace('@^\*OpenGroup:\s+"?[^/]+/([^/]+).*$@i', '\1', $line);
196                                 } else {
197                                         $group= $complete;
198                                         $name = $complete;
199                                 }
200                                 $properties[$group]= array('_name' => $name);
201                                 continue;
202                         }
203                         if (preg_match("/^\*CloseGroup:\s+\"?$group\"?/i", $line)){
204                                 $group= "";
205                                 continue;
206                         }
208                         /* Trigger for options */
209                         if (preg_match('/^\*OpenUI\s+/i', $line)){
211                                 /* Sanity check */
212                                 if ($option != ""){
213                                         trigger_error(_('Nested options are not supported!'), E_USER_WARNING);
214                                         continue;
215                                 }
217                                 // TODO: Symbol values are not supported yet!
218                                 if (preg_match('/\^/', $line)){
219                                         trigger_error(_('Symbol values are not supported yet!'), E_USER_WARNING);
220                                 }
221                                 $complete= preg_replace('@^\*OpenUI\s+(.*)$@i', '\1', $line);
222                                 $complete= trim($complete, '"');
223                                 if (preg_match('@/@', $complete)){
224                                         $option= trim(preg_replace('@^\*OpenUI\s+([^/]+)/.*$@i', '\1', $line));
225                                         $name = trim(preg_replace('@^\*OpenUI\s+[^/]+/([^/]+).*$@i', '\1', $line));
226                                 } else {
227                                         $option= trim($complete);
228                                         $name  = trim($complete);
229                                 }
231                                 /* Extract option type */
232                                 $type= trim(preg_replace('/^[^:]+:\s+/', '', $line));
233                                 $name= preg_replace('/:.*$/', '', $name);
234                                 $option= preg_replace('/:.*$/', '', $option);
236                                 // TODO: PickMany is not supported yet!
237                                 if (preg_match('/PickMany/i', $type)){
238                                         trigger_error(_('PickMany is not supported yet!'), E_USER_WARNING);
239                                 }
240                                 if(empty($group)){
241                                         $properties["NO_SECTION"][$option]= array('_name' => $name, '_type' => $type);
242                                 }else{
243                                         $properties[$group][$option]= array('_name' => $name, '_type' => $type);
244                                 }
245                                 continue;
246                         }
247                         /* Show interest for option parsing */
248                         if ($option != ""){
250                                 $eoption= preg_replace('@\*@', '', $option);
252                                 /* Close section? */
253                                 if (preg_match("@^\*CloseUI:\s+\*$eoption@i", $line)){
254                                         $option= "";
255                                         continue;
256                                 }
258                                 /* Default value? */
259                                 if (preg_match("@^\*Default$eoption:@", $line)){
260                                         $c= preg_replace("@^\*Default$eoption:\s+@", "", $line);
261                                         if(empty($group)){
262                                                 $properties["NO_SECTION"][$option]['_default']= trim(trim($c, '"'));
263                                         }else{
264                                                 $properties[$group][$option]['_default']= trim(trim($c, '"'));
265                                         }
266                                         continue;
267                                 }
269                                 /* Possible value? */
270                                 if (preg_match("@^\*$eoption\s+@", $line)){
271 #*PageSize Letter/US Letter: "<>setpagedevice"
272                                         $c= preg_replace("@^\*$eoption\s+([^/]+).*$@", "$1", $line);
273                                         $d= preg_replace("@^\*$eoption\s+[^/]+/([^:]+).*$@", "$1", $line);
274                                         if(empty($group)){
275                                                 $properties["NO_SECTION"][$option][trim($c)]= trim($d);
276                                         }else{
277                                                 $properties[$group][$option][trim($c)]= trim($d);
278                                         }
279                                         continue;
280                                 }
281                         }
282                 }
283                 fclose ($fh);
284                 return ($properties);
285         }
287         function loadDescription($ppdFile)
288         {
289                 $model= "";
290                 $manufacturer= "";
292                 
293                 /* Only parse complete PPD file again, if it was changed */
294                 $modified = filemtime($ppdFile);
295                 if(isset($this->cachedList[$ppdFile]) && isset($this->timestamps[$ppdFile]) && $modified == $this->timestamps[$ppdFile]){
296                         return($this->cachedList[$ppdFile]);
297                 }
299                 /* Remember modified timestamp, to speed up next request */
300                 $this->timestamps[$ppdFile] = filemtime($ppdFile);
302                 $fh= fopen ($ppdFile, 'r');
303                 while ((!feof($fh))&&($fh)) {
305                         /* Read line */
306                         $line= fgets($fh, 256);
307                         if (strlen($line) >= 256){
308                                 trigger_error(_('Parsing PPD file %s failed - line too long. Trailing characters have been ignored'), E_USER_WARNING);
309                         }
311                         /* Extract interesting informations */
312                         if (preg_match('/^\*Manufacturer:/i', $line)){
313                                 $manufacturer= preg_replace('/^\*Manufacturer:\s+"?([^"]+)"?.*$/i', '\1', $line);
314                         }
315                         if (preg_match('/^\*ModelName:/i', $line)){
316                                 $model= preg_replace('/^\*ModelName:\s+"?([^"]+)"?.*$/i', '\1', $line);
317                         }
319                         /* Got everything we need? Skip rest for speed reasons... */
320                         if ($model != '' && $manufacturer != ''){
321                                 break;
322                         }
323                 }
324                 fclose ($fh);
326                 /* Write out a notice that the PPD file seems to be broken if we can't
327                    extract any usefull informations */
328                 if ($model == '' || $manufacturer == ''){
329                         trigger_error(sprintf(_('Parsing PPD file %s failed - no information found.'), $ppdFile), E_USER_WARNING);
330                 }
332                 return ($manufacturer.' - '.$model);
333         }
336         function getPrinterList($reload= false)
337         {
338                 /* Load list of PPD files */
339                 if (count($this->cachedList) == 0 || $reload){
340                         $list= $this->findPPD($this->path);
342                         /* Load descriptive informations to build final printer list */
343                         $new = array();
344                         foreach ($list as $ppdFile){
345                                 $new[$ppdFile] = $this->loadDescription($ppdFile); 
346                         }
347                         $this->cachedList= $new ;
349                 }
351                 return ($this->cachedList);
352         }
356 ?>