2 # Functions for printcap-style printer management
5 # Returns a list of known printer names
9 foreach $l (&list_printcap()) {
10 $l->{'name'} =~ /^([^\|]+)/;
16 # get_printer(name, [nostatus])
19 local($l, %prn, @w, @n, $w, %cap, @jobs);
20 foreach $l (&list_printcap()) {
21 @n = split(/\|/, $l->{'name'});
23 # found the printer.. get info from printcap
25 if (@n > 2) { $prn{'alias'} = [ @n[1..$#n-1] ]; }
26 if (@n > 1) { $prn{'desc'} = $n[$#n]; }
27 $prn{'iface'} = $l->{'if'};
28 $prn{'banner'} = !defined($l->{'sh'});
29 $prn{'dev'} = $l->{'lp'};
30 $prn{'rhost'} = $l->{'rm'};
31 $prn{'rqueue'} = $l->{'rp'};
32 $prn{'msize'} = $l->{'mx'};
33 $prn{'ro'} = $l->{'file'} eq $config{'ro_printcap_file'};
36 # call lpc to get status
37 local $esc = quotemeta($prn{'name'});
38 $out = &backquote_command("lpc status $esc 2>&1", 1);
39 $prn{'accepting'} = ($out =~ /queuing is enabled/);
40 $prn{'enabled'} = ($out =~ /printing is enabled/);
52 local $esc = quotemeta($_[0]);
53 open(LPQ, "lpq -P$esc |");
56 if (/^Rank\s+Owner\s+/) { $doneheader++; }
57 elsif ($doneheader && /^(\S+)\s+(\S+)\s+(\d+)\s+(.*\S)\s+(\d+)\s+(\S+)$/) {
63 $job{'printing'} = ($1 eq "active");
73 return $_[0] !~ /^(why|allow|default|ctype|riface|sysv|direct|rnoqueue|ipp)$/;
77 # create_printer(&details)
78 # Create a new printer in /etc/printcap
82 $cap{'sd'} = "$config{'spool_dir'}/$_[0]->{'name'}";
83 &lock_file($cap{'sd'});
84 mkdir($cap{'sd'}, 0755);
85 &unlock_file($cap{'sd'});
87 &lock_file($config{'printcap_file'});
88 local $lref = &read_file_lines($config{'printcap_file'});
89 push(@$lref, &make_printcap($_[0], \%cap));
90 &flush_file_lines($config{'printcap_file'});
91 &unlock_file($config{'printcap_file'});
95 # modify_printer(&details)
98 local(@old, $o, $old, @cap);
99 &lock_file($config{'printcap_file'});
100 @old = &list_printcap();
102 $o->{'name'} =~ /^([^\|]+)/;
103 if ($1 eq $_[0]->{'name'}) {
104 # found current details
109 if (!$old) { &error("Printer '$_[0]->{'name'}' no longer exists"); }
110 local $lref = &read_file_lines($config{'printcap_file'});
111 splice(@$lref, $old->{'line'}, $old->{'eline'} - $old->{'line'} + 1,
112 &make_printcap($_[0], $old));
113 &flush_file_lines($config{'printcap_file'});
114 &unlock_file($config{'printcap_file'});
115 &apply_status($_[0]);
118 # delete_printer(name)
121 local(@old, $o, $old, @cap);
122 &lock_file($config{'printcap_file'});
123 @old = &list_printcap();
125 $o->{'name'} =~ /^([^\|]+)/;
127 # found current details
132 if (!$old) { &error("Printer '$_[0]' no longer exists"); }
133 local $lref = &read_file_lines($config{'printcap_file'});
134 splice(@$lref, $old->{'line'}, $old->{'eline'} - $old->{'line'} + 1);
135 &flush_file_lines($config{'printcap_file'});
136 &unlock_file($config{'printcap_file'});
139 # cancel_job(printer, job)
140 # Calls lprm to remove some job
144 local $esc = quotemeta($_[0]);
145 local $iesc = quotemeta($_[1]);
146 $out = &backquote_logged("lprm -P$esc $iesc 2>&1");
147 if ($?) { &error("lprm failed : $out"); }
150 # make_printcap(&details, &old)
151 # Updates or creates a printcap line
154 local(%prn, %cap, $a, $rv, $c);
155 %prn = %{$_[0]}; %cap = %{$_[1]};
156 $cap{'if'} = $prn{'iface'} ? $prn{'iface'} : undef;
157 $cap{'sh'} = $prn{'banner'} ? undef : "";
158 $cap{'lp'} = $prn{'dev'} ? $prn{'dev'} : undef;
159 $cap{'rm'} = $prn{'rhost'} ? $prn{'rhost'} : undef;
160 $cap{'rp'} = $prn{'rqueue'} ? $prn{'rqueue'} : undef;
161 $cap{'mx'} = defined($prn{'msize'}) ? $prn{'msize'} : undef;
163 foreach $a (@{$prn{'alias'}}) { $rv .= "|$a"; }
164 $rv .= "|$prn{'desc'}";
165 foreach $c (keys %cap) {
166 if (length($c) == 2 && defined($cap{$c})) {
167 if ($cap{$c} eq "") { $rv .= ":$c"; }
168 elsif ($cap{$c} =~ /^\d+$/) { $rv .= ":$c#$cap{$c}"; }
169 else { $rv .= ":$c=$cap{$c}"; }
177 # Returns an array of associative arrays containing printcap fields
180 return @list_printcap_cache if (scalar(@list_printcap_cache));
181 local(@rv, @line, $line, $cont, $lnum, $i, %done, $capfile);
182 foreach $capfile ($config{'printcap_file'}, $config{'ro_printcap_file'}) {
183 next if (!$capfile || $done{$capfile}++);
186 while($line = <CAP>) {
187 $line =~ s/^#.*$//g; # remove comments
188 $line =~ s/\s+$//g; # remove trailing spaces
189 $line =~ s/^\s+//g; # remove leading spaces
191 $ncont = ($line =~ s/\\$//g);
193 $line[$#line] .= $line;
194 $eline[@line - 1] = $lnum;
198 $eline[@line - 1] = $sline[@line - 1] = $lnum;
205 for($i=0; $i<@line; $i++) {
207 @w = split(/:+/, $line[$i]);
208 $cap{'name'} = $w[0];
209 $cap{'line'} = $sline[$i];
210 $cap{'eline'} = $eline[$i];
211 $cap{'file'} = $capfile;
212 foreach $w (@w[1..$#w]) {
213 if ($w =~ /^([A-z0-9]+)[=#](.*)$/) { $cap{$1} = $2; }
214 elsif ($w =~ /^([A-z0-9]+)$/) { $cap{$w} = ""; }
219 @list_printcap_cache = @rv;
223 # apply_status(&details)
224 # Calls lpc to enable or disable a printer.
225 # Restarting lpd doesn't seem to be necessary?
229 local $esc = quotemeta($_[0]->{'name'});
230 $out = &backquote_command("lpc status $esc 2>&1", 1);
231 if ($_[0]->{'enabled'} && $out !~ /printing is enabled/)
232 { &backquote_logged("lpc up $esc"); }
233 elsif (!$_[0]->{'enabled'} && $out =~ /printing is enabled/)
234 { &backquote_logged("lpc down $esc"); }
235 if ($_[0]->{'accepting'} && $out !~ /queuing is enabled/)
236 { &backquote_logged("lpc enable $esc"); }
237 elsif (!$_[0]->{'accepting'} && $out =~ /queuing is enabled/)
238 { &backquote_logged("lpc disable $esc"); }
242 # Returns the pid if lpsched is running, 0 if not, -1 if cannot be stopped
245 @pid = &find_byname("lpd");
246 if (@pid) { return $pid[0]; }
254 local $out = &backquote_logged("lpd 2>&1");
255 if ($?) { &error("failed to start lpd : <tt>$out</tt>"); }
259 # Stop the running lpsched process
262 local @pid = &find_byname("lpd");
263 &kill_logged('TERM', @pid) || &error("Failed to stop lpd : $!");
266 # print_command(printer, file)
267 # Returns the command to print some file on some printer
270 local $esc = quotemeta($_[0]);
271 local $fesc = quotemeta($_[1]);
272 return "lpr -P$esc $fesc";
275 # check_print_system()
276 sub check_print_system
278 &has_command("lpr") || return &text('freebsd_ecmd', "<tt>lpr</tt>");
279 -d $config{'spool_dir'} || return &text('freebsd_espool', "<tt>$config{'spool_dir'}</tt>");
283 if ($gconfig{'os_type'} eq 'openbsd') {
284 @device_files = ("/dev/lpt0", "/dev/cua00", "/dev/cua01");
287 @device_files = ("/dev/lpt0", "/dev/cuaa0", "/dev/cuaa1");
289 @device_names = ($text{'freebsd_paralel'}, &text('freebsd_serial', "1"),
290 &text('freebsd_serial', "2"));