Sophie

Sophie

distrib > Mandriva > 9.1 > i586 > by-pkgid > f1098342ec4a2b28475e34123ce17201 > files > 1037

howto-html-it-9.1-0.5mdk.noarch.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
 <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
 <TITLE>SMB HOWTO: Condividere una stampante Windows con macchine Linux</TITLE>
 <LINK HREF="SMB-HOWTO-11.html" REL=next>
 <LINK HREF="SMB-HOWTO-9.html" REL=previous>
 <LINK HREF="SMB-HOWTO.html#toc10" REL=contents>
</HEAD>
<BODY>
<A HREF="SMB-HOWTO-11.html">Avanti</A>
<A HREF="SMB-HOWTO-9.html">Indietro</A>
<A HREF="SMB-HOWTO.html#toc10">Indice</A>
<HR>
<H2><A NAME="s10">10. Condividere una stampante Windows con macchine Linux</A></H2>

<P>Per condividere una stampante su una macchina Windows, &egrave; necessario:
<P>
<OL>
<LI>Avere una configurazione corretta in <CODE>/etc/printcap</CODE> che 
corrisponda alla struttura delle directory locali (per le
directory di spool, ecc.)
</LI>
<LI>Usare lo script 
<A HREF="#smbprint">/usr/bin/smbprint</A>.  
Questo script &egrave; disponibile con il sorgente di <B>Samba</B>, purtroppo 
non con tutte le distribuzioni in formato binario.  Pi&ugrave; avanti verr&agrave; 
presentata una versione leggermente diversa di 
<A HREF="#smbprint">smbprint</A>.
</LI>
<LI>Se si desidera convertire file ASCII in Postscript, &egrave; necessario 
avere <CODE>nenscript</CODE>, o qualcosa di equivalente.  <CODE>nenscript</CODE> &egrave; un 
convertitore Postscript generalmente installato in <CODE>/usr/bin</CODE>.
</LI>
<LI>Si potrebbe desiderare rendere la stampa con <B>Samba</B> pi&ugrave; semplice 
tramite un semplice <I>front-end</I>.  Di seguito &egrave; riportato un 
semplice script (
<A HREF="#print">print</A>) in Perl per 
manipolare ASCII, Postscript... 
</LI>
<LI>Si potrebbe anche usare MagicFilter per ottenere il risultato.  I
dettagli necessari per configurare MagicFilter sono presenti nello
script perl.  MagicFilter ha dei punti di favore in quanto
conosce automaticamente come convertire tra un gran numero di formati.</LI>
</OL>
<P>La successiva configurazione di <CODE>/etc/printcap</CODE> &egrave; valida per una 
stampante <B>HP 5MP</B> su un host Windows NT.  Le linee hanno il 
seguente significato:
<P>
<DL>
<DT><B>cm</B><DD><P>commento
<P>
<DT><B>lp</B><DD><P>dispositivo da aprire per output
<P>
<DT><B>sd</B><DD><P>directory di spool della stampante sulla macchina locale
<P>
<DT><B>af</B><DD><P>file per registrare le transazioni
<P>
<DT><B>mx</B><DD><P>massima grandezza per un file (zero significa nessun limite)
<P>
<DT><B>if</B><DD><P>nome del filtro di output (script)
</DL>
<P>Per maggiori informazioni consultare il 
<A HREF="http://sunsite.unc.edu/LDP/HOWTO/Printing-HOWTO.html">Printing HOWTO</A>
o le pagine del manuale per la voce <I>printcap</I>.
<P>
<BLOCKQUOTE><CODE>
<HR>
<PRE>
# /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:
</PRE>
<HR>
</CODE></BLOCKQUOTE>
<P>&Egrave; 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 <B>smbprint</B> (
<A HREF="#smbprint">dato oltre</A>) ed inoltre che il 
dispositivo puntato sia corretto (il file speciale <CODE>/dev</CODE>).
<P>Di seguito lo script <B>smbprint</B>.  Di solito &egrave; installato in 
<CODE>/usr/bin</CODE> ed &egrave; attribuibile, per quanto ne so, ad Andrew Tridgell, 
la persona che ha creato <B>Samba</B>.  Viene fornito con la distribuzione in 
formato sorgente di <B>Samba</B> ma &egrave; riportato, essendo assente in certe 
distribuzioni in formato binario.
<P>Potrebbe essere utile studiarlo attentamente, alcune piccole 
modifiche hanno dimostrato essere di enorme utilit&agrave;.
<P>
<A NAME="smbprint"></A> 
<BLOCKQUOTE><CODE>
<HR>
<PRE>
#!/bin/sh -x

# Questo script &egrave; 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 &egrave; 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&agrave;
# 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&eacute; tutto funzioni &egrave; 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 &egrave; 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&ograve; 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
</PRE>
<HR>
</CODE></BLOCKQUOTE>
<P>La maggior parte delle distribuzioni Linux include <CODE>nenscript</CODE> per 
convertire documenti ASCII a Postscript.  Lo script Perl che segue 
rende la vita pi&ugrave; semplice agendo da semplice interfaccia per la stampa di 
Linux attraverso <CODE>smbprint</CODE>.
<P>
<PRE>
Usage: print [-a|c|p] &lt;filename>
       -a prints &lt;filename> as ASCII
       -c prints &lt;filename> formatted as source code
       -p prints &lt;filename> as Postscript
        If no switch is given, print attempts to
        guess the file type and print appropriately.
</PRE>
<P>Usare <CODE>smbprint</CODE> 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).
<P>La formattazione del codice sorgente &egrave; fatta con <CODE>nenscript</CODE>.  Il 
file ASCII viene formattato su 2 colonne con un'intestazione (data, 
nome del file, ecc.) inoltre numera le linee.  Usandolo come esempio, 
&egrave; possibile realizzare altri tipi di formattazione.
<P>I documenti Postscript sono gi&agrave; correttamente formattati, quindi passano 
senza essere modificati.
<P>
<A NAME="print"></A> 
<BLOCKQUOTE><CODE>
<HR>
<PRE>
#!/usr/bin/perl

# Script:   print
# Autore:   Brad Marshall, David Wood
#           Plugged In Communications
# Data:     960808
#
# Script per stampare su oreilly che &egrave; 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&ugrave; 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!";
}

&amp;ParseCmdLine(@ARGV);

# DBG
print "Il file e' di tipo: $filetype\n";

if ($filetype eq "ASCII") {
    &amp;wrap($line_length);
} elsif ($filetype eq "code") {
    &amp;codeformat;
} elsif ($filetype eq "ps") {
    &amp;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 ($#_ &lt; 0) {
        &amp;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] &lt;nomefile>
       -a stampa &lt;nomefile> come ASCII
       -c stampa &lt;nomefile> formattato come codice sorgente
       -p stampa &lt;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' &lt;
        # 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, "&lt;$file") || die "Impossibile aprire: $file: $!\n";
    while(&lt;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
    &amp;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, "&lt;$tmpfile") || die "Impossibile aprire $file: $!\n";
    while(&lt;FILE>) {
        push(@newlines,$_);
    }
    close(FILE);
    system("rm $tmpfile");
}

sub createarray {
    # Crea l'array per Postscript
    open(FILE, "&lt;$file") || die "Impossibile aprire $file: $!\n";
    while(&lt;FILE>) {
        push(@newlines,$_);
    }
    close(FILE);
}
</PRE>
<HR>
</CODE></BLOCKQUOTE>
<P>A questo punto si pu&ograve; esaminare MagicFilter. Ringraziamenti ad
Alberto Menegazzi (
<A HREF="mailto:flash.egon@iol.it">flash.egon@iol.it</A>) per queste informazioni.
<P>Alberto scrive:
<P>
<OL>
<LI>Installare MagicFilter con il filtro per le stampanti 
in <CODE>/usr/bin/local</CODE> ma <EM>non</EM> si compili il
file <CODE>/etc/printcap</CODE> con i suggerimenti dati dalla
documentazione di MagicFilter.</LI>
<LI>Si scriva <CODE>>/etc/printcap</CODE> in questo modo (l'esempio
si riferisce alla LaserJet 4L dell'autore):

<BLOCKQUOTE><CODE>
<HR>
<PRE>
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:
</PRE>
<HR>
</CODE></BLOCKQUOTE>


&Egrave; necessario spiegare che 'lp=/dev/...' viene aperta e
bloccata (locked) quindi &egrave; necessario utilizzare 
un dispositivo "virtuale" per ciascuna stampante remota
che si debba usare.
<P>&Egrave; possibile crearli ad esempio con: 'touch /dev/ljet41'
<P>
</LI>
<LI>Si scriva un filtro <CODE>/usr/local/bin/main-filter</CODE> come
quello suggerito, usando <B>ljet4l-filter</B> invece di
bf/cat/.
<P>Ad esempio:
<P>
<BLOCKQUOTE><CODE>
<HR>
<PRE>
#! /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
</PRE>
<HR>
</CODE></BLOCKQUOTE>
</LI>
</OL>
<P>C'&egrave; anche un riferimento dal Print2Win mini-Howto relativamente
il locking dei dispositivi e sul perch&eacute; conviene creare
stampanti virtuali.
<P>
<HR>
<PRE>
     Suggerimento da Rick Bressler:
     A titolo di suggerimento, la configurazione che segue non &egrave;
     una buona idea:

        :lp=/dev/null:\

     in quanto lpr apre in modo 'esclusivo' il file specificato
     tramite lp=.  &Egrave; necessario per prevenire il tentativo di
     diversi processi di stampare contemporaneamente sulla
     stessa stampante.

     Un effetto collaterale &egrave; che in tal caso, eng e colour non
     possono stampare contemporaneamente, (di solito &egrave; pi&ugrave; 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&agrave; interrotto!

     Non si tratta di un grosso problema in un sistema per utente
     singolo.  L'autore ha un sistema con pi&ugrave; di 50 stampanti.
     Sarebbe un problema in questo caso.

     La soluzione &egrave; quella di creare una stampante fittizia per
     ciascuna di quelle fisiche, esempio con il comando:

     touch /dev/eng
</PRE>
<HR>
<P>
<HR>
<A HREF="SMB-HOWTO-11.html">Avanti</A>
<A HREF="SMB-HOWTO-9.html">Indietro</A>
<A HREF="SMB-HOWTO.html#toc10">Indice</A>
</BODY>
</HTML>