home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / rt11pascal.zip / rtkerm.pas < prev    next >
Pascal/Delphi Source File  |  1984-05-22  |  10KB  |  402 lines

  1. PROGRAM    Kermit(input,output);
  2.  
  3. LABEL
  4.   9999;          { used only to simulate a "halt" instruction }
  5.  
  6. CONST
  7.  
  8. { standard file descriptors. subscripts in open, etc. }
  9.     STDIN = 1;    { these are not to be changed }
  10.     STDOUT = 2;
  11.     STDERR = 3;
  12.     DL11LINE = 4;
  13.     BINARYFILE = 5;
  14.  
  15. { other io-related stuff }
  16.  
  17.     IOERROR = 0;    { status values for open files }
  18.     IOAVAIL = 1;
  19.     IOREAD = 2;
  20.     IOWRITE = 3;
  21.     IOLINE = 4;
  22.  
  23.     MAXOPEN = 7;    { maximum number of open files }
  24.         MAXCMD  = 10;   { maximun number of arguments }
  25.  
  26. { universal manifest constants }
  27.     ENDFILE = MaxInt;     { Cannot be -1 }
  28.     ENDSTR = 256;        { Cannot be 0    }
  29.     MAXSTR = 100;        { longest possible string }
  30.     CONLENGTH = 20;        { length of constant string }
  31.     BLKSIZE = 512;        { Block Size for files }
  32.  
  33.  
  34. { ascii character set in decimal }
  35. { used by KERMIT                 }
  36.  
  37.     NULLCHAR  = 0;
  38.     SOH = 1;               { SOH }
  39.     BACKSPACE = 8;
  40.     TAB = 9;
  41.     NEWLINE = 10;        { LF }
  42.     CR = 13;              { CR }
  43.     BLANK = 32;
  44.     SHARP = 35;        { # }
  45.     AMPER = 38;        { & }
  46.     PERIOD = 46;        { . }
  47.     COLON = 58;        { : }
  48.     LESS = 60;        { < }
  49.     GREATER = 62;        { > }
  50.     QUESTION = 63;        { ? }
  51.       DEL = 127;             { rubout }
  52.  
  53. { Constants for KERMIT }
  54.  
  55.    DEFTRY       = 5;       { default for number of retries }
  56.    DEFITRY      = 15;      { default for number of retries on init }
  57.    DEFTIMEOUT   = 12;      { default time out }
  58.    MAXPACK      = 94;      { max is 94 ~ - ' ' }
  59.    DEFDELAY     = 5;       { delay before sending first init }
  60.    NUMPARAM     = 7;       { number of parameters in init packet }
  61.    DEFQUOTE     = SHARP;   { default quote character  }
  62.    DEFPAD       = 0;       { default number OF padding chars  }
  63.    DEFPADCHAR   = 0;       { default padding character  }
  64.    DEF8CHAR    = AMPER;   { default 8 Bit Quote Character }
  65.  
  66. { packet types }
  67.  
  68.    TYPEB  = 66; { ord('B') }
  69.    TYPED  = 68; { ord('D') }
  70.    TYPEE  = 69; { ord('E') }
  71.    TYPEF  = 70; { ord('F') }
  72.    TYPEN  = 78; { ord('N') }
  73.    TYPES  = 83; { ord('S') }
  74.    TYPET  = 84; { ord('T') }
  75.    TYPEY  = 89; { ord('Y') }
  76.    TYPEZ  = 90; { ord('Z') }
  77.  
  78.  
  79. { Command parser constants }
  80.  
  81.    SMALLSIZE = 13;
  82.    LARGESIZE = 80;
  83.    MINPACKETSIZE = 10;
  84.    MAXPACKETSIZE = 94;
  85.  
  86.    oON = 21;
  87.    oOFF = 22;
  88.    oEVEN = 31;
  89.    oODD = 32;
  90.    oNONE = 33;
  91.  
  92.  
  93. TYPE
  94.  
  95.     character = -128..MaxInt;  { byte-sized. ascii + other stuff }
  96.     string = array [1..MAXSTR] of character;
  97.     string100 = PACKED ARRAY[1..MAXSTR] of char;
  98.     cstring = PACKED ARRAY [1..CONLENGTH] OF char;
  99.  
  100.     filedesc = IOERROR..MAXOPEN;
  101.     ioblock = record    { to keep track of open files }
  102.         filevar : text;
  103.         mode : -IOWRITE..IOLINE;
  104.     end;
  105.     block = array[1..BLKSIZE] of char;
  106.     binfile = file of block;
  107.  
  108. { Data Types for Kermit }
  109.  
  110.  
  111.    Packet = RECORD
  112.                mark : character;       { SOH character }
  113.                count: character;       { # of bytes following this field }
  114.                seq  : character;       { sequence number modulo 64  }
  115.                ptype: character;       { d,y,n,s,b,f,z,e,t  packet type }
  116.                data : string;          { the actual data }
  117. { chksum is last validchar in data array }
  118. { eol is added, not considered part of packet proper }
  119.             END;
  120.  
  121.    Command = (Transmit,Receive,SetParm,Connect,Invalid,Alldone);
  122.  
  123.    KermitStates = (FileData,Init,Break,FileHeader,EOFile,Complete,Abort);
  124.  
  125.    EOLtype = (LineFeed,CrLf,JustCr);
  126.  
  127.    Stats = real;
  128.  
  129.    Ppack = ^Packet;
  130.  
  131.    InType = (nothing,CRin,abortnow);
  132.  
  133.    TypeOfBinary = (NotSupported,FullBinary,Quoted);
  134.  
  135.    {  Parser defined types }
  136.  
  137.    string13 = packed array [1..SMALLSIZE] of char;
  138.    string80 = packed array [1..LARGESIZE] of char;
  139.  
  140. VAR
  141.  
  142.    { for system }
  143.  
  144.    openlist : ARRAY [1..MAXOPEN] OF ioblock; { open files }
  145.    redirect : ARRAY [STDIN..STDOUT] OF filedesc;
  146.    cmdargs  : 0..MAXCMD;
  147.    cmdlin   : string;
  148.    cmdidx   : ARRAY [1..MAXCMD] OF 1..MAXSTR;
  149.    bfile    : binfile;
  150.    binbuffer : block;
  151.    bptr    :  integer;
  152.  
  153.    { Varibles for Kermit }
  154.  
  155.    DiskFile : filedesc;  { File being read/written }
  156.    SaveState : kermitstates;
  157.    NextArg  : integer;   { next argument to process }
  158.    local    : boolean;   { local/remote flag }
  159.    MaxTry   : integer;
  160.    n        : integer;   { packet number }
  161.    NumTry   : integer;   { times this packet retried }
  162.    OldTry   : integer;
  163.    Pad      : integer;    { padding to send }
  164.    MyPad    : integer;    { number of padding characters I need }
  165.    PadChar  : character;
  166.    MyPadChar: character;
  167.    RunType  : command;
  168.    State    : kermitstates; { current state of the automaton }
  169.    MyTimeOut:  integer;     { when i want to be timed out }
  170.    TheirTimeOut  : integer;
  171.    Delay    : integer;
  172.    LineIN,LineOUT : filedesc; { Line to other KERMIT }
  173.    SizeRecv, SizeSend : integer;
  174.    SendEOL, SendQuote : character;
  175.    myEOL,myQuote: character;
  176.    QuoteForBinary : character;
  177.    BinaryMode : TypeOfBinary;
  178.    Def8QuoteMode : character;  { default 8 Bit Mode is Y or AMPER  
  179.                    this the one we send when starting transmit }
  180.    EOLforFile : EOLtype;
  181.    NumSendPacks : integer;
  182.    NumRecvPacks : integer;
  183.    NumACK : integer;
  184.    NumNAK : integer;
  185.    NumACKrecv : integer;
  186.    NumNAKrecv : integer;
  187.    NumBADrecv : integer;
  188.    RunTime: integer;
  189.    ChInFileSend, ChInPackSend, ChInFileRecv, ChInPackRecv : Stats;
  190.    Verbosity: boolean;     { true to print verbose messages }
  191.    OneWayOnly : boolean;   { used for testing }
  192.    Debug : boolean;
  193.  
  194.    ThisPacket : Ppack; { current packet being sent }
  195.    LastPacket : Ppack; { last packet sent }        
  196.    CurrentPacket : Ppack; { current packet received }
  197.    NextPacket : Ppack; { next packet being received }
  198.    InputPacket : Ppack; { save input to do debug }
  199.  
  200.    TimeLeft : integer; { until Time_Out }
  201.  
  202.    { these are used for the Receive Packet Procedures }
  203.  
  204.    FromConsole : InType;   { input from Console during receive }
  205.    check: integer;    { Checksum }
  206.    PacketPtr : integer; { pointer to InputPacket }
  207.    dataptr : integer;    { pointer to data of Packet }
  208.    fld : 0..5;        { current fld number }
  209.    t : character;    { input character }
  210.    finished : boolean;    { finished packet ? }
  211.    restart : boolean;    { restart packet ? }
  212.    control : boolean;    { quoted ? }
  213.    ishigh : integer;    { shift to put high bit on }
  214.    isgood : boolean;    { packet is good  ? }
  215.  
  216.    invalidConnection : boolean;
  217.  
  218.    {  Parser defined variables }
  219.  
  220.     commandLine, fileSpec : string80;
  221.     exitProgram,fileWarning : boolean;
  222.     localEcho, sFileSpec, rFileSpec, fileWarn, lSpeed : integer;
  223.     debugging, commandLen, fileEol, parity, eightBitQuoting : integer;
  224.     oldRunType : command;
  225.  
  226.  
  227.  
  228. {$E+}
  229.   PROCEDURE stiphalt; {    used by    external procedures for    halt }
  230.    BEGIN
  231.      GOTO 9999;
  232.    END;
  233. {$E-}
  234.  
  235.   { initio (RT-11) -- initialize open file list    }
  236.   PROCEDURE initio;
  237.   EXTERNAL;
  238.  
  239.   { open (RT-11) -- open a file    for reading or writing }
  240.   FUNCTION Sopen (VAR name : string; omode : integer) :    filedesc;
  241.   EXTERNAL;
  242.  
  243.   { close all files on exit }
  244.   PROCEDURE closeall;
  245.   EXTERNAL;
  246.  
  247.   FUNCTION Exists({ Using } VAR    s:string): { Returning } boolean;
  248.   EXTERNAL;
  249.  
  250.   { getarg (RT-11) -- copy n-th    command    line argument into s }
  251.   FUNCTION getarg (n : integer;    VAR s :    string;
  252.            maxs    : integer) : boolean;
  253.   EXTERNAL;
  254.  
  255.   PROCEDURE PutCS({ Using } x:cstring;
  256.           { Using } s :    string;
  257.           { Using } fd:filedesc);
  258.   EXTERNAL;
  259.  
  260.   PROCEDURE OpenPort;
  261.   EXTERNAL;
  262.  
  263.   PROCEDURE BadVTerminalConnect;
  264.   EXTERNAL;
  265.  
  266.   PROCEDURE MakeConnection;
  267.   EXTERNAL;
  268.  
  269.   PROCEDURE KermitInit;     { initialize various parameters  & defaults }
  270.   EXTERNAL;
  271.  
  272.   PROCEDURE FinishUp(ok    : boolean); { do any End of Program clean up }
  273.   EXTERNAL;
  274.  
  275.   PROCEDURE ErrorPack({    Using }    c:cstring);
  276.     { output Error packet if necessary -- then exit }
  277.   EXTERNAL;
  278.  
  279.   PROCEDURE PutErr({ Using } c:cstring);
  280.     { Print error_messages }
  281.   EXTERNAL;
  282.  
  283.   PROCEDURE Verbose({ Using } c:cstring);
  284.   EXTERNAL;
  285.  
  286.   PROCEDURE SendSwitch;
  287.   EXTERNAL;
  288.  
  289.   PROCEDURE RecvSwitch;    
  290.   EXTERNAL;
  291.  
  292.  
  293.  
  294.   PROCEDURE KermitMain;    { Main    KERMIT procedure }
  295.   VAR
  296.     aline : string;
  297.     j :    integer;
  298.     errorOccurred : boolean;
  299.     dummy : boolean;
  300.    BEGIN
  301.  
  302.      Verbose('KermitMain...       ');
  303.  
  304.      errorOccurred := false;
  305.      CASE Runtype OF
  306.        Receive:
  307.     BEGIN {    filename is optional here }
  308.       IF (rFileSpec    = oON)
  309.        THEN
  310.         BEGIN
  311.           dummy := getarg(1,aline,MAXSTR);
  312.           IF ((Exists(aline)) AND (local))
  313.            THEN
  314.            PutCS('Overwriting         ',aline,STDERR);
  315.           DiskFile := Sopen(aline, -IOWRITE);
  316.           IF (DiskFile <= IOERROR)
  317.            THEN
  318.         BEGIN
  319.           PutErr('Cannot Open File    ');
  320.           errorOccurred    := true;
  321.         END
  322.            ELSE
  323.            IF (local)
  324.         THEN
  325.         PutCS('Receiving File...   ',
  326.               aline, STDERR);
  327.           rFileSpec    := oOFF;
  328.         END;
  329.  
  330.       IF NOT(errorOccurred)
  331.        THEN
  332.        RecvSwitch;
  333.     END;
  334.        Transmit:       SendSwitch;
  335.  
  336.        Invalid,
  337.        SetParm,
  338.        Alldone:           { nothing };
  339.       END;
  340.      {    case }
  341.  
  342.      FinishUp(errorOccurred); {    end  of    program    }
  343.  
  344.    END { main KERMIT };
  345.  
  346.  
  347.   PROCEDURE PromptAndParseUser(VAR exitProgram : boolean;
  348.                    VAR RunType : command);
  349.   EXTERNAL;
  350.  
  351.  
  352.  
  353.  BEGIN    { of main }
  354.  
  355.    initio;
  356.  
  357.    KermitInit;         { initialize }
  358.  
  359.  
  360. 9999: {    Goto for an error_packet }
  361.  
  362.    RunType := Invalid;
  363.  
  364.    WHILE NOT(exitProgram) DO
  365.     BEGIN
  366.  
  367.       PromptAndParseUser(exitProgram, RunType);
  368.  
  369.       IF NOT(exitProgram)
  370.        THEN
  371.     BEGIN
  372.       CASE RunType OF
  373.         Receive,
  374.         Transmit :
  375.         IF (NOT local)
  376.          THEN
  377.          KermitMain
  378.          ELSE
  379.          IF    NOT(invalidConnection)
  380.           THEN
  381.           KermitMain
  382.           ELSE
  383.           BadVTerminalConnect;
  384.         Connect :
  385.          BEGIN
  386.            local :=    true;
  387.            OpenPort;
  388.            IF NOT(invalidConnection)
  389.         THEN
  390.         MakeConnection
  391.         ELSE
  392.         BadVTerminalConnect;
  393.          END;
  394.        END;
  395.     END;
  396.       RunType := Invalid;
  397.     END;
  398.  
  399.    Closeall;
  400.  
  401.  END.
  402.