.op KK KK EEEEEEEE RRRRRRRR MM MM IIII TTTTTTTTTT KK KK EE RR RR MMM MMM II TT KK KK EE RR RR MMMM MMMM II TT KK KKKK EEEEEE RRRRRRRR MM MMM MM II TT KKKK KK EE RR RR MM M MM II TT KK KK EE RR RR MM MM II TT KK KK EEEEEEEE RR RR MM MM IIII TT ____________________________________________________________ ____________________________________________________________ MM MM AAAAAA NN NN UU UU AAAAAA LL MMM MM AA AA NNN NN UU UU AA AA LL MMMM MMMM AA AA NNNN NN UU UU AA AA LL MM MMM MM AA AA NN NN NN UU UU AA AA LL MM M MM AAAAAAAA NN NN NN UU UU AAAAAAAA LL MM MM AA AA NN NNNN UU UU AA AA LL MM MM AA AA NN NN UUUUUUU AA AA LLLLLLL DDDDDDDDD OOOOOO DD DD OO OO DD DD OO OO DD DD OO OO DD DD OO OO DD DD OO OO DDDDDDDDD OOOOOO PPPPP RRRRR OOOO TTTTTT OOOO CCCC OOOO LL OOOO PP PP RR RR OO OO TT OO OO CC OO OO LL OO OO PP PP RR RR OO OO TT OO OO CC OO OO LL OO OO PPPPP RRRRR OO OO TT OO OO CC OO OO LL OO OO PP RR R OO OO TT OO OO CC OO OO LL OO OO PP RR RR OO OO TT OO OO CC OO OO LL OO OO PP RR RR OOOO TT OOOO CCCC OOOO LLLLL OOOO ____________________________________________________________ ____________________________________________________________ TELEBRAS * Quinta Edic,a~o * Brasi'lia, setembro de 1986 .pa MANUAL DO PROTOCOLO KERMIT Quinta Edic,a~o Frank da Cruz Columbia University Center for Computing Activities New York, NY, 10027 Copyright (C) 1981, 1982, 1983, 1984 Trustees of Columbia University in the City of New York Traduc,a~o de J. Ricardo B. Ghirlanda Telecomunicac,o~es Brasileiras S. A. - TELEBRAS Brasi'lia - DF, 1986 E' permitida e, mesmo, incentivada, a co'pia e divulgac,a~o de qualquer parte deste manual, desde que para fins na~o comerciais. .foKERMIT: Manual do Protocolo i I' N D I C E ---------------- Prefa'cio da Quarta Edic,a~o........................... 1 Quinta Edic,a~o....................................... 2 Mais algumas palavras............................... 2 Agradecimentos...................................... 2 Aviso............................................... 3 .cp4  1. Introduc,a~o.......................................... 4 .cp3 1.1. Cena'rio........................................ 4 .cp3 1.2. Visa~o Geral.................................... 4 .cp4  2. Definic,o~es.......................................... 6 .cp3 2.1. Terminologia Geral............................. 6 .cp3 2.2. Nu'meros........................................ 7 .cp3 2.3. Conjunto de Caracteres......................... 7 .cp3 2.4. Func,o~es de Conversa~o........................... 8 .cp3 2.5. Jarga~o do Protocolo............................ 8 .cp4  3. Requisitos de sistema............................... 10 .cp4  4. Texto Impri'mivel VERSUS Dados Bina'rios.............. 12 .cp3 4.1. Arquivos de Texto Imprimi'vel................... 12 .cp3 4.2. Arquivos Bina'rios.............................. 13 .cp4  5. Transfere^ncia de Arquivos........................... 14 .cp3 5.1. Condicionando o Terminal....................... 15 .cp3 5.2. Timeouts, NAKs e Retries....................... 15 .cp3 5.3. Erros.......................................... 16 .cp3 5.4. Heuri'stica..................................... 17 .cp3 5.5. Nomes de Arquivos.............................. 18 .cp3 5.6. Robustez....................................... 19 .cp3 5.7. Controle de Fluxo.............................. 19 .cp3 5.8. Tabela de Estados do Protocolo KERMIT Ba'sico... 20 .cp4  6. Formato dos Pacotes................................. 23 .cp3 6.1. Campos......................................... 23 .cp3 6.2. Terminador..................................... 24 .cp3 6.3. Outros dados inter-pacotes..................... 25 .cp3 6.4. Codificac,a~o, Prefixac,a~o, Checagem de Bloco..... 25 .cp4  7. Conexa~o Inicial..................................... 27 .cp4  8. Facilidades Opcionais............................... 32 .cp3 8.1. Prefixac,a~o de oitavo bit e contador de repetic,o~es......................... 32 .cp3 8.2. Operac,a~o de SERVER (Servidor).................. 34 8.2.1. Comandos SERVER......................... 35 8.2.2. Temporizac,a~o............................ 37 8.2.3. O Comando "R"........................... 37 8.2.4. Respostas Curtas e Respostas Longas..... 38 8.2.5. Comandos SERVER Adicionais.............. 38 .foKERMIT: Manual do Protocolo ii 8.2.6. Comandos de Host........................ 41 8.2.7. Trocando para^metros antes de comandos SERVER...................... 41 .cp3 8.3. Tipos alternativos de checagem de bloco........ 42 .cp3 8.4. Interrompendo uma transfere^ncia de arquivo..... 44 .cp3 8.5. Transmitindo atributos de arquivos............. 45 .cp3 8.6. Tabela de estados do Protocolo KERMIT Avanc,ado. 52 .cp4  9. Comandos KERMIT..................................... 58 .cp3 9.1. Comandos Ba'sicos............................... 58 .cp3 9.2. Comandos de gere^ncia do programa............... 58 .cp3 9.3. Comandos de emulac,a~o de terminal............... 59 .cp3 9.4. Comandos em modo-usua'rio especiais............. 59 .cp3 9.5. Comandos cujo objeto deve ser especificado..... 60 .cp3 9.6. O comando SET.................................. 62 .cp3 9.7. Macros (o comando DEFINE)...................... 64 .cp4 10. Emulac,a~o de terminal................................ 65 .cp4 11. Escrevendo um programa KERMIT....................... 68 .cp3 11.1. Organizac,a~o do programa....................... 68 .cp3 11.2. Linguagem de programac,a~o...................... 71 .cp3 11.3. Documentac,a~o.................................. 71 .cp3 11.4. Bootstrapping................................. 72 .cp6 A P E N D I C E S ----------------- .cp4  A. Formato e Tipos dos Pacotes......................... 73 .cp4  B. Relac,a~o das Facilidades............................. 74 .cp4  C. Problemas na~o resolvidos............................ 76 .cp4  D. Um programa KERMIT.................................. 79 .cp4  E. O conjunto de caracteres ASCII (ANSI X3.4-1968)..... 104 .pa .foKERMIT: Manual do Protocolo iii I'N D I C E DE F I G U R A S ---------------------------------- .cp3 2-1: Caracteres Mneumo^nicos ASCII:.......................... 7 .cp3 5-1: Estados de Transmissa~o................................. 21 5-2: Estados de Recepc,a~o.................................... 22 5-3: Estados Comuns a Transmitir e Receber.................. 22 .pa .foKERMIT: Manual do Protocolo # .pn1 Prefa'cio da Quarta Edic,a~o A quarta edic,a~o (novembro de 1983) do Manual do Protocolo Kermit incorpora algumas novas ide'ias que cresceram de nossa experie^ncia em tentar implementar algumas das facilidades descritas em edic,o~es anteriores, particularmente func,o~es USER/SERVER. Isto inclui um mecanismo que permite interromper transfere^ncias em batch sem traumas, tanto para o arquivo corrente quanto para o conjunto total de uma transfere^ncia em batch; uma "ma'scara de capacidade"; uma extensa~o do protocolo para a passagem de atributos de arquivo. Ale'm disso, nu'meros sa~o escritos em forma decimal, ao inve's de octal, que costumava confundir a maioria dos leitores. Tambe'm foram feitas mudanc,as, por incompatibilidades, em a'reas de menos releva^ncia, onde ainda na~o houvesse acontecido alguma implementac,a~o; isso inclui: - o formato e a interpretac,a~o dos operandos dos comandos de um SERVER; - uso dos campos reservados 10-11 do pacote SEND-INIT e adic,a~o de novos campos reservados. A maior parte do material restante foi reescrito e reorganizado e muito material novo acrescentado, inclusive uma sec,a~o recomendando um vocabula'rio para documentac,a~o e comandos. As edic,o~es pre'vias deste manual tentaram definir a "Versa~o 3" do protocolo; esta edic,a~o abandona tal conceito. Uma vez que o desenvolvimento do KERMIT e' uma tarefa desorganizada, desordenada e distribui'da, na~o ha' forma de impor que implementadores de KERMIT incluam certas capacidades em suas verso~es. Porisso nesta edic,a~o tentamos definir o funcionamento ba'sico do KERMIT e, enta~o, descrever va'rias func,o~es opcionais. O princi'pio chave e' que qualquer implementac,a~o de KERMIT deveria funcionar com qualquer outra, independentemente qua~o avanc,ada seja uma delas ou qua~o primitiva seja a outra. A ma'scara de capacidade e outros campos SEND-INIT tentam promover tal princi'pio. .pa Quinta Edic,a~o A Quinta Edic,a~o (marc,o de 1984) tenta esclarecer alguns pontos que ficaram ambi'guos na Quarta Edic,a~o, particularmente a respeito de quando e como e' feito codificac,a~o de prefixo (e quando na~o e') e acerca de mudanc,as de tipos de checagem de blocos. Para o armazenamento de arquivos e' sugerido um mecanismo na Sec,a~o de Atributos onde diversos deles foram rearranjados e acrescentados (isto na~o deve fazer mal algum, ja' que ningue'm ate' hoje tentou implementar Pacote de Atributo). E' fornecida uma tabela de estado do protocolo mais completa, incluindo algumas adic,o~es na colec,a~o de tipos de pacotes. Mais algumas palavras... Antes de se decidir por escrever uma nova versa~o de KERMIT, por favor, tenha em mente que, por filosofia, ele nunca foi nem jamais deve vir a ser um produto comercial, vendido por lucro. Sua meta e' promover comunicac,a~o e compartilhamento e o KERMIT deve, ele pro'prio, ser compartilhado, na~o vendido. Mi'dia e custos de reproduc,a~o podem ser recuperados se desejado mas o lucro na~o deve ser o motivo. Vendedores de softwares comerciais, no entanto, podem pedir permissa~o para incluir o KERMIT com (ou dentro de) seus programas, desde que certas condic,o~es sejam aceitas, inclusive que os cre'ditos pelo protocolo devem ser dados a` CUCCA e o prec,o do produto na~o crescer substancialmente alem de custos de mi'dia e reproduc,a~o pela inclusa~o do KERMIT. Entre em contato com o KERMIT GROUP se voce tiver qualquer du'vida a respeito disso. De qualquer forma, implementadores de KERMIT em potencial devem fazer isso, porque algue'm pode ja' ter feito ou comec,ado a fazer a mesma coisa. O KERMIT e' distribui'do pela Universidade de Columbia em fita magne'tica. As instruc,o~es completas sobre a forma de fazer o seu pedido podem ser encontradas no Guia do Usua'rio. Consultas diretas podem ser feitas para: KERMIT DISTRIBUTION COLUMBIA UNIVERSITY CENTER FOR COMPUTING ACTIVITIES 7TH FLOOR, WATSON LABORATORY 612 WEST 115TH STREET NEW YORK, NY 10025 Agradecimentos Frank da Cruz e Bill Catchings desenharam o Protocolo KERMIT Ba'sico na Universidade de Columbia em 1981. Por ide'ias, procuraram em alguns dos modelos ANSI (X3.57, X3.66), o modelo OSI da ISO, alguns "protocolos assi'ncronos" do mundo real (incluindo o DIALNET PROJECT de Stanford, o TTYFTP PROJECT de Utah), assim como a transfere^ncia de arquivos nas redes tradicionais como (DECNET e ARPANET). O Bill escreveu os dois primeiros programas a implementarem o protocolo, um para o DEC-20, outro para um microcomputador sob CP/M-80 e, no processo, definiu a maior parte dos detalhes e a heuri'stica necessa'rios num processo de transfere^ncia de arquivos. Enquanto isso Daphne Tzoar e Vace Kundakci, tambe'm da Columbia, definiram os detalhes adicionais para comunicac,a~o com um I.B.M. ..@iIBM Muito cre'dito tambe'm deve ir para Bernie Eiben da Digital Equipment Corporation por haver promovido o uso do KERMIT e por acrescentar diversas novas maneiras de como ele poderia ser operado e para Nick Bush e Bob McQueen do Stevens Institute of Technology, pelas muitas contribuic,o~es a`s partes "avanc,adas" do protocolo e para outros grandes implementadores de KERMIT. Agradecemos a`s muitas pessoas que, por todo o mundo, contribuiram com novas implementac,o~es de KERMIT, que ajudaram na distribuic,a~o do KERMIT atrave's de va'rios Grupos de Usua'rios e a`queles que contribuiram para a qualidade do protocolo e suas muitas implementac,o~es ao reportar ou eliminar problemas, criticar o desenho ou sugerir novas facilidades. Aviso Nenhuma garantia do software nem da perfeic,a~o da documentac,a~o aqui apresentada pode ser expressa ou implicitamente dada, nem os autores nem a Universidade de Columbia se responsabilizam por quaisquer danos que possam advir de erros de software ou documentac,a~o, nem do uso destes. .pa ..@adu 1. Introduc,a~o .heIntroduc,a~o Este manual descreve o protocolo KERMIT. Assume que voce compreenda o propo'sito e a operac,a~o das facilidades do KERMIT de transfere^ncia de arquivos, descrita no Guia do Usua'rio, bem como a terminologia ba'sica de comunicac,a~o de dados e programac,a~o de computadores. .cp3 ..@bd 1.1. Cena'rio ..@iambiente ..@icenario O protocolo KERMIT de transfere^ncia de arquivos e' direcionado a`queles ambientes onde aparecem diversos tipos de computadores (micros, computadores pessoais, estac,o~es de trabalho, computadores de laborato'rio, sistemas de timesharing) fornecidos por diversos fabricantes. Tudo que esses sistemas te^m que ter em comum e' a facilidade de se comunicarem serialmente em ASCII. ..@iIBM Originalmente o KERMIT foi desenhado na Universidade de Columbia pela necessidade de se transferir arquivos entre nossos computadores de grande porte (DECSYSTEM-20 e IBM-370) e va'rios microcomputadores. Aconteceu que as diversas caracteri'sticas desses tres tipos de sistemas resultaram num desenho que era gene'rico o suficiente para atender a quase qualquer sistema. O sistema IBM, em particular, prepondera sobre a maioria das formas de comunicac,a~o de computadores. .cp3 ..@bd 1.2. Visa~o Geral ..@ivisao geral ..@ifilosofia do protocolo ..@iprotocolo, visao geral O protocolo KERMIT e' especificamente projetado para transmissa~o de caracteres atrave's de linhas de telecomunicac,a~o (diz-se "orientado para caracter"). O projeto faz concesso~es a`s restric,o~es e peculiaridades do meio e requisitos de diversos ambientes operacionais (buferizac,a~o, duplex, paridade, conjunto de caracteres, organizac,a~o de arquivos etc.). O protocolo e' obedecido por Programas KERMIT em cada ponta da conexa~o serial que trocam "pacotes" entre si; o transmissor manda nomes de arquivos, conteu'dos e informac,o~es de controle; o receptor acusa (positiva ou negativamente) a chegada de cada pacote. Os pacotes tem um desenho padra~o, mais ou menos mantendo as filosofias ANSI e ISO, com os campos mais exteriores usados pelos manuseadores da conexa~o para a verificac,a~o da integridade dos dados, os pro'ximos indicando continuidade e, centralmente, os dados a ni'vel de aplicac,a~o. As conexo~es entre sistemas sa~o estabelecidas pelo pro'prio usua'rio. Num caso ti'pico, o usua'rio, com o KERMIT no microcomputador, entra em modo de emulac,a~o de terminal, se conecta a um computador hospedeiro remoto (normalmente por discagem), faz o LOGIN, chama o KERMIT de la' e, enta~o, da' os comandos para que o KERMIT do hospedeiro comece uma transfere^ncia de arquivo; "escapa" de volta para o micro e comanda o KERMIT do micro para fazer sua parte da transfere^ncia. A transfere^ncia de arquivos pode ser feita um por vez ou em grupos. O KERMIT ba'sico prove^ apenas transfere^ncia de arquivos e somente para arquivos sequenciais, embora o protocolo tente permitir a transfere^ncia de va'rios tipos de arquivos sequenciais. Tambe'm se espera que as implementac,o~es de KERMIT em microcomputadores possibilitem emulac,a~o de terminal, de forma a facilitar a conexa~o inicial. Implementac,o~es mais avanc,adas simplificam a vida do usua'rio ao permitir que o KERMIT do computador hospedeiro trabalhe em modo "SERVER" (servidor), que pode transferir arquivos nas duas direc,o~es sob comando do KERMIT do microcomputador, em modo "USER" (usua'rio local). O SERVER pode, tambe'm, acrescentar funcionalidade adicional, como gere^ncia de arquivos, correio e por ai' a fora. Outras facilidades existem, inclusive uma variedade de tipos de checagem de blocos, um mecanismo para passar 8 bits atrave's de linhas de comunicac,a~o de 7 bits, maneiras de comprimir uma seque^ncia de caracteres repetidos etc. Conforme as redes locais forem se tornando mais populares, baratas e padronizadas, a demanda pelo KERMIT e protocolos similares podera' decair mas nunca deixara' de ter seu espac,o. Diferentemente das redes fixas, o KERMIT da' ao usua'rio comum o poder de estabelecer conexo~es seguras entre dois computadores, a prova de erros. Sempre havera' a eventual necessidade de uma conexa~o a longa distancia... .pa .heDefinic,o~es ..@adu 2. Definic,o~es ..@idefinicoes ..@bd 2.1. Terminologia Geral ..@iterminologia ..@iTTY TTY Esta e' uma terminologia usada normalmente para um equipamento conectado a um computador via uma linha de telecomunicac,a~o serial. Tal equipamento em geral e' um terminal ASCII mas pode ser um microcomputador ou mesmo um computador de grande porte, multi-usua'rio, emulando um terminal ASCII. A maioria dos computadores dispo~e de hardware (conectores RS-232 e UARTS) e software (device drivers) capazes de suportar conexo~es TTY; isto e' o que torna os protocolos de transfere^ncia de arquivos orientados para TTY, como o KERMIT, possi'veis a baixo (ou, mesmo, nenhum) custo. ..@ilocal LOCAL Quando duas ma'quinas sa~o conectadas, a "LOCAL" e' aquela com a qual voce interage diretamente, na qual voce tem o controle do terminal. O KERMIT LOCAL e' aquele que roda na MA'QUINA LOCAL. Um KERMIT LOCAL sempre se comunica atrave's de um equipamento externo (a porta de comunicac,a~o do micro, uma linha TTY associada etc.). ..@iremoto REMOTO(A) A ma'quina REMOTA e' a que esta' na outra ponta de uma conexa~o, com a qual voce interage atrave's da ma'quina LOCAL. O KERMIT REMOTO normalmente se comunica por seu pro'prio "console", "terminal de controle" ou equipamento "padra~o de I/O". ..@ihost HOST Outro nome para "computador hospedeiro", so' que, desta vez, usando-se o termo americano. Normalmente se referindo a um computador que pode ser um "lar" para mu'ltiplos usua'rios ou aplicac,o~es. Tal termo deve ser evitado no jarga~o KERMIT, a menos que precedido, imediatamente, por "local" ou "remoto", de forma a denotar de qual HOST se esta' falando. ..@iservidor ..@iSERVER SERVER (ou SERVIDOR) Uma implementac,a~o de KERMIT REMOTO capaz de aceitar comandos em pacote de um programa KERMIT local, ao inve's de diretamente do usua'rio. ..@iUSER ..@iusuario USER (ou usua'rio) Adicionalmente ao sentido normal (aquele que usa), "USER" sera' usado neste manual quando houver a necessidade de se referenciar a um programa KERMIT LOCAL, quando um KERMIT REMOTO estiver funcionando como SERVER. .cp3 ..@bd 2.2. Nu'meros ..@inumeros ..@ibases de numeracao Todos os nu'meros que aparecem no texto deste manual sa~o expressos em notac,a~o decimal (BASE 10), a menos que em determinadas situac,o~es seja indicado diferentemente. Os nu'meros sa~o sempre referenciados em termos de suas posic,o~es numa palavra de computador. Ja' que o KERMIT pode ser implementado em computadores com palavras de tamanhos diferentes, podemos comec,ar numerando os BITs da "direita" (bit-0 e' o menos significativo). Os BITs 0-5 sa~o os 6 BITs menos significativos; se todos estiverem em "1", o valor seria 63. Uma falha especial na terminologia usual, no entanto, se refere ao bit de mais alta ordem de um caracter, quando ele deve ser transmitido por uma linha de comunicac,a~o, como sendo o "oitavo bit". Mais propriamente ele e' o bit 7, uma vez que comec,amos a contar do 0. Referencias ao "oitavo bit" sa~o feitas em relac,a~o ao bit que uma transmissa~o ASCII usa como bit de paridade. O KERMIT ve^ se tal bit pode ser usurpado para a transmissa~o de dados ou, se na~o, se pode recorrer a ele para "prefixac,a~o de oitavo bit". .cp3 ..@bd 2.3. Conjunto de Caracteres ..@iconjunto de caracteres ..@icaracteres, mneumonicos ..@imneumonicos Todos os caracteres sa~o representados em ASCII (American Standard Code for Information Interchange), padra~o ANSI X3.4-1968. Todas as implementac,o~es de KERMIT transmitem e recebem somente caracteres em ASCII. O conjunto dos caracteres ASCII esta' listado no Ape^ndice E. .cp11 ..@f Figura2-1: Caracteres Mneumo^nicos ASCII: ============================= NOME VALOR CARACTER NUL nulo, morto 0 ^@ SOH start-of-header 1 ^A SP espac,o 32 branco CR carriage-return 13 ^M LF line-feed 10 ^J CRLF seque^ncia CR/LF DEL delete, rubout 127 E' considerado um caracter de controle qualquer byte cujos 7 bits menos significativos estejam na faixa 0-31 ou igual a 127. Neste manual os caracteres de controle podem estar escritos de diversas maneiras: CONTROL-A Denota o valor "1", comumente referenciado como "control A". .cp2 CTRL-A Abreviac,a~o de "CONTROL-A". Um caracter de controle normalmente e' teclado em um computador mantendo-se apertada a tecla marcada "CTRL" enquanto se aperta a tecla com o si'mbolo alfabe'tico correspondente, no caso "A". ^A Esta e' a notac,a~o dita "seta-para-cima" para o CONTROL. Muitos computadores "ecoam" caracteres de controle desta forma. E' considerado um caracter ASCII imprimi'vel, qualquer caracter na faixa 32-126 (do espac,o ao til). .cp3 ..@bd 2.4. Func,o~es de Conversa~o ..@iconversoes ..@ifuncoes de conversao Diversas func,o~es de conversa~o sa~o u'teis na descric,a~o do protocolo e no programa exemplo. A ma'quina onde roda o KERMIT so' precisa saber operar com dados inteiros; sa~o func,o~es que operam sobre o valor nume'rico de um caracter ASCII simples. char(x) = x + 32 transforma o inteiro "x" (desde que esteja na faixa 0- 94) num caracter ASCII imprimi'vel; 0 vira SP, 1 vira "!", 3 vira "#" etc. unchar(x) = x - 32 transforma o caracter "x" (desde que dentro da faixa imprimi'vel (SP-TIL) em um inteiro na faixa 0-94. ctl(x) = x ou 64 mapeia dentro dos caracteres de controle e suas representac,o~es imprimi'veis, preservando o bit de mais alta ordem. Se "x" for um caracter de controle, enta~o x = ctl(ctl(x)) ou seja: a mesma func,a~o e' usada para "controlizar" e "descontrolizar". E' assumido que o argumento seja um caracter de controle de verdade (0 a 31 ou 127) ou o resultado da aplicac,a~o do "ctl" em um caracter de controle (i. e': de 63 a 95). A transformac,a~o e' uma transformac,a~o mneumo^nica (^A vira A e vice-versa). .cp3 ..@bd 2.5. Jarga~o do Protocolo ..@ijargao do protocolo ..@iprotocolo, jargao Um pacote e' uma seque^ncia de caracteres claramente delimitada, composta de "campos de controle" aninhados em torno dos dados; os campos de controle permitem a um programa KERMIT determinar se os dados foram transmitidos correta e completamente. Um pacote e' a unidade de transmissa~o no Protocolo KERMIT. "ACK" e' "acknowledge" ou seja: "conhecimento". Um pacote que e' mandado para acusar o recebimento de um outro pacote. Na~o deve ser confundido com o caracter ASCII "ACK". "NAK" e' "negative acknowledge" ou seja: "desconhecimento". E' um pacote enviado para dizer que um outro pacote recebido estava adulterado ou incompleto, que foi recebido um pacote errado ou que o pacote esperado na~o foi recebido. Na~o deve ser confundido com o caracter ASCII "NACK". Um TIMEOUT e' um evento que pode ocorrer se um dado esperado na~o chega num determinado espac,o de tempo. O programa gerando o pedido de input pode ligar uma interrupc,a~o por tempo para sair de uma leitura sem resposta e ativar procedimentos de recuperac,a~o. .pa .foKERMIT: Manual do Protocolo # .heRequisitos de Sistema ..@adu 3. Requisitos de sistema ..@iprotocolo, requisitos ..@irequisitos do protocolo O protocolo KERMIT requer que: - o HOST possa mandar e receber caracteres usando codificac,a~o ASCII atrave's de uma conexa~o fi'sica EIA RS- 232 privada ou discada; - todos os caracteres imprimi'veis sejam aceitos como entrada pelo HOST e na~o sejam transformados sob condic,a~o alguma (caso sejam convertidos - para EBCDIC, por exemplo - o programa KERMIT deve ser capaz de reconstruir o pacote na forma original, antes da transformac,a~o). Similarmente, qualquer rede ou equipamento de comunicac,a~o interveniente ("smart- modems", TELENET, concentradores de terminais, seletores de porta etc) na~o devem transformar ou "engolir" qualquer caracter ASCII imprimi'vel; - um caracter ASCII simples de controle possa passar de um sistema para o outro sem transformac,a~o; tal caracter e' usado para sincronismo de pacotes; normalmente e' CONTROL-A (SOH, ASCII 1) mas pode ser redefinido; - se um HOST exigir um terminador de linha para entrada de terminal, tal terminador deve ser um u'nico caracter ASCII de controle, como CR or LF, distintos do caracter de sincronismo de pacotes; - ao usar um terminal de controle de JOBs para transfere^ncia de arquivos, o sistema deve permitir que o programa KERMIT passe o terminal para o modo sem eco, comprimento infinito (sem wraparound ou inserc,a~o de CRLF pelo sistema operacional) e sem formatac,a~o de caracteres chegantes ou saintes (por exemplo: transformar minu'sculas em maiu'sculas, caracteres de controle em imprimi'veis etc.); resumindo: o terminal deve ser colocado em modo "bina'rio" ou "cru'" e (tomara!) restaurado depois a`s condic,o~es originais de operac,a~o; - o processador de entrada de terminal do HOST deva ser capaz de receber uma "rajada" de 40 a 100 caracteres em velocidades normais de transmissa~o; este e' o tamanho ti'pico de um pacote. Note que a maior parte desses requisitos impugnam o uso do KERMIT atrave's de conversores IBM-3270/ASCII. O protocolo KERMIT na~o requer que: - a conexa~o seja feita em qualquer baud rate determinada; - o sistema possa fazer XON/XOFF ou qualquer outro tipo de controle de fluxo; controle de fluxo (por hardware ou por software) pode ajudar mas na~o e' necessa'rio (veja sec,a~o "Contro^le de Fluxo"); - o sistema seja capaz de operac,a~o full-duplex; qualquer mistura de half e full duplex e' suportada; - que o sistema possa transmitir ou receber bytes de 8 bits; o KERMIT tomara' vantagem das conexo~es de 8 bits para transmitir arquivos bina'rios; se uma conexa~o de 8 bits na~o for possi'vel, os arquivos bina'rios podem assim mesmo ser manuseados utilizando-se codificaca~o de prefixo. .pa .heTexto Imprimi'vel VERSUS Dados Bina'rios ..@adu 4. Texto Imprimi'vel VERSUS Dados Bina'rios ..@idados, binarios ..@itexto, imprimivel Para transmissa~o entre sistemas diferentes, os arquivos devem ser associados a` uma das duas categorias: texto imprimi'vel ou dados bina'rios. Um texto imprimi'vel e' aquele que pode fazer sentido entre sistemas diferentes (um documento, um programa-fonte, um texto etc.). Ja' um arquivo bina'rio e' aquele que na~o faz (e provavelmente na~o pode fazer) sentido entre sistemas diferentes (um programa executa'vel, nu'meros armazenados num determinado formato interno etc.). Em sistemas de bytes de 8 bits, arquivos ASCII imprimi'veis te^m os bits de mais alta ordem zerados (ja' que o ASCII e' um co'digo de 7 bits) enquanto que arquivos bina'rios usam o bit de mais alta ordem de cada byte para dados (seu valor pode variar de byte para byte). NOTA: existem algumas excec,o~es, como sistemas que armazenam arquivos de texto no chamado "ASCII negativo" ou arquivos de texto produzidos por processadores de texto que utilizam o bit de mais alta ordem para indicar sublinhado, negrito ou outras indicac,o~es. Muitos computadores na~o tem como distinguir um texto imprimi'vel de um arquivo bina'rio, especialmente um que tenha vindo de um sistema diferente. Porisso o usua'rio pode ter que dar comandos expli'citos para o KERMIT de forma a fazer com que ele fac,a converso~es. .cp3 ..@bd 4.1. Arquivos de Texto Imprimi'vel ..@itexto, imprimivel ..@iarquivo, imprimivel A principal meta do KERMIT e' transformar arquivos contendo textos imprimi'veis u'teis no sistema alvo depois da transfere^ncia. Isto exige uma representac,a~o padra~o para o texto durante a transmissa~o. O padra~o KERMIT e' simples: caracteres de 7 bits com "registros lo'gicos" (linhas) delimitados por CRLF's. E' da responsabilidade dos sistemas que na~o armazenam arquivos imprimi'veis desta forma executar as converso~es necessa'rias sobre entradas e sai'das. Por exemplo: ma'quinas de grande porte I.B.M. podem retirar brancos da direita na sai'da e acrescenta'-los de volta na entrada; o UNIX precedera' com um CR seu terminador normal de registro, um LF, na sai'da e o descartara' na entrada. Ale'm disso, os grandes sistemas I.B.M. devem fazer uma traduc,a~o EBCDIC/ASCII para arquivos de texto. Nenhuma outra conversa~o (p.e.: expansa~o de TAB) e' feita sobre arquivos de texto. Foi preferido assim por causa da maneira como os arquivos de texto sa~o armazenados na maioria dos microcomputadores e em muitos outros sistemas. Na maioria dos casos nenhuma transformac,a~o e' necessa'ria. .cp3 ..@bd 4.2. Arquivos Bina'rios ..@iarquivo, binario Os arquivos bina'rios sa~o transmitidos como se fossem uma mera seque^ncia de caracteres. A diferenc,a para os arquivos imprimi'veis e' que o status do oitavo bit deve ser mantido. Quando arquivos bina'rios sa~o transmitidos para sistemas diferentes, o objetivo maior e' que possam ser trazidos de volta ao sistema original (ou a um similar) intacto; nenhuma conversa~o especial deve ser feita durante a transmissa~o, a na~o ser aquela necessa'ria para que os dados possam passar pelo meio de transmissa~o. Para arquivos bina'rios, a transmissa~o a 8 bits e' permitida entre dois KERMITs desde que eles possam controlar o valor do bit de paridade e que nenhum equipamento de comunicc,a~o interveniente possa alterar este valor. Neste caso o oitavo bit de um caracter transmitido sera' igual ao original, depois de ter sido feito qualquer prefixac,a~o de controle. Quando pelo menos um dos lados na~o puder controlar o bit de paridade, um caracter especial de prefixo pode ser inserido, como descrito abaixo. Sistemas que na~o armazenam dados bina'rios em bytes de 8 bits ou cuja palavra na~o tem um nu'mero de bits mu'ltiplo de 8 podem fabricar um mecanismo especial para transferir arquivos bina'rios em "modo imagem". Isto pode ser feito dentro do protocolo ba'sico fazendo-se com que os dois lados implicitamente concordem com um esquema de compactac,a~o dos dados em caracteres ASCII de 7 ou 8 bits ou enta~o podem ser opcionalmente usadas facilidades e atributos de arquivo mais flexi'veis. O primeiro me'todo e' usado nas ma'quinas PDP-10, de 36 bits por byte, onde os textos sa~o armazenados em 5 bytes de 7 bits por palavra; o valor do "bit i'mpar" e' enviado como o bit de paridade de cada quinta palavra. .pa .heTransfere^ncia de Arquivos ..@adu 5. Transfere^ncia de Arquivos ..@iarquivo, transferencia ..@itransferencia de arquivos O protocolo de transfere^ncia de arquivos acontece numa transac,a~o. Uma transac,a~o e' uma troca de pacotes comec,ando com um SEND-INIT (S) e terminando com um BREAK-TRANSMISSION (B) ou ERROR (E) e pode incluir a transfere^ncia de um ou mais arquivos, todos na mesma direc,a~o. Uma transac,a~o tambe'm pode ser considerada terminada quando um dos lados parou sem enviar um pacote de erro. De forma a diminuir imprevistos, os pacotes KERMIT nao conte'm caracteres de controle, exceto um especialmente designado para marcar o ini'cio de um pacote. Exceto pelo marcador de pacote, somente caracteres imprimi'veis sa~o transmitidos. A sequencia a seguir caracteriza a operac,a~o KERMIT ba'sica; o transmissor e' a ma'quina que estiver mandando arquivos; o receptor e' a que os esta' recebendo. 1. O transmissor manda um pacote SEND-INIT (S) para especificar seus para^metros (comprimento do pacote, timeout etc.; explicados abaixo). 2. O receptor envia um pacote ACK (Y), com seus pro'prios para^metros no campo de dados. 3. O transmissor manda um FILE-HEADER (F), com o nome do arquivo em seu campo de dados. 4. O receptor "ACKceita" o pacote F mandando um pacote ACK sem informaca~o em seu campo de dados (opcionalmente, o campo de dados podera' conter o nome sob o qual o guardara' o arquivo que vai receber). 5. O transmissor envia o conteu'do do arquivo em pacotes do tipo "D". Qualquer caracter fora da faixa imprimi'vel e' prefixado e substitui'do por um equivalente que o seja. Cada pacote D tem que ser aceito ("Y") antes que o pro'ximo possa ser transmitido. 6. Quando todos os dados do arquivo tiverem sido transmitidos, transmissor manda um pacote de fim-de- arquivo (Z). 7. O receptor informa que tudo bem com um pacote ACK (Y). 8. Caso haja outro arquivo a ser transmitido, o processo e' repetido a partir do passo 3. 9. Quando na~o existirem mais arquivos a serem transmitidos, o transmissor envia um pacote de fim-de- transmissa~o (B). 10. O receptor manda um ACK (Y). Isto encerra a transac,a~o e desmonta a conexa~o lo'gica (a conexa~o fi'sica permanece aberta). Cada pacote tem um nu'mero de seque^ncia, que comec,a em ZERO com o SEND-INIT. A validac,a~o (ACK ou NAK) tem o mesmo nu'mero do pacote sendo validado. Uma vez que um pacote tenha recebido um ACK, esse nu'mero e' incrementado de 1, mo'dulo 64. Se o transmissor for remoto, ele espera, durante um certo tempo (algo como de 5 a 30 segundos) antes de transmitir o SEND-INIT, de forma a dar ao usua'rio tempo para ESCapar de volta ao KERMIT LOCAL e dizer a ele para receber arquivos. .cp3 ..@bd 5.1. Condicionando o Terminal ..@iterminal, condicionando o - ..@icondicionando o terminal Normalmente o KERMIT e' usado com o usua'rio sentado defronte a um microcomputador conectado a um sistema remoto de time-sharing, atrave's de uma porta de comunicac,a~o. O KERMIT remoto esta' usando seu pro'prio "terminal de controle" de JOBs para transfere^ncia de arquivos. Enquanto a porta do micro e' um mero equipamento, um terminal de controle de JOBs de um computador de time-sharing e' qualquer coisa de especial e frequentemente executa servic,os que interfeririam na operac,a~o normal do KERMIT. Tais servic,os incluem eco (em sistemas full-duplex), marcac,a~o de linhas com a seque^ncia CRLF quando atingida a "largura" da tela do terminal, pausa no "fim da tela", avisos do sistema, conversa~o alfabe'tica (minu'sculas em maiu'sculas), interpretac,a~o de caracteres de controle etc. Os programas KERMIT que rodam em mainframes devem estar preparados para inibir tantos desses servic,os quanto possi'vel antes de iniciar uma comunicac,a~o de pacotes e restaura'-los depois. Inibir tais servic,os e' normalmente conhecido como "colocando o terminal em modo bina'rio". O uso do KERMIT de equivalentes imprimi'veis dos caracteres de controle, comprimentos de pacotes varia'vel, marcadores e prefixos redefini'veis e tolera^ncia de deixar aparecer qualquer caracter entre pacotes sem efeitos adversos, da' uma boa margem de adaptabilidade para aqueles sistemas que na~o permitem inibir algumas (ou qualquer) dessas facilidades. .cp3 ..@bd 5.2. Timeouts, NAKs e Retries. ..@itimeout ..@iNAK ..@iretransmissoes ..@iretries ..@itemporizacao Se um programa KERMIT for capaz de preparar uma interrupc,a~o por tempo ou um limite de tempo para um pedido de entrada, deve fazer isto sempre que for tentar ler um pacote da linha, ao transmitir ou receber arquivos. Lido um pacote, deve desligar o temporizador. Se um programa KERMIT for capaz de ativar uma interrupc,a~o por tempo ou um limite de tempo em um pedido de input, deve faze^-lo sempre que for tentar ler um pacote da linha de comunicac,a~o, na~o importa se transmitindo ou recebendo um arquivo. Lido o pacote, o temporizador deve ser desativado. Se o transmissor entra em timeout esperando um ACK, deve retransmitir o mesmo pacote, repetindo este procedimento um certo nu'mero de vezes ate' um limite de tentativas ou ate' receber um ACK. Se o receptor entra em timeout esperando um pacote, pode tanto mandar um pacote NAK pelo pacote esperado quanto um pacote ACK pelo u'ltimo pacote que tenha recebido. Se um pacote do transmissor for danificado ou perdido (o primeiro detetado por um checksum errado, o segundo por um nu'mero de seque^ncia incrementado de mais de 1), o receptor manda um NAK pelo pacote adulterado ou perdido. Se um ACK ou um NAK do receptor for alterado ou perdido, o transmissor o ignora; em tal caso um dos dois lados entra em timeout e retransmite. Deve ser mantido um contador de retransmisso~es e um limite para ele, normalmente deixado em torno de 5. Quando quer que um pacote seja retransmitido (por timeout ou NAK) o contador e' incrementado. Quando atinge seu limite, ele e' zerado e a transac,a~o encerrada. Se nenhum dos lados for capaz de trabalhar com timeout, uma facilidade de intervenc,a~o manual deve estar disponi'vel no KERMIT local. Tipicamente isto funciona testando-se periodicamente o teclado; caso haja um input, CR por exemplo, o programa deve tomar o mesmo procedimento que tomaria em caso de timeout. O KERMIT local mante'm uma tela informativa que permite ao usua'rio detetar quando o tra'fego para. Neste ponto uma intervenc,a~o manual deve acabar com o trancamento. Sistemas compartilhados que tendem a ficar lentos quando pesadamente usados, devem ajustar seus intervalos de timeout baseados em pacotes, de acordo com a carga do sistema, de modo que uma transfere^ncia na~o falhe simplesmente porque o sistema esta' muito lento. Normalmente somente um dos lados deve estar trabalhando com timeouts; de prefere^ncia o lado que tiver maior conhecimento do seu ambiente (carga do sistema, baud rate etc), de modo a otimizar o intervalo de timeout para cada pacote. Se os dois lados estiverem trabalhando com timeout, seus intervalos devem diferir o suficiente para evitar coliso~es. .cp3 ..@bd 5.3. Erros ..@ierros ..@itransferencia, erros Durante uma transferencia de arquivos, o transmissor pode encontrar um erro de I/O no disco ou o receptor pode tentar gravar em um disco protegido ou, mesmo, cheio. Qualquer condic,a~o adversa ao sucesso de uma transmissa~o de um arquivo e' chamada "erro fatal". Erros fatais devem ser detetados e a transmissa~o ser cancelada elegantemente, com as informac,o~es pertinentes dadas ao usua'rio. Os pacotes de erro prove^em um mecanismo para atender tal premissa. Se acontece um erro fatal, tanto no lado que transmite quanto no lado que recebe, o que encontrou o erro deve mandar um pacote (E) de erro. O pacote "E" conte'm uma breve mensagem, textual, em seu campo de dados. Os dois lados devem estar preparados para receber um pacote de erro a qualquer tempo durante a transac,a~o. Neste caso os dois lados devem parar e voltar ao modo comando de usua'rio. Um SERVER deve voltar a esperar comandos do USER, que deve mostrar a mensagem de erro na tela. Na~o existe provisa~o para mandar mensagens de erros na~o fatais, avisos ou outras informac,o~es durante uma transac,a~o. Ate' que isto seria possi'vel mas requereria que ambos os lados concordassem em usar a ativac,a~o de um bit na ma'scara de capacidade, uma vez que antigos KERMITs na~o sabem desta facilidade e poderiam entrar em estado de erro fatal. De qualquer forma a utilidade de tal facilidade e' questiona'vel, ja' que ningue'm garante que o usua'rio vai estar presente para ler tais mensagens nos momentos em que elas forem emitidas; mesmo que sejam gravadas para posterior observac,a~o, em algum tipo de "caixa postal", suas significa^ncias podem ser diminui'das conforme for passando o tempo ate' serem lidas pelo usua'rio. Veja a sec,a~o sobre robustez, abaixo. .cp3 ..@bd 5.4. Heuri'stica ..@iheuristica Durante qualquer transac,a~o, diversas heuri'sticas sa~o u'teis: 1. Um NAK pelo pacote corrente e' equivalente a um ACK pelo pacote anterior (mo'dulo 64). Isto trata a situac,a~o muito comum na qual um pacote e' recebido com sucesso e aceito (ACK), mas o ACK e' perdido. O lado do ACK, enta~o, entra em timeout esperando pelo pro'ximo pacote e manda um NAK por ele. O lado que recebe o NAK pelo pacote n+1 ao esperar um ACK pelo pacote n, simplesmente retransmite o pacote n+1. 2. Se um pacote n chega mais de uma vez, mande um ACK e dispense-o. Isto pode acontecer quando o primeiro ACK se perdeu. Retransmitir o ACK e' necessa'rio e suficiente (na~o grave o pacote novamente!!!). 3. Ao abrir uma conexa~o, esvazie todo o buffer de entrada da linha antes de tentar receber ou transmitir o pri meiro pacote. Isto e' especialmente importante se o outro lado estiver em modo recepc,a~o (ou agindo como um SERVER), em cujo caso pode ter mandado NAKs perio'dicos pelo seu esperado pacote de comando ou SEND-INIT. Se voce na~o faz isso, voce pode descobrir que existem NAKs suficientes para impedir uma transfere^ncia: voce manda um SEND-INIT e le^ a resposta, que e' um NAK (ja' velho no buffer); retransmite o SEND-INIT, ganha um outro velho NAK e fica assim ate' atingir o limite de re transmisso~es e desiste antes de conseguir o ACK que estava esperando depois de todos os velhos NAKs. Se o nu'mero de NAKs for menor que o limite de retransmis so~es, enta~o cada pacote pode ser retransmitido diversas vezes. 4. Da mesma forma, apo's ler um pacote, com sucesso ou na~o, voce deve limpar o buffer de entrada. Na~o deve haver coisa alguma para voce la', mesmo, ja' que o outro lado deve normalmente esperar que voce envie sue pacote de resposta. Deixar de limpar o buffer pode resultar numa propagac,a~o de repetic,a~o de um pacote devido a NAKs empilhados. Obs.: sob "Facilidades Opcionais", mais sobre heuri'stica... .cp3 ..@bd 5.5. Nomes de Arquivos ..@inomes de arquivos ..@iarquivo, nomes de A sintaxe para nomes de arquivos pode variar muito de sistema para sistema. Para evitar problemas, sugere-se que os nomes de arquivos sejam representados nos pacotes (F) de cabecalho de arquivo numa "forma normal", por default, isto e': deve haver uma opc,a~o para passar por cima de tais converso~es. 1. Apague todos os atributos e pathnames das especificac,o~es de arquivo. O pacote de cabec,alho na~o deve conter nomes de dispositivos ou direto'rio, caso contra'rio isto pode fazer com que o receptor tente gravar o arquivo em uma area inacessi'vel ou inexistente ou, ainda, resultar em um nome de arquivo muito estranho. 2. Depois de retirados quaisquer adendos do nome do arquivo, converta o que sobrou para a forma "NOME.TIPO", sem restric,o~es quanto a comprimento, desde que caiba no campo de dados do pacote "F" e: a) na~o inclua mais que um ponto b) use somente di'gitos e letras maiu'sculas no nome e tipo. Caracteres especiais como "$", "&", "-", "_" etc., devem ser evitados, ja' que provavelmente causara~o problemas no outro sistema. O receptor, claro, na~o pode depender do transmissor para seguir esta convenc,a~o e deve tomar certas precauc,o~es. No entanto, ja' que a maioria dos sistemas trabalham com a noc,a~o de nome e tipo de arquivo, esta convenc,a~o permitira' que esses i'tens sejam expressos de uma forma que sistemas diferentes possam compreender. Esta notac,a~o em particular foi adotada simplesmente por ser a mais comum. O receptor deve se preocupar com o comprimento dos campos de nome e tipo em um nome de arquivo. Se um deles for muito extenso, deve ser truncado. Se o resultado, truncado ou na~o, e' o mesmo que algum arquivo ja' existente na mesma a'rea, o receptor deve ser capaz de evitar gravar por cima do arquivo mais antigo. As implementac,o~es de KERMIT que, por default, convertem as especificac,o~es de arquivos para uma forma normal, devem ter uma opc,a~o para deixar de lado esta facilidade. Isto e' mais u'til ao se transferir arquivos entre sistemas similares, talvez usado em conjunc,a~o com o modo "imagem" de arquivo. Isto pode permitir, por exemplo, um sistema UNIX mandar para outro toda uma a'rvore de direto'rio. .cp3 ..@bd 5.6. Robustez ..@iprotocolo, robustez ..@irobustez Uma grande facilidade do protocolo KERMIT e' a habilidade de transferir mu'ltiplos arquivos. Se um KERMIT em particular pode, realmente, ou na~o fazer isto depende da capacidade do programa e do sistema operacional do host (qualquer programa KERMIT pode receber arquivos mu'ltiplos). Se um programa KERMIT pode transmitir arquivos mu'ltiplos, deve tomar todo cuidado para mandar o grupo especificado inteiro. Se ele falha em enviar um arquivo em particular, na~o deve encerrar o batch inteiro mas, sim, ir ao pro'ximo e proceder ate' que uma tentativa seja feita para mandar cada um dos arquivos do grupo. Operar nesta robusta forma, no entanto, da' chance ao aparecimento de um problema: o usua'rio deve ser notificado de uma falha em transmitir algum arquivo. Infelizmente na~o e' suficiente dar uma mensagem na tela, ja' que o usua'rio pode na~o estar fisicamente presente. Uma melhor soluc,a~o seria fazer com que o transmissor tivesse um "log" opcional, com o nome de cada arquivo para o qual foi feita uma tentativa e informando se a tentativa teve e^xito e, se na~o, a raza~o. Auxi'lios adicionais para robustecer mais um programa KERMIT esta~o descritos na sec,a~o sobre facilidades adicionais, abaixo. .cp3 ..@bd 5.7. Controle de Fluxo ..@iXON/XOFF ..@icontrole de fluxo ..@ifluxo, controle de Em conexo~es full-duplex, controles de fluxo XON/XOFF podem, geralmente, ser usadas em conjunc,a~o com uma trans fere^ncia de arquivo via KERMIT, sem efeitos colaterais. Isto e' porque XOFF's sa~o mandados na direc,a~o oposta ao fluxo dos pacotes, de forma que na~o interfirira~o com os pacotes, pro priamente. XON/XOFF's, porisso, na~o precisam estar definidos em um programa KERMIT mas podem, por outro lado, ser utiliza dos pelo host. Se o host prove^ esta possibilidade, ela deve ser utilizada. Se os dois lados puderem responder aos sinais XON/XOFF, enta~o poderemos evitar os estouros de buffer e as onerosas retransmisso~es que isso implica. Acautele-se, pore'm, com a seguinte situac,a~o: o KERMIT remoto esta' mandando NAKs perio'dicos, o sistema local os esta' bufferizando a ni'vel de sistema operacional (porque o usua'rio na~o iniciou ainda o ponto final da transfere^ncia de arquivos); o buffer de linha local fica lotado, o sistema local manda XOFF, o remoto comec,a a bufferiza'-los, o usua'rio finalmente inicia o ponto final da transfere^ncia, limpa o buffer, o sistema operacional local manda XON e, enta~o os NAKs bufferizados remotamente aparecem, causando o problema descrito acima dos ecos de pacotes, apesar do buffer limpo no sistema local. Tambe'm podem ser empregados os controles de fluxo via sinais de modem, quando disponi'veis. .cp3 ..@bd 5.8. Tabela de Estados do Protocolo KERMIT Ba'sico ..@iestados do protocolo ..@iprotocolo, estados O protocolo KERMIT pode ser descrito como um conjunto de estados, transic,o~es e regras que dizem o que fazer ao acontecer uma mudanc,a de um estado para outro. Mudanc,as de estado ocorrem dependendo do tipo de pacotes que sa~o trans mitidos ou recebidos ou de erros que possam ocorrer. Os pacotes sempre va~o para frente e para tra's; o transmissor de um arquivo sempre manda pacotes de dados de algum tipo (ini cializac,a~o, cabec,alho, dados) e o receptor sempre devolve pacotes ACK ou NAK. Ao entrar em um dado estado, um certo tipo de pacote esta' sendo transmitido ou esperado (isto e' mostrado no tope da descric,a~o daquele estado). Como resultado da ac,a~o, va'rias respostas podem aparecer. Elas sa~o mostradas na coluna de eventos. Para cada evento, uma ac,a~o apropriada e' tomada e o protocolo entra em um novo estado. A tabela a seguir especifica a operac,a~o ba'sica do KERMIT. Por simplicidade, as condic,o~es de erro e timeouts foram omitidas mas a ac,a~o esta' como descrita acima. Opera c,o~es de SERVER e algumas das facilidades avanc,adas tambe'm foram omitidas. A tabela total de estados sera' mostrada no capi'tulo "Facilidades Opcionais". .pa ..@f Figura 5-1: Estados de Transmissa~o ================================== Novo Est. Evento Ac,a~o Est. === ===================== ============================= ==== **** Manda pacote SEND-INIT **** S recebe NAK ou mal ACK nenhuma S recebe bom ACK prepara parms., abre arq. SF outros nenhuma A **** Manda pacote de cabec,alho de arquivo **** SF recebe NAK ou mal ACK nenhuma SF recebe bom ACK enche buffer ou dados de arq. SD outros nenhuma A **** Manda pacote de dados de arquivo **** SD recebe NAK ou mal ACK nenhuma SD recebe bom ACK enche buffer ou dados de arq. SD fim de arquivo nenhuma SZ outros nenhuma A **** Manda pacote de fim de arquivo **** SZ recebe NAK ou mal ACK nenhuma SZ recebe bom ACK pega proximo arq. a enviar SF na~o mais arquivos nenhuma SB outros nenhuma A **** Manda pacote de break (EOT) **** SB recebe NAK ou mal ACK nenhuma SB recebe bom ACK nenhuma C outros nenhuma A .pa ..@f Figura 5-2: Estados de Recepc,a~o =============================== Novo Est. Evento Ac,a~o Est. === ===================== ============================= ==== **** Espera por pacote SEND-INIT **** R recebe SEND-INIT ACK c/ para^metros locais RF outros nenhuma A **** Espera por pacote de Cabec,alho de Arquivo **** RF recebe SEND-INIT ACK c/ para^metros locais ACK pre'vio foi perdido RF recebe SEND-EOF ACK (prev. foi perdido) RF recebe BREAK ACK C recebe cab.arq. abre arq., ACK RD outros nenhuma A **** Espera por pacote de dados de arquivo **** RD rec.pac.anterior(D,F) ACK de novo RD recebe EOF ACK, fecha o arquivo. RF recebe dados bons grava, ACK RD outros nenhuma A ..@f Figura 5-3: Estados Comuns a Transmitir e Receber ================================================= Novo Est. Evento Ac,a~o Est. === ===================== ============================= ==== C (envio completado) ini'cio A ("abortar") ini'cio .pa .heFormato dos Pacotes ..@adu 6. Formato dos Pacotes ..@ipacote, formato ..@iformato do pacote ..@bd 6.1. Campos ..@icampos do pacote ..@ipacote, campos O protocolo KERMIT e' construi'do em torno da troca de pacotes no seguinte formato: +------+-----+-----+------+------+-------+ | mark | len | seq | type | data | check | +------+-----+-----+------+------+-------+ onde todos os campos consistem de caracteres ASCII. Os campos sa~o os seguintes: .cp2 MARK (marca) E' o caracter de sincronismo que marca o ini'cio do pacote. Deve ser, normalmente, um CTRL-A, mas pode ser redefinido. .cp2 LEN (comprimento) Nu'mero de caracteres ASCII dentro do pacote que segue este campo. Em outras palavras: comprimento do pacote menos dois. Uma vez que este nu'mero e' transformado em um u'nico caracter atrave'z da func,a~o "char()", os contadores de caracteres em um pacote podem valer de 0 a 94, sendo 96 o tamanho ma'ximo de um pacote. O comprimento na~o inclui os caracteres de fim-de-linha ou de preenchimento, que esta~o fora do pacote e esta~o la' estritamente para benefi'cio do sistema operacional ou do equipamento de comunicac,a~o MAS INCLUI OS CARACTERES DE CHECAGEM DE BLOCO. .cp2 SEQ (seque^ncia) O nu'mero de seque^ncia do pacote, mo'dulo 64 (ou seja: varia de 0 a 63). Estes contadores, ao atingirem 63, voltam a 0 (viram zero a cada 64 pacotes). .cp2 TYPE (tipo) E' o pro'prio tipo do pacote, com uma letra. Os seguintes tipos de pacotes sa~o exigidos: D pacote de dados Y aceito (ACK) N na~o aceito (NAK) S SEND-INIT (troca de para^metros) B break na transmissa~o (EOT) F cabec,alho de arquivo Z fim de arquivo (EOF) E erro T reservado para uso interno O pacote NAK somente e' usado para indicar que o pacote esperado na~o foi corretamente recebido, nunca para suprir outros tipos de informac,a~o, como recusa em executar um servic,o pedido. O pacote NAK tem sempre seu campo de dados vazio. O pacote "T" e' usado internamente por muitos programas KERMIT para indicar que ocorreu um timeout. .cp2 DATA (dados) E' o "conteu'do" do pacote, se algum conteu'do for neces sa'rio naquele tipo de pacote, interpretado de acordo com o tipo de pacote. Carateres de controle (bytes cujos 7 bits de mais baixa ordem estiverem na faixa de controle ASCII 0-31 ou 127) sa~o prefixados por um caracter especial, geralmente "#" e "descontrolificados" via ctl(). Uma seque^ncia prefixada na~o pode ser quebrada de um pacote para o outro. Registros lo'gicos em arquivos imprimi'veis sa~o delimitados com CRLFs, devidamente prefixados (e.g.: #M#J). Registros lo'gicos na~o sa~o obrigados a corresponderem a pacotes. Quaisquer caracteres de prefixac,a~o sa~o inclui'dos no contador. A codificac,a~o opcional para 8 bits e para caracteres repetidos sera~o descritas posteriormente. CHECK (checagem de bloco) E' a checagem de bloco dos caracteres no pacote entre (mas na~o incluindo) a marca e o check. O check para cada pacote e' computado por ambos os lados e devem ser iguais se e' que o pacote deve ser aceito. Um checksum aritme'tico de um u'nico caracter e' o check normal e exigido. De forma a todos os bits de cada caracter de dado contribui'rem para tal ca'lculo, os bits 6 e 7 do valor final sa~o somados a` quantidade formada pelos bits de 0 a 5. Assim, se S for a soma aritme'tica dos caracteres ASCII, enta~o check = char((s + ((s and 192)/64)) and 63). Este e' o ca'lculo default e todos os KERMITs devem ser capazes de executa'-lo. Outros tipos opcionais de ca'lculo sera~o descritos mais tarde. O check de bloco e' baseado nos valores ASCII de todos os caracteres no pacote, inclusive caracteres de controle e caracteres de prefixac,a~o. Sistemas na~o-ASCII devem traduzir para ASCII antes de fazer os ca'lculos de check. .cp3 ..@bd 6.2. Terminador ..@iterminador ..@iCR ..@iterminador, CR Qualquer terminador de linha exigido pelo sistema pode ser inclui'do no pacote; costuma ser o CR. Terminadores de linha na~o sa~o considerados parte do pacote e na~o sa~o inclui' dos no contador de check. Na~o sa~o necessa'rios para o protoco lo e sa~o invisi'veis para ele, ja' que qualquer caracter pode aparecer entre pacotes. Se um host na~o puder receber um u'nico caracter de uma linha TTY, enta~o um terminador sera' neces sa'rio para transmitir para tal host. O terminador pode ser especificado no ini'cio da conexa~o. Algumas implementac,o~es de KERMIT tambe'm usam o terminador por uma outra raza~o: velocidade. Alguns sistemas na~o sa~o ra'pidos o suficiente para pegar um pacote e decodifica'-lo caracter a caracter sob velocidades mais altas; Recebendo "cegamente" todos os caracteres entre a marca e o EOL, sa~o capazes de absorver os caracteres que chegam a` toda velocidade e, enta~o, processa'-los calmamente. ..@iEOL ..@iterminador, EOL .cp3 ..@bd 6.3. Outros dados inter-pacotes. ..@idados inter-pacotes ..@ipacote, dados inter-pacote O espac,o entre pacotes pode ser utilizado para qualquer propo'sito desejado. Caracteres de handshaking podem ser necessa'rios em certas conexo~es, outras podem exigir controle de tela, outras ainda seque^ncias para manter os pacotes fluindo. .cp3 ..@bd 6.4. Codificac,a~o, Prefixac,a~o, Checagem de Bloco ..@icontrole, campos ..@icampos de controle ..@icodificacao ..@ipacote, codificacao ..@iprefixacao ..@ipacote, prefixacao ..@ibloco, checagem de ..@ichecagem de bloco Mark, len, seq, type e check sa~o campos de controle. Sa~o sempre campos de um u'nico caracter literal, exceto que o campo check pode ser expandido por um ou dois caracteres de check adicionais. Cada campo de controle e' codificado pela char() ou tomado literalmente mas nunca prefixados. Os campos de controle nunca conte'm dados de 8 bits. Os campos de dados (data) conte'm uma cadeia de caracteres onde quaisquer caracteres de controle sa~o codificados imprimivelmente e precedidos pelo prefixo de controle. A decisa~o de prefixar um caracter desta forma depende de seus 7 bits menos significativos terem um valor dentro da faixa ASCII de controle (0-31 ou 127). Os caracteres de prefixo que aparecem nos dados devem ser, eles mesmos, precedidos pelo prefixo de controle mas, diferentemente dos caracteres de controle, eles retem seus valores literais no pacote. O tratamento do bit mais significativo ("oitavo") de um byte de dados e' o seguinte: * se o canal de comunicac,a~o permite 8 bits por caracter, enta~o o valor original do oitavo bit e' mantido no caracter de prefixo; por exemplo: um byte correspondendo a um CTRL-A com o oitavo bit ligado, e' transmitido como um prefixo de controle, normalmente "#", com o oitavo bit desligado, seguido por ctl(^A) com o oitavo bit ligado; em notac,a~o bina'ria seria 00100110 10000001 neste caso, o oitavo bit entra em todos os ca'lculos de checagem de bloco; * se o canal de comunicac,a~o ou um dos hosts exigem paridade em cada caracter e ambos os lados sa~o capazes de prefixac,a~o de 8 bits, enta~o o oitavo bit sera' usado para paridade e na~o deve ser inclui'do na checagem de bloco; prefixac,a~o de oitavo bit e' uma opc,a~o que esta' descrita em mais detalhes na sec,a~o 8, abaixo; * se se estiver usando paridade mas na~o prefixac,a~o de oitavo bit, o valor do oitavo bit de cada byte de dados sera' perdido e arquivos bina'rios na~o sera~o transmitidos corretamente; novamente, o oitavo bit na~o entra na checagem de bloco. Os campos de dados de todos os pacotes esta~o sujeitos a codificac,a~o prefixada, exceto nos pacotes "S", "I" e "A" e seus ACKs (veja adiante). .pa .heConexa~o Inicial ..@adu 7. Conexa~o Inicial ..@iconexao inicial A conexa~o inicial ocorre quando o usua'rio iniciou um programa KERMIT nas duas pontas da conexa~o fi'sica. Um KERMIT foi ativado para transferir um arquivo e o outro para recebe- lo. O KERMIT receptor espera por um pacote SEND-INIT do KERMIT transmissor. Na~o importa se o KERMIT transmissor foi iniciado antes ou depois do KERMIT receptor (se antes, o pacote SEND-INIT deve ser retransmitido periodicamente ate' que o KERMIT receptor o aceite). O campo de dados do pacote SEND-INIT e' opcional; campos posteriores podem ser omitidos (ou deixados em branco, isto e': contendo espac,os) para aceitar ou especificar valores default. O pacote SEND-INIT conte'm uma string de informac,o~es de configurac,a~o no seu campo de dados. O receptor manda um ACK pelo SEND-INIT, cujo campo de dados conte'm seus pro'prios para^metros de configurac,a~o. O campo de dados do SEND-INIT e do ACK pelo SEND-INIT sa~o literais ou seja: na~o ha' codificac,a~o de prefixo. Isto e' porque as duas partes na~o saberiam fazer codificac,a~o de prefixo ate' depois da troca de dados de configurac,a~o. E' importante notar que campos recentemente inventados sa~o acrescentados a` direita, de forma que os antigos KERMITs, que na~o tem co'digo para lidar com os novos campos, podem agir como se eles simplesmente na~o existissem. Por esta raza~o o valor default para qualquer campo, indicado por branco, deve resultar no comportamento anterior a` definic,a~o ou inclusa~o do novo campo. 1 2 3 4 5 6 +------+------+------+------+-----+------+ | MAXL | TIME | NPAD | PADC | EOL | QCTL | +------+------+------+------+-----+------+ 7 8 9 10... +------+------+------+------ | QBIN | CHKT | REPT | CAPAS +------+------+------+------- Os campos sa~o os seguintes (a primeira pessoa, "eu", e a segunda, "voce", sa~o usadas para distinguir os dois lados). Os campos sa~o codificados "imprimivelmente" usando-se a func,a~o char(), a menos que indicado de forma diferente. .cp2 1. MAXL E' o comprimento do maior pacote que eu quero receber, um nu'mero ate' 94. Voce responde com o ma'ximo que quer receber. Isto permite que os sistemas se adaptem aos seus tamanhos de buffer ou a`s condic,o~es do meio de transmissa~o. .cp2 2. TIME Nu'mero de segundos depois dos quais eu quero que voce me coloque em timeout ou esperar um pacote meu. Voce responde com a quantidade de tempo que eu devo esperar pacotes de voce. Isto permite que ambos os lados se acomodem a diferentes velocidades de linha ou a outros fatores que possam causar problemas de tempo. Somente um dos lados precisa trabalhar com timeout. Se os dois lados o fazzem, os tempos de timeout na~o devem ser pro'ximos. .cp2 3. NPAD O nu'mero de caracteres de preenchimento que eu quero que precedam cada pacote que chegue a mim; voce responde da mesma forma. Preenchimento e' necessa'rio ao se trabalhar em sistemas half-duplex que precisam de algum tempo para inverter a direc,a~o da transmissa~o, embora na pra'tica tal situac,a~o seja normalmente manuseada por um mecanismo de handshaking. .cp2 4. PADC E' o caracter de controle que eu preciso para preenchimento, se for o caso, transformado pela func,a~o ctl() (na~o chr()) para torna'-la imprimi'vel. Voce me responde com o seu. Normalmente e' o NUL (ASCII 0) mas alguns sistemas usam o DEL (127). Este campo deve ser ignorado se o valor de NPAD for zero. .cp2 5. EOL O caracter que eu preciso para terminar um pacote que chega, se algum. Voce responde com o seu. A maioria dos sistemas que exigem um terminador de linha para um input de terminal aceitam CR para tal propo'sito. (note que, ja' que na~o ha' forma de se especificar que o EOL na~o deve ser enviado, e' melhor usar ctl() para este campo, ao inve's de char() mas agora e' muito tarde...). .cp2 6. QCTL (VERBATIM) O caracter imprimi'vel que eu vou usar para marcar caracteres de controle. Normalmente e, por default, "#". Voce responde com o que voce vai usar. Os campos a seguir esta~o relacionados com o uso de facilidades opcionais do protocolo KERMIT, descritas no capi'tulo "Facilidades Opcionais". .cp2 7. QBIN (VERBATIM) O caracter imprimi'vel que eu vou usar para marcar caracteres que tenham o oitavo bit ligado, para transmitir arquivos bina'rios quando o bit de paridade na~o puder ser usado para dados. Ja' que este tipo de marcac,a~o aumenta o overhead, tanto de transmissa~o quanto de processamento, normalmente deve ser evitado. O caracter de marcac,a~o deve estar na faixa ASCII 33-62 ("!" a ">") ou 96-126 ("@" a "^") mas diferente do caracter que marca caracteres de controle. Este campo e' interpretado da seguinte maneira: Y eu concordo com marcac,a~o do oitavo bit se voce pedir N na~o farei marcac,a~o do oitavo bit & (ou qualquer outro caracter na faixa 33-62 ou 96- 126): eu quero fazer marcac,a~o do oitavo bit com este caracter (isto sera' feito se o outro KERMIT colocar um Y neste campo ou responder com o mesmo caracter de prefixac,a~o, como &); o caracter prefixo de marcac,a~o recomendado e' "&" qualquer outra coisa: na~o sera' feita a marcac,a~o do oitavo bit. Note que este esquema permite que qualquer lado inicie o pedido e que a ordem na~o importa. Por exemplo: um micro capaz de se comunicar em 8 bits normalmente usara' um "Y" neste campo, enquanto um mainframe que usa paridade sempre usara' um "&". Na~o importa quem manda primeiro: esta combinac,a~o resultara' numa "eleic,a~o" da marcac,a~o do oitavo bit. .cp2 8. CHKT Tipo de checagem, o me'todo para detec,a~o de erros. E' "1" para checksum de um caracter (o me'todo normal e exigido), "2" para checksum de dois caracteres (opcional) e "3" para checksum CRC-CCITT (opcional). Se voce responde concordando, o me'todo designado sera' usado; sena~o sera' o checksum de um so' caracter. .cp2 9. REPT E' o prefixo que quero usar para indicar um caracter repetido. Pode ser qualquer caracter imprimi'vel na faixa ASCII 33-62 ou 96-126 mas diferente dos prefixos de oitavo bit e de controle. Espac,o (32) indica que na~o deve ser executado o processamento de contagem de repetic,o~es. Til ("~") e' o prefixo normal e recomendado. Se voce na~o responde identicamente, esta facilidade na~o sera' usada. Grupos de pelo menos 3 ou 4 caracteres identicos podem ser transmitidos mais eficientemente usando-se um contador de repetic,o~es, embora uma implementac,a~o individual possa preferir usar um princi'pio diferente. 10-?. CAPAS Ma'scara de bits, onde cada bit ligado representa uma capacidade do KERMIT. Cada caracter contem um campo de 6 bits (transformado pela func,a~o char()), cujo bit de mais baixa ordem estara' ligado se a este se segue outro byte de capacidades e desligado se este for o u'ltimo. Ate' agora as capacidades definidas sa~o as seguintes: .cp3 #1 reservada #2 reservada #3 habilidade em receber pacotes "A" (atrib. de arquivos). .cp7 O byte de capacidades ate' agora definido se apresenta assim: BIT5 BIT4 BIT3 BIT2 BIT1 BIT0 +----+----+----+----+----+----+ | #1 | #2 | #3 | -- | -- | 0 | +----+----+----+----+----+----+ Se todas estas capacidades estiverem "ligadas", o valor do byte seria 70 (octal). Quando as capacidades 4, 5 e 6 sa~o acrescentadas, a ma'scara de capacidade fica assim: BIT5 BIT4 BIT3 BIT2 BIT1 BIT0 +----+----+----+----+----+----+ | #1 | #2 | #3 | #4 | #5 | 1 | +----+----+----+----+----+----+ BIT5 BIT4 BIT3 BIT2 BIT1 BIT0 +----+----+----+----+----+----+ | #6 | -- | -- | -- | -- | 0 | +----+----+----+----+----+----+ Pro'ximos 4: campos reservados Instalac,o~es que queiram acrescentar seus pro'prios para^metros a` negociac,a~o do ini'cio da conexa~o, devem comec,ar no quinto campo depois do u'ltimo byte de capacidade. Qualquer campo no meio pode ser deixado em branco (isto e': podem conter o caracter SP, "espac,o"). Estes campos esta~o reservados para futuro uso pelo protocolo KERMIT. Os prefixos de controle, oitavo bit e de repetic,a~o devem ser distintos entre si. O KERMIT receptor responde com um pacote ACK ("Y") no mesmo formato para indicar suas pro'prias prefere^ncias, opc,o~es e para^metros. O ACK na~o precisa conter o mesmo nu'mero de campos como o SEND-INIT. Deste ponto, os dois programas KERMIT esta~o configurados para se comunicarem ate' o fim da transac,a~o. No caso de se usar a marcac,a~o do oitavo bit, um dos lados deve informar o caracter a ser usado e o outro concordar com um "Y" no mesmo campo mas a ordem em que isto ocorre na~o importa. Da mesma forma para os checksums: se um dos lados pede o de dois caracteres e o outro diz "1" (ou na~o diz) o jeito e' usar "1", ja' que na~o se pode esperar que todas as implementac,o~es trabalhem com dois bytes em checksums e/ou CRCs. E para contadores de repetic,a~o: se o campo de repetic,a~o do SEND-INIT e do ACK na~o concordam entre si, na~o havera' o processo. Todos os campos do SEND-INIT sa~o opcionais. O campo de dados pode ser deixado completamente em branco. Da mesma forma, campos intervenientes podem ter seus defaults acionados pelo fato de serem deixados em branco. As implementac,o~es de KERMIT devem saber o que fazer nesses casos, principalmente aplicar os defaults apropriados. Os defaults sa~o os seguintes: .cp9 MAXL = 80 NPAD = 0, sem preenchimento PADC = 0 (NUL) EOL = CR QCTL = o caracter "#" QBIN = nenhum, na~o faz marcac,a~o do oitavo bit CHKT = "1" (checksum de um caracter) REPT = na~o MASK = tudo zero (sem capacidades especiais) Na~o existem negociac,o~es prolongadas na seque^ncia inicial de conexa~o: existe apenas um SEND-INIT e um ACK de resposta; tudo deve ser acionado nesta troca. O primeiro SEND-INIT pode na~o passar se o KERMIT transmissor assumir coisas erradas acerca do receptor. Por exemplo, o receptor pode exigir alguma paridade, algum tipo de preenchimento, handshaking ou um EOL especial para que consiga ler o pacote SEND-INIT. Por esta raza~o, deve haver um modo do usua'rio especificar o que quer que seja necessa'rio para conseguir fazer passar o primeiro pacote. Na~o e' provido um campo de paridade no pacote SEND-INIT porque poderia na~o ser u'til, va'lido. Se o transmissor exige um certo tipo de paridade, tambe'm o estara' utilizando (e mandando). Se o receptor na~o souber disto de antema~o, antes de receber o SEND-INIT, ele na~o sera' capaz de receber o pacote SEND-INIT. .pa .heFacilidades Opcionais ..@adu 8. Facilidades Opcionais ..@ifacilidades opcionais ..@iopcionais, facilidades Discutimos, nas sec,o~es anteriores, as operac,o~es ba'sicas, exigidas para qualquer implementac,a~o de KERMIT. Nas pro'ximas sec,o~es discutiremos as facilidades avanc,adas opcionais. ..@bd 8.1. Prefixac,a~o de oitavo bit e contador de repetic,o~es ..@iprefixacao de oitavo bit ..@irepeticoes, contador ..@ioitavo bit, prefixacao ..@icontador de repeticoes A marcac,a~o de caracteres de controle e' obrigato'ria. Ale'm disto, a prefixac,a~o tambe'm pode ser usada para quantidades de 8 bits ou contadores de repetic,a~o, quando os dois programas KERMIT concordam em faze^-lo. Uma prefixac,a~o de oitavo bit pode permitir que dados bina'rios passem atrave's de links fi'sicos de 7 bits. Prefixac,a~o de contadores de repetic,a~o podem melhorar dramaticamente o throughput de certos tipos de arquivo; arquivos bina'rios (programas executa'veis particularmente) e textos estruturados (colunares ou altamente identados) tendem a ser os maiores beneficia'rios. Quando mais de um tipo de prefixac,a~o esta' em efeito, um u'nico caracter de dados pode ser precedido por mais de um caracter de prefixac,a~o. Um receptor nunca fara' qualquer tipo de prefixac,a~o, ja' que a prefixac,a~o so' ocorre no campo de dados e o receptor so' responde com ACKs ou NAKs com campos de dados vazios ou especiais. O processamento de contadores de repetic,a~o so' pode ser requisitado pelo transmissor e so' sera' utilizado pelo transmissor se o receptor concordar. A prefixac,a~o de oitavo bit e' um caso especial, porque seu uso normalmente na~o e' desejado, ja' que aumenta muito o overhead tanto na transmissa~o quanto na recepc,a~o. No entanto, uma vez que e' o u'nico mecanismo direto para transmissa~o de arquivos bina'rios disponi'vel aos sistemas que usurpam o oitavo bit para paridade, um receptor deve ser capaz de pedir ao trans missor que fac,a a marcac,a~o do oitavo bit, ja' que a maioria dos transmissores normalmente na~o o fara~o por default. O prefixo de repetic,a~o e' imediatamente seguido por um caracter (1 byte) de contador, codificado via func,a~o char(). seguido pelo pro'prio caracter (talvez prefixado por marca dores de controle ou de oitavo bit, como explicado abaixo). O contador de repetic,o~es pode expressar valores de 0 a 94. Se um caracter aparece mais de 94 vezes em uma linha, deve ser "cortado" em 94, emitido com todos os prefixos apropriados assim por diante ate' que todos tenham sido transmitidos. .cp 14 representac,a~o com contador de caracter marcada repetic,o~es para 6 A A ^(A ("(" e' ASCII 40-32=6) ^A #A ^(#A 'A &A ^(&A '^A &#A ^(&#A # ## ^(## '# &## ^(&## & #& ^(#& '& &#& ^(&#& ^ #^ ^(#^ '^ &#^ ^(&#^ NUL #@ ^^#@^:#@ (120 NULs) A representa qualquer caracter imprimi'vel ^A qualquer caracter de controle 'X qualquer caracter com o oitavo bit ligado # e' usado para marcar caracteres de controle & marca caracteres cujo oitavo bit esta' ligado O contador de repetic,o~es deve sempre preceder qualquer outro caracter de prefixac,a~o; e' tomado literalmente (depois de ter sido transformado pela unchar(). Por exemplo: "#" e "&" seguindo imediatamente um "^" denota contadores de repetic,a~o, na~o caracteres de oito bits ou de controle. O caracter de marcac,a~o de controle "#" cerca mais proximamente o caracter de dados, enta~o o prefixo para oito bits e, ai', o contador de repetic,o~es. Em outras palavras a ordem e': prefixo de repetic,a~o e contador marca de oito bits marca de controle caracter de dado. Como ilustrac,a~o, note que &#A na~o e' equivalente a #&A. Quando o bit de paridade esta' disponi'vel para dados, na~o deve ser utilizada a marcac,a~o de oitavo bit e o oitavo bit do caracter prefixado tera' o mesmo valor do oitavo bit do byte original de dados. Neste caso, a tabela fica assim: .cp 14 representac,a~o com contador de caracter marcada repetic,o~es para 6 'A 'A ^('A '^A #'A ^(#'A '# #'# ^(#'# '& '& ^('& Note que, desde que na~o se esta' fazendo marcac,a~o de oitavo bit, "&" na~o esta' sendo usado como um caracter de prefixac,a~o de oitavo bit, porisso na~o precisa ser marcado com "#". Note, tambe'm, que o oitavo bit esta' ligado no argumento final da seque^ncia de repetic,a~o, na~o importando qua~o longa seja e na~o em algum dos caracteres de prefixac,a~o. Lembre-se, finalmente, das seguintes regras: - seque^ncias prefixadas na~o podem ser quebradas de um pacote para outro - os prefixos para controle, oitavo bit e contadores de repetic,a~o devem ser diferentes entre si - os campos de dados de todos os pacotes devem passar pelo mecanismo de codificac,a~o de prefixos, menos os pacotes "S", "I" e "A" e os ACKs para eles. Na primeira regra acima, note que uma seque^ncia prefixada significa um u'nico caracter e todos os seus prefixos, como ^%&#X, na~o uma seque^ncia como #M#J, que sa~o duas seque^ncias prefixadas. ..@bd 8.2. Operac,a~o de SERVER (Servidor) ..@iSERVER, operacao ..@iservidor ..@ioperacao de SERVER Um SERVER e' um programa KERMIT rodando remotamente sem um "interface com o usua'rio". Todos os comandos para o KERMIT SERVER chegam em pacotes do KERMIT LOCAL. A operac,a~o de um KERMIT SERVER e' muito mais conveniente do que a operac,a~o ba'sica, ja' que o usua'rio na~o precisa interagir diretamente com o programa KERMIT remoto uma vez que o tenha acionado em modo SERVER e, dai' em diante, na~o manda mais comandos SEND e RECEIVE complementares, dos dois lados, para conseguir que um arquivo seja transferido. Ao inve's disso, um u'nico comando (SEND ou GET) no KERMIT local basta. Os SERVERs podem oferecer tambe'm servic,os que na~o os de transfere^ncia de arquivos. Entre transac,o~es, um KERMIT SERVER espera pacotes contendo comandos de SERVER. O nu'mero de seque^ncia de pacote sempre volta a 0 depois de uma transac,a~o. Um KERMIT SERVER esperando comando deve ficar procurando um pacote 0 e pacotes de comando mandados para um SERVER devem ser tambe'm 0. Certos comandos de SERVER resultara~o numa troca de diversos pacotes. Tais operac,o~es se processam exatamente como uma transfere^ncia de arquivo. Um programa KERMIT SERVER, esperando por um pacote de comando e' dito "em espera de comando SERVER". Uma vez posto neste estado, o SERVER nunca deve deixa'-lo ate' receber um pacote comandando-o para tal. Isto significa que depois que qualquer transac,a~o termina, normalmente ou por alguma condic,a~o de erro, o SERVER deve voltar ao estado de espera de comando SERVER. Enquanto em espera, um SERVER pode resolver mandar NAKs perio'dicos pelo pacote 0, o esperado pacote de comando. Uma vez que o usua'rio pode ter se desconectado do SERVER por longos peri'odos de tempo (horas), os intervalos entre os NAKs devem ser significativamente maiores que o tempo normal de timeout (digamos: 30-60 segundos, ao inve's de 5-10). Os NAKs perio'dicos sa~o u'teis para quebrar um deadlock que ocorreria se um programa local na~o fosse capaz de entrar em timeout e mandar um comando que se perdesse. Por outro lado podem causar problemas para KERMITs locais que na~o possam limpar seus buffers de input ou para sistemas que fazem cegamente XON/XOFF, forc,ando os NAKs a ficarem bufferi zados no host do SERVER e serem soltos de repente, em massa, quando chegar um XON. Por esta raza~o os SERVERs devem ter uma opc,a~o para preparar um intervalo para "acordar" ou para desabilita'-lo de uma vez. A operac,a~o de SERVER deve ser implementada em dois lugares: no SERVER, propriamente, e em qualquer programa KERMIT que venha a se comunicar com ele. O SERVER tem que ter co'digo para ler comandos SERVER de pacotes e para responde^- los. O USER KERMIT deve ter co'digo para analisar comandos do usua'rio relacionados com o SERVER, formar pacotes de comandos para o SERVER, transmiti-los e manusear as respostas a tais comandos. ..@cd 8.2.1. Comandos SERVER ..@iSERVER, comandos Os comandos SERVER esta~o relacionados abaixo. Nem todos eles foram implementados e alguns podem nunca chegar a se^-lo mas seus usos devem ser reservados. Embora a operac,a~o em modo SERVER seja opcional, certos comandos devem ser implementados em todos os SERVERs. Isto inclui os comandos SEND-INIT (S), RECEIVE-INIT (R) e GENERIC LOGOUT (GL) e/ou FINISH (GF). Se o SERVER recebe um comando que na~o entende ou na~o pode executar, deve responder com um pacote de erro (E) contendo uma mensagem como "UNIMPLEMENTED SERVER COMMAND (comando SERVER na~o implementado)" e ambos os lados devem voltar o nu'mero de seque^ncia de pacote para 0 e o SERVER permanecer em espera por comando. So' um comando GL ou GF pode encerrar uma operac,a~o de SERVER. .cp 20 Os comandos KERMIT sa~o os seguintes: S - SEND-INITIATE (troca para^metros; o SERVER espera arquivo) R - RECEIVE-INITIATE (pede ao SERVER arquivos especificados) I - INITIALIZE (troca para^metros) X - TEXT-HEADER (Permite transferencia de texto para a tela do usua'rio em resposta a um comando gene'rico ou do host. Isto funciona exatamente como uma transfere^ncia de arquivo exceto que o "equipamento de destino" e' uma tela, ao inve's de um arquivo. Os campos de dados podem conter um nome de arquivo, um ti'tulo ou outro cabec,alho qualquer.) C - Comando de host. O campo de dados conte'm uma seque^ncia de caracteres a ser executada pelo host como um comando direto. K - Comando KERMIT. O campo de dados conte'm uma seque^ncia de caracteres na linguagem interativa do KERMIT SERVER (normalmente um comando SET) a ser executada como se houvesse sido digitada a ni'vel de comando. G - Comando KERMIT gene'rico. Um u'nico caracter no campo de dados (possivelmente seguido de operandos, mostrados em chaves, campos opcionais, tambe'm em colchetes) especifica o comando: I LOGIN {[*user[*password[*conta]]]} C CWD, CHANGE WORKING DIRECTORY {[*directory[*password]]} L LOGOUT, BYE F FINISH ("derruba" o SERVER mas na~o da' LOGOUT) D DIRECTORY {[*especificac,a~o-de-arquivo]} U DISK USAGE QUERY {[*area]} E ERASE (DELETE) {*especificac,a~o-de-arquivo} T TYPE {*especificac,a~o-de-arquivo} R RENAME {*nome-antigo*nome-novo} K COPY {*fonte*destino} W quem esta' no ar? (FINGER) {[*ident-do-usua'rio]} W quem esta' no ar? (FINGER) {[*NETWORK HOST[*opc,o~es]]} M mensagem curta {*destinata'rio*texto} H HELP {[*to'pico]} Q SERVER STATUS QUERY P programa {*[espec.arq] [*comandos]} J JOURNAL {*comando[*argumento]} V varia'vel [*comando[*argumento*argumento]]} Note que a codificac,a~o do comprimento do campo e' usada dentro do campo de dados mas na~o dentro dos campos de dados de outros pacotes como S, I, R, X, K e C. Um asterisco (*), como usado acima, representa um campo de comprimento de um u'nico caracter, codificado via char(), para o operando que o segue; assim, comprimentos de 0 a 94 podem ser especificados; isto permite que operandos mu'ltiplos sejam claramente delimitados a despeito de seus conteu'dos. Todos os comandos SERVER que mandam argumentos em seus campos de dados devem passar pelo mecanismo de codificac,a~o de prefixos. Assim se um caracter de dados ou campo de comprimento acontece de corresponder a um caracter de prefixo ativo, ele pro'prio deve ser prefixado. O comprimento do campo denota o comprimento do campo antes da codificac,a~o de prefixo e (ainda bem!) depois da decodificac,a~o. Por exemplo, para mandar um comando gene'rico com dois campos, "ABC" e "ZZZZZZZZ", primeiro cada campo seria prefixado por char() de seu comprimento, neste caso char(3) e char(8), dando "#ABC(ZZZZZZZZ". Mas "#" e' o caracter de prefixo de controle normal, dai' deve repetir o prefixo (se o contador de repetic,o~es estiver ativo), de modo que o resultado da codificac,a~o seja "##ABC(~(Z" (assumindo que o prefixo de repetic,a~o seja til - "~"). O receptor decodifica de volta para o "#ABC(ZZZZZZZZ" original antes de tentar extrair os dois campos. Uma vez que um comando gene'rico deve caber em um u'nico pacote, o programa que manda o comando se assegura que cabe mesmo e na~o inclui campos de comprimento que apontam para depois do fim do pacote. Os SERVERs, no entanto, devem ser defensivos e na~o tentar processar qualquer caracter depois do campo de dados, mesmo se o campo de comprimento do argumento o leve a fazer isso. ..@cd 8.2.2. Temporizac,a~o ..@itemporizacao O KERMIT na~o prove^ um mecanismo para suspender e continuar uma transac,a~o. Isto significa que um texto mandado para a tela do usua'rio na~o deve ser "congelado" por longos peri'odos (i. e': na~o mais que o peri'odo de timeout vezes o limite de tentativas). Entre transac,o~es, quando o SERVER na~o tem servic,os pendentes, pode mandar NAKs perio'dicos (sempre com checksums do tipo 1) para evitar um deadlock no caso de um comando seja mandado para ele e perdido. Tais NAKs podem se empilhar no buffer de input do KERMIT USER (se ele tiver um), assim o KERMIT USER deve estar preparado para "limpar" seu buffer de input antes de mandar um comando para um SERVER. Enquanto isso, os SERVERs devem reconhecer que alguns sistemas na~o permitem que, por programa, se fac,a isto (ou, quando o fazem, o processo pode ser atrapalhado pelo firmware de controle de fluxo do sistema) e, enta~o, ter um jeito de deixar de mandar (ou diminuir o ri'tmo de) os NAKs de espera de comando. ..@cd 8.2.3. O Comando "R" ..@icomando, R O pacote R, geralmente mandado por um programa KERMIT local cujo usua'rio teclou um comando GET, diz ao SERVER para mandar os arquivos especificados por nome no campo de dados do pacote R. Ja' que na~o podemos assumir que dois KERMITs estejam rodando em sistemas semelhantes, o KERMIT (USER) local deve encarar a especificac,a~o do arquivo como uma cadeia de caracteres e deixar o SERVER analisa'-la. Se o SERVER puder abir e ler o arquivo especificado, ele o transmite um pacote SEND-INIT (S) (na~o um ACK !) para o USER e completa a transac,a~o de transmissa~o de arquivo, como ja' descrito. Se o SERVER na~o pode mandar o arquivo, deve responder com um pacote de erro (E) contendo a raza~o, como "FILE NOT FOUND (arquivo na~o encontrado)" ou "READ ACCESS REQUIRED (exigido acesso para leitura)". ..@cd 8.2.4. Respostas Curtas e Respostas Longas ..@irespostas curtas e longas Qualquer pedido feito a um SERVER pode ser respondido de duas formas e qualquer USER KERMIT que faz tal pedido deve estar preparado para qualquer uma delas: * Uma resposta curta. Consiste em um simples pacote ACK, que pode conter texto em seu campo de dados. Por exemplo, o usua'rio pode pedir informac,o~es sobre espac,o em disco ao SERVER e ele responder com uma curta cadeia de caracteres no campo de dados de seu pacote de ACK, como "12K BYTES FREE (12K bytes disponi'veis)". O USER KERMIT deve mostrar este texto em sua tela. * Uma resposta longa. Funciona como uma transfere^ncia de um arquivo (e em alguns casos pode se tratar disso mesmo). Comec,a com um dos seguintes: * um pacote "F" de cabec,alho de arquivo (seguido, opcionalmente, por um ou mais pacotes de atributos, discutidos mais tarde); * um pacote "X" de cabec,alho de texto; * um pacote "S" (SEND-INIT) seguido por um pacote "X" ou "F"; Depois do pacote X ou F vem um nu'mero arbitra'rio de pacotes de dados ("D") e, enta~o, um pacote "Z" (END-OF-FILE) e, finalmente, um pacote "B" (BREAK-TRANSMISSION), como para uma transfere^ncia normal de um arquivo. ..@cd 8.2.5. Comandos SERVER Adicionais ..@iSERVER, comandos adicionais ..@icomandos SERVER adicionais Os comandos SERVER a seguir pedem ao SERVER para executar tarefas que na~o as de transmitir e receber arquivos. Quase todos eles sa~o passi'veis de respostas curtas ou longas. Por exemplo, o comando ERASE gene'rico (GE) pode gerar um simples ACK ou uma rajada de pacotes contendo os nomes de todos os arquivos que ele apagou (ou na~o). Vejamos agora tais comandos em mais detalhes, os argumentos sa~o como providos nos comandos teclados para o USER KERMIT (sujeitos a codificac,a~o de prefixo); nenhuma transformac,a~o a qualquer forma normal ou cano^nica e' feita: nomes de arquivos e outros operandos esta~o na sintaxe do sistema host do SERVER. I LOGIN. Para uso quando um KERMIT SERVER e' mantido perpetuamente rodando numa linha dedicada. Isto permite a um novo usua'rio identificar-se perante o sistema do host. Se o campo de dados estiver vazio, ele remove a identificac,a~o do usua'rio, de forma que o pro'ximo na~o tenha acesso ao host com a mesma identificac,a~o. Um SERVER dedicado como este deve provavelmente desabilitar os comandos gene'ricos L e F, descritos abaixo. L LOGOUT, BYE. Este comando "derruba" o SERVER inteiramente, fazendo-o encerrar seu pro'prio JOB. Deve ser usado quando o SERVER foi iniciado manualmente pelo usua'rio que, enta~o, deve derruba'-lo remotamente. F FINISH. Isto e' para permitir que o usua'rio possa derrubar o SERVER, colocando seu terminal de volta ao modo normal (diferente de bina'rio ou natural) e o JOB do SERVER devolvido ao ni'vel de comando de sistema, ainda "logado", de forma a poder continuar seus afazeres no host. C CWD. Este comando torna ativo o direto'rio ou a'rea default para transfere^ncia de arquivos no host do SERVER. Sem operandos, passa a ser a pro'pria a'rea default do usua'rio. D DIRECTORY. Manda uma listagem do direto'rio para o usua'rio. O USER KERMIT tanto pode mostra'-la na tela quanto armazena'- -la em disco. Normalmente e' aceito algum tipo de designador de grupos de arquivos para pedir que o SERVER so' liste os nomes de arquivos cujos nomes satisfac,am a regra dada. U DISK USAGE QUERY. O SERVER responde com o total de espac,o em disco usado e livre em Kbytes (ou outra unidade, que deveria ser especificada). E ERASE (DELETE). Apaga o arquivo ou o grupo de arquivos especificado. T TYPE. Manda o arquivo ou grupo deles, indicando (comec,ando com um pacote X ao inve's de um F ou usando o atributo TYPE) que o arquivo deve ser mandado para a tela e na~o armazenado. R RENAME. Muda o nome do arquivo ou arquivos como indicado. A seque^ncia de caracteres indicando o novo nome pode conter outros atributos, como co'digo de protec,a~o, permitido nas especificac,o~es de arquivo do host. K COPY. Produz uma co'pia do arquivo ou grupo deles, como indicado, deixando o(s) arquivo(s) fonte(s) intacto(s). W WHO'S LOGGED IN? (FINGER). Sem argumentos, lista todos os usua'rios usando o sistema do host no momento. Se for especificado algum argumento, prove^ informac,o~es mais detalhadas sobre o usua'rio ou host da rede especificado. M SHORT MESSAGE. Manda o bilhete (de um u'nico pacote) para a tela do usua'rio indicado. P PROGRAM. Este comando tem dois argumentos: nome do programa [especif.arq.] e parametros para o programa. O primeiro campo e' exigido mas pode ser deixado nulo (i. e': comprimento zero). Se for nulo, o programa correntemente carregado e' alimentado com o comando. Se na~o nulo, o programa especificado e' carregado e iniciado; se um comando de programa for dado, e' passado para o programa que entrou como se fosse um comando inicial (por exemplo, como uma linha de argumentos em sistemas que aceitam tal conceito). Em qualquer um dos casos, a sai'da do programa e' mandada de volta em forma de respostas curtas ou longas, como ja' descrito. J JOURNAL. Este comando controla o "dia'rio" da transac,a~o do SERVER. O campo de dados conte'm um dos seguintes: + Comec,a a anotar a transac,a~o. Se e' dado um nome de arquivo, fecha qualquer transac,a~o ora aberta e abre o arquivo especificado como o novo LOG de transac,a~o. Se na~o existe LOG aberto nem e' dado um nome de arquivo, o SERVER deve abrir um arquivo com um nome default, como TRANSACTION.LOG. - Para de anotar a transac,a~o mas na~o fecha o LOG corrente. C Para de anotar a transac,a~o e fecha o LOG corrente. S Transmite o LOG. Se aberto, fecha-o primeiro. Anotar uma transac,a~o e' registrar o progresso de transfere^ncias de arquivos. Deve conter entradas mos trando o nome de cada arquivo transferido, quando a transfere^ncia comec,ou e quando acabou, se terminou com sucesso e, se na~o, por que. V Arma ou inquire uma varia'vel. O comando pode ser S ou Q. O primeiro argumento e' o nome da varia'vel. O segun do, se houver, e' seu valor. S Arma o valor da varia'vel especificada com o valor especificado. Se o valor for nulo, elimina a varia'vel. Se ela na~o existe, cria. O SERVER deve responder com um ACK cujo campo de dados conte'm um Y para indicar que a varia'vel foi preparada ou N, caso contra'rio; um campo de dados vazio vale um Y. Q questiona sobre o valor da varia'vel declarada. Se na~o for declarado um nome, mostra o valor de todas as varia'veis ativas. O SERVER responde com uma resposta curta ou longa, como descrito acima. Se a varia'vel na~o existe, volta um valor nulo. Os nomes das varia'veis sa~o cadeias de caracteres e tem caracteres como valores. Podem ser esta'ticas ou dina^micas. Por exemplo, um SERVER pode ter varia'veis built-in como "SYSTEM NAME", que nunca mudam, ou outras como "MAIL STATUS" que, quando inquirida, faz com que o SERVER busque alguma corresponde^ncia para o usua'rio. ..@cd 8.2.6. Comandos de Host ..@ihost, comandos ..@icomandos de host Sa~o conceitualmente simples mas podem ser difi'ceis de implementar em alguns sistemas. O pacote C contem um texto em seu campo de dados que e' simplesmente passado para o processador de comandos do sistema do host do SERVER; qualquer sai'da desse processador e' mandada de volta para o usua'rio no KERMIT em pacotes, em mensagens curtas ou longas. A implementac,a~o dessa facilidade sob UNIX, com sua estrutura processual em "fork" e seu redirecionamento de I/O via "pipes", e' muito natural. Em outros sistemas pode se tornar virtualmente impossi'vel. ..@cd 8.2.7. Trocando Para^metros Antes de Comandos SERVER ..@iSERVER, trocando parms antes No KERMIT ba'sico, a troca SEND-INIT sempre e' suficiente para configurar os dois lados entre si. Por outro lado, durante uma operac,a~o SERVER, algumas operac,o~es podem na~o comec,ar com um pacote SEND-INIT. Por exemplo, quando o USER manda um pacote R (pedindo para mandar um arquivo), o SERVER escolhe que opc,a~o de checagem de bloco usar. Ou se o usua'rio pede uma listagem do direto'rio, o SERVER na~o sabe que comprimento de pacote usar. A soluc,a~o e' o pacote "I" (INIT-INFO). E' exatamente como um pacote SEND-INIT e o ACK age exatamente da mesma forma. Entretanto, a recepc,a~o de um pacote I na~o implica na transic,a~o para o status de transmissa~o de arquivo. A troca do pacote I simplesmente permite que os dois lados ajeitem seus para^metros, preparando-se para a pro'xima transac,a~o. Um SERVER em espera de comando deve ser capaz de rece ber um pacote I e mandar um ACK por ele. Um KERMIT USER, no entanto, na~o precisa mandar pacotes I; neste caso, o SERVER assume todos os valores default para o USER relacionados na sec,a~o sobre prefixac,a~o, neste capi'tulo, ou qualquer que seja o valor para o para^metro, armado por outro meio (por exemplo, comandos SET teclados para o SERVER antes dele ser posto em modo SERVER). .cp5 ..@bd 8.3. Tipos alternativos de checagem de bloco ..@itipos alternativos de checagem de bloco ..@ichecagem de blocos, tipos alternativos ..@ibloco, tipos alternativos de checagem Existem dois tipos opcionais de cheques de bloco: TIPO 2 ====== Um checksum de 2 caracteres baseado nos 12 bits de mais baixa ordem da soma aritme'tica dos caracteres no pacote (do campo de comprimento ate' o u'ltimo caracter do campo de dados, inclusives) como se segue: 1 2 ---------+--------------+-------------+ dados | char(B6-B11) | char(B0-B5) | ---------+--------------+-------------+ Por exemplo, se o resultado de 16 bits for 154321 (octal), os dois caracteres de checagem de bloco seriam "C1". TIPO 3 ====== Um CRC-CCITT de 3 caracteres de 16 bits. O ca'lculo CRC trata os dados que opera como uma cadeia de bits com o bit de mais baixa ordem do primeiro caracter primeiro e o bit de mais alta ordem do u'ltimo caracter por u'ltimo. O valor inicial do CRC e' 0; o CRC de 16 bits e' o resto da divisa~o da cadeia pelo polino^mio 16 12 5 X + X + X + 1 (este ca'lculo, na realidade, pode ser feito um byte de cada vez, usando-se uma tabela simples e um algori'tmo de busca). O resultado e' representado como tres caracteres imprimi'veis no fim do pacote, assim: ---------+---------------+--------------+--------------+ dados | char(B12-B15) | char(B6-B11) | char (B0-B5) | ---------+---------------+--------------+--------------+ Por exemplo, se o resultado de 16 bits for 154321 (octal), enta~o o cheque de bloco de 3 caracteres seria "-C1". A te'cnica CRC escolhida aqui concorda com muitas implementac,o~es de hardware (p.e. a instruc,a~o CRC do VAX). Uma refere^ncia u'til para ca'lculos de CRC por tabela pode ser vista no artigo "BYTE-WISE CRC CALCULATIONS" de Aram Perez, na IEEE MICRO de junho de 1983, pa'gina 40. O checksum de um u'nico caracter se provou deveras adequado na pra'tica. As outras opc,o~es so' podem ser emprega das se os dois lados concordarem via troca de pacotes INIT (S ou I). Os cheques de bloco de 2 ou 3 caracteres tambe'm so' devem ser empregados sob severas condic,o~es de rui'do de linha e adulterac,a~o de pacotes. Ja' que cheques dos tipos 2 e 3 sa~o opcionais, nem todos os KERMITs sa~o capazes de entende^-los. Por este motivo, uma comunicac,a~o deve comec,ar com o tipo 1. Se durante a troca de pacotes S ou I o uso dos tipos 2 ou 3 forem aceitos pelos dois lados, a mudanc,a sera' levada a cabo somente depois que o SEND-INIT houver sido enviado e um ACK por ele recebido, usando-se o tipo 1 de checagem de bloco. Isto significa que o primeiro pacote com checagem do tipo 2 ou 3 sempre sera' um F ou um X. Depois de completada a transac,a~o, ambos os lados devem voltar ao tipo 1 (uma vez que nenhum dos dois lados pode saber se o outro parou e recomec,ou). A transac,a~o termina depois que um pacote B ou E foi transmitido e recebeu seu ACK ou depois de haver ocorrido qualquer erro que terminasse a transac,a~o prematura ou anormalmente. Uma conseque^ncia desta regra e' que se se vai usar uma checagem de bloco do tipo 2 ou 3, uma resposta longa mandada pelo SERVER deve comec,ar com um pacote SEND-INIT (S), mesmo se uma troca de pacote I ja' ocorreu. Se o tipo 1 esta' sendo empregado, o pacote S pode ser enviado e a transfere^ncia pode comec,ar com um pacote X ou F. Um SERVER que completou uma transac,a~o e esta' esperando um novo comando pode mandar NAKs perio'dicos por ele (pacote 0). Tais NAKs devem ter cheques de bloco do tipo 1. O uso de tipos alternados de cheques de bloco pode causar certas complicac,o~es. Por exemplo, se o SERVER recebe um erro "horri'vel" (ta~o ruim que nem consegue mandar um pacote de erro) e reverte em espera de comando, o fato de ficar mandando NAKs por pacote 0, usando cheque de bloco tipo 1, enquanto uma transfere^ncia usando tipo 2 ou 3 estava em progresso, fara' com que nenhum dos lados seja capaz de entender os pacotes do outro. A comunicac,a~o pode inclusive se estrangular se A manda um SEND-INIT pedindo cheque de bloco tipo 3, por exemplo, B ACK o pedido, passa para tipo 3 e espera por um pacote X ou F com cheque de bloco deste tipo mas o ACK se perdeu; dai'... A retransmite o pacote S com tipo 1. Situac,o~es como esta se resolvera~o, na pior das hipo'teses, depois que os dois lados atinjam seus limites de retransmisso~es mas podem ser retificadas antes atrave's do uso de duas heuri'sticas: - a rotina de leitura de pacotes assume que se o pacote e' S, enta~o o tipo de cheque de bloco e' o 1; - um pacote NAK na~o tem conteu'do em seu campo de dados; dai' o tipo de cheque de bloco pode ser deduzido pela rotina de leitura de pacotes pelo campo de comprimento de um NAK; de fato, e' o valor do campo de comprimento menos 2; um NAK pode, assim, ser encarado com um tipo de "sincronizador universal". Estas heuri'sticas tendem a desvirtuar a natureza desenhada do protocolo, uma vez que a rotina de leitura de pacotes normalmente na~o deve se preocupar com o tipo de pacote (que e' de interesse do ni'vel de aplicac,a~o que chama a rotina de leitura de pacotes). Um desenho melhor teria cada pacote inclui'do como um indicador do tipo de seu pro'prio cheque de bloco; isto deixaria o tipo ser trocado dinamicamente durante uma transac,a~o. Mas e' muito tarde para isto, agora... ..@bd 8.4. Interrompendo uma transfere^ncia de arquivo ..@itransferencia, interrompendo ..@iinterrompendo transferencia ..@iarquivo, interrompendo transferencia Esta sec,a~o descreve uma facilidade opcional do protocolo KERMIT que permite uma interrupc,a~o elegante de uma transfere^ncia de arquivo. Esta facilidade na~o se relaciona com operac,a~o de SERVER. Para interromper o envio de um arquivo, mande um pacote EOF (Z) em lugar do pro'ximo pacote de dados, incluindo um D (que significa "dispense") no campo de dados. O receptor manda um ACK pelo pacote Z, normalmente, mas na~o retem o arquivo. Isto na~o interfere com os antigos KERMITs que estiverem na recepc,a~o: eles na~o inspecionam o campo de dados e fecham normalmente o arquivo. O mecanismo pode ser engatilhado teclando-se um caracter de interrupc,a~o no console do programa KERMIT transmissor. Se um grupo de arquivos (wildcard) esta' sendo mandado, e' possivel pular para o pro'ximo arquivo ou encerrar todo o batch. O protocolo e' o mesmo em qualquer um dos casos mas a ac,a~o poderia ser selecionada por diferentes caracteres de interrupc,a~o, e.g. CTRL-X para passar para o pro'ximo arquivo, CTRL-Z para acabar de uma vez. Para interromper o receptor, ponha um X no campo de dados de um ACK por um pacote de dados. Para interromper a recepc,a~o de todo um grupo de arquivos, use um Z. O usua'rio pode engatilhar este mecanismo teclando um caracter de interrupc,a~o, digamos, CTRL-X ou CTRL-Z, respectivamente, no console do KERMIT receptor. Um transmissor que conhec,a tal facilidade, ao encontrar um desses co'digos, agiria como descrito acima: mandaria um pacote Z com um co'digo D; um transmissor que na~o implemente esta facilidade simplesmente ignoraria os co'digos e continuaria transmitindo. Neste caso e se o usua'rio quizesse interromper todo o batch (ou somente um arquivo), o programa KERMIT receptor, depois de descobrir que o transmissor ignorou o co'digo X ou Z, poderia mandar um pacote de erro (E) para parar a transfere^ncia. O transmissor pode tambe'm decidir mandar um pacote Z contendo o co'digo D quando descobre que o arquivo que esta' transmitindo na~o pode ser enviado correta ou completamente. Por exemplo, depois de haver mandado corretamente alguns pacotes, aparece um erro de leitura; ou repara que o "oitavo bit" de um dos bytes do arquivo de texto que esta' sendo transmitido esta' ligado e na~o sa havia feito proviso~es de transmissa~o de oito bits. ..@bd 8.5. Transmitindo atributos de arquivos ..@iarquivo, transmitindo atributos ..@iatributos ..@itransmitindo atributos de arquivos O pacote opcional de atributos (A) prove^ um mecanismo para que o transmissor de um arquivo possa dar maiores infor mac,o~es sobre ele. Este pacote pode ser mandado se o receptor indicar sua capacidade em processa'-lo, ligando o bit de atributo na ma'scara de capacidade. Se os dois lados ligam este bit na ma'scara de capacidade, o transmissor, depois de mandar o nome do arquivo no pacote F e receber o ACK correspondente, pode (mas na~o tem que) mandar um pacote A com informac,o~es de atributos do arquivo. Ligar o bit de atributo na ma'scara de capacidade na~o indica suporte a qualquer atributo em particular, somente que o receptor esta' preparado para receber o pacote A. Os atributos sa~o mandados no campo de dados do pacote A. Este campo consiste de 0 ou mais subcampos, que podem ocorrer em qualquer ordem. Cada subcampo e' da seguinte forma: +----------+-------------------+-------+ | atributo | char(comprimento) | dados | +----------+-------------------+-------+ onde atributo e' um u'nico caracter imprimi'vel diferente de espac,o, comprimento e' o comprimento dos caracteres de dados (0 a 94), com 32 somado para produzir um u'nico caracter imprimi'vel e dados e' "comprimento" caracteres com dados, todos imprimi'veis. Nenhuma prefixac,a~o ou marcac,a~o e' feita nesses dados. Mais de um pacote de atributos pode ser mandado. A u'nica exige^ncia e' que todos os pacotes A para um arquivo devem seguir imediatamente seu pacote de cabec,alho de arquivo (F) e preceder o primeiro pacote de dados. Podem existir 93 atributos diferentes, um para cada caracter ASCII imprimi'vel diferente de espac,o. Esta~o associados na ordem ASCII. ! (ASCII 33) Comprimento. O campo de dados da' o comprimento em K (1024) bytes, como um nu'mero decimal imprimi'vel, e.g. "!#109". Isto permitira' que o receptor determine com antecede^ncia se existe espac,o suficiente para o arquivo e/ou quanto tempo durara' a transfere^ncia. " (ASCII 34) Tipo. O campo de dados pode conter algum indicador da natureza do arquivo. Os operandos aparecem dentro de {chaves}, i'tens opcionais entre [colchetes]. A{[xx]} Texto ASCII, na~o contendo quantidades com 8 bits, registros lo'gicos (linhas) delimi tados pela seque^ncia de caracteres (marca) de controle [xx], representada aqui pela sua contraparte imprimi'vel (MJ = CRLF, J = LF etc.). Por exemplo "AMJ" significa que o aparecimento de #M#J (a seque^ncia normal CRLF prefixada) num pacote de dados de arquivo indica o fim de um registro, assu mindo que o prefixo de controle corrente seja "#". Se [xx] for omitido, sera' assu mido MJ. B{[xx]} Bina'rio. [xx] indica de que maneira o arquivo e' bina'rio: 8 (default) o arquivo e' uma seque^ncia de bytes de 8 bits, que devem ser salvos como esta~o. O oitavo bit pode ser mandado nu' ou prefixado de acor do com a negociac,a~o SEND-INIT acerca da prefixac,a~o de oitavo bit. 36 O arquivo esta' no formato PDP-11, no qual 5 dos 7 bits do byte ficam numa palavra de 36 bits, com o u'ltimo bit de cada palavra representando o "bit de paridade" de cada quinto caracter (talvez prefixado). D{x} Move daqui para atributo de formato F{x} Move daqui para atributo de formato I{[x]} Imagem. O arquivo esta' sendo transmitido exatamente como representado no sistema de origem. Para uso entre sistemas semelhantes. Existem [x] bits usa'veis por caracter, antes de uma prefixac,a~o. Por exemplo, para mandar dados bina'rios de um sistema com bytes de 9 bits, pode ser conveniente mandar 3 caracteres de 6 bits para cada 2 bytes de 9 bits. O valor default para [x] e' 8. # (ASCII 35) Data de criac,a~o, expressa no formato "[yy]yymmdd[hh:mm[:ss]] (formato juliano padra~o ISO), e.g. 850731 15:51. A hora e' opcional; se dada, deve estar no formato "24 horas", os segundos podem ser omitidos e um u'nico espac,o deve separar a hora da data. $ (ASCII 36) Identificac,a~o do criador, expressa numa cadeia de caracteres de comprimento dado. % (ASCII 37) Conta onde sera' cobrado o arquivo, expressa numa cadeia de caracteres de comprimento dado. & (ASCII 38) a'rea onde o arquivo sera' armazenado, expressa numa cadeia de caracteres de comprimento dado. ' (ASCII 39) Password para a a'rea descrita acima, cadeia de caracteres. ( (ASCII 40) Tamanho do bloco. O arquivo tem ou deve ser armazenado com o dado tamanho. ) (ASCII 41) Acesso: N Novo, o caso normal - cria um arquivo com o nome dado. S SUPERSEDE (OVERWRITE) qualquer arquivo do mesmo nome. A Acrescenta ao arquivo de nome dado. * (ASCII 42) Codificac,a~o: A ASCII, codificac,a~o normal, com qualquer prefixac,a~o necessa'ria. H Codificac,a~o hexadecimal (em nibbles). E EBCDIC (mandado como se fosse um arquivo bina'rio). S Conjunto de caracteres SIXBIT (equivalente a 16). R RADIX50. X Encriptado. Q{x} Codificac,a~o Huffman de compressa~o. Os primeiros x bytes do arquivo sa~o a chave. + (ASCII 43) Disposic,a~o (os operandos sa~o especificados na sintaxe do sistema do host receptor): M{usua'rio(s)} manda o arquivo como correio para o(s) usua'rio(s) especificado(s). O{destino} manda o arquivo como mensagem longa para terminal para o destino especificado (terminal, JOB ou usua'rio). S{[opc,o~es]} submete o arquivo como um JOB para batch do sistema, com as opc,o~es especificadas. P{[opc,o~es]} imprime o arquivo numa impressora do sistema, com as opc,o~es especificadas (uma impressora em particular, formula'rio etc.). T Tecla o arquivo na tela. L{[aaa]} Carrega o arquivo na memo'ria no enderec,o dado (opcional). X{[aaa]} Carrega o arquivo na memo'ria (no enderec,o dado) e executa-o. A Armazena o arquivo; salva o arquivo junto com os pacotes de atributo que o precederam, de forma a poderem ser mandados de volta ao sistema de origem com todos seus atributos intactos. Um arquivo armazenado desta maneira pode ser marcado especialmente de forma que o KERMIT que o mande de volta reconhec,a as informac,o~es de atributo como distintas do arquivo de dados. , (ASCII 44) Protec,a~o. Co'digo de protec,a~o para o arquivo, na sintaxe do sistema de arquivos do host. Sem operandos, armazena de acordo com a protec,a~o default do sistema para a a'rea designada como destino. - (ASCII 45) Protec,a~o. Co'digo de protec,a~o para o arquivo em relac,a~o ao "pu'blico" ou ao "mundo", expresso geralmente em uma quantidade de 16 bits, tornada imprimi'vel via char(), no qual os bits tem o seguinte significado: B0: acesso para leitura B1: " " gravac,a~o B2: " " execuc,a~o B3: " " append B4: " " apagar B5: listagem de direto'rio Um 1 na posic,a~o do bit significa habilitar o tipo de acesso correspondente, um 0, proibir. Por exemplo, a letra E neste campo daria o acesso a` leitura, execuc,a~o e listagem do direto'rio (unchar("E") = 69-32 = 37 = 100101 bina'rio). . (ASCII 46) Ma'quina e sistema operacional de origem. E' u'til em conjunc,a~o com o atributo de disposic,a~o do arquivo. Permite que um arquivo, uma vez armazenado, seja transferido entre diferentes tipos de sistemas, mantendo seus status de arquivo, ate' que se encontre em uma ma'quina com as caracteri'sticas certas para utiliza'-lo. Os sistemas sa~o denotados por co'digos; o primeiro caracter e' o designador maior de sistema, o segundo indica o modelo ou sistema operacional. Um terceiro caracter pode ser acrescentado para fazer maiores distinc,o~es, por exemplo a versa~o do sistema operacional. Os sistemas abaixo na~o formam uma colec,a~o completa; muitos mais podem e provavelmente sera~o inclui'dos. A Apple Microcomputers 1 Apple ][, DOS 2 Apple III 3 MacIntosh 4 Lisa B Sperry (UNIVAC) Mainframes 1 Se'rie 1100, EXEC C CDC Mainframes 1 Se'rie Cyber, NOS D DEC Systems 1 DECSYSTEM-10/20, TOPS-10 2 DECSYSTEM-10/20, TOPS-20 3 DECSYSTEM-10/20, TENEX 4 DECSYSTEM-10/20, ITS 5 DECSYSTEM-10/20, WAITS 6 DECSYSTEM-10/20, MAXC 7 VAX-11, VMS 8 PDP-11, RSX-11 9 PDP-11, IAS A PDP-11, RSTS/E B PDP-11, RT-11 C PROFESSIONAL-300, P/OS D WORD PROCESSOR (WPS ou DECMATE), WPS D Honeywell Mainframes 1 Sistemas Multic 2 Se'rie DPS, CP-6 F Ma'quinas Data General 1 RDOS 2 AOS G Ma'quinas Prime, PRIMOS H Ma'quinas Hewlett-Packard 1 HP-1000, RTE 2 HP-3000, MPE I I.B.M. Se'ries /370 e compati'veis 1 VM/CMS 2 MVS/TSO 3 DOS 4 MUSIC 5 GUTS 6 MTS J Tandy Microcomputers, TRSDOS K Atari Micros, DOS L-T (reservado) U Sistemas operacionais ou arquivos porta'veis 1 UNIX 2 Software Tools 3 CP/M-80 4 CP/M-86 5 CP/M-68K 6 MP/M 7 CP/M concorrente 8 MS-DOS 9 UCSD P-system A MUMPS / (ASCII 47) Formato dos dados dentro dos pacotes. A{xxx} Registros delimitados de comprimento varia'vel, terminados pela seque^ncia de caracteres {xx}, onde xx e' uma cadeia de caracteres de um ou mais caracteres de controle, representado aqui por seus equivalentes imprimi'veis na~o prefixados, e.g. MJ para ^M^J (CRLF). D{x} Registros na~o delimitados de comprimento varia'vel. Cada registro lo'gico comec,a com um campo de comprimento de {x} caracteres decimais ASCII (similar ao formato ANSI "D" de fita). Por exemplo, "D$" indicaria campos de comprimento de 4 di'gitos, como "0123". F{xxxx} Registros na~o delimitados de comprimento fixo. Cada registro lo'gico tem {xxxx} bytes. R{x} Para transfere^ncias orientadas para registros, a ser empregado combinado com um dos formatos dados acima. Cada registro comec,a (no caso do formato D, depois co campo de comprimento) com um campo de posic,a~o de {x} caracteres indicando a posicao do byte dentro do arquivo onde este registro deve ser colocado. 0 (ASCII 48) Para^metros especiais dependentes de sistema para armazenar o arquivo no sistema de origem, para especificac,a~o de atributos exo'ticos na~o cobertos explicitamente por qualquer dos descritores de atributos do KERMIT. Sa~o dados por uma cadeia de caracteres na pro'pria linguagem do sistema, por exemplo uma lista de para^metros de uma DCB, usando a Job Control Language IBM. 1-@ (ASCII 49-64) (reservado) Outros atributos podem ser imaginados e acrescentados mais tarde, se desejado. No entanto, dois pontos importantes devem ser observados: - O receptor pode na~o ter, absolutamente, forma alguma de honrar, ou mesmo gravar, um dado atributo. Por exemplo, o CP/M-80 na~o tem lugar para data de criac,a~o nem identificac,a~o do criador em sua FCB; o DEC-20 na~o tem o conceito de tamanho de bloco etc. - O receptor pode na~o ter forma de determinar os valores corretos de qualquer dos atributos. Isto e' particularmente verdade ao transmitir arquivos de origem estrangeira. O mecanismo do pacote A prove^ somente uma maneira de mandar certas informac,o~es sobre um arquivo para o receptor, sem garantia do que pode ser feito por quem recebe com o arquivo. Tal informac,a~o pode ser conseguida diretamente da entrada no direto'rio do arquivo (FCB,FDB, ...) ou especificado via comando de usua'rio. O ACK pelo pacote A pode, por sua vez, ter informac,o~es em seu campo de dados. No entanto, nenhuma negociac,a~o complicada acerca de atributos de arquivo pode ter lugar, porisso o resultado li'quido e' que o receptor tanto pode aceitar quanto recusar o arquivo. Pode responder ao pacote A com um ACK contendo, em seu campo de dados, qualquer um dos co'digos a seguir: (campo de dados vazio) Aceitei o arquivo; va' em frente, transmita-o! N{[xxx]} Recusarei o arquivo como especificado, na~o o transmita! [xxx] e' uma cadeia de zero ou mais dos caracteres de atributo listados acima, para especificar quais aqueles estou rejeitando (e.g. "!" significa que e' muito longo, "&" que na~o tenho acesso a` a'rea especificada etc.) Y{[xxx]} Concordo em receber o arquivo mas na~o posso honrar os atributos [xxx], de modo que armazena-lo-ei de acordo com meus pro'prios defaults. Y (caso degenerado do anterior, equivalente ao , acima.) Como o receptor realmente responde, e' uma decisa~o de implementac,a~o. Um NAK em resposta ao pacote A significa, claro, que o receptor na~o recebeu o "A" corretamente, na~o que se recuse a receber o arquivo. ..@bd 8.6. Tabela de estados do Protocolo KERMIT Avanc,ado ..@iestado, tabela avancada ..@iprotocolo, estados avancados ..@itabela dos estados do protocolo avancado A tabela simples apresentada anteriomente e' suficiente para se implementar um KERMIT ba'sico. A tabela de estados a seguir cobre todo o protocolo KERMIT, incluindo desde modo SERVER e comandos de transmissa~o ate' KERMIT SERVER. Na~o inclui o manuseio do pacote A, de atributos de arquivo. Note que os estados cujos nomes comec,am com "SEND" sempre mandam um pacote cada vez que entram (mesmo quando o estado anterior era o mesmo). Estados que comec,am com "REC" sempre esperam por um pacote a ser recebido (ate' o limite para timeout) e processa o pacote recebido. Estados cujos nomes na~o incluem "SEND" ou "REC" na~o processam pacotes diretamente; Sa~o estados que executam alguma operac,a~o local e mudam para outro estado. O estado inicial e' determinado pelo comando do usua' rio. Um comando "SERVER" entra em REC-SERVER-IDLE (inativi dade R/S). Um comando "SEND" entra em SEND-INIT. Um comando "RECEIVE" (a antiga versa~o na~o-SERVER, na~o um comando "GET") entra em REC-INIT. Qualquer comando gene'rico, o "GET" e o "HOST" entram tanto em SEND-SERVER-INIT quanto em SEND-GEN- CMD, dependendo da resposta esperada. Sob "MENS.REC." (mensagem recebida), e' mostrado o tipo de pacote da mensagem que chega, seguido pelo nu'mero dele entre pare^nteses; (n) e' o pacote corrente, (n-1) e (n+1) o pre'vio e pro'ximo pacote (mo'dulo 64), (0) e' pacote 0. Seguin do o nu'mero do pacote pode aparecer uma barra e uma letra, indicando algum sinal especial no campo de dados. Por exem plo, Z(n)/D indica um pacote Z (EOF), nu'mero sequencial n, com um "D" em seu campo de dados. Sob "AC,A~O", "R+" significa que o contador de tentativas e' incrementado e comparado com um limite. Se tal limite for excedido, um pacote de erro e' mandado e o estado muda para "ABORT". "N+" quer dizer que o nu'mero de pacote e' incremen tado, mo'dulo 64, e o contador de tentativas, R, e' devolvido a zero. .pa ESTADO MENS.REC. AC,A~O PROX.ESTADO ====== ========= ==== =========== REC-SERVER-IDLE -- SERVER esperando alguma mensagem Po~e N e R em 0 I(0) Manda ACK REC-SERVER-IDLE S(0) Processa parms, ACK c/parms, N+ REC-FILE R(0) Salva nome.arq. SEND-INIT K, C, OR G(0) Resposta curta: ACK(0)/REPLY REC-SERVER-IDLE Resposta longa: INIT necessario SEND-INIT INIT desnecessario, N+ OPEN-FILE TIMEOUT Manda NAK(0) REC-SERVER-IDLE outro erro REC-SERVER-IDLE REC-INIT -- Entrada p/ comando RECEIVEde na~o-SERVER Po~e N e R em 0 S(0) Proces.parms, manda ACK c/parms, N+ REC-FILE TIMEOUT manda NAK(0),R+ REC-INIT outro NAK ABORT REC-FILE -- Busca mensagem de cabec,alho de arquivo ou de EOT F(N) Abre arq., ACK, N+ REC-DATA X(N) Prepara p/ mostrar na tela,ACK, N+ REC-DATA B(N) ACK COMPLETE S(N-1) ACK c/ parms, R+ REC-FILE Z(N-1) ACK, R+ REC-FILE TIMEOUT NAK, R+ REC-FILE outro NAK ABORT REC-DATA -- Recebe dados ate' final de arquivo D(N) Guarda dados,ACK,N+; se quer interrup- c,a~o, inclua X ou Z no ACK REC-DATA D(N-1) Manda ACK,R+ REC-DATA Z(N) Fecha arq.,ACK,N+ REC-FILE Z(N)/D Abandona arq,ACK,N+ REC-FILE F(N-1) Manda ACK,R+ REC-DATA X(N-1) Manda ACK,R+ REC-DATA TIMEOUT Manda ACK,R+ REC-DATA outro Manda E ABORT SEND-INIT -- Entrada p/ comando SEND tambe'm Po~e N e R em 0, Manda S(0) com para^metros Y(0) Processa parms,N+ OPEN-FILE N, TIMEOUT R+ SEND-INIT outro R+ SEND-INIT OPEN-FILE -- Abre arquivo ou prepara texto para enviar SEND-FILE SEND-FILE -- Manda cabec,alho ou arquivo de texto Manda F ou X(n) Y(N), N(N+1) Pega prim.buffer de dados,N+ SEND-DATA ou SEND-EOF se arq.vazio ou texto N, TIMEOUT R+ SEND-FILE outro ABORT SEND-DATA -- Manda conteu'do de arquivo ou informac,a~o textual Manda D(n) com buffer corrente Y(N), N(N+1) N+, Pega prox.buff SEND-DATA ou SEND-EOF se no fim do arq. ou texto Y(N)/X ou Z N+ SEND-EOF N, TIMEOUT R+ SEND-DATA outro ABORT SEND-EOF -- Manda indicador de fim de arquivo Manda Z(n); se interrompendo, manda Z(n)/D Y(N), N(N+1) Abre prox.arq.,N+ SEND-FILE se mais ou SEND-BREAK se acabou ou se interrupc,a~o "Z". N,TIMEOUT R+ SEND-EOF outro ABORT SEND-BREAK -- Fim de Transac,a~o (END OF TRANSACTION) Manda B(n) Y(N), N(0) COMPLETE N(N), TIMEOUT SEND-BREAK outro ABORT SEND-SERVER-INIT -- Entrada para comandos SERVER que esperam resposla longa. Manda I(0) com para^metros Y(0) Processa parms. SEND-GEN-CMD N, TIMEOUT R+ SEND-SERVER-INIT E Usa parms. default SEND-GEN-CMD outro ABORT SEND-GEN-CMD -- Entrada para comandos SERVER que esperam resposta curta (ACK) Manda G, R ou C(0) S(0) Processa parms, ACK c/parms, N+ REC-FILE X(1) Prepara p/ teclar no term., N+ REC-DATA Y(0) Tecla dados no tty COMPLETE N, TIMEOUT R+ SEND-GEN-CMD outro ABORT COMPLETE -- Transac,a~o completada com sucesso Arma N e R em 0 Se SERVER, restaura parms, REC-SERVER-IDLE sena~o EXIT ABORT -- Te'rmino prematuro de transac,a~o Restaura qualquer arquivo aberto, arma N e R em 0 Se SERVER, restaura para^metros, REC-SERVER-IDLE sena~o EXIT EXIT/LOGOUT --termina ou executa "LOGOUT" Note que os comandos gene'ricos determinam o pro'ximo estado da seguinte maneira: 1. Se o comando na~o for suportado, um pacote de erro e' transmitido e o pro'ximo estado e' ABORT. 2. Se o comando gera uma resposta que pode caber no campo de dados de um ACK, um ACK e' mandado com o texto (marcado como se fizer necessa'rio) no seu campo de dados. 3. Se o comando gera uma resposta grande ou tem que transmitir um arquivo, nada e' mandado do estado REC- SERVER-IDLE e o pro'ximo estado e' ou SEND-INIT (ou se na~o foi recebida mensagem I ou se deve ser usado um tipo de checagem de bloco alternativo) ou OPEN-FILE (se chegou uma mensagem I ou se deve usar a checagem de bloco de um u'nico caracter). 4. Se o comando e' LOGOUT, e' mandado um ACK e o novo estado e' LOGOUT. 5. Se o comando e' EXIT, e' mandado um ACK e o novo estado e' EXIT. .pa .heComandos KERMIT ..@adu 9. Comandos KERMIT ..@icomandos KERMIT ..@iKERMIT, comandos Sugerimos os comandos e termos KERMIT como na lista abaixo. Na~o e' intenc,a~o recomendar um estilo particular de ana'lise de comandos, somente promover um vocabula'rio consistente, tanto em documentac,a~o quanto na escolha dos nomes para os comandos. ..@bd 9.1. Comandos Ba'sicos ..@icomandos basicos ..@icomando, SEND ..@iSEND SEND Este verbo diz ao programa KERMIT para mandar um ou mais arquivos de sua pro'pria estrutura de arquivos. ..@iRECEIVE ..@icomando, RECEIVE RECEIVE Informa ao KERMIT para esperar um ou mais arquivos que devem chegar. ..@iGET ..@icomando, GET GET Diz a um USER KERMIT para pedir que o SERVER do outro lado da conexa~o mande um ou mais arquivos. Algumas implementac,o~es do KERMIT tem comandos separados de GET e RECEIVE; outros usam o RECEIVE para os dois propo'sitos, o que gera confusa~o. O fato de se poder especificar nomes diferentes para arquivos fonte e destino pode ser u'til e, a`s vezes, necessa'rio. Porisso esses comandos podem ter operandos opcionais [entre colchetes] como aparecem abaixo. ..@iSEND ..@icomando, SEND SEND nome-local-fonte [nome-remoto-destino] Se for inclui'da a especificac,a~o do arquivo em seu destino, ela ira' no pacote de cabec,alho de arquivo, em lugar do nome local. ..@iRECEIVE ..@icomando, RECEIVE RECEIVE [nome-local-de-destino] Se a especificac,a~o do arquivo em seu destino e' dada, o arquivo chegante sera' armazenado sob tal nome, ao inve's do que vier no pacote de cabec,alho de arquivo. ..@iGET ..@icomando, GET GET nome-fonte-remoto [nome-local-destino] Se o nome local for especificado, o arquivo chegante sera' armazenado sob tal nome, abandonando o nome que vier no pacote de cabec,alho de arquivo. Na~o se deve usar nomes alternados se um grupo de arqui vos estiver sendo transmitido ou recebido. ..@bd 9.2. Comandos de gere^ncia do programa ..@icomandos de gerencia do programa ..@iprograma, comandos de gerencia ..@igerencia, comandos de - do programa ..@iEXIT ..@icomando, EXIT EXIT Deixa o programa KERMIT, fazendo antes qualquer limpeza que seja necessa'ria -- desassociando pe rife'ricos, fechando arquivos etc. ..@iQUIT ..@icomando, QUIT QUIT Deixa o programa KERMIT, sem fazer antes qualquer arrumac,a~o, de maneira a permitir alguma posterior manipulac,a~o de arquivos e perife'ricos. ..@iPUSH ..@icomando, PUSH PUSH Preserva o atual ambiente KERMIT e entra no processador de comandos do sistema. ..@iTAKE ..@icomando, TAKE TAKE Le^ e executa comandos KERMIT a partir de um arquivo local. ..@iLOG ..@icomando, LOG LOG Especifica um arquivo de LOG para transac,o~es de transfere^ncia de arquivos ou para LOGGIN de sesso~es de terminal. ..@bd 9.3. Comandos de emulac,a~o de terminal. ..@icomandos de emulacao de terminal ..@iterminal, comandos de emulacao ..@iemulacao, comandos de - de terminal ..@iCONNECT ..@icomando, CONNECT CONNECT Este verbo, va'lido somente para um KERMIT local, significa entrar no modo emulac,a~o de terminal; cria a ilusa~o de ser um terminal do sistema remoto. Prove^ um "caracter de escape" para permitir que o usua'rio "volte" ao sistema local. O caracter de escape, quando teclado, pede um argumento de um u'nico caracter; sa~o sugeridos os seguintes: 0 (zero) transmite um NUL B transmite um BREAK C encerra a emulac,a~o P forc,a a entrada no processador de comandos do sistema Q encerra o logging (se estiver sendo feito) R reinicia (RESUME) o logging S mostra o status da conexa~o ? mostra os argumentos va'lidos para o caracter de escape (outro caracter de escape): transmite o pro'prio caracter de escape Os equivalentes minu'sculos devem ser aceitos. Se um argumento inva'lido for teclado, soar um bip. (veja, tambe'm, o comando SET.) ..@bd 9.4. Comandos em modo-usua'rio especiais ..@icomandos em modo-usuario especiais ..@imodo-usuario, comandos especiais Tais comandos somente sa~o usados por USERs em SERVERs. ..@icomando, BYE ..@iBYE BYE Este comando manda uma mensagem para o SERVER remoto para que ele se LOGOUT e, apo's o sucesso desta operac,a~o, termina o programa KERMIT local. ..@icomando, FINISH ..@iFINISH FINISH Forc,a o SERVER remoto a terminar sem encerrar seu JOB, deixando o KERMIT local em ni'vel de comando, permitindo que o usua'rio se reconecte ao JOB remoto. ..@bd 9.5. Comandos cujo objeto deve ser especificado ..@icomandos com objeto ..@icomando, com objetos Algumas implementac,o~es do KERMIT incluem diversos servic,os de gerenciamento de arquivos locais e comandos para invoca'-los. Por exemplo, uma implementac,a~o pode ter comandos que permitam que voce tenha listagens de direto'rio, apague arquivos, troque de discos e saiba quanto espac,o tem disponi'vel sem que, para isto, tenha que sair e reiniciar o programa. SERVERs remotos tambe'm podem prover tais servic,os. Um USER KERMIT pode ser capaz de distinguir entre comandos direcionados ao seu pro'prio sistema daqueles que devem ser repassados para o sistema remoto. Quando passi'vel de confusa~o, um comando pode ser prefixado por um dos "prefixos objeto": ..@iREMOTE ..@icomando, REMOTE REMOTE Pede que o SERVER remoto fac,a este servic,o. ..@iLOCAL ..@icomando, LOCAL LOCAL Faz o servic,o localmente. Se o "prefixo objeto" for omitido, o comando deve ser executado localmente. Os servic,os sa~o: ..@iLOGIN ..@icomando, LOGIN LOGIN Deve ser empregado no seu sentido de compartilhamento de tempo, para criar uma identificac,a~o ("JOB", "sessa~o", "acesso", "conta") no sistema. ..@iLOGOUT ..@icomando, LOGOUT LOGOUT Para terminar uma sessa~o iniciada com LOGIN. ..@iCOPY ..@icomando, COPY COPY faz uma co'pia do arquivo especificado com o nome dado. ..@iCWD ..@icomando, CWD CWD Muda o direto'rio de trabalho. Este e' feio mas verbos naturais como CONNECT e ATTACH sa~o muito imprecisos. CWD e' o comando padra~o para trans fere^ncia de arquivos na ARPANET para invocar esta func,a~o. ..@iDIRECTORY ..@icomando, DIRECTORY DIRECTORY Prove^ uma lista de nomes e possivelmente outros atributos dos arquivos no direto'rio de trabalho corrente ou especificado. ..@iDELETE ..@icomando, DELETE DELETE Apaga o(s) arquivo(s) especificado(s). ..@iERASE ..@icomando, ERASE ERASE Poderia ser um sino^nimo para DELETE. Na~o parece ser bom incluir UNDELETE ou UNERASE na lista padra~o: a maioria dos sistemas na~o suportam uma func,a~o como esta e na~o se deve brincar com as expectativas de um usua'rio... ..@iKERMIT ..@icomando, KERMIT KERMIT Manda um comando para o analisador de comandos do SERVER remoto. ..@iRENAME ..@icomando, RENAME RENAME Muda o nome do arquivo especificado. ..@iTYPE ..@icomando, TYPE TYPE Mostra o conteu'do do arquivo especificado na tela do usua'rio. ..@iSPACE ..@icomando, SPACE SPACE Informa quanto espac,o esta' usado e quanto esta' disponi'vel para armazenamento de arquivos no direto'rio corrente ou especificado. ..@iSUBMIT ..@icomando, SUBMIT SUBMIT Submete o arquivo especificado para processamento em batch. ..@iPRINT ..@icomando, PRINT PRINT Imprime o(s) arquivo(s) especificado(s) numa impressora. ..@iMOUNT ..@icomando, MOUNT MOUNT Pede a montagem de um disco, fita ou outro meio de armazenamento de massa removi'vel. ..@iWHO ..@icomando, WHO WHO Mostra quem esta' "logado" (num sistema de timesharing) ou da' informac,o~es a respeito de um determinado usua'rio ou host (numa rede de computadores). ..@iMAIL ..@icomando, MAIL MAIL Manda uma corresponde^ncia eletro^nica para determinado(s) usua'rio(s). ..@iMESSAGE ..@icomando, MESSAGE MESSAGE Manda uma mensagem de terminal (numa rede ou sistema de timesharing). ..@iHELP ..@icomando, HELP HELP Da' breves informac,o~es sobre como usar o KERMIT. ..@iSET ..@icomando, SET SET Prepara va'rios para^metros relacionados com depurac,a~o, transmissa~o, modo de arquivo etc. ..@iSHOW ..@icomando, SHOW SHOW Mostra como os para^metros esta~o preparados, potencialidades etc. ..@iSTATISTICS ..@icomando, STATISTICS STATISTICS Da' informac,o~es acerca da performance da transfere^ncia de arquivos mais recente -- tempo decorrido, baud rate efetivo, diversos contadores etc. ..@iHOST ..@icomando, HOST HOST Repassa a cadeia de caracteres (de comando) dada para o host (local ou remoto) especificado para execuc,a~o em sua pro'pria linguagem de comandos. ..@iLOGGING ..@icomando, LOGGING LOGGING Abre ou fecha um LOG remoto de transac,a~o ou de depurac,a~o. .cp 4 ..@bd 9.6. O comando SET ..@icomando, SET ..@iSET Deve ser provido um comando SET para que o usua'rio possa adaptar uma conexa~o a`s particularidades do caminho da comunicac,a~o, ao sistema de arquivos local ou remoto etc. Aqui esta~o alguns para^metros passi'veis de alterac,a~o atrave's de um comando SET: ..@iBLOCK-CHECK BLOCK-CHECK Especifica o tipo de checagem de bloco a ser utilizada: checksum de um u'nico caracter, de dois ou CRC de 3 caracteres. ..@iDEBUGGING DEBUGGING Mostra ou "LOGa" o tra'fego e nu'meros dos pacotes e os estados em que entra o programa. Muito u'til para depurar novas verso~es de KERMIT, combinac,o~es ine'ditas de KERMITs etc. ..@iDELAY DELAY Quantos segundos um KERMIT remoto (na~o SERVER) deve esperar antes de mandar o pacote SEND-INIT, para dar tempo ao usua'rio para "escapar" de volta ao KERMIT local e teclar um comando RECEIVE. ..@iDUPLEX DUPLEX Para emulac,a~o de terminal, especifica full duplex (eco remoto) ou half duplex (eco local). ..@iEIGHT-BIT-PREFIXING EIGHT-BIT-PREFIXING Ativa a prefixac,a~o de oitavo bit. ..@iEND-OF-LINE ..@iEOL END-OF-LINE Especifica qualquer terminador de linha que deva ser empregado depois de um pacote. ..@iESCAPE ESCAPE Informa qual caracter de escape deve ser usado numa emulac,a~o de terminal. ..@iarquivo, atributo ..@iatributos de arquivos ..@iFILES ATTRIBUTES FILE ATTRIBUTES Quase todos os atributos listados antes (sec,a~o 8.5). A necessidade mais comum e' a de dizer ao KERMIT se o arquivo a ser transmitido ou recebido e' texto ou bina'rio. ..@iFLOW-CONTROL ..@iXON/XOFF ..@iDTR/CTS ..@ifcontrole de fluxo ..@ifluxo, controle de FLOW-CONTROL Especifica o mecanismo de controle de fluxo para a linha, como XON/XOFF, DTR/CTS etc. Permite acionar ou retirar controle de fluxo, que e' feito somente em conexo~es full duplex. ..@iHANDSHAHE HANDSHAKE Especifica qualquer negociac,a~o de acesso a` linha que deva ser empregada ou simulada durante uma transfere^ncia de arquivo. Por exemplo, um sistema half duplex frequentemente precisa "virar a linha" depois de mandar um pacote, de forma a lhe dar permissa~o para responder. Um handshake comum e' XON (^Q); o usua'rio corrente da linha transmite um XON quando termina de transmitir seus dados ..@iLINE LINE Especifica a linha ou designador de dispositivo para a conexa~o. Para emprego em um programa KERMIT que possa rodar tanto em modo local quanto remoto; a linha default e' o terminal de controle (para operac,a~o remota). Se um dispositivo externo e' usado, presume-se operac,a~o local. ..@iLOG LOG Informa o arquivo local onde guardar um LOG da transac,a~o. Podem existir LOGs para depurac,a~o (tra'fego de pacotes, transic,o~es de estado etc) e para propo'sitos de auditoria (registrar nome e disposic,a~o de cada transfere^ncia de arquivo). ..@iMARKER MARKER Muda o marcador de ini'cio de pacote, do seu default SOH (^A) para algum outro caracter de controle, no caso de um (ou ambos) os sistemas ter problema em usar SOH para tal propo'sito. ..@iPACKET-LENGTH ..@ipacote, comprimento do ..@icomprimento do pacote PACKET-LENGTH O maior comprimento de um pacote. Normalmente na~o deve ser menor que 30 ou 40 e nunca maior que 96. Pacotes curtos podem ser uma vantagem em linhas com muito rui'do; eles reduzem a probabilidade de um pacote ser corrompido, bem como o overhead de retransmisso~es quando acontece o erro. ..@iPADDING ..@ipreenchimento PADDING O nu'mero de caracteres de preenchimento que devem ser transmitidos antes de cada pacote e qual deve ser tal caracter. Raramente necessa'rio. ..@iPARITY ..@iparidade PARITY Especifica a paridade (ODD, EVEN, MARK, SPACE, NONE) na conexa~o fi'sica. Se diferente de NONE, o oitavo bit na~o pode ser usado para transmitir dados e na~o pode ser usado por qualquer dos dos lados no ca'lculo de checagem de bloco. ..@iPAUSE PAUSE Quantos segundos pausar depois de receber um pacote e antes de mandar o pro'ximo. Normalmente 0 mas quando um processador de comunicac,a~o de um sistema (front end) esta' com problemas de tra'fego, uma pequena pausa entre pacotes pode ajudar; grac,as aos ce'us algo abaixo de 1 segundo e' suficiente. ..@iPREFIX .cp 2 PREFIX Muda o prefixo default para caracteres de controle, caracteres de 8 bits ou quantidades repetidas. ..@iPROMPT PROMPT Troca o prompt do programa. E' u'til ao rodar KERMIT entre dois sistemas com o mesmo prompt, eliminando a confusa~o acerca de qual dos KERMITs esta' falando com voce. ..@iREPEAT-COUNT-PROCESSING ..@icontador de repeticoes REPEAT-COUNT-PROCESSING Muda o default para o processamento do contador de repetic,o~es. Normalmente sera' feito se ambos os KERMITs concordarem com isto. ..@iRETRY ..@iretransmissoes ..@ilimite de retransmissoes RETRY Nu'mero ma'ximo de tentativas em mandar ou receber um pacote antes de desistir. O nu'mero normal e' em torno de 5 mas o usua'rio deve estar capacitado a ajusta'-lo de acordo com as condic,o~es da linha, a carga nos sistemas etc. ..@iTIMEOUT TIMEOUT Especifica a quantidade de tempo a ser dada para uma espera por um pacote. ..@bd 9.7. Macros (o comando DEFINE) ..@iDEFINE ..@imacros ..@icomando, DEFINE Ale'm dos comandos SET individuais, uma facilidade de "macro comandos" e' recomendada, para permitir que os usua'rios combinem as caracteri'sticas de determinados sistemas em um u'nico comando SET. Por exemplo: ..@iUNIX ..@iIBM ..@iexemplo ..@iparidade ..@iTELENET ..@ihandshake ..@iDUPLEX ..@iFULL ..@iHALF ..@iMARK DEFINE IBM = PARITY ODD, DUPLEX HALF, HANDSHAKE XON DEFINE UNIX = PARITY NONE, DUPLEX FULL DEFINE TELENET = PARITY MARK Isto pode ser feito provendo-se um analisador caprichado para comandos como este (que podem utilizar o pro'prio arquivo de inicializac,a~o do KERMIT USER durante a inicializac,a~o do programa) ou simplesmente escrito dentro da tabela do comando SET, no fonte do KERMIT. Feitas estas definic,o~es, o usua'rio simplesmente teclaria "SET UNIX" ou qualquer outra coisa, que prepararia todo o programa, de uma so' vez, para se comunicar com o sistema remoto. .pa .heEmulac,a~o de Terminal ..@adu 10. Emulac,a~o de terminal ..@iterminal ..@iterminal, emulacao O sistema local tem que ser capaz de agir como um terminal, de modo a permitir que o usua'rio se conecte ao sistema remoto, identifique-se la' e inicie o KERMIT remoto. Qualquer programa KERMIT que rode localmente deve prover emulac,a~o de terminal, para que o usua'rio na~o tenha que ficar trocando de programas de forma a transferir arquivos e operar protocolo de terminal. Nos sistemas menores isto e' particularmente importante por va'rias razo~es (reiniciar o programa e reentrar todos os comandos SET necessa'rios e' muito inconveniente e desperdic,a muito tempo; em alguns micros, entrar e sair de emulac,a~o de terminal pode fazer a portadora cair etc.). O KERMIT so' precisa suprir uma emulac,a~o de teminal bem simples, pe'-de-boi. Na~o ha' a necessidade de simular qualquer terminal particularmente "esperto". Uma simulac,a~o de qualquer terminal "burro" e' suficiente para fazer o servic,o. E' bom ter uma emulac,a~o mais caprichada, no entanto, para se tirar vantagem das capacidades de visualizac,a~o e edic,a~o do sistema remoto. Em alguns casos o firmware do microcomputador cuidara' disto. Para construir uma emulac,a~o de um tipo especial de terminal no programa, voce deve interpretar e agir sobre as seque^ncias de ESCAPE conforme elas forem chegando na porta. Durante a emulac,a~o de terminal na~o e' feita checagem de erros. Esta' "fora do protocolo"; os caracteres va~o e ve^m "nus". Sob este ponto de vista, emular um terminal atrave's do KERMIT na~o e' melhor que usar, realmente, um terminal real. Algumas implementac,o~es de KERMIT podem permitir logar a emulac,a~o de terminal em um arquivo local. Tal facilidade ajuda a "capturar" arquivos teclados remotamente, (lembre-se: sem correc,a~o ou checagem de erros). Quando existe tal facili dade, e' deseja'vel ter uma forma conveniente de ligar e desligar a gravac,a~o do LOG. Se o sistema local na~o prove^ controle de fluxo a ni'vel de sistema (ou de firmware), como XON/XOFF, o programa de emulac,a~o de terminal deve tentar simula'-lo, especialmente se estiver sendo feito LOG. A facilidade de emulac,a~o de terminal deve ser capaz de lidar tanto com eco local quanto remoto (full ou half duplex), qualquer handshake exigido, bem como transmitir qualquer paridade exigida pelo lado remoto ou meio de comunicac,a~o. Os emuladores de terminal funcionam amostrando conti nuamente tanto inputs da console do terminal local quanto da linha de comunicac,a~o. As func,o~es simples de input e output na~o sera~o suficientes, entretanto, ja' que se voce pede input de um determinado dispositivo na~o houver a disponibilidade, geralmente voce vai bloquear ate' que haja, realmente, um input e durante este tempo estara' perdendo inputs do outro dispositivo. Assim voce tem que ter uma maneira de "olhar" para um lado e para o outro, independentemente de haver ou na~o um input disponi'vel. Diversos mecanismos sa~o comunmente usados: * "Pular" para frente e para tra's, continuamente, entre o registrador de status da porta e da console, checando os bits de status em busca de input disponi'vel. Isto so' e' pra'tico em sistemas mono-usua'rio, mono-processo, onde a CPU na~o tem mais nada a fazer. * Emitir um pedido de input blocado normal para a porta mas habilitando interrupc,a~o por input da console ou vice-versa. * Manusear o input da porta em um processo e da console em outro, paralelamente. O programa KERMIT para UNIX listado neste manual emprega este me'todo. Qualquer input da porta deve ser mostrado, imediatamente, na tela. Qualquer input da console deve ser, em seguida, transmitido porta a fora. Adicionalmente, se a conexa~o for half duplex, o input da console deve ser mostrado na tela, tambe'm. O co'digo de emulac,a~o de terminal deve examinar cada caracter da console para determinar se e' o "caracter de escape". Se for, deve tomar o pro'ximo como um comando especial, que, enta~o, executa. Estes comandos foram descritos anteriormente, na sec,a~o 9.3. O emulador de terminal deve ser capaz de transmitir todos os caracteres ASCII, do NUL ao DEL, e ser capaz tambe'm de transmitir um sinal BREAK (na~o e' um caracter mas um "escape" de uma transmissa~o ASCII na qual um 0 e' colocado na linha durante cerca de 1/4 de segundo, a despeito do baud rate, sem bits de framing). O BREAK e' importante ao se comunicar com va'rios sistemas, como mainframes da IBM. Finalmente, a`s vezes, e' necessa'rio executar certas transformac,o~es no caracter CR que normalmente e' teclado para terminar uma linha de input. Alguns sistemas usam LF, EOT ou outro caracter para esta func,a~o. Para complicar, alguns equipamentos de comunicac,a~o intervenientes (particularmente redes de comutac,a~o de pacotes publicas) podem ter seus pro'prios requisitos independentes. Assim, ao se usar o KERMIT para se comunicar atrave's, digamos, da TRANSPAC, com um sistema que emprega LF para fim-de-linha, pode ser necessa'ria a transformac,a~o do CR em LFCR (LF antes -- o CR comanda a rede para transmitir o pacote, que contera' o LF e o host usa o LF para terminac,a~o). O usua'rio deve ser provido de um mecanismo para especificar esta transformac,a~o, um comando como "SET CR seque^ncia". .pa .heEscrevendo um programa KERMIT ..@adu 11. Escrevendo um programa KERMIT ..@iKERMIT, escrevendo um ..@iprograma, escrevendo um KERMIT Antes de escrever uma nova implementac,a~o de KERMIT ou modificar uma existente, entre em contato com o Centro de Distribuic,a~o do KERMIT, na Universidade de Colu'mbia, para se assegurar que voce na~o estara' duplicando o esforc,o de outra pessoa e de que tera' todo o material mais atualizado para trabalhar. Caso voce realmente escreva ou modifique significantemente (ou documente) um programa KERMIT, por favor: mande-o de volta para o C.U.C.C.A., onde sera' inclui'do na distribuic,a~o padra~o do KERMIT e outros podera~o ser beneficiados. E' somente atrave's desta forma de compartilhamento que o KERMIT cresceu de seu modesto ini'cio para a escala atual. As sec,o~es a seguir prove^em algumas "dicas" de programac,a~o KERMIT. ..@bd 11.1. Organizac,a~o do programa ..@iprograma, organizacao ..@iorganizacao do programa Uma implementac,a~o ba'sica de KERMIT pode usualmente ser escrita como sendo um programa relativamente pequeno, auto- contido num u'nico fonte. Entretanto e' normal o caso de um programa que foi escrito para rodar em um sistema, ser adaptado para rodar em outros sistemas tambe'm. Neste caso e' melhor evitar ter fontes totalmente divergentes, porque quando novas facilidades sa~o acrescentadas (ou problemas corrigidos) em partes do programa independentes de sistema (i. e': no protocolo em si), somente uma implementac,a~o colhera' os benefi'cios inicialmente, enquanto que as outras exigira~o ajustes dolorosos, propensos a erro(s) ate' que sejam levadas ao mesmo ni'vel. Assim, se houver alguma chance de um programa KERMIT vir a rodar em mais de um tipo de ma'quina ou sistema operacional ou, ainda, suportar mais de um tipo de porta ou modem etc., e' deseja'vel isolar as partes dependentes de sistema de uma forma a deixar as partes comuns utiliza'veis pelas va'rias implementac,o~es. Existem diversos enfoques: 1. Suporte em tempo de execuc,a~o. Se possi'vel, o programa pode inspecionar o hardware ou pedir para^metros relevantes sobre o sistema e se configurar dinamicamente em tempo de inicializac,a~o. E' a forma mais difi'cil de implementar. 2. Compilac,a~o (montagem) condicional. Se o nu'mero de sistemas ou opc,o~es a serem suportados for pequeno, a parte do co'digo dependente de sistema pode ser inclui'do em rotinas compiladas condicionalmente (como IF IBMPC ... ENDIF). Como exemplo, veja a listagem de um KERMIT para UNIX fornecida com este manual. No entanto, conforme o nu'mero de depende^ncias de sistema a serem suportadas cresce, este me'todo tende a se tornar canhestro e passi'vel de erros (instalar suporte para o sistema X pode tornar inva'lido o suporte para o sistema Y). 3. Composic,a~o modular. Quando existir a potenciali dade de um grande nu'mero de opc,o~es vir a ser suportadas, o programa deve ser quebrado em mo'dulos separados, com convenc,o~es de chamada simples e claramente especificadas. Isto permite que pessoas com novas opc,o~es de^em seu pro'prio suporte a elas de forma fa'cil, sem perigo de causar mal ao suporte existente. Os mo'dulos sugeridos para um programa KERMIT sa~o: - manuseio de protocolo independente de sistema: troca de estado, formac,a~o de pacotes, codificac,a~o (prefixac,a~o), deco dificac,a~o etc. - interface com o usua'rio: o analisador de comandos; sendo um mo'dulo separado, permite inclusa~o de analisadores de comando de acordo com o gosto do usua' rio, mimetizando o estilo do analisador de comandos do host ou de algum aplica tivo popular etc. - manuseio da tela: este mo'dulo conteria os co'digos de controle de tela, rotinas de posicionamento do cursor etc. - manuseio da porta: permite o suporte de va'rios hardwares de porta; este mo'dulo pode definir a localizac,a~o do registra dor de status da porta, o significado de seus bits e dai' em diante e pode imple mentar as func,o~es de receber e transmitir caracteres pela porta - controle de modem: deve suportar qualquer tipo de modem "inteligente", que na~o seja meramente uma extensa~o transparente da porta de comunicac,a~o; tais modems podem aceitar comandos especiais para executar func,o~es como discar, rediscar o u'ltimo nu'mero, desligar etc. e podem carecer de inicializac,a~o especial (forc,ar sinais como DTR, p.e.) - input de console: este mo'dulo deve suprir a func,a~o de pegar um caracter da console; ele saberia as localizac,o~es dos registradores de status e o significado de seus bits, estrutura de interrupc,a~o, conversa~o tecla-caracter etc., implementar redefinic,o~es de teclas, macros de teclado, func,o~es programa'veis, controles expandidos, meta-func,o~es etc. - emulac,a~o de terminal: este mo'dulo deve interpretar seque^ncias de escape no fluxo de caracteres que chegam (obtido do mo'dulo de I/O da porta) para o tipo particular de terminal sendo emulado e interpreta'-lo fazendo os "call's" apropriados ao mo'dulo de I/O de tela e mandaria o que o usua'rio teclasse (obtido do mo'dulo de entrada por console) pela porta serial (novamente usando o mo'dulo de I/O de porta); a ide'ia e' poder trocar este mo'dulo por outros, de forma a emular diferentes tipos de terminais (ANSI, VT52, ADM3A etc.) - I/O de arquivos: conte'm todo o conheci mento a respeito da estrutura de sistema de arquivamento de host; como abrir e fechar arquivos, operac,o~es de "pegar o pro'ximo arquivo", ler, gravar, determi nar e alterar seus atributos, detectar o fim de um arquivo etc.; prove^ tambe'm as func,o~es (incluindo a de bufferizac,a~o) de ler um caracter de um arquivo e grava'- lo em outro; este mo'dulo tambe'm pode prover servic,os de gerenciamento de arquivos em termos locais (listagens de direto'rio, apagar, renomear, copiar etc.) - definic,o~es e dados: mo'dulos separados podem ser tambe'm guardados para definic,o~es de para^matros para tempo de compilac,a~o e para dados globais para tempo de execuc,a~o. .pa ..@bd 11.2. Linguagem de programac,a~o ..@iprogramacao, linguagem ..@ilinguagem de programacao A linguagem a ser usada para se escrever um programa KERMIT e' qualquer coisa mais do que mera questa~o de gosto. A considerac,a~o prima'ria e' que a linguagem escolhida deve dar a funcionalidade e velocidade necessa'rias. Por exemplo, uma implementac,a~o do BASIC em um microcomputador pode na~o permitir o tipo de acesso em baixo ni'vel aos registradores dos dispositivos necessa'rio em uma emulac,a~o de terminal ou para detetar input da console durante uma transfere^ncia de arquivo ou, mesmo, se pode fazer essas coisas, pode na~o ser capaz de rodar ra'pido o suficiente para manter a linha de comunicac,a~o na baud rate desejada. A segunda considerac,a~o em escolher a linguagem e' sua portabilidade. Pode ser encarada de duas maneiras: 1) se a linguagem e' de domi'nio pu'blico (ou, equivalentemente, distribui'da sem o^nus como parte de um sistema ba'sico) e 2) se e' bem padronizada e de uso difundido em va'rios sistemas. Uma linguagem porta'vel nesses dois sentidos deve ter prefere^ncia. Qualquer que seja a linguagem escolhida, e' importante que todas as linhas do programa fonte na~o excedam 80 carac teres (depois da expansa~o dos TABs). Isto porque material KERMIT frequentemente precisa ser transportado por RJE e outros links de comunicac,a~o que obedecem o formato "carta~o". E, finalmente, e' importante que os nomes de todos os arquivos usados na criac,a~o e suporte de uma determinada implementac,a~o do KERMIT seja (possivelmente um subset) da forma NOME.TIPO, onde NOME esta' limitado a 6 caracteres e TIPO a 3; onde o nome de cada arquivo comece com um prefixo comum de 2 ou 3 caracteres. Isto e' assim para que todos os arquivos relacionados ficara~o agrupados numa listagem alfabe'tica de direto'rio e tambe'm, quando todas as centenas de arquivos relacionados com o KERMIT fiquem colocados juntos em uma fita, todos os nomes sera~o tanto legais quanto u'nicos, especialmente em sistemas (como o do PDP-11) com convenc,o~es restritivas de batismo de arquivos. ..@bd 11.3. Documentac,a~o ..@idocumentacao Um programa KERMIT novo deve ser pesadamente documentado. Um dos pontos altos do KERMIT e' sua documentac,a~o. Deve ser tanto a ni'vel de usua'rio (como usar o programa, quais comandos existem e porque etc., similarmente a` documentac,a~o presentemente encontrada no "Guia do Usua'rio"), quanto a ni'vel de implementac,a~o (descrevendo depende^ncias do sistema, pontos para possi'vel adaptac,a~o para outros sistemas etc.). Ale'm disso, os pro'prios programas devem conter, copiosamente, comenta'rios. Como o programa fonte, a documentac,a~o deve ser mantida no limite dos 80 caracteres por linha. Se possi'vel, uma sec,a~o para a implementac,a~o deve ser escrita para ser anexada ao Guia do Usua'rio usando-se a linguagem de formatac,a~o do SCRIBE, da Unilogic (subsets do qual podem ser encontrados em alguns softwares de processamento de texto para microcomputadores, como Perfect Writer, ou Final Word), usando a mesma convenc,a~o geral das sec,o~es de implementac,a~o do EXISTIC, formato Scribe. Programas KERMIT tambe'm devem conter um histo'rico das reviso~es, onde cada alterac,a~o e' explicada sucintamente, associada a um "nu'mero de edic,a~o", programador responsa'vel e lugar e/ou data. As linhas ou sec,o~es editadas devem ser marcadas com o nu'mero de edic,a~o correspondente e o programa KERMIT, ao se iniciar, deve anunciar sua versa~o e nu'mero de edic,a~o, de forma que um usua'rio, ao perceber um defeito, possa se referir a essas informac,o~es. O nu'mero da versa~o muda quando a funcionalidade mudou suficientemente para requerer maiores reviso~es na documentac,a~o. O nu'mero de edic,a~o deve crescer (monotonicamente, na~o relacionado com o nu'mero da versa~o) sempre que uma alterac~ao for feita no programa. Os nu'meros de edic,a~o sa~o muito importantes para a gere^ncia do fonte; depois de mandar para algue'm uma versa~o do, digamos, CP/M KERMIT-80, costumamos receber muitas co'pias dele de volta, cada uma contendo seu pro'prio conjunto de mudanc,as, que precisamos reconciliar de alguma maneira. O uso dos nu'meros de edic,a~o auxiliam muito esta tarefa. ..@bd 11.4. Bootstrapping ..@ibootstrapping Finalmente, deve ser dado um procedimento de bootstrap. O KERMIT geralmente e' distribui'do em fita magne'tica para grandes instalac,o~es; os usua'rios precisam de maneiras de "baixar" as va'rias implementac,o~es para seus micros e outros sistemas locais. Um procedimento simples de bootstrap consistiria de instruc,o~es precisas de como conseguir um co'pia "sem garantia" do programa. Talvez um simples, pequeno programa possa ser escrito para cada ponta que fac,a o servic,o; listagens e instruc,o~es podem ser dadas para que o usua'rio digite e rode tais programas. .pa .heFormato e Tipos dos Pacotes ..@x ..@adu A. Formato e Tipos dos Pacotes ..@ipacote, formato ..@iformato dos pacotes ..@ilayout dos pacotes Layout de um pacote KERMIT: +------+-----+-----+------+------+-------+ | mark | len | seq | type | data | check | +------+-----+-----+------+------+-------+ Layout do campo de dados do pacote SEND-INIT: +------+------+------+------+-----+------+ | maxl | time | npad | padc | eol | qctl | ... +------+------+------+------+-----+------+ +------+------+------+-------+ ... | qbin | chkt | rept | capas | +------+------+------+-------+ Tipos e subtipos de pacotes KERMIT (* = exigido): ..@ipacote, tipos Y* ACK (aceito) N* NAK (na~o aceito) S* SEND-INIT (troca de para^metros) I INIT (troca de para^metros) F* cabec,alho de arquivo A atributos de arquivo D* dados Z* EOF (fim de arquivo) B* EOT (interrupc,a~o da transmissa~o) E* erro R REC-INIT (pede arquivos especificados ao SERVER) C comando para o host K comando para o KERMIT T reservado para uso interno G comando KERMIT gene'rico; subcomandos: I LOGIN/LOGOUT C CWD (troca de direto'rio corrente) L BYE F FINISH D DIRECTORY U pergunta sobre uso de disco E ERASE/DELETE T TYPE R RENAME K COPY W WHO? (quem esta' "logado"?) M mensagem curta H HELP Q pergunta status do SERVER P invoca programa J controle de jornalizac,a~o V varia'veis (inquire, arma) .pa .heRelac,a~o das Facilidades ..@adu B. Relac,a~o das Facilidades ..@irelacao das facilidades ..@ifacilidades, relacao das Na~o existe uma escala linear verdadeira ao longo da qual se mec,a uma implementac,a~o de KERMIT. Uma implementac,a~o ba'sica, mi'nima, prove^ transfere^ncia de arquivos em ambas as direc,o~es e, para microcomputadores (PC's, workstations, outros sistemas mono-usua'rio), emulac,a~o de terminal. Mesmo dentro desta estrutura podem haver variac,o~es. Por exemplo: pode o programa mandar um grupo de arquivos em um u'nico programa ou deve emitir um comando para cada arquivo? Aqui esta' uma lista de facilidades que podem ser apresentadas; para qualquer implementac,a~o de KERMIT a documentac,a~o deve mostrar se a facilidade existe e como invoca'-la. - Grupos de arquivos. Pode mandar um grupo de arquivos com um u'nico comando, usando "wildcard" ("coringa"), modelo ou notac,a~o de lista? Pode, com sucesso, transmi tir ou receber um grupo de arquivos de tipos diferen tes? Pode recuperar-se de um erro em um arquivo em particular e continuar com o pro'ximo? Pode manter um LOG dos arquivos envolvidos, mostrando o arranjo de cada um? - Nomes de arquivos. Ele consegue evitar destruir um arquivo local quando chega um novo arquivo com o mesmo nome? Pode converter nomes de arquivo para/de forma "legal" ou "normal"? - Tipos de arquivos. Arquivos bina'rios sa~o ta~o bem transmitidos quanto os arquivos de texto? - Prefixac,a~o de oitavo bit. Ele pode mandar e receber dados de 8 bits por um canal de 7 bits usando o mecanismo de prefixac,a~o? - Processamento do contador de repetic,o~es. Consegue transmitir e receber dados com caracteres repetidos substitui'dos por uma seque^ncia prefixada? - Emulac,a~o de terminal. Tem ele facilidade de emulac,a~o de terminal? Prove^ va'rias opc,o~es de comunicac,a~o, como selec,a~o de duplex, paridade e handshake? Pode transmi tir todos os caracteres ASCII? Transmite um BREAK? Consegue "logar" uma sessa~o remota localmente, para prover captura de arquivo sem teste de eventuais erros? - Opc,o~es de checagem de bloco. Ale'm do checksum ba'sico de um u'nico caracter, pode ser selecionado um CRC de 2 ou 3 caracteres? - SERVER ba'sico. Pode rodar em modo SERVER, aceitando comandos para mandar ou receber arquivos ou terminar a si pro'prio? - SERVER avanc,ado. Aceita comandos SERVER para apagar arquivos, dar listagens de direto'rio, mandar mensagens etc.? - Mandar comandos para um SERVER. Consegue mandar mensa gens para um SERVER e manusear todas as possi'veis respostas? - Comandos de host. E' capaz de analisar e transmitir comandos para um host remoto? Se e' um SERVER, consegue passar tais comandos para o processador de comandos do host e devolver os resultados para o KERMIT usua'rio local? - Interromper transfere^ncias de arquivos. Pode ele inter romper uma transmissa~o ou recepc,a~o de um arquivo? Consegue responder a pedidos de interrupc,a~o vindos do outro lado? - Servic,os de gerenciamento de arquivos locais. Existem comandos para dar listagens do direto'rio local, apagar arquivos locais etc.? - Atributos de arquivos. Ele consegue transmitir informa c,o~es sobre atributos de arquivos locais e lidar com informac,o~es deste tipo que porventura cheguem? Disposi c,o~es alternativas podem ser alteradas? Arquivos podem ser armazenados? - Capacidade de depurac,a~o. O tra'fego de pacotes pode ser "logado", examinado, refeito passo-a-passo? .pa .heProblemas na~o resolvidos ..@adu C. Problemas na~o resolvidos ..@iproblemas nao resolvidos O KERMIT na~o faz tudo. Esta' aqui uma relac,a~o das coisas que ele na~o faz ou poderia fazer melhor. - O KERMIT na~o pode ser utilizado atrave's de emuladores do protocolo IBM 3270. Sa~o equipamentos que possibilitam terminais ASCII assi'ncronos ou PCs comunicarem-se com mainframes IBM como se fossem terminais si'ncronos de tela completa. Os problemas incluem: a) o conversor de protocolo traduz de EBCDIC para ASCII (isto e': assume que esta' recebendo EBCDIC quando se espera que o KERMIT esteja transmitindo em ASCII) de acordo com uma tabela interna pro'pria, que pode variar de instalac,a~o para instalac,a~o e nunca e' um mapeamento biuni'voco; b) caracteres de controle na~o imprimi'veis, como SOH, na~o podem ser transmitidos, de forma alguma; c) o conversor de protocolos busca comandos de formatac,a~o 3270 e os traduz para seque^ncias ESC para o terminal ASCII, possi'velmente modificando o pacote de dados; d) o sistema IBM automaticamente pausa no final de cada pa'gina cheia; e) o conversor de protocolos pensa que sabe o que esta' "na tela" e pode tentar otimizar; geralmente na~o se sabe exatamente como um conversor de protocolos vai agir ou quanto pode diferir de um outro; apesar disto, pode ser possi'vel contornar esses problemas se os KERMITs nas duas pontas sejam colocados num "modo especial 3270", "limparem a tela" entre dois pacotes e concordarem com alguma convenc,a~o especial para delimitar pacote e traduzir dados. - Prefixac,a~o de caracteres de controle. Isto pode vir a ficar bem caro para arquivos bina'rios ou outros arqui vos cheios de caracteres de controle. Pode ser uma boa ide'ia fazer com que cada host informe quais os carac teres que consegue receber sem prefixac,a~o. Por outro lado, o tiro pode sair pela culatra, quando os dois hosts esta~o ligados atrave's de uma rede ou equipamento que filtra caracteres de controle mesmo que nenhum dos dois hosts os filtre. Em conexo~es diretas, sem fatores desconhecidos, no entanto, muitos caracteres de con trole podem ser transmitidos sem prefixac,a~o. - Quando esta~o sendo transmitidas longas seque^ncias de caracteres dentro da faixa de controle, a prefixac,a~o individual de cada caracter fica onerosa. Co'digos "entra/sai" podem ser aqui empregados mais efetivamente. Idem para longas cadeias com o oitavo bit ligado, quando se faria prefixac,a~o de oitavo bit. O custo seria mais um conjunto de caracteres de prefixac,a~o e a complexidade associada a` formac,a~o e decodificac,a~o dos pacotes. - Em algumas situac,o~es, certos caracteres impri'veis na~o conseguem passar pelo link de comunicac,a~o. Por exemplo: um SERVER terminal de uma rede pode reservar "@" como seu caracter de "atenc,a~o". Deve o protocolo permitir uma forma de codificar tais caracteres para traduc,a~o? Um conjunto de seque^ncias ESC defini'vel pelo usua'rio poderia ser u'til neste caso. - Ironicamente, alguns sistemas na~o se da~o bem com os pequenos tamanhos dos pacotes KERMIT. Sa~o, tipicamente, os grandes sistemas que esperam se comunicar com termi nais em modo "bloco", recebendo milhares de caracteres de uma vez. Tais sistemas acham o KERMIT simplesmente muito caros de rodar. Enquanto isso, outros sistemas que podem rodar KERMIT sem dificuldade, acham sua per formance desapontadora (a eficie^ncia geralmente da' um jeito em cerca de 50 a 80 porcento, isto e': caracteres de dados dividido pela velocidade de transmissa~o da linha, em caracteres por segundo). Estes dois problemas podem ser resolvidos de duas maneiras: permitir a transmissa~o de pacotes mais longos ou de pacotes de dados mu'ltiplos ponto-a-ponto. * Sem mudar o formato ou a codificac,a~o dos campos dos pacotes de controle, pode ser possi'vel ter pacotes mais longos, reservando-se os comprimentos de 0, 1, 2 e 3 como co'digos para nu'meros maiores como 200, 500, 1000, 2000. No entanto, quanto maior for o pacote, maior a probabilidade de ser corrompido e maior a retransmissa~o, se houver NAK. Ale'm disto, a adequac,a~o da checagem de bloco de um caracter seria muito reduzida para pacotes longos, que deveriam, por conseguinte, ser transmitidos com checagem dos tipos 2 ou 3. * Seria possi'vel extender o protocolo para permitir transmissa~o de pacotes de dados enquanto ainda estiverem pendentes ACKs e qualquer ACK poderia valer para o pacote especi'fico ou para todos os precedentes. Um limite para o nu'mero de ACKs pendentes poderia ser combinado; o tamanho ma'ximo de tal "janela varia'vel" teria que ser menor que 64, que e' o ponto onde o nu'mero de um pacote volta a zero e a janela na~o poderia se extender ale'm de 63 sob pena do KERMIT perder a noc,a~o de quantas vezes 64 pacotes foram transmitidos. Uma janela varia'vel de 8 e um tamanho de pacote de 95 teria o mesmo efeito que pacotes de 700 caracteres. Um NAK poderia exigir que o transmissor repetisse tudo desde o pacote que recebeu o NAK. Uma futura edic,a~o deste manual podera' incluir uma especificac,a~o para estas janelas. .pa .heUm programa KERMIT ..@adu D. Um programa KERMIT ..@iprograma, fonte KERMIT em C ..@ifonte de um KERMIT ..@iKERMIT, fonte em C O que temos a seguir e' uma listagem de uma versa~o real de KERMIT, escrita na linguagem C (Kernighan & Ritchie, The C Programming Language, Prentice Hall, 1978). Foi desenhada para rodar sob diversas verso~es do sistema operacional UNIX. A funcionalidade ba'sica do KERMIT esta' presente mas muito pouco das facilidades opcionais. Somente o analisador de comandos mais rudimentar (estilo UNIX) esta' presente. O programa ilustra muitas das considerac,o~es descritas neste manual, com respeito ao protocolo, o desenho do programa etc. Deve ser enfatizado que e' uma implementac,a~o mi'nima do KERMIT. Qualquer um que for escrever um novo KERMIT a partir do zero, deve se sentir encorajado a consultar na fonte a respeito das mais novas implementac,o~es avanc,adas como modelo (cheque, no Guia de Usua'rios KERMIT, a lista de implementac,o~es de KERMIT e suas facilidades). Embora voce possa na~o entender a linguagem em que foi escrito, os profusos comenta'rios podem ser u'teis. O programa a seguir usa notac,a~o decimal para nu'meros e tochar() ao inve's de char() na conversa~o integer-caracter. /* * K E R M I T File Transfer Utility * * UNIX KERMIT, Columbia University, 1981, 1982, 1983 * Bill Catchings, Bob Cattani, Chris Maio, * Frank da Cruz, Alan Crosswell * * also: Jim Guyton, Rand Corporation * Walter Underwood, Ford Aerospace * * usage: kermit c [lbe line baud escapechar] to connect * kermit s [d..ifbl line baud] file ...to send files * kermit r [d..ifbl line baud] to receive files * * where c=connect, s=send, r=receive, * d=debug, i=image mode, f=no filename conversion, * l=tty line, b=baud rate, e=escape char. * * for remote kermit, format is either: * kermit r to receive files * or kermit s files ... to send files * */ /* * modification history: * * oct. 17 included fixes from Alan Croswell (CUCCA) * for IBM_uts: * - change MYEOL character from \N to \R. * - change char to int in bufill so getc would return -1 on * EOF instead of 255 (-1 truncated to 8 bits) * - added read() in rpack to eat the EOL character * - added fflush() call in printmsg to force the output * note: the last three changes are not conditionally * compiled since they should work equally well on any * system. * * changed Berkeley 4.x conditional compilation flag from * UNIX4X to UCB4X. * added support for error packets and cleaned up the printing * routines. */ #include /* definic,o~es standard UNIX */ /* Compilac,a~o condicional para sistemas/ma'quinas dif. */ /* Uma e so' uma das linhas abaixo pode ser 1 */ #define ucb4x 1 /* berkeley 4.x unix */ #define tops-20 0 /* tops-20 */ #define ibm_uts 0 /* amdahl uts em sistema IBM */ #define vax_vms 0 /* vax_vms (na~o implementada, ainda)*/ /* Compilac,a~o condicional para variantes UNIX */ /* Zero significa na~o compila; na~o-zero compila */ #if ucb4x #define v6_libs 0 /* na~o usa "retrofit libraries" */ #define no_fionread 0 /* temos ioctl(fionread,...) para flushinput() */ #define no_tandem 0 /* temos disciplina XON/XOFF */ #endif #if ibm_uts #define v6_libs 0 /* na~o usa "retrofit libraries" */ #define no_fionread 1 /* na~o temos ioctl(fionread,...) para flushinput() */ #define no_tandem 1 /* sem XON/XOFF */ #endif #if v6_libs #include #include #include #else /* #include */ /* #include */ /* #include */ #endif #if no_tandem #define tandem 0 /* na~o suportada */ #endif /* definic,a~o de si'mbolos */ #define maxpacksiz 94 /* maior tamanho para um pacote */ #define soh 1 /* start of header */ #define cr 13 /* carriage return */ #define sp 32 /* espac,o */ #define del 127 /* delete (rubout) */ #define escchr '^' /* escape default no CONNECT */ #define maxtry 10 /* numero de tentativas por pacote */ #define myquote '#' /* caracter de marcac,a~o (quote ) */ #define mypad 0 /* nu'mero de carac.preenchimento */ #define mypchar 0 /* caracter preenchimento (null) */ #if ibm_uts #define myeol '\R' /* end-of-line para sistemas UTS */ #else #define myeol '\N' /* end-of-line */ #endif #define mytime 10 /* segundos para me porem em timeout */ #define maxtim 60 /* timeout ma'ximo*/ #define mintim 2 /* timeout mi'nimo */ /* #define true -1 */ /* constantes boleanas */ /* #define false 0 */ /* macros */ /* * tochar: converte um caracter de controle em caracter * imprimi'vel, somando um espac,o. * * unchar: desfaz tochar. * * ctl: converte caracteres de controle para imprimi'vel * e vice-versa, trocando o bit de controle (isto * e': ^A vira A e A vira ^A). */ #define tochar(ch) ((ch) + ' ') #define unchar(ch) ((ch) - ' ') #define ctl(ch) ((ch) ^ 64 ) /* varia'veis globais */ int size, /* tamanho do dado presente */ rpsiz, /* maior tamanho de pacote recebido */ spsiz, /* maior tamanho de pacote transmitido */ pad, /* quanto mandar de preenchimento */ timint, /* timeout para host estrangeiro em TX */ n, /* nu'mero do pacote */ numtry, /* vezes que retransmiti este pacote */ oldtry, /*vezes que pacote anterior foi retransmitido*/ ttyfd, /* fd de tty para I/O, 0 se remoto */ remote, /* -1 ==> sou KERMIT REMOTO */ image, /* -1 ==> modo 8 bits */ debug, /* ni'vel de sai'da de depurac,a~o */ /* 0 = nenhum */ filnamcnv, /* -1 ==> converte nome arq. p/maiu'sc.*/ filecount; /* nu'mero de arquivos deixados de TX */ char state, /* estado atual */ padchar, /* caracter de preenchimento a mandar */ eol, /* end-of-line a mandar */ escchr, /* caracter de escape num CONNECT */ quote, /* caracter de marcac,a~o que chega */ **filelist, /* lista de arquivos a TX */ *filnam, /* nome do arquivo corrente */ recpkt[maxpacksiz], /* buffer p/receber o pacote */ packet[maxpacksiz]; /* buffer para o pacote */ file *fp, /* pointer para arquivo em disco atual */ *log; /* pointer para arquivo de LOG */ jmp_buf env; /* prt.do ambiente para "timeout longjump" */ /* * m a i n * * main routine - analisa comandos e opc,o~es, * prepara a linha tty, * e pula para a rotina apropriada. */ main(argc,argv) int argc; /* pointers de caracteres e contadores */ char **argv; /* argumentos de linha de comando */ { char *ttyname, /* nome tty p/arg.linha */ *cp; /* pointer de caracter */ int speed, /* velocidade do tty */ cflg, rflg, sflg; /*flags p/connect,receive,send*/ struct sgttyb rawmode, /* controlando tty (raw mode) */ cookedmode, /* controlando tty (cooked mode) */ ttymode; /* modo de linha tty em opc,a~o de linha */ if (argc < 2) usage(); /* existe linha de comando? */ cp = *++argv; argv++; argc -= 2; /* arma ptrs p/args */ /* inicializa esses valores e torce p/que o primeiro pacote * passe numa boa... */ eol = cr; /* eol para pacotes saintes */ quote = '#'; pad = 0; /* sem preenchimento */ padchar = null; /* uso null se na~o se quer preench.*/ speed = cflg = sflg = rflg = 0; /* desliga todos os flags de analise */ ttyname = 0; /* o default e' modo remoto */ #if ucb4x /* default: mascarar em 7 bits, crlf */ image = false; /* maiu'sculas no que chegar e nos nomes de arquivos */ filnamcnv = true; /* conversion for unix systems */ #else image = true; filnamcnv = false; #endif escchr = escchr; /* caracter default p/escape */ while (( *cp) != null) /* analisa carac. no prim.arg.*/ switch (*cp++) { case 'C': cflg++; break; /* CONNECT */ case 'S': sflg++; break; /* SEND */ case 'R': rflg++; break; /* RECEIVE */ case 'D': /* increm. contador de depurac,a~o */ debug++; break; case 'F': /* F = na~o faz conv.maiu'sc.*/ filnamcnv = false; /*em nomes de arq. */ break; case 'I': /* modo imagem (8 bits) */ image = true; break; /* (este e' o default p/ na~o-UNIX)*/ case 'L': /* L = linha tty a usar */ if (argc--) ttyname = *argv++; else usage(); if (debug) printf("Linha p/ host remoto: %s/n", ttyname ); break; case 'E': /* E = caracter de escape */ if (argc--) escchr = **argv++; else usage(); if (debug) printf("Escape = \"%c\"\n",escchr); break; case 'B': /* baud rate */ #if ucb4x if (argc--) speed = atoi(*argv++); else usage(); if (debug) printf("Velocidade da linha p/ host: %d\n",speed); break; #else printmsg("Preparar velocidade so' sob UNIX."); exit(1); #endif } /* fazendo a ana'lise */ if ((cflg+sflg+rflg) != 1) /* so' pode 1 comando */ usage(); if (ttyname) /* se foi especificada linha, */ { /* opera em modo local */ ttyfd = open(ttyname,2); /* abre linha tty */ if (ttyfd < 0) { printmsg("%s nao abre.", ttyname); exit(1); } remote = false;/* indica modo local */ } else /* linha nao especificada */ { ttyfd = 0; remote = true; } /* poe o tty certo no modo correto */ if (remote) { gtty(0,&cookedmode); /* salva modo corrente*/ gtty(0,&rawmode); rawmode.sg_flags \= (raw\tandem); rawmode.sg_flags &= ^(echo\crmod); stty(0,&rawmode); /* poe tty em raw mode */ } else /* local, usa linha associada */ { gtty(ttyfd,&ttymode); ttymode.sg_flags \= (raw\tandem); ttymode.sg_flags &= ^(echo\crmod); #if ucb4x /* so' muda velocidade sob UNIX */ if (speed) /* usuario especificou veloc.? */ { switch(speed) { case 110: speed = b110; break; case 150: speed = b150; break; case 300: speed = b300; break; case 1200: speed = b1200; break; case 2400: speed = b2400; break; case 4800: speed = b4800; break; case 9600; speed = b9600; break; default: printmsg("Velocidade errada."); exit(1); } ttymode.sg_ispeed = speed; ttymode.sg_ospeed = speed; } #endif /* ucb4x */ stty(ttyfd,&ttymode); /* tty em in raw mode */ } /* tudo preparado, executa-se o comando dado. */ if (debug) { printf("Nivel de depuracao: %d\n\n",debug); if (cflg) printf("Comando CONNECT\n\n"); if (sflg) printf("Comando SEND\n\n"); if (rflg) printf("Comando RECEIVE\n\n"); } if (cflg) connect(); /* comando CONNECT */ if (sflg) /* comando SEND */ { if (argc--) filnam = *argv++; /* pega arq. p/TX */ else { if (remote) stty(0,cookedmode); /*restaura tty */ usage(); /* e da' o erro */ } fp = null; /* indica que ainda nao abriu arq. */ filelist = argv; /* prep. resto da lista de arq.*/ filecount = argc; /* num.arq.deixados de TX */ if (sendw() == false) /* manda o(s) arq(s) */ printmsg("SEND falhou."); else printmsg("Pronto."); } if (rflg) /* comando RECEIVE */ { if (recsw() == false)/* recebe o(s) arq.(s) */ printmsg("RECEIVE falhou."); else printmsg("Feito."); } if (remote) stty(0,&cookedmode); /* restaura modos tty */ } /* * s e n d s w * * E' o "switcher" da tabela de estados para mandar * arquivos. Fica em "loop" ate' acabar ou acontecer um erro. * As rotinas chamadas por ela sa^o responsa'veis pelas * mudanc,as na tabela. * */ sendsw() { char sinit(), sfile(), sdata(), seof(), sbreak(); state = 'S'; /* este e' o estado inicial */ n = 0; /* inicializa nu'mero da mensagem */ numtry = 0; /* nenhuma retransm., ainda */ while(true) /* faz isto enquanto for necessa'rio */ { if (debug) printf("Estado SENDSW: %c\n",state); switch(state) { case 'S': state = sinit(); break; /*send-init*/ case 'F': state = sfile(); break; /*send-file*/ case 'D': state = sdata(); break; /*send-data*/ case 'Z': state = seof(); break; /*send-eof*/ case 'B': state = sbreak(); break; /*send-break*/ case 'C': return (true); /* completo */ case 'A': return (false); /* "abort" */ default: return (false); /*desconhecido,falha*/ } } } /* * s i n i t * * SEND-INIT: manda os para^metros deste host e * pega os do outro lado. * */ char sinit() { int num, len; /* nu'mero e comprimento do pacote */ if (numtry++ > maxtry) return('A'); /* se muitas */ /* retransmisso~es, desiste */ spar(packet); /* preenche pacote infos iniciais*/ flushinput(); /* input pendente */ spack('S',n,6,packet); /* manda umpacote S */ switch(rpack(&len,&num,recpkt)) /* qual a resposta ? */ { case 'N': return(state); /* nak, tenta de novo */ case 'Y': /* ack */ if (n !=num) /* se ack errado, fica no estado S */ return(state); /* e tenta de novo */ rpar(recpkt); /* pega infos do outro lado */ if (eol == 0) eol = '\N'; /* checa e arma defaults */ if (quote == 0) quote = '#'; numtry = 0; /* zera contador de retransm. */ n = (n+1)%64; /* "pula" contador de pacotes */ return('F'); /* ok, muda estado para F */ case 'E': /* chegou pacote de erro */ prerrpkt(recpkt); /* imprime-o e */ return('A'); /* aborta */ case false: return(state); /* falha de RX, retenta */ default: return('A'); /* qq. outra coisa, aborta */ } /* * s f i l e * * manda cabec,alho de arquivo */ char sfile() { int num, len; /* nu'mero do pacote, comprimento */ char filnam1[50], /* nome de arquivo convertido */ *newfilnam, /* pointer para arq. a transmitir */ *cp; /* char pointer */ if (numtry++ > maxtry) return('A'); /* se muitas */ /* retransm., desiste */ if (fp == null) /* se ainda na~o aberto, */ { if (debug) printf("Abrindo %s para transmitir.\n",filnam); fp = fopen(filnam,"r"); /* abre o arquivo p/ ser TX */ if (fp == null) /* se pointer de arq.furado, desiste*/ { error("Nao da' p/ abrir %s", filnam); return('A'); } } strcpy(filnam1,filnam); /* copia nome do arquivo */ newfilnam = cp = filnam1; while (*cp != '\0') /* tira nomes do ini'cio do */ if (*cp++ == '/') /* direto'rio (ie. ate' u'ltimo) */ newfilnam = cp; if (filnamcnv) /* converte p/maiu'sculas */ for (cp = newfilnam; *cp != '\0'; cp++) if (*cp >= 'A' && *cp <= 'Z') *cp ^= 040; len = cp - newfilnam; /* computa compr.novo nome arq. */ printmsg("Transmitindo %s como %s", filnam, newfilnam); spack('F',n,len,newfilnam); /* manda um pacote F */ switch(rpack(&len,&num,recpkt)) /* qual a resposta? */ { case 'N': /* nak: fica neste estado */ num = (--num<0 ? 63:num); /* a menos que seja */ /* pelo pro'ximo pacote */ if (n != num) /* que e' como ack */ return(state); /* este pacote cai em... */ case 'Y': /* ack */ if (n != num) return(state); /* se ack errado, */ /* fica no estado F */ numtry = 0; /* zera contador de retransmisso~es */ n = (n+1)%64; /* "vira contador de pacote */ size = bufill(packet); /* pega prim.dado do arq.*/ return('D'); /* muda estado para D */ case 'E': /* Chegou pacote de erro */ prerrpkt(recpkt); /* imprime-o e */ return('A'); /* aborta */ case false: return(state); /* falha de RX: fica em F*/ default: return('A'); /* qq. outra coisa, aborta */ } } /* * s e o f * * manda end-of-file. */ char seof() { int num, len; /* nu'mero e compr. do pacote */ if (numtry++ > maxtry) return('A'); /* muitas = aborta */ spack('Z',n,0,packet); /* manda um pacote Z */ switch(rpack(&len,&num,recpkt)) /* qual foi a resposta ? */ { case 'N': /* nak: fica neste estado */ num = (--num<0 ? 63:num); /* a menos que seja um */ /* nak p/ pro'ximo pacote, */ if (n != num) /* que e' como um ack para este estado */ return(state); /* cai em...*/ case 'Y': /* ack */ if (n != num) return(state); /*se ack errado,segura*/ numtry = 0; /* zera contador de retransmisso~es */ n = (n+1)%64; /* e "vira" contador de pacote */ if (debug) printf("Fechando arquivo de entrada %s, ",filnam); fclose(fp); /* fecha o arquivo de entrada */ fp = null; /* arma flag = nenhum arquivo aberto */ if (debug) printf("Buscando proximo arquivo...\n"); if (gnxtfl() == false) /* nenhum outro arquivo a TX?*/ return('B'); /* se na~o, break, eot, pronto! */ if (debug) printf(" novo arquivo e' %s\n",filnam); return('F'); /* mais arquivos, estado vira F */ case 'E': /* chegou pacote de erro */ prerrpkt(recpkt); /* imprime-o e */ return('A'); /* aborta */ case false: return(state); /* falha de RX: fica em Z */ default: return('A'); /* qq. outra coisa, aborta */ } } /* * s b r e a k * * manda break (eot) * */ char sbreak() { int num, len; /* nu'mero e comprimento do pacote */ if (numtry++ > maxtry) return('A'); /* muitas=aborta */ spack('B',n,0,packet); /* manda pacote B */ switch (rpack(&len,&num,recpkt)) /* qual a resposta ? */ { case 'N': /* nak: fica neste estado */ num = (--num<0 ? 63:num); /* a menos que nak p/ */ /* pacote anterior, */ if (n != num) /* que e' como um ack */ return(state); /* p/este, dai' cai em*/ case 'Y': /* ack */ if (n != num) return(state); /* ack errado=falha*/ numtry = 0; /* zera contador de retransmisso~es */ n = (n+1)%64; /* e "vira" o nu'mero do pacote */ return('C'); /* estado vira completo */ case 'E': /* chegou pacote de erro */ prerrpkt(recpkt); /* imprime-o e */ return('A'); /* aborta */ case false: return(state); /* falha de RX: fica em B*/ default: return ('A'); /* qq.outra coisa: aborta */ } } /* * r e c s w * * Este e' o switcher da tabela de estados de RX de arq. * */ recsw() { char rinit(), rfile(), rdata(); /*usa estas procedures*/ state = 'R'; /* receive-init e' o estado inicial */ n = 0; /* inicializa nu'mero da mensagem */ numtry = 0; /* nenhuma retransmissa~o ainda */ while(true) { if (debug) printf(" Estado recsw: %c\n",state); switch(state) /* faz ate' acabar */ { case 'R': /* receive-init */ state = rinit(); break; case 'F': /* receive-file */ state = rfile(); break; case 'D': /* receive-data */ state = rdata(); break; case 'C': return(true); /* estado completo */ case 'A': return(false); /*estado de aborc,a~o */ } } } /* * r i n i t * * recebe inicializac,a~o * */ char rinit() { int len, num; /* comprimento e nu'mero do pacote */ if (numtry++ > maxtry) return('A'); /* muitas=aborta */ switch(rpack(&len,&num,packet)) /* pega um pacote */ { case 'S': /* send-init */ rpar(packet); /* pega o outro lado */ spar(packet); /* enche pacote c/minhas infos de */ /* inicializac,a~o */ spack('Y',n,6,packet); /* ack c/meus parms. */ oldtry = numtry; /* salva cont.retransmisso~es */ numtry = 0; /* inicializa novo contador */ n = (n+1)%64; /* "vira" num.pacote */ return('F'); /* entra em estado file-receive */ case 'E': /* chegou pacote de erro */ prerrpkt(recpkt); /* imprime-o e */ return('A'); /* aborta */ case false: /* na~o pegou pacote*/ spack('N',n,0,0); /* retorna nak */ return(state); /* fica tentando */ default: return('A'); /* qq.outro tipo aborta */ } } /* * r f i l e * * recebe cabec,alho de arquivo * */ char rfile() { int num, len; /* nu'mero e comprimento do pacote */ char filnam1[50]; /* guarda nome do arq. convertido */ if (numtry++ > maxtry) return('A'); /* muitas=aborta */ switch(rpack(&len,&num,packet)) /* pega um pacote */ { case 'S': /* send-init, talvez nosso ack se perdeu */ if (oldtry++ > maxtry) return('A'); /* muitas=abort */ if (num == ((n==0) ? 63:n-1)) /* pac.ant.mod 64?*/ { /* sim: ack de novo */ spar(packet); /* com nossos parms.*/ /* de send-init */ spack('Y',num,6,packet); numtry = 0; /* zera contador de retransm.*/ return(state); /* fica neste estado */ } else return('A'); /* sem pacote pre'vio: aborta*/ case 'Z': /* end-of-file */ if (oldtry++ > maxtry) return('A'); if (num == ((n==0) ? 63:n-1)) /*pac.ant.mod 64 ?*/ { /*sim: ack de novo*/ spack('Y',num,0,0); numtry = 0; return(state); /* fica este estado */ } else return('A'); /* sem pac.anterior: aborta */ case 'F': /* file header (o que queri'amos) */ if (num != n) return('A'); /* o num.pacote deve estar OK!*/ strcpy(filnam1,packet); /* copia o nome do arq. */ if (filnamcnv) /* converte p/minu'sculas */ for (filnam=filnam1; *filnam != '\0'; filnam++) if (*filnam >= 'A' && *filnam <= 'Z') *filnam \= 040; if ((fp=fopen(filnam1,"w"))==null) /*tenta abrir*/ /* novo arq. */ { error("nao da' p/criar %s",filnam1); /*se na~o*/ /* da', desiste */ return('A'); } else /* ok: da' mensagem */ printmsg("Recebendo %s como %s",packet,filnam1); spack('Y',n,0,0); /* ack p/ cab.arq. */ oldtry = numtry; /* Zera cont.retransm. */ numtry = 0; /* ... */ n = (n+1)%64; /* "vira" num.pacote mod 64 */ return('D'); /* entra em estado de dados */ case 'B': /* interrompe transmissa~o (eot) */ if (num != n) return('A'); /* preciso #pacote certo aqui */ spack('Y',n,0,0); /* diz OK */ return('C'); /* vai p/estado completo */ case 'E': /* chegou pacote de erro */ prerrpkt(recpkt); /* imprime-o e */ return('A'); /* aborta */ case false: /* na~o pegou pacote */ spack('N',n,0,0); /* devolve um nak */ return(state); /* fica tentando */ default: return('A'); /* qq.outro pacote: aborta */ } } /* * r d a t a * * recebe dados * */ char rdata() { int num, len; /* nu'mero e comprimento do pacote */ if (numtry++ > maxtry) return('A'); /* muitas = aborta */ switch(rpack(&len,&num,packet)) /* pega pacote */ { case 'D': /* pegou pacote de dados */ if (num != n) /* pacote certo? */ { /* na~o */ if (oldtry++ > maxtry) return('A'); /* muitas=aborta */ if (num == ((n==0) ? 63:n-1)) /* sena~o checa nu'mero do pacote */ { /* pacote anterior de novo? */ spack('Y',num,6,packet); /* sim: re-ack */ numtry = 0; /* zera cont.retransm. */ return(state); /* na~o grava dados */ } else return('A'); /*desculpe: nu'mero errado.*/ } /* pega dados c/nu'mero certo */ bufemp(packet,len); /* grava os dados no arquivo*/ spack('Y',n,0,0); /* ack p/pacote */ oldtry = numtry; /* zera cont.retransm. */ numtry = 0; /* ... */ n = (n+1)%64; /* "vira" num.pacote */ return('D'); /* permanece em estado de dados */ case 'F'; /* pega cabec,alho de arquivo */ if (oldtry++ > maxtry) return('A'); /* muitas=aborta */ if (num == ((n==0) ? 63:n-1)) /*senao checa #pac*/ { /* era o pacote anterior */ spack('Y',num,0,0); /* ack de novo */ numtry = 0; /* zera cont.retr. */ return(state); /* fica em est.dados*/ } else return('A'); /* na~o pac.pre'vio: aborta */ case 'Z': /* end-of-file */ if (num != n) return('A'); /* deve ter num.pac certo */ spack('Y',n,0,0); /* ok: ack */ fclose(fp); /* fecha o arq. */ n = (n+1)%64; /* "vira" #pacote */ return('F'); /* volta estado recebe arq. */ case 'E': /* chegou pacote de erro */ prerrpkt(recpkt); /* imprime-o e */ return('A'); /* aborta */ case false: /* na~o pegou pacote */ spack('N',n,0,0); /* retorna nak */ return(state); /* fica tentando*/ default: return('A'); /* qq.outro pacote = aborta */ } } /* * c o n n e c t * * Estabelece conexa~o de terminal virtual com o host * remoto via linha tty. * */ connect() { int pid, /* guarda identificac,a~o da crianc,a */ connected; /* flag de conexa~o */ char bel = '\07', c; struct sgttyb rawmode, /* controlando tty, modo raw */ cookedmode; /* controlando tty, modo cooked */ if (remote) /* nada a que conectar em remoto */ { printmsg("nenhuma linha especificada para conexa~o."); return; } gtty(0,&cookedmode); /* salva modo corrente */ gtty(0,&rawmode); rawmode.sg_flags \= (rawmode\tandem); rawmode.sg_flags &= ^(echo\crmod); stty(0,&rawmode); /* po~e tty em modo raw */ pid = fork(); /* comeca a "garfar" o que */ /* o host remoto "digitar" */ if (pid) /* pai: manda teclas p/ host remoto */ { printmsg("conectado...\r"); connected = true; /* entra em modo conectado */ while (connected) { read(0,&c,1); /* pega um caracter */ if ((c&0177) == escchr) /* ve se caracter de esc*/ { read(0,&c,1); if ((c&0177) == escchr) write(ttyfd,&c,1); else switch (c&0177) { case 'C': connected = false; write(0,"\r\n",2); break; case 'H': write(0,"\r\nyes,ainda estou aqui...\r\n",26); break; default: write(0,&bel,1); break; } } else { /* se na~o caracter de escape, */ write(ttyfd,&c,1); /* transmite-o */ c = null; /* nulifica-o (por que?) */ } } kill(pid,9); /* pronto: mata a crianc,a */ wait(0); /* e queima-a */ stty(0,&cookedmode); /* restaura modo tty */ printmsg("disconectado.") return; /* pronto */ } else /* a crianc,a le^ do host remoto */ { while(1) /* faz isto p/sempre */ { read(ttyfd,&c,1); write(1,&c,1); } } } /* * utilita'rios kermit. */ clkint() /* timer interrupt handler */ { longjmp(env,true); /* manda rpack desistir */ } /* * r p a c k * * manda um pacote * */ spack(type,num,len,data) char type, *data; int num, len; { int i; /* contador de loop de caracter */ char chksum, buffer[100]; /* checksum, buffer de pacote*/ register char *bufp; /* pointer do buffer */ if (debug>1) /* mostra pacote sainte */ { if (data != null) data[len] = '\0'; /*termina dados c/nulo p/impr.*/ printf(" tipo do spack: %c\n",type); printf(" numero: %d\n",num); printf(" comprimento: %d\n",len); if (data != null) printf(" dados: \"%s\"\n",data); } bufp = buffer; /* arma pointer do buffer */ for (i=1; i<=pad; i++) write(ttyfd,&padchar,1); /* manda qq. preenchi/o */ *bufp++ = soh; /* marcador de pacote (soh) = ASCII 1 */ *bufp++ = tochar(len+3); /* manda o contador de carac. */ chksum = tochar(len+3); /* inicializa o checksum */ *bufp++ = tochar(num); /* numero do pacote */ chksum += tochar(num); /* atualiza o checksum */ *bufp++ = type; /* tipo do pacote */ chksum += type; /* atualiza o checksum */ for (i=0; i> 6)+chksum)&077; /* calcula checksum final */ *bufp++ = tochar(chksum); /* po~e no pacote */ *bufp = eol; /* terminador de linha extra-packet */ write(ttyfd,buffer,bufp-buffer+1; /* manda o pacote */ } /* * r p a c k * * le^ um pacote */ rpack(len,num,data) int *len, *num; /* nu'mero e comprimento do pacote */ char *data; /* dados do pacote */ { int i, done; /* nu'mero carac. de dados, sai'da do loop */ char t, /* caracter de input corrente */ type, /* tipo do pacote */ cchksum, /* nosso (do computador) checksum */ rchksum; /* checksum recebido do host */ #if ucb4x /* o tops-20 na~o manuseia timeouts... */ if (setump(env)) return false; /* atingiu timeout: falhou */ signal(sigalrm,clkint); /* arma o timeout */ if ((timint > maxtim) \\ (timint < mintim)) timint = mytime; alarm(timint); #endif /* ucb4x */ while (t != soh) /* espera cabec.arquivo */ { read(ttyfd,&t,1); t &= 0177; /* manuseia paridade */ } done = false; /* recebeu soh, inicia loop */ while (!none) /* loop p/ conseguir um pacote */ { read(ttyfd,&t,1); /* pega caracter */ if (!image) t &= 0177; /* trata paridade */ if (t == soh) continue; /* resincroniza se soh */ cchksum = t; /* inicializa o checksum */ *len = unchar(t)-3; /* contador de caracteres */ read(ttyfd,&t,1); /* pega caracter */ if (!image) t &= 0177; /* trata paridade */ if (t == soh) continue; /* resincroniza se soh */ cchksum = cchksum + t; /* atualiza checksum */ *num = unchar(t); /* nu'mero do pacote */ read(ttyfd,&t,1); /* pega caracter */ if (!image) t &= 0177; /* trata paridade */ if (t == soh) continue; /* atualiza checksum */ type = t; /* tipo do pacote */ for (i=0; i<*len; i++) /* o pro'prio dado, se existir*/ { /* loop para contar caracteres */ read(ttyfd,&t,1); /* pega caracter */ if (!image) t &= 0177; /* manuseia paridade */ if (t == soh) continue; /* resincroniza se soh */ cchksum = cchksum + t; /* atualiza checksum */ data[i] = t; /* inclui checksum no buffer */ } data[*len] = 0; /* marca fim de dados */ read(ttyfd,&t,1); /* pega u'ltimo caracter (checksum)*/ rchksum = unchar(t); /* converte p/ numerico */ read(ttyfd,&t,1); /* pega caracter de eol e joga */ if (!image) t &= 0177; /* manuseia paridade */ if (t == soh) continue; /* resincroniza se soh */ done = true; /* pegou checksum, feito */ } #if ucb4x alarm(0); /* desabilita o timer interrupt */ #endif if (debug>1) /* mostra pacote chegante */ { if (data != null) data[*len] = '\0'; /* encerra dado c/nulo p/impr*/ printf(" tipo rpack: %c\n",type); printf(" numero: %d\n",*num); printf(" comprimento: %d\n",*len); if (data != null) printf(" dados: \"%s\"\n",data); } cchksum = (((cchksum&0300) >> 6)+cchksum)&077; /*checksum final*/ if (cchksum != rchksum) return(false); return(type); /* tudo bem; retorna tipo do pacote */ } /* * b u f i l l * * Pega buffer cheio de dados do arquivo sendo * transmitido. * So' e' feito controle de marcac,a~o; * na~o sa~o manuseadas as prefixac,o~es de * oitavo bit e * contador de repetic,o~es. */ bufill(buffer) char buffer[]; /* buffer */ { int i, /* indice do loop */ t; /* caracter lido do arquivo */ char t7; /* versa~o 7-bit d'acima */ i = 0; /* inicializa pointer do buffer de dados */ while((t = getc(fp)) != eof) /*pega pro'ximo caracter */ { t7 = t & 0177; /* pega 7 bits de mais baixa ordem */ if (t7 < sp \\ t7==del \\ t7==quote) /* este caracter precisa manuseio especial? */ if (t=='\n' && !image) { /* faz mapeamento lf->crlf se !image */ buffer[i++] = quote; buffer[i++] = ctl('\r'); } buffer[i++] = quote; /* marca o caracter */ if (t7 != quote) { t = ctl(t); /* e descontrolifica-o */ t7 = ctr(t7); } } if (image) buffer[i++] = t; /* deposita o pro'prio caracter */ else buffer[i++] = t7; if (i >= spsiz-8) return(i); /* checa comprimento */ } if (i==0) return (eof); /*sobrevoa por aqui so' se eof*/ return(i); /* trata buffer parcial */ } /* * b u f e m p * * po~e dado do pacote chegante num pacote * */ bufemp(buffer,len) char buffer[]; /* buffer */ int len; /* comprimento */ { int i; /* contador */ char t; /*guardador de carac*/ for (i=0; i maior-que 063 077 3F 6F ? ponto de interrogac,a~o 064 100 40 7C @ arro^ba .cp30 caracteres alfabe'ticos maiu'sculos (letras) ===ASCII=== =EBCDIC= DEC OCT HEX HEX CHAR OBS. 065 101 41 C1 A 066 102 42 C2 B 067 103 43 C3 C 068 104 44 C4 D 069 105 45 C5 E 070 106 46 C6 F 071 107 47 C7 G 072 110 48 C8 H 073 111 49 C9 I 074 112 4A D1 J 075 113 4B D2 K 076 114 4C D3 L 077 115 4D D4 M 078 116 4E D5 N 079 117 4F D6 O 080 120 50 D7 P 081 121 51 D8 Q 082 122 52 D9 R 083 123 53 E2 S 084 124 54 E3 T 085 125 55 E4 U 086 126 56 E5 V 087 127 57 E6 W 088 130 58 E7 X 089 131 59 E8 Y 090 132 5A E9 Z .cp10 mais caracteres de pontuac,a~o: ===ASCII=== =EBCDIC= DEC OCT HEX HEX CHAR OBS. 091 133 5B AD [ abre-colchete 092 134 5C E0 \ barra-inversa 093 135 5D BD ] fecha-colchete 094 136 5E 5F ^ circunflexo, seta-para-cima 095 137 5F 6D _ sublinhado 096 140 60 79 ` acento grave .cp30 caracteres alfabe'ticos minu'sculos: ===ASCII=== =EBCDIC= DEC OCT HEX HEX CHAR OBS. 097 141 61 81 a 098 142 62 82 b 099 143 63 83 c 100 144 64 84 d 101 145 65 85 e 102 146 66 86 f 103 147 67 87 g 104 150 68 88 h 105 151 69 89 i 106 152 6A 91 j 107 153 6B 92 k 108 154 6C 93 l 109 155 6D 94 m 110 156 6E 95 n 111 157 6F 96 o 112 160 70 97 p 113 161 71 98 q 114 162 72 99 r 115 163 73 A2 s 116 164 74 A3 t 117 165 75 A4 u 118 166 76 A5 v 119 167 77 A6 w 120 170 78 A7 x 121 171 79 A8 y 122 172 7A A9 z .cp8 mais caracteres de pontuac,a~o: ===ASCII=== =EBCDIC= DEC OCT HEX HEX CHAR OBS. 123 173 7B C0 { abre-chave 124 174 7C 4F | barra-vertical 125 175 7D D0 } fecha-chave 126 176 7E 7E ~ til .cp5 e, finalmente, mais um caracter na~o imprimi'vel: ===ASCII=== =EBCDIC= DEC OCT HEX HEX CHAR OBS. 127 177 7F 07 DEL delete, rubout. .pa