Handle hostnames with upper-case letters
[webmin.git] / lpadmin / suse-driver.pl
1 # suse-driver.pl
2 # Functions for APS print filters, as used by SUSE
3
4 @paper_sizes = ( [ 'a4', 'A4' ],
5                  [ 'a4dj', 'A4 inkjet' ],
6                  [ 'a3', 'A3' ],
7                  [ 'letter', 'US Letter' ],
8                  [ 'letterdj', 'US Letter inkjet' ],
9                  [ 'note', 'Note' ],
10                  [ 'legal', 'Legal' ],
11                  [ 'ledger', 'Ledger' ],
12                  [ 'a0', 'A0' ],
13                  [ 'a1', 'A1' ],
14                  [ 'a2', 'A2' ],
15                  [ 'a5', 'A5' ],
16                  [ 'a6', 'A6' ],
17                  [ 'a7', 'A7' ],
18                  [ 'a8', 'A8' ],
19                  [ 'a9', 'A9' ],
20                  [ 'a10', 'A10' ],
21                  [ 'b0', 'B0' ],
22                  [ 'b1', 'B1' ],
23                  [ 'b2', 'B2' ],
24                  [ 'b3', 'B3' ],
25                  [ 'b4', 'B4' ],
26                  [ 'b5', 'B5' ],
27                  [ 'archE', 'archE' ],
28                  [ 'archD', 'archD' ],
29                  [ 'archC', 'archC' ],
30                  [ 'archB', 'archB' ],
31                  [ 'archA', 'archA' ],
32                  [ 'flsa', 'flsa' ],
33                  [ 'flse', 'flse' ],
34                  [ 'halfletter', 'Half Letter' ],
35                  [ '11x17', '11x17' ] );
36 $apsfilter_dir = "/var/lib/apsfilter/bin";
37 $apsfilter_prog = "/var/lib/apsfilter/apsfilter";
38 $apsfilter_config = "/var/lib/apsfilter/template/apsfilterrc.gs_device_name";
39 $apsfilter_base = "/etc/apsfilterrc";
40 $driver_dir = "/etc/gs.upp";
41 $webmin_windows_driver = 1;
42
43 open(DRIVERS, "$module_root_directory/drivers");
44 while(<DRIVERS>) {
45         if (/^(\S+)\s+(.*)/) {
46                 $driver{$1} = $2 if (!$driver{$1});
47                 }
48         }
49 close(DRIVERS);
50 open(STP, "stp");
51 while(<STP>) {
52         if (/^(\S+)\s+(.*)/) {
53                 $stp{$1} = $2 if (!$stp{$1});
54                 }
55         }
56 close(STP);
57 foreach $u (&list_uniprint()) {
58         $u->[1] =~ s/,.*$//;
59         $driver{"$u->[0].upp"} = $u->[1];
60         }
61
62 # is_windows_driver(path, %driver)
63 # Returns a driver structure if some path is a windows driver
64 sub is_windows_driver
65 {
66 return &is_webmin_windows_driver(@_);
67 }
68
69 # is_driver(path, &printer)
70 # Returns a structure containing the details of a driver
71 sub is_driver
72 {
73 if (!$_[0]) {
74         return { 'mode' => 0,
75                  'desc' => "$text{'suse_none'}" };
76         }
77 elsif ($_[0] =~ /$apsfilter_dir\/([^-]+)-([^-]+)-([^-]+)-([^-]+)-([^-]+)$/) {
78         # Looks like an APS driver from suse (old style)
79         local $rv =  {  'mode' => 1,
80                         'device' => $1,
81                         'paper' => $2,
82                         'method' => $3,
83                         'colour' => $4,
84                         'res' => $5 };
85         local $desc = $driver{$rv->{'device'}} ? $driver{$rv->{'device'}} :
86                       $rv->{'device'} =~ /^PS_/ ? "Postscript"
87                                                 : $rv->{'device'};
88         $rv->{'desc'} = $rv->{'res'} ? "$desc ($rv->{'res'} DPI)" : $desc;
89         return $rv;
90         }
91 #elsif ($_[0] =~ /$apsfilter_dir\/([^-]+)--([^-]+)-([^-]+)$/ &&
92 #       -r "$driver_dir/$1") {
93 #       # Looks like a new-style APS suse driver
94 #       local $rv = { 'mode' => 3,
95 #                     'method' => $2 };
96 #       open(GS, "$driver_dir/$1");
97 #       while(<GS>) {
98 #               s/\r|\n//g;
99 #               if (/^-sDEVICE=(\S+)/) { $rv->{'device'} = $1; }
100 #               elsif (/^-sPAPERSIZE=(\S+)/) { $rv->{'paper'} = $1; }
101 #               elsif (/^-sCOLOR=(\S+)/) { $rv->{'colour'} = $1; }
102 #               elsif (/^-r(\S+)/) { $rv->{'res'} = $1; }
103 #               elsif (/^-supModel="(.*)"/) { $rv->{'desc'} = $1; }
104 #               elsif (/^-sModel="(.*)"/) { $rv->{'model'} = $1; }
105 #               elsif (/^\@(\S+\.upp)/) { $rv->{'device'} = $1; }
106 #               else { push(@{$rv->{'extra'}}, $_); }
107 #               }
108 #       close(GS);
109 #       return $rv;
110 #       }
111 elsif ($_[0] =~ /$apsfilter_dir\/([^-]+)-([^-]+)-([^-]+)$/) {
112         # Null APS driver?
113         return { 'mode' => 0,
114                  'desc' => 'None' };
115         }
116 else {
117         # Some other kind of driver
118         return { 'mode' => 2,
119                  'file' => $_[0],
120                  'desc' => $_[0] };
121         }
122 }
123
124 # create_windows_driver(&printer, &driver)
125 # Creates a new windows printer driver
126 sub create_windows_driver
127 {
128 return &create_webmin_windows_driver(@_);
129 }
130
131 # create_driver(&printer, &driver)
132 # Creates a new local printer driver and returns the path
133 sub create_driver
134 {
135 local ($prn, $drv) = @_;
136 if ($drv->{'mode'} == 0) {
137         return undef;
138         }
139 elsif ($drv->{'mode'} == 2) {
140         return $drv->{'file'};
141         }
142 else {
143         local $device;
144         if ($drv->{'device'} eq 'ps') {
145                 $device = "PS_$drv->{'res'}dpi";
146                 }
147         else {
148                 $device = $drv->{'device'};
149                 }
150         local $aps = "$apsfilter_dir/$device-$drv->{'paper'}-".
151                      "$drv->{'method'}-$drv->{'colour'}-$drv->{'res'}";
152         &lock_file($aps);
153         symlink($apsfilter_prog, $aps);
154         &unlock_file($aps);
155         if (!-r "$apsfilter_base.$device") {
156                 &lock_file("$apsfilter_base.$device");
157                 local $conf = &read_file_contents($apsfilter_config);
158                 $conf =~ s/<gs_device_name>/$device/g;
159                 &open_tempfile(CONF, ">$apsfilter_base.$device");
160                 &print_tempfile(CONF, $conf);
161                 &close_tempfile(CONF);
162                 &unlock_file("$apsfilter_base.$device");
163                 }
164         return $aps;
165         }
166 }
167
168 # delete_driver(name)
169 sub delete_driver
170 {
171 }
172
173 # driver_input(&printer, &driver)
174 sub driver_input
175 {
176 local ($prn, $drv) = @_;
177 local ($found, $d);
178
179 printf "<tr> <td><input type=radio name=mode value=0 %s> %s</td>\n",
180         $drv->{'mode'} == 0 ? "checked" : "", $text{'suse_none'};
181 print "<td>($text{'suse_nonemsg'})</td> </tr>\n";
182
183 printf "<tr> <td><input type=radio name=mode value=2 %s> %s</td>\n",
184         $drv->{'mode'} == 2 ? "checked" : "", $text{'suse_prog'};
185 printf "<td><input name=iface value=\"%s\" size=35></td> </tr>\n",
186         $drv->{'mode'} == 2 ? $drv->{'file'} : "";
187
188 if ($drv->{'mode'} == 2 || 1) {
189         # Show input for old-style suse printer
190         printf "<tr> <td valign=top><input type=radio name=mode value=1 %s>\n",
191                 $drv->{'mode'} == 1 ? "checked" : "";
192         print "$text{'suse_driver'}</td> <td><table width=100%>";
193
194         print "<tr> <td valign=top><b>$text{'suse_printer'}</b></td>\n";
195         print "<td colspan=3><select size=10 name=device>\n";
196         printf "<option value=ps %s>Postscript\n",
197                 $drv->{'device'} =~ /^PS_/ ? 'selected' : '';
198         $found++ if ($drv->{'device'} =~ /^PS_/);
199         foreach $d (&list_uniprint()) {
200                 local $u = "$d->[0].upp";
201                 printf "<option value=%s %s>%s\n",
202                         $u, $drv->{'device'} eq $u ? 'selected' : '', $d->[1];
203                 $found++ if ($drv->{'device'} eq $u);
204                 }
205         local $out = &backquote_command("$config{'gs_path'} -help 2>&1", 1);
206         $out =~ /Available devices:\n((\s+.*\n)+)/i;
207         foreach $d (split(/\s+/, $1)) {
208                 if ($driver{$d}) {
209                         printf "<option value=%s %s>%s\n",
210                                 $d, $drv->{'device'} eq $d ? 'selected' : '',
211                                 $driver{$d};
212                         $found++ if ($drv->{'device'} eq $d);
213                         }
214                 }
215         print "<option selected value=$drv->{'device'}>$drv->{'device'}\n"
216                 if (!$found && $drv->{'device'});
217         print "</select></td> </tr>\n";
218
219         print "<tr> <td><b>$text{'suse_res'}</b></td>\n";
220         print "<td><input name=res size=8 value='$drv->{'res'}'></td>\n";
221
222         print "<td><b>$text{'suse_colour'}</b></td>\n";
223         printf "<td><input name=colour type=radio value=color %s> %s\n",
224                 $drv->{'colour'} eq 'mono' ? '' : 'checked', $text{'yes'};
225         printf "<input name=colour type=radio value=color %s> %s</td> </tr>\n",
226                 $drv->{'colour'} eq 'mono' ? 'checked' : '', $text{'no'};
227
228         print "<tr> <td><b>$text{'suse_paper'}</b></td>\n";
229         print "<td><select name=paper>\n";
230         foreach $p (@paper_sizes) {
231                 printf "<option value=%s %s>%s\n",
232                         $p->[0], $drv->{'paper'} eq $p->[0] ? 'selected' : '',
233                         $p->[1];
234                 }
235         print "</select></td>\n";
236
237         print "<td><b>$text{'suse_method'}</b></td>\n";
238         printf "<td><input type=radio name=method value=auto %s> %s\n",
239                 $drv->{'method'} eq 'ascii' ? '' : 'checked',
240                 $text{'suse_auto'};
241         printf "<input type=radio name=method value=ascii %s> %s</td> </tr>\n",
242                 $drv->{'method'} eq 'ascii' ? 'checked' : '',
243                 $text{'suse_ascii'};
244
245         print "</table></td> </tr>\n";
246         }
247 else {
248         # Show input for new-style suse printer (NOT DONE YET!)
249         printf "<tr> <td valign=top><input type=radio name=mode value=3 %s>\n",
250                 $drv->{'mode'} == 3 ? "checked" : "";
251         print "$text{'suse_yast2'}</td> <td><table width=100%>";
252
253         print "<tr> <td valign=top><b>$text{'suse_printer'}</b></td>\n";
254         print "<td colspan=3><select size=10 name=device>\n";
255         printf "<option value=ps %s>Postscript\n",
256                 $drv->{'device'} eq 'PS' ? 'selected' : '';
257         $found++ if ($drv->{'device'} eq 'PS');
258         local $out = &backquote_command("$config{'gs_path'} -help 2>&1", 1);
259         $out =~ /Available devices:\n((\s+.*\n)+)/i;
260         foreach $d (split(/\s+/, $1)) {
261                 if ($d ne 'stp' && $driver{$d}) {
262                         printf "<option value=%s %s>%s\n",
263                                 $d, $drv->{'device'} eq $d ? 'selected' : '',
264                                 $driver{$d};
265                         $found++ if ($drv->{'device'} eq $d);
266                         }
267                 }
268         foreach $d (&list_uniprint()) {
269                 local $u = "$d->[0].upp";
270                 printf "<option value=%s %s>%s\n",
271                         $u, $drv->{'device'} eq $u ? 'selected' : '', $d->[1];
272                 $found++ if ($drv->{'device'} eq $u);
273                 }
274         foreach $s (sort { $a cmp $b } keys %stp) {
275                 printf "<option value=%s.stp %s>%s\n",
276                         $s, $drv->{'device'} eq 'stp' &&
277                             $drv->{'model'} eq $s ? 'selected' : '', $stp{$s};
278                 $found++ if ($drv->{'device'} eq 'stp' &&
279                              $drv->{'model'} eq $s);
280                 }
281         print "<option selected value=$drv->{'device'}>$drv->{'device'}\n"
282                 if (!$found && $drv->{'device'});
283         print "</select></td> </tr>\n";
284
285         print "<tr> <td><b>$text{'suse_colour'}</b></td>\n";
286         printf "<td><input name=colour type=radio value=color %s> %s\n",
287                 $drv->{'colour'} eq 'mono' ? '' : 'checked', $text{'yes'};
288         printf "<input name=colour type=radio value=color %s> %s</td>\n",
289                 $drv->{'colour'} eq 'mono' ? 'checked' : '', $text{'no'};
290
291         print "<td><b>$text{'suse_paper'}</b></td>\n";
292         print "<td><select name=paper>\n";
293         foreach $p (@paper_sizes) {
294                 printf "<option value=%s %s>%s\n",
295                         $p->[0], $drv->{'paper'} eq $p->[0] ? 'selected' : '',
296                         $p->[1];
297                 }
298         print "</select></td> </tr>\n";
299
300         print "<tr> <td><b>$text{'suse_res'}</b></td>\n";
301         printf "<td><input type=radio name=res_def value=1 %s> %s\n",
302                 $drv->{'res'} ? '' : 'checked', $text{'suse_auto'};
303         printf "<input type=radio name=res_def value=0 %s>\n",
304                 $drv->{'res'} ? 'checked' : '';
305         print "<input name=res size=8 value='$drv->{'res'}'></td>\n";
306
307         print "<td><b>$text{'suse_method'}</b></td>\n";
308         print "<td><select name=method>\n";
309         foreach $m ('auto', 'ascii', 'raw') {
310                 printf "<option value=%s %s>%s\n",
311                         $m, $drv->{'method'} eq $m ? 'selected' : '',
312                         $text{"suse_$m"};
313                 }
314         print "</select></td> </tr>\n";
315
316         print "<tr> <td><b>$text{'suse_extra'}</b></td>\n";
317         print "<td colspan=3><input name=extra size=50 value='",
318               join(" ", @{$drv->{'extra'}}),"'></td> </tr>\n";
319
320         print "</table></td> </tr>\n";
321         }
322 }
323
324 # parse_driver()
325 # Parse driver selection from %in and return a driver structure
326 sub parse_driver
327 {
328 if ($in{'mode'} == 0) {
329         return { 'mode' => 0 };
330         }
331 elsif ($in{'mode'} == 2) {
332         (-x $in{'iface'}) || &error(&text('suse_eprog', $in{'iface'}));
333         return { 'mode' => 2,
334                  'file' => $in{'iface'} };
335         }
336 elsif ($in{'mode'} == 3) {
337         # New suse printer (NOT DONE YET!)
338         # All the other odd files created by yast2 need to be supported
339         $in{'device'} || &error($text{'suse_edriver'});
340         $in{'res_def'} || $in{'res'} =~ /^\d+$/ ||
341                 $in{'res'} =~ /^\d+x\d+$/ || &error($text{'suse_eres'});
342         }
343 elsif ($in{'mode'} == 1) {
344         # Old-style suse printer
345         $in{'device'} || &error($text{'suse_edriver'});
346         $in{'res'} =~ /^\d+$/ || &error(&text('suse_eres', $in{'res'}));
347         return { 'mode' => 1,
348                  'device' => $in{'device'},
349                  'paper' => $in{'paper'},
350                  'method' => $in{'method'},
351                  'colour' => $in{'colour'},
352                  'res' => $in{'res'} };
353         }
354 }
355
356 1;
357