Handle hostnames with upper-case letters
[webmin.git] / lpadmin / irix-lib.pl
1 # irix-lib.pl
2 # Functions for irix-style printer management
3
4 $irix_iface_path = "/var/spool/lp/interface";
5
6 # list_printers()
7 # Returns an array of known printer names
8 sub list_printers
9 {
10 local(@rv, $_);
11 open(STAT, "/usr/bin/lpstat -p |");
12 while(<STAT>) {
13         if (/^printer\s+(\S+)/) { push(@rv, $1); }
14         }
15 close(STAT);
16 return &unique(@rv);
17 }
18
19 # get_printer(name, [nostatus])
20 # Returns a reference to an associative array of printer details
21 sub get_printer
22 {
23 local($stat, @rv, $body, $body, $avl, $con, $sys, %prn, $_, $out);
24 local $esc = quotemeta($_[0]);
25 $out = &backquote_command("/usr/bin/lpstat -p$esc", 1);
26 if ($out =~ /^printer\s+(\S+)\s*(.*)\s+(enabled|disabled)\s+since\s+(.+?)\n?(.*)?$/) {
27         # printer exists
28         $prn{'name'} = $1;
29         $prn{'enabled'} = $3 eq "enabled";
30         $body = $5;
31         }
32 else {
33         # no printer found
34         return undef;
35         }
36
37 # Interface
38 $prn{'iface'} = "$irix_iface_path/$prn{'name'}";
39
40 # Description
41 local $wdrv = &is_windows_driver($prn{'iface'});
42 local $hdrv = &is_hpnp_driver($prn{'iface'});
43 $prn{'desc'} = $wdrv ? &grep_interface($wdrv->{'program'}) :
44                     $hdrv ? &grep_interface($hdrv->{'program'}) :
45                          &grep_interface($prn{'iface'});
46
47 # printer enabled?
48 if (!$prn{'enabled'} && $body =~ /^\s+(.*)/) {
49         $prn{'enabled_why'} = $1 eq "reason unknown" ? "" : $1;
50         }
51
52 if (!$_[1]) {
53         # request availability
54         $avl = &backquote_command("/usr/bin/lpstat -a$esc 2>&1", 1);
55         if ($avl =~ /^\S+\s+not accepting.*\n\s+(.*)/) {
56                 $prn{'accepting'} = 0;
57                 $prn{'accepting_why'} = $1;
58                 if ($prn{'accepting_why'} eq "reason unknown") {
59                         $prn{'accepting_why'} = "";
60                         }
61                 }
62         else { $prn{'accepting'} = 1; }
63         }
64
65 # request connection
66 $con = &backquote_command("/usr/bin/lpstat -v$esc 2>&1", 1);
67 if ($con =~ /^device for \S+:\s+(\S+)\n\s+(remote to:)\s+(\S+)\s+(on)\s+(\S+)/) {
68         $prn{'rhost'} = $5;
69         $prn{'rqueue'} = $3;
70         }
71 elsif ($con =~ /^device for \S+:\s+(\S+)/) { $prn{'dev'} = $1; }
72
73 # Check if this is the default printer
74 if (&backquote_command("$lpstat -d 2>&1", 1) =~ /destination:\s+(\S+)/ &&
75     $1 eq $prn{'name'}) {
76         $prn{'default'} = 1;
77         }
78
79 return \%prn;
80 }
81
82 sub get_jobs
83 {
84 local @jobs;
85 local $esc = quotemeta($_[0]);
86 open(STAT, "/usr/bin/lpstat -o$esc |");
87 while(<STAT>) {
88         if (/^(\S+-\d+)\s+(\S+)\s+(\d+)\s+(\S+ \d+ \d+:\d+)\s+(.*)/) {
89                 local(%job, $d, $f, @pf);
90                 $job{'id'} = $1;
91 #               local $id = $2;
92                 $job{'user'} = $2;
93                 $job{'size'} = $3;
94                 $job{'when'} = $4;
95                 $job{'printing'} = ($5 =~ /^on /);
96 #               if ($job{'user'} =~ /(\S+)\!/ &&
97 #                   -d ($d="/var/spool/lp/tmp/$1")) {
98 #                       opendir(DIR, $d);
99 #                       foreach $f (readdir(DIR)) {
100 #                               push(@pf, "$d/$f") if ($f =~ /^$id-[1-9]/);
101 #                               }
102 #                       closedir(DIR);
103 #                       $job{'printfile'} = @pf ? \@pf : undef;
104 #                       }
105
106         push(@jobs, \%job);
107                 }
108         }
109 close(STAT);
110 return @jobs;
111 }
112
113 # grep_interface($iface)
114 # try to find a description in the interface/model
115 sub grep_interface
116 {
117 local($iface, $desc, $out);
118 $iface = $_[0];
119
120 local $drv = &is_driver($iface);
121 if ($drv->{'mode'} == 1) {
122         $desc = $drv->{'desc'};
123         }
124 elsif ($drv->{'mode'} == 2) {
125         $out = &backquote_command("head $drv->{'prog'} | grep -e interface -e Printer -e /model/", 1);
126         if ($out =~ /interface for\s+(.*)/) { $desc = $1; }
127         elsif ($out =~ /\s+(\S.*)interface/) { $desc = $1; }
128         elsif ($out =~ /Printer Command Language level\s+(\S+)/) { $desc = "PCL$1"; }
129         elsif ($out =~ /\/model\/(\S+).*/) { $desc = $1; }
130         elsif ($out =~ /^#\s+(.*)/) { $desc = $1; }
131         else { $desc = "None"; }
132         }
133 else {
134         $desc = "None";
135         }
136 return $desc;
137 }
138
139 # printer_support(option)
140 sub printer_support
141 {
142 return $_[0] !~ /^(allow|alias|ctype|banner|desc|editdest|msize|direct|rnoqueue|ipp)$/;
143 }
144
145 # list_classes()
146 # Returns an associative array of print classes
147 sub list_classes
148 {
149 local($stat, %rv);
150 $stat = &backquote_command("/usr/bin/lpstat -c 2>&1", 1);
151 while($stat =~ /^members of class (\S+):\n((\s+\S+\n)+)([\000-\377]*)$/) {
152         $stat = $4;
153         $rv{$1} = [ grep { $_ ne "" } split(/\s+/, $2) ];
154         }
155 return \%rv;
156 }
157
158 # create_printer(&details)
159 # Create a new printer
160 sub create_printer
161 {
162 local(%prn, $cmd, $out, $model, $dummy, $scheduler);
163 %prn = %{$_[0]};
164 #local $wdrv = &is_windows_driver($prn{'iface'});
165 #local $hdrv = &is_hpnp_driver($prn{'iface'});
166 #$scheduler = &sched_running();
167 #$dummy = "webmin.tmp"; `touch $config{'model_path'}/$dummy`;
168
169 # create lpadmin command
170 local $esc = quotemeta($prn{'name'});
171 $cmd = "/usr/lib/lpadmin -p$esc";
172
173 ## remote unix printer
174 if ($prn{'rhost'}) {
175         if ($prn{'iface'}) {
176                 &error("lpadmin failed : <pre>No model allowed for remote unix printer.</pre>");
177         }
178    &copy_netface_driver($_[0]);
179         $cmd .= " -i$irix_iface_path/$esc.tmp";
180         $cmd .= " -v/dev/null";
181         }
182
183 ## remote windows printer
184 #elsif ($wdrv) {
185 #       $cmd .= " -m$dummy";
186 #       $cmd .= " -v/dev/null";
187 #       }
188
189 ## remote HPNP printer
190 #elsif ($hdrv) {
191 #       $cmd .= " -m$dummy";
192 #       $cmd .= " -v/dev/null";
193 #       }
194
195 ## local printer with webmin driver
196 #elsif ($prn{'iface'} eq "$drivers_directory/$prn{'name'}") {
197 #       $cmd .= " -m$dummy";
198 #       $cmd .= " -v".quotemeta($prn{'dev'});
199 #       }
200
201 ## local printer with IRIX model
202 elsif ($prn{'iface'} =~ $config{'model_path'}) {
203         $model = substr($prn{'iface'}, length($config{'model_path'}) + 1);
204         $cmd .= " -m$model";
205         $cmd .= " -v".quotemeta($prn{'dev'});
206         }
207 else {
208         &error("lpadmin failed : <pre>Action not supported.</pre>");
209         }
210
211 # stop scheduler
212 #$out = &backquote_logged("/usr/lib/lpshut 2>&1");
213
214 # call lpadmin
215 $out = &backquote_logged("$cmd 2>&1");
216 if ($?) { &error("lpadmin failed : <pre>$out</pre>"); }
217
218 if ($prn{'rhost'}) {
219   &unlink_file("$irix_iface_path/$prn{'name'}.tmp");
220 }
221
222 ## Link to windows webmin driver
223 #&lock_file("$irix_iface_path/$prn{'name'}");
224 #if ($wdrv) {
225 #       `rm $irix_iface_path/$prn{'name'}`;
226 #       `ln -s $drivers_directory/$prn{'name'}.smb $irix_iface_path/$prn{'name'}`;
227 #       }
228
229 ## Link to webmin hpnp driver
230 #if ($hdrv) {
231 #       `rm $irix_iface_path/$prn{'name'}`;
232 #       `ln -s $drivers_directory/$prn{'name'}.hpnp $irix_iface_path/$prn{'name'}`;
233 #       }
234
235 ## Link to webmin driver
236 #if ($prn{'iface'} eq "$drivers_directory/$prn{'name'}" && !$wdrv) {
237 #       `rm $irix_iface_path/$prn{'name'}`;
238 #       `ln -s $drivers_directory/$prn{'name'} $irix_iface_path/$prn{'name'}`;
239 #       }
240 #&unlock_file("$irix_iface_path/$prn{'name'}");
241 #&lock_file("$config{'model_path'}/$dummy");
242 #`rm $config{'model_path'}/$dummy`;
243 #&unlock_file("$config{'model_path'}/$dummy");
244
245 # start scheduler
246 #if ($scheduler) {
247 #       $out = &backquote_logged("/usr/lib/lpsched 2>&1");
248 #       if ($?) { &error("lpsched failed : <pre>$out</pre>"); }
249 #       }
250
251 #change printer parameters
252 &modify_printer($_[0]);
253 }
254
255 # copy_netface_driver(&prn)
256 # Copies netface driver to interfaces directory and changes
257 # remote host address, name and type of remote printer.
258 sub copy_netface_driver {
259   local (%prn);
260 %prn = %{$_[0]};
261   my ($cmd, $rname, $rtype, $nettype, $driver_file ) = ();
262
263   if ( $prn{'rtype'} eq "s5" ) {
264     $nettype = "sgi";
265     $cmd = "/usr/bsd/rsh -l lp $prn{'rhost'} "
266          . "\'grep \"^NAME\" $irix_iface_path/$prn{'rqueue'}\'";
267     $rname = &backquote_logged("$cmd");
268     if ($?) { &error("Failed to read remote printer's name : <pre>$rname</pre>"); }
269     $cmd = "/usr/bsd/rsh -l lp $prn{'rhost'} "
270          . "\'grep \"^TYPE\" $irix_iface_path/$prn{'rqueue'}\'";
271     $rtype = &backquote_logged("$cmd");
272     if ($?) { &error("Failed to read remote printer's type : <pre>$rtype</pre>"); }
273   } else {
274     $nettype = "bsd";
275     $rname = "BSD Printer";
276     $rtype = "PostScript";
277   }  
278   undef local $/;
279   open (NETFACE,"<$config{'model_path'}/netface") or &error("Failed to open netface driver."); 
280   $driver_file = <NETFACE>;
281   close (NETFACE);
282
283   $driver_file =~ s/^TYPE=unknown/$rtype/m;
284   $driver_file =~ s/^NAME=/$rname/m;
285   $driver_file =~ s/^NETTYPE=/NETTYPE=$nettype/m;
286   $driver_file =~ s/^HOSTNAME=/HOSTNAME=$prn{'rhost'}/m;
287   $driver_file =~ s/^HOSTPRINTER=/HOSTPRINTER=$prn{'rqueue'}/m;
288   
289   &open_tempfile(INTERFACE,">$irix_iface_path/$prn{'name'}.tmp", 1) ||
290         &error("Failed to open interface for $prn{'name'}."); 
291   &print_tempfile(INTERFACE, $driver_file);
292   &close_tempfile(INTERFACE);  
293 }
294
295
296
297
298 # modify_printer(&details)
299 # Change an existing printer
300 sub modify_printer
301 {
302 local(%prn, $cmd, $out);
303 %prn = %{$_[0]};
304
305 # make the default
306 local $esc = quotemeta($prn{'name'});
307 if ($prn{'default'}) {
308         $out = &backquote_logged("/usr/lib/lpadmin -d$esc 2>&1");
309         if ($?) { &error("Failed to set default : <pre>$out</pre>"); }
310         }
311
312 # enable or disable
313 if ($prn{'enabled'}) { $cmd = "/usr/bin/enable $esc"; }
314 elsif ($prn{'enabled_why'}) {
315         local $wesc = quotemeta($prn{'enabled_why'});
316         $cmd = "/usr/bin/enable $esc ; /usr/bin/disable -r$wesc $esc";
317         }
318 else { $cmd = "/usr/bin/enable $esc ; /usr/bin/disable $esc"; }
319 $out = &backquote_logged("$cmd 2>&1");
320
321 # accepting or rejecting requests
322 if ($prn{'accepting'}) { $cmd = "/usr/lib/accept $esc"; }
323 elsif ($prn{'accepting_why'}) {
324         local $wesc = quotemeta($prn{'accepting_why'});
325         $cmd = "/usr/lib/accept $esc ; /usr/lib/reject -r$wesc $esc";
326         }
327 else { $cmd = "/usr/lib/accept $esc ; /usr/lib/reject $esc"; }
328 $out = &backquote_logged("$cmd 2>&1");
329 }
330
331 # delete_printer(name)
332 # Deletes some existing printer
333 sub delete_printer
334 {
335 local($out, $scheduler);
336 #$scheduler = &sched_running();
337 local $esc = quotemeta($_[0]);
338
339 # delete print jobs
340 $out = &backquote_logged("/usr/bin/cancel -a $esc  2>&1");
341 if ($?) { &error("cancel failed : <pre>$out</pre>"); }
342
343 # call lpadmin
344 $out = &backquote_logged("/usr/lib/lpadmin -x$esc 2>&1");
345 if ($?) { &error("lpadmin failed : <pre>$out</pre>"); }
346 }
347
348 # cancel_job(printer, id)
349 # Cancels some print job
350 sub cancel_job
351 {
352 local($out);
353 local $iesc = quotemeta($_[1]);
354 $out = &backquote_logged("/usr/bin/cancel $iesc 2>&1");
355 if ($?) { &error("cancel failed : <pre>$out</pre>"); }
356 sleep(1);
357 }
358
359 # sched_running()
360 # Returns 1 if running and 0 if not running
361 sub sched_running
362 {
363 local $out = &backquote_command("lpstat -r 2>&1", 1);
364 if ($out =~ /not/) { return 0; }
365 else { return 1; }
366 }
367
368 # start_sched()
369 # Start lpsched
370 sub start_sched
371 {
372 my $cmd = "/usr/lib/lpshut > /dev/null 2>&1;"
373         . "/sbin/killall lpautoenable;"
374         . "rm -f /var/spool/lp/SCHEDLOCK /var/spool/lp/FIFO;"
375         . "/usr/lib/lpsched 2>&1";
376 local $out = &backquote_logged($cmd);
377 if ($?) { &error("failed to start lpsched : <tt>$out</tt>"); }
378 }
379
380 # stop_sched(pid)
381 # Stop the running lpsched process
382 sub stop_sched
383 {
384 local $out = &backquote_logged("/usr/lib/lpshut 2>&1");
385 if ($?) { &error("lpshut failed : <tt>$out</tt>"); }
386 }
387
388 # print_command(printer, file)
389 # Returns the command to print some file on some printer
390 sub print_command
391 {
392 local $esc = quotemeta($_[0]);
393 local $fesc = quotemeta($_[1]);
394 return "lp -d$esc $fesc";
395 }
396
397 # check_print_system()
398 sub check_print_system
399 {
400 &has_command("lpstat") || return &text('irix_ecmd', "<tt>lpstat</tt>");
401 -d $irix_iface_path || return &text('irix_eiface',"<tt>$irix_iface_path</tt>");
402 return undef;
403 }
404
405 @device_files = ("/dev/plp", 
406        "/dev/ttyd1", "/dev/ttyd2",
407                  "/dev/null");
408 @device_names = ("Parallel", 
409                  "Serial 1", "Serial 2",
410                  "Null Device");