|
Per condividere una stampante su una macchina Windows, è necessario:
/etc/printcap
che
corrisponda alla struttura delle directory locali (per le
directory di spool, ecc.)
nenscript
, o qualcosa di equivalente. nenscript
è un
convertitore Postscript generalmente installato in /usr/bin
.
La successiva configurazione di /etc/printcap
è valida per una
stampante HP 5MP su un host Windows NT. Le linee hanno il
seguente significato:
commento
dispositivo da aprire per output
directory di spool della stampante sulla macchina locale
file per registrare le transazioni
massima grandezza per un file (zero significa nessun limite)
nome del filtro di output (script)
Per maggiori informazioni consultare il Printing HOWTO o le pagine del manuale per la voce printcap.
# /etc/printcap
#
# //zimmerman/oreilly via smbprint
#
lp:\
:cm=HP 5MP Postscript OReilly on zimmerman:\
:lp=/dev/lp1:\
:sd=/var/spool/lpd/lp:\
:af=/var/spool/lpd/lp/acct:\
:mx#0:\
:if=/usr/bin/smbprint:
È necessario accertarsi che le directory di spool e per la
registrazione delle transazioni (log) esistano e siano scrivibili.
Assicurarsi che la linea 'if' contenga un percorso corretto allo script
di smbprint (
dato oltre) ed inoltre che il
dispositivo puntato sia corretto (il file speciale /dev
).
Di seguito lo script smbprint. Di solito è installato in
/usr/bin
ed è attribuibile, per quanto ne so, ad Andrew Tridgell,
la persona che ha creato Samba. Viene fornito con la distribuzione in
formato sorgente di Samba ma è riportato, essendo assente in certe
distribuzioni in formato binario.
Potrebbe essere utile studiarlo attentamente, alcune piccole modifiche hanno dimostrato essere di enorme utilità.
#!/bin/sh -x
# Questo script è un filtro di input per la stampa via printcap da una
# macchina UNIX. Usa il programma smbclient per stampare il file sul
# server e servizio specificati usando il protocollo smb.
# Per esempio è possibile avere una linea del printcap del tipo:
#
# smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint
#
# Che dovrebbe creare una stampante UNIX chiamata "smb" che stamperà
# attraverso questo script. E' necessario creare la directory di spool
# /usr/spool/smb con permessi, proprietario e gruppo appropriati per il
# sistema.
# Assegnare i valori che seguono in modo da accordarsi al server e
# e servizio su cui si desidera stampare. In questo esempio si suppone
# di avere un PC con WfWg chiamato "lapland" che ha una stampante
# esportata chiamata "printer" senza password.
#
# Script modificato da hamiltom@ecnz.co.nz (Michael Hamilton)
# in modo da poter leggere server, servizio e password dal file
# /usr/var/spool/lpd/PRINTNAME/.config
#
# Affinché tutto funzioni è necessario che esista una linea in
# /etc/printcap che includa il file di accounting (af=...):
#
# cdcolour:\
# :cm=CD IBM Colorjet on 6th:\
# :sd=/var/spool/lpd/cdcolour:\
# :af=/var/spool/lpd/cdcolour/acct:\
# :if=/usr/local/etc/smbprint:\
# :mx=0:\
# :lp=/dev/null:
#
# Il file /usr/var/spool/lpd/PRINTNAME/.config dovrebbe contenere:
# server=PC_SERVER
# service=PR_SHARENAME
# password="password"
#
# Esempio:
# server=PAULS_PC
# service=CJET_371
# password=""
#
# File per i messaggi di debug, cambiare in /dev/null se si preferisce.
#
logfile=/tmp/smb-print.log
# logfile=/dev/null
#
# L'ultimo parametro del filtro è il file per la registrazione delle
# transazioni.
#
spool_dir=/var/spool/lpd/lp
config_file=$spool_dir/.config
# Le seguenti variabili dovrebbero essere assegnate nel file di
# configurazione:
# server
# service
# password
# user
eval `cat $config_file`
#
# Supporto per il debugging si può cambiare >> con > per risparmiare
# spazio.
#
echo "server $server, service $service" >> $logfile
(
# NOTA Si potrebbe desiderare di aggiungere la linea `echo translate'
# per avere la conversione automatica CR/LF quando si stampa.
echo translate
echo "print -"
cat
) | /usr/bin/smbclient "\\\\$server\\$service" $password -U $user -N -P >> $logfile
La maggior parte delle distribuzioni Linux include nenscript
per
convertire documenti ASCII a Postscript. Lo script Perl che segue
rende la vita più semplice agendo da semplice interfaccia per la stampa di
Linux attraverso smbprint
.
Usage: print [-a|c|p] <filename> -a prints <filename> as ASCII -c prints <filename> formatted as source code -p prints <filename> as Postscript If no switch is given, print attempts to guess the file type and print appropriately.
Usare smbprint
per stampare file ASCII comporta a volte troncare
le linee lunghe. Lo script che segue interrompe, se possibile,
le linee lunghe su uno spazio (invece che in mezzo ad una parola).
La formattazione del codice sorgente è fatta con nenscript
. Il
file ASCII viene formattato su 2 colonne con un'intestazione (data,
nome del file, ecc.) inoltre numera le linee. Usandolo come esempio,
è possibile realizzare altri tipi di formattazione.
I documenti Postscript sono già correttamente formattati, quindi passano senza essere modificati.
#!/usr/bin/perl
# Script: print
# Autore: Brad Marshall, David Wood
# Plugged In Communications
# Data: 960808
#
# Script per stampare su oreilly che è attualmente connessa a zimmerman
# Scopo: Dati diversi tipi di file come argomenti, li elabora
# correttamente per mandarli in pipe ad uno script di stampa Samba.
#
# Tipi di file correntemente supportati:
#
# ASCII - Verifica che le linee più lunghe di $line_length caratteri
# si interrompano su spazio.
# Postscript - Intrapresa nessuna azione.
# Codice - Formatta in Postscript (usando nenscript) per rendere al
# al meglio (in orizzontale, font, ecc.)
#
# Lunghezza massima concessa per ciascuna linea di testo ASCII.
$line_length = 76;
# Nome e percorso dello script di stampa Samba
$print_prog = "/usr/bin/smbprint";
# Nome e percorso di nenscript (converte ASCII-->Postscript)
$nenscript = "/usr/bin/nenscript";
unless ( -f $print_prog ) {
die "Non trovo: $print_prog!";
}
unless ( -f $nenscript ) {
die "Non trovo: $nenscript!";
}
&ParseCmdLine(@ARGV);
# DBG
print "Il file e' di tipo: $filetype\n";
if ($filetype eq "ASCII") {
&wrap($line_length);
} elsif ($filetype eq "code") {
&codeformat;
} elsif ($filetype eq "ps") {
&createarray;
} else {
print "Spiacente...file di tipo sconosciuto.\n";
exit 0;
}
# Pipe the array to smbprint
open(PRINTER, "|$print_prog") || die "Impossibile aprire $print_prog: $!\n";
foreach $line (@newlines) {
print PRINTER $line;
}
# Spedisce un linefeed extra nel caso in cui il file abbia l'ultima linea
# incompleta.
print PRINTER "\n";
close(PRINTER);
print "Finito.\n";
exit 0;
# --------------------------------------------------- #
# Da questo punto in poi ci sono solo subroutine #
# --------------------------------------------------- #
sub ParseCmdLine {
# Analizza la linea di comand, cercando di riconoscere il tipo di
# file.
# Se esistono imposta $arg e $file agli argomenti.
if ($#_ < 0) {
&usage;
}
# DBG
# foreach $element (@_) {
# print "*$element* \n";
# }
$arg = shift(@_);
if ($arg =~ /\-./) {
$cmd = $arg;
# DBG
# print "\$cmd trovato.\n";
$file = shift(@_);
} else {
$file = $arg;
}
# Definisce il tipo di file
unless ($cmd) {
# Nessun argomento
if ($file =~ /\.ps$/) {
$filetype = "ps";
} elsif ($file =~ /\.java$|\.c$|\.h$|\.pl$|\.sh$|\.csh$|\.m4$|\.inc$|\.html$|\.htm$/) {
$filetype = "code";
} else {
$filetype = "ASCII";
}
# Elabora $file in base al suo tipo e ritorna $filetype
} else {
# Il tipo che e' viene restituito in $arg
if ($cmd =~ /^-p$/) {
$filetype = "ps";
} elsif ($cmd =~ /^-c$/) {
$filetype = "code";
} elsif ($cmd =~ /^-a$/) {
$filetype = "ASCII"
}
}
}
sub usage {
print "
Uso: print [-a|c|p] <nomefile>
-a stampa <nomefile> come ASCII
-c stampa <nomefile> formattato come codice sorgente
-p stampa <nomefile> come Postscript
Se non viene fornito alcun parametro, cerca di
indovinare il tipo e stamparlo adeguatamente.\n
";
exit(0);
}
sub wrap {
# Crea un array di linee del file, dove ciascuna linea e' <
# del numero di caratteri specificato, e termina solo su spazi.
# Recupera il numero di caratteri a cui limitare la linea.
$limit = pop(@_);
# DBG
#print "Entra subroutine wrap\n";
#print "La lunghezza limite per la linea e' $limit\n";
# Leggi il file, analizzalo e mettilo nell'array.
open(FILE, "<$file") || die "Impossibile aprire: $file: $!\n";
while(<FILE>) {
$line = $_;
# DBG
#print "La linea e':\n$line\n";
# Se la linea e' oltre il limite vai a capo.
while ( length($line) > $limit ) {
# DBG
#print "Limita...";
# Prendi i primi $limit +1 caratteri.
$part = substr($line,0,$limit +1);
# DBG
#print "La linea parziale e':\n$part\n";
# verifica se l'ultimo carattere e' spazio
$last_char = substr($part,-1, 1);
if ( " " eq $last_char ) {
# Se lo e' stampa il resto.
# DBG
#print "L'ultimo carattere era spazio\n";
substr($line,0,$limit + 1) = "";
substr($part,-1,1) = "";
push(@newlines,"$part\n");
} else {
# se non lo e', cerca l'ultimo spazio nella
# sottolinea e stampa fino a li'.
# DBG
#print "L'ultimo carattere non era spazio\n";
# RImuove i caratteri oltre $limit
substr($part,-1,1) = "";
# Rovescia la linea per rendere semplice da trovare
# l'ultimo carattere.
$revpart = reverse($part);
$index = index($revpart," ");
if ( $index > 0 ) {
substr($line,0,$limit-$index) = "";
push(@newlines,substr($part,0,$limit-$index)
. "\n");
} else {
# Non c'erano spazi cosi' stampa fino a $limit
substr($line,0,$limit) = "";
push(@newlines,substr($part,0,$limit)
. "\n");
}
}
}
push(@newlines,$line);
}
close(FILE);
}
sub codeformat {
# Chiama la funzione wrap e poi filtra il risultato attraverso
# nenscript
&wrap($line_length);
# Manda il risultato attraverso nenscript per creare un file
# Postscript che abbia un formato accettabile di stampa per
# il codice sorgente (stile orizzontale, font Courier, numeri
# di linea)
# Per prima cosa stampa su un file temporaneo.
$tmpfile = "/tmp/nenscript$$";
open(FILE, "|$nenscript -2G -i$file -N -p$tmpfile -r") ||
die "Non posso aprire nenscript: $!\n";
foreach $line (@newlines) {
print FILE $line;
}
close(FILE);
# Legge il file temporaneo inun array per passarlo allo script di
# stampa di Samba
@newlines = ("");
open(FILE, "<$tmpfile") || die "Impossibile aprire $file: $!\n";
while(<FILE>) {
push(@newlines,$_);
}
close(FILE);
system("rm $tmpfile");
}
sub createarray {
# Crea l'array per Postscript
open(FILE, "<$file") || die "Impossibile aprire $file: $!\n";
while(<FILE>) {
push(@newlines,$_);
}
close(FILE);
}
A questo punto si può esaminare MagicFilter. Ringraziamenti ad Alberto Menegazzi ( flash.egon@iol.it) per queste informazioni.
Alberto scrive:
/usr/bin/local
ma non si compili il
file /etc/printcap
con i suggerimenti dati dalla
documentazione di MagicFilter.>/etc/printcap
in questo modo (l'esempio
si riferisce alla LaserJet 4L dell'autore):
lp|ljet4l:\
:cm=HP LaserJet 4L:\
:lp=/dev/null:\ # or /dev/lp1
:sd=/var/spool/lpd/ljet4l:\
:af=/var/spool/lpd/ljet4l/acct:\
:sh:mx#0:\
:if=/usr/local/bin/main-filter:
È necessario spiegare che 'lp=/dev/...' viene aperta e
bloccata (locked) quindi è necessario utilizzare
un dispositivo "virtuale" per ciascuna stampante remota
che si debba usare.
È possibile crearli ad esempio con: 'touch /dev/ljet41'
/usr/local/bin/main-filter
come
quello suggerito, usando ljet4l-filter invece di
bf/cat/.
Ad esempio:
#! /bin/sh
logfile=/var/log/smb-print.log
spool_dir=/var/spool/lpd/ljet4l
(
echo "print -"
/usr/local/bin/ljet4l-filter
) | /usr/bin/smbclient "\\\\SHIR\\HPLJ4" -N -P >> $logfile
C'è anche un riferimento dal Print2Win mini-Howto relativamente il locking dei dispositivi e sul perché conviene creare stampanti virtuali.
Suggerimento da Rick Bressler: A titolo di suggerimento, la configurazione che segue non è una buona idea: :lp=/dev/null:\ in quanto lpr apre in modo 'esclusivo' il file specificato tramite lp=. È necessario per prevenire il tentativo di diversi processi di stampare contemporaneamente sulla stessa stampante. Un effetto collaterale è che in tal caso, eng e colour non possono stampare contemporaneamente, (di solito è più o meno trasparente dal momento che stampano velocemente, e dal momento che usano una coda, probabilmente non si nota), tuttavia ogni altro processo che cerca di scrivere a /dev/null sarà interrotto! Non si tratta di un grosso problema in un sistema per utente singolo. L'autore ha un sistema con più di 50 stampanti. Sarebbe un problema in questo caso. La soluzione è quella di creare una stampante fittizia per ciascuna di quelle fisiche, esempio con il comando: touch /dev/eng
Hosting by: hurra.com
Generated: 2007-01-26 17:56:18