📄 linux-lib.pl
字号:
# linux-lib.pl# Functions for printcap-style printer management# list_printers()# Returns a list of known printer namessub list_printers{local($l, @rv);foreach $l (&list_printcap()) { $l->{'name'} =~ /^([^\|]+)/; push(@rv, $1); }return @rv;}sub get_printer{local($l, %prn, @w, @n, $w, %cap, @jobs);foreach $l (&list_printcap()) { @n = split(/\|/, $l->{'name'}); if ($n[0] eq $_[0]) { # found the printer.. get info from printcap $prn{'name'} = $n[0]; if (@n > 2) { $prn{'alias'} = [ @n[1..$#n-1] ]; } if (@n > 1) { $prn{'desc'} = $n[$#n]; } $prn{'iface'} = $l->{'if'}; $prn{'banner'} = !defined($l->{'sh'}); $prn{'dev'} = $l->{'lp'}; $prn{'rhost'} = $l->{'rm'}; $prn{'rqueue'} = $l->{'rp'}; $prn{'msize'} = $l->{'mx#'}; $prn{'comment'} = $l->{'comment'}; # call lpc to get status $out = `lpc status $prn{'name'} 2>&1`; $prn{'accepting'} = ($out =~ /queuing is enabled/); $prn{'enabled'} = ($out =~ /printing is enabled/); return \%prn; } }return undef;}# get_jobs(printer)sub get_jobs{local @jobs;open(LPQ, "lpq -P$_[0] |");while(<LPQ>) { chop; if (/^Rank\s+Owner\s+/) { $doneheader++; } elsif ($doneheader && /^(\S+)\s+(\S+)\s+(\d+)\s+(.*\S)\s+(\d+)\s+(\S+)$/) { local(%job); $job{'id'} = $3; $job{'user'} = $2; $job{'size'} = $5; $job{'file'} = $4; $job{'printing'} = ($1 eq "active"); push(@jobs, \%job); } }close(LPQ);return @jobs;}sub printer_support{return $_[0] !~ /^(why|allow|default|ctype|sysv)$/;}# create_printer(&details)# Create a new printer in /etc/printcapsub create_printer{local(%cap);$cap{'sd'} = "$config{'spool_dir'}/$_[0]->{'name'}";mkdir($cap{'sd'}, 0755);open(CAP, ">> $config{'printcap_file'}");print CAP &make_printcap($_[0], \%cap),"\n";close(CAP);&apply_status($_[0]);}# modify_printer(&details)sub modify_printer{local(@old, $o, $old, @cap);@old = &list_printcap();foreach $o (@old) { $o->{'name'} =~ /^([^\|]+)/; if ($1 eq $_[0]->{'name'}) { # found current details $old = $o; last; } }if (!$old) { &error("Printer '$_[0]->{'name'}' no longer exists"); }open(CAP, $config{'printcap_file'});@cap = <CAP>;close(CAP);splice(@cap, $old->{'line'}, $old->{'eline'} - $old->{'line'} + 1, &make_printcap($_[0], $old)."\n");open(CAP, "> $config{'printcap_file'}");print CAP @cap;close(CAP);&apply_status($_[0]);}# delete_printer(name)sub delete_printer{local(@old, $o, $old, @cap);@old = &list_printcap();foreach $o (@old) { $o->{'name'} =~ /^([^\|]+)/; if ($1 eq $_[0]) { # found current details $old = $o; last; } }if (!$old) { &error("Printer '$_[0]' no longer exists"); }open(CAP, $config{'printcap_file'});@cap = <CAP>;close(CAP);splice(@cap, $old->{'line'}, $old->{'eline'} - $old->{'line'} + 1);open(CAP, "> $config{'printcap_file'}");print CAP @cap;close(CAP);if ($old->{'sd'} eq "$config{'spool_dir'}/$_[0]") { system("rm -rf $old->{'sd'}"); }}# cancel_job(printer, job)# Calls lprm to remove some jobsub cancel_job{local($out);$out = `lprm -P$_[0] $_[1] 2>&1`;if ($?) { &error("lprm failed : $out"); }}# make_printcap(&details, &old)# Updates or creates a printcap linesub make_printcap{local(%prn, %cap, $a, $rv, $c);%prn = %{$_[0]}; %cap = %{$_[1]};$cap{'if'} = $prn{'iface'} ? $prn{'iface'} : undef;$cap{'sh'} = $prn{'banner'} ? undef : "";$cap{'lp'} = $prn{'dev'} ? $prn{'dev'} : undef;$cap{'rm'} = $prn{'rhost'} ? $prn{'rhost'} : undef;$cap{'rp'} = $prn{'rqueue'} ? $prn{'rqueue'} : undef;$cap{'mx#'} = $prn{'msize'} ? $prn{'msize'} : undef;$rv = $prn{'comment'}."\n" if ($prn{'comment'});$rv .= $prn{'name'};foreach $a (@{$prn{'alias'}}) { $rv .= "|$a"; }$rv .= "|$prn{'desc'}" if ($prn{'desc'});foreach $c (keys %cap) { if ($c =~ /^(\S\S)(#?)$/ && defined($cap{$c})) { if ($cap{$c} eq "") { $rv .= ":$c"; } elsif ($2 eq "#") { $rv .= ":$c$cap{$c}"; } else { $rv .= ":$c=$cap{$c}"; } } }$rv .= ":";return $rv;}# list_printcap()# Returns an array of associative arrays containing printcap fieldssub list_printcap{local(@rv, @line, @comment, @eline, @sline, $line, $cont, $lnum, $i);open(CAP, $config{'printcap_file'});$lnum = 0;while($line = <CAP>) { $line =~ s/\s+$//g; # remove trailing spaces/newline if ($line =~ /^(##.*)/) { # special commented line .. keep it $comment[@line] = $line; } else { $line =~ s/^#.*$//g; # remove comments $line =~ s/^\s+//g; # remove leading spaces if ($line =~ /\S/) { local $ncont = ($line =~ s/\\$//g); if ($cont) { $line[$#line] .= $line; $eline[@line - 1] = $lnum; } else { push(@line, $line); $eline[@line - 1] = $sline[@line - 1] = $lnum; } $cont = $ncont; } else { # only keep comments immediately before an entry $comment[@line] = undef; } } $lnum++; }close(CAP);for($i=0; $i<@line; $i++) { local(%cap); @w = split(/:+/, $line[$i]); $cap{'name'} = $w[0]; $cap{'line'} = $sline[$i] - ($comment[$i] ? 1 : 0); $cap{'eline'} = $eline[$i]; $cap{'comment'} = $comment[$i]; foreach $w (@w[1..$#w]) { if ($w =~ /^([A-z0-9]+)=(.*)$/) { $cap{$1} = $2; } elsif ($w =~ /^([A-z0-9]+)#(.*)$/) { $cap{$1."#"} = $2; } elsif ($w =~ /^([A-z0-9]+)$/) { $cap{$w} = ""; } } push(@rv, \%cap); }return @rv;}# apply_status(&details)# Calls lpc to enable or disable a printer.# Restarting lpd doesn't seem to be necessary?sub apply_status{local($out);$out = `lpc status $prn{'name'} 2>&1`;if ($prn{'enabled'} && $out !~ /printing is enabled/) { `lpc up $prn{'name'}`; }elsif (!$prn{'enabled'} && $out =~ /printing is enabled/) { `lpc down $prn{'name'}`; }if ($prn{'accepting'} && $out !~ /queuing is enabled/) { `lpc enable $prn{'name'}`; }elsif (!$prn{'accepting'} && $out =~ /queuing is enabled/) { `lpc disable $prn{'name'}`; }}# sched_running()# Returns the pid if lpsched is running, 0 if not, -1 if cannot be stoppedsub sched_running{@pid = &find_byname("lpd");if (@pid) { return $pid[0]; }return 0;}# start_sched()# Start lpschedsub start_sched{local $out = `lpd 2>&1`;if ($?) { &error("failed to start lpd : <tt>$out</tt>"); }}# stop_sched(pid)# Stop the running lpsched processsub stop_sched{kill('TERM', $_[0]) || &error("Failed to stop lpd : $!");}if (-r "/dev/lp0") { @device_files = ("/dev/lp0", "/dev/lp1", "/dev/ttyS0", "/dev/ttyS1", "/dev/null"); }else { @device_files = ("/dev/lp1", "/dev/lp2", "/dev/ttyS0", "/dev/ttyS1", "/dev/null"); }push(@device_files, "/dev/usblp0") if (-r "/dev/usblp0");@device_names = ("Parallel port 1", "Parallel port 2", "Serial Port 1 (COM1)", "Serial Port 2 (COM2)", "Null Device", "USB printer");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -