Como Compatilhar uma impressora do Windows com máquinas Linux ? Moderator: rmello@cc.usu.edu (inherited from parent) Para compartilhar uma impressora de uma máquina com Windows, deve-se observar os seguintes passos: a) Deve-se ter as entradas adequadas em /etc/printcap e elas devem corresponder à estrutura de diretórios local (para o diretório de tarefas temporárias, etc.). b) Deve-se ter à disposição o programa /usr/bin/smbprint. Ele é disponibilizado com os fontes do Samba, mas não necessariamente em todas as distribuições binárias. Uma cópia ligeiramente modificada é apresentada a seguir. c) Caso se deseje converter arquivos ASCII em Postscript, deve-se ter à disposição o nenscript, ou o seu equivalente. O Nenscript é um conversor Postscrip, geralmente instalado em /usr/bin. d) Pode ser desejável tornar a impressão via Samba mais simples disponibilizando uma interface composta por um simples programa perl (código-fonte mais abaixo) para lidar com arquivos ASCII, Postscript ou Postscript criados. A entrada no arquivo /etc/printcap a seguir é destinada à uma impressora HP 5MP em uma máquina com Windows NT. As entradas podem ter o seguinte formato: cm - comentário lp - nome do dispositivo a ser acionado na saída sd - nome do diretório de tarefas temporárias na máquina local af - arquivo de contabilidade mx - tamanho máximo de arquivo (zero significa ilimitado) if - nome do filtro de entrada (um programa) Para maiores informações veja o COMO FAZER-Impressão ou as páginas de impressão do 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: Esteja seguro de que o diretório temporário e os diretórios de contabilidade existem e, é permitida a gravação nesses diretórios. Verifique se a linha 'if' contém a rota apropriada para o programa smbprint (fornecido a seguir) e esteja seguro que o dispositivo apropriado está apontado (para o arquivo especial /dev). A seguir verificaremos o programa smbprint. Ele normalmente está localizado em /usr/bin e é de autoria de Andrew Tridgell, a pessoa que criou o Samba até onde eu sei. Ele vem com os fontes da distribuição Samba, mas está ausente em algumas distribuições binárias, razão pela qual eu o recriei aqui. Pode-se desejar verificar o seu conteúdo atentamente. Há algumas pequenas alterações que mostraram-se muito úteis. PROGRAMA smbprint: #!/bin/sh -x # Este programa é um filtro de entrada na impressão printcap em uma maquina # Unix. Ele é usado pelo programa smbclient para imprimir um arquivo no servidor # baseado em SMB. # Pode-se, por exemplo, criar uma entrada no printcap com a seguinte linha: # # smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint # # a qual pode criar uma impressora Unix chamada "smb" que irá imprimir através # deste programa. Deve-se criar o diretório de tarefas temporárias denominado # /usr/spool/smb com as permissões e proprietários apropriados ao sistema local. # Configure este para o servidor e o serviço no qual se deseje imprimir. # Neste exemplo eu tenho um PC com Windows For Workgroups chamado "terrasanta" que # tem uma impressora exportada como "impressora" e não possui senhas. # # Este programa foi alterado por hamiltom@ecnz.co.nz (Michael Hamilton) # permitindo que o servidor, o serviço e a senha possam ser lidas a partir # do arquivo /usr/var/spool/lpd/PRINTNAME/.config. # # Para que este programa possa funcionar, a entrada no /etc/printcap deve incluir # um arquivo de contabilidade (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: # # O arquivo /usr/var/spool/lpd/PRINTNAME/.config deve conter: # server=SERVIDOR # service=PR_NOME_COPARTILHAMENTO # password="senha" # # Exemplo: # server=SERVIDOR_2 # service=CJET_371 # password="" # # Para depurar o arquivo de mensagens deve-se alterar o parâmetro /dev/null para # o arquivo desejado # logfile=/tmp/smb-impressora.log # logfile=/dev/null # # O último parâmetro para o filtro é o nome do arquivo de contabilidade. # spool_dir=/var/spool/lpd/lp config_file=$spool_dir/.config # Devem ser lidas as seguintes variáveis no arquivo de configuração: # servidor # serviço # senha # usuário eval `cat $config_file` # # Dicas na depuração: mude >> para > se você quiser o mesmo espaço. # echo "server $server, service $service" >> $logfile ( # NOTA: é possível anexar a linha `echo translate' caso se deseje # conversões automáticas de CR/LF durante a impressão echo translate echo "print -" cat ) | /usr/bin/smbclient "\\\\$server\\$service" $password -U $user -N -P >> $logfile Muitas distribuições Linux contém o nenscript para a conversão de documentos ASCII para Postscript. O seguinte programa em Perl torna a vida mais simples ao prover uma interface simples a impressão Linux via smbprint. Uso: print [-a|c|p] nome_do_arquivo -a imprime nome_do_arquivo como ASCII -c imprime nome_do_arquivo formatado como código fonte -p imprime nome_do_arquivo como Postscript caso nenhum parâmetro seja informado, o comando de impressão tenta descobrir o tipo de arquivo e imprimi-lo corretamente. O uso do smbprint para a impressão de longas filas ASCII tende a truncar linhas longas. Este programa quebra estas linhas, se possível, nos espaços em branco (ao invés de fazê-lo no meio de uma palavra). A formatação do fonte é feita com nenscript. Ele recebe uma arquivo ASCII e o formata em duas colunas com um cabeçalho interessante (data, nome do arquivo, etc.), além de numerar as linhas. Usando isso como um exemplo, outros tipos de formatacao podem ser conseguidos. Documentos PostScript ja estao formatados corretamente, nao sendo tratados pelo programa. #!/usr/bin/perl # Programa: print # Autores: Brad Marshall, David Wood # Conectados em Comunicações # Data: 08/08/96 # # Programa para impressão para Oreilly, que está com zimmerman # Propósito: Recebe arquivos de vários tipos como argumentos e # os processa adequadamente, conectando-os ao programa # de impressão Samba. - Atualmente suporta os seguintes # tipos de arquivos: # # ASCII - garante que linhas com um número de caracteres maior que o valor # da variável $line_length sejam divididas quando é encontrado um # espaço em branco. # Postscript - Não executa nenhuma ação. # Code - Formata em Postscript (usando nenscript) para listá-los # adequadamente (formato, fonte, etc.). # # Configuração do tamanho máximo de cada linha de texto ASCII $line_length = 76; # Configura o caminho e o nome do programa de impressão Samba $print_prog = "/usr/bin/smbprint"; # Configura o caminho e o nome para nenscript (o conversor ASCII-->Postscript) $nenscript = "/usr/bin/nenscript"; unless ( -f $print_prog ) { die "Não foi possível encontrar $print_prog!"; } unless ( -f $nenscript ) { die "Não foi possível encontrar $nenscript!"; } &ParseCmdLine(@ARGV); # DBG print "arquivo é do tipo $filetype\n"; if ($filetype eq "ASCII") { &wrap($line_length); } elsif ($filetype eq "code") { &codeformat; } elsif ($filetype eq "ps") { &createarray; } else { print "Desculpe..tipo de arquivo desconhecido.\n"; exit 0; } # Conecta a tabela com smbprint open(PRINTER, "|$print_prog") || die "Não foi possível abrir $print_prog: $!\n"; foreach $line (@newlines) { print PRINTER $line; } # Envia uma nova linha extra no caso do arquivo ter uma última linha incompleta. print PRINTER "\n"; close(PRINTER); print "Finalizado\n"; exit 0; # --------------------------------------------------- # # O conteúdo abaixo é uma subrotina # # --------------------------------------------------- # sub ParseCmdLine { # Recebe a linha de comando, descobrindo qual o tipo de arquivo # Recebe $arq e $file como argumentos (se existirem) # e o nome do arquivo if ($#_ < 0) { &usage; } # DBG # foreach $element (@_) { # print "*$element* \n"; # } $arg = shift(@_); if ($arg =~ /\-./) { $cmd = $arg; # DBG # print "\$cmd found.\n"; $file = shift(@_); } else { $file = $arg; } # Definindo o tipo de arquivo unless ($cmd) { # Temos alguns argumentos if ($file =~ /\.ps$/) { $filetype = "ps"; } elsif ($file =~ /\.java$|\.c$|\.h$|\.pl$|\.sh$|\.csh$|\.m4$|\.inc$|\.html$|\.htm$/) { $filetype = "code"; } else { $filetype = "ASCII"; } # Processa $file para o tipo de arquivo indicado e retorna $filetype } else { # O parâmetro informado está em $arg if ($cmd =~ /^-p$/) { $filetype = "ps"; } elsif ($cmd =~ /^-c$/) { $filetype = "code"; } elsif ($cmd =~ /^-a$/) { $filetype = "ASCII" } } } sub usage { print " Uso: print [-a|c|p] nome_do_arquivo -a imprime nome_do_arquivo como ASCII -c imprime nome_do_arquivo formatado como código fonte -p imprime nome_do_arquivo como Postscript caso nenhum parâmetro seja informado, o comando de impressão tenta descobrir o tipo de arquivo e imprimi-lo corretamente.\n "; exit(0); } sub wrap { # Cria um vetor com as linhas do arquivo, onde cada linha é menor # que o número de caracteres especificado, e quebrada somente onde # houver espaços em branco # Obtém o limite do número de caracteres por linha. $limit = pop(@_); # DBG #print "Entrando na subrotina de quebra de linhas\n"; #print "O tamanho máximo de caracteres por linha é igual a $limit\n"; # Lê o arquivo e o coloca em um vetor open(FILE, "<$file") || die "Não foi possível abrir $file: $!\n"; while(FILE) { $line = $_; # DBG # print "Linha:\n$line\n"; # Quebra a linha que estiver além do limite. while ( length($line) > $limit ) { # DBG #print "Quebrando..."; # Obtém o limite + 1 caractere $part = substr($line,0,$limit +1); # DBG #print "A linha parcial é:\n$part\n"; # verifica se o último caractere é um espaço. $last_char = substr($part,-1, 1); if ( " " eq $last_char ) { # Em caso positivo imprime o restante. # DBG #print "O último caractere foi um espaço\n"; substr($line,0,$limit + 1) = ""; substr($part,-1,1) = ""; push(@newlines,"$part\n"); } else { # caso contrário, encontra o último espaço na # sublinha e o imprime. # DBG #print "O último caractere não era um espaço\n"; # Remove o caractere que ultrapassar o limite substr($part,-1,1) = ""; # inverte a linha para facilitar a busca pelo último # espaço $revpart = reverse($part); $index = index($revpart," "); if ( $index > 0 ) { substr($line,0,$limit-$index) = ""; push(@newlines,substr($part,0,$limit-$index) . "\n"); } else { # Não há espaço na linha, então # será impresssa até $limit. substr($line,0,$limit) = ""; push(@newlines,substr($part,0,$limit) . "\n"); } } } push(@newlines,$line); } close(FILE); } sub codeformat { # Chama a subrotina wrap e executa um filtro através de nenscript &wrap($line_length); # Conecta o resultado através de nenscript para criar um arquivo # Postscript que esteja de acordo com algum formato de impressão # código fonte (paisagem, fonte Courier, numeração de linhas) # Inicialmente imprime em um arquivo temporário $tmpfile = "/tmp/nenscript$$"; open(FILE, "|$nenscript -2G -i$file -N -p$tmpfile -r") || die "Não foi possível abrir nenscript: $!\n"; foreach $line (@newlines) { print FILE $line; } close(FILE); # Lê o arquivo temporário de volta em um vetor viabilizando # a sua passagem para um programa de impressão Samba @newlines = (""); open(FILE, "<$tmpfile") || die "Não foi possível abrir $file: $!\n"; while(FILE) { push(@newlines,$_); } close(FILE); system("rm $tmpfile"); } sub createarray { # Cria um vetor para o arquivo Postscript open(FILE, "<$file") || die "Não foi possível abrir $file: $!\n"; while(FILE) { push(@newlines,$_); } close(FILE); } Retirado do COMO FAZER-SMB, por David Wood e traduzido por Conectiva Informatica info@conectiva.com.br Direitos autorais: Este COMO FAZER foi produzido em 1996 por David Wood. Ele pode ser reproduzido em qualquer formato e livremente distribuído desde que o arquivo permaneça intacto, incluindo este aviso. [Append to This Answer] rb.mello@usu.edu, rmello@cc.usu.edu