Handle hostnames with upper-case letters
[webmin.git] / lpadmin / unixware-lib.pl
1 # unixware-lib.pl
2 # Functions for UnixWare style printer management
3
4 $default_interface = "/usr/lib/lp/model/standard";
5
6 # list_printers()
7 # Returns an array of known printer names
8 sub list_printers
9 {
10 local(@rv, $_);
11 open(STAT, "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, $avl, $con, $sys, %prn, @jobs, $_, $out);
24 local $esc = quotemeta($_[0]);
25 $out = `lpstat -l -p $esc`;
26 if ($out =~ /^printer\s+(\S+)\s*(.*)\s+(enabled|disabled)\s+since\s+([^\.]*)\.\s+(.*)\.\n([\000-\377]*)$/) {
27         # printer exists
28         $prn{'name'} = $1;
29         $prn{'enabled'} = $3 eq "enabled";
30         $body = $6;
31         }
32 elsif ($out =~ /^printer\s+(\S+)\s+waiting for auto-retry.\s+(\S+)\.\n([\000-\377]*)$/) {
33         # printer has some problem
34         $prn{'name'} = $1;
35         $prn{'enabled'} = 1;
36         $body = $3;
37         }
38 else {
39         # no printer found
40         return undef;
41         }
42 if (!$prn{'enabled'} && $body =~ /^\s+(.*)/) {
43         $prn{'enabled_why'} = $1 eq "unknown reason" ? "" : $1;
44         }
45 if ($body =~ /Description: (.*)/) { $prn{'desc'} = $1; }
46 if ($body =~ /Printer types: (.*)/) { $prn{'ptype'} = $1; }
47 if ($body =~ /Interface: (.*)/) { $prn{'iface'} = $1; }
48 if ($body =~ /Banner not required/) { $prn{'banner'} = 0; }
49 else { $prn{'banner'} = 1; }
50 if ($body =~ /Content types: (.*)/) { $prn{'ctype'} = [ split(/[ ,]+/, $1) ]; }
51 if ($body =~ /Users (allowed|denied):\n((\s+\S+\n)+)/) {
52         local(@l);
53         @l = grep { $_ } split(/\s+/, $2);
54         if ($1 eq "allowed") {
55                 if ($l[0] eq "(all)") { $prn{'allow_all'} = 1; }
56                 elsif ($l[0] eq "(none)") { $prn{'deny_all'} = 1; }
57                 else { $prn{'allow'} = \@l; }
58                 }
59         else { $prn{'deny'} = \@l; }
60         }
61
62 if (!$_[1]) {
63         # request availability
64         $avl = `lpstat -a $esc 2>&1`;
65         if ($avl =~ /^\S+\s+not accepting.*\n\s+(.*)/) {
66                 $prn{'accepting'} = 0;
67                 $prn{'accepting_why'} = $1;
68                 if ($prn{'accepting_why'} eq "unknown reason") {
69                         $prn{'accepting_why'} = "";
70                         }
71                 }
72         else { $prn{'accepting'} = 1; }
73         }
74
75 # request connection
76 $con = `lpstat -v $esc 2>&1`;
77 if ($con =~ /^device for \S+:\s+(\S+)/) { $prn{'dev'} = $1; }
78 elsif ($con =~ /^system for \S+:\s+(\S+)\s+\(as printer (\S+)\)/) {
79         $prn{'rhost'} = $1;
80         $prn{'rqueue'} = $2;
81         $sys = `lpsystem -l $prn{'rhost'} 2>&1`;
82         $sys =~ /Type:\s+(\S+)/; $prn{'rtype'} = $1;
83         }
84
85 # Check if this is the default printer
86 `lpstat -d 2>&1` =~ /destination: (\S+)/;
87 if ($1 eq $prn{'name'}) { $prn{'default'} = 1; }
88
89 return \%prn;
90 }
91
92 sub get_jobs
93 {
94 local @jobs;
95
96 # Get used lang
97 local $lang = $gconfig{'lang'};
98
99 # Added 'env LANG=$lang'
100 local $esc = quotemeta($_[0]);
101 open(STAT, "env LANG=$lang lpstat -o $esc |");
102 while(<STAT>) {
103 # original line which does not work
104 #       if (/^(\S+-\d+)\s+(\S+)\s+(\d+)\s+(\S+ \d+ \d+:\d+)\s+(.*)/) {
105 #
106
107 # lang=es
108   if ( $lang eq 'es' ) {
109         if (/^(\S+-\d+)\s+(\S+)\s+(\d+)\s+(\S+ \d+ \S+ \S+ \d+ \d+:\d+:\d+)\s+(.*)/) {
110                 local(%job);
111                 $job{'id'} = $1;
112                 $job{'user'} = $2;
113                 $job{'size'} = $3;
114                 $job{'when'} = $4;
115                 $job{'printing'} = ($5 =~ /^en /);
116                 push(@jobs, \%job);
117         }
118   }
119 # lang=C (us)
120   elsif ( $lang eq 'us' ) {
121         if (/^(\S+-\d+)\s+(\S+)\s+(\d+)\s+(\S+ \S+ \d+ \d+:\d+:\d+ \S+ \d+)\s+(.*)/) {
122                 local(%job);
123                 $job{'id'} = $1;
124                 $job{'user'} = $2;
125                 $job{'size'} = $3;
126                 $job{'when'} = $4;
127                 $job{'printing'} = ($5 =~ /^on /);
128                 push(@jobs, \%job);
129         }
130   }
131 # short string (any language)
132   elsif (/^(\S+-\d+)\s+(\S+)\s+(\d+)\s+\s+(.*)/) {
133                 local(%job);
134                 $job{'id'} = $1;
135                 $job{'user'} = $2;
136                 $job{'size'} = $3;
137                 $job{'when'} = $4;
138                 $job{'printing'} = ($5 =~ /^on /);
139                 push(@jobs, \%job);
140                 }
141   }
142 close(STAT);
143 return @jobs;
144 }
145
146 # printer_support(option)
147 sub printer_support
148 {
149 return $_[0] !~ /^(msize|alias|riface|direct|rnoqueue|ipp)$/;
150 }
151
152 # list_classes()
153 # Returns an associative array of print classes
154 sub list_classes
155 {
156 local($stat, %rv);
157 $stat = `lpstat -c 2>&1`;
158 while($stat =~ /^members of class (\S+):\n((\s+\S+\n)+)([\000-\377]*)$/) {
159         $stat = $4;
160         $rv{$1} = [ grep { $_ ne "" } split(/\s+/, $2) ];
161         }
162 return \%rv;
163 }
164
165 # create_printer(&details)
166 # Create a new printer
167 sub create_printer
168 {
169 &modify_printer($_[0]);
170 }
171
172 # modify_printer(&details)
173 # Change an existing printer
174 sub modify_printer
175 {
176 local(%prn, $cmd, $out);
177 %prn = %{$_[0]};
178
179 # call lpsystem if needed
180 local $tesc = quotemeta($prn{'rtype'});
181 local $resc = quotemeta($prn{'rhost'});
182 local $qesc = quotemeta($prn{'rqueue'});
183 if ($prn{'rhost'}) {
184         $out = &backquote_logged("lpsystem -t $tesc $resc 2>&1");
185         if ($?) { &error("lpsystem failed : <pre>$out</pre>"); }
186         }
187
188 # call lpadmin
189 local $esc = quotemeta($prn{'name'});
190 local $desc = quotemeta($prn{'desc'}) || "''";
191 $cmd = "lpadmin -p $esc -D $desc";
192 if ($prn{'allow_all'}) { $cmd .= " -u allow:all"; }
193 elsif ($prn{'deny_all'}) { $cmd .= " -u deny:all"; }
194 elsif ($prn{'allow'}) {
195         &system_logged("lpadmin -p $esc -u deny:all >/dev/null 2>&1");
196         $cmd .= " -u allow:".join(',', map { quotemeta($_) } @{$prn{'allow'}});
197         }
198 elsif ($prn{'deny'}) {
199         &system_logged("lpadmin -p $esc -u allow:all >/dev/null 2>&1");
200         $cmd .= " -u deny:".join(',', map { quotemeta($_) } @{$prn{'deny'}});
201         }
202 if ($prn{'dev'}) {
203         $cmd .= " -v $prn{'dev'}";
204         $cmd .= " -i \"$prn{'iface'}\"";
205         if ($prn{'banner'}) { $cmd .= " -o banner"; }
206         else { $cmd .= " -o nobanner"; }
207         }
208 else { $cmd .= " -s $resc!$qesc"; }
209 @ctype = @{$prn{'ctype'}};
210 if (@ctype) { $cmd .= " -I ".join(',' , @ctype); }
211 $out = &backquote_logged("$cmd 2>&1");
212 if ($?) { &error("lpadmin failed : <pre>$out</pre>"); }
213
214 # make the default
215 if ($prn{'default'}) {
216         $out = &backquote_logged("lpadmin -d $esc 2>&1");
217         if ($?) { &error("Failed to set default : <pre>$out</pre>"); }
218         }
219
220 # enable or disable
221 if ($prn{'enabled'}) { $cmd = "enable $esc"; }
222 elsif ($prn{'enabled_why'}) {
223         local $wesc = quotemeta($prn{'enabled_why'});
224         $cmd = "enable $esc ; disable -r $wesc $esc";
225         }
226 else { $cmd = "enable $esc ; disable $esc"; }
227 $out = &backquote_logged("$cmd 2>&1");
228
229 # accepting or rejecting requests
230 if ($prn{'accepting'}) { $cmd = "accept $esc"; }
231 elsif ($prn{'accepting_why'}) {
232         local $wesc = quotemeta($prn{'accepting_why'});
233         $cmd = "accept $esc ; reject -r $wesc $esc";
234         }
235 else { $cmd = "accept $esc ; reject $esc"; }
236 $out = &backquote_logged("$cmd 2>&1");
237 }
238
239 # delete_printer(name)
240 # Deletes some existing printer
241 sub delete_printer
242 {
243 local($out);
244 local $esc = quotemeta($_[0]);
245 $out = &backquote_logged("lpadmin -x $esc 2>&1");
246 if ($?) { &error("lpadmin failed : <pre>$out</pre>"); }
247 }
248
249 # cancel_job(printer, id)
250 # Cancels some print job
251 sub cancel_job
252 {
253 local($out);
254 local $iesc = quotemeta($_[1]);
255 $out = &backquote_logged("cancel $iesc 2>&1");
256 if ($?) { &error("cancel failed : <pre>$out</pre>"); }
257 sleep(1);
258 }
259
260 # sched_running()
261 # Returns the pid if lpsched is running, 0 if not, -1 if cannot be stopped
262 sub sched_running
263 {
264 #@pid = &find_byname("lpsched");
265 #if (@pid) { return $pid[0]; }
266 #return 0;
267 return -1;
268 }
269
270 # start_sched()
271 # Start lpsched
272 sub start_sched
273 {
274 local $out = &backquote_logged("/usr/lib/lp/lpsched 2>&1");
275 if ($?) { &error("failed to start lpsched : <tt>$out</tt>"); }
276 }
277
278 # stop_sched(pid)
279 # Stop the running lpsched process
280 sub stop_sched
281 {
282 local $out = &backquote_logged("lpshut 2>&1");
283 if ($?) { &error("lpshut failed : <tt>$out</tt>"); }
284 }
285
286 # print_command(printer, file)
287 # Returns the command to print some file on some printer
288 sub print_command
289 {
290 local $esc = quotemeta($_[0]);
291 local $fesc = quotemeta($_[1]);
292 return "lp -d $esc $fesc";
293 }
294
295 # check_print_system()
296 sub check_print_system
297 {
298 &has_command("lpstat") || return &text('unixware_ecmd', "<tt>lpstat</tt>");
299 &has_command("/usr/lib/lp/lpsched") || return &text('unixware_ecmd', "<tt>lpsched</tt>");
300 return undef;
301 }
302
303 @device_files = ("/dev/lp0", "/dev/lp1", "/dev/lp2",
304                  "/dev/tty1a", "/dev/tty2a", "/dev/null");
305 @device_names = (&text('unixware_paralel', "0"), &text('unixware_paralel', "1"),
306                  &text('unixware_paralel', "2"), &text('unixware_serial', "A"),
307                  &text('unixware_serial', "B"), $text{'unixware_null'});
308