home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / cdccyber / cdcker.for < prev    next >
Text File  |  2020-01-01  |  186KB  |  6,006 lines

  1. *comdeck comcker
  2. cc    comcker - kermit symbol definitions.
  3. c     this comdeck contains all symbol definitions needed by kermit.  it
  4. c     contains items found in several different areas in the texas
  5. c     version of kermit, and cleans up usage conflicts among the various
  6. c     parameter values.  this comdeck should be *called into every
  7. c     kermit module.
  8.       implicit integer (a - z)
  9.   
  10. cc    kermit site definitions.
  11. c     character set information.
  12. c     ipc641 = ip.c64.1 (from iptext).
  13. c     ipc642 = ip.c64.2 (from iptext).
  14. c     ipc63 = ip.c63 (from iptext). 
  15. c     ipcset = ip.cset = character set in use at your site. 
  16. c     n.b.  ipcset is ignored if ut2d = 1.
  17.       parameter (ipc641=0, ipc642=1, ipc63=2) 
  18. *if def,63cset,1
  19.       parameter (ipcset=ipc63)
  20. *if def,641cset,1 
  21.       parameter (ipcset=ipc641) 
  22. *if def,642cset,1 
  23.       parameter (ipcset=ipc642) 
  24.   
  25. cc    o.s. definitions.  set your o.s. to 1, all others to 0. 
  26. *if def,nos,1 
  27.       parameter (ut2d=0, nos=1, nosbe=0, scope=0) 
  28. *if def,nosbe,1 
  29.       parameter (ut2d=0, nos=0, nosbe=1, scope=0) 
  30. *if def,scope,1 
  31.       parameter (ut2d=0, nos=0, nosbe=0, scope=1) 
  32. *if def,ut2d,1
  33.       parameter (ut2d=1, nos=0, nosbe=0, scope=0) 
  34.   
  35. cc    site definitions.  used for sites with non-standard opsys.
  36. *if def,uariz,1 
  37.       parameter (utexas=0, uariz=1) 
  38. *if def,utexas,1
  39.       parameter (utexas=1, uariz=0) 
  40. *if def,other,1 
  41.       parameter (utexas=0, uariz=0) 
  42.   
  43. cc    nos definitions.  used for nos sites. 
  44. c     nosver = version number (14, 20, 21, etc).
  45. c     noslvl = psr level. 
  46.   
  47.       parameter (nosver = 22, noslvl=602) 
  48.   
  49. cc    file i/o definitions. 
  50.       parameter (stdin=1, stdout=2) 
  51.   
  52. cc    ascii character definitions.
  53.       parameter (soh=1, tab=9, lf=10, cr=13, blank=32, minus=45)
  54.       parameter (qmark=63, del=127, nel=o"0205", null=o"4000", eof=-1)
  55.   
  56. cc    miscellaneous.
  57.       parameter (ok=1, error=-2, on=1, off=0, yes=1, no=0)
  58.   
  59. cc    protocol definitions. 
  60.       parameter (unknown=0, fulldup=1, halfdup=2) 
  61.       parameter (none=0, even=1, odd=2, mark=3, space=4)
  62.       parameter (maxinit=20, maxtry=5)
  63.       parameter (maxpack=94, mytime=10, mypad=0, mypadch=0) 
  64.       parameter (myeol=13, myquote=35, quot8ch=78, mycktyp=49)
  65.       parameter (prefxch=126) 
  66.   
  67. cc    packet types. 
  68.       parameter (a=65, b=66, c=67, d=68, e=69, f=70, g=71, l=76, n=78)
  69.       parameter (r=82, s=83, y=89, z=90)
  70.   
  71. cc    packet error definitions
  72.       parameter (toomany=o"1000", invalid=o"2000", seqerr=o"4000")
  73.       parameter (lclfile=o"10000", notlcl=o"20000", invfn=o"40000") 
  74.       parameter (srvcmd=o"100000")
  75.       parameter (sending=o"100", reading=o"200")
  76.       parameter (initerr=1, filerr=2, dataerr=4, eoferr=o"10")
  77.       parameter (brkerr=o"20")
  78.   
  79.   
  80. cccc  kermit saved common block header
  81. c     all common blocks to be saved when executing monitor
  82. c     commands must be placed between /header/ and /trailer/
  83.       common /header/ header
  84.   
  85.   
  86. cccc  kermit command processor common block.
  87.       common /kermcmd/ autoret, dskcset, rdelay 
  88.   
  89.   
  90. cccc  kermit packet description common block. 
  91. c     do not allocate any storage between packsiz and sndsync!
  92.   
  93. c     allocate storage for what i want. 
  94.   
  95.       common /packet/ packsiz, timeout, npad, padch, eolch, quotech,
  96.      +                quote8, chktyp, rprefix, reserve(2), sync,
  97.   
  98. c     allocate storage for what partner wants.
  99.   
  100.      +                spksiz, stimout, spad, spadch, speol, spquote,
  101.      +                s8quote, schktyp, srepeat, unused(2), sndsync 
  102.   
  103.   
  104. cccc  kermit protocol common block. 
  105.       common /proto/ packet(maxpack), recpack(maxpack), 
  106.      +   filestr(maxpack),
  107.      +   psize, packnum, numtry, maxrtry, maxrini, state, ifd, ofd, ffd,
  108.      +   delayfp, savedpx,
  109.   
  110. c     storage for statistics. 
  111.   
  112.      +   abortyp, startim, endtim, schcnt, rchcnt, schovrh, rchovrh 
  113.   
  114.   
  115. cccc  debug common block. 
  116.       parameter (dbgoff=0, dbgstat=1, dbgpack=2, dbgall=3)
  117.       common /debug/ debug, debugfd, debugfn(8) 
  118.   
  119.   
  120. cccc  ascii string message common block defintions. 
  121.       integer errmsg(maxpack) 
  122.   
  123.       common /msg/ errmsg 
  124.   
  125.   
  126. cccc  kermit saved common block trailer 
  127.       common /trailer/ trailer
  128.   
  129.   
  130. cccc  file i/o common block definitions.
  131.       parameter (maxfile=5) 
  132.   
  133. c     cio related parameters. 
  134. c     ciord = cio read function code. 
  135. c     ciowt = cio write function code.
  136. c     ciobufl = cio buffer length (must be .gt. pru size of device).
  137. c     fetl = fet length in words. 
  138. c     maxwd = line size in words; must be an even number. 
  139. c     normal = flag to exitpgm that this is a normal exit.
  140.   
  141.       boolean ciord, ciowt
  142.       parameter (ciord = o"10", ciowt = o"14")
  143.       parameter (asciiio = 43, nosbit = 42, cioodd = o"2")
  144.       parameter (ciobufl=129, fetl=6, maxwd=32) 
  145.   
  146.       parameter (closed=0, rd=1, wr=2, create=3)
  147.       parameter (nopar=0, evepar=1, oddpar=2, mrkpar=3, spcpar=4) 
  148.       parameter (dskdpc=0, dsknos8=1, dskut8=2, dskimag=4)
  149.       parameter (dskasci = dsknos8 .or. dskut8) 
  150.   
  151.       character*10 fname(maxfile) 
  152.       common /fileioc/ fname
  153.   
  154.       boolean fchbuf(maxwd,maxfile) 
  155.       boolean fets(0:fetl - 1,maxfile), ciobuff(ciobufl,maxfile)
  156.       integer fmode(maxfile), fnwds(maxfile), fwptr(maxfile), 
  157.      +        fwshft(maxfile) 
  158.       logical feof(maxfile), ctdev(maxfile), rawmode, binmode 
  159.       logical normal
  160.       common /fileio/ fmode, fwptr, fnwds, feof, fwshft,
  161.      +   ctdev, rawmode, binmode, parity, duplex, normal
  162.       common /fetcom/ fets, ciobuff, fchbuf 
  163. c     common // ciobuff, fchbuf 
  164.   
  165.   
  166. cccc  message common block. 
  167.       character*37 version
  168.       character*15 ambig
  169.       character*38 nomatch
  170.       character*24 follow 
  171.       character*53 nodigit
  172.       character*31 missing
  173.       character*33 confmsg
  174.       character*19 notconf
  175.       character*42 hlpdlfp
  176.       character*37 hlpdbfn
  177.       character*24 hlpplen
  178.       character*34 hlppadl
  179.       character*74 hlpasch
  180.       character*29 hlpiprc
  181.       character*21 hlpprtr
  182.       character*43 hlptimo
  183.       character*19 hlpsnfn
  184.       character*41 hlprdel
  185.   
  186.       common /message/ version, ambig, nomatch, follow, nodigit,
  187.      +   missing, confmsg, notconf, 
  188.      +   hlpasch, hlpdlfp, hlpdbfn, hlpplen, hlppadl, hlpiprc, hlpprtr, 
  189.      +   hlptimo, hlpsnfn, hlprdel
  190.   
  191.   
  192. cccc  character conversion tables.
  193. c     dpctbl = ascii to display code table. 
  194. c     lascii = display code to lower case ascii.
  195. c     uascii = display code to upper case ascii.
  196.   
  197.       boolean dpctbl(0:127), lascii(0:63), uascii(0:63) 
  198.       common /charcom/ dpctbl, lascii, uascii 
  199. *comdeck kermcom  same as comcker, but turns off listing. 
  200. c$    list(s=0) 
  201. c     the following c$ lines are here instead of comcker because
  202. c     ftn5 flags them as errors in a block data module (grrrr). 
  203. c$    collate(fixed)
  204. c$    do(ot=0)
  205. *call comcker 
  206. c$    list(s=1) 
  207. *deck kermit
  208. *if def,ovcap 
  209.           ident  kermit 
  210.           lcc    overlay(0,0,ov=8)
  211.           ldset  lib
  212.           ldset  lib=kermlib/azlib/ftn5lib
  213.           ldset  omit=syserr.  saves 2000b+ words 
  214.           entry  kermit 
  215.           syscom b1 
  216.  kermit   title  kermit - micro computer file exchange/kermit protocol. 
  217.           comment micro computer file exchange/kermit protocol. 
  218.  kermit   space  4,10 
  219. *****     kermit - micro computer file exchange/kermit protocol.
  220. *         kermit is a file shipping program used by micro computers to
  221. *         transfer files to/from another computer.  it was originally 
  222. *         developed by columbia university for their decsystem-20, and
  223. *         adapted by the university of texas for their cyber and ut2d 
  224. *         operating system. 
  225.  kermit   space  4,10 
  226. ***       micro computer file interchange/kermit protocol.
  227. *         this version is for use under nos/be.  in case you are
  228. *         wondering, kermit stands for (k)l10 (e)rror-free (r)eciprocal 
  229. *         (m)icroprocessor (i)nterchange over (t)ty lines.  (x) 
  230. *         indicates a letter in the acronym.  a kl-10 (aka kl-20) is a
  231. *         digital equipment corporation 36 bit cpu. 
  232.  kermit   space  4,10 
  233. **        internal documentation. 
  234. *         due to the nasty habit intercom has of swapping out jobs that 
  235. *         go into terminal input wait, kermit's field length must be
  236. *         kept to a minimum.  since kermit does ascii i/o, it cannot
  237. *         use fortran read and write statements.  thus, an easy way to
  238. *         save memory is to kick out most ftn5lib modules.  this is 
  239. *         complicated by some needed modules calling 'syserr.', which 
  240. *         in turn drags in about 3000b words of other stuff.  for this
  241. *         reason, i have included an 'ldset omit=syserr.' in this 
  242. *         module.  thus, should some error condition arise that 
  243. *         would cause ichar, char, xovcap, or whoever to call 'syserr.',
  244. *         an error mode 1 at will happen in the routine making the
  245. *         call.  since this should not occur, i am willing to live
  246. *         with the user hostile diagnostic.  for debugging purposes,
  247. *         the ldset may be commented out so you get the ftn5 error
  248. *         diagnostic. 
  249. *         i also used ovcaps instead of segmenting kermit so the core 
  250. *         image can be installed in nucleus, with the ovcaps in sysovl. 
  251. *         cdc has not yet answered a psr we submitted regarding fdl.ocr 
  252. *         not looking in sysovl for caps for nucleus programs.  thus, 
  253. *         without our suggested code, ovcaps will need to be in nucleus 
  254. *         also. 
  255. *         each ovcap has a compass front-end so that the comment field
  256. *         of the binary has useful information in it.  this is useful 
  257. *         when you itemize a deadstart tape.  also, making the main 
  258. *         be in compass gets rid of a call to 'q5ntry=' which also
  259. *         saves some memory.
  260.  kermit   title  main program.
  261. **        main program. 
  262.   
  263.   
  264.  kermit   sb1    1
  265.           if     def,actr,1 
  266.           sa1    actr        get control card parameter count 
  267.           if     def,ra.act,1 
  268.           sa1    ra.act      get control card parameter count 
  269.           sx1    x1 
  270.           zr     x1,kermit1  if no parameters 
  271.           message (=c* kermit - too many parameters.*),,rcl 
  272.           abort  ,nd,s
  273.   
  274.  kermit1  rj     =xkermain   call the real workhorse
  275.           endrun
  276.   
  277.           end    kermit 
  278. *if def,nos 
  279.           ident  nostuff
  280.           title  nostuuf - nos version 2 *kermit* assist. 
  281. *comment  nostuuf - nos version 2 *kermit* assist.
  282.           entry  memstat
  283.           entry  nosinit
  284.           entry  nosexit
  285.           entry  nosetlf
  286.           entry  nosctab
  287.           entry  noswait
  288.           ldset  lib=srvlib/symlib
  289.           sst 
  290.           syscom b1 
  291.  nostuff  space  4,10 
  292. ***       nostuuf - nos version 2 *kermit* assist.
  293. *         bill russell.      84/07/01.
  294.  nostuff  space  4,10 
  295. ***              nostuff contains various subroutines that interface
  296. *         kermit to nos version 2.
  297.           title  nosinit - initialize *kermit* in a nos system. 
  298.  nosinit  space  4,10 
  299. ***       nosinit - initialize *kermit* in a nos system.
  300. *         entry  none.
  301. *         exit   the following will be true:
  302. *                            all nos/iaf prompts will be *off*
  303. *                            the terminal will be in *ascii* mode 
  304.   
  305.   
  306.  nosinit  subr
  307.           sb1    1
  308.           prompt off
  309.           cset   ascii
  310.           eq     nosinit
  311.           title  nosexit - terminate *kermit* in a nos system.
  312.  nosexit  space  4,10 
  313. ***       nosexit - terminate *kermit* in a nos system. 
  314. *         entry  none.
  315. *         exit   final status message will be issued. 
  316.   
  317.   
  318.  nosexit  subr
  319.           sb1    1
  320.           move   endcl,endc,endb
  321.           sx6    3
  322.           sa6    mema 
  323.           rj     memstat
  324.           endrun
  325.           title  memstat - issue *b display* kermit memory status.
  326.  memstat  space  4,10 
  327. ***       memstat - issue *b display* kermit memory status. 
  328. *         entry  none.
  329. *         exit   kermit status message will be displayed on the 
  330. *                *b display*. 
  331. *         calls  cmm.gss (in nos system library symlib).
  332. *                cmm.op4 (to shrink memory).
  333.   
  334.  memstat  subr
  335.           sb1    1
  336.           rj     =xcmm.op4   shrink at end of memory
  337.           rj     =xcmm.gss   fetch memory stats 
  338.           sa1    x1+b1
  339.           rj     =xcod= 
  340.           sa1    endb+2 
  341.           mx0    42 
  342.           lx6    18 
  343.           bx6    x0*x6
  344.           bx7    -x0*x1 
  345.           bx6    x6+x7
  346.           sa6    a1 
  347.   
  348.           sa4    mema 
  349.           message endb,x4,r 
  350.           eq     memstat
  351.   
  352.  mema     con    1             only line 1 of the display 
  353.  enda     con    0
  354.  endb     data   c* kermit running.     xxxxxxb  cm used.*
  355.  endc     data   c* kermit complete.    xxxxxxb  cm used.*
  356. *                  1234567890123456789012345678901234567890 
  357.  endcl    equ    *-endc 
  358.           title  nosetlf - set the list-of-files. 
  359.  nosetlf  space  4,10 
  360. ***       nosetlf - set the list-of-files.
  361. *         entry  arg1 = fet pointer.
  362. *                arg2 = fet ordinal.
  363. *         exit   (ra+arg2) = 42/ file name, 18/ fet address 
  364.   
  365.   
  366.  nosetlf  subr
  367.           sb1    1
  368.           mx0    42 
  369.           sa3    x1 
  370.           bx3    x0*x3       file name only 
  371.           sa4    a1+b1
  372.           sa4    x4          file ordinal 
  373.           sx6    x4-3        check if special name
  374.           pl     x6,slf1     if not a special name
  375.           sa3    slfa+x4     fetch special nos name 
  376.   
  377.  slf1     sx6    x1 
  378.           bx6    x6+x3       file name + pointer to fet 
  379.           sa6    x4+b1       set name in lof
  380.           eq     nosetlf
  381.   
  382.  slfa     bss    0           special list of files filenames
  383.   
  384.           vfd    60/0             for *nothing* 
  385.           vfd    42/0linput,18/0  for *stdin* 
  386.           vfd    42/0loutput,18/0 for *stdout*
  387.           title  nosctab - check type-ahead buffer in a nos system. 
  388.  nosctab  space  4,10 
  389. ***       nosctab - check type-ahead buffer in a nos system.
  390. *         entry  none.
  391. *         exit   (x6) = 0 = if no characters in the type-ahead buffer.
  392.   
  393.   
  394.  nosctab  subr
  395.           sb1    1
  396.           system tlx,r,ctab,1600b *check* type-ahead buffer 
  397.           sa1    ctab 
  398.           bx6    x1 
  399.           eq     nosctab     return 
  400.  ctab     bssz   1           type-ahead present flag
  401.           title  noswait - wait at a control point for 24 milli-seconds.
  402.  noswait  space  4,10 
  403. ***       noswait - wait at a control point for 24 milli-seconds. 
  404. *         entry  none.
  405.   
  406.   
  407.  noswait  subr
  408.           sb1    1
  409.           wait   24          ** current nos 2.2 system default ** 
  410.           eq     noswait
  411.           end 
  412. *endif
  413. *if def,ovcap 
  414.       subroutine kermain
  415. *endif
  416. *if -def,ovcap
  417.       program kermit
  418. *endif
  419.   
  420. ccc   kermit - a cyber file transfer program using the kermit protocol
  421. c     this program may not be sold for profit.
  422. c     modifications:
  423. c     2.2   8/22/84  ric anderson, university of arizona at tuscon
  424. c        add update ifdefs for character set, operating system, and site
  425. c        selection.  fix execmd to work under nos/be.  fix cfe for use
  426. c        under nos/be.  correct spelling errors.
  427. c     2.1   8/16/84  bill russell, new york university
  428. c        added nos 2.2 support (up through level 602).  add 
  429. c        timeout during reads (nos 2.2 level 602 or above only).
  430. c        problems with the nos version should be directed to: 
  431. c           bill russell
  432. c           new york university 
  433. c           courant institute of mathematical sciences
  434. c           251 mercer street 
  435. c           ny, ny  10012 
  436. c           arpa:  russell@nyu.arpa 
  437. c           uucp:  ...!allegra!cmcl2!russell
  438. c     2.0   4/17/84  jim knutson, university of texas at austin 
  439. c        fix filename packet to send uppercase file names only. 
  440. c        cleanup error packet handling (added to state table handlers). 
  441. c        fix retry counts to use proper number. modify character tables.
  442. c        merge ric anderson's nos/be code.  try to organize the 
  443. c        source a little better.  added push and ! commands.
  444. c        add read delay for performance tuning.  changed nel back to
  445. c        205b.  the binary data-mode ignores nel though.
  446. c        ut2d requires the nel be a 205b.  changed character tables 
  447. c        to use octal constants for non-representable characters. 
  448. c     1.1   01/21/84  ric anderson, university of arizona at tuscon 
  449. c        add ovcaps for installation in nucleus.  add display code
  450. c        support.  remove gobs and gobs of field length.  changed 
  451. c        nel to 4012b to avoid confusion with data byte.  updated 
  452. c        character tables for 63 and 64 character sets.  changed
  453. c        percents in fprintfs to at-signs since 63 character set has
  454. c        no percent sign. 
  455. c     1.0   10/14/83  jim knutson, university of texas at austin
  456. c        original implementation. 
  457. c     jim knutson 
  458. c     computation center room 1 
  459. c     univerisity of texas
  460. c     austin, tx   78712
  461. c     aprpanet address:  knutson@ut-ngp 
  462. c     special thanks to king ables for his contribution.
  463. c     modified for nos/be by ric anderson 
  464. c     university of arizona 
  465. c     computer center 
  466. c     tucson, arizona 85721 
  467. c     future enhancements:
  468. c        8th bit quoting
  469. c        repeat counts
  470. c        wild card sends
  471. c        conditional code generation for i/o checks 
  472. c     build sequence: 
  473. c        build an update oplpl from the source file.
  474. c        create the compile file, changing the site parameter in the
  475. c           common deck comcker.  also use *defines for ovcaps vs.
  476. c           segload version and site dependent compass.  see
  477. c           implementation notes. 
  478. c        for the ovcap version: 
  479. c           ftn5,i,opt=2. 
  480. c           ftn5,i,opt=2,b=librel.
  481. c           libgen,p=kermlib,f=librel.
  482. c           load,lgo. 
  483. c           nogo,kermit.
  484. c        for the segload version: 
  485. c           ftn5,i,opt=2. 
  486. c           segload,i=segdef,b=kermit.
  487. c           load,lgo. 
  488. c           nogo. 
  489. c        load it with the following segload directives: 
  490. c          tree     kermit-(set,hlpcmd,execmd,server-(receive,send))
  491. c set      include  show,status,match,setval
  492. c receive  include  rinit,rfile,rdata 
  493. c send     include  sinit,sfile,sdata,seof,sbreak 
  494. c kermit   global   proto,packet,debug,message,fileio,fileioc 
  495. c          end      kermit
  496. c     implementation notes: 
  497. c        there are now two versions available for kermit.  one uses 
  498. c        segload the other uses ovcaps.  only the ovcap version may 
  499. c        be installed on the system nucleus (cld for you ut2d fans).
  500. c        the default version you get from update is for segload.
  501. c        the ovcap version may be obtained by using the update
  502. c        directive *define,ovcap. 
  503.   
  504. c        the following defines have also been setup to select character 
  505. c        set, operating system, and site.  nos sites still need to
  506. c        modify the nosver and noslvl parameter in deck comcker.
  507. c           *define cset (63cset, 641cset, 642cset) 
  508. c           *define opsys (ut2d, nos, nosbe, scope) 
  509. c           *define site (utexas, uariz, other) 
  510. c        this version of kermit should be portable to other cdc sites 
  511. c        except for the above mentioned conditional updates and the 
  512. c        following cases. 
  513. c        the delay subroutine uses subroutine rtime to return the system
  514. c        real time clock (number of jifs since deadstart).  nos and 
  515. c        nos/be rtime macros allegedly return slightly different
  516. c        formats of data, so nos sites may need to modify delay().
  517. c        the server knows how to logout on ut2d and nos/be sites. 
  518. c        ut2d uses a local funtion called bellc to perform this.  nos/be
  519. c        and nos sites use a function to essentially pcc a logout 
  520. c        control command.  for nos sites, only those running level
  521. c        596 or above may logout.  see subroutine logout(). 
  522. c        the ascii i/o is also probably not portable since
  523. c        cdc does not really support ascii i/o yet. 
  524. c        ascii i/o on ut2d (univ. of texas op. sys.) is done by 
  525. c        setting bit 2**43 in fet+1.  the ascii character set that
  526. c        is used is "8 in 12".  this is 8 bits of an ascii character
  527. c        stored in a 12 bit byte.  nulls are represented as 4000b,
  528. c        and the newline character (nel) is 205b.  this is slightly 
  529. c        different from the cdc end-of-line which is 0000b in the 
  530. c        low order byte of the word.  currently, 0000b bytes are ignored
  531. c        since nulls are guarded. 
  532. c        the display code character mappings for ut2d are different 
  533. c        than the 64 and 63 character set (sigh).  these should 
  534. c        already be taken care of in the conditional compilation. 
  535. c        sites that modify kermit to run on their system should 
  536. c        modify the appropriate parameter definition to allow 
  537. c        conditional compilation for their site.  try to be 
  538. c        as general as you can when making mods.
  539. c        ****** above all send your mods back to ut ******* 
  540. c     kermit i/o considerations:
  541. c        kermit uses two modes of i/o.  it does coded i/o when reading
  542. c        from the terminal to get commands.  this causes the front
  543. c        end to map the cr/lf pair into a single nel character. 
  544. c        normal cyber sites will have the nel character added for 
  545. c        them by the subroutine findeol.
  546. c        command editing (backspace and cancel)  and parity is taken
  547. c        careof by the front-end.  binary i/o is used when reading
  548. c        and sending packets.  this allows kermit to control the
  549. c        parity bit.  other nos sites may have to set transparent mode
  550. c        to do this.  binary i/o also causes no command editing to be 
  551. c        done (backspaces are treated as regular ascii characters) and
  552. c        cr/lf is not mapped to nel. rawmode is a mode internal 
  553. c        to kermit that causes no cr/lf <-> nel mapping.
  554. c        kermit opens two files (stdin and stdout) and connects 
  555. c        them to the terminal for doing the ascii i/o.  this was
  556. c        done to prevent problems with trying to buffer reads and 
  557. c        writes to the same file.  when reading/writing disk files, 
  558. c        kermit will try to buffer 2 disk sectors (128 words) worth 
  559. c        of data per read/write.  this was changed from the 8 disk
  560. c        sectors (512 words) since this reduced wasted space for
  561. c        the terminal files and helped reduce field length. 
  562. c        all i/o is done through interface routines to the compass
  563. c        i/o macros.
  564. c        the only implementation dependent i/o routines should be 
  565. c        the compass i/o interface routines, stty() and perhaps 
  566. c        the rtime() subroutine.
  567. c        see these routines for more info on what they do.
  568. c     subroutine ordering:
  569. c        main program and initialization
  570. c           kermit
  571. c           blkdat. 
  572. c           exitpgm 
  573. c           abtp
  574. c        kermit command subroutines 
  575. c           execmd
  576. c           hlpcmd
  577. c           rcvfile 
  578. c           sndfile 
  579. c           set 
  580. c           show
  581. c           status
  582. c           server
  583. c        kermlib routines:
  584. c           dmodcmd 
  585. c           dbugcmd 
  586. c           setpack 
  587. c           dplxcmd 
  588. c           parcmd
  589. c        command parsing subroutines
  590. c           match 
  591. c           outtbl
  592. c           setval
  593. c           confirm 
  594. c        server subroutines 
  595. c           logout
  596. c        kermit receive state protocol subroutines
  597. c           receive 
  598. c           rinit 
  599. c           rfile 
  600. c           rdata 
  601. c        kermit send state protocol subroutines 
  602. c           send
  603. c           sinit 
  604. c           sfile 
  605. c           sdata 
  606. c           seof
  607. c           sbreak
  608. c        packet i/o subroutines 
  609. c           sndpack 
  610. c           rdpack
  611. c           buffill 
  612. c           bufemp
  613. c        standard i/o subroutines 
  614. c           fopen 
  615. c           fclose
  616. c           fflush
  617. c           getc
  618. c           ungetc
  619. c           getword 
  620. c           putc
  621. c           fread 
  622. c           fwrite
  623. c           putstr
  624. c           putint
  625. c           putday
  626. c           putmnth 
  627. c           fprintf 
  628. c           sprintf 
  629. c           doprnt
  630. c           stty
  631. c           gtty
  632. c        utility subroutines
  633. c           as2dpc
  634. c           asc 
  635. c           dpc2as
  636. c           ctoi
  637. c           itos
  638. c           getemsg 
  639. c           creat 
  640. c           getnow
  641. c           filchk
  642. c           rdparam 
  643. c           remove
  644. c           strcpy
  645. c           slen
  646. c           sndpar
  647. c           sleep 
  648. c           delay 
  649. c        nos/be utility modules.
  650. c           echoplx 
  651. c           getrec
  652. c           findeol 
  653. c           edl 
  654. c           cfe 
  655. c           getrec
  656. c        nos utility routines 
  657. c           conbuff 
  658. *call kermcom 
  659.       logical cfe 
  660.       external exitpgm
  661.       parameter (tsize=11)
  662.       character*10 cmd(tsize) 
  663.       data cmd / 'exit', 'help', 'push', 'quit', 'receive', 'send', 
  664.      +    'server', 'set', 'show', 'status', '!' /
  665.   
  666. c     insure we are an interactive job. 
  667. c$    if (nosbe .eq. 1) then
  668.       call xgjo(ipriv,iorig)
  669.       if(iorig .ne. 3) then 
  670.           call remark(' kermit - incorrect job origin.')
  671.           call abtp("nd,s") 
  672.       endif 
  673. c$    endif 
  674. c$    if (ut2d .eq. 1)
  675.       call jobinfo(11,iorig)
  676.       if ((iorig.and.4) .ne. 4) then
  677.          call remark(' kermit - incorrect job origin.') 
  678.          call abtp("nd,s")
  679.       endif 
  680. c$    endif 
  681. c     if running from a system library, set infinite cpu
  682. c     time limit for this job step. 
  683. c$    if (nosbe .eq. 1) then
  684.       if(ipriv .eq. -1) call entl(o"77777") 
  685. c$    endif 
  686. c     if running under nos - initialize kermit. 
  687. c$    if (nos .eq. 1) 
  688.       call nosinit
  689. c$    endif 
  690. c     open the i/o files
  691.       if (fopen('stdin',rd) .ne. stdin) then
  692.          call displa(' cannot open standard input') 
  693.          call abtp("nd")
  694.       else if (fopen('stdout',wr) .ne. stdout) then 
  695.          call displa(' cannot open standard output')
  696.          call abtp("nd")
  697.       endif 
  698. c     read in environment if needed 
  699.       if (cfe('zzzzken')) then
  700.          cfd = fopen('zzzzken',rd)
  701.          if (cfd .eq. error) then 
  702.             call displa(' cannot open temp file') 
  703.          else 
  704.             call fread(cfd,header,locf(trailer)-locf(header)) 
  705.             call fclose(cfd)
  706.          endif
  707.          call retfile('zzzzken')
  708.       endif 
  709. c     make sure things get fixed during aborts
  710. c$    if (nos .eq. 1) 
  711.       call recovr(exitpgm,o"277",0) 
  712. c$    else
  713.       call recovr(exitpgm,o"77",0)
  714. c$    endif 
  715. c     parse and execute any commands
  716. 5     call fprintf(stdout,'^kermit-170>',0,0,0,0) 
  717.       call fflush(stdout) 
  718. c$    if (nos .eq. 1) 
  719. c     if running under nos - issue memory status message. 
  720.       call writer(fets(0,stdout)) 
  721.       call memstat
  722. c$    endif 
  723.       call fflush(stdin)
  724.       indx = match(cmd,tsize,.true.)
  725.       if (indx .eq. error .or. indx .eq. 0) go to 5 
  726.       if (indx .eq. eof) then 
  727.           normal = .true. 
  728.           call exitpgm
  729.       endif 
  730.       go to (10, 20, 30, 10, 40, 50, 60, 70, 80, 90, 100), indx 
  731. c     thats all folks 
  732. 10    normal = .true. 
  733.       call exitpgm
  734. c     give some help
  735. *if def,ovcap 
  736. 20    call xovcap('kermhlp')
  737.       call uovcap('kermhlp')
  738. *endif
  739. *if -def,ovcap
  740. 20    call hlpcmd 
  741. *endif
  742.       go to 5 
  743. c     same as exit and quit but allows you to reenter with
  744. c     the same environment as before
  745. 30    autoret = no
  746. *if def,ovcap 
  747.       call xovcap('kermxcc')
  748.       call uovcap('kermxcc')
  749. *endif
  750. *if -def,ovcap
  751.       call execmd 
  752. *endif
  753.       go to 5 
  754. c     receive a file
  755. *if def,ovcap 
  756. 40    call xovcap('kermrcv')
  757.       call uovcap('kermrcv')
  758. *endif
  759. *if -def,ovcap
  760. 40    call rcvfile
  761. *endif
  762.       go to 5 
  763. c     send a file 
  764. *if def,ovcap 
  765. 50    call xovcap('kermsnd')
  766.       call uovcap('kermsnd')
  767. *endif
  768. *if -def,ovcap
  769. 50    call sndfile
  770. *endif
  771.       go to 5 
  772. c     enter server mode 
  773. *if def,ovcap 
  774. 60    call xovcap('kermsrv')
  775.       call uovcap('kermsrv')
  776. *endif
  777. *if -def,ovcap
  778. 60    call server 
  779. *endif
  780.       go to 5 
  781. c     set some attributes 
  782. *if def,ovcap 
  783. 70    call xovcap('kermset')
  784.       call uovcap('kermset')
  785. *endif
  786. *if -def,ovcap
  787. 70    call set
  788. *endif
  789.       go to 5 
  790. c     show current settings 
  791. *if def,ovcap 
  792. 80    call xovcap('kermsho')
  793.       call uovcap('kermsho')
  794. *endif
  795. *if -def,ovcap
  796. 80    call show 
  797. *endif
  798.       go to 5 
  799. c     give the status of last transfer
  800. *if def,ovcap 
  801. 90    call xovcap('kermsta')
  802.       call uovcap('kermsta')
  803. *endif
  804. *if -def,ovcap
  805. 90    call status 
  806. *endif
  807.       go to 5 
  808. c     exec a control command
  809. 100   autoret = yes 
  810. *if def,ovcap 
  811.       call xovcap('kermxcc')
  812.       call uovcap('kermxcc')
  813. *endif
  814. *if -def,ovcap
  815.       call execmd 
  816. *endif
  817.       go to 5 
  818.       end 
  819.       block data
  820. *call comcker 
  821.   
  822.   
  823.       data fmode / maxfile*closed / 
  824.       data fwptr,fnwds / maxfile*0, maxfile*0 / 
  825.       data rawmode, binmode / 2*.false. / 
  826.       data parity, duplex / nopar, fulldup /
  827.       data dskcset / dskdpc / 
  828.       data normal / .false. / 
  829.       data ifd, ofd         / stdin, stdout / 
  830.       data ffd              / 0 / 
  831.       data maxrtry, maxrini / maxtry, maxinit / 
  832.       data packnum          / 0 / 
  833.       data startim, endtim  / 2*0 / 
  834.       data schcnt , rchcnt  / 2*0 / 
  835.       data schovrh, rchovrh / 2*0 / 
  836.       data state            / c / 
  837.       data delayfp          / 5 / 
  838.       data rdelay           / 100 / 
  839.       data sync   , sndsync / 2*soh / 
  840.       data packsiz, spksiz  / 2*maxpack / 
  841.       data timeout, stimout / 2*mytime  / 
  842.       data npad   , spad    / 2*mypad   / 
  843.       data padch  , spadch  / 2*mypadch / 
  844.       data eolch  , speol   / 2*myeol   / 
  845.       data quotech, spquote / 2*myquote / 
  846.       data quote8 , s8quote / 2*quot8ch / 
  847.       data chktyp , schktyp / 2*mycktyp / 
  848.       data rprefix, srepeat / 2*prefxch / 
  849.       data debug  , debugfd / dbgoff, 0 / 
  850.       data debugfn          / 75, 69, 82, 77, 76, 79, 71, 0 / 
  851. c                              k   e   r   m   l   o   g
  852.       data (errmsg(i),i=1,14) / 63, 75, 101, 114, 109, 105, 116, 45, 49,
  853. c                             ?   k    e    r    m    i    t   -   1
  854.      +                       55, 48, 58, 2*32 / 
  855. c                             7   0   : 
  856.       data version / '^cyber-170 ^k^e^r^m^i^t version 2.2\n' /
  857.       data ambig   / '?^ambiguous - "' /
  858.       data nomatch / '?^does not match switch or keyword - "' / 
  859.       data follow  / '^one of the following:\n' / 
  860.       data nodigit /
  861.      +   '?^invalid, ^first nonspace character is not a digit\n' /
  862.       data missing / '?^invalid, ^missing parameter\n' /
  863.       data confmsg / '^confirm with a carriage return\n' /
  864.       data notconf / '?^not confirmed - "' /
  865.       data hlpasch / '^decimal, octal (^b), or hexidecimal (^h) code for
  866.      + ^a^s^c^i^i character \n' / 
  867.       data hlpdlfp / '^number of seconds to delay first packet\n' / 
  868.       data hlpdbfn / '^debug output logfile specification\n' /
  869.       data hlpplen / '^maximum packet length\n' / 
  870.       data hlppadl / '^number of pad characters to use\n' / 
  871.       data hlpiprc / '^initial packet retry count\n' /
  872.       data hlpprtr / '^packet retry count\n' /
  873.       data hlptimo / '^number of seconds to wait before timeout\n' /
  874.       data hlpsnfn / '^filename to send\n' /
  875.       data hlprdel / '^milliseconds to delay each ^t^t^y read\n' /
  876.   
  877. c$    if (ut2d .eq. 1)
  878.       data dpctbl/r" ",31*r" ",r" ",r"!",r"""",o"65",r"$",o"71",r"&", 
  879.      +            o"64",r"(",r")",r"*",r"+",r",",r"-",r".",r"/",r"0", 
  880.      +            r"1",r"2",r"3",r"4",r"5",r"6",r"7",r"8",r"9", 
  881.      +            o"63",r";",r"<",r"=",r">",o"75",r"@", 
  882.      +            r"a",r"b",r"c",r"d",r"e",r"f",r"g",r"h",r"i", 
  883.      +            r"j",r"k",r"l",r"m",r"n",r"o",r"p",r"q",r"r", 
  884.      +            r"s",r"t",r"u",r"v",r"w",r"x",r"y",r"z",
  885.      +            r"[",o"76",r"]",o"70",r" ",r" ",
  886.      +            r"a",r"b",r"c",r"d",r"e",r"f",r"g",r"h",r"i", 
  887.      +            r"j",r"k",r"l",r"m",r"n",r"o",r"p",r"q",r"r", 
  888.      +            r"s",r"t",r"u",r"v",r"w",r"x",r"y",r"z",
  889.      +            5*r" "/ 
  890.       data lascii/0,97,98,99,100,101,102,103,104,105,106,107,108,109, 
  891. c                    a  b  c   d   e   f   g   h   i   j   k   l   m
  892.      +            110,111,112,113,114,115,116,117,118,119,120,121,122,
  893. c                   n   o   p   q   r   s   t   u   v   w   x   y   z 
  894.      +            48,49,50,51,52,53,54,55,56,57,
  895. c                  0  1  2  3  4  5  6  7  8  9 
  896.      +            43,45,42,47,40,41,36,61,32,44,46,34,91,93,58, 
  897. c                  +  -  *  /  (  )  $  =     ,  .  "  [  ]  :
  898.      +            39,35,33,38,94,37,60,62,64,63,92,59/
  899. c                  '  #  !  &  ^  <pct>  <  >  @  ?  \  ; 
  900.       data uascii/0,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81, 
  901. c                    a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q
  902.      +            82,83,84,85,86,87,88,89,90,48,49,50,51,52,53,54,55, 
  903. c                 r  s  t  u  v  w  x  y  z  0  1  2  3  4  5  6  7 
  904.      +            56,57,43,45,42,47,40,41,36,61,32,44,46,34,91,93,58, 
  905. c                 8  9  +  -  *  /  (  )  $  =     ,  .  "  [  ]  : 
  906.      +            39,35,33,38,94,37,60,62,64,63,92,59/
  907. c                   '  #  !  &  ^  <pct>  <  >  @  ?  \  ;
  908. c$    else
  909. c$      if(ipcset .eq. ipc63) 
  910.         data dpctbl/r" ",31*r" ",r" ",r"!",r"""",o"60",r"$",r" ",r"&",
  911.      +              o"70",r"(",r")",r"*",r"+",r",",r"-",r".",r"/",r"0", 
  912.      +              r"1",r"2",r"3",r"4",r"5",r"6",r"7",r"8",r"9", 
  913.      +              o"63",r";",r"<",r"=",r">",o"71",r"@", 
  914.      +              r"a",r"b",r"c",r"d",r"e",r"f",r"g",r"h",r"i", 
  915.      +              r"j",r"k",r"l",r"m",r"n",r"o",r"p",r"q",r"r", 
  916.      +              r"s",r"t",r"u",r"v",r"w",r"x",r"y",r"z",
  917.      +              r"[",o"75",r"]",o"76",o"65",r"@", 
  918.      +              r"a",r"b",r"c",r"d",r"e",r"f",r"g",r"h",r"i", 
  919.      +              r"j",r"k",r"l",r"m",r"n",r"o",r"p",r"q",r"r", 
  920.      +              r"s",r"t",r"u",r"v",r"w",r"x",r"y",r"z",
  921.      +              r"[",r"\",r"]",r"^",r" "/ 
  922.         data lascii/32,97,98,99,100,101,102,103,104,105,106,107,108,109,
  923. c                       a  b  c   d   e   f   g   h   i   j   k   l   m 
  924.      +              110,111,112,113,114,115,116,117,118,119,120,121,122,
  925. c                     n   o   p   q   r   s   t   u   v   w   x   y   z 
  926.      +              48,49,50,51,52,53,54,55,56,57,
  927. c                    0  1  2  3  4  5  6  7  8  9 
  928.      +              43,45,42,47,40,41,36,61,32,44,46,35,91,93,58, 
  929. c                    +  -  *  /  (  )  $  =     ,  .  %  [  ]  :
  930.      +              34,95,33,38,39,63,60,62,64,92,94,59/
  931. c                    "  #  !  &  '  ?  <  >  @  \  ^  ; 
  932.         data uascii/32,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80, 
  933. c                       a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p
  934.      +              81,82,83,84,85,86,87,88,89,90,48,49,50,51,52,53,54, 
  935. c                    q  r  s  t  u  v  w  x  y  z  0  1  2  3  4  5  6
  936.      +              55,56,57,43,45,42,47,40,41,36,61,32,44,46,35,91,93, 
  937. c                    7  8  9  +  -  *  /  (  )  $  =     ,  .  %  [  ]
  938.      +              58,34,95,33,38,39,63,60,62,64,92,94,59/ 
  939. c                    :  "  #  !  &  '  ?  <  >  @  \  ^  ;
  940. c$      else
  941.         data dpctbl/r" ",31*r" ",r" ",r"!",r"""",o"60",r"$",o"63",r"&", 
  942.      +              o"70",r"(",r")",r"*",r"+",r",",r"-",r".",r"/",r"0", 
  943.      +              r"1",r"2",r"3",r"4",r"5",r"6",r"7",r"8",r"9", 
  944.      +              o"0",r";",r"<",r"=",r">",o"71",r"@",
  945.      +              r"a",r"b",r"c",r"d",r"e",r"f",r"g",r"h",r"i", 
  946.      +              r"j",r"k",r"l",r"m",r"n",r"o",r"p",r"q",r"r", 
  947.      +              r"s",r"t",r"u",r"v",r"w",r"x",r"y",r"z",
  948.      +              r"[",o"75",r"]",o"76",o"65",r"@", 
  949.      +              r"a",r"b",r"c",r"d",r"e",r"f",r"g",r"h",r"i", 
  950.      +              r"j",r"k",r"l",r"m",r"n",r"o",r"p",r"q",r"r", 
  951.      +              r"s",r"t",r"u",r"v",r"w",r"x",r"y",r"z",
  952.      +              r"[",r"\",r"]",r"^",r" "/ 
  953.         data lascii/58,97,98,99,100,101,102,103,104,105,106,107,108,109,
  954. c                    :  a  b  c   d   e   f   g   h   i   j   k   l   m 
  955.      +              110,111,112,113,114,115,116,117,118,119,120,121,122,
  956. c                     n   o   p   q   r   s   t   u   v   w   x   y   z 
  957.      +              48,49,50,51,52,53,54,55,56,57,
  958. c                    0  1  2  3  4  5  6  7  8  9 
  959.      +              43,45,42,47,40,41,36,61,32,44,46,35,91,93,37, 
  960. c                    +  -  *  /  (  )  $  =     ,  .  %  [  ]  <pct>
  961.      +              34,95,33,38,39,63,60,62,64,92,94,59/
  962. c                    "  #  !  &  '  ?  <  >  @  \  ^  ; 
  963.         data uascii/58,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80, 
  964. c                    :  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p
  965.      +              81,82,83,84,85,86,87,88,89,90,48,49,50,51,52,53,54, 
  966. c                    q  r  s  t  u  v  w  x  y  z  0  1  2  3  4  5  6
  967.      +              55,56,57,43,45,42,47,40,41,36,61,32,44,46,35,91,93, 
  968. c                    7  8  9  +  -  *  /  (  )  $  =     ,  .  %  [  ]
  969.      +              37,34,95,33,38,39,63,60,62,64,92,94,59/ 
  970. c                <pct>  "  #  !  &  '  ?  <  >  @  \  ^  ;
  971. c$      endif 
  972. c$    endif 
  973.       end 
  974.       subroutine exitpgm
  975.   
  976. ccc   exitpgm - exit the program
  977. *call kermcom 
  978. c     set complete bit in all fets, in case we died in mid-cio call.
  979.       if(.not. normal) then 
  980.           call remark (' kermit aborted.')
  981.           do 10 i = 1, maxfile
  982.               fets(0,i) = or(fets(0,i),1) 
  983. 10        continue
  984.       endif 
  985.   
  986.       call fflush(stdout) 
  987.       call stty('raw',off)
  988.       call stty('binary',off) 
  989.       if (savedpx .ne. halfdup) call stty('duplex',fulldup) 
  990.       call fclose(stdin)
  991.       call fclose(stdout) 
  992.       if (debugfd.ne.0) call fclose(debugfd)
  993. c     if running under nos - issue memory status message. 
  994. c$    if (nos .eq. 1) 
  995.       call nosexit
  996. c$    else
  997.       call endrun 
  998. c$    endif 
  999.   
  1000.       end 
  1001.       subroutine abtp(type) 
  1002.   
  1003. cc    abtp - abort program. 
  1004. c     this subroutine should not return.
  1005. *call kermcom 
  1006.       boolean type
  1007. c$    if (ut2d .eq. 1) then 
  1008.       call abort
  1009. c$    else
  1010.       call abort(type)
  1011. c$    endif 
  1012.       return
  1013.       end 
  1014. *if def,ovcap 
  1015.           ident    kermxcc
  1016.           entry    kermxcc
  1017.           lcc      ovcap. 
  1018.           ldset    noept=unlfile
  1019. kermxcc   title    kermxcc - kermit execute control command processor.
  1020.           comment kermxcc - kermit execute control command processor. 
  1021. kermxcc   space    4,10 
  1022. **        kermxcc - kermit execute control command processor. 
  1023. kermxcc   subr                     entry/exit 
  1024.           rj       =xexecmd        call the real workhorse
  1025.           eq       kermxccx        return 
  1026.   
  1027.           end 
  1028. *endif
  1029.       subroutine execmd 
  1030.   
  1031. ccc   execmd - execute a control command
  1032. c     execute a control command and return to command mode or 
  1033. c     exit to the operating system.  next execution of kermit 
  1034. c     will return with current environment.  this subroutine
  1035. c     does not return.
  1036. *call kermcom 
  1037.       logical confirm, eatline
  1038. c$    if (nos .eq. 1) 
  1039. c     if running under nos - issue memory status message. 
  1040.       call memstat
  1041. c$    endif 
  1042. c     before we do anything rash
  1043.       if (autoret .eq. no) then 
  1044.          if (.not. confirm(stdin)) return 
  1045.       endif 
  1046. c     write out the current environment 
  1047.       call retfile('zzzzken') 
  1048.       cfd = fopen('zzzzken',wr) 
  1049.       if (cfd .eq. error) then
  1050.          call remark(' cannot create environment file.')
  1051.          return 
  1052.       endif 
  1053.       call fwrite(cfd,header,locf(trailer)-locf(header))
  1054.       call fclose(cfd)
  1055. c     if only exit to the operating system
  1056.       if (autoret .eq. no) then 
  1057.          normal = .true.
  1058.          call exitpgm 
  1059.       endif 
  1060. c     write the control command file
  1061.       dskcset = dskdpc
  1062.       call retfile('zzzzkcc') 
  1063.       fd = fopen('zzzzkcc',create)
  1064.       if (fd .eq. error) then 
  1065.          call remark(' cannot create ccl file.')
  1066.          fd = closed
  1067.          return 
  1068.       endif 
  1069. c$    if (nos .eq. 1 .or. nosbe .eq. 1) 
  1070.       call fprintf(fd, '.proc,zzzzkcc.\n',0,0,0,0)
  1071. c$    endif 
  1072. c     copy command to command file
  1073.       eatline = .false. 
  1074. 10    if (getc(stdin,ch) .eq. blank) then 
  1075.          go to 10 
  1076.       else
  1077.          if (ch .eq. qmark) then
  1078.             eatline = .true.
  1079.             call fprintf(stdout,'^monitor command to execute\n',0,0,0,0)
  1080. c$          if (nos .eq. 1) 
  1081.             call fflush(stdout) 
  1082.             call writer(fets(0,stdout)) 
  1083. c$          endif 
  1084.          else 
  1085.             call putc(ch,fd)
  1086.          endif
  1087.       endif 
  1088. 20    ch = getc(stdin,ch) 
  1089.       if (.not. eatline) call putc(ch,fd) 
  1090.       if (ch .ne. nel) go to 20 
  1091. c     copy cleanup commands to command file 
  1092. c$    if (nosbe .eq. 1) then
  1093.       call fprintf(fd,'skip(ok)\nexit(s)\nendif(ok)\n' // 
  1094.      +  'return(zzzzkcc)\nkermit.\n',0,0,0,0) 
  1095. c$    endif 
  1096. c$    if (ut2d .eq. 1)
  1097.       call fprintf(fd,'.skipcc\n.exit\n.return zzzzkcc\n.kermit\n', 
  1098.      +             0,0,0,0) 
  1099. c$    endif 
  1100. c$    if (nos .eq. 1) 
  1101.       call fprintf(fd, 'return(zzzzkcc)\nrevert,ex.kermit.\n',
  1102.      +             0,0,0,0) 
  1103.       call fprintf(fd, 'exit.\nreturn(zzzzkcc)\nrevert,ex.kermit.\n', 
  1104.      +             0,0,0,0) 
  1105. c$    endif 
  1106.       call fclose(fd) 
  1107. c     execute the command file
  1108. c$    if (nosbe .eq. 1) then
  1109.       call excst('begin,,zzzzkcc.') 
  1110. c$    endif 
  1111. c$    if (ut2d .eq. 1)
  1112.       call excst('.cntrl,zzzzkcc')
  1113. c$    endif 
  1114. c$    if (nos .eq. 1) 
  1115.       call excst('zzzzkcc.')
  1116. c$    endif 
  1117.       end 
  1118. *if def,ovcap 
  1119.           ident  kermhlp
  1120.           entry  kermhlp
  1121.           lcc    ovcap. 
  1122.           ldset  noept=unlfile
  1123.  kermhlp  title  kermhlp - kermit help command processor. 
  1124.           comment kermit help command processor.
  1125.  kermhlp  space  4,10 
  1126. **        kermhlp - kermit help command processor.
  1127.   
  1128.   
  1129.  kermhlp  subr               entry/exit 
  1130.           rj     =xhlpcmd    call the real workhorse
  1131.           eq     kermhlpx    return 
  1132.   
  1133.           end 
  1134. *endif
  1135.       subroutine hlpcmd 
  1136.   
  1137. ccc   hlpcmd - process the help command.
  1138. *call kermcom 
  1139.       parameter (tsize=12)
  1140.       character*10 hlptyp(tsize)
  1141.       logical confirm 
  1142.       data hlptyp / 'exit', 'help', 'kermit', 'push', 'quit', 'receive',
  1143.      +              'send', 'server', 'set', 'show', 'status', '!' /
  1144.   
  1145. c$    if (nos .eq. 1) 
  1146. c     if running under nos - issue memory status message. 
  1147.       call memstat
  1148. c$    endif 
  1149.       indx = match(hlptyp,tsize,.true.) 
  1150.       if (indx .eq. eof .or. indx .eq. error) return
  1151.       if (indx .eq. 0) go to 30 
  1152.       if (.not. confirm(stdin)) return
  1153.       go to (10, 20, 30, 40, 10, 50, 60, 70, 80, 90, 100, 110), indx
  1154. c     help exit 
  1155. 10    call fprintf(stdout,'^exit from ^kermit-170\n') 
  1156.       return
  1157. c     help help 
  1158. 20    call fprintf(stdout,'\n^h^e^l^p [topic]\n\n^typing ^h^e^l^p alone 
  1159.      +prints a brief summary of ^kermit-170 and its commands.\n^you can 
  1160.      +also type\n\n   ^h^e^l^p command\n\nfor any ^kermit-170 command, e
  1161.      +.g. "help send", to get more detailed information\nabout a specifi
  1162.      +c command.  ^type\n\n   ^h^e^l^p ?\n\nto see a list of all the ava
  1163.      +ilable help commands, or consult the ^kermit ^users\n^guide.\n\n')
  1164.       return
  1165. c     help kermit 
  1166. 30    call fprintf(stdout,'\n^kermit is a file transfer protocol for use
  1167.      + over an asynchronous serial\ntelecommunication line.  ^files are 
  1168.      +broken up into "packets" with checksums and\nother control informa
  1169.      +tion to ensure (with high probability) error-free and\ncomplete tr
  1170.      +ansmission.\n\n^kermit-170 is the implementation for the ^cyber 17
  1171.      +0/730 and is\nrun "remotely" from another computer (e.g. a microco
  1172.      +mputer).\n\n^you can run ^kermit interactively by typing repeated 
  1173.      +commands in response to\nits "^kermit-170>" prompt, or you can run
  1174.      + it as a remote server.\n\n^kermit-170 command summary -- optional
  1175.      + parts are in [brackets]:\n\n') 
  1176.       call fprintf(stdout,'* ^for exchanging files:         ^s^e^n^d fil
  1177.      +e\n') 
  1178.       call fprintf(stdout,'                                ^r^e^c^e^i^v^
  1179.      +e\n\n') 
  1180.       call fprintf(stdout,'* ^for acting as a server:       ^s^e^r^v^e^r
  1181.      +\n\n')
  1182.       call fprintf(stdout,'* ^setting nonstandard transmission and file 
  1183.      +parameters:\n        ^s^e^t ^d^e^b^u^g, ^d^e^l^a^y, ^d^u^p^l^e^x, 
  1184.      +^p^a^r^i^t^y, ^i^n^i^t-^r^e^t^r^y, ^r^e^t^r^y\n') 
  1185.       call fprintf(stdout,'        ^s^e^t ^s^e^n^d (or ^r^e^c^e^i^v^e) ^
  1186.      +end-of-^line, ^packet-length, ^pad-^character,\n                ^p
  1187.      +ad-^length, ^quote-^character, ^sync-^character, ^time-^out\n') 
  1188.       call fprintf(stdout,'* ^getting information:          ^h^e^l^p [to
  1189.      +pic], ^s^t^a^t^u^s, ^s^h^o^w\n\n')
  1190.       call fprintf(stdout,'* ^leaving the program:          ^e^x^i^t, ^q
  1191.      +^u^i^t\n\n')
  1192.       call fprintf(stdout,'^for further information, type "help" for any
  1193.      + of the above, e.g. "help set",\nor see the "^kermit ^users ^guide
  1194.      +" and the "^kermit ^protocol ^manual" for complete\ndetails.\n\n')
  1195.       return
  1196. c     help push 
  1197. 40    call fprintf(stdout,'\n^p^u^s^h\n\n^exit from ^kermit-170 saving t
  1198.      +he current environment.  ^the environment will be\nrestored upon r
  1199.      +eentering ^kermit-170.\n')
  1200.       return
  1201. c     help receive
  1202. 50    call fprintf(stdout,'\n^r^e^c^e^i^v^e\n\n^receive a file or group 
  1203.      +of files from the other host.  ^if the name in the\n')
  1204.       call fprintf(stdout,'header packet is not a legal ^cyber file name
  1205.      +, the first 7 legal characters\n')
  1206.       call fprintf(stdout,'will be used.\n\n^if the file already exits a
  1207.      +s a local file, ^kermit will abort the transfer.\n')
  1208.       call fprintf(stdout,'^if an error occurs during transfer, the file
  1209.      + being received will be\nremoved from the local file list to allow
  1210.      + the transfer to be retried.\n')
  1211.       call fprintf(stdout,'^you should escape back to your local ^kermit
  1212.      + after entering ^r^e^c^e^i^v^e\nmode and give the ^s^e^n^d command
  1213.      +.\n\n') 
  1214.       return
  1215. c     help send 
  1216. 60    call fprintf(stdout,'\n^s^e^n^d filename\n\n')
  1217.       call fprintf(stdout,'^send a file to the other host.  ^the name of
  1218.      + the file is passed\nto the other host in a file header packet, so
  1219.      + that the file can be\nstored there with the same name.\n\n') 
  1220.       call fprintf(stdout,'^you should escape back to your local ^kermit
  1221.      + and give the ^r^e^c^e^i^v^e\ncommand.  ^if you don''t do this fas
  1222.      +t enough the "send-init" packet may\narrive prematurely.  ^to prev
  1223.      +ent this, use ^s^e^t ^d^e^l^a^y or hit the ^r^e^t^u^r^n key\non yo
  1224.      +ur microcomputer if it does not timeout.\n\n')
  1225.       return
  1226. c     help server 
  1227. 70    call fprintf(stdout,'\n^s^e^r^v^e^r\n\n') 
  1228. c$    if(ut2d .eq. 1) 
  1229.       call fprintf(stdout,'^act as a server for another ^kermit.  ^take 
  1230.      +all further commands only from\nthe other ^kermit.  ^after issuing
  1231.      + this command, escape back to your local\nsystem and issue ^s^e^n^
  1232.      +d, ^r^e^c^e^i^v^e or ^g^e^t, ^b^y^e, or other server-oriented\ncom
  1233.      +mands from there.  ^if your local ^kermit does not have a ^b^y^e c
  1234.      +ommand,\nit does not have the full ability to communicate with a ^
  1235.      +kermit server (in\nwhich case you can only use the ^s^e^n^d comman
  1236.      +d).  ^if your local ^kermit\ndoes have a ^b^y^e command, use it to
  1237.      + shut down and log out the ^kermit\nserver when you are done with 
  1238.      +it; otherwise, connect back to the ^cyber, type\nseveral ^control-
  1239.      +^c''s to stop the server, and logout.\n\n') 
  1240. c$    else
  1241. c$    if(nosbe .eq. 1  .or.  scope .eq. 1)
  1242.       call fprintf(stdout,'^act as a server for another ^kermit.  ^take 
  1243.      +all further commands only from\nthe other ^kermit.  ^after issuing
  1244.      + this command, escape back to your local\nsystem and issue ^s^e^n^
  1245.      +d, ^r^e^c^e^i^v^e or ^g^e^t, ^b^y^e, or other server-oriented\ncom
  1246.      +mands from there.  ^if your local ^kermit does not have a ^b^y^e c
  1247.      +ommand,\nit does not have the full ability to communicate with a ^
  1248.      +kermit server (in\nwhich case you can only use the ^s^e^n^d comman
  1249.      +d).  ^if your local ^kermit\ndoes have a ^b^y^e command, use it to
  1250.      + shut down and log out the ^kermit\nserver when you are done with 
  1251.      +it; otherwise, connect back to the ^cyber, type\nseveral ^percent-
  1252.      +^a''s to stop the server, and logout.\n\n') 
  1253. c$    else
  1254.       call fprintf(stdout,'^act as a server for another ^kermit.  ^take 
  1255.      +all further commands only from\nthe other ^kermit.  ^after issuing
  1256.      + this command, escape back to your local\nsystem and issue ^s^e^n^
  1257.      +d, ^r^e^c^e^i^v^e or ^g^e^t, ^b^y^e, or other server-oriented\ncom
  1258.      +mands from there.  ^if your local ^kermit does not have a ^b^y^e c
  1259.      +ommand,\nit does not have the full ability to communicate with a ^
  1260.      +kermit server (in\nwhich case you can only use the ^s^e^n^d comman
  1261.      +d).  ^if your local ^kermit\ndoes have a ^b^y^e command, use it to
  1262.      + shut down and log out the ^kermit\nserver when you are done with 
  1263.      +it; otherwise, connect back to the ^cyber, type\nseveral ^control-
  1264.      +^t''s to stop the server, and logout.\n\n') 
  1265. c$    endif 
  1266. c$    endif 
  1267.       return
  1268. c     help set
  1269. 80    call fprintf(stdout,'\n^s^e^t\n') 
  1270.       call fprintf(stdout,'  ^establish system-dependent parameters.  ^y
  1271.      +ou can examine their values with the\n  ^s^h^o^w command.  ^numeri
  1272.      +c values may be decimal, octal (postfixed with a ^b),\n  or hexade
  1273.      +cimal (postfixed by an ^h).  ^the following may be ^s^e^t:\n\n')
  1274.       call fprintf(stdout,' ^d^a^t^a-^m^o^d^e keyword\n') 
  1275.       call fprintf(stdout,'   ^declares the data mode to be used while p
  1276.      +rocessing disk files.  ^the choices\n   are ^a^s^c^i^i, ^d^i^s^p^l
  1277.      +^a^y, and ^image-^a^s^c^i^i.  ^a^s^c^i^i means the disk file conta
  1278.      +ins\n   ^a^s^c^i^i data, ^d^i^s^p^l^a^y means the file contains ^d
  1279.      +isplay ^code data, and ^image-\n   ^a^s^c^i^i means the file conta
  1280.      +ins 8-bit ^a^s^c^i^i data.  ^the default is ^d^i^s^p^l^a^y.\n\n') 
  1281.       call fprintf(stdout,' ^d^e^b^u^g options\n   ^show packet traffic 
  1282.      +explicitly.  ^options are:\n')
  1283.       call fprintf(stdout,'   ^a^l^l      ^set all debug options.\n') 
  1284.       call fprintf(stdout,'   ^l^o^g-^f^i^l^e ^log states and packets to
  1285.      + the specified file.  ^the default\n            log-file is file ^
  1286.      +k^e^r^m^l^o^g.\n')
  1287.       call fprintf(stdout,'   ^o^f^f      ^don''t display debugging info
  1288.      +rmation (this is the default).  ^if\n            debugging was in 
  1289.      +effect, turn it off and close any log file.\n') 
  1290.       call fprintf(stdout,'   ^p^a^c^k^e^t^s  ^display each incoming and
  1291.      + outgoing packet (lengthy).\n') 
  1292.       call fprintf(stdout,'   ^s^t^a^t^e^s   ^show kermit state transiti
  1293.      +ons and packet numbers (brief).\n\n') 
  1294.       call fprintf(stdout,' ^d^e^l^a^y decimal-number\n') 
  1295.       call fprintf(stdout,'   ^how many seconds to wait before sending t
  1296.      +he first packet.  ^this gives you\n   time to "escape" back and is
  1297.      +sue a ^r^e^c^e^i^v^e command.\n\n') 
  1298.       call fprintf(stdout,' ^d^u^p^l^e^x keyword\n')
  1299.       call fprintf(stdout,'   ^changes the method of echoing characters 
  1300.      +when being prompted for commands.\n   ^the choices are ^f^u^l^l an
  1301.      +d ^h^a^l^f.  ^full means the ^cyber will echo the\n   characters y
  1302.      +ou type.  ^half means the local systems echos them.  ^full is\n 
  1303.      +the default, and is used by most hosts.\n\n') 
  1304.       call fprintf(stdout,' ^i^n^i^t-^r^e^t^r^y decimal-number\n')
  1305.       call fprintf(stdout,'   ^set the maximum number of retries allowed
  1306.      + for the initial connection\n   before giving up.\n\n') 
  1307.       call fprintf(stdout,' ^p^a^r^i^t^y keyword\n')
  1308.       call fprintf(stdout,'   ^if the other computer is using parity on 
  1309.      +the communication line, you must\n   inform ^kermit-170, so it can
  1310.      + send the desired parity on outgoing characters,\n   and strip it 
  1311.      +from incoming ones.\n') 
  1312.       call fprintf(stdout,'\n   ^this must be set in ^kermit and the fro
  1313.      +nt-end.  ^see a system manual for\n   setting parity in the front-
  1314.      +end.\n')
  1315.       call fprintf(stdout,'\n   ^choices are ^n^o^n^e (the default), ^e^
  1316.      +v^e^n, ^o^d^d, ^m^a^r^k, and ^s^p^a^c^e.\n   ^n^o^n^e means no par
  1317.      +ity processing is done, and the 8th bit of each character\n   can 
  1318.      +be used for data when transmitting binary files.\n\n')
  1319.       call fprintf(stdout,' ^r^d^e^l^a^y decimal-number\n') 
  1320.       call fprintf(stdout,'   ^set the number of milliseconds of delay b
  1321.      +efore issuing a read to the\n   terminal.  ^this may be used to tu
  1322.      +ne reads so that data is ready\n   when the read function is issue
  1323.      +d and swapping does not take place.\n\n') 
  1324.       call fprintf(stdout,' ^r^e^t^r^y decimal-number\n') 
  1325.       call fprintf(stdout,'   ^set the maximum number of retries allowed
  1326.      + for sending a particular packet.\n\n') 
  1327.       call fprintf(stdout,' ^s^e^n^d parameter\n   ^parameters for outgo
  1328.      +ing packets as follows:\n\n') 
  1329.       call fprintf(stdout,'   ^end-of-^line octal-number\n')
  1330.       call fprintf(stdout,'     ^the octal value of the ^a^s^c^i^i chara
  1331.      +cter to be used as a line terminator\n     for packets, if one is 
  1332.      +required by the other system.  ^carriage\n     return (15^b) by de
  1333.      +fault.\n\n')
  1334.       call fprintf(stdout,'   ^packet-^length decimal-number\n')
  1335.       call fprintf(stdout,'     ^maximum packet length to send, decimal 
  1336.      +number, between 20 and 94,\n     94 by default.\n\n') 
  1337.       call fprintf(stdout,'   ^pad-^character octal-number\n')
  1338.       call fprintf(stdout,'     ^character to use for padding.  ^default
  1339.      + is ^n^u^l.\n\n') 
  1340.       call fprintf(stdout,'   ^pad-^length decimal-number\n') 
  1341.       call fprintf(stdout,'     ^how much padding to send before a packe
  1342.      +t.  ^default is no padding.\n\n') 
  1343.       call fprintf(stdout,'   ^quote-^character octal-number\n')
  1344.       call fprintf(stdout,'     ^what printable character to use for quo
  1345.      +ting of control characters.\n     ^the default is "#" (43^b).  ^th
  1346.      +ere should be no reason to change this.\n\n') 
  1347.       call fprintf(stdout,'   ^sync-^character octal-number\n') 
  1348.       call fprintf(stdout,'     ^the control character that marks the be
  1349.      +ginning of the packet.  ^normally\n     ^s^o^h (^control-^a, ^a^s^
  1350.      +c^i^i 1).  ^there should be no reason to change this.\n\n') 
  1351.       call fprintf(stdout,'   ^time-^out decimal-number\n') 
  1352.       call fprintf(stdout,'     ^how many seconds the other ^kermit want
  1353.      +s before being asked\n     for retransmission.  ^unfortunately, th
  1354.      +e ^cyber has no way of timing\n     out so this parameter is ignor
  1355.      +ed.\n\n') 
  1356.       call fprintf(stdout,' ^r^e^c^e^i^v^e parameter\n   ^parameters to 
  1357.      +request or expect for incoming packets, as follows:\n\n') 
  1358.       call fprintf(stdout,'   ^end-of-^line octal-number\n')
  1359.       call fprintf(stdout,'     ^the octal value of the ^a^s^c^i^i chara
  1360.      +cter to be used as a line terminator\n     for packets, if one is 
  1361.      +required by the other system.  ^carriage\n     return (15^b) by de
  1362.      +fault.\n\n')
  1363.       call fprintf(stdout,'   ^packet-^length decimal-number\n')
  1364.       call fprintf(stdout,'     ^maximum packet length to send, decimal 
  1365.      +number, between 20 and 94,\n     94 by default.\n\n') 
  1366.       call fprintf(stdout,'   ^pad-^character octal-number\n')
  1367.       call fprintf(stdout,'     ^character to use for padding.  ^default
  1368.      + is ^n^u^l.\n\n') 
  1369.       call fprintf(stdout,'   ^pad-^length decimal-number\n') 
  1370.       call fprintf(stdout,'     ^how much padding to send before a packe
  1371.      +t.  ^default is no padding.\n\n') 
  1372.       call fprintf(stdout,'   ^quote-^character octal-number\n')
  1373.       call fprintf(stdout,'     ^what printable character to use for quo
  1374.      +ting of control characters.\n     ^the default is "#" (43^b).  the
  1375.      +re should be no reason to change this.\n\n')
  1376.       call fprintf(stdout,'   ^sync-^character octal-number\n') 
  1377.       call fprintf(stdout,'     ^the control character that marks the be
  1378.      +ginning of the packet.  ^normally\n     ^s^o^h (^control-^a, ^a^s^
  1379.      +c^i^i 1).  ^there should be no reason to change this.\n\n') 
  1380.       call fprintf(stdout,'   ^time-^out decimal-number\n') 
  1381.       call fprintf(stdout,'     ^how many seconds the other ^kermit shou
  1382.      +ld wait for a packet before\n     asking for retransmission.\n\n')
  1383.       return
  1384. c     help show 
  1385. 90    call fprintf(stdout,'^display current ^s^e^t parameters, version o
  1386.      +f ^kermit-170, and other info.\n')
  1387.       return
  1388. c     help status 
  1389. 100   call fprintf(stdout,'^give statistics about the most recent file t
  1390.      +ransfer.\n')
  1391.       return
  1392. c     help !
  1393. 110   call fprintf(stdout,'\n! ^monitor-^command\n\n^execute a monitor c
  1394.      +ommand from within ^kermit-170.  ^the current settings\nwill be pr
  1395.      +eserved.\n')
  1396. c$    if (nos .eq. 1) 
  1397.       call fprintf(stdout,'\n^note: ^the command must be formmated corre
  1398.      +ctly with a ^n^o^s terminator [. or )].\n') 
  1399. c$    endif 
  1400.       return
  1401.       end 
  1402. *if def,ovcap 
  1403.           ident  kermrcv
  1404.           entry  kermrcv
  1405.           lcc    ovcap. 
  1406.           ldset  noept=unlfile
  1407.  kermrcv  title  kermrcv - kermit receive file processor. 
  1408.           comment kermit receive file processor.
  1409.  kermrcv  space  4,10 
  1410. **        kermrcv - kermit receive file processor.
  1411.   
  1412.   
  1413.  kermrcv  subr               entry/exit 
  1414.           rj     =xrcvfile   call the real workhorse
  1415.           eq     kermrcvx    return 
  1416.   
  1417.           end 
  1418. *endif
  1419.       subroutine rcvfile
  1420.   
  1421. ccc   rcvfile - top level subroutine to start receive state.
  1422. *call kermcom 
  1423.       logical confirm 
  1424. c$    if (nos .eq. 1) 
  1425. c     if running under nos - issue memory status message. 
  1426.       call memstat
  1427. c$    endif 
  1428. c     confirm the command 
  1429.       if (.not. confirm(stdin)) return
  1430. c     insure their is no junk in the file array.  this keeps remove 
  1431. c     happy, in the event we blow off before we get a file spec.
  1432.       do 10 i = 1, maxpack
  1433.           filestr(i) = 0
  1434. 10    continue
  1435.   
  1436.       call stty('binary',on)
  1437.       if(dskcset .eq. dskimag) call stty('raw',on)
  1438.       savedpx = gtty('duplex')
  1439.       call stty('duplex',halfdup) 
  1440.       if (receive(r) .eq. ok) then
  1441.          call fprintf(stdout,'^receive complete.\n',0,0,0,0)
  1442.       else
  1443.          call fprintf(stdout,'^receive failed.\n',0,0,0,0)
  1444.       endif 
  1445.       if(dskcset .eq. dskimag) call stty('raw',off) 
  1446.       call stty('binary',off) 
  1447.       if (savedpx .ne. halfdup) call stty('duplex',fulldup) 
  1448.       return
  1449.       end 
  1450. *if def,ovcap 
  1451.           ident  kermsnd
  1452.           entry  kermsnd
  1453.           lcc    ovcap. 
  1454.           ldset  noept=unlfile
  1455.  kermsnd  title  kermsnd - kermit send file processor.
  1456.           comment kermit send file processor. 
  1457.  kermsnd  space  4,10 
  1458. **        kermsnd - kermit send file processor. 
  1459.   
  1460.   
  1461.  kermsnd  subr               entry/exit 
  1462.           rj     =xsndfile   call the real workhorse
  1463.           eq     kermsndx    return 
  1464.   
  1465.           end 
  1466. *endif
  1467.       subroutine sndfile
  1468.   
  1469. ccc   sndfile - send a file to other kermit.
  1470. *call kermcom 
  1471.       logical cfe 
  1472.       character*10 lfn
  1473. c$    if (nos .eq. 1) 
  1474. c     if running under nos - issue memory status message. 
  1475.       call memstat
  1476. c$    endif 
  1477. c     pick up the file name and save it for opening later 
  1478.       call setval(filestr,'s',iret,7,0,0,hlpsnfn,.true.)
  1479.       if (iret .eq. error) return 
  1480. c     make sure the name is legal.
  1481.       call as2dpc(filestr,lfn)
  1482.       if (xvfn(lfn) .ne. 0) then
  1483.          call fprintf(stdout,'?^illegal file name: @s.\n',filestr,0,0,0)
  1484.          return 
  1485.       endif 
  1486. c     map it to upper-case
  1487.       call dpc2as(lfn,filestr,slen(filestr))
  1488. c     check to make sure it's there to send 
  1489.       if (.not. cfe(lfn)) then
  1490.          call fprintf(stdout,'?^file @s is not local.\n',filestr,0,0,0) 
  1491.          return 
  1492.       endif 
  1493. c     delay the first packet
  1494.       if (delayfp .gt. 0) call sleep(delayfp) 
  1495.       call stty('binary',on)
  1496.       if(dskcset .eq. dskimag) call stty('raw',on)
  1497.       savedpx = gtty('duplex')
  1498.       call stty('duplex',halfdup) 
  1499. c     start sending packets 
  1500.       packnum = 0 
  1501.       if (send() .eq. ok) then
  1502.          call fprintf(stdout,'^send complete.\n',0,0,0,0) 
  1503.       else
  1504.          call fprintf(stdout,'^send failed.\n',0,0,0,0) 
  1505.       endif 
  1506.       if(dskcset .eq. dskimag) call stty('raw',off) 
  1507.       call stty('binary',off) 
  1508.       if (savedpx .ne. halfdup) call stty('duplex',fulldup) 
  1509.       return
  1510.       end 
  1511. *if def,ovcap 
  1512.           ident  kermset
  1513.           entry  kermset
  1514.           lcc    ovcap. 
  1515.           ldset  noept=unlfile
  1516.  kermset  title  kermset - kermit set command processor.
  1517.           comment kermit set command processor. 
  1518.  kermset  space  4,10 
  1519. **        kermset - kermit set command processor. 
  1520.   
  1521.   
  1522.  kermset  subr               entry/exit 
  1523.           rj     =xset       call the real workhorse
  1524.           eq     kermsetx    return 
  1525.   
  1526.           end 
  1527. *endif
  1528.       subroutine set
  1529.   
  1530. ccc   set - set some attributes.
  1531. *call kermcom 
  1532.       parameter (tsize=10)
  1533.       character*10 settyp(tsize)
  1534.       data settyp / 'data-mode', 'debug', 'delay', 'duplex',
  1535.      +    'init-retry', 'parity', 'receive', 'rdelay',
  1536.      +    'retry', 'send' / 
  1537.   
  1538. c$    if (nos .eq. 1) 
  1539. c     if running under nos - issue memory status message. 
  1540.       call memstat
  1541. c$    endif 
  1542.       indx = match(settyp,tsize,.false.)
  1543.       if (indx .le. 0) return 
  1544.       go to (10, 20, 30, 40, 50, 60, 70, 75, 80, 90), indx
  1545. c     set character set 
  1546. 10    call dmodcmd
  1547.       return
  1548. c     set debugging modes 
  1549. 20    call dbugcmd
  1550.       return
  1551. c     set first packet delay
  1552. 30    call setval(delayfp,'i',0,30,0,30,hlpdlfp,.true.) 
  1553.       return
  1554. c     set the duplex
  1555. 40    call dplxcmd
  1556.       return
  1557. c     set intial packet retry count 
  1558. 50    call setval(maxrini,'i',1,50,1,50,hlpiprc,.true.) 
  1559.       return
  1560. c     set parity
  1561. 60    call parcmd 
  1562.       return
  1563. c     set receive packet attributes 
  1564. 70    call setpack(packsiz) 
  1565.       return
  1566. c     set read data delay 
  1567. 75    call setval(rdelay,'i',0,2000,0,2000,hlprdel,.true.)
  1568.       return
  1569. c     set packet retry count
  1570. 80    call setval(maxrtry,'i',1,50,1,50,hlpprtr,.true.) 
  1571.       return
  1572. c     set send packet attributes
  1573. 90    call setpack(spksiz)
  1574.       return
  1575.       end 
  1576. *if def,ovcap 
  1577.           ident  kermsho
  1578.           entry  kermsho
  1579.           lcc    ovcap. 
  1580.           ldset  noept=unlfile
  1581.  kermsho  title  kermsho - kermit show command processor. 
  1582.           comment kermit show command processor.
  1583.  kermsho  space  4,10 
  1584. **        kermsho - kermit show command processor.
  1585.   
  1586.   
  1587.  kermsho  subr               entry/exit 
  1588.           rj     =xshow      call the real workhorse
  1589.           eq     kermshox    return 
  1590.   
  1591.           end 
  1592. *endif
  1593.       subroutine show 
  1594.   
  1595. ccc   show the current program settings 
  1596. *call kermcom 
  1597.       logical confirm 
  1598. c$    if (nos .eq. 1) 
  1599. c     if running under nos - issue memory status message. 
  1600.       call memstat
  1601. c$    endif 
  1602. c     confirm the command 
  1603.       if (.not. confirm(stdin)) return
  1604.       call fprintf(stdout,version,0,0,0,0)
  1605. c$    if (nos .eq. 1) 
  1606.       call fprintf(stdout,'^n^o^s ^version @d.@d - ^level @d ', 
  1607.      +   nosver/10, (nosver-((nosver/10)*10)), noslvl, 0, 0)
  1608. c$    endif 
  1609. c     display the current date and time 
  1610.       call getnow(mm,dd,yy,hr,min,sec)
  1611.       call putday(stdout,mm,dd,yy)
  1612.       call fprintf(stdout,', ',0,0,0,0) 
  1613.       call putmnth(stdout,mm) 
  1614.       call fprintf(stdout,' @d, @d ',dd,yy,0,0) 
  1615.       if (hr .lt. 10) call putc(asc('0'),stdout)
  1616.       call fprintf(stdout,'@d:',hr,0,0,0) 
  1617.       if (min .lt. 10) call putc(asc('0'),stdout) 
  1618.       call fprintf(stdout,'@d:',min,0,0,0)
  1619.       if (sec .lt. 10) call putc(asc('0'),stdout) 
  1620.       call fprintf(stdout,'@d\n\n',sec,0,0,0) 
  1621. c     display disk character set
  1622.       call fprintf(stdout,'  ^data-mode: ',0,0,0,0) 
  1623.       if(dskcset .eq. dsknos8) then 
  1624.           call fprintf(stdout,'^n^o^s 812 ^a^s^c^i^i\n',0,0,0,0)
  1625.       elseif(dskcset .eq. dskut8) then
  1626.           call fprintf(stdout,'^u^t 812 ^a^s^c^i^i\n',0,0,0,0)
  1627.       elseif(dskcset .eq. dskdpc) then
  1628.           call fprintf(stdout,'^display-^code\n',0,0,0,0) 
  1629.       elseif(dskcset .eq. dskimag) then 
  1630.           call fprintf(stdout,'^image-^a^s^c^i^i\n',0,0,0,0)
  1631.       else
  1632.           call fprintf(stdout,'^unknown',0,0,0,0) 
  1633.       endif 
  1634. c     display known parity
  1635.       call fprintf(stdout,'  ^parity:    ',0,0,0,0) 
  1636.       parity = gtty('parity') 
  1637.       if (parity .eq. none) then
  1638.          call fprintf(stdout,'^none\n',0,0,0,0) 
  1639.       else if (parity .eq. even) then 
  1640.          call fprintf(stdout,'^even\n',0,0,0,0) 
  1641.       else if (parity .eq. odd) then
  1642.          call fprintf(stdout,'^odd\n',0,0,0,0)
  1643.       else if (parity .eq. mark) then 
  1644.          call fprintf(stdout,'^mark\n',0,0,0,0) 
  1645.       else if (parity .eq. space) then
  1646.          call fprintf(stdout,'^space\n',0,0,0,0)
  1647.       else
  1648.          call fprintf(stdout,'^unknown\n',0,0,0,0)
  1649.       endif 
  1650. c     display the current duplex
  1651.       call fprintf(stdout,'  ^duplex:    ',0,0,0,0) 
  1652.       duplex = gtty('duplex') 
  1653.       if (duplex .eq. fulldup) then 
  1654.          call fprintf(stdout,'^full\n',0,0,0,0) 
  1655.       else if (duplex .eq. halfdup) then
  1656.          call fprintf(stdout,'^half\n',0,0,0,0) 
  1657.       else
  1658.          call fprintf(stdout,'^unknown\n',0,0,0,0)
  1659.       endif 
  1660. c     display current debug modes 
  1661.       call fprintf(stdout,'  ^debugging: ',0,0,0,0) 
  1662.       if ((debug.and.dbgstat).ne.0) call fprintf(stdout,'^states ', 
  1663.      +   0,0,0,0) 
  1664.       if ((debug.and.dbgpack).ne.0) call fprintf(stdout,'^packets', 
  1665.      +   0,0,0,0) 
  1666.       if (debug.eq.dbgoff) call fprintf(stdout,'^off',0,0,0,0)
  1667.       call putc(nel,stdout) 
  1668.       if (debug .ne. dbgoff) then 
  1669.          call fprintf(stdout,'   ^log file: @s\n',debugfn,0,0,0)
  1670.       endif 
  1671. c     display packet settings 
  1672.       call fprintf(stdout,'\n^packet ^parameters\n',0,0,0,0)
  1673.       call fprintf(stdout,
  1674.      +   '                    ^receive   ^send\n',0,0,0,0)
  1675.       call fprintf(stdout,'  ^size:             @d        @d\n',
  1676.      +   packsiz,spksiz,0,0)
  1677.       call fprintf(stdout,'  ^timeout:          @d        @d\n',
  1678.      +   timeout,stimout,0,0) 
  1679.       call fprintf(stdout,'  ^padding:          @d',npad,0,0,0) 
  1680.       if (npad .lt. 10) call putc(blank,stdout) 
  1681.       call fprintf(stdout,'        @d\n',spad,0,0,0)
  1682.       call fprintf(stdout,'  ^pad character:    \^@c        \^@c\n',
  1683.      +   o"100".xor.(padch),o"100".xor.(spadch),0,0)
  1684.       call fprintf(stdout,'  ^end-of-^line:      \^@c        \^@c\n', 
  1685.      +   o"100".xor.(eolch),o"100".xor.(speol),0,0) 
  1686.       call fprintf(stdout,'  ^control quote:    @c         @c\n', 
  1687.      +   quotech,spquote,0,0) 
  1688.       call fprintf(stdout,'  ^start-of-^packet:  \^@c        \^@c\n', 
  1689.      +   o"100".xor.(sync),o"100".xor.(sndsync),0,0)
  1690. c     display protocol stuff
  1691.       call fprintf(stdout,'\n^delay before sending first packet: @d\n', 
  1692.      +   delayfp,0,0,0) 
  1693.       call fprintf(stdout,
  1694.      +  '^delay @d milliseconds before each ^t^t^y read\n',rdelay,0,0,0)
  1695.       call fprintf(stdout,'^init packet retry count: @d\n',maxrini,0,0, 
  1696.      +   0) 
  1697.       call fprintf(stdout,'^packet retry count: @d\n\n',maxrtry,0,0,0)
  1698.       return
  1699.       end 
  1700. *if def,ovcap 
  1701.           ident  kermsta
  1702.           entry  kermsta
  1703.           lcc    ovcap. 
  1704.           ldset  noept=unlfile
  1705.  kermsta  title  kermsta - kermit status command processor. 
  1706.           comment kermit status command processor.
  1707.  kermsta  space  4,10 
  1708. **        kermsta - kermit status command processor.
  1709.   
  1710.   
  1711.  kermsta  subr               entry/exit 
  1712.           rj     =xstatus    call the real workhorse
  1713.           eq     kermstax    return 
  1714.   
  1715.           end 
  1716. *endif
  1717.       subroutine status 
  1718.   
  1719. ccc   status - tell how long last transfer took.
  1720. *call kermcom 
  1721.       logical confirm 
  1722. c$    if (nos .eq. 1) 
  1723. c     if running under nos - issue memory status message. 
  1724.       call memstat
  1725. c$    endif 
  1726. c     confirm the command 
  1727.       if (.not. confirm(stdin)) return
  1728.       call fprintf(stdout,
  1729.      +   '^max characters in packet: @d received; @d sent\n',packsiz, 
  1730.      +   spksiz,0,0)
  1731.       if (endtim .lt. startim) endtim = endtim + 86400
  1732.       nsec = endtim - startim 
  1733.       hr = nsec / 3600
  1734.       nsec = nsec - (hr * 3600) 
  1735.       min = nsec / 60 
  1736.       nsec = nsec - (min * 60)
  1737.       call fprintf(stdout,'^number of characters transmitted in ',
  1738.      +   0,0,0,0) 
  1739.       if (hr .gt. 0) call fprintf(stdout,'@d hours ',hr,0,0,0)
  1740.       if (min .gt. 0) call fprintf(stdout,'@d minutes ',min,0,0,0)
  1741.       call fprintf(stdout,'@d seconds\n\n',nsec,0,0,0)
  1742.       call fprintf(stdout,'             ^sent:  @20d',schcnt,0,0,0) 
  1743.       call fprintf(stdout,' ^overhead:  @d\n',schovrh,0,0,0)
  1744.       call fprintf(stdout,'         ^received:  @20d',rchcnt,0,0,0) 
  1745.       call fprintf(stdout,' ^overhead:  @d\n',rchovrh,0,0,0)
  1746.       call fprintf(stdout,'^total transmitted:  @20d',schcnt+rchcnt,0,0,
  1747.      +   0) 
  1748.       call fprintf(stdout,' ^overhead:  @d\n',schovrh+rchovrh,0,0,0)
  1749.       call fprintf(stdout,
  1750.      +   '^total characters transmitted per sec: @d\n', 
  1751.      +   (schcnt+rchcnt) / (endtim-startim),0,0,0)
  1752.       call fprintf(stdout,
  1753.      +   '^effective data rate: @d baud\n', ((schcnt+rchcnt) -
  1754.      +   (schovrh+rchovrh)) / (endtim-startim) * 10,0,0,0)
  1755.       if (state .ne. c) then
  1756.          call getemsg(packet) 
  1757.          call fprintf(stdout,'?^kermit:  @s\n',packet,0,0,0)
  1758.       endif 
  1759.       return
  1760.       end 
  1761. *if def,ovcap 
  1762.           ident  kermsrv
  1763.           entry  kermsrv
  1764.           lcc    ovcap. 
  1765.           ldset  noept=unlfile
  1766.  kermsrv  title  kermsrv - kermit server-mode processor.
  1767.           comment kermit server-mode processor. 
  1768.  kermsrv  space  4,10 
  1769. **        kermsrv - kermit server-mode processor. 
  1770.   
  1771.   
  1772.  kermsrv  subr               entry/exit 
  1773.           rj     =xserver    call the real workhorse
  1774.           eq     kermsrvx    return 
  1775.   
  1776.           end 
  1777. *endif
  1778.       subroutine server 
  1779.   
  1780. ccc   server - start kermit server
  1781. c     the server currently knows about the send and receive packets 
  1782. c     and also the generic kermit packets logout and finish.  using 
  1783. c     logout can cause problem due to files not being made permanent
  1784. c     before leaving.  i suppose implementing system command packets
  1785. c     would allow files to be saved but what other kermit allows
  1786. c     system command packets and is there a standard what to
  1787. c     checkpoint programs on the cyber? 
  1788. *call kermcom 
  1789.       character*10 lfn
  1790.       logical confirm, cfe
  1791. c$    if (nos .eq. 1) 
  1792. c     if running under nos - issue memory status message. 
  1793.       call memstat
  1794. c$    endif 
  1795. c     confirm the command 
  1796.       if (.not. confirm(stdin)) return
  1797. c     initialize msg #, say no tries yet
  1798.       packnum = 0 
  1799.       numtry = 0
  1800.       call fprintf(stdout,'[^kermit server running on ^cyber host.  ^ple
  1801.      +ase type your escape sequence to\n return to your local machine. ^
  1802.      +shut down the server by typing the ^kermit ^b^y^e \n command on yo
  1803.      +ur local machine.]\n',0,0,0,0)
  1804. c$    if (nos .eq. 1) 
  1805.       call fflush(stdout) 
  1806. c$    endif 
  1807.       call stty('binary',on)
  1808.       savedpx = gtty('duplex')
  1809.       call stty('duplex',halfdup) 
  1810.     1 ptyp = rdpack(len,num,recpack)
  1811.       if (ptyp .eq. s) then 
  1812.          packnum = num
  1813.          call rdparam(recpack)
  1814.          i = sndpar(packet) 
  1815.          call sndpack(y,packnum,i,packet) 
  1816.          numtry = 0 
  1817.          packnum = mod(packnum+1,64)
  1818.          recstat = receive(f) 
  1819.          if (debug .ne. 0) then 
  1820.             if (recstat .eq. error) then
  1821.                call fprintf(debugfd,'^receive failed.\n',0,0,0,0) 
  1822.             else
  1823.                call fprintf(debugfd,'^receive completed.\n',0,0,0,0)
  1824.             endif 
  1825.          endif
  1826.       else if (ptyp .eq. r) then
  1827.             i = 0 
  1828.             call strcpy(recpack,filestr)
  1829.             call as2dpc(filestr,lfn)
  1830.             if (xvfn(lfn) .ne. 0) then
  1831.                abortyp = invfn
  1832.                call getemsg(errmsg(15)) 
  1833.                call sndpack(e,packnum,slen(errmsg),errmsg)
  1834.             else if (.not. cfe(lfn)) then 
  1835.                abortyp = notlcl 
  1836.                call getemsg(errmsg(15)) 
  1837.                call sndpack(e,packnum,slen(errmsg),errmsg)
  1838.             else
  1839.                sndstat = send() 
  1840.                packnum = 0
  1841.                if (debug .ne. 0) then 
  1842.                   if (sndstat .eq. error) then
  1843.                      call fprintf(debugfd,'^send failed.\n',0,0,0,0)
  1844.                   else
  1845.                      call fprintf(debugfd,'^send completed.\n',0,0,0,0) 
  1846.                   endif 
  1847.                endif
  1848.             endif 
  1849.       else if (ptyp .eq. g) then
  1850.             if (recpack(1) .eq. l) then 
  1851.                call sndpack(y,num,0,0)
  1852.                call logout
  1853.             else if (recpack(1) .eq. f) then
  1854.                   call sndpack(y,num,0,0) 
  1855.                   normal = .true. 
  1856.                   call exitpgm
  1857.             else
  1858.                abortyp = srvcmd 
  1859.                call getemsg(errmsg(15)) 
  1860.                call sndpack(e,packnum,slen(errmsg),errmsg)
  1861.             endif 
  1862.       else
  1863.          if (debug .ne. 0) call fprintf 
  1864.      +     (debugfd,'server: invalid packet type: @d\n',ptyp,0,0,0) 
  1865.          abortyp = invalid.or.reading.or.srvcmd 
  1866.          call getemsg(errmsg(15)) 
  1867.          call sndpack(e,packnum,slen(errmsg),errmsg)
  1868.       endif 
  1869.       go to 1 
  1870.       end 
  1871. *if def,ovcap 
  1872. *cweor
  1873. *endif
  1874. *deck kermlib 
  1875.       subroutine dmodcmd
  1876.   
  1877. ccc   dmodcmd - perform a set data-mode xxxx command. 
  1878. *call kermcom 
  1879.       logical confirm 
  1880. c$    if (ut2d .eq. 1)
  1881.       parameter (tsize=4) 
  1882. c$    endif 
  1883. c$    if (ut2d .ne. 1)
  1884.       parameter (tsize=3) 
  1885. c$    endif 
  1886.       character*15 datatyp(tsize) 
  1887. c$    if (ut2d .eq. 1)
  1888.       data datatyp /'ascii', 'display-code', 'image-ascii', 'nos-ascii'/
  1889. c$    endif 
  1890. c$    if (ut2d .ne. 1)
  1891.       data datatyp / 'ascii', 'display-code', 'image-ascii' / 
  1892. c$    endif 
  1893. c     match the parameter.
  1894.       indx = match(datatyp,tsize,.false.) 
  1895.       if (indx .le. 0) return 
  1896.       if (.not. confirm(stdin)) return
  1897. c     take the appropriate action.
  1898. c$    if (ut2d .eq. 1)
  1899.       go to (10, 20, 30, 40), indx
  1900. c$    endif 
  1901. c$    if (ut2d .ne. 1)
  1902.       go to (10, 20, 30), indx
  1903. c$    endif 
  1904. c     set ascii character set.
  1905. c$    if (ut2d .eq. 1)
  1906. 10    dskcset = dskut8
  1907. c$    endif 
  1908. c$    if (ut2d .ne. 1)
  1909. 10    dskcset = dsknos8 
  1910. c$    endif 
  1911.       return
  1912. c     set display character set.
  1913. 20    dskcset = dskdpc
  1914.       return
  1915. c     set image data mode.
  1916. 30    dskcset = dskimag 
  1917.       return
  1918.   
  1919. c$    if (ut2d .eq. 1)
  1920. c     set nos 812 ascii 
  1921. 40    dskcset = dsknos8 
  1922.       return
  1923. c$    endif 
  1924.       end 
  1925.       subroutine dbugcmd
  1926.   
  1927. ccc   dbugcmd - set the debugging modes.
  1928. *call kermcom 
  1929.       character*10 fn 
  1930.       logical confirm 
  1931.       parameter (tsize=5) 
  1932.       character*10 dbgtyp(tsize)
  1933.       data dbgtyp / 'all', 'log-file', 'off', 'packets', 'states' / 
  1934.   
  1935.       indx = match(dbgtyp,tsize,.false.)
  1936.       if (indx .le. 0) return 
  1937.       go to (10, 20, 30, 40, 50), indx
  1938. c     set all debug modes 
  1939. 10    if (.not. confirm(stdin)) return
  1940.       debug = dbgall
  1941.       go to 100 
  1942. c     set debug logfile 
  1943. 20    call setval(debugfn,'s',iret,7,0,0,hlpdbfn,.true.)
  1944.       if (iret .eq. ok) then
  1945.          if (debugfd .ne. 0) then 
  1946.             call fclose(debugfd)
  1947.             debugfd = 0 
  1948.          endif
  1949.          go to 100
  1950.       endif 
  1951.       return
  1952. c     turn off all debugging
  1953. 30    if (.not. confirm(stdin)) return
  1954.       debug = dbgoff
  1955.       if (debugfd .ne. 0) then
  1956.          call fclose(debugfd) 
  1957.          debugfd = 0
  1958.       endif 
  1959.       return
  1960. c     toggle debug packets
  1961. 40    if (.not. confirm(stdin)) return
  1962.       debug = debug .xor. dbgpack 
  1963.       go to 100 
  1964. c     toggle debug states 
  1965. 50    if (.not. confirm(stdin)) return
  1966.       debug = debug .xor. dbgstat 
  1967.       go to 100 
  1968. c     open the debug file if not done already 
  1969. 100   if (debugfd .eq. 0) then
  1970.          call as2dpc(debugfn,fn)
  1971.          debugfd = fopen(fn,wr) 
  1972.       endif 
  1973.       return
  1974.       end 
  1975.       subroutine setpack(attr)
  1976.   
  1977. ccc   set packet send or receive attributes.
  1978. c     setpack will wet the attributes of the passed attribute 
  1979. c     list.  this subroutine will set the appropriate packet
  1980. c     parameter.  the parameter to set is passed in an array
  1981. c     and is very order dependent.  see common block /packet/ 
  1982. c     for the ordering.  note that send and receive parameter 
  1983. c     ordering and storage size in the common block are 
  1984. c     identical.  keep it that way! 
  1985. *call kermcom 
  1986.       integer attr(12)
  1987.       parameter (tsize=7) 
  1988.       character*15 attrtyp(tsize) 
  1989.       data attrtyp / 'end-of-line', 'packet-length', 'pad-character', 
  1990.      +               'pad-length', 'quote-character', 'sync-character', 
  1991.      +               'time-out' / 
  1992.   
  1993.       indx = match(attrtyp,tsize,.false.) 
  1994.       if (indx .le. 0) return 
  1995.       go to (10, 20, 30, 40, 50, 60, 70), indx
  1996. c     set eol character 
  1997. 10    call setval(attr(5),'i',1,31,127,127,hlpasch,.true.)
  1998.       return
  1999. c     set maximum packet length 
  2000. 20    call setval(attr(1),'i',20,94,20,94,hlpplen,.true.) 
  2001.       return
  2002. c     set pad character 
  2003. 30    call setval(attr(4),'i',0,31,127,127,hlpasch,.true.)
  2004.       return
  2005. c     set pad length
  2006. 40    call setval(attr(3),'i',0,94,0,94,hlppadl,.true.) 
  2007.       return
  2008. c     set quote character 
  2009. 50    call setval(attr(6),'i',33,62,96,126,hlpasch,.true.)
  2010.       return
  2011. c     set sync character
  2012. 60    call setval(attr(12),'i',0,127,0,127,hlpasch,.true.)
  2013.       return
  2014. c     set timeout value 
  2015. 70    call setval(attr(2),'i',0,94,0,94,hlptimo,.true.) 
  2016.       return
  2017.       end 
  2018.       subroutine dplxcmd
  2019.   
  2020. ccc   dplxcmd - perform a set duplex xxxx command 
  2021. *call kermcom 
  2022.       logical confirm 
  2023.       parameter (tsize=2) 
  2024.       character*10 duptyp(tsize)
  2025.       data duptyp / 'full', 'half' /
  2026. c     match the parameter 
  2027.       indx = match(duptyp,tsize,.false.)
  2028.       if (indx .le. 0) return 
  2029.       if (.not. confirm(stdin)) return
  2030. c     take the appropriate action 
  2031.       go to (10, 20), indx
  2032. c     set full duplex 
  2033. 10    call stty('duplex',fulldup) 
  2034.       return
  2035. c     set half duplex 
  2036. 20    call stty('duplex',halfdup) 
  2037.       return
  2038.       end 
  2039.       subroutine parcmd 
  2040.   
  2041. ccc   parcmd - set the parity for terminal i/o. 
  2042. *call kermcom 
  2043.       logical confirm 
  2044.       parameter (tsize=5) 
  2045.       character*10 partyp(tsize)
  2046.       data partyp / 'even', 'mark', 'none', 'odd', 'space' /
  2047. c     match the parameter 
  2048.       indx = match(partyp,tsize,.false.)
  2049.       if (indx .le. 0) return 
  2050.       if (.not. confirm(stdin)) return
  2051. c     set the proper parity 
  2052.       go to (10, 20, 30, 40, 50), indx
  2053. 10    call stty('parity',even)
  2054.       return
  2055. 20    call stty('parity',mark)
  2056.       return
  2057. 30    call stty('parity',none)
  2058.       return
  2059. 40    call stty('parity',odd) 
  2060.       return
  2061. 50    call stty('parity',space) 
  2062.       return
  2063.       end 
  2064.       integer function match(table,tablen,nelok)
  2065.   
  2066. ccc   match - match input with a table of possibilities.
  2067. c     table should be an array of character strings defining what 
  2068. c     is reasonable input.  match will read input and return the
  2069. c     index of the table entry that matches or "error" if a proper
  2070. c     match couldn't be made.  matchs will fail if the input match
  2071. c     is ambiguous or doesn't match at all.  a question mark in the 
  2072. c     input will output the possible matches according to the input 
  2073. c     previously read and then return as if no match was made.
  2074. *call kermcom 
  2075.       character*(*) table(tablen) 
  2076.       logical nelok 
  2077.       character*40 word 
  2078.       integer astr(41)
  2079. c     get the word to match 
  2080.       len = getword(stdin,astr,40)
  2081.       if (len .eq. 0 .or. len .eq. eof) then
  2082.          match = len
  2083.          if (len .eq. 0 .and. .not. nelok) then 
  2084.             match = error 
  2085.             call fprintf(stdout,'?^null switch or keyword given\n',0,0, 
  2086.      +         0,0) 
  2087.          endif
  2088.          call fflush(stdin) 
  2089.          return 
  2090.       endif 
  2091.       call as2dpc(astr,word)
  2092. c     begin the matching here; tables must be in alphabetical order 
  2093.       t1 = 1
  2094.       t2 = tablen 
  2095.       chp = 1 
  2096. 10    if (chp .le. len) then
  2097. c        if we find a "?", then give the possibilities
  2098.          if (word(chp:chp) .eq. '?') then 
  2099.             call fprintf(stdout,follow,0,0,0,0) 
  2100.             call outtbl(table,t1,t2)
  2101.             call fflush(stdin)
  2102.             match = error 
  2103.             return
  2104.          endif
  2105. c        while word is less than lower table entry
  2106. 20       if (word(chp:chp) .gt. table(t1)(chp:chp) .and.
  2107.      +       t1 .le. t2) then 
  2108.             t1 = t1 + 1 
  2109.             go to 20
  2110.          endif
  2111. c        while word is greater than upper table entry 
  2112. 30       if (word(chp:chp) .lt. table(t2)(chp:chp) .and.
  2113.      +       t2 .ge. t1) then 
  2114.             t2 = t2 - 1 
  2115.             go to 30
  2116.          endif
  2117. c        if we know we have a mismatch
  2118.          if (t2 .lt. t1) then 
  2119.             call fprintf(stdout,nomatch,0,0,0,0)
  2120.             call putstr(stdout,astr)
  2121.             call fprintf(stdout,'"\n',0,0,0,0)
  2122.             call fflush(stdin)
  2123.             match = error 
  2124.             return
  2125.          endif
  2126.          chp = chp + 1
  2127.          go to 10 
  2128.       endif 
  2129. c     after looking at the whole word, is it still ambiguous? 
  2130.       if (t1 .ne. t2) then
  2131.          call fprintf(stdout,ambig,0,0,0,0) 
  2132.          call putstr(stdout,astr) 
  2133.          call fprintf(stdout,'"\n',0,0,0,0) 
  2134.          call fflush(stdin) 
  2135.          match = error
  2136.       else
  2137.          match = t1 
  2138.       endif 
  2139.       return
  2140.       end 
  2141.       subroutine outtbl(table,start,fin)
  2142.   
  2143. ccc   outtbl - output a string array in tabular format. 
  2144. *call kermcom 
  2145.       character*(*) table(fin)
  2146.       integer start, fin
  2147.   
  2148.       character*80 line 
  2149.       integer astr(81)
  2150.       integer colwid, ncols 
  2151.   
  2152.       colwid = len(table(1)) + 2
  2153.       ncols = 80 / colwid 
  2154.       line = ' '
  2155.       icol = 1
  2156.       do 100 i = start,fin
  2157.          ipos = (icol-1)*colwid + 1 
  2158.          line(ipos:) = table(i) 
  2159.          icol = icol + 1
  2160.          if (icol .gt. ncols .or. i .eq. fin) then
  2161.             call dpc2as(line,astr,len(line))
  2162. c           delete trailing blanks
  2163.             j = len(line) 
  2164. 10          if (line(j:j) .eq. ' ') then
  2165.                astr(j) = 0
  2166.                j = j - 1
  2167.                go to 10 
  2168.             endif 
  2169.             call putstr(stdout,astr)
  2170.             call putc(nel,stdout) 
  2171.             line = ' '
  2172.             icol = 1
  2173.          endif
  2174. 100   continue
  2175.       return
  2176.       end 
  2177.       subroutine setval(var,vtyp,mn1,mx1,mn2,mx2,hlpmsg,confrm) 
  2178.   
  2179. ccc   setval - set a variable value.
  2180. c     setval will read a token from input and set a variable to 
  2181. c     that value.  if the token is a question mark then the 
  2182. c     help message will be displayed and setval will return 
  2183. c     without setting a value.
  2184. c     entry:   (vtyp) = character 's' for string variable.
  2185. c                     = character 'i' for integer variable. 
  2186. c              (mn1-mx1) = range #1 for var to fit in if integer. 
  2187. c                        = mn1 is return code for error and mx1 is
  2188. c                          max size of string if string var.
  2189. c              (mn2-mx2) = secondary range for var to fit in if 
  2190. c                          integer var. 
  2191. c                        = unused for string var. 
  2192. c              (hlpmsg) = fprintf message format to display if
  2193. c                       a question mark is read.
  2194. c     exit:    (var) = int value read if integer var. or string 
  2195. c                      value read if string var.
  2196. *call kermcom 
  2197.       character*(*) vtyp, hlpmsg
  2198.       integer var(41), str(41)
  2199.       logical confrm, confirm 
  2200. c     check var type
  2201.       if (vtyp .ne. 's' .and. vtyp .ne. 'i') then 
  2202.          call fprintf(stdout,'setval - invalid var type @c\n',asc(vtyp),
  2203.      +      0,0,0)
  2204.          return 
  2205.       endif 
  2206.       if (vtyp .eq. 's' .and. mx1 .gt. 40) then 
  2207.          call fprintf(stdout,'setval - string max of @d is too large\n',
  2208.      +      mx1,0,0,0)
  2209.          return 
  2210.       endif 
  2211.       len = getword(stdin,str,mx1)
  2212.       if (len .eq. 0 .or. len .eq. eof) then
  2213.          if (vtyp .eq. 'i') then
  2214.             call fprintf(stdout,nodigit,0,0,0,0)
  2215.          else 
  2216.             call fprintf(stdout,missing,0,0,0,0)
  2217.             mn1 = error 
  2218.          endif
  2219.          return 
  2220.       endif 
  2221.       if (str(1) .eq. qmark) then 
  2222.          call fprintf(stdout,hlpmsg,0,0,0,0)
  2223.          call fflush(stdin) 
  2224.          if (vtyp .eq. 's') mn1 = error 
  2225.          return 
  2226.       endif 
  2227. c     confirm the request if necessary
  2228.       if (confrm) then
  2229.          if (.not. confirm(stdin)) then 
  2230.             if (vtyp .eq. 's') mn1 = error
  2231.             return
  2232.          endif
  2233.       endif 
  2234. c     go ahead and set the variable 
  2235.       if (vtyp .eq. 'i') then 
  2236.          i = ctoi(str)
  2237.          if (i .ge. mn1 .and. i .le. mx1) then
  2238.             var(1) = i
  2239.          else if (i .ge. mn2 .and. i .le. mx2) then 
  2240.             var(2) = i
  2241.          else 
  2242.             call fprintf(stdout,
  2243.      +         '?^value is not within range of @d - @d',
  2244.      +         mn1,mx1,0,0) 
  2245.             if (mn1 .ne. mn2 .or. mx1 .ne. mx2) call fprintf(stdout,
  2246.      +         ' or @d - @d',mn2,mx2,0,0) 
  2247.             call putc(nel,stdout) 
  2248.          endif
  2249.       else
  2250.          do 100 i = 1,len 
  2251.             var(i) = str(i) 
  2252. 100      continue 
  2253.          var(len+1) = 0 
  2254.          mn1 = ok 
  2255.       endif 
  2256.       return
  2257.       end 
  2258.       logical function confirm(fd)
  2259.   
  2260. ccc   confirm - look for a newline. 
  2261. c     confirm will expect that the next token of input be a 
  2262. c     newline for confirmation to be true.  if the next token 
  2263. c     is a question mark, then confirmation is false and
  2264. c     a "confirm with a carriage return" message will be displayed. 
  2265. c     any other text will cause a 'not confirmed "text"' message
  2266. c     to be displayed and confirm will return false.
  2267. *call kermcom 
  2268. c     get leading blanks til a token is found 
  2269.       confirm = .false. 
  2270. 10    if (getc(fd,ch) .eq. nel) then
  2271.          confirm = .true. 
  2272.       else if (ch .eq. eof) then
  2273.          return 
  2274.       else if (ch .eq. blank .or. ch .eq. tab) then 
  2275.          go to 10 
  2276.       else if (ch .eq. qmark) then
  2277.          call fprintf(stdout,confmsg,0,0,0,0) 
  2278.       else
  2279.          call fprintf(stdout,notconf,0,0,0,0) 
  2280. 20       call putc(ch,stdout) 
  2281.          ch = getc(fd,ch) 
  2282.          if (ch .ne. nel .and. ch .ne. eof) go to 20
  2283.          call fprintf(stdout,'"\n',0,0,0,0) 
  2284.       endif 
  2285.       return
  2286.       end 
  2287.       subroutine logout 
  2288.   
  2289. ccc   logout - log out the job
  2290. c     this is site dependent. 
  2291. *call kermcom 
  2292.       iret = error
  2293. c$    if (ut2d .eq. 1)
  2294.       call bellc(l"logout",0,iret)
  2295. c$    endif 
  2296. c$    if(nosbe .eq. 1)
  2297.       if(savedpx .ne. halfdup) call stty('duplex',fulldup)
  2298.       call excst('logout.') 
  2299. c$    endif 
  2300. c$    if(nos .eq. 1)
  2301. c$    if(noslvl .ge. 596) 
  2302.       if(savedpx .ne. halfdup) call stty('duplex',fulldup)
  2303.       call excst('logout.') 
  2304. c$    endif 
  2305. c$    endif 
  2306.       if (iret .ne. 0) call displa('logout error',iret) 
  2307.       return
  2308.       end 
  2309.       integer function receive(istate)
  2310.   
  2311. ccc   receive - receive file state switching routine. 
  2312. *call kermcom 
  2313. c     initialize statistics variables 
  2314.       call getnow(mm,dd,yy,hr,min,sec)
  2315.       startim = hr * 3600 + min * 60 + sec
  2316.       schcnt = 0
  2317.       rchcnt = 0
  2318.       schovrh = 0 
  2319.       rchovrh = 0 
  2320. c     set packet retry count & current state
  2321.       numtry = 0
  2322.       state = istate
  2323. c     take appropriate action for the current state 
  2324. 10    if (state .eq. d) then
  2325.          state = rdata()
  2326.       else if (state .eq. f) then 
  2327.          state = rfile()
  2328.       else if (state .eq. r) then 
  2329.          state = rinit()
  2330.       else if (state .eq. c) then 
  2331.          call getnow(mm,dd,yy,hr,min,sec) 
  2332.          endtim = hr * 3600 + min * 60 + sec
  2333.          receive = ok 
  2334.          return 
  2335.       else if (state .eq. e) then 
  2336.          receive = error
  2337.          if (ffd .ne. closed) then
  2338.             call fclose(ffd)
  2339.             call remove(filestr)
  2340.          endif
  2341.          return 
  2342.       else if (state .eq. a) then 
  2343.          call getnow(mm,dd,yy,hr,min,sec) 
  2344.          endtim = hr * 3600 + min * 60 + sec
  2345.          receive = error
  2346.          if (ffd .ne. closed) then
  2347.             call fclose(ffd)
  2348.             call remove(filestr)
  2349.          endif
  2350.          call getemsg(errmsg(15)) 
  2351.          call sndpack(e,packnum,slen(errmsg),errmsg)
  2352.          return 
  2353.       else
  2354.          call displa(' receive - state error = ',state) 
  2355.          if (ffd .ne. closed) call fclose(ffd)
  2356.          receive = error
  2357.          return 
  2358.       endif 
  2359.       if ((debug.and.dbgstat).ne.0) then
  2360.          call fprintf(debugfd,'@c@2d ',state,packnum,0,0) 
  2361.          if (mod(packnum+1,16) .eq. 0) call putc(nel,debugfd) 
  2362.       endif 
  2363.       go to 10
  2364.       end 
  2365.       integer function rinit()
  2366.   
  2367. ccc   rinit - receive a send-init packet. 
  2368. *call kermcom 
  2369. c     clean out filestr array so remove does not do dire things 
  2370. c     to the previously received file if we die before we get 
  2371. c     the new file specification. 
  2372.       do 10 i = 1, maxpack
  2373.           filestr(i) = 0
  2374. 10    continue
  2375. c     check retry count 
  2376.       if (numtry .gt. maxrini) then 
  2377.          rinit = a
  2378.          abortyp = toomany.or.reading.or.initerr
  2379.          return 
  2380.       endif 
  2381.       numtry = numtry + 1 
  2382. c     read a packet and hope for the best 
  2383.       ptyp = rdpack(len,num,packet) 
  2384. c     is it a valid packet type?
  2385.       if (ptyp .eq. s) then 
  2386.          packnum = num
  2387.          call rdparam(packet) 
  2388.          len = sndpar(packet) 
  2389.          call sndpack(y,num,len,packet) 
  2390.          numtry = 0 
  2391.          packnum = mod(packnum+1,64)
  2392.          rinit = f
  2393. c     did we get a checksum error 
  2394.       else if (ptyp .eq. error) then
  2395.          rinit = state
  2396.          call sndpack(n,num,0,0)
  2397.       else
  2398.          rinit = a
  2399.          abortyp = invalid.or.reading.or.initerr
  2400.       endif 
  2401.       return
  2402.       end 
  2403.       integer function rfile()
  2404.   
  2405. ccc   rfile  read a filename packet.
  2406. c     rfile expects to see a filename (type f) packet.  however, it may 
  2407. c     find a send-init retry, end-of-file retry or break packet.
  2408. *call kermcom 
  2409.       if (numtry .gt. maxrtry) then 
  2410.          rfile = a
  2411.          abortyp = toomany.or.reading.or.filerr 
  2412.          return 
  2413.       endif 
  2414.       numtry = numtry + 1 
  2415. c     read a packet 
  2416.       ptyp = rdpack(len,num,packet) 
  2417. c     is it a filename packet?
  2418.       if (ptyp .eq. f) then 
  2419.          if (num .ne. packnum) then 
  2420.             rfile = a 
  2421.             abortyp = seqerr.or.reading.or.filerr 
  2422.             return
  2423.          endif
  2424.          ffd = creat(packet)
  2425.          if (ffd .eq. error) then 
  2426.             ffd = closed
  2427.             rfile = a 
  2428.             abortyp = lclfile.or.reading.or.filerr
  2429.          else 
  2430.             if (debug .ne. 0) call fprintf(debugfd, 
  2431.      +         '^receiving file @s\n',packet,0,0,0) 
  2432.             call strcpy(packet,filestr) 
  2433.             call sndpack(y,num,0,0) 
  2434.             numtry = 0
  2435.             packnum = mod(packnum+1,64) 
  2436.             rfile = d 
  2437.          endif
  2438. c     is it an old send-init packet 
  2439.       else if (ptyp .eq. s) then
  2440.          if (mod(num+1,64) .eq. packnum) then 
  2441.             len = sndpar(packet)
  2442.             call sndpack(y,num,len,packet)
  2443.             numtry = 0
  2444.             rfile = state 
  2445.          else 
  2446.             rfile = a 
  2447.             abortyp = seqerr.or.reading.or.initerr
  2448.          endif
  2449. c     is it an old eof packet?
  2450.       else if (ptyp .eq. z) then
  2451.          if (mod(num+1,64) .eq. packnum) then 
  2452.             call sndpack(y,num,0,0) 
  2453.             numtry = 0
  2454.             rfile = state 
  2455.          else 
  2456.             rfile = a 
  2457.             abortyp = seqerr.or.reading.or.eoferr 
  2458.          endif
  2459. c     is it a break packet? 
  2460.       else if (ptyp .eq. b) then
  2461.          if (num .ne. packnum) then 
  2462.             rfile = a 
  2463.             abortyp = seqerr.or.reading.or.brkerr 
  2464.          else 
  2465.             call sndpack(y,packnum,0,0) 
  2466.             rfile = c 
  2467.          endif
  2468. c     did we get an error packet? 
  2469.       else if (ptyp .eq. e) then
  2470.          rfile = e
  2471.          return 
  2472. c     did we get a checksum error?
  2473.       else if (ptyp .eq. error) then
  2474.          rfile = state
  2475.          call sndpack(n,num,0,0)
  2476. c     invalid packet type, so abort 
  2477.       else
  2478.          rfile = a
  2479.          abortyp = invalid.or.reading.or.filerr 
  2480.       endif 
  2481.       return
  2482.       end 
  2483.       integer function rdata()
  2484.   
  2485. ccc   rdata - read a data packet. 
  2486. *call kermcom 
  2487. c     check retry count 
  2488.       if (numtry .gt. maxrtry) then 
  2489.          rdata = a
  2490.          abortyp = toomany.or.reading.or.dataerr
  2491.          return 
  2492.       endif 
  2493.       numtry = numtry + 1 
  2494. c     read a packet 
  2495.       ptyp = rdpack(len,num,packet) 
  2496. c     did we get a data packet? 
  2497.       if (ptyp .eq. d) then 
  2498.          if (num .ne. packnum) then 
  2499.             if (mod(num+1,64) .eq. packnum) then
  2500.                call sndpack(y,num,0,0)
  2501.                rdata = state
  2502.             else
  2503.                rdata = a
  2504.                abortyp = seqerr.or.reading.or.dataerr 
  2505.             endif 
  2506.          else 
  2507.             call bufemp(packet,ffd,len) 
  2508.             call sndpack(y,packnum,0,0) 
  2509.             numtry = 0
  2510.             packnum = mod(packnum+1,64) 
  2511.             rdata = state 
  2512.          endif
  2513. c     is it an old filename packet? 
  2514.       else if (ptyp .eq. f) then
  2515.          if (mod(num+1,64) .eq. packnum) then 
  2516.             call sndpack(y,num,0,0) 
  2517.             numtry = 0
  2518.             rdata = state 
  2519.          else 
  2520.             rdata = a 
  2521.             abortyp = seqerr.or.reading.or.filerr 
  2522.          endif
  2523. c     is it an eof packet?
  2524.       else if (ptyp .eq. z) then
  2525.          if (num .ne. packnum) then 
  2526.             rdata = a 
  2527.             abortyp = seqerr.or.reading.or.eoferr 
  2528.          else 
  2529.             call sndpack(y,packnum,0,0) 
  2530.             call fclose(ffd)
  2531.             ffd = 0 
  2532.             packnum = mod(packnum+1,64) 
  2533.             rdata = f 
  2534.          endif
  2535. c     did we get an error packet? 
  2536.       else if (ptyp .eq. e) then
  2537.          rdata = e
  2538.          return 
  2539.       else if (ptyp .eq. error) then
  2540.          rdata = state
  2541.          call sndpack(n,num,0,0)
  2542.       else
  2543.          rdata = a
  2544.          abortyp = invalid.or.reading.or.dataerr
  2545.       endif 
  2546.       return
  2547.       end 
  2548.       integer function send() 
  2549.   
  2550. ccc   send - send file state switching routine
  2551. c     the filename to send is assumed to have already been
  2552. c     obtained and set in ascii string buffer filestr.
  2553. *call kermcom 
  2554. c     initialize statics variables
  2555.       call getnow(mm,dd,yy,hr,min,sec)
  2556.       startim = hr * 3600 + min * 60 + sec
  2557.       schcnt = 0
  2558.       rchcnt = 0
  2559.       schovrh = 0 
  2560.       rchovrh = 0 
  2561.       state = s 
  2562.       numtry = 0
  2563. c     take appropriate action for the current state 
  2564. 10    if (state .eq. d) then
  2565.          state = sdata()
  2566.       else if (state .eq. f) then 
  2567.          state = sfile()
  2568.       else if (state .eq. z) then 
  2569.          state = seof() 
  2570.       else if (state .eq. s) then 
  2571.          state = sinit()
  2572.       else if (state .eq. b) then 
  2573.          state = sbreak() 
  2574.       else if (state .eq. c) then 
  2575.          call getnow(mm,dd,yy,hr,min,sec) 
  2576.          endtim = hr * 3600 + min * 60 + sec
  2577.          send = ok
  2578.          return 
  2579.       else if (state .eq. e) then 
  2580.          call getnow(mm,dd,yy,hr,min,sec) 
  2581.          endtim = hr * 3600 + min * 60 + sec
  2582.          send = error 
  2583.          if (ffd .ne. closed) call fclose(ffd)
  2584.          return 
  2585.       else if (state .eq. a) then 
  2586.          call getnow(mm,dd,yy,hr,min,sec) 
  2587.          endtim = hr * 3600 + min * 60 + sec
  2588.          send = error 
  2589.          if (ffd .ne. closed) call fclose(ffd)
  2590.          call getemsg(errmsg(15)) 
  2591.          call sndpack(e,packnum,slen(errmsg),errmsg)
  2592.          return 
  2593.       else
  2594.          call displa(' send - state error = ',state)
  2595.          send = error 
  2596.          if (ffd .ne. closed) call fclose(ffd)
  2597.          return 
  2598.       endif 
  2599.       if ((debug.and.dbgstat).ne.0) then
  2600.          call fprintf(debugfd,'@c@2d ',state,packnum,0,0) 
  2601.          if (mod(packnum+1,16) .eq. 0) call putc(nel,debugfd) 
  2602.       endif 
  2603.       go to 10
  2604.       end 
  2605.       integer function sinit()
  2606.   
  2607. ccc   sinit - send the send-init packet and wait for reply. 
  2608. c     assumes filestr has already been checked for legal filename 
  2609. c     and being local.
  2610. *call kermcom 
  2611.       character*10 filenam
  2612. c     check number of retries 
  2613.       if (numtry .gt. maxrini) then 
  2614.          sinit = a
  2615.          abortyp = toomany.or.sending.or.initerr
  2616.          return 
  2617.       endif 
  2618.       numtry = numtry + 1 
  2619. c     send the send-init packet with the right info 
  2620.       len = sndpar(packet)
  2621.       call sndpack(s,packnum,len,packet)
  2622. c     pick up and process the reply 
  2623.       ptyp = rdpack(len,num,recpack)
  2624.       if (ptyp .eq. n) then 
  2625.          sinit = state
  2626.          return 
  2627.       else if (ptyp .eq. y) then
  2628.          if (packnum .ne. num) then 
  2629.             sinit = state 
  2630.             return
  2631.          endif
  2632.          call rdparam(recpack)
  2633.          numtry = 0 
  2634.          packnum = mod(packnum+1,64)
  2635.          call as2dpc(filestr,filenam) 
  2636.          ffd = fopen(filenam,rd)
  2637.          if (ffd .eq. error) then 
  2638.             sinit = a 
  2639.             ffd = closed
  2640.          else 
  2641.             sinit = f 
  2642.          endif
  2643. c     did we get an error packet? 
  2644.       else if (ptyp .eq. e) then
  2645.          sinit = e
  2646.          return 
  2647.       else if (ptyp .eq. error) then
  2648.          sinit = state
  2649.       else
  2650.          sinit = a
  2651.          abortyp = invalid.or.sending.or.initerr
  2652.       endif 
  2653.       return
  2654.       end 
  2655.       integer function sfile()
  2656.   
  2657. ccc   sfile - send a filename packet and wait for reply.
  2658. c     the filename is assumed to have been previously obtained
  2659. c     and stored in the ascii string buffer filestr in upper case.
  2660. *call kermcom 
  2661. c     have we tried this too many times?
  2662.       if (numtry .gt. maxrtry) then 
  2663.          sfile = a
  2664.          abortyp = toomany.or.sending.or.filerr 
  2665.          return 
  2666.       endif 
  2667.       numtry = numtry + 1 
  2668. c     send the filename packet
  2669.       call sndpack(f,packnum,slen(filestr),filestr) 
  2670. c     check on the reply
  2671.       ptyp = rdpack(len,num,recpack)
  2672.       if (ptyp .eq. n) then 
  2673.          if (mod(packnum+1,64) .ne. num) then 
  2674.             sfile = state 
  2675.             return
  2676.          else 
  2677.             ptyp = y
  2678.             num = num - 1 
  2679.          endif
  2680.       endif 
  2681.       if (ptyp .eq. y) then 
  2682.          if (packnum .ne. num) then 
  2683.             sfile = state 
  2684.             return
  2685.          endif
  2686.          numtry = 0 
  2687.          packnum = mod(packnum+1,64)
  2688. c        get first packet of data from the file 
  2689.          psize = buffill(ffd,packet)
  2690.          sfile = d
  2691. c     did we get an error packet? 
  2692.       else if (ptyp .eq. e) then
  2693.          sfile = e
  2694.          return 
  2695.       else if (ptyp .eq. error) then
  2696.          sfile = state
  2697.       else
  2698.          sfile = a
  2699.          abortyp = invalid.or.sending.or.filerr 
  2700.       endif 
  2701.       return
  2702.       end 
  2703.       integer function sdata()
  2704.   
  2705. ccc   sdata - send a data packet and wait for reply.
  2706. *call kermcom 
  2707. c     have we tried this too many times?
  2708.       if (numtry .gt. maxrtry) then 
  2709.          sdata = a
  2710.          abortyp = toomany.or.sending.or.dataerr
  2711.          return 
  2712.       endif 
  2713.       numtry = numtry + 1 
  2714. c     send the current data buffer
  2715.       if (psize .eq. eof) then
  2716.          sdata = z
  2717.          return 
  2718.       endif 
  2719.       call sndpack(d,packnum,psize,packet)
  2720. c     check on the reply
  2721.       ptyp = rdpack(len,num,recpack)
  2722.       if (ptyp .eq. n) then 
  2723.          if (mod(packnum+1,64) .ne. num) then 
  2724.             sdata = state 
  2725.             return
  2726.          else 
  2727.             ptyp = y
  2728.             num = num - 1 
  2729.          endif
  2730.       endif 
  2731.       if (ptyp .eq. y) then 
  2732.          if (packnum .ne. num) then 
  2733.             sdata = state 
  2734.             return
  2735.          endif
  2736.          numtry = 0 
  2737.          packnum = mod(packnum+1,64)
  2738.          psize = buffill(ffd,packet)
  2739.          if (psize .eq. eof) then 
  2740.             sdata = z 
  2741.          else 
  2742.             sdata = state 
  2743.          endif
  2744. c     did we get an error packet? 
  2745.       else if (ptyp .eq. e) then
  2746.          sdata = e
  2747.          return 
  2748.       else if (ptyp .eq. error) then
  2749.          sdata = state
  2750.       else
  2751.          sdata = a
  2752.          abortyp = invalid.or.sending.or.dataerr
  2753.       endif 
  2754.       return
  2755.       end 
  2756.       integer function seof() 
  2757.   
  2758. ccc   seof - send an eof packet and wait for the reply. 
  2759. *call kermcom 
  2760. c     have we tried this too many times?
  2761.       if (numtry .gt. maxrtry) then 
  2762.          seof = a 
  2763.          abortyp = toomany.or.sending.or.eoferr 
  2764.          return 
  2765.       endif 
  2766.       numtry = numtry + 1 
  2767. c     send the eof packet 
  2768.       call sndpack(z,packnum,0,0) 
  2769. c     check the reply 
  2770.       ptyp = rdpack(len,num,recpack)
  2771.       if (ptyp .eq. n) then 
  2772.          if (mod(packnum+1,64) .ne. num) then 
  2773.             seof = state
  2774.             return
  2775.          else 
  2776.             ptyp = y
  2777.             num = num - 1 
  2778.          endif
  2779.       endif 
  2780.       if (ptyp .eq. y) then 
  2781.          if (packnum .ne. num) then 
  2782.             seof = state
  2783.             return
  2784.          endif
  2785.          numtry = 0 
  2786.          packnum = mod(packnum+1,64)
  2787.          call fclose(ffd) 
  2788.          seof = b 
  2789. c     did we get an error packet? 
  2790.       else if (ptyp .eq. e) then
  2791.          seof = e 
  2792.          return 
  2793.       else if (ptyp .eq. error) then
  2794.          seof = state 
  2795.       else
  2796.          seof = a 
  2797.          abortyp = invalid.or.sending.or.eoferr 
  2798.       endif 
  2799.       return
  2800.       end 
  2801.       integer function sbreak() 
  2802.   
  2803. ccc   sbreak - send the break packet and wait for reply.
  2804. *call kermcom 
  2805. c     have we tried this too many times?
  2806.       if (numtry .gt. maxrtry) then 
  2807.          sbreak = a 
  2808.          abortyp = toomany.or.sending.or.brkerr 
  2809.          return 
  2810.       endif 
  2811.       numtry = numtry + 1 
  2812. c     send the break packet 
  2813.       call sndpack(b,packnum,0,0) 
  2814. c     check on the reply
  2815.       ptyp = rdpack(len,num,recpack)
  2816.       if (ptyp .eq. n) then 
  2817.          if (mod(packnum+1,64) .ne. num) then 
  2818.             sbreak = state
  2819.             return
  2820.          else 
  2821.             ptyp = y
  2822.             num = num - 1 
  2823.          endif
  2824.       endif 
  2825.       if (ptyp .eq. y) then 
  2826.          if (packnum .ne. num) then 
  2827.             sbreak = state
  2828.             return
  2829.          endif
  2830.          numtry = 0 
  2831.          packnum = mod(packnum+1,64)
  2832.          sbreak = c 
  2833. c     did we get an error packet? 
  2834.       else if (ptyp .eq. e) then
  2835.          sbreak = e 
  2836.          return 
  2837.       else if (ptyp .eq. error) then
  2838.          sbreak = state 
  2839.       else
  2840.          sbreak = a 
  2841.          abortyp = invalid.or.sending.or.brkerr 
  2842.       endif 
  2843.       return
  2844.       end 
  2845.       subroutine sndpack(type,num,len,data) 
  2846.   
  2847. ccc   sndpack - send a packet down an output stream 
  2848. c     sndpack will send a packet of information and log it
  2849. c     if debug is turned on.  this subroutine could be made 
  2850. c     more efficient by not calling a subroutine for each 
  2851. c     character, but that might cause portability problems. 
  2852. *call kermcom 
  2853.       integer data(200) 
  2854. c     define the tochar statement function
  2855.       tochar(ascch) = ascch + blank 
  2856.   
  2857.       if ((debug.and.dbgpack).ne.0) call fprintf(debugfd,'^sending...', 
  2858.      +   0,0,0,0) 
  2859. c     put out pad chars 
  2860.       do 100 i = 1,spad 
  2861.          call putc(spadch,ofd)
  2862.          if ((debug.and.dbgpack).ne.0) then 
  2863.             call putc(spadch,debugfd) 
  2864.          endif
  2865. 100   continue
  2866.       call putc(sndsync,ofd)
  2867. c     packet len assumes one character checksums
  2868.       chksum = tochar(len+3)
  2869.       call putc(chksum,ofd) 
  2870.       tmp = tochar(num) 
  2871.       chksum = chksum + tmp 
  2872.       call putc(tmp,ofd)
  2873.       chksum = chksum + type
  2874.       call putc(type,ofd) 
  2875.       do 110 i = 1,len
  2876.          chksum = chksum + (data(i) .and. o"377") 
  2877.          call putc(data(i),ofd) 
  2878. 110   continue
  2879.       chksum = (chksum + (chksum.and.o"300") / o"100") .and. o"77"
  2880.       call putc(tochar(chksum),ofd) 
  2881.       call putc(speol,ofd)
  2882.       if ((debug.and.dbgpack).ne.0) then
  2883.          call putc(sndsync,debugfd) 
  2884.          call putc(tochar(len+3),debugfd) 
  2885.          call putc(tochar(num),debugfd) 
  2886.          call putc(type,debugfd)
  2887.          if (len .gt. 0) call putstr(debugfd,data)
  2888.          call putc(tochar(chksum),debugfd)
  2889.          call putc(speol,debugfd) 
  2890.          call putc(nel,debugfd) 
  2891.       endif 
  2892.   
  2893. c     force buffer flush since desired eol char won't.  under nos/be, 
  2894. c     scope, and (i suspect) nos, we need 12 bits of zero in the
  2895. c     low order 12 bits of a word to be the eol, or the data gets left
  2896. c     in an intercom small buffer till the eol (or a writer) comes
  2897. c     along.  the conditional code adds a 60 bit eol in the case
  2898. c     where the data is a multiple of 5 characters.  in all other 
  2899. c     cases the eol is present, as the word was zeroed before any 
  2900. c     data was put in it. 
  2901.   
  2902.       if(fwshft(ofd) .eq. 0) then 
  2903.           fwshft(ofd) = 48
  2904.           fnwds(ofd) = fnwds(ofd) + 1 
  2905.           fchbuf(fnwds(ofd),ofd) = 0
  2906.       endif 
  2907.       call fflush(ofd)
  2908. c     update the statistics 
  2909.       nch = spad + 5 + len + 1
  2910.       schcnt = schcnt + nch 
  2911.       schovrh = schovrh + nch - len 
  2912.       return
  2913.       end 
  2914.       integer function rdpack(len,num,data) 
  2915.   
  2916. ccc   rdpack - read a packet of information.
  2917. c     rdpack will read a packet of data and return the packet type
  2918. c     as a result.  if the packet contains an error (checksum) then 
  2919. c     error will be returned.  len, num, and data will be set according 
  2920. c     to the fields of the packet.
  2921. *call kermcom 
  2922.       integer data(*) 
  2923. c     define the unchar statement function
  2924.       unchar(ascch) = ascch - blank 
  2925. c     is debug packets turned on? 
  2926.       if ((debug.and.dbgpack).ne.0) then
  2927.          call fprintf(debugfd,'^reading...',0,0,0,0)
  2928.       endif 
  2929.       nch = 0 
  2930. c     hunt for the start of packet
  2931. 10    if(getc(ifd,ch) .eq. eof) then
  2932.           call remark(' rdpack - found unexpected eof.')
  2933.           call abtp("nd") 
  2934.       endif 
  2935.       nch = nch + 1 
  2936.       if ((debug.and.dbgpack).ne.0) call putc(ch,debugfd) 
  2937.       if (ch .ne. sync) go to 10
  2938.       chksum = 0
  2939.       len = 0 
  2940. c     parse each field of the packet
  2941. c     for (field=1; field <= 5; field++)
  2942.       field = 1 
  2943. 20    if (field .le. 5) then
  2944. c        a character read in field 4 here is the first char of the
  2945. c        data field or the checksum character if the data field is empty
  2946.          if (field .ne. 5 .or. len .gt. 0) then 
  2947.             if(getc(ifd,ch) .eq. eof) then
  2948.                call remark(' rdpack - found unexpected eof.') 
  2949.                call abtp("nd")
  2950.             endif 
  2951.             if (ch .eq. sync) field = 0 
  2952.             nch = nch + 1 
  2953.             if ((debug.and.dbgpack).ne.0) call putc(ch,debugfd) 
  2954.          endif
  2955.          if (field .le. 3) chksum = chksum + ch 
  2956. c        if resync
  2957.          if (field .eq. 0) then 
  2958.             chksum = 0
  2959.             if ((debug.and.dbgpack).ne.0) then
  2960.                call fprintf(debugfd,'\n^reading...@c',sync,0,0,0) 
  2961.             endif 
  2962. c        if data length 
  2963.          else if (field .eq. 1) then
  2964.             len = unchar(ch-3)
  2965. c        if packet number 
  2966.          else if (field .eq. 2) then
  2967.             num = unchar(ch)
  2968. c        if packet type 
  2969.          else if (field .eq. 3) then
  2970.             type = ch 
  2971. c        if data field is not empty 
  2972.          else if (field .eq. 4 .and. len .gt. 0) then 
  2973. c           read 2nd-len chars of data & checksum char
  2974.             do 100 i = 1,len
  2975.                if (i .gt. 1) then 
  2976.                   ch = getc(ifd,ch) 
  2977.                   if(ch .eq. eof) then
  2978.                      call remark(' rdpack - found unexpected eof.') 
  2979.                      call abtp("nd")
  2980.                   endif 
  2981.                   nch = nch + 1 
  2982.                   if (ch .eq. sync) then
  2983.                      field = 0
  2984.                      go to 20 
  2985.                   endif 
  2986.                   if ((debug.and.dbgpack).ne.0) call putc(ch,debugfd) 
  2987.                endif
  2988.                chksum = chksum + ch 
  2989.                data(i) = ch 
  2990. 100         continue
  2991. c        if chksum char 
  2992.          else if (field .eq. 5) then
  2993.             data(len+1) = 0 
  2994.             chksum = (chksum + ((chksum .and. o"300") / o"100"))
  2995.      +               .and. o"77"
  2996.          endif
  2997. c     process next packet field 
  2998.          field = field + 1
  2999.          go to 20 
  3000.       endif 
  3001.       if ((debug.and.dbgpack).ne.0) call putc(nel,debugfd)
  3002. c     does the checksum match?
  3003.       if (chksum .ne. unchar(ch)) then
  3004.          rdpack = error 
  3005.          rchovrh = rchovrh + nch
  3006.          if (debug .ne. 0) then 
  3007.             call fprintf(debugfd,'chksum error, found @d needed @d\n',
  3008.      +                   unchar(ch),chksum,0,0) 
  3009.          endif
  3010.       else
  3011.          rdpack = type
  3012.          rchovrh = rchovrh + nch - len
  3013.       endif 
  3014.       rchcnt = rchcnt + nch 
  3015. c     flush any end-of-line characters and other garbage
  3016.       call fflush(ifd)
  3017.       return
  3018.       end 
  3019.       integer function buffill(fd,buffer) 
  3020.   
  3021. ccc   buffill - get some data to send.
  3022. c     buffill reads from the file to send and performs all
  3023. c     the proper escaping of control characters and mapping 
  3024. c     newlines into crlf sequences.  if it ever gets smart
  3025. c     enough, it will also do the 8 bit quoting and repeat
  3026. c     counts. 
  3027. c *** note: this algorithm assumes 5 overhead characters for the
  3028. c     packet and leaves 3 characters in case the last character 
  3029. c     to buffer is a nel (expands to 4 characters). 
  3030. *call kermcom 
  3031.       boolean buffer(*) 
  3032. c     define ctl statement function 
  3033.       ctl(ascch) = ascch .xor. o"100" 
  3034. c     get a packet worth of data
  3035.       i = 0 
  3036. 10    if (getc(fd,ch) .ne. eof) then
  3037.          if(ch .eq. null) ch = 0
  3038.          tch = ch .and. o"177"
  3039.          if (tch.lt.blank .or. tch.eq.del .or. tch.eq.spquote) then 
  3040.             if (ch .eq. nel .and. dskcset .ne. dskimag) then
  3041.                buffer(i+1) = spquote
  3042.                buffer(i+2) = ctl(cr)
  3043.                i = i + 2
  3044.                ch = lf
  3045.             endif 
  3046.             i = i + 1 
  3047.             buffer(i) = spquote 
  3048.             if (tch.lt.blank .or. tch.eq.del) ch = ctl(ch)
  3049.          endif
  3050.          i = i + 1
  3051.          buffer(i) = ch 
  3052.          if (i .ge. spksiz-8) then
  3053.             buffill = i 
  3054.             go to 99
  3055.          endif
  3056.          go to 10 
  3057.       endif 
  3058.       if (i .eq. 0) then
  3059.          buffill = eof
  3060.       else
  3061.          buffill = i
  3062.       endif 
  3063. 99    buffer(i+1) = 0 
  3064.       return
  3065.       end 
  3066.       subroutine bufemp(buffer,fd,len)
  3067.   
  3068. ccc   bufemp - dump a buffer to a file. 
  3069. *call kermcom 
  3070.       boolean buffer(*), ch, prevch 
  3071.       save prevch 
  3072.       data prevch / -1 /
  3073. c     define ctl statement function 
  3074.       ctl(ascch) = ascch .xor. o"100" 
  3075. c     write the packet data to the file 
  3076.       i = 1 
  3077. 10    if (i .le. len) then
  3078.          ch = buffer(i) 
  3079.          if (ch .eq. quotech) then
  3080.             i = i + 1 
  3081.             ch = buffer(i)
  3082.             tch = ch .and. o"177" 
  3083.             if ((ctl(tch).lt.blank).or.(ctl(tch).eq.del)) ch = ctl(ch)
  3084.             if(ch .eq. 0) ch = null 
  3085.          endif
  3086. c     if image transfer, do not convert things. 
  3087.          if(dskcset .eq. dskimag) then
  3088.             call putc(ch,fd)
  3089.          else 
  3090. c     convert cr/lf pair to nel (205b)
  3091.             if (ch .eq. lf .and. prevch .eq. cr) then 
  3092.                ch = nel 
  3093. c     just a lone cr
  3094.             else if (prevch .eq. cr) then 
  3095.                call putc(prevch,fd) 
  3096.             endif 
  3097.             if (ch .ne. cr) call putc(ch,fd)
  3098.             prevch = ch 
  3099.          endif
  3100.          i = i + 1
  3101.          go to 10 
  3102.       endif 
  3103.       return
  3104.       end 
  3105.       integer function fopen(fn,mode) 
  3106.   
  3107. ccc   fopen - pretend to open a file for i/o. 
  3108. c     fopen just assigns a file desciptor (integer index) to
  3109. c     a file name.  no opening of the file is really performed
  3110. c     since this is done automatically by iop.
  3111. *call kermcom 
  3112.       character*10 fn 
  3113.       logical cfe 
  3114. c     check for valid parameters
  3115.       if (mode .lt. rd .or. mode .gt. create) then
  3116.          call displa(' fopen - invalid mode ',mode) 
  3117.          call abtp("nd")
  3118.       endif 
  3119. c     find the next unused entry
  3120.       do 100 i = 1, maxfile 
  3121. c        if unused table entry is found 
  3122.          if (fmode(i) .eq. closed) then 
  3123.             fname(i) = fn 
  3124.             fwptr(i) = 1
  3125.             fnwds(i) = 0
  3126.             if (mode .eq. rd) then
  3127.                fwshft(i) = 12 
  3128.             else
  3129.                fwshft(i) = 0
  3130.             endif 
  3131.             if (mode .eq. create) then
  3132.                if (cfe(fname(i))) then
  3133.                   fmode(i) = closed 
  3134.                   fopen = error 
  3135.                   return
  3136.                endif
  3137.                fmode(i) = wr
  3138.             else
  3139.                fmode(i) = mode
  3140.             endif 
  3141.             feof(i) = .false. 
  3142.             ctdev(i) = .false.
  3143.             fopen = i 
  3144.             call makefet(fname(i),fets(0,i),fetl,ciobuff(1,i),ciobufl)
  3145. c$    if (nos .eq. 1) 
  3146.             call nosetlf(fets(0,i), i)
  3147. c$    endif 
  3148. c           if standard i/o files, connect them to the terminal.
  3149.             if (fn .eq. 'stdin' .or. fn .eq. 'stdout') then 
  3150. c$          if (nos .eq. 1) 
  3151.                call return (fets(0,i))
  3152.                fets(1,i) = l"tt" .or. (compl(mask(12)) .and. fets(1,i)) 
  3153.                call mtr (l"lfmp" .or. shift(13, 24) .or. shift(1, 19) 
  3154.      +            .or. locf (fets(0,i)))
  3155. c$          else
  3156.                call xcon(fets(0,i),1) 
  3157. c$          endif 
  3158.                ctdev(i) = .true.
  3159.             endif 
  3160. c        set the ascii flag and rewind the file.
  3161.             if(fmode(i) .eq. rd) then 
  3162.                 call open(fets(0,i),"read") 
  3163.             else
  3164.                 call open(fets(0,i),"write")
  3165.             endif 
  3166.             call recall(fets(0,i))
  3167.             fets(0,i) = and(fets(0,i),shift(mask(44),2))
  3168.             if(fmode(i) .eq. wr) fets(0,i) = or(fets(0,i),ciowt)
  3169.             if(fmode(i) .eq. rd) fets(0,i) = or(fets(0,i),ciord)
  3170.             return
  3171. c        if table entry file name matches fn
  3172.          else if (fname(i) .eq. fn) then
  3173.             call remark(' fopen - file ' // fn // ' already open.') 
  3174.             call abtp("nd") 
  3175.          endif
  3176. 100   continue
  3177.       call remark(' fopen - too many files open.')
  3178.       call abtp("nd") 
  3179.       return
  3180.       end 
  3181.       subroutine fclose(fd) 
  3182.   
  3183. ccc   fclose - remove an fd from the active list. 
  3184. c     fclose will remove the fd from the active list for
  3185. c     allocation at a later date. 
  3186. *call kermcom 
  3187.   
  3188.       if (fd .lt. 1 .or. fd .gt. maxfile) then
  3189.          call displa(' fclose - invalid fd ',fd)
  3190.          call abtp("nd")
  3191.       endif 
  3192.       if (fmode(fd) .eq. 0) then
  3193.          call displa(' fclose - fd not open.',fd) 
  3194.          return 
  3195.       endif 
  3196. c     force emptying of the buffer
  3197.       call fflush(fd) 
  3198. c     write a file mark 
  3199.       if(fmode(fd) .eq. wr) then
  3200.           call writer(fets(0,fd)) 
  3201.           call recall(fets(0,fd)) 
  3202.       endif 
  3203.       fmode(fd) = closed
  3204.       if(ctdev(fd)) then
  3205.           call close(fets(0,fd),"unload") 
  3206.           call recall(fets(0,fd)) 
  3207.       else
  3208.           call close(fets(0,fd),"rewind") 
  3209.           call recall(fets(0,fd)) 
  3210.       endif 
  3211.       return
  3212.       end 
  3213.       subroutine fflush(fd) 
  3214.   
  3215. ccc   fflush - flush an i/o buffer. 
  3216. c     fflush will flush the ascii string buffer for a particular
  3217. c     file descriptor.
  3218. *call kermcom 
  3219.   
  3220.       parameter (nosibit = 36, intrcom = 42, asc128 = 22, asc256 = 23)
  3221.       parameter (first = 1, in = 2, out = 3, limit = 4, intwd = 5)
  3222. c$    if (nos .eq. 1) 
  3223.       boolean bpatx 
  3224. c$    endif 
  3225. c     is the fd valid?
  3226.       if (fd .lt. 1 .or. fd .gt. maxfile) then
  3227.          call displa(' fflush - invalid file descriptor',fd)
  3228.          call abtp("nd")
  3229.       endif 
  3230.       if (fmode(fd) .eq. 0) then
  3231.          call displa(' fflush - file descriptor not open',fd) 
  3232.          call abtp("nd")
  3233.       endif 
  3234. c     if fd was opened as write, then flush to the file 
  3235.       if (fmode(fd) .eq. wr) then 
  3236.          if(ctdev(fd)) then 
  3237. c$    if (ut2d .eq. 1) then 
  3238.             fets(first,fd) = or(fets(first,fd),shift(1,asciiio))
  3239. c$    else
  3240.             fets(first,fd) = or(fets(first,fd),shift(1,intrcom))
  3241.             fets(intwd,fd) = shift(1,asc256)
  3242. c$    if (nos .eq. 1) 
  3243.             fets(first,fd) = or(fets(first,fd),shift(1,nosibit))
  3244.             if (fnwds(fd) .eq. 1) then
  3245.                bpatx = o"00004000400040004000"
  3246.             else
  3247.                bpatx = o"40004000400040004000"
  3248.             endif 
  3249.             fchbuf(fnwds(fd),fd) = fchbuf(fnwds(fd),fd) .or. bpatx
  3250.             fnwds(fd) = fnwds(fd) + 1 
  3251.             fchbuf(fnwds(fd),fd) = 0
  3252. c$    endif 
  3253. c$    endif 
  3254.          elseif(fd .ne. debugfd  .and.  dskcset .eq. dskdpc) then 
  3255.             temp = dpctbl(0)
  3256.             dpctbl(0) = 0 
  3257.             call xtxs(fchbuf(1,fd),fnwds(fd),fchbuf(1,fd),dpctbl) 
  3258.             if(mod(fnwds(fd),2) .eq. 0) 
  3259.      +        fchbuf(fnwds(fd) / 2 + 1,fd) = 0
  3260.             dpctbl(0) = temp
  3261.             fnwds(fd) = findeol(fchbuf(1,fd),fnwds(fd),.false.) 
  3262.          endif
  3263.          call writew(fets(0,fd),fchbuf(1,fd),fnwds(fd)) 
  3264. c$    if (nos .eq. 1) 
  3265.          if ((binmode .or. rawmode) .and. ctdev(fd)) then 
  3266.             call writer(fets(0,fd)) 
  3267.          endif
  3268. c$    endif 
  3269.       else if (fmode(fd) .eq. rd) then
  3270.          call recall(fets(0,fd))
  3271.          fets(in,fd) = and(fets(first,fd),o"777777")
  3272.          fets(out,fd) = fets(in,fd) 
  3273.       endif 
  3274. c     reset buffer character count
  3275.       fwptr(fd) = 1 
  3276.       fnwds(fd) = 0 
  3277.       if (fmode(fd) .eq. rd) then 
  3278.          fwshft(fd) = 12
  3279.       else
  3280.          fwshft(fd) = 0 
  3281.       endif 
  3282.       return
  3283.       end 
  3284.       integer function getc(fd,ch)
  3285.   
  3286. ccc   getc - return next character from the input stream. 
  3287. c     getc will return the next ascii character that was
  3288. c     read from the file descriptor fd.  reads are buffered 
  3289. c     with 5 characters packed to a word.  o"0000" bytes
  3290. c     are ignored.  nuls are o"4000" bytes.  eof (-1) is
  3291. c     returned when eof is read.
  3292. *call kermcom 
  3293. c     is the fd valid?
  3294.       if (fd .lt. 1 .or. fd .gt. maxfile) then
  3295.          call displa(' getc - invalid file descriptor',fd)
  3296.          call abtp("nd")
  3297.       endif 
  3298.       if (fmode(fd) .eq. closed) then 
  3299.          call displa(' getc - file descriptor not open',fd) 
  3300.          call abtp("nd")
  3301.       endif 
  3302. c     check if ok to read 
  3303.       if ((fmode(fd).and.rd) .ne. rd) then
  3304.          call displa(' getc - read on write-only file ',fd) 
  3305.          call abtp("nd")
  3306.       endif 
  3307. c     check if more data needed 
  3308. 10    if (fwptr(fd) .gt. fnwds(fd)) then
  3309.          if (feof(fd)) then 
  3310.             getc = eof
  3311.             return
  3312.          endif
  3313. c        get a buffer worth of data 
  3314.          nread = getrec(fd,fchbuf(1,fd),maxwd,feof(fd)) 
  3315.          fwptr(fd) = 1
  3316.          fnwds(fd) = nread
  3317.          fwshft(fd) = 12
  3318.          go to 10 
  3319.       endif 
  3320. c     pickup char to return and check for ignored o"0000" byte
  3321.       ch = shift(fchbuf(fwptr(fd),fd),fwshft(fd)) .and. o"7777" 
  3322.       fwshft(fd) = fwshft(fd) + 12
  3323.       if (fwshft(fd) .gt. 60) then
  3324.          fwshft(fd) = 12
  3325.          fwptr(fd) = fwptr(fd) + 1
  3326.       endif 
  3327. c     if the front-end isn't stripping parity and we aren't using 
  3328. c     the eigth bit for data, then strip the parity bit.  also, convert 
  3329. c     carriage returns and linefeeds which come from the keyboard into
  3330. c     regular end-of-lines (this only happens in binmode).
  3331.       if (binmode .and. .not. rawmode) then 
  3332.          if (parity .ne. nopar .and. ctdev(fd)) ch = ch .and. o"177"
  3333.          if(ctdev(fd)  .and.  (ch .eq. cr .or. ch .eq. lf)) ch = nel
  3334.       endif 
  3335.       if (ch .eq. 0) go to 10 
  3336.       getc = ch 
  3337.       return
  3338.       end 
  3339.       subroutine ungetc(fd,ch)
  3340.   
  3341. ccc   ungetc - try to put a character back into the input stream. 
  3342. c     ungetc can only put back characters as far as the beginning 
  3343. c     of the buffer.  hopefully, this is ok, since only getword 
  3344. c     does this with an nel which should be well into the buffer. 
  3345. *call kermcom 
  3346. c     is it ok to back up the pointer?
  3347.       if (fwshft(fd) .eq. 12 .and. fwptr(fd) .eq. 1) then 
  3348.          call displa('ungetc - cannot push character ',ch)
  3349.          return 
  3350.       endif 
  3351. c     back up the pointer 
  3352.       if (fwshft(fd) .eq. 12) then
  3353.          fwshft(fd) = 60
  3354.          fwptr(fd) = fwptr(fd) - 1
  3355.       else
  3356.          fwshft(fd) = fwshft(fd) - 12 
  3357.       endif 
  3358.       fchbuf(fwptr(fd),fd) = (fchbuf(fwptr(fd),fd) .and. shift( 
  3359.      +   o"7777",60-fwshft(fd))) .or. shift(ch,60-fwshft(fd)) 
  3360.       feof(fd) = .false.
  3361.       return
  3362.       end 
  3363.       integer function getword(fd,str,maxlen) 
  3364.   
  3365. ccc   getword - get a word from an input stream.
  3366. c     getword considers a word to be delimited by blanks. 
  3367. c     it will return the length of the word as its value. 
  3368. *call kermcom 
  3369.       integer str(maxlen) 
  3370.   
  3371.       len = 0 
  3372. c     skip leading white spaces 
  3373. 10    if (getc(fd,ch) .eq. eof) then
  3374.          getword = eof
  3375.          return 
  3376.       else if (ch .eq. nel) then
  3377.          getword = 0
  3378.          return 
  3379.       endif 
  3380.       if (ch .eq. blank .or. ch .eq. tab) go to 10
  3381. c     found the first character, so keep going
  3382. 20    if (len .lt. maxlen) then 
  3383.          len = len + 1
  3384.          str(len) = ch
  3385.       endif 
  3386.       ch = getc(fd,ch)
  3387.       if (ch .ne. eof .and. ch .ne. blank .and. ch .ne. tab .and. 
  3388.      +    ch .ne. nel) go to 20 
  3389. c     save eols for next getword
  3390.       if (ch .eq. nel) call ungetc(fd,ch) 
  3391.       str(len+1) = 0
  3392.       getword = len 
  3393.       return
  3394.       end 
  3395.       subroutine putc(tch,fd) 
  3396.   
  3397. ccc   putc - put a character into an output stream
  3398. c     putc outputs a character with the parity bit set to the 
  3399. c     proper parity if the output file is conversational. 
  3400. c     the five types of parity are defined for each character 
  3401. c     in a table. 
  3402. *call kermcom 
  3403.       integer chparty(128)
  3404.       data (chparty(i),i=1,38) /
  3405.      +               o"40000200020040004000", o"02010001020100010001",
  3406. c                            nul                      soh 
  3407.      +               o"02020002020200020002", o"00030203020300030003",
  3408. c                            stx                      etx 
  3409.      +               o"02040004020400040004", o"00050205020500050005",
  3410. c                            eot                      enq 
  3411.      +               o"00060206020600060006", o"02070007020700070007",
  3412. c                            ack                      bel 
  3413.      +               o"02100010021000100010", o"00110211021100110011",
  3414. c                            bs                       ht
  3415.      +               o"00120212021200120012", o"02130013021300130013",
  3416. c                            lf                       vt
  3417.      +               o"00140214021400140014", o"02150015021500150015",
  3418. c                            ff                       cr
  3419.      +               o"02160016021600160016", o"00170217021700170017",
  3420. c                            so                       si
  3421.      +               o"02200020022000200020", o"00210221022100210021",
  3422. c                            dle                      dc1 
  3423.      +               o"00220222022200220022", o"02230023022300230023",
  3424. c                            dc2                      dc3 
  3425.      +               o"00240224022400240024", o"02250025022500250025",
  3426. c                            dc4                      nak 
  3427.      +               o"02260026022600260026", o"00270227022700270027",
  3428. c                            syn                      etb 
  3429.      +               o"00300230023000300030", o"02310031023100310031",
  3430. c                            can                      em
  3431.      +               o"02320032023200320032", o"00330233023300330033",
  3432. c                            sub                      esc 
  3433.      +               o"02340034023400340034", o"00350235023500350035",
  3434. c                            fs                       gs
  3435.      +               o"00360236023600360036", o"02370037023700370037",
  3436. c                            rs                       us
  3437.      +               o"02400040024000400040", o"00410241024100410041",
  3438. c                                                     ! 
  3439.      +               o"00420242024200420042", o"02430043024300430043",
  3440. c                            "                        pound 
  3441.      +               o"00440244024400440044", o"02450045024500450045" / 
  3442. c                            $                        percent 
  3443.       data (chparty(i),i=39,76) / 
  3444.      +               o"02460046024600460046", o"00470247024700470047",
  3445. c                            &                        ' 
  3446.      +               o"00500250025000500050", o"02510051025100510051",
  3447. c                            (                        ) 
  3448.      +               o"02520052025200520052", o"00530253025300530053",
  3449. c                            *                        + 
  3450.      +               o"02540054025400540054", o"00550255025500550055",
  3451. c                            ,                        - 
  3452.      +               o"00560256025600560056", o"02570057025700570057",
  3453. c                            .                        / 
  3454.      +               o"00600260026000600060", o"02610061026100610061",
  3455. c                            0                        1 
  3456.      +               o"02620062026200620062", o"00630263026300630063",
  3457. c                            2                        3 
  3458.      +               o"02640064026400640064", o"00650265026500650065",
  3459. c                            4                        5 
  3460.      +               o"00660266026600660066", o"02670067026700670067",
  3461. c                            6                        7 
  3462.      +               o"02700070027000700070", o"00710271027100710071",
  3463. c                            8                        9 
  3464.      +               o"00720272027200720072", o"02730073027300730073",
  3465. c                            :                        ; 
  3466.      +               o"00740274027400740074", o"02750075027500750075",
  3467. c                            <                        = 
  3468.      +               o"02760076027600760076", o"00770277027700770077",
  3469. c                            >                        ? 
  3470.      +               o"03000100030001000100", o"01010301030101010101",
  3471. c                            @                        a 
  3472.      +               o"01020302030201020102", o"03030103030301030103",
  3473. c                            b                        c 
  3474.      +               o"01040304030401040104", o"03050105030501050105",
  3475. c                            d                        e 
  3476.      +               o"03060106030601060106", o"01070307030701070107",
  3477. c                            f                        g 
  3478.      +               o"01100310031001100110", o"03110111031101110111",
  3479. c                            h                        i 
  3480.      +               o"03120112031201120112", o"01130313031301130113" / 
  3481. c                            j                        k 
  3482.       data (chparty(i),i=77,114) /
  3483.      +               o"03140114031401140114", o"01150315031501150115",
  3484. c                            l                        m 
  3485.      +               o"01160316031601160116", o"03170117031701170117",
  3486. c                            n                        o 
  3487.      +               o"01200320032001200120", o"03210121032101210121",
  3488. c                            p                        q 
  3489.      +               o"03220122032201220122", o"01230323032301230123",
  3490. c                            r                        s 
  3491.      +               o"03240124032401240124", o"01250325032501250125",
  3492. c                            t                        u 
  3493.      +               o"01260326032601260126", o"03270127032701270127",
  3494. c                            v                        w 
  3495.      +               o"03300130033001300130", o"01310331033101310131",
  3496. c                            x                        y 
  3497.      +               o"01320332033201320132", o"03330133033301330133",
  3498. c                            z                        [ 
  3499.      +               o"01340334033401340134", o"03350135033501350135",
  3500. c                            \                        ] 
  3501.      +               o"03360136033601360136", o"01370337033701370137",
  3502. c                            ^                        underscore
  3503.      +               o"01400340034001400140", o"03410141034101410141",
  3504. c                            grave accent             a 
  3505.      +               o"03420142034201420142", o"01430343034301430143",
  3506. c                            b                        c 
  3507.      +               o"03440144034401440144", o"01450345034501450145",
  3508. c                            d                        e 
  3509.      +               o"01460346034601460146", o"03470147034701470147",
  3510. c                            f                        g 
  3511.      +               o"03500150035001500150", o"01510351035101510151",
  3512. c                            h                        i 
  3513.      +               o"01520352035201520152", o"03530153035301530153",
  3514. c                            j                        k 
  3515.      +               o"01540354035401540154", o"03550155035501550155",
  3516. c                            l                        m 
  3517.      +               o"03560156035601560156", o"01570357035701570157",
  3518. c                            n                        o 
  3519.      +               o"03600160036001600160", o"01610361036101610161" / 
  3520.       data (chparty(i),i=115,128) / 
  3521. c                            p                        q 
  3522.      +               o"01620362036201620162", o"03630163036301630163",
  3523. c                            r                        s 
  3524.      +               o"01640364036401640164", o"03650165036501650165",
  3525. c                            t                        u 
  3526.      +               o"03660166036601660166", o"01670367036701670167",
  3527. c                            v                        w 
  3528.      +               o"01700370037001700170", o"03710171037101710171",
  3529. c                            x                        y 
  3530.      +               o"03720172037201720172", o"01730373037301730173",
  3531. c                            z                        left brace
  3532.      +               o"03740174037401740174", o"01750375037501750175",
  3533. c                            bar                      right brace 
  3534.      +               o"01760376037601760176", o"03770177037701770177" / 
  3535. c                            tilde                    del 
  3536. c     is the fd valid?
  3537.       if (fd .lt. 1 .or. fd .gt. maxfile) then
  3538.          call displa(' putc - invalid file descriptor',fd)
  3539.          call abtp("nd")
  3540.       endif 
  3541.       if (fmode(fd) .eq. closed) then 
  3542.          call displa(' putc - file descriptor not open',fd) 
  3543.          call abtp("nd")
  3544.       endif 
  3545. c     is it ok to write on this stream? 
  3546.       if ((fmode(fd).and.wr) .ne. wr) then
  3547.          call displa(' putc - write on read-only file ',fd) 
  3548.          call abtp("nd")
  3549.       endif 
  3550. c     add another character to the output buffer
  3551.       ch = tch
  3552. 10    if (ctdev(fd)) then 
  3553.          if (ch .eq. nel .and. .not. rawmode) ch = cr 
  3554.          if (ch .ge. 0 .and. ch .lt. 128) 
  3555.      +      ch = shift(chparty(ch+1),parity*12) .and. o"7777" 
  3556.       endif 
  3557.       if (fwshft(fd) .eq. 0) then 
  3558.          if (fnwds(fd) .eq. maxwd) then 
  3559.             call fflush(fd) 
  3560.          endif
  3561.          fwshft(fd) = 48
  3562.          fnwds(fd) = fnwds(fd) + 1
  3563.          fchbuf(fnwds(fd),fd) = 0 
  3564.       else
  3565.          fwshft(fd) = fwshft(fd) - 12 
  3566.       endif 
  3567. c     if this is an mass storage device (disk), and we have a nel 
  3568. c     character, flush the line into the cio buffer.  the standard cdc
  3569. c     line terminator is already present thanks to the above code 
  3570. c     pre-zeroing the target word before anything is put in it. 
  3571. c     however, don't flush if we need the nel character in the
  3572. c     line (e.g. ut 812 ascii and disk image format). 
  3573.       if(.not.ctdev(fd) .and. tch.eq.nel .and. dskcset.ne.dskut8 .and.
  3574.      +   dskcset.ne.dskimag) then 
  3575.           call fflush(fd) 
  3576.           return
  3577.       endif 
  3578.   
  3579. c$    if (nos .eq. 1) 
  3580. c     preset transparent output for the terminal if first word of buffer
  3581.       if (fnwds(fd) .eq. 1 .and. fwshft(fd) .eq. 48) then 
  3582.          if (fmode(fd) .eq. wr .and. ctdev(fd)) then
  3583.             fchbuf(fnwds(fd),fd) = shift(o"0007",48)
  3584.             fwshft(fd) = 36 
  3585.          endif
  3586.       endif 
  3587.   
  3588.       if (ctdev(fd)) ch = ch .or. o"4000" 
  3589. c$    endif 
  3590.   
  3591.       fchbuf(fnwds(fd),fd) = fchbuf(fnwds(fd),fd) .or.
  3592.      +   shift(and(ch,o"7777"),fwshft(fd))
  3593.       if (tch .eq. nel .and. (ch.and.o"0177") .eq. cr) then 
  3594.          ch = lf
  3595.          go to 10 
  3596.       endif 
  3597.       if (tch .eq. nel .and. ctdev(fd)) call fflush(fd) 
  3598.       return
  3599.       end 
  3600.       subroutine fread(fd,buf,nwd)
  3601.   
  3602. ccc   fread - read some words from a file.
  3603. *call kermcom 
  3604.       integer buf(nwd)
  3605. c     is the fd valid?
  3606.       if (fd .lt. 1 .or. fd .gt. maxfile) then
  3607.          call displa(' fread - invalid file descriptor',fd) 
  3608.          call abtp("nd")
  3609.       endif 
  3610.       if (fmode(fd) .eq. closed) then 
  3611.          call displa(' fread - file descriptor not open',fd)
  3612.          call abtp("nd")
  3613.       endif 
  3614. c     check if ok to read 
  3615.       if ((fmode(fd).and.rd) .ne. rd) then
  3616.          call displa(' fread - read on write-only file ',fd)
  3617.          call abtp("nd")
  3618.       endif 
  3619. c     transfer a cio buffer full at a time until done 
  3620.       istart = 1
  3621.       nleft = nwd 
  3622. 10    nrd = nleft 
  3623.       if (nrd .gt. ciobufl-1) then
  3624.          nrd = ciobufl-1
  3625.       endif 
  3626.       call readw(fets(0,fd),buf(istart),nrd)
  3627.       istart = istart + nrd 
  3628.       nleft = nleft - nrd 
  3629.       if (nleft .gt. 0) goto 10 
  3630.       return
  3631.       end 
  3632.       subroutine fwrite(fd,buf,nwd) 
  3633.   
  3634. ccc   fwrite - write some words to a file.
  3635. *call kermcom 
  3636. c     is the fd valid?
  3637.       if (fd .lt. 1 .or. fd .gt. maxfile) then
  3638.          call displa(' fwrite - invalid fd ',fd)
  3639.          call abtp("nd")
  3640.       endif 
  3641.       if (fmode(fd) .eq. closed) then 
  3642.          call displa(' fwrite - fd not open.',fd) 
  3643.          return 
  3644.       endif 
  3645. c     is it ok to write on this stream? 
  3646.       if ((fmode(fd).and.wr) .ne. wr) then
  3647.          call displa(' fwrite - write on read-only file ',fd) 
  3648.          call abtp("nd")
  3649.       endif 
  3650. c     write the words to the file 
  3651.       call writew(fets(0,fd),buf,nwd) 
  3652.       return
  3653.       end 
  3654.       subroutine putstr(fd,str) 
  3655.   
  3656. ccc   putstr - output a string to an output stream. 
  3657. c     putstr will add characters from the null terminated character 
  3658. c     buffer str to the specified output stream.
  3659. *call kermcom 
  3660.       integer str(*)
  3661. c     is the fd valid?
  3662.       if (fd .lt. 1 .or. fd .gt. maxfile) then
  3663.          call displa(' putc - invalid fd ',fd)
  3664.          call abtp("nd")
  3665.       endif 
  3666.       if (fmode(fd) .eq. 0) then
  3667.          call displa(' putc - fd not open.',fd) 
  3668.          return 
  3669.       endif 
  3670. c     is it ok to write on this stream? 
  3671.       if ((fmode(fd).and.wr) .ne. wr) then
  3672.          call displa(' putc - write on read-only file ',fd) 
  3673.          call abtp("nd")
  3674.       endif 
  3675. c     put chars in the output buffer
  3676.       i = 1 
  3677. 10    if (str(i) .ne. 0) then 
  3678. c        is it a valid character? 
  3679. c        if ((str(i).and.mask(48)) .ne. 0) then 
  3680. c           call displa(' putstr - invalid ascii byte ',str(i)) 
  3681. c           call abort
  3682. c        endif
  3683.          call putc(str(i),fd) 
  3684.          i = i + 1
  3685.          go to 10 
  3686.       endif 
  3687.       return
  3688.       end 
  3689.       subroutine putint(fd,int,minwid)
  3690.   
  3691. ccc   putint - output an integer. 
  3692. *call kermcom 
  3693.       integer string(21)
  3694.   
  3695.       width = 0 
  3696.       if (int .lt. 0) then
  3697.          call putc(asc('-'),fd) 
  3698.          width = 1
  3699.       endif 
  3700.       val = iabs(int) 
  3701.       ascii0 = asc('0') 
  3702.       nch = 0 
  3703. 10    nch = nch + 1 
  3704.       string(nch) = mod(val,10) + ascii0
  3705.       val = val / 10
  3706.       if (val .ne. 0 .and. nch .lt. 20) go to 10
  3707.       width = width + nch 
  3708. c     now output the digits 
  3709. 20    call putc(string(nch),fd) 
  3710.       nch = nch - 1 
  3711.       if (nch .gt. 0) go to 20
  3712. 30    if (width .lt. minwid) then 
  3713.          call putc(blank,fd)
  3714.          width = width + 1
  3715.          go to 30 
  3716.       endif 
  3717.       return
  3718.       end 
  3719.       subroutine putday(fd,mm,dd,yy)
  3720.   
  3721. ccc   output day of week. 
  3722. *call kermcom 
  3723.       izlr(iyr,m,idy)=mod((13*(m+10-(m+10)/13*12)-1)/5+idy+77 
  3724.      1 +5*(iyr+(m-14)/12-(iyr+(m-14)/12)/100*100)/4 
  3725.      2 +(iyr+(m-14)/12)/400-(iyr+(m-14)/12)/100*2,7)+1
  3726.       wkday = izlr(yy,mm,dd)
  3727.       if (wkday .eq. 1) then
  3728.          call fprintf(fd,'^sunday') 
  3729.       else if (wkday .eq. 2) then 
  3730.          call fprintf(fd,'^monday') 
  3731.       else if (wkday .eq. 3) then 
  3732.          call fprintf(fd,'^tuesday')
  3733.       else if (wkday .eq. 4) then 
  3734.          call fprintf(fd,'^wednesday')
  3735.       else if (wkday .eq. 5) then 
  3736.          call fprintf(fd,'^thursday') 
  3737.       else if (wkday .eq. 6) then 
  3738.          call fprintf(fd,'^friday') 
  3739.       else
  3740.          call fprintf(fd,'^saturday') 
  3741.       endif 
  3742.       return
  3743.       end 
  3744.       subroutine putmnth(fd,mm) 
  3745.   
  3746. ccc   putmnth - output the month name.
  3747. *call kermcom 
  3748.       if (mm .eq. 1) then 
  3749.          call fprintf(fd,'^january',0)
  3750.       else if (mm .eq. 2) then
  3751.          call fprintf(fd,'^february',0) 
  3752.       else if (mm .eq. 3) then
  3753.          call fprintf(fd,'^march',0)
  3754.       else if (mm .eq. 4) then
  3755.          call fprintf(fd,'^april',0)
  3756.       else if (mm .eq. 5) then
  3757.          call fprintf(fd,'^may',0)
  3758.       else if (mm .eq. 6) then
  3759.          call fprintf(fd,'^june',0) 
  3760.       else if (mm .eq. 7) then
  3761.          call fprintf(fd,'^july',0) 
  3762.       else if (mm .eq. 8) then
  3763.          call fprintf(fd,'^august',0) 
  3764.       else if (mm .eq. 9) then
  3765.          call fprintf(fd,'^september',0)
  3766.       else if (mm .eq. 10) then 
  3767.          call fprintf(fd,'^october',0)
  3768.       else if (mm .eq. 11) then 
  3769.          call fprintf(fd,'^november',0) 
  3770.       else if (mm .eq. 12) then 
  3771.          call fprintf(fd,'^december',0) 
  3772.       else
  3773.          call fprintf(fd,'putmnth - no such month as @d\n',mm)
  3774.       endif 
  3775.       return
  3776.       end 
  3777.       subroutine fprintf(fd,fmt,i1,i2,i3,i4)
  3778.   
  3779. ccc   fprintf - poor attempt at formatted ascii output. 
  3780. c     conversion is similar to fprintf used in c.  supported
  3781. c     conversions are @d (integer), @c (ascii character), @s (ascii 
  3782. c     string buffer).  a \n will map to a newline, a \t will
  3783. c     will map to a tab, a \0 will terminate the format scanning. 
  3784. c     a \ followed by any other character will cause that character 
  3785. c     to be output.  the default output case will be lowercase. 
  3786. c     a ^ followed by a letter will cause that character to be output 
  3787. c     as uppercase.  a @d conversion may now specify a minimum field
  3788. c     width as @<n>d (i.e. @10d) in which the number will be blank
  3789. c     padded to the right to use up <n> characters. 
  3790. *call kermcom 
  3791.       character*(*) fmt 
  3792. c     is the fd valid?
  3793.       if (fd .lt. 1 .or. fd .gt. maxfile) then
  3794.          call displa(' fprintf - invalid fd ',fd) 
  3795.          call abtp("nd")
  3796.       endif 
  3797.       if (fmode(fd) .eq. closed) then 
  3798.          call displa(' fprintf - fd not open.',fd)
  3799.          return 
  3800.       endif 
  3801. c     is it ok to write on this stream? 
  3802.       if ((fmode(fd).and.wr) .ne. wr) then
  3803.          call displa(' fprintf - write on read-only file ',fd)
  3804.          call abtp("nd")
  3805.       endif 
  3806. c     now call the real fprintf workhorse 
  3807.       call doprnt(fd,0,1,fmt,i1,i2,i3,i4) 
  3808.       return
  3809.       end 
  3810.       subroutine sprintf(str,fmt,i1,i2,i3,i4) 
  3811.   
  3812. ccc   sprintf - poor attempt at doing internal formatted i/o. 
  3813. c     sprintf is the same as fprintf except that it writes to 
  3814. c     and ascii string buffer instead.
  3815. *call kermcom 
  3816.       character*(*) fmt 
  3817.       boolean str(*)
  3818. c     call the real sprintf workhorse 
  3819.       call doprnt(0,str,2,fmt,i1,i2,i3,i4)
  3820.       return
  3821.       end 
  3822.       subroutine doprnt(fd,strng,ptyp,fmt,i1,i2,i3,i4)
  3823.   
  3824. ccc   doprnt - workhorse for formatted ascii i/o. 
  3825. c     conversion is similar to fprintf used in c.  supported
  3826. c     conversions are @d (integer), @c (ascii character), @s (ascii 
  3827. c     string buffer).  a \n will map to a newline, a \t will
  3828. c     will map to a tab, a \0 will terminate the format scanning. 
  3829. c     a \ followed by any other character will cause that character 
  3830. c     to be output.  the default output case will be lowercase. 
  3831. c     a ^ followed by a letter will cause that character to be output 
  3832. c     as uppercase.  a @d conversion may now specify a minimum field
  3833. c     width as @<n>d (i.e. @10d) in which the number will be blank
  3834. c     padded to the right to use up <n> characters. 
  3835. *call kermcom 
  3836.       character*(*) fmt 
  3837.       boolean str(21), strng(*) 
  3838.       character*1 ch
  3839. c     check for file or string write
  3840.       if (ptyp .ne. 1 .and. ptyp .ne. 2) then 
  3841.          call displa(' doprnt - invalid write function',ptyp) 
  3842.          call abtp("nd")
  3843.       endif 
  3844. c     output the formatted string 
  3845.       iptr = 1
  3846.       optr = 1
  3847.       fptr = 1
  3848.       fmtlen = len(fmt) 
  3849. 10    if (fptr .le. fmtlen) then
  3850.          ch = fmt(fptr:fptr)
  3851.          if (ch .ne. '\' .and. ch .ne. '@' .and. ch .ne. '^') then
  3852.             if (ptyp .eq. 1) then 
  3853.                call putc(asc(ch),fd)
  3854.             else
  3855.                strng(optr) = asc(ch)
  3856.                optr = optr + 1
  3857.             endif 
  3858. c        is it a quote or special sequence character? 
  3859.          else if (ch .eq. '\') then 
  3860.             fptr = fptr+1 
  3861.             ch = fmt(fptr:fptr) 
  3862.             if (ch .eq. 'n' .and. ptyp .eq. 1) then 
  3863.                call putc(nel,fd)
  3864.             else if (ch .eq. 't' .and. ptyp .eq. 1) then
  3865.                call putc(tab,fd)
  3866.             else if (ch .eq. '0') then
  3867.                if (ptyp .eq. 2) strng(optr) = 0 
  3868.                return 
  3869.             else if (ch .eq. 'n') then
  3870.                strng(optr) = nel
  3871.                optr = optr + 1
  3872.             else if (ch .eq. 't') then
  3873.                strng(optr) = tab
  3874.                optr = optr + 1
  3875.             else
  3876.                if (ptyp .eq. 1) then
  3877.                   call putc(asc(ch),fd) 
  3878.                else 
  3879.                   strng(optr) = asc(ch) 
  3880.                   optr = optr + 1 
  3881.                endif
  3882.             endif 
  3883. c     is it an uppercase mapping? 
  3884.          else if (ch .eq. '^') then 
  3885.             fptr = fptr + 1 
  3886.             ch = fmt(fptr:fptr) 
  3887.             if (ch .ge. 'a' .and. ch .le. 'z') then 
  3888.                ach = asc(ch)-32 
  3889.             else
  3890.                ach = asc(ch)
  3891.             endif 
  3892.             if (ptyp .eq. 1) then 
  3893.                call putc(ach,fd)
  3894.             else
  3895.                strng(optr) = ach
  3896.                optr = optr + 1
  3897.             endif 
  3898. c        must be a conversion (@) 
  3899.          else 
  3900.             intwdth = 1 
  3901.             fptr = fptr + 1 
  3902.             ch = fmt(fptr:fptr) 
  3903. c           is it an integer value format spec? 
  3904. 20          if (ch .eq. 'd') then 
  3905.                if (iptr .eq. 1) then
  3906.                   ach = i1
  3907.                else if (iptr .eq. 2) then 
  3908.                   ach = i2
  3909.                else if (iptr .eq. 3) then 
  3910.                   ach = i3
  3911.                else 
  3912.                   ach = i4
  3913.                endif
  3914.                if (ptyp .eq. 1) then
  3915.                   call putint(fd,ach,intwdth) 
  3916.                else 
  3917.                   tlen = itos(ach,strng(optr),intwdth)
  3918.                   optr = optr + tlen
  3919.                endif
  3920.                iptr = iptr + 1
  3921. c           is it a character value output spec?
  3922.             else if (ch .eq. 'c') then
  3923.                if (iptr .eq. 1) then
  3924.                   ach = i1
  3925.                else if (iptr .eq. 2) then 
  3926.                   ach = i2
  3927.                else if (iptr .eq. 3) then 
  3928.                   ach = i3
  3929.                else 
  3930.                   ach = i4
  3931.                endif
  3932.                if (ptyp .eq. 1) then
  3933.                   call putc(ach,fd) 
  3934.                else 
  3935.                   strng(optr) = ach 
  3936.                   optr = optr + 1 
  3937.                endif
  3938.                iptr = iptr + 1
  3939. c           is it a string value output spec? 
  3940.             else if (ch .eq. 's') then
  3941.                if (iptr .eq. 1) then
  3942.                   if (ptyp .eq. 1) then 
  3943.                      call putstr(fd,i1) 
  3944.                   else
  3945.                      call strcpy(i1,strng(optr))
  3946.                      optr = optr + slen(i1) 
  3947.                   endif 
  3948.                else if (iptr .eq. 2) then 
  3949.                   if (ptyp .eq. 1) then 
  3950.                      call putstr(fd,i2) 
  3951.                   else
  3952.                      call strcpy(i2,strng(optr))
  3953.                      optr = optr + slen(i2) 
  3954.                   endif 
  3955.                else if (iptr .eq. 3) then 
  3956.                   if (ptyp .eq. 1) then 
  3957.                      call putstr(fd,i3) 
  3958.                   else
  3959.                      call strcpy(i3,strng(optr))
  3960.                      optr = optr + slen(i3) 
  3961.                   endif 
  3962.                else 
  3963.                   if (ptyp .eq. 1) then 
  3964.                      call putstr(fd,i4) 
  3965.                   else
  3966.                      call strcpy(i4,strng(optr))
  3967.                      optr = optr + slen(i4) 
  3968.                   endif 
  3969.                endif
  3970.                iptr = iptr + 1
  3971. c           is it a field width specifier?
  3972.             else if (ch .ge. '0' .and. ch .le. '9') then
  3973.                sptr = 0 
  3974. 30             sptr = sptr + 1
  3975.                str(sptr) = asc(ch)
  3976.                fptr = fptr + 1
  3977.                ch = fmt(fptr:fptr)
  3978.                if (ch .ge. '0' .and. ch .le. '9') go to 30
  3979.                str(sptr+1) = 0
  3980.                intwdth = ctoi(str)
  3981.                go to 20 
  3982. c           unknown conversion so output the @ and conversion char
  3983.             else
  3984.                if (ptyp .eq. 1) then
  3985.                   call putc(asc('@'),fd)
  3986.                   call putc(asc(ch),fd) 
  3987.                else 
  3988.                   strng(optr) = asc('@')
  3989.                   strng(optr+1) = asc(ch) 
  3990.                   optr = optr + 2 
  3991.                endif
  3992.          endif
  3993.          endif
  3994.          fptr = fptr + 1
  3995.          go to 10 
  3996.       endif 
  3997.       if (ptyp .eq. 2) strng(optr) = 0
  3998.       return
  3999.       end 
  4000.       subroutine stty(mode,value) 
  4001.   
  4002. ccc   stty - set a terminal mode. 
  4003. *call kermcom 
  4004.       character*(*) mode
  4005.       integer value 
  4006. c$    if (nos .eq. 1) 
  4007.       integer  nositm(5), nosttm(2), nosfull, noshalf,
  4008.      +   noszero, nosodd, noseven, nosnone
  4009. c        for nos (initiate *rawmode*):
  4010. c          set pw=0,ci=0,li=0,pg=n,ubl=15,ubz=200,eb=cr,fa=y,cp=0,lk=y
  4011.       data  nositm / o"00164043400040544000", o"40554000404540004030",
  4012.      +               o"40174031400241014001", o"40674001410740004040",
  4013.      +               o"40010000000000000000" /
  4014. c        for nos (terminate *rawmode*): 
  4015. c           set fa=n,cp=1,lk=n
  4016.       data  nosttm / o"00164067400041074001", o"40404000000000000000" / 
  4017. c        for nos (full/half duplex):
  4018.       data  nosfull / o"00164061400100000000" / 
  4019.       data  noshalf / o"00164061400000000000" / 
  4020. c        for nos (parity: zero, odd, even, none)
  4021.       data  noszero / o"00164062400000000000" / 
  4022.       data  nosodd  / o"00164062400100000000" / 
  4023.       data  noseven / o"00164062400200000000" / 
  4024.       data  nosnone / o"00164062400300000000" / 
  4025. c$    endif 
  4026. c     is it setting duplex? 
  4027.       if (mode .eq. 'duplex') then
  4028.          if (value .eq. fulldup) then 
  4029. c$          if (ut2d .eq. 1)
  4030.             call bellc(l"full",0,0) 
  4031. c$          endif 
  4032. c$          if(uariz .eq. 1)
  4033.             call echoplx('on')
  4034. c$          endif 
  4035. c$          if(nos .eq. 1)
  4036.             call writew(fets(0,stdout),nosfull,1) 
  4037.             call writer(fets(0,stdout)) 
  4038.             if (debug .ne. 0) then
  4039.                call fprintf(debugfd, '^stty - full duplex.\n')
  4040.             endif 
  4041. c$          endif 
  4042.             duplex = fulldup
  4043.          else if (value .eq. halfdup) then
  4044. c$          if (ut2d .eq. 1)
  4045.             call bellc(l"half",0,0) 
  4046. c$          endif 
  4047. c$          if(uariz .eq. 1)
  4048.             call echoplx('off') 
  4049. c$          endif 
  4050. c$          if(nos .eq. 1)
  4051.             call writew(fets(0,stdout),noshalf,1) 
  4052.             call writer(fets(0,stdout)) 
  4053.             if (debug .ne. 0) then
  4054.                call fprintf(debugfd, '^stty - half duplex.\n')
  4055.             endif 
  4056. c$          endif 
  4057.             duplex = halfdup
  4058.          else 
  4059.             call displa(' stty - invalid duplex ',value)
  4060.             call abtp("nd") 
  4061.          endif
  4062. c     is it setting parity? 
  4063.       else if (mode .eq. 'parity') then 
  4064.          if (value .eq. nopar .or. value .eq. evepar .or. 
  4065.      +       value .eq. oddpar .or. value .eq. mrkpar .or.
  4066.      +       value .eq. spcpar) then
  4067.             parity = value
  4068. c$          if (nos .eq. 1) 
  4069.             if (debug .ne. 0) then
  4070.                call fprintf(debugfd, '^stty - parity switch.\n')
  4071.             endif 
  4072.             if (parity .eq. nopar) then 
  4073.                call writew(fets(0,stdout),nosnone,1)
  4074.                call writer(fets(0,stdout))
  4075.             else if (parity .eq. evepar) then 
  4076.                call writew(fets(0,stdout),noseven,1)
  4077.                call writer(fets(0,stdout))
  4078.             else if (parity .eq. oddpar) then 
  4079.                call writew(fets(0,stdout),nosodd,1) 
  4080.                call writer(fets(0,stdout))
  4081.             else if (parity .eq. mrkpar) then 
  4082.                call writew(fets(0,stdout),noszero,1)
  4083.                call writer(fets(0,stdout))
  4084.             else if (parity .eq. spcpar) then 
  4085.                call writew(fets(0,stdout),noszero,1)
  4086.                call writer(fets(0,stdout))
  4087.             endif 
  4088. c$          endif 
  4089.          else 
  4090.             call displa(' stty - invalid parity ',value)
  4091.             call abtp("nd") 
  4092.          endif
  4093. c     is it setting binary (no translation) i/o?
  4094.       else if (mode .eq. 'binary') then 
  4095.          binmode = (value .eq. on)
  4096.          do 100 i = 1,maxfile 
  4097.             if (fmode(i) .ne. closed) then
  4098.                if (ctdev(i)) then 
  4099.                   if (binmode) then 
  4100.                      fets(0,i) = or(fets(0,i),cioodd) 
  4101.                   else
  4102.                      fets(0,i) = and(fets(0,i),.not.cioodd) 
  4103.                   endif 
  4104.                endif
  4105.             endif 
  4106. 100      continue 
  4107. c$       if(nos .eq. 1) 
  4108.          if (binmode) then
  4109.             call writew(fets(0,stdout),nositm, 5) 
  4110.             call writer(fets(0,stdout)) 
  4111.             if (debug .ne. 0) then
  4112.                call fprintf(debugfd, '^stty - binary.\n') 
  4113.             endif 
  4114.          else 
  4115.             call writew(fets(0,stdout),nosttm, 2) 
  4116.             call writer(fets(0,stdout)) 
  4117.             if (debug .ne. 0) then
  4118.                call fprintf(debugfd, '^stty - normal.\n') 
  4119.             endif 
  4120.          endif
  4121. c$       endif
  4122. c     is it setting transparent (raw) i/o?
  4123.       else if (mode .eq. 'raw') then
  4124.          if (value .eq. 0) then 
  4125.             rawmode = .false. 
  4126.          else 
  4127.             rawmode = .true.
  4128.          endif
  4129.       else
  4130.          call displa(' stty - invalid mode ',bool(mode))
  4131.          call abtp("nd")
  4132.       endif 
  4133.       return
  4134.       end 
  4135.       integer function gtty(mode) 
  4136.   
  4137. ccc   gtty - get a tty mode.
  4138. *call kermcom 
  4139.       character*(*) mode
  4140. c     is it duplex they're looking for? 
  4141.       if (mode .eq. 'duplex') then
  4142.          gtty = duplex
  4143. c     is it parity they're looking for? 
  4144.       else if (mode .eq. 'parity') then 
  4145.          gtty = parity
  4146.       else
  4147.          call displa(' gtty - invalid mode ',bool(mode))
  4148.          call abtp("nd")
  4149.       endif 
  4150.       return
  4151.       end 
  4152.       subroutine as2dpc(astr,dstr)
  4153.   
  4154. ccc   as2dpc - translate an ascii string buffer to dpc char string. 
  4155. c     ascii string is terminated by a zero byte.
  4156. *call kermcom 
  4157.       boolean astr(*) 
  4158.       character dstr*(*)
  4159.       integer clen
  4160.       i = 1 
  4161.       clen = len(dstr)
  4162.       dstr = ' '
  4163. 10    if (astr(i) .ne. 0 .and. i .le. clen) then
  4164.          if (astr(i) .gt. 127) then 
  4165.             call movech(dpctbl(blank),9,dstr,i - 1,1) 
  4166.          else 
  4167.             call movech(dpctbl(astr(i)),9,dstr,i - 1,1) 
  4168.          endif
  4169.          i = i + 1
  4170.          go to 10 
  4171.       endif 
  4172.       return
  4173.       end 
  4174.       integer function asc(dpch)
  4175.   
  4176. ccc   asc - convert a dpc character to lower case ascii.
  4177. *call kermcom 
  4178.       character*1 dpch
  4179.       asc = lascii(ichar(dpch)) 
  4180.       return
  4181.       end 
  4182.       subroutine dpc2as(dstr,astr,nwords) 
  4183. c  translate string of display code characters to uppercase ascii.
  4184. c  string is nwords characters (words) long.
  4185. *call kermcom 
  4186.   
  4187.       character*(*) dstr
  4188.       boolean astr(nwords)
  4189.       do 1 i=1,nwords 
  4190.          astr(i) = uascii((ichar(dstr(i:i)))) 
  4191.     1    continue 
  4192. c     set ascii end-of-string-buffer
  4193.       astr(nwords+1) = 0
  4194.       return
  4195.       end 
  4196.       integer function ctoi(astr) 
  4197.   
  4198. ccc   ctoi - convert character buffer to integer. 
  4199. c     ctoi converts the number using base 10 as a default.
  4200. c     a suffix of h will convert using base 16 and a suffix 
  4201. c     of o will convert using base 8.  default suffix is
  4202. c     d.
  4203. *call kermcom 
  4204.       parameter (dig0=48, dig7=55, dig9=57, biga=65, bigb=66, bigd=68)
  4205.       parameter (bigf=70, bigh=72, bigo=79, leta=97, letb=98, letd=100) 
  4206.       parameter (letf=102, leth=104, leto=111)
  4207.       integer astr(*) 
  4208.   
  4209.       base = 0
  4210.       ptr = 0 
  4211. c     find last valid digit 
  4212. 10    ptr = ptr + 1 
  4213.       if (astr(ptr) .ne. 0) go to 10
  4214.       ptr = ptr - 1 
  4215.       if (astr(ptr) .eq. leto .or. astr(ptr) .eq. bigo .or. 
  4216.      +    astr(ptr) .eq. letb .or. astr(ptr) .eq. bigb .or. 
  4217.      +    astr(ptr) .eq. leth .or. astr(ptr) .eq. bigh) then
  4218.          eod = ptr - 1
  4219.       else
  4220.          eod = ptr
  4221.          ptr = ptr + 1
  4222.       endif 
  4223. c     try to figure out the base
  4224.       if (astr(ptr) .eq. 0) then
  4225.          base = 10
  4226.       else if (astr(ptr) .eq. leto .or. astr(ptr) .eq. bigo .or.
  4227.      +         astr(ptr) .eq. letb .or. astr(ptr) .eq. bigb) then 
  4228.          base = 8 
  4229.       else if (astr(ptr) .eq. leth .or. astr(ptr) .eq. bigh) then 
  4230.          base = 16
  4231.       endif 
  4232. c     if didn't find a base 
  4233.       if (base .eq. 0) then 
  4234.          call fprintf(stdout,'ctoi - invalid base @c\n',astr(ptr),0,0,0)
  4235.          ctoi = 0 
  4236.          return 
  4237.       endif 
  4238. c     add up the digits 
  4239.       total = 0 
  4240.       isneg = 1 
  4241.       do 100 i = 1,eod
  4242.          ch = astr(i) 
  4243.          if (ch .eq. minus) then
  4244.             isneg = -1
  4245.             go to 100 
  4246.          endif
  4247.          if (base .eq. 10) then 
  4248.             if (ch .lt. dig0 .or. ch .gt. dig9) then
  4249.                call fprintf(stdout,'ctoi - invalid decimal digit @c\n', 
  4250.      +                      ch,0,0,0) 
  4251.                ctoi = 0 
  4252.                return 
  4253.             else
  4254.                ch = ch - dig0 
  4255.             endif 
  4256.          else if (base .eq. 8) then 
  4257.             if (ch .lt. dig0 .or. ch .gt. dig7) then
  4258.                call fprintf(stdout,'ctoi - invalid octal digit @c\n', 
  4259.      +                      ch,0,0,0) 
  4260.                ctoi = 0 
  4261.                return 
  4262.             else
  4263.                ch = ch - dig0 
  4264.             endif 
  4265.          else if (base .eq. 16) then
  4266.             if (ch .ge. dig0 .and. ch .le. dig9) then 
  4267.                ch = ch - dig0 
  4268.             else if (ch .ge. leta .and. ch .le. letf) then
  4269.                ch = 10 + ch - leta
  4270.             else if (ch .ge. biga .and. ch .le. bigf) then
  4271.                ch = 10 + ch - biga
  4272.             else
  4273.                call fprintf(stdout,'ctoi - invalid hex digit @c\n', 
  4274.      +                      ch,0,0,0) 
  4275.                ctoi = 0 
  4276.                return 
  4277.             endif 
  4278.          endif
  4279.          total = total*base + ch
  4280. 100   continue
  4281.       ctoi = total * isneg
  4282.       return
  4283.       end 
  4284.       integer function itos(int,str,minwid) 
  4285.   
  4286. ccc   itos - convert an integer to string format. 
  4287. *call kermcom 
  4288.       integer str(*)
  4289.   
  4290.       width = 0 
  4291.       if (int .lt. 0) then
  4292.          width = 1
  4293.          str(width) = asc('-')
  4294.       endif 
  4295.       val = iabs(int) 
  4296.       ascii0 = asc('0') 
  4297. 10    width = width + 1 
  4298.       str(width) = mod(val,10) + ascii0 
  4299.       val = val / 10
  4300.       if (val .ne. 0) go to 10
  4301.       str(width+1) = 0
  4302. c     now reverse the digits
  4303.       iptr = 1
  4304.       endptr = width
  4305.       if (str(iptr) .eq. asc('-')) iptr = iptr + 1
  4306. 20    if (iptr .lt. endptr) then
  4307.          tch = str(iptr)
  4308.          str(iptr) = str(endptr)
  4309.          str(endptr) = tch
  4310.          iptr = iptr + 1
  4311.          endptr = endptr - 1
  4312.          go to 20 
  4313.       endif 
  4314.       itos = width
  4315.       return
  4316.       end 
  4317.       subroutine getemsg(strng) 
  4318.   
  4319. ccc   getemsg - get an error message string for the current error.
  4320. *call kermcom 
  4321.       integer direc(8,2)
  4322.       integer packnam(9,0:6)
  4323.       data direc / 115, 101, 110, 100, 4*0, 
  4324. c                    s    e    n    d 
  4325.      +             114, 101,  99, 101, 105, 118, 101, 0 / 
  4326. c                    r    e    c    e    i    v    e
  4327.       data packnam / 85,  78,  75,  78,  79,  87,  78, 2*0, 
  4328. c                     u    n    k    n    o    w    n 
  4329.      +               73, 110, 105, 116, 5*0,
  4330. c                     i    n    i    t
  4331.      +               70, 105, 108, 101, 110,  97, 109, 101, 0,
  4332. c                     f    i    l    e    n    a    m    e
  4333.      +               68,  97, 116,  97, 5*0,
  4334. c                     d    a    t    a
  4335.      +               69,  79,  70, 6*0, 
  4336. c                     e    o    f 
  4337.      +               66, 114, 101,  97, 107, 4*0, 
  4338. c                     b    r    e    a    k 
  4339.      +               83, 101, 114, 118, 101, 114, 3*0 / 
  4340. c                     s    e    r    v    e    r
  4341.       if ((abortyp.and.initerr) .ne. 0) then
  4342.          ptyp = 1 
  4343.       else if ((abortyp.and.filerr) .ne. 0) then
  4344.          ptyp = 2 
  4345.       else if ((abortyp.and.dataerr) .ne. 0) then 
  4346.          ptyp = 3 
  4347.       else if ((abortyp.and.eoferr) .ne. 0) then
  4348.          ptyp = 4 
  4349.       else if ((abortyp.and.brkerr) .ne. 0) then
  4350.          ptyp = 5 
  4351.       else if ((abortyp.and.srvcmd) .ne. 0) then
  4352.          ptyp = 6 
  4353.       else
  4354.          ptyp = 0 
  4355.       endif 
  4356.       dtyp = shift(abortyp.and.o"300",-6) 
  4357.       if ((abortyp.and.toomany) .ne. 0) then
  4358.          call sprintf(strng,'^cannot @s @s packet',direc(1, 
  4359.      +      dtyp),packnam(1,ptyp),0,0)
  4360.       else if ((abortyp.and.invalid) .ne. 0) then 
  4361.          call sprintf(strng,
  4362.      +  '^received an invalid packet while trying to @s @s packet', 
  4363.      +  direc(1,dtyp),packnam(1,ptyp),0,0)
  4364.       else if ((abortyp.and.seqerr) .ne. 0) then
  4365.          call sprintf(strng,
  4366.      +   '^packet sequence error while trying to @s @s packet', 
  4367.      +   direc(1,dtyp),packnam(1,ptyp),0,0) 
  4368.       else if ((abortyp.and.lclfile) .ne. 0) then 
  4369.          call sprintf(strng,'^file is already local',0,0,0,0) 
  4370.       else if ((abortyp.and.notlcl) .ne. 0) then
  4371.          call sprintf(strng,'^file is not local',0,0,0,0) 
  4372.       else if ((abortyp.and.invfn) .ne. 0) then 
  4373.          call sprintf(strng,'^invalid filename',0,0,0,0)
  4374.       else if ((abortyp.and.srvcmd) .ne. 0) then
  4375.          call sprintf(strng,'^unimplemented server command',0,0,0,0)
  4376.       endif 
  4377.       return
  4378.       end 
  4379.       integer function creat(fn)
  4380.   
  4381. ccc   creat - open a file for writing packet data to. 
  4382. c     creat will try to create a file to write to.  if it 
  4383. c     already exists, then it will fail.
  4384. *call kermcom 
  4385.       character*10 filenam
  4386. c     get the dpc version of the filename 
  4387.       call as2dpc(fn,filenam) 
  4388.       call filchk(filenam)
  4389.       creat = fopen(filenam,create) 
  4390.       return
  4391.       end 
  4392.       subroutine getnow(mm,dd,yy,hr,min,sec)
  4393.   
  4394. ccc   get the current date and time.
  4395. *call kermcom 
  4396.       character*10 date, time, string 
  4397.   
  4398.       string = date() 
  4399.       offset = ichar('0') 
  4400. c$    if (ut2d .eq. 1)
  4401.       dd = (ichar(string(2:2))-offset)*10 + ichar(string(3:3))-offset 
  4402.       mm = -1 
  4403.       if (string(5:7) .eq. 'jan') then
  4404.          mm = 1 
  4405.       else if (string(5:7) .eq. 'feb') then 
  4406.          mm = 2 
  4407.       else if (string(5:7) .eq. 'mar') then 
  4408.          mm = 3 
  4409.       else if (string(5:7) .eq. 'apr') then 
  4410.          mm = 4 
  4411.       else if (string(5:7) .eq. 'may') then 
  4412.          mm = 5 
  4413.       else if (string(5:7) .eq. 'jun') then 
  4414.          mm = 6 
  4415.       else if (string(5:7) .eq. 'jul') then 
  4416.          mm = 7 
  4417.       else if (string(5:7) .eq. 'aug') then 
  4418.          mm = 8 
  4419.       else if (string(5:7) .eq. 'sep') then 
  4420.          mm = 9 
  4421.       else if (string(5:7) .eq. 'oct') then 
  4422.          mm = 10
  4423.       else if (string(5:7) .eq. 'nov') then 
  4424.          mm = 11
  4425.       else if (string(5:7) .eq. 'dec') then 
  4426.          mm = 12
  4427.       endif 
  4428.       yy = (ichar(string(9:9))-offset)*10 + ichar(string(10:10))-offset 
  4429. c$    endif 
  4430. c$    if (nos .eq. 1) 
  4431.       yy = (ichar(string(2:2))-offset)*10 + ichar(string(3:3))-offset 
  4432.       mm = (ichar(string(5:5))-offset)*10 + ichar(string(6:6))-offset 
  4433.       dd = (ichar(string(8:8))-offset)*10 + ichar(string(9:9))-offset 
  4434. c$    endif 
  4435. c$    if (nosbe .eq. 1) 
  4436.        dd = (ichar(string(5:5))-offset)*10 + ichar(string(6:6))-offset
  4437.        mm = (ichar(string(2:2))-offset)*10 + ichar(string(3:3))-offset
  4438.        yy = (ichar(string(8:8))-offset)*10 + ichar(string(9:9))-offset
  4439. c$    endif 
  4440.       yy = yy + 1900
  4441.       string = time() 
  4442.       hr  = (ichar(string(2:2))-offset)*10 + ichar(string(3:3))-offset
  4443.       min = (ichar(string(5:5))-offset)*10 + ichar(string(6:6))-offset
  4444.       sec = (ichar(string(8:8))-offset)*10 + ichar(string(9:9))-offset
  4445.       return
  4446.       end 
  4447.       subroutine filchk(fn) 
  4448.   
  4449. ccc   filchk - check and fix filename validity. 
  4450. c     check validity of filename.  invalid characters are dropped 
  4451. c     and the filename is truncated at 7 characters.  if there
  4452. c     is still not a valid filename (all characters were bad) then
  4453. c     use file kermdat. 
  4454. *call kermcom 
  4455.       boolean ch
  4456.       character *(*) fn 
  4457.       integer ptr,length
  4458.       ptr = 0 
  4459.       length = len(fn)
  4460.       do 2 i=1,7
  4461.     1    ptr = ptr + 1
  4462.          if (ptr .gt. length) go to 3 
  4463.          ch = ichar(fn(ptr:ptr))
  4464.          if (ch .lt. 1 .or. ch .gt. 36) go to 1 
  4465.          fn(i:i)=fn(ptr:ptr)
  4466.     2 continue
  4467.       i = 8 
  4468.     3 if (length .gt. 7) then 
  4469.          do 4 j=i,length
  4470.             fn(j:j) = ' ' 
  4471.     4    continue 
  4472.       endif 
  4473. c     use our magic file if no valid characters in the file name. 
  4474. c     this can happen as some micros allow things like '&' for
  4475. c     a file name.  note that nos allows a digit in the first 
  4476. c     character of an lfn while scope and nos/be do not.
  4477. c$    if(ut2d .eq. 1 .or. nosbe .eq. 1  .or.  scope .eq. 1) 
  4478.       if(ichar(fn(1:1)) .lt. 1  .or.  ichar(fn(1:1)) .gt. 26) 
  4479.      +  fn = 'kermdat'
  4480. c$    else
  4481.       if(ichar(fn(1:1)) .lt. 1  .or.  ichar(fn(1:1)) .gt. 36) 
  4482.      +  fn = 'kermdat'
  4483. c$    endif 
  4484.       return
  4485.       end 
  4486.       subroutine rdparam(pdata) 
  4487.   
  4488. ccc   rdparam - get the packet parameters from the other kermit.
  4489. *call kermcom 
  4490.       boolean pdata(*)
  4491.       integer params(11)
  4492.       equivalence (params,spksiz) 
  4493. c     define ctl and unchar statement functions 
  4494.       ctl(ascch) = ascch .xor. o"100" 
  4495.       unchar(ascch) = ascch - blank 
  4496. c     cycle through the list of parameters until the end-of-list
  4497. c     is found (a 0 byte).
  4498.       i = 1 
  4499. 10    if (pdata(i) .ne. 0) then 
  4500. c        is it the pad character? 
  4501.          if (i .eq. 4) then 
  4502.             params(i) = ctl(pdata(i)) 
  4503.             if (params(i) .eq. 0) params(i) = null
  4504. c        is it the quote character? 
  4505.          else if (i .eq. 6) then
  4506.             params(i) = pdata(i)
  4507.          else 
  4508.             if (unchar(pdata(i)) .ne. 0) then 
  4509.                params(i) = unchar(pdata(i)) 
  4510.             endif 
  4511.          endif
  4512.          i = i + 1
  4513.          go to 10 
  4514.       endif 
  4515.       return
  4516.       end 
  4517.       subroutine remove(fn) 
  4518.   
  4519. ccc   remove - remove a file from the local file list.
  4520. *call kermcom 
  4521.       boolean fn(*) 
  4522.       character*10 lfn
  4523. c     quit if nothing useful in the file name array.
  4524.       if(fn(1) .eq. 0) return 
  4525. c     convert the file name to display code.
  4526.       call as2dpc(fn,lfn) 
  4527. c     get rid of the file.
  4528.       call retfile(lfn) 
  4529.       return
  4530.       end 
  4531.       subroutine strcpy(s1,s2)
  4532.   
  4533. ccc   strcpy - copy one ascii string to another 
  4534. *call kermcom 
  4535.       boolean s1(*),s2(*) 
  4536.   
  4537.       i1 = 1
  4538. 10    s2(i1) = s1(i1) 
  4539.       if (s1(i1) .ne. 0) then 
  4540.          i1 = i1 + 1
  4541.          go to 10 
  4542.       endif 
  4543.       return
  4544.       end 
  4545.       integer function slen(str)
  4546.   
  4547. ccc   slen - return the length of a zero terminated ascii string buffer.
  4548. *call kermcom 
  4549.       boolean str(*)
  4550.   
  4551.       i = 0 
  4552. 10    if (str(i+1) .ne. 0) then 
  4553.          i = i + 1
  4554.          go to 10 
  4555.       endif 
  4556.       slen = i
  4557.       return
  4558.       end 
  4559.       integer function sndpar(pdata)
  4560.   
  4561. ccc   sndpar - set up parameters to send to other kermit. 
  4562. *call kermcom 
  4563.       boolean pdata(*)
  4564. c     define ctl and tochar statement functions 
  4565.       ctl(ascch) = ascch .xor. o"100" 
  4566.       tochar(ascch) = ascch + blank 
  4567. c     send what we want 
  4568.       pdata(1) = tochar(packsiz)
  4569.       pdata(2) = tochar(timeout)
  4570.       pdata(3) = tochar(npad) 
  4571.       pdata(4) = ctl(padch) 
  4572.       pdata(5) = tochar(eolch)
  4573.       pdata(6) = quotech
  4574.       pdata(7) = 0
  4575. c     return length of how many things we want to set 
  4576.       sndpar = 6
  4577. c     other values are set by default to not operate
  4578.       return
  4579.       end 
  4580.       subroutine sleep(seconds) 
  4581.   
  4582. cc    sleep - use periodic recall to delay things.
  4583. c     entry   seconds = integer number of seconds to sleep. 
  4584. c     exit    indicated number of seconds has elapsed.
  4585. *call kermcom 
  4586.   
  4587.       do 100 i=1,seconds
  4588.          call delay(1000) 
  4589. 100   continue
  4590.       return
  4591.       end 
  4592.       subroutine delay(msec)
  4593.   
  4594. cc    delay - delay for a few milliseconds. 
  4595. c     entry   msec = delay time in milliseconds.
  4596. c     exit    time has elapsed. 
  4597. c     notes   works for scope, ut2d, and nos/be systems.  nos users must
  4598. c             change the computation to account for the difference
  4599. c             in data returned by rtime macro.
  4600. *call kermcom 
  4601. c    use real time clock to control delay period. 
  4602.       call rtime(rtcl)
  4603.       rtcl = and(rtcl,compl(mask(24)))
  4604. 10    call rtime(rtcl1) 
  4605.       rtcl1 = and(rtcl1,compl(mask(24)))
  4606. c     convert from seconds/4096 to milliseconds.
  4607.       if((rtcl1-rtcl)/4.096 .gt. msec) return 
  4608. c     sleep for 100 milliseconds. 
  4609.       call recall(0)
  4610.       go to 10
  4611.   
  4612.       end 
  4613.       subroutine echoplx(ecmode)
  4614.   
  4615.   
  4616. ***   echoplx - set echoplex mode for 2550 front end. 
  4617. *     depends on u of arizona modifications to cci, plus a u of 
  4618. *     arizona pp routine 'uui'.  this subroutine is only called 
  4619. *     from stty if uariz is defined.
  4620. *     entry   ecmode = 'on' or 'off' to enable or disable echoplex. 
  4621. *     exit    uui called to change echoplex mode. 
  4622.   
  4623.   
  4624. *call kermcom 
  4625.   
  4626. c     don't compile if not university of arizona
  4627. c$    if (uariz .eq. 1) 
  4628.       boolean echofnc, echooff, echoon, uuiwd 
  4629.       character*(3) ecmode
  4630.       parameter (echofnc=o"10",echooff=0,echoon=1)
  4631.   
  4632.       if(ecmode .eq. 'on') then 
  4633.           uuiwd = or(shift(echoon,12),echofnc)
  4634.       elseif(ecmode .eq. 'off') then
  4635.           uuiwd = or(shift(echooff,12),echofnc) 
  4636.       else
  4637.           call remark(' kermit - invalid echoplex option.') 
  4638.           call abtp("nd") 
  4639.       endif 
  4640.       call mtr(l"uui","rcl",locf(uuiwd))
  4641.   
  4642. *     nudge 2550 into processing the reconfiguration message
  4643. *     sent by the uui call, so echo gets fully reset, even if 
  4644. *     next kermit operation is a read, not a write. 
  4645.   
  4646.       call putc(null,stdout)
  4647.       call fflush(stdout) 
  4648. c$    endif 
  4649.       return
  4650.   
  4651.       end 
  4652.       integer function getrec(fd,wsa,wsal,eofflag)
  4653.   
  4654. cc    getrec - get a record from a file.
  4655. c     nread = getrec(fd,wsa,wsal,eofflag) 
  4656. c     entry   fd = file descriptor. 
  4657. c             wsal = length of wsa. 
  4658. c     exit    wsa contains data record. 
  4659. c             nread = number of words actually placed in wsa
  4660. c             eofflag = .true. if eof hit (iff nread .eq. 0). 
  4661. c     notes   performs display to ascii conversion if needed. 
  4662.   
  4663. *call kermcom 
  4664.   
  4665.       parameter (intrcom = 42, asc128 = 22, asc256 = 23)
  4666.       parameter (first = 1, in = 2, out = 3, limit = 4, intwd = 5)
  4667.       boolean status, wsa(wsal) 
  4668.       logical eofflag 
  4669.   
  4670.       eofflag = .false. 
  4671. c     start read if possible, and determine disk character set
  4672. c     if not in raw data mode.
  4673. 1     if(.not. ctdev(fd)  .and.  and(fets(0,fd),o"1") .eq. o"1") then 
  4674.           if(fets(in,fd) .eq. fets(out,fd)  .and. 
  4675.      +      and(fets(0,fd),o"20") .eq. 0) then
  4676.               call read(fets(0,fd)) 
  4677.               if(.not. rawmode) then
  4678.                   cset = xscs(fets(0,fd)) 
  4679.                   if(cset .eq. 0) go to 1 
  4680.                   if (cset .eq. -1) then
  4681.                      dskcset = dsknos8
  4682. c$    if (ut2d .eq. 1)
  4683. c     must set nos bit for screwy coded read routines 
  4684.                      fets(first,fd) = fets(first,fd)
  4685.      +                  .or.shift(1,nosbit) 
  4686. c$    endif 
  4687.                   elseif(cset .eq. -2) then 
  4688.                      dskcset = dskut8 
  4689. c$    if (ut2d .eq. 1)
  4690. c     must clear nos bit for screwy coded read routines 
  4691.                      fets(first,fd) = and(fets(first,fd), 
  4692.      +                  .not.shift(1,nosbit)) 
  4693. c$    endif 
  4694.                   endif 
  4695.                   if(cset .lt. 0) then
  4696. c$    if (ut2d .eq. 1)
  4697. c     these are needed for strange coded read routines. 
  4698.                      fets(first,fd) = fets(first,fd).or.shift(1,asciiio)
  4699. c$    endif 
  4700.                   else
  4701.                      dskcset = dskdpc 
  4702. c$    if (ut2d .eq. 1)
  4703.                      fets(first,fd) = and(fets(first,fd), 
  4704.      +                  .not.shift(1,asciiio))
  4705. c$    endif 
  4706.                   endif 
  4707.               endif 
  4708.           endif 
  4709.       endif 
  4710. c     process terminal devices. 
  4711.       if(ctdev(fd)) then
  4712. c$    if (ut2d .eq. 1) then 
  4713.          fets(first,fd) = or(fets(first,fd),shift(1,asciiio)) 
  4714. c$    else
  4715.           fets(first,fd) = or(fets(first,fd),shift(1,intrcom))
  4716.           fets(intwd,fd) = shift(1,asc128)
  4717.           if(binmode .or. rawmode) fets(intwd,fd) = shift(1,asc256) 
  4718. c$    endif 
  4719. c$    if (nos .eq. 1) 
  4720. c$    if (noslvl .ge. 602)
  4721. c        wait for input checking for timeout on read
  4722.           if (binmode .or. rawmode) then
  4723.              nosdlay = stimout * 1000 
  4724.           else
  4725.              nosdlay = rdelay 
  4726.           endif 
  4727.           do 10 irdl = 1, nosdlay, 24 
  4728.           if (nosctab().ne.0) goto 11 
  4729.           call noswait
  4730. 10        continue
  4731.           if (binmode .or. rawmode) then
  4732.              call remark(' kermit - read timeout....')
  4733.           endif 
  4734. c$    else
  4735.           if (rdelay .gt. 0) call delay(rdelay) 
  4736. c$    endif 
  4737. 11        continue
  4738. c$    else
  4739.           if (rdelay .gt. 0) call delay(rdelay) 
  4740. c$    endif 
  4741.           call readc(fets(0,fd),wsa,wsal,status)
  4742.           if(status .eq. 0) then
  4743.               nread = wsal
  4744.           elseif(status .lt. 0) then
  4745. c$    if (nos .eq. 1) 
  4746.               nread = 0 
  4747. c        give poor user another prompt
  4748.               if ((.not. rawmode) .and. (.not. binmode)) then 
  4749.                  call memstat 
  4750.                  call fprintf(stdout,'^kermit-170>',0,0,0,0)
  4751.                  call fflush(stdout)
  4752.                  call writer(fets(0,stdout))
  4753.                  call read(fets(0,fd))
  4754.               endif 
  4755.               goto 1
  4756. c$    else
  4757.               nread = 0 
  4758.               eofflag = .true.
  4759. c$    endif 
  4760.           else
  4761.               nread = status - locf(wsa)
  4762.               fets(0,fd) = or(and(fets(0,fd),shift(mask(44),2)),ciord)
  4763.               if(nread .le. 0) go to 1
  4764.           endif 
  4765. c$    if (nos .eq. 1) 
  4766.           if (nread .gt. 0) call conbuff(wsa, nread, eofflag, status) 
  4767. c$    endif 
  4768.           getrec = nread
  4769.           if(nread .gt. 0) getrec = findeol(wsa,nread,.not. binmode)
  4770.       else
  4771. c     process mass storage (disk) files.
  4772.           if(rawmode) then
  4773.               call readw(fets(0,fd),wsa,wsal,status)
  4774.           elseif((dskcset.and.dskasci) .ne. 0) then 
  4775.               call readc(fets(0,fd),wsa,wsal,status)
  4776.           else
  4777.               call readc(fets(0,fd),wsa(wsal / 2 + 1),wsal / 2, status) 
  4778.               if(status .ge. 0) then
  4779.                   call edl(wsa,wsa(wsal / 2 + 1),wsal / 2,status) 
  4780.               endif 
  4781.           endif 
  4782. c     process mass storage (disk) file status return. 
  4783.           if(status .eq. 0) then
  4784.               getrec = findeol(wsa,wsal,.not. rawmode)
  4785.           elseif(status .gt. 0) then
  4786.               getrec = findeol(wsa,status - locf(wsa),.not. rawmode)
  4787.               fets(0,fd) = or(and(fets(0,fd),shift(mask(44),2)),ciord)
  4788.               if(getrec .le. 0) go to 1 
  4789.           elseif(status .eq. -1) then 
  4790.               getrec = 0
  4791.               fets(0,fd) = or(and(fets(0,fd),shift(mask(44),2)),ciord)
  4792. c$    if (ut2d .eq. 1) then 
  4793.               eofflag = .true.
  4794. c$    else
  4795.               go to 1 
  4796. c$    endif 
  4797.           else
  4798.               getrec = 0
  4799.               eofflag = .true.
  4800.           endif 
  4801.       endif 
  4802.       return
  4803.       end 
  4804.       integer function findeol(wsa,wsal,addnel) 
  4805.   
  4806. cc    findeol - find eol byte in working buffer.
  4807. c     len = findeol(wsa,wsal,addnel)
  4808. c     entry   wsa = line image. 
  4809. c             wsal = length of wsa. 
  4810. c             addnel = .true. if a nel should be stuffed in buffer. 
  4811. c     exit    len = length of data line in words. 
  4812.   
  4813. *call kermcom 
  4814.   
  4815.       boolean wsa(wsal) 
  4816.       logical addnel
  4817. c     if the line length is zero, return zero length. 
  4818.       if(wsal .le. 0) then
  4819.           findeol = 0 
  4820.           return
  4821.       endif 
  4822. c     find eol, and stick nel in if needed. 
  4823.       do 10 i = 1, wsal 
  4824.           if((and(wsa(i),o"7777") .eq. 0) .or.
  4825.      +       (and(wsa(i),o"7777") .eq. nel)) then 
  4826.             if(addnel .and. (dskcset.ne.dskut8)) wsa(i) = or(wsa(i),nel)
  4827.             findeol = i 
  4828.             return
  4829.           endif 
  4830. 10    continue
  4831.       if(addnel) wsa(wsal) = or(and(wsa(wsal),mask(48)),nel)
  4832.       findeol = wsal
  4833.       return
  4834.       end 
  4835.       subroutine edl(ascbuf,dpcbuf,dpcbufl,status)
  4836.   
  4837. cc    edl - expand display code line. 
  4838. c     call edl(ascbuf,dpcbuf,dpcbufl,status)
  4839. c     entry   dpcbuf = display code line image. 
  4840. c             dpcbufl = dimensioned size of dpcbuf. 
  4841. c             status = readc status.
  4842. c     exit    ascbuf = ascii line.
  4843. c             status = lwa + 1 of data converted, iff status was
  4844. c             non-zero on entry to edl. 
  4845. c     notes   edl must not be called with negative status values. 
  4846.   
  4847. *call kermcom 
  4848.   
  4849.       boolean ascbuf(*), dpcbuf(dpcbufl), dpcch, status, tempdpc
  4850. c     determine number of words in buffer (worst case). 
  4851.       wc = dpcbufl
  4852.       if(status .gt. 0) wc = status - locf(dpcbuf)
  4853.       if(wc .le. 0) then
  4854.           status = locf(ascbuf) 
  4855.           return
  4856.       endif 
  4857. c     now scan for zero byte. 
  4858.       do 10 i = 1, wc 
  4859.           if(and(dpcbuf(i),o"7777") .eq. 0) go to 1 
  4860. 10    continue
  4861. c     no eol was found, so we force one in the last word. 
  4862.       i = wc
  4863.       dpcbuf(i) = and(dpcbuf(i),mask(48)) 
  4864. c     at this point, 'i' contains the position of the eol word. 
  4865. 1     eolwd = i 
  4866.       ascbuf(1) = 0 
  4867.       if(eolwd .eq. 1  .and.  dpcbuf(eolwd) .eq. 0) return
  4868.       if(eolwd .gt. 1  .and.  dpcbuf(eolwd) .eq. 0  .and. 
  4869.      +  and(dpcbuf(eolwd - 1),o"77") .eq. 0) eolwd = eolwd - 1
  4870. c     now we convert everything up to the eol word, but not the eol word
  4871. c     itself, as we do not want to 'convert' the line terminator. 
  4872.       wc = 0
  4873.       if(eolwd .gt. 1) then 
  4874.           call xsxt(dpcbuf,eolwd - 1,ascbuf,uascii) 
  4875.           wc = 2 * (eolwd - 1)
  4876.       endif 
  4877. c     now convert the eol word.  code can handle overlapping buffers. 
  4878.       wc = wc + 1 
  4879.       tempdpc = dpcbuf(eolwd) 
  4880.       ascbuf(wc) = 0
  4881.       ascbuf(wc + 1) = 0
  4882.       do 20 i = 0, 9
  4883.           tempdpc = shift(tempdpc,6)
  4884.           dpcch = and(tempdpc,o"77")
  4885.           tempdpc = and(tempdpc,mask(54)) 
  4886.           if(tempdpc .eq. 0  .and. dpcch .eq. 0) then 
  4887.               if(status .gt. 0) status = locf(ascbuf(wc + i / 5)) + 1 
  4888.               return
  4889.           endif 
  4890.           ascbuf(wc + i / 5) = or(ascbuf(wc + i / 5), 
  4891.      +      shift(uascii(dpcch),60 - 12 * (mod(i,5) + 1)))
  4892. 20    continue
  4893.       if(status .gt. 0) status = locf(ascbuf(wc + 1)) + 1 
  4894.       return
  4895.       end 
  4896.           ident  makefet
  4897.           entry  makefet
  4898.           sst 
  4899.           syscom b1 
  4900.  makefet  title  makefet - make a file environment table. 
  4901.           comment make a file environment table.
  4902.  makefet  space  4,10 
  4903. **        makefet - make a file environment table.
  4904. *         call makefet(lfn,fet,fetl,ciobuf,ciobufl) 
  4905. *         entry  (lfn) = is the character*7 file name.
  4906. *                (fet) = an array to receive the fet. 
  4907. *                (fetl) = length of fet in words (minimum of 5).
  4908. *                (ciobuf) = an array to be used as the cio buffer.
  4909. *                (ciobufl) = the length of ciobuf.
  4910. *         exit   fet built. 
  4911.   
  4912.   
  4913.  makefet  subr               entry/exit 
  4914.           sb1    1           always 
  4915.           sa2    a1+b1
  4916.           sb6    x2          (b6) = fet address 
  4917.           sa2    a2+b1
  4918.           sa3    x2          (x3) = fet length
  4919.           sa2    a2+b1
  4920.           sx6    x2          (x6) = fwa of cio buffer 
  4921.           sa2    a2+b1
  4922.           sa2    x2          (x2) = buffer length 
  4923.           ix7    x6+x2       (x7) = limit pointer 
  4924.           sa6    b6+2        set in and out 
  4925.           sa6    a6+b1
  4926.           sa7    a6+b1       set limit
  4927.           sx7    x3-5        (x7) = fet length - 5
  4928.           sb7    x7 
  4929.           lx7    18 
  4930.           bx6    x6+x7       add (fet length - 5) to first
  4931.           sa6    b6+b1       set first
  4932.           mx7    0
  4933.  makefet1 gt     b7,b0,makefet2  if no more words to set
  4934.           sa7    a7+b1
  4935.           sb7    b7-b1
  4936.           eq     makefet1    loop till done 
  4937.   
  4938.  makefet2 sb7    b1          length of transfer 
  4939.           rj     =xmfs>      move lfn into fet
  4940.           sa1    b6-b1
  4941.           rj     =xbtz>      convert blanks to 00b
  4942.           sx1    b1          add complete bit to lfn
  4943.           bx6    x6+x1
  4944.           sa6    a1 
  4945.           eq     makefetx    return 
  4946.   
  4947.           end 
  4948. *if def,nosbe 
  4949.           ident  cfe
  4950.           entry  cfe
  4951.           syscom b1 
  4952.  cfe      title  cfe - check files existance. 
  4953.           comment check files existance.
  4954.  cfe      space  4,10 
  4955. **        cfe - check files existance.
  4956. *         logical cfe, result 
  4957. *         result =  cfe(lfn)
  4958. *         entry  (lfn) = is the character*7 file name.
  4959. *         exit   (result) = .true. if file exists.
  4960. *                (result) = .false. otherwise.
  4961.   
  4962.   
  4963.  cfe      subr               entry/exit 
  4964.           sb1    1           always 
  4965.           sb6    cfea 
  4966.           sb7    b1 
  4967.           rj     =xmfs>      move lfn into filinfo block
  4968.           sa1    cfea 
  4969.           rj     =xbtz>      convert blanks to 00b
  4970.           sx1    4           block length 
  4971.           lx1    12 
  4972.           bx6    x6+x1
  4973.           sa6    a1 
  4974.           mx7    0           clear rest of block
  4975.           sa7    a6+b1
  4976.           sa7    a7+b1
  4977.           sa7    a7+b1
  4978.           sa7    a7+b1
  4979.           filinfo cfea       check on file
  4980.           mx6    0           assume no file (.false.) 
  4981.           mx7    12 
  4982.           sa1    cfea+1 
  4983.           bx7    x7*x1       (x7) = device code if file exists, or 0
  4984.           zr     x7,cfex     if no file 
  4985.           mx6    -1          set file found (.true.)
  4986.           eq     cfex        return 
  4987.   
  4988.  cfea     vfd    42/**,6/4,12/0  filinfo block
  4989.           bssz   4
  4990.   
  4991.           end 
  4992. *endif
  4993. *if -def,nosbe
  4994.           ident  cfe
  4995.           entry  cfe
  4996.           sst 
  4997.           syscom b1 
  4998.  cfe      title  cfe - check files existance. 
  4999.           comment check files existance.
  5000.  cfe      space  4,10 
  5001. **        cfe - check files existance.
  5002. *         logical cfe, result 
  5003. *         result =  cfe(lfn)
  5004. *         entry  (lfn) = is the character*7 file name.
  5005. *         exit   (result) = .true. if file exists.
  5006. *                (result) = .false. otherwise.
  5007.   
  5008.   
  5009.  cfe      subr               entry/exit 
  5010.           sb1    1           always 
  5011.           sb6    cfea 
  5012.           sb7    b1 
  5013.           rj     =xmfs>      move lfn into filinfo block
  5014.           sa1    cfea 
  5015.           rj     =xbtz>      convert blanks to 00b
  5016.           sx1    b1          set complete 
  5017.           bx6    x6+x1
  5018.           sa6    a1 
  5019.           mx7    0           clear rest of block
  5020.           sa7    a6+b1
  5021.           sa7    a7+b1
  5022.           sa7    a7+b1
  5023.           sa7    a7+b1
  5024.           status cfea        check on file
  5025.           mx6    0           assume no file (.false.) 
  5026.           mx7    11 
  5027.           lx7    12 
  5028.           sa1    cfea 
  5029.           bx7    x7*x1       (x7) = 0 if file doesn't exist 
  5030.           zr     x7,cfex     if no file 
  5031.           mx6    -1          set file found (.true.)
  5032.           eq     cfex        return 
  5033.   
  5034. cfea      bssz   1           fake fet 
  5035.   
  5036.           end 
  5037. *endif
  5038.       subroutine conbuff (buf, wc, eofflag, status) 
  5039. *call,kermcom 
  5040. c$    if (nos .eq. 1) 
  5041.       boolean buf(1), nosbuf(maxwd) 
  5042.       logical eofflag, conbug 
  5043.       data  conbug / .false. /
  5044.   
  5045. c     check for special *eof* flag. 
  5046.   
  5047.       if (wc .eq. 1 .and. buf(1) .eq. shift(r"^<",48)) then 
  5048.          wc = 0 
  5049.          eofflag = .true. 
  5050.          return 
  5051.       endif 
  5052.   
  5053. c     copy the buffer first 
  5054.   
  5055.       savewc = wc 
  5056.       do 1 i = 1, wc
  5057. 1     nosbuf(i) = buf(i)
  5058.   
  5059.       if (debug .ne. 0 .and. conbug) then 
  5060.          call fprintf(debugfd, 'conbuff called.\n',0,0,0,0) 
  5061.       endif 
  5062.   
  5063.       ips = 0 
  5064.       ipw = 1 
  5065.       ops = 60
  5066.       opw = 1 
  5067.       buf(opw) = 0
  5068. c     now scan for zero byte. 
  5069.       do 2 i = 1, wc
  5070.           if(and(nosbuf(i),o"7777") .eq. 0) go to 3 
  5071. 2     continue
  5072. c     no eol was found, so we force one in the last word. 
  5073.       i = wc
  5074.       nosbuf(i) = and(nosbuf(i),mask(48)) 
  5075. c     at this point, 'i' contains the position of the eol word. 
  5076. 3     eolwd = i 
  5077.       if(eolwd .eq. 1  .and.  nosbuf(eolwd) .eq. 0) return
  5078. c        check for the famous 66-bit end-of-line!!! 
  5079.       if(eolwd .gt. 1  .and.  nosbuf(eolwd) .eq. 0  .and. 
  5080.      +  and(nosbuf(eolwd - 1),o"77") .eq. 0) eolwd = eolwd - 1
  5081.   
  5082. c     calculate the character position of the last *real* character!
  5083.   
  5084.       do 4 j = 6, 54, 6 
  5085.       if ((compl(mask(60-j)) .and. nosbuf(eolwd)) .ne. 0) then
  5086.          lps = 72 - j 
  5087.          goto 5 
  5088.       endif 
  5089. 4     continue
  5090.       lps = 6 
  5091. c     now convert the characters! 
  5092. 5     nose = 0
  5093.       lch = 0 
  5094.       if (debug .ne. 0 .and. conbug) then 
  5095.          call fprintf(debugfd,' conbuff - wc @d\n', wc,0,0,0) 
  5096.          call fprintf(debugfd,' conbuff - el @d\n', eolwd,0,0,0)
  5097.          call fprintf(debugfd,' conbuff - ls @d\n', lps,0,0,0)
  5098.       endif 
  5099.   
  5100. 10    ips = ips + 6 
  5101.       if (ips .eq. 66) then 
  5102.          ips = 6
  5103.          ipw = ipw + 1
  5104.       endif 
  5105.       if (debug .ne. 0 .and. conbug) then 
  5106.          call fprintf(debugfd,' conbuff - is @d\n', ips,0,0,0)
  5107.          call fprintf(debugfd,' conbuff - iw @d\n', ipw,0,0,0)
  5108.       endif 
  5109.       if (ipw .eq. eolwd .and. ips .ge. lps) then 
  5110.          if (.not.rawmode) then 
  5111.             ch = nel
  5112.             lch = nel 
  5113.             goto 40 
  5114.          else 
  5115.             goto 50 
  5116.          endif
  5117.       endif 
  5118.   
  5119.       ich = and(shift(nosbuf(ipw), ips), o"77") 
  5120.       if (debug .ne. 0 .and. conbug) then 
  5121.          call fprintf(debugfd,' conbuff - ich @d\n', ich,0,0,0) 
  5122.       endif 
  5123.   
  5124.       if (nose .eq. 0) then 
  5125.          if (ich .eq. r"@") then
  5126.             nose = ich
  5127.          else if (ich .eq. r"^") then 
  5128.             nose = ich
  5129.          else if (ich .ge. r"a" .and. ich .le. r"z") then 
  5130.             if (.not.(binmode .or. rawmode)) then 
  5131.                ch = lascii(ich) 
  5132.             else
  5133.                ch = uascii(ich) 
  5134.             endif 
  5135.          else 
  5136.             ch = uascii(ich)
  5137.          endif
  5138.       else if (nose .eq. r"^") then 
  5139.          nose = 0 
  5140.          if (ich .ge. r"a" .and. ich .le. r"z") then
  5141.             ch = lascii(ich)
  5142.          else if (ich .ge. r"0" .and. ich .le. r"4") then 
  5143.             ch = ich + o"140" 
  5144.          else if (ich .ge. r"5" .and. ich .le. r";") then 
  5145.             ch = ich - o"40"
  5146.             if (ch .eq. 0) ch = nul 
  5147.          else 
  5148.             ch = nul
  5149.          endif
  5150.       else if (nose .eq. r"@") then 
  5151.          nose = 0 
  5152.          if (ich .eq. r"a") then
  5153.             ch = lascii(r"@") 
  5154.          else if (ich .eq. r"b") then 
  5155.             ch = lascii(r"^") 
  5156.          else if (ich .eq. r"d") then 
  5157.             ch = lascii(r":") 
  5158.          else if (ich .eq. r"g") then 
  5159.             ch = o"140" 
  5160.          else if (ich .eq. r"h") then 
  5161.             ch = cr 
  5162.          else if (ich .eq. r"i") then 
  5163.             ch = lf 
  5164.          else 
  5165.             ch = nul
  5166.          endif
  5167.       endif 
  5168. c        process this character.
  5169.       if (nose .ne. 0) then 
  5170.          goto 10
  5171.       else if (ch .lt. 0) then
  5172.          goto 10
  5173.       else if (ch .eq. lf .and. .not. rawmode) then 
  5174.          goto 10
  5175.       else if (ch .eq. cr .and. .not. rawmode) then 
  5176.          ch = nel 
  5177.       else if (ch .eq. nul .and. .not. rawmode) then
  5178.          goto 10
  5179.       endif 
  5180. c        really process the character.
  5181. 40    if (debug .ne. 0 .and. conbug) then 
  5182.          call fprintf(debugfd,' conbuff - ich @d\n', ich,0,0,0) 
  5183.          call fprintf(debugfd,' conbuff -  ch @d\n',  ch,0,0,0) 
  5184.          call fprintf(debugfd,' conbuff -  ch @c\n',  ch,0,0,0) 
  5185.       endif 
  5186. c        put it in the buffer 
  5187.       if (ops .eq. 0) then
  5188.          ops = 48 
  5189.          opw = opw + 1
  5190.          buf(opw) = 0 
  5191.       else
  5192.          ops = ops - 12 
  5193.       endif 
  5194.       buf(opw) = buf(opw) .or. shift(ch,ops)
  5195.       if (lch .eq. 0) goto 10 
  5196.   
  5197. c        we are now done. 
  5198.   
  5199. 50    wc = opw
  5200.       if (debug .ne. 0 .and. conbug) then 
  5201.          call fprintf(debugfd, ' conbuff exited.\n',0,0,0,0)
  5202.       endif 
  5203. c$    endif 
  5204.       return
  5205.       end 
  5206.