COMO FAZER SMB David Wood, dwood@plugged.net.au Traduzido e Revisado por Conectiva Informática, , no dia 07 de Abril de 1999. v1.0, 10 de Agosto de 1996 Este é o COMO FAZER SMB. Este documento descreve como usar o protocolo de Bloco de Mensagens de Sessão (SMB), também denominado NetBIOS ou protocolo Lan Manager, com o Linux. ______________________________________________________________________ Índice geral 1. Introdução 2. Informações Adicionais 3. Instalação 4. Executando os Servidores 5. Configuração Geral (/etc/smb.conf) 6. Compartilhando um dispositivo Linux com máquinas Windows 7. Compartilhando Um Dispositivo Windows com Máquinas Linux 8. Compartilhando Uma Impressora Linux com Máquinas Windows 9. Compartilhando uma impressora do Windows com máquinas Linux 10. Direitos Autorais 11. Agradecimentos ______________________________________________________________________ 11.. IInnttrroodduuççããoo Este é o COMO FAZER SMB. Este documento descreve como usar o protocolo de Bloco de Mensagens de Sessão (SMB), também denominado NetBIOS ou protocolo Lan Manager com o Linux. Este documento é mantido por David Wood (dwood@plugged.net.au). Adições, modificações ou correções podem ser enviadas via correio eletrônico para inclusão em próximas versões. O protocolo SMB é usado pelo Microsoft Windows 3.11, NT e 95 para o compartilhamento de discos e impressoras. Utilizando-se o conjunto de ferramentas Samba desenvolvidas por Andrew Tridgell, máquinas UNIX (inclusive Linux) podem compartilhar discos e impressoras com máquinas Windows. Há quatro coisas que podem ser feitas com o Samba: 1. Compartilhar um dispositivo Linux com máquinas Windows. 2. Compartilhar um dispositivo Windows com máquinas Linux. 3. Compartilhar uma impressora Linux com máquinas Windows. 4. Compartilhar uma impressora Windows com máquinas Linux. Todos estes itens são cobertos neste documento. Aviso: os procedimentos e programas funcionam para o autor ou assim foram informados por diversos usuários. Diferentes configurações podem não funcionar completamente com as informações aqui disponibilizadas. Caso o leitor se defronte com tal situação, por favor envie uma mensagem para o autor com sugestões de melhorias deste documento, porém o autor não pode fornecer garantias de qualquer espécie. O que você espera? Afinal o autor é, antes de tudo, um pesquisador... 22.. IInnffoorrmmaaççõõeess AAddiicciioonnaaiiss Este COMO FAZER tenta explicar como efetuar as configurações básicas dos serviços SMB de compartilhamento de arquivos e impressão em uma máquina Linux. O Samba é bastante complexo e contém um pacote com várias funcionalidades. Não há sentido em duplicar aqui toda a documentação do Samba. Para maiores informações por favor consulte os seguintes documentos: · Documentação Samba, disponível como parte da distribuição Samba, disponível em:ftp://nimbus.anu.edu.au/pub/tridge/samba/ · O Linux COMO FAZER Impressão · O mini COMO FAZER Imprimindo Em Windows 33.. IInnssttaallaaççããoo Os fontes mais atualizados do Samba encontram-se em: ftp://nimbus.anu.edu.au/pub/tridge/samba/ De qualquer forma, se foi instalada uma distribuição Red Hat ou Conectiva Linux, tem-se a opção de instalá-lo como um pacote. Algumas outras distribuições também incluem os binários do Samba. Os seguintes servidores são necessário para o pacote Samba. Eles normalmente estão instalados em /usr/sbin e são executados a partir da inicialização do sistema ou a partir do servidor inetd. Programas de exemplo são apresentados na seção ``Executando os Servidores''. ______________________________________________________________________ smbd (O Servidor SMB) nmbd (Provê suporte de servidor de nomes NetBIOS aos clientes) ______________________________________________________________________ Tipicamente, os seguintes binários Samba são instalados em /usr/bin, apesar da sua localização ser opcional. ______________________________________________________________________ smbclient (programa cliente SMB para máquinas UNIX) smbprint (programa para imprimir em uma impressora conectada a uma máquina SMB) smbprint.sysv (programa para imprimir em uma impressora conectada a uma máquina Unix SVR4) smbstatus (lista a situação atual de conexões SMB para a máquina local) smbrun (programa de exemplo para facilitar a execução de aplicações em máquinas SMB) ______________________________________________________________________ Adicionalmente um programa chamado "print" é incluído com este COMO FAZER, o qual serve como interface útil ao programa smbprint. O pacote Samba é simples de ser instalado. Simplesmente deve-se obter os fontes a partir da localização acima indicada e ler-se atentamente o conteúdo do arquivo README presente na distribuição. Há ainda um arquivo chamado docs/INSTALL.txt na distribuição, que provê um roteiro simples e passo a passo para a instalação. Seguindo na instalação, os servidores devem ser copiados para /usr/sbin e os binários para /usr/bin. A seguir devem ser instaladas as páginas de manual em /usr/local/man. Ao se construir um pacote Samba, deve-se especificar no arquivo de configuração a localização do arquivo de configuração smb.conf. Normalmente ele está localizado em /etc, mas pode ser especificada qualquer localização que se queira. Neste documento presumimos que se tenha especificado a localização /etc/smb.conf, sendo que o arquivo de registro de ocorrência será o /var/log/samba-log.%m e o arquivo de retenção de recursos será o /var/lock/samba. Após isso, deve-se instalar o arquivo de configuração smb.conf, e depois ir para o diretório onde o Samba foi construído. Vá ao subdiretório examples/simple e leia o arquivo README. Copie o arquivo smb.conf encontrado neste diretório para /etc. SEJA CUIDADOSO! Caso se tenha uma distribuição que já tenha o Samba instalado, é provável que já haja um arquivo de configuração em /etc. Deve-se fazer a inicialização então com este arquivo. Caso não se deseje ter o arquivo de configuração em /etc, coloque-o onde achar mais indicado e crie uma ligação simbólica em /etc da seguinte forma (não esquecendo de substituir os itens pertinentes): ______________________________________________________________________ ln -s /caminho/para/smb.conf /etc/smb.conf ______________________________________________________________________ 44.. EExxeeccuuttaannddoo ooss SSeerrvviiddoorreess Os dois servidores SMB são denominados /usr/sbin/smbd e /usr/sbin/nmbd. Pode-se executar os servidores Samba a partir do inetd ou em processos isolados. Caso se esteja configurando um servidor de arquivos permanente, deve-se configurá-los para serem executados a partir do inetd, assim eles serão automaticamente reinicializados em casos de finalizações indevidas. Caso se deseje utilizar os serviços SMB ocasionalmente ou para auxiliar na administração de sistemas, pode-se inicializá-los com o programa /etc/rc.d/init.d ou mesmo manualmente, sempre que necessário. Para executar os servidores a partir do inetd, coloque as seguintes linhas no arquivo de configuração do inetd, denominado /etc/inetd.conf: ______________________________________________________________________ # Serviços NetBIOS SAMBA (para compartilhamento de arquivos e impressoras) netbios-ssn stream tcp nowait root /usr/sbin/smbd smbd netbios-ns dgram udp wait root /usr/sbin/nmbd nmbd ______________________________________________________________________ Para reinicializar o servidor inetd deve-se executar o seguinte comando: ______________________________________________________________________ kill -HUP 1 ______________________________________________________________________ Para inicializar os servidores automaticamente quando todo o sistema for iniciado, coloque o seguinte programa em um arquivo chamado /etc/rc.d/init.d/smb e estabeleça uma ligação simbólica com os arquivos especificados nos comentários: ______________________________________________________________________ #!/bin/sh # # /etc/rc.d/init.d/smb - para e inicia os serviços SMB. # # Os seguintes arquivos devem ser ligações simbólicas para este arquivo: # /etc/rc.d/rc1.d/K35smb (encerra os serviços SMB e desliga o sistema) # /etc/rc.d/rc3.d/S91smb (inicia os serviços SMB em modo multiusuário) # /etc/rc.d/rc6.d/K35smb (finaliza os serviços SMB e reinicializa o # sistema) # # Biblioteca fonte de funções . /etc/rc.d/init.d/functions # Configuração de rede . /etc/sysconfig/network # Verifica se a rede está ativa [ ${NETWORKING} = "no" ] && exit 0 # Verifica como o programa está sendo executado case "$1" in start) echo -n "Iniciando serviços SMB: " daemon smbd -D daemon nmbd -D echo touch /var/lock/subsys/smb ;; stop) echo -n "Desligando serviços SMB: " killproc smbd killproc nmbd rm -f /var/lock/subsys/smb echo "" ;; *) echo "Uso: smb {start|stop}" exit 1 esac ______________________________________________________________________ 55.. CCoonnffiigguurraaççããoo GGeerraall ((//eettcc//ssmmbb..ccoonnff)) A configuração do Samba no Linux (e em outras máquinas Unix) é controlada por um único arquivo denominado /etc/smb.conf. Este arquivo determina quais recursos do sistema se deseja compartilhar com o mundo exterior e quais restrições se deseja aplicar aos usuários externos. Uma vez que as seções seguintes apresentam o compartilhamento de dispositivos Linux e impressoras com máquinas Windows, o arquivo smb.conf aqui apresentado é bastante simples, e serve simplesmente para propósitos introdutórios. Não se preocupe sobre os detalhes ainda. As seções posteriores irão apresentar os conceitos iniciais. Cada seção de arquivo inicia com um cabeçalho de seção como um [global], [homes], [printers], etc.. A seção [global] define algumas variáveis do Samba que irão ser utilizadas para definir o compartilhamento de todos os recursos. A seção [homes] permite que usuários remotos acessem seus (e somente os seus) diretórios pessoais em máquinas Linux locais. Ou seja, usuários Windows que tentam conectar-se à suas áreas compartilhadas a partir de máquinas Windows, se conectarão então aos seus diretórios pessoais. Observe que para executar isso, eles devem ter uma conta na máquina Linux. O arquivo de exemplo smb.conf a seguir permite que usuários remotos obtenham acesso aos seus diretórios pessoais na máquina local e escrevam em um diretório temporário. Para um usuário Windows visualizar estes compartilhamentos, a máquina Linux deve estar presente na rede local. Então o usuário deve simplesmente conectar-se ao dispositivo de rede a partir do Gerenciador de Arquivos Windows ou do Explorador Windows. Observe que nas seções seguintes, entradas adicionais podem ser informadas, permitindo que mais recursos possam ser compartilhados. ______________________________________________________________________ ; /etc/smb.conf ; ; Esteja seguro de reinicializar o servidor após executar as mudanças no : arquivo, exemplo: ; /etc/rc.d/init.d/smb stop ; /etc/rc.d/init.d/smb start [global] ; Deve ser retirado o símbolo de comentário (;) caso se deseje ter um usuário ; convidado (guest) ; guest account = nobody log file = /var/log/samba-log.%m lock directory = /var/lock/samba share modes = yes [homes] comment = Diretórios Pessoais browseable = no read only = no create mode = 0750 [tmp] comment = Localização de Arquivos Temporários path = /tmp read only = no public = yes ______________________________________________________________________ 66.. CCoommppaarrttiillhhaannddoo uumm ddiissppoossiittiivvoo LLiinnuuxx ccoomm mmááqquuiinnaass WWiinnddoowwss Conforme demonstrado no arquivo smb.conf acima, o compartilhamento de dispositivos com usuários Windows é bastante simples. De qualquer forma, como tudo mais com o Samba, pode-se controlar as coisas em um nível mais detalhado. Seguem aqui alguns exemplos: Para compartilhar um diretório com o público em geral, deve-se criar uma cópia na seção tmp acima e adicionar algo similar a: ______________________________________________________________________ [public] comment = Itens Públicos path = /home/publico public = yes writable = yes printable = yes ______________________________________________________________________ Para tornar o diretório acima acessível a todos os usuários, mas a adição de conteúdo podendo ser executada somente pelo grupo staff, deve-se modificar as entradas para o seguinte formato: ______________________________________________________________________ [public] comment = Itens Públicos path = /home/publico public = yes writable = yes printable = no write list = @staff ______________________________________________________________________ Para informações adicionais sobre as configurações de dispositivos compartilhados, por favor verifique a documentação do Samba ou as páginas de manual online. 77.. CCoommppaarrttiillhhaannddoo UUmm DDiissppoossiittiivvoo WWiinnddoowwss ccoomm MMááqquuiinnaass LLiinnuuxx Um programa SMB cliente para máquinas Unix é incluído na distribuição do Samba. Ele disponibiliza uma interface similar ao FTP na linha de comando. Pode-se usar este utilitário para "transferir" arquivos entre um "servidor" Windows e um cliente Linux. Para verificar quais compartilhamentos estão disponíveis em uma determinada máquina, pode-se executar o seguinte comando: ______________________________________________________________________ /usr/sbin/smbclient -L máquina ______________________________________________________________________ onde "máquina" é o nome da máquina que se deseja visualizar. Isso retornará uma lista de nomes de serviços, ou seja, nomes de dispositivos ou impressoras que podem ser compartilhadas com o usuário que executou o comando. A menos que o servidor SMB não tenha itens de segurança configurados, será solicitada uma senha antes do fornecimento das informações. Obtenha as informações de senha para a conta "guest" (convidado) ou para a sua conta pessoal na máquina desejada. Por exemplo: ______________________________________________________________________ smbclient -L pimenta ______________________________________________________________________ A saída deste comando deve ter uma aparência similar a: ______________________________________________________________________ Server time is Sat Aug 10 15:58:27 1996 Timezone is UTC+10.0 Password: Domain=[WORKGROUP] OS=[Windows NT 4.0] Server=[NT LAN Manager 4.0] Server=[PIMENTA] User=[] Workgroup=[WORKGROUP] Domain=[] Sharename Type Comment --------- ---- ------- ADMIN$ Disk Administração Remota public Disk Público C$ Disk Compartilhamento Padrão IPC$ IPC IPC Remoto OReilly Printer OReilly print$ Disk Programas de controle de impressoras Esta máquina tem uma lista similar a: Server Comment --------- ------- HOPPER Samba 1.9.15p8 KERNIGAN Samba 1.9.15p8 LOVELACE Samba 1.9.15p8 RITCHIE Samba 1.9.15p8 PIMENTA ______________________________________________________________________ A lista acima mostra outros servidores SMB com recursos compartilhados na rede local. Pare se usar o programa cliente deve-se executar o seguinte: ______________________________________________________________________ /usr/sbin/smbclient serviço ______________________________________________________________________ onde "serviço" é uma máquina e o nome de compartilhamento. Por exemplo, caso se esteja tentando alcançar o diretório compartilhado como "público" em uma máquina denominada zimmerman, os serviços devem ser referenciados como \\zimmerman\public. De qualquer forma, devido às restrições do ambiente de trabalho, serão necessárias usar as contrabarras de fuga, o que provocará a geração de um comando similar a: ______________________________________________________________________ /usr/sbin/smbclient \\\\zimmerman\\public senha ______________________________________________________________________ onde "senha" é literalmente a cadeia de caracteres que contém a senha do usuário. Se obterá o indicador de linha de comando do smbclient: ______________________________________________________________________ Server time is Sat Aug 10 15:58:44 1999 Timezone is UTC+10.0 Domain=[WORKGROUP] OS=[Windows NT 4.0] Server=[NT LAN Manager 4.0] smb: \> ______________________________________________________________________ Digite "h" para obter ajuda ao usar o smbclient: ______________________________________________________________________ smb: \> h ls dir lcd cd pwd get mget put mput rename more mask del rm mkdir md rmdir rd prompt recurse translate lowercase print printmode queue cancel stat quit q exit newer archive tar blocksize tarmode setmode help ? ! smb: \> ______________________________________________________________________ Caso se possa utilizar FTP, as páginas de manual online não serão necessárias para o smbclient. 88.. CCoommppaarrttiillhhaannddoo UUmmaa IImmpprreessssoorraa LLiinnuuxx ccoomm MMááqquuiinnaass WWiinnddoowwss Para compartilhar uma impressora Linux com máquinas Windows, é necessário certificar-se inicialmente de que a impressora funciona perfeitamente sob Linux. Caso se possa imprimir a partir deste sistema, então é possível prosseguir na configuração do seu compartilhamento. Se quiser maiores informações sobre a configuração de uma impressora local, por favor verifique o COMO FAZER - Impressão. (N.B.: para facilitar o processo de configuração utilize o utilitário Control- Panel). Uma vez que o autor utiliza uma impressora conectada a uma máquina Windows NT, esta seção não deve ser considerada como definitiva e sim como uma sugestão. Maiores detalhes sobre este tipo de compartilhamento podem ser enviados para dwood@plugged.net.au para complementar esta seção. Adicionando a configuração de uma impressora ao arquivo smb.conf: ______________________________________________________________________ [global] printing = bsd printcap name = /etc/printcap load printers = yes log file = /var/log/samba-log.%m lock directory = /var/lock/samba [printers] comment = Impressoras security = server path = /var/spool/lpd/lp browseable = no printable = yes public = yes writable = no create mode = 0700 [ljet] security = server path = /var/spool/lpd/lp printer name = lp writable = yes public = yes printable = yes print command = lpr -r -h -P %p %s ______________________________________________________________________ Esteja seguro de que a rota para a impressora (neste caso sob [ljet]) coincide com o diretório de tarefas temporárias em /etc/printcap! NOTA: existem alguns problemas no compartilhamento de impressoras em máquinas Unix com máquinas Windows NT usando-se o Samba. Um deles é a visualização pelo Windows NT da impressora compartilhada. Para corrigir isso, por favor verifique as notas da distribuição do Samba no arquivo docs/WinNT.txt. O segundo problema é sobre senhas. Veja os comentários no mesmo arquivo para um melhor entendimento do problema e como corrigí-lo. 99.. CCoommppaarrttiillhhaannddoo uummaa iimmpprreessssoorraa ddoo WWiinnddoowwss ccoomm mmááqquuiinnaass LLiinnuuxx 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. ______________________________________________________________________ #!/bin/sh -x # Este programa é um filtro de entrada na impressão printcap em uma máquina # 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] -a imprime como ASCII -c imprime formatado como código fonte -p imprime 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 formatação podem ser realizados. Documentos Postscript são formatados de forma adequada, não sendo então 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] -a imprime como ASCII -c imprime formatado como código fonte -p imprime 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() { $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() { 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() { push(@newlines,$_); } close(FILE); } ______________________________________________________________________ 1100.. DDiirreeiittooss AAuuttoorraaiiss 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. 1111.. AAggrraaddeecciimmeennttooss Quando receber mensagens com sugestões, colocarei os devidos agradecimentos na próxima versão deste documento.