home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / d / ncrker.jar < prev    next >
Text File  |  2020-01-01  |  576KB  |  18,061 lines

  1. This file, NCRKER.JAR, is a "join archive".  It contains the following files
  2. for NCR 9800 Kermit:
  3.  
  4.         CKCDEB   H    IVS / MCS-Kermit header file
  5.         CKVFN2   C    IVS / MCS-Kermit C source module
  6.         CKVFNS   C    IVS / MCS-Kermit C source module
  7.         CKCKER   H    IVS / MCS-Kermit header file
  8.         CKVMAI   C    IVS / MCS-Kermit C source module
  9.         CKVPRO   C    IVS / MCS-Kermit C source module
  10.         CKUSYM   H    IVS / MCS-Kermit header file
  11.         CKVCMD   C    IVS / MCS-Kermit C source module
  12.         CKUCMD   H    IVS / MCS-Kermit header file
  13.         CKVCON   C    IVS / MCS-Kermit C source module
  14.         CKVDIA   C    IVS / MCS-Kermit C source module
  15.         CKVFI2   C    IVS / MCS-Kermit C source module
  16.         CKVSCR   C    IVS / MCS-Kermit C source module
  17.         CKVTIO   C    IVS / MCS-Kermit C source module
  18.         CKVUS2   C    IVS / MCS-Kermit C source module
  19.         CKVUS3   C    IVS / MCS-Kermit C source module
  20.         CKVUSR   C    IVS / MCS-Kermit C source module
  21.         CKUUSR   H    IVS / MCS-Kermit header file
  22.         CKVFIO   C    IVS / MCS-Kermit C source module
  23.         CKVMCS   C    MCS-Kermit C source module  MCSONLY
  24.                       MCS system I/F routines
  25.         CKVBUF   C    MCS-Kermit C source module
  26.                       Buffering routines for MCS I/F
  27.         COMPILE  INS  Compilation instructions
  28.         KERMISC  H    IVS / MCS-Kermit header file
  29.         IVSKPM   PRO  SCL routine to execute IVS-Kermit
  30.         MCS      H    MCS-Kermit header file: used to
  31.                       redefine fgets, fputs, etc.
  32.         MCS_DEFS H    MCS control structures
  33.         MCSKJ    N3   SCL jobfile to execute MCS-Kermit
  34.         PWD      H    IVS / MCS-Kermit header file*
  35.         SGTTY    H    IVS / MCS-Kermit header file*
  36.         SIGNAL   H    IVS / MCS-Kermit header file*
  37.         TYPES    H    IVS / MCS-Kermit header file*
  38.         VKNCRLIO NCR  IVS / MCS-Kermit C source module
  39.         VRX      H    IVS / MCS-Kermit header file
  40.         MCSKNDLJ N3   NDL compilation jobfile to specify
  41.                       terminal / queue characterisitics,
  42.                       and produce NDL object.
  43.         LINKMCS  PRO  LinkEdit SCL procedure file used
  44.                       to link MCS-Kermit
  45.         LNK1KSRC N3   LinkEdit jobfile used to link
  46.                       IVS-Kermit
  47.  
  48.   * These files do not exist on a VRX/VE system, they are
  49.     placed in either the compilation catalog node or disk.
  50.  
  51. Each file begins with a line having the filename enclosed in triple angle
  52. brackets, for example <<< kerm.doc >>>.  All the lines up to the next
  53. <<< filename >>> line are the contents of the file.  You can break up this 
  54. "jar" file into its consituent files using a text editor, or with a program 
  55. like the following one, which is written in the C language.  If you call this
  56. program "unjoin" and you have a "jar" file called foo.jar, then you would
  57. break up the jar file by typing "unjoin < foo.jar".
  58. ---(cut here)---------------------------
  59. /* unjoin -- Split a "jar file" up into its original component files.  */
  60. /* The jar file is read from standard input.  */
  61. /*
  62. /* This program can be used on UNIX systems, and with Microsoft C */
  63. /*
  64. /* Authors: F. da Cruz, C. Gianone, Columbia University, 1988 */
  65.  
  66. #include <stdio.h>
  67.  
  68. int files = 0;
  69. FILE *fd;
  70. char *name;
  71. #define BUFLEN 1000
  72. char buf[BUFLEN];
  73. char msg[100];
  74.  
  75. main() {
  76.     while(1) {
  77.     if (gets(buf) == NULL) doexit(0);
  78.     if (chkhdr()) {
  79.         if (files > 0) fclose(fd);
  80.         if ((fd = fopen(name,"w")) == NULL) {
  81.         sprintf(msg,"Fatal - Can't create %s",name);
  82.         perror(msg);
  83.         doexit(1);
  84.         } else files++;
  85.     } else {
  86.         if (files == 0) {
  87.         fprintf(stderr,"Fatal - not a joined file!\n");
  88.         doexit(1);
  89.         } else {
  90.         fprintf(fd,"%s\n",buf);
  91.         }
  92.     }
  93.     }
  94. }
  95.  
  96. chkhdr() {                /* Look for "<<< filename >>>" */
  97.     int i;
  98.  
  99.     if (buf[0] != '<') return(0);
  100.     if (buf[1] != '<') return(0);    
  101.     if (buf[2] != '<') return(0);
  102.     if (buf[3] != ' ') return(0);
  103.     for (i = 4; (buf[i] != '\0') && (i < BUFLEN); i++) ;
  104.     if (buf[i-1] != '>') return(0);
  105.     if (buf[i-2] != '>') return(0);
  106.     if (buf[i-3] != '>') return(0);
  107.     if (buf[i-4] != ' ') return(0);
  108.     buf[i-4] = '\0';
  109.     name = buf+4;
  110.     return;
  111. }
  112.  
  113. doexit(x) int x; {            /* Exit from program */
  114.     if (files > 0) fclose(fd);
  115.     fprintf(stderr,
  116.         "Done, unjoined %d file%c\n",files,(files == 1) ? ' ' : 's');
  117.     exit(x);
  118. }
  119. <<< ckcdeb.h >>>
  120. /*  C K C D E B . H  */
  121.  
  122. ]/**********************************************************************
  123. *                                                   *
  124. * IVS / MCS-Kermit REL 2                                              *
  125. * source code                                                         *
  126. *                                                                     *
  127. * Change History:                                                     *
  128. *                                                                     *
  129. *                1. Modify C-Kermit(4E) source code to                *
  130. *                   produce new module for MCS/IVS-Kermit             *
  131. *                   ORIGINAL RELEASE                                  *
  132. *                   June 22, 1990                                     *
  133. *                                                                     *
  134. *                                                                     *
  135. ***********************************************************************/
  136.  
  137. /*
  138.  This file is included by all C-Kermit modules, including the modules
  139.  that aren't specific to Kermit (like the command parser and the ck?tio and
  140.  ck?fio modules.  It specifies format codes for debug(), tlog(), and similar
  141.  functions, and includes any necessary typedefs to be used by all C-Kermit
  142.  modules, and also includes some feature selection compile-time switches.
  143. */
  144. /*
  145.  Copyright (C) 1987, 1989, Trustees of Columbia University in the City of New
  146.  York. Permission is granted to any individual or institution to use, copy, or
  147.  redistribute this software so long as it is not sold for profit, provided this
  148.  copyright notice is retained.
  149. */
  150.  
  151. /*
  152.  DEBUG and TLOG should be defined in the Makefile if you want debugging
  153.  and transaction logs.  Don't define them if you want to save the space
  154.  overhead.
  155. */
  156. #ifndef DEBUG
  157. #define debug(a,b,c,d) {}
  158. #endif
  159.  
  160. #ifndef TLOG
  161. #define tlog(a,b,c,d) {}
  162. #endif
  163.  
  164. /* Formats for debug(), tlog(), etc */
  165.  
  166. #define F000 0
  167.  
  168. #define F001 1
  169. #define F010 2
  170. #define F011 3
  171. #define F100 4
  172. #define F101 5
  173. #define F110 6
  174. #define F111 7
  175.  
  176. /* Unix Version Dependencies */
  177.  
  178. /* signal() type, void or int? */
  179. #ifdef SVR3
  180. typedef void SIGTYP;            /* System V R3 and later */
  181. #else
  182. #ifdef SUNOS4
  183. typedef void SIGTYP;            /* SUNOS V 4.0 and later */
  184. #else
  185. typedef int SIGTYP;
  186. #endif
  187. #endif
  188.  
  189. /* C Compiler Dependencies */
  190.  
  191. #ifdef ZILOG
  192. #define setjmp setret
  193. #define longjmp longret
  194. #define jmp_buf ret_buf
  195. typedef int ret_buf[10];
  196. #endif /* zilog */
  197.  
  198. #ifdef PROVX1
  199. typedef char CHAR;
  200. typedef long LONG;
  201. typedef int void;
  202. #else
  203. #ifdef V7
  204. typedef char CHAR;
  205. typedef long LONG;
  206. #else
  207. #ifdef C70
  208. typedef char CHAR;
  209. typedef long LONG;
  210. #else
  211. #ifdef BSD29
  212. typedef char CHAR;
  213. typedef long LONG;
  214. #else
  215. typedef unsigned char CHAR;
  216. typedef long LONG;
  217. #endif
  218. #endif
  219. #endif
  220. #endif
  221.  
  222. #ifdef TOWER1
  223. typedef int void;
  224. #endif
  225.  
  226. /* Line delimiter for text files */
  227.  
  228. /*
  229.  If the system uses a single character for text file line delimitation,
  230.  define NLCHAR to the value of that character.  For text files, that
  231.  character will be converted to CRLF upon output, and CRLF will be converted
  232.  to that character on input during text-mode (default) packet operations.
  233. */
  234. #ifdef MAC                              /* Macintosh */
  235. #define NLCHAR 015
  236. #else                                   /* All Unix-like systems */
  237. #define NLCHAR 012
  238. #endif
  239. /*
  240.  At this point, if there's a system that uses ordinary CRLF line
  241.  delimitation AND the C compiler actually returns both the CR and
  242.  the LF when doing input from a file, then #undef NLCHAR.
  243. */
  244.  
  245. /* The device name of a job's controlling terminal */
  246. /* Special for VMS, same for all Unixes (?), not used by Macintosh */
  247.  
  248. #ifdef vms
  249. #define CTTNAM "TT:"
  250. #else
  251. #ifdef datageneral
  252. #define CTTNAM "@output"
  253. #else
  254. #define CTTNAM "/dev/tty"
  255. #endif
  256. #endif
  257.  
  258. /* Some special includes for VAX/VMS */
  259.  
  260. #ifndef vms
  261. /* The following #includes cause problems for some preprocessors. */
  262. /*
  263. #endif
  264. #ifdef vms
  265. #include ssdef
  266. #include stsdef
  267. #endif
  268. #ifndef vms
  269. */
  270. #endif
  271.  
  272. /* Program return codes for VMS, DECUS C, and Unix */
  273.  
  274. #ifdef vms
  275. #define GOOD_EXIT   (SS$_NORMAL | STS$M_INHIB_MSG)
  276. #define BAD_EXIT    SS$_ABORT
  277. #else
  278. #ifdef decus
  279. #define GOOD_EXIT   IO_NORMAL
  280. #define BAD_EXIT    IO_ERROR
  281. #else
  282. #define GOOD_EXIT   0
  283. #define BAD_EXIT    1
  284. #endif
  285. #endif
  286.  
  287. /* Special hack for Fortune, which doesn't have <sys/file.h>... */
  288.  
  289. #ifdef FT18
  290. #define FREAD 0x01
  291. #define FWRITE 0x10
  292. #endif
  293.  
  294. <<< ckcker.h >>>
  295. /* ckcker.h -- Symbol and macro definitions for C-Kermit */
  296.  
  297. /**********************************************************************
  298. *                                                   *
  299. * IVS / MCS-Kermit REL 2                                              *
  300. * source code                                                         *
  301. *                                                                     *
  302. * Change History:                                                     *
  303. *                                                                     *
  304. *                1. Modify C-Kermit(4E) source code to                *
  305. *                   produce new module for MCS/IVS-Kermit             *
  306. *                   ORIGINAL RELEASE                                  *
  307. *                   June 22, 1990                                     *
  308. *                                                                     *
  309. *                                                                     *
  310. ***********************************************************************/
  311.  
  312. /*
  313.  Author: Frank da Cruz (SY.FDC@CU20B),
  314.  Columbia University Center for Computing Activities, January 1985.
  315.  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
  316.  Permission is granted to any individual or institution to use, copy, or
  317.  redistribute this software so long as it is not sold for profit, provided this
  318.  copyright notice is retained.
  319. */
  320.  
  321. /* Mnemonics for ASCII characters */
  322.  
  323. #define NUL       000            /* ASCII Null */
  324. #define SOH       001            /* ASCII Start of header */
  325. #define BEL        007        /* ASCII Bell (Beep) */
  326. #define BS         010        /* ASCII Backspace */
  327. #define LF         012            /* ASCII Linefeed */
  328. #define CR         015        /* ASCII Carriage Return */
  329. #define XON       021            /* ASCII XON */
  330. #define SP       040        /* ASCII Space */
  331. #define DEL       0177        /* ASCII Delete (Rubout) */
  332.  
  333. /* Packet buffer and window sizes, will probably need to be #ifdef'd for */
  334. /* each system. */
  335.  
  336. #define MAXSP 2048            /* Send packet buffer size  */
  337. #define MAXRP 1024            /* Receive packet buffer size  */
  338. #define MAXWS 1                /* Maximum window size */
  339.  
  340. /* Kermit parameters and defaults */
  341.  
  342. #define MAXPACK       94        /* Maximum unextended packet size */
  343. #define CTLQ       '#'        /* Control char prefix I will use */
  344. #define MYEBQ       '&'        /* 8th-Bit prefix char I will use */
  345. #define MYRPTQ       '~'        /* Repeat count prefix I will use */
  346.  
  347. #define MAXTRY        10          /* Times to retry a packet */
  348. #define MYPADN        0          /* How many padding chars I need */
  349. #define MYPADC        '\0'      /* Which padding character I need */
  350.  
  351. #define DMYTIM        7          /* Default timeout interval to use. */
  352. #define URTIME        10          /* Timeout interval to be used on me. */
  353.  
  354. #define DEFTRN        0           /* Default line turnaround handshake */
  355. #define DEFPAR        0           /* Default parity */
  356. #define MYEOL        CR          /* End-Of-Line character I need on packets. */
  357.  
  358. #define DRPSIZ        90            /* Default incoming packet size. */
  359. #define DSPSIZ        90            /* Default outbound packet size. */
  360.  
  361. #define DDELAY      5        /* Default delay. */
  362. #define DSPEED        9600     /* Default line speed. */
  363.  
  364. /* Files */
  365.  
  366. #define ZCTERM      0            /* Console terminal */
  367. #define ZSTDIO      1        /* Standard input/output */
  368. #define ZIFILE        2        /* Current input file */
  369. #define ZOFILE      3            /* Current output file */
  370. #define ZDFILE      4            /* Current debugging log file */
  371. #define ZTFILE      5            /* Current transaction log file */
  372. #define ZPFILE      6            /* Current packet log file */
  373. #define ZSFILE      7        /* Current session log file */
  374. #define ZSYSFN        8        /* Input from a system function */
  375. #define ZNFILS      9            /* How many defined file numbers */
  376.  
  377. /* Screen functions */
  378.  
  379. #define SCR_FN 1        /* filename */
  380. #define SCR_AN 2        /* as-name */
  381. #define SCR_FS 3     /* file-size */
  382. #define SCR_XD 4        /* x-packet data */
  383. #define SCR_ST 5          /* File status: */
  384. #define   ST_OK   0       /*  Transferred OK */
  385. #define   ST_DISC 1     /*  Discarded */
  386. #define   ST_INT  2     /*  Interrupted */
  387. #define   ST_SKIP 3     /*  Skipped */
  388. #define   ST_ERR  4     /*  Fatal Error */
  389. #define SCR_PN 6        /* packet number */
  390. #define SCR_PT 7        /* packet type or pseudotype */
  391. #define SCR_TC 8        /* transaction complete */
  392. #define SCR_EM 9        /* error message */
  393. #define SCR_WM 10       /* warning message */
  394. #define SCR_TU 11    /* arbitrary undelimited text */
  395. #define SCR_TN 12       /* arbitrary new text, delimited at beginning */
  396. #define SCR_TZ 13       /* arbitrary text, delimited at end */
  397. #define SCR_QE 14    /* quantity equals (e.g. "foo: 7") */
  398.  
  399. /* Macros */
  400.  
  401. #define tochar(ch)  ((ch) + SP )    /* Number to character */
  402. #define xunchar(ch) ((ch) - SP )    /* Character to number */
  403. #define ctl(ch)     ((ch) ^ 64 )    /* Controllify/Uncontrollify */
  404. #define unpar(ch)   ((ch) & 127)    /* Clear parity bit */
  405. <<< ckucmd.h >>>
  406. /*  C K U C M D . H  --  Header file for Unix cmd package  */
  407.  
  408. /**********************************************************************
  409. *                                                   *
  410. * IVS / MCS-Kermit REL 2                                              *
  411. * source code                                                         *
  412. *                                                                     *
  413. * Change History:                                                     *
  414. *                                                                     *
  415. *                1. Modify C-Kermit(4E) source code to                *
  416. *                   produce new module for MCS/IVS-Kermit             *
  417. *                   ORIGINAL RELEASE                                  *
  418. *                   June 22, 1990                                     *
  419. *                                                                     *
  420. *                                                                     *
  421. ***********************************************************************/
  422.  
  423. /*
  424.  Author: Frank da Cruz (SY.FDC@CU20B),
  425.  Columbia University Center for Computing Activities, January 1985.
  426.  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
  427.  Permission is granted to any individual or institution to use, copy, or
  428.  redistribute this software so long as it is not sold for profit, provided this
  429.  copyright notice is retained.
  430. */
  431.  
  432. /* Special getchars... */
  433.  
  434. #ifdef vax11c
  435. #define getchar()   vms_getchar()
  436. #endif
  437.  
  438. #ifdef aegis
  439. #undef getchar
  440. #define getchar()   coninc(0)
  441. #endif
  442.  
  443. #ifdef AMIGA
  444. #undef getchar
  445. #define getchar() coninc(0)
  446. #endif
  447.  
  448. /* Sizes of things */
  449.  
  450. #define HLPLW  78            /* Width of ?-help line */
  451. #define HLPCW  19            /* Width of ?-help column */
  452. #define CMDBL  200            /* Command buffer length */
  453. #define HLPBL  100            /* Help string buffer length */
  454. #define ATMBL  100            /* Command atom buffer length*/
  455.  
  456. /* Special characters */
  457.  
  458. #ifndef NUL
  459. #define NUL  '\0'            /* Null */
  460. #endif
  461. #define HT   '\t'            /* Horizontal Tab */
  462. #define NL   '\n'            /* Newline */
  463. #ifndef CR
  464. #define CR   '\r'
  465. #endif
  466. #define FF   0014            /* Formfeed    (^L) */
  467. #define RDIS 0022            /* Redisplay   (^R) */
  468. #define LDEL 0025            /* Delete line (^U) */
  469. #define WDEL 0027            /* Delete word (^W) */
  470. #define ESC  0033            /* Escape */
  471. #define RUB  0177            /* Rubout */
  472.  
  473. #ifndef BEL
  474. #define BEL  0007            /* Bell */
  475. #endif
  476.  
  477. #ifndef BS
  478. #define BS   0010            /* Backspace */
  479. #endif
  480.  
  481. #ifndef SP
  482. #define SP   0040            /* Space */
  483. #endif
  484.  
  485. /* Keyword table flags */
  486.  
  487. #define CM_INV 1            /* Invisible keyword */
  488.  
  489. /* Keyword Table Template */
  490.  
  491. struct keytab {                /* Keyword table */
  492.     char *kwd;                /* Pointer to keyword string */
  493.     int val;                /* Associated value */
  494.     int flgs;                /* Flags (as defined above) */
  495. };
  496. <<< ckusym.h >>>
  497. /**********************************************************************
  498. *                                                   *
  499. * IVS / MCS-Kermit REL 2                                              *
  500. * source code                                                         *
  501. *                                                                     *
  502. * Change History:                                                     *
  503. *                                                                     *
  504. *                1. Modify C-Kermit(4E) source code to                *
  505. *                   produce new module for MCS/IVS-Kermit             *
  506. *                   ORIGINAL RELEASE                                  *
  507. *                   June 22, 1990                                     *
  508. *                                                                     *
  509. *                                                                     *
  510. ***********************************************************************/
  511.  
  512. /* This file is for use with compilers that don't have the capability to
  513.  * #define symbols on the C compiler command line.  This file must
  514.  * be #include'd before all other ck*.h files so that the symbols #define'd
  515.  * here can be used for any subsequent conditional code.  Symbols should be
  516.  * #define'd as 1 if TRUE and 0 if FALSE.  This implies, of course, that they
  517.  * be tested with #if's, not #ifdef's and #ifndef's.
  518.  */
  519.  
  520. /*
  521.  * For example, this file was required to compile Macintosh Kermit under
  522.  * Megamax C (which we don't do any more), because Megamax did not have
  523.  * a mechanism for defining symbols on the command line, so this file was
  524.  * used to define the symbol MAC.
  525.  */
  526. <<< ckuusr.h >>>
  527. /*  C K U U S R . H  --  Symbol definitions for V-Kermit ckuus*.c modules  */
  528.  
  529. /**********************************************************************
  530. *                                                   *
  531. * IVS / MCS-Kermit REL 2                                              *
  532. * source code                                                         *
  533. *                                                                     *
  534. * Change History:                                                     *
  535. *                                                                     *
  536. *                1. Modify C-Kermit(4E) source code to                *
  537. *                   produce new module for MCS/IVS-Kermit             *
  538. *                   ORIGINAL RELEASE                                  *
  539. *                   June 22, 1990                                     *
  540. *                                                                     *
  541. *                                                                     *
  542. ***********************************************************************/
  543.  
  544. /*
  545.  Author: Frank da Cruz (SY.FDC@CU20B),
  546.  Columbia University Center for Computing Activities, January 1985.
  547.  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
  548.  Permission is granted to any individual or institution to use, copy, or
  549.  redistribute this software so long as it is not sold for profit, provided this
  550.  copyright notice is retained.
  551. */
  552.  
  553. /* Name of C-Kermit program initialization file. */
  554. #ifdef vax11c
  555. #define KERMRC "kermit.ini"
  556. #else
  557. #define KERMRC "kermrc"
  558. #endif
  559.  
  560. #ifndef AMIGA
  561. #ifndef vax11c
  562. #ifndef datageneral
  563. #include "pwd.h"
  564. #endif
  565. #endif
  566. #endif
  567.  
  568. /* Values associated with top-level commands, must be 0 or greater. */
  569.  
  570. #define XXBYE   0    /* BYE */
  571. #define XXCLE   1    /* CLEAR */
  572. #define XXCLO   2    /* CLOSE */
  573. #define XXCON   3    /* CONNECT */
  574. #define XXCPY   4    /* COPY */
  575. #define XXCWD   5    /* CWD (Change Working Directory) */
  576. #define XXDEF    6    /* DEFINE (a command macro) */
  577. #define XXDEL   7    /* (Local) DELETE */
  578. #define XXDIR   8    /* (Local) DIRECTORY */
  579. #define XXDIS   9    /* DISCONNECT */
  580. #define XXECH  10    /* ECHO */
  581. #define XXEXI  11    /* EXIT */
  582. #define XXFIN  12    /* FINISH */
  583. #define XXGET  13    /* GET */
  584. #define XXHLP  14    /* HELP */
  585. #define XXINP  15    /* INPUT */
  586. #define XXLOC  16    /* LOCAL */
  587. #define XXLOG  17    /* LOG */
  588. #define XXMAI  18    /* MAIL */
  589. #define XXMOU  19    /* (Local) MOUNT */
  590. #define XXMSG  20    /* (Local) MESSAGE */
  591. #define XXOUT  21    /* OUTPUT */
  592. #define XXPAU  22    /* PAUSE */
  593. #define XXPRI  23    /* (Local) PRINT */
  594. #define XXQUI  24    /* QUIT */
  595. #define XXREC  25    /* RECEIVE */
  596. #define XXREM  26    /* REMOTE */
  597. #define XXREN  27    /* (Local) RENAME */
  598. #define XXSEN  28    /* SEND */
  599. #define XXSER  29       /* SERVER */
  600. #define XXSET  30    /* SET */
  601. #define XXSHE  31    /* Command for SHELL */
  602. #define XXSHO  32    /* SHOW */
  603. #define XXSPA  33    /* (Local) SPACE */
  604. #define XXSTA  34    /* STATISTICS */
  605. #define XXSUB  35    /* (Local) SUBMIT */
  606. #define XXTAK  36    /* TAKE */
  607. #define XXTRA  37    /* TRANSMIT */
  608. #define XXTYP  38    /* (Local) TYPE */
  609. #define XXWHO  39    /* (Local) WHO */
  610. #define XXDIAL 40    /* (Local) DIAL */
  611. #define XXLOGI 41    /* (Local) SCRIPT */
  612. #define XXCOM  42    /* Comment */
  613. #define XXHAN  43       /* HANGUP */
  614.  
  615. /* SET parameters */
  616.  
  617. #define XYBREA  0    /* BREAK simulation */
  618. #define XYCHKT  1    /* Block check type */
  619. #define XYDEBU  2    /* Debugging */
  620. #define XYDELA  3    /* Delay */
  621. #define XYDUPL  4    /* Duplex */
  622. #define XYEOL   5    /* End-Of-Line (packet terminator) */
  623. #define XYESC   6    /* Escape character */
  624. #define XYFILE  7    /* File Parameters */
  625. #define   XYFILN 0      /*  Naming  */
  626. #define   XYFILT 1      /*  Type    */
  627. #define   XYFILW 2      /*  Warning */
  628. #define   XYFILD 3      /*  ...     */
  629. /* empty space to add something */
  630. #define XYFLOW  9    /* Flow Control */
  631. #define XYHAND 10    /* Handshake */
  632. #define XYIFD  11    /* Incomplete File Disposition */
  633. #define XYIMAG 12    /* "Image Mode" */
  634. #define XYINPU 13    /* INPUT command parameters */
  635. #define XYLEN  14    /* Maximum packet length to send */
  636. #define XYLINE 15    /* Communication line to use */
  637. #define XYLOG  16    /* Log file */
  638. #define XYMARK 17    /* Start of Packet mark */
  639. #define XYNPAD 18    /* Amount of padding */
  640. #define XYPADC 19    /* Pad character */
  641. #define XYPARI 20    /* Parity */
  642. #define XYPAUS 21    /* Interpacket pause */
  643. #define XYPROM 22    /* Program prompt string */
  644. #define XYQBIN 23    /* 8th-bit prefix */
  645. #define XYQCTL 24    /* Control character prefix */
  646. #define XYREPT 25    /* Repeat count prefix */
  647. #define XYRETR 26    /* Retry limit */
  648. #define XYSPEE 27    /* Line speed (baud rate) */
  649. #define XYTACH 28    /* Character to be doubled */
  650. #define XYTIMO 29    /* Timeout interval */
  651. #define XYMODM 30    /* Modem type */
  652. #define XYSEND 31    /* SEND parameters, used with some of the above */
  653. #define XYRECV 32   /* RECEIVE parameters, ditto */
  654. #define XYTERM 34    /* Terminal parameters */
  655. #define XYID   35   /* SPUR file id-fields */
  656. #define XYNUM  36   /* SPUR file line numbers */
  657. #define XYRNUM 37   /* SPUR file line renumbering */
  658. #define XYADD  38   /* SPUR file line number adding */
  659.  
  660. /* REMOTE command symbols */
  661.  
  662. #define XZCPY  0    /* Copy */
  663. #define XZCWD  1    /* Change Working Directory */
  664. #define XZDEL  2    /* Delete */
  665. #define XZDIR  3    /* Directory */
  666. #define XZHLP  4    /* Help */
  667. #define XZHOS  5    /* Host */
  668. #define XZKER  6    /* Kermit */
  669. #define XZLGI  7    /* Login */
  670. #define XZLGO  8    /* Logout */
  671. #define XZMAI  9    /* Mail */
  672. #define XZMOU 10    /* Mount */
  673. #define XZMSG 11    /* Message */
  674. #define XZPRI 12    /* Print */
  675. #define XZREN 13    /* Rename */
  676. #define XZSET 14    /* Set */
  677. #define XZSPA 15    /* Space */
  678. #define XZSUB 16    /* Submit */
  679. #define XZTYP 17    /* Type */
  680. #define XZWHO 18    /* Who */
  681.  
  682. /* Symbols for logs */
  683.  
  684. #define LOGD 0            /* Debugging */
  685. #define LOGP 1          /* Packets */
  686. #define LOGS 2          /* Session */
  687. #define LOGT 3          /* Transaction */
  688. <<< ckvbuf.c >>>
  689. /* CKVBUF_C  12 June 90 */
  690.  
  691. /***********************************************************************
  692. * MCS-Kermit REL 2                                                    *
  693. * source code                                                         *
  694. *                                                                     *
  695. * Change History:                                                     *
  696. *                                                                     *
  697. *                1. Modify C-Kermit(4E) source code to                *
  698. *                   produce new module for MCS/IVS-Kermit             *
  699. *                   ORIGINAL RELEASE                                  *
  700. *                   June 22, 1990                                     *
  701. *                                                                     *
  702. *                                                                     *
  703. ***********************************************************************/
  704.  
  705.  
  706. #include <stdio.h>
  707. #include <string.h>
  708. #include <memory.h>
  709. #include "mcs_defs_h"
  710. #include "ckcdeb.h"                      /* DRE 030690 */
  711. #include "ckcker.h"                      /* DRE 060690 */
  712.  
  713. extern FILE *Log;
  714. extern int         server;                       /* DRE 020890 */
  715. extern int         deblog;                       /* DRE 030690 */
  716.  
  717. static char         _inbuffer[MAXRP] = { '\0' };
  718. static char         _outbuffer[MAXSP] = { '\0' };
  719.  
  720. static char         *_instart = &_inbuffer[0];
  721. static char         *_inend = &_inbuffer[0];
  722. static char         *_outstart = &_outbuffer[0];
  723. static char         *_outend = &_outbuffer[0];
  724.  
  725. static char         mcsstr[MAXSP];
  726. static char         buf[MAXRP];
  727.  
  728. #define _insize  (_inend - _instart)
  729. #define _outsize (_outend - _outstart)
  730.  
  731. /*****************************************************************************
  732.  *****************************************************************************
  733.  *********                   OUTPUT ROUTINES                          ********
  734.  *****************************************************************************
  735.  *****************************************************************************/
  736.  
  737. mcs_printf(tmp_string)
  738. char         *tmp_string;
  739. {
  740.          if (deblog)
  741.              debug (F110, "funct: mcs_printf", tmp_string, 0);
  742.          if (_myprnt(tmp_string))
  743.              return strlen(tmp_string);
  744.          else
  745.              return EOF;
  746. }
  747.  
  748. mcs_fprintf(stream, tmp_string)
  749. FILE *stream;
  750. char         *tmp_string;
  751. {
  752.          if (deblog)
  753.              debug (F110, "funct: mcs_fprintf", tmp_string, 0);
  754.  
  755.          if (stream == stdout) {
  756.              if (_myprnt(tmp_string))
  757.                  return strlen(tmp_string);
  758.              else
  759.                  return EOF;
  760.          } else
  761.              return(fprintf(stream, tmp_string));
  762. }
  763.  
  764. mcs_puts(tmp_string)
  765. char         *tmp_string;
  766. {
  767.          if (deblog)
  768.              debug (F110, "funct: mcs_puts", tmp_string, 0);
  769.  
  770.          if (!_myprnt(tmp_string))
  771.              return EOF;
  772.          if (!_myprnt("\n"))
  773.              return EOF;
  774.          else
  775.              return '\n';
  776. }
  777.  
  778. mcs_fputs(tmp_string, stream)
  779. char         *tmp_string;
  780. FILE *stream;
  781. {
  782.          if (deblog)
  783.              debug (F110, "funct: mcs_fputs", tmp_string, 0);
  784.  
  785.          if (stream == stdout) {                     /* DRE 1/24/90 */
  786.              if (_myprnt(tmp_string))
  787.                  return 0;
  788.              else
  789.                  return EOF;
  790.          } else
  791.              return(fputs(tmp_string, stream));
  792. }
  793.  
  794. mcs_fputc(ch, stream)
  795. int         ch;
  796. FILE *stream;
  797. {
  798.          char    tmp_string[5];
  799.  
  800.          if (deblog)
  801.              debug (F101, "funct: mcs_fputc", "", ch);
  802.  
  803.          if (stream == stdout) {                     /* DRE 1/24/90 */
  804.              tmp_string[0] = ch;
  805.              tmp_string[1] = '\0';
  806.              if (_myprnt(tmp_string))
  807.                  return tmp_string[0];
  808.              else
  809.                  return EOF;
  810.          } else
  811.              return(fputc(ch, stream));
  812. }
  813.  
  814. mcs_fputchar(ch)
  815. int         ch;
  816. {
  817.          char    tmp_string[5];
  818.  
  819.          if (deblog)
  820.              debug (F101, "funct: mcs_fputchar", "", ch);
  821.  
  822.          tmp_string[0] = ch;
  823.          tmp_string[1] = '\0';
  824.          if (_myprnt(tmp_string))
  825.              return tmp_string[0];
  826.          else
  827.              return EOF;
  828. }
  829.  
  830. mcs_putchar(tmp_char)
  831. char         tmp_char;
  832. {
  833.          char    tmp_string[5];
  834.  
  835.          if (deblog)
  836.              debug (F101, "funct: mcs_putchar", "", tmp_char);
  837.  
  838.          tmp_string[0] = tmp_char;
  839.          tmp_string[1] = '\0';
  840.          if (_myprnt(tmp_string))
  841.              return tmp_string[0];
  842.          else
  843.              return EOF;
  844. }
  845.  
  846. mcs_fflush()
  847. {
  848.          int    mesg_len;
  849.          char    status[3];
  850.  
  851.          if (deblog)
  852.              debug (F100, "funct: mcs_fflush", "", 0);
  853.  
  854.          if (_outend != _outstart) {
  855.              mesg_len = _outend - _outstart + 1;
  856.              strncpy(mcsstr, _outstart, mesg_len);
  857.              mcsstr[mesg_len] = '\0';
  858.              mcs_send(QUEUENAME, mcsstr, mesg_len, OUT_TERM, status);
  859.              _outstart = &_outbuffer[0];
  860.              _outend = _outstart;
  861.          }
  862.  
  863. }
  864.  
  865. mcs_clrbuf()
  866. {
  867.          if (deblog)
  868.              debug (F100, "funct: mcs_clrbuf", "", 0);
  869.          _instart = &_inbuffer[0];
  870.          _inend = _instart;
  871. }
  872.  
  873. mcs_write(fildes, buffer, nbyte)
  874. int         fildes;
  875. char         *buffer;
  876. unsigned         nbyte;
  877. {
  878.          int    mesg_len = nbyte;
  879.          char    status[3];
  880.  
  881.          if (deblog)
  882.              debug (F100, "funct: mcs_write", "", 0);
  883.  
  884.          if (fildes == 1) {
  885.              mcs_send(QUEUENAME, buffer, mesg_len, OUT_TERM, status);
  886.              return(nbyte);
  887.              /* NEED A RETURN STATUS */
  888.          } else
  889.              return(write(fildes, buffer, nbyte));
  890. }
  891.  
  892. /*****************************************************************************
  893.  *****************************************************************************
  894.  *********                    INPUT ROUTINES                          ********
  895.  *****************************************************************************
  896.  *****************************************************************************/
  897.  
  898. mcs_gets(tmp_string)
  899. char         *tmp_string;
  900. {
  901.          int    mesg_len;
  902.  
  903.          if (deblog)
  904.              debug (F100, "funct: mcs_gets", "", 0);
  905.  
  906.          mesg_len = _myread(tmp_string, 0);
  907.          if (mesg_len == 0)
  908.              return NULL;
  909.          tmp_string[mesg_len - 1] = '\0';
  910.          return (int)tmp_string;
  911. }
  912.  
  913. mcs_getchar()
  914. {
  915.          char    tmp_string[5];
  916.          int    mesg_len;
  917.  
  918.          if (deblog)
  919.              debug (F100, "funct: mcs_getchar", "", 0);
  920.  
  921.          mesg_len = _myread(tmp_string, 1);
  922.          if (mesg_len == 0)
  923.              return EOF;
  924.          return(tmp_string[0]);
  925. }
  926.  
  927. char         *mcs_fgets(str, num, stream)
  928. char         *str;
  929. int         num;
  930. FILE *stream;
  931. {
  932.          int    mesg_len;
  933.  
  934.          if (deblog)
  935.              debug (F100, "funct: mcs_fgets", "", 0);
  936.  
  937.          if (stream == stdin) {
  938.              mesg_len = _myread(str, num - 1);
  939.              if (mesg_len == 0)
  940.                  return NULL;
  941.              return str;
  942.          } else
  943.              return(fgets(str, num, stream));
  944. }
  945.  
  946. mcs_fgetc(stream)
  947. FILE *stream;
  948. {
  949.          char    tmp_string[5];
  950.          int    mesg_len;
  951.  
  952.          if (deblog)
  953.              debug (F100, "funct: mcs_fgetc", "", 0);
  954.  
  955.          if (stream == stdin) {
  956.              mesg_len = _myread(tmp_string, 1);
  957.              if (mesg_len == 0)
  958.                  return EOF;
  959.              return(tmp_string[0]);
  960.          } else
  961.              return(fgetc(stream));
  962. }
  963.  
  964. mcs_read(fildes, buffer, nbyte)
  965. int         fildes;
  966. char         *buffer;
  967. unsigned         nbyte;
  968. {
  969.          int    mesg_len = nbyte;
  970.          int    num = 0, i;
  971.          char    status[3];
  972.  
  973.          if (deblog)
  974.              debug (F100, "funct: mcs_read", "", 0);
  975.  
  976.          if (fildes == 0) {
  977.  
  978.              /* WHAT IS THE MINIMUM BYTES ALLOWED TO BE READ?  -  80 chars */
  979.              /* msleep(500);  */
  980.  
  981.              for (; num < nbyte; num++) {
  982.                  *(buffer + num) = mcs_getchar();
  983.                  if (*(buffer + num) == '\n') {
  984.                      num++;
  985.                      break;
  986.                  }
  987.              }
  988.              buffer[num] = '\0';
  989.              /* NEED A RETURN STATUS */
  990.              return(num);
  991.          } else
  992.              return(read(fildes, buffer, nbyte));
  993. }
  994.  
  995. _myprnt(str)
  996. char         *str;
  997. {
  998.          register char    *p;
  999.          char    status[3], tmp_c;
  1000.          register int    mesg_len, size;
  1001.          int outcome;                                /* DRE 060690 */
  1002.  
  1003.          if (deblog)
  1004.              debug (F110, "funct: _myprnt", str, 0);
  1005.  
  1006.          outcome = 1;                   /* start with good outcome */
  1007.  
  1008.          for (p = str; *p != '\0'; )
  1009.              *_outend++ = *p++;      /* append string to buffer */
  1010.          *_outend = *p;                 /* put null character at end */
  1011.  
  1012.          for (p = _outstart; *p; ) {
  1013.              if (*p == '\n') {       /* if newline found, send line */
  1014.                  p++;
  1015.                  mesg_len = p - _outstart;
  1016.                  tmp_c = *p;
  1017.                  *p = '\0';
  1018.  
  1019.                  mcs_send(QUEUENAME, _outstart, mesg_len, OUT_TERM,
  1020.                       status);
  1021.  
  1022.                  if ((strncmp(status, "00", 2) != 0) &&
  1023.                             (strncmp(status, "98", 2) != 0)) {
  1024.  
  1025.                            /* log the message then throw it away */
  1026.  
  1027.                            fprintf(stderr,"_myprnt: mcs_send failed\n");
  1028.                            fprintf(stderr,"  ==> %s", _outstart);
  1029.                            outcome = 0;       /* bad outcome */
  1030.                  }
  1031.                  *p  = tmp_c;
  1032.                  _outstart = p;
  1033.              } else
  1034.                  p++;
  1035.          }
  1036.  
  1037.          if (_outstart != &_outbuffer[0]) {    /* we must have sent a msg */
  1038.              if (_outstart != _outend) {    /* reset the buffer */
  1039.                  size = _outsize;
  1040.  /*
  1041.         The strcpy function call was removed on 6-12-90
  1042.         because it was causing some type of buffer corruption
  1043.         problem.  The exact cause was not determined, but the
  1044.         problem disappeared when strcpy was replaced by the
  1045.         sprintf function call.
  1046.  
  1047.                   strcpy(_outbuffer, _outstart);
  1048. */
  1049.                         sprintf(_outbuffer,"%s",_outstart);
  1050.                  _outstart = &_outbuffer[0];
  1051.                  _outend = _outstart + size;
  1052.              } else {
  1053.                  _outstart = &_outbuffer[0];
  1054.                  _outend = _outstart;
  1055.              }
  1056.          }
  1057.  
  1058.          return (outcome);
  1059. }
  1060.  
  1061. _myread(str, num)
  1062. char         *str;
  1063. int         num;
  1064. {
  1065.          register char    *p;
  1066.          char    status[3], *endstr;
  1067.          register int    i, size;
  1068.          int    mesg_len;
  1069.  
  1070.          if (deblog)
  1071.              debug (F100, "funct: _myread", "", 0);
  1072.  
  1073.          if (_insize == 0) {
  1074.                 if (!server)  mcs_fflush();
  1075.  
  1076.              mcs_recv(QUEUENAME, buf, &mesg_len, IN_TERM, status);
  1077.  
  1078.              if ((strncmp(status, "00", 2) != 0) &&  (strncmp(status,
  1079.                   "98", 2) != 0)) {
  1080.  
  1081.                  if (!server)
  1082.                      mcs_send(QUEUENAME, "\n", 1, OUT_TERM,
  1083.                           status);
  1084.                  return 0;
  1085.              }
  1086.  
  1087.                 if (!server)
  1088.                  mcs_send(QUEUENAME, "\n", 1, OUT_TERM, status);
  1089.  
  1090.                 memcpy(_instart,buf,(mesg_len+1));
  1091. /*
  1092.  *              _inend = _instart + mesg_len + 1;
  1093.  */
  1094.                 _inend = _instart + mesg_len;
  1095.  
  1096.          }
  1097.  
  1098.          if (num == 0) {
  1099.              for (p = _instart; *p != '\n'; )
  1100.                  *str++ = *p++;
  1101.              *str++ = *p++;
  1102.              *str = '\0';
  1103.              mesg_len = p - _instart;
  1104.              _instart = p;
  1105.          } else {
  1106.              for (i = 0; i < num; i++) {
  1107.                  str[i] = _instart[i];
  1108.                  if (str[i] == '\n') {
  1109.                      i++;
  1110.                      break;
  1111.                  }
  1112.              }
  1113.              mesg_len = i;
  1114.              str[mesg_len] = '\0';
  1115.              _instart = _instart + mesg_len;
  1116.          }
  1117.  
  1118.          if (_instart != &_inbuffer[0]) {
  1119.              if (_instart != _inend) {
  1120.                  size = _insize;
  1121.                  memcpy(_inbuffer, _instart,size);
  1122.                  _instart = &_inbuffer[0];
  1123.                  _inend = _instart + size;
  1124.  
  1125.              } else {
  1126.                  _instart = &_inbuffer[0];
  1127.                  _inend = _instart;
  1128.              }
  1129.          }
  1130.  
  1131.          return mesg_len;
  1132. }
  1133. <<< ckvcmd.c >>>
  1134. char     *cmdv = "VRX/E cmd package V2(023), 06 June 90";
  1135.  
  1136. /*  C K V C M D  --  Interactive command package for NCR-VRX  */
  1137.  
  1138. /**********************************************************************
  1139. *                                                                       *
  1140. * IVS / MCS-Kermit REL 2                                              *
  1141. * source code                                                         *
  1142. *                                                                     *
  1143. * Change History:                                                     *
  1144. *                                                                     *
  1145. *                1. Modify C-Kermit(4E) source code to                *
  1146. *                   produce new module for MCS/IVS-Kermit             *
  1147. *                   ORIGINAL RELEASE                                  *
  1148. *                   June 22, 1990                                     *
  1149. *                                                                     *
  1150. *                                                                     *
  1151. ***********************************************************************/
  1152.  
  1153.  
  1154. /*
  1155.  V2 adds support for Data General and Apollo Aegis.
  1156. */
  1157. /*
  1158.  Modelled after the DECSYSTEM-20 command parser (the COMND JSYS)
  1159.  
  1160.  Features:
  1161.  . parses and verifies keywords, text strings, numbers, and other data
  1162.  . displays appropriate menu or help message when user types "?"
  1163.  . does keyword and filename completion when user types ESC
  1164.  . accepts any unique abbreviation for a keyword
  1165.  . allows keywords to have attributes, like "invisible"
  1166.  . can supply defaults for fields omitted by user
  1167.  . provides command line editing (character, word, and line deletion)
  1168.  . accepts input from keyboard, command files, or redirected stdin
  1169.  . allows for full or half duplex operation, character or line input
  1170.  . settable prompt, protected from deletion
  1171.  
  1172.  Functions:
  1173.   cmsetp - Set prompt (cmprom is prompt string, cmerrp is error msg prefix)
  1174.   cmsavp - Save current prompt
  1175.   prompt - Issue prompt
  1176.   cmini  - Clear the command buffer (before parsing a new command)
  1177.   cmres  - Reset command buffer pointers (before reparsing)
  1178.   cmkey  - Parse a keyword
  1179.   cmnum  - Parse a number
  1180.   cmifi  - Parse an input file name
  1181.   cmofi  - Parse an output file name
  1182.   cmfld  - Parse an arbitrary field
  1183.   cmtxt  - Parse a text string
  1184.   cmcfm  - Parse command confirmation (end of line)
  1185.   stripq - Strip out backslash quotes from a string.
  1186.  
  1187.  Return codes:
  1188.   -3: no input provided when required
  1189.   -2: input was invalid
  1190.   -1: reparse required (user deleted into a preceding field)
  1191.    0 or greater: success
  1192.   See individual functions for greater detail.
  1193.  
  1194.  Before using these routines, the caller should #include ckucmd.h, and
  1195.  set the program's prompt by calling cmsetp().  If the file parsing
  1196.  functions cmifi and cmofi are to be used, this module must be linked
  1197.  with a ck?fio file system support module for the appropriate system,
  1198.  e.g. ckufio for NCR-VRX.  If the caller puts the terminal in
  1199.  character wakeup ("cbreak") mode with no echo, then these functions will
  1200.  provide line editing -- character, word, and line deletion, as well as
  1201.  keyword and filename completion upon ESC and help strings, keyword, or
  1202.  file menus upon '?'.  If the caller puts the terminal into character
  1203.  wakeup/noecho mode, care should be taken to restore it before exit from
  1204.  or interruption of the program.  If the character wakeup mode is not
  1205.  set, the system's own line editor may be used.
  1206.  
  1207.  Author: Frank da Cruz (SY.FDC@CU20B),
  1208.  Columbia University Center for Computing Activities, January 1985.
  1209.  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
  1210.  Permission is granted to any individual or institution to use, copy, or
  1211.  redistribute this software so long as it is not sold for profit, provided this
  1212.  copyright notice is retained.
  1213. */
  1214.  
  1215. /* Includes */
  1216.  
  1217. #include <stdio.h>                      /* Standard C I/O package */
  1218. #include <ctype.h>                      /* Character types */
  1219. #include "ckucmd.h"                     /* Command parsing definitions */
  1220. #include "ckcdeb.h"                     /* Formats for debug() */
  1221. #ifdef MCS_FLAG
  1222. #include "mcs.h"
  1223. #endif
  1224.  
  1225. /* external variables */
  1226.  
  1227. extern int     deblog;
  1228. extern void    errhdlr();               /* replaces perror */
  1229. extern int     debug();
  1230.  
  1231. extern int ncmd;
  1232. extern struct keytab cmdtab[];
  1233.  
  1234.  
  1235. /* Local variables */
  1236.  
  1237. int   psetf = 0,                  /* Flag that prompt has been set */
  1238.       cc = 0,                     /* Character count */
  1239.       dpx = 0;                    /* Duplex (0 = full) */
  1240.  
  1241. int   hw = HLPLW,                 /* Help line width */
  1242.       hc = HLPCW,                 /* Help line column width */
  1243.       hh,                         /* Current help column number */
  1244.       hx;                         /* Current help line position */
  1245.  
  1246. #define PROML 60                      /* Maximum length for prompt */
  1247.  
  1248. char     cmprom[PROML+1];             /* Program's prompt */
  1249. char     *dfprom = "Command? ";       /* Default prompt */
  1250.  
  1251. char     cmerrp[PROML+1];             /* Program's error message prefix */
  1252.  
  1253. int      cmflgs;                      /* Command flags */
  1254.  
  1255. char     cmdbuf[CMDBL+4];             /* Command buffer */
  1256. char     hlpbuf[HLPBL+4];             /* Help string buffer */
  1257. char     atmbuf[ATMBL+4];             /* Atom buffer */
  1258. char     filbuf[ATMBL+4];             /* File name buffer */
  1259.  
  1260. /* Command buffer pointers */
  1261.  
  1262. static char     *bp,                /* Current command buffer position */
  1263. *pp,                                /* Start of current field */
  1264. *np;                                /* Start of next field */
  1265.  
  1266. long     zchki();                           /* From ck?fio.c. */
  1267.  
  1268.  
  1269. /*  C M S E T P  --  Set the program prompt.  */
  1270.  
  1271. cmsetp(s)
  1272. char     *s;
  1273. {
  1274.      char     *sx, *sy, *strncpy();
  1275.      psetf = 1;                          /* Flag that prompt has been set. */
  1276.      strncpy(cmprom, s, PROML - 1);      /* Copy the string. */
  1277.      cmprom[PROML] = NUL;                /* Ensure null terminator. */
  1278.      sx = cmprom;
  1279.      sy = cmerrp;           /* Also use as error message prefix. */
  1280.      while (*sy++ = *sx++)  ;            /* Copy */
  1281.      sy -= 2;
  1282.      if (*sy == '>')
  1283.           *sy = NUL; /* Delete any final '>'. */
  1284. }
  1285.  
  1286.  
  1287. /*  C M S A V P  --  Save a copy of the current prompt.  */
  1288.  
  1289. cmsavp(s, n)
  1290. int     n;
  1291. char     s[];
  1292. {
  1293.      extern char     *strncpy();                         /* +1   */
  1294.      strncpy(s, cmprom, n - 1);
  1295.      s[n] = NUL;
  1296. }
  1297.  
  1298.  
  1299. /*  P R O M P T  --  Issue the program prompt.  */
  1300.  
  1301. prompt()
  1302. {
  1303.      if (psetf == 0)
  1304.           cmsetp(dfprom);     /* If no prompt set, set default. */
  1305. #ifndef MCS_FLAG
  1306.      printf("\r%s", cmprom);              /* Print the prompt. */
  1307. #else
  1308.        sprintf(print_str,"\r%s", cmprom);
  1309.        mcs_printf(print_str);             /* Print the prompt. */
  1310. #endif
  1311. }
  1312.  
  1313.  
  1314. /*  C M R E S  --  Reset pointers to beginning of command buffer.  */
  1315.  
  1316. cmres()
  1317. {
  1318.      cc = 0;                             /* Reset character counter. */
  1319.      pp = np = bp = cmdbuf;              /* Point to command buffer. */
  1320.      cmflgs = -5;                        /* Parse not yet started. */
  1321. }
  1322.  
  1323.  
  1324. /*  C M I N I  --  Clear the command and atom buffers, reset pointers.  */
  1325.  
  1326. /*
  1327. The argument specifies who is to echo the user's typein --
  1328.   1 means the cmd package echoes
  1329.   0 somebody else (system, front end, terminal) echoes
  1330. */
  1331. cmini(d)
  1332. int     d;
  1333. {
  1334.      for (bp = cmdbuf; bp < cmdbuf + CMDBL; bp++)
  1335.           *bp = NUL;
  1336.      *atmbuf = NUL;
  1337.      dpx = d;
  1338.      cmres();
  1339. }
  1340.  
  1341.  
  1342. stripq(s)
  1343. char     *s;
  1344. {                    /* Function to strip '\' quotes */
  1345.      char     *t;
  1346.      while (*s) {
  1347.           if (*s == '\\') {
  1348.                for (t = s; *t != '\0'; t++)
  1349.                     *t = *(t + 1);
  1350.           }
  1351.           s++;
  1352.      }
  1353. }
  1354.  
  1355.  
  1356. /*  C M N U M  --  Parse a number in the indicated radix  */
  1357.  
  1358. /*  For now, only works for positive numbers in base 10.  */
  1359.  
  1360. /*
  1361.  Returns
  1362.    -3 if no input present when required,
  1363.    -2 if user typed an illegal number,
  1364.    -1 if reparse needed,
  1365.     0 otherwise, with n set to number that was parsed
  1366. */
  1367. cmnum(xhlp, xdef, radix, n)
  1368. char     *xhlp, *xdef;
  1369. int     radix, *n;
  1370. {
  1371.      int     x;
  1372.      char    *s;       /* will point to atmbuf or xdef */
  1373.  
  1374.      if (radix != 10) {                  /* Just do base 10 for now */
  1375. #ifndef MCS_FLAG
  1376.           printf("cmnum: illegal radix - %d\n", radix);
  1377. #else
  1378.           sprintf(print_str,"cmnum: illegal radix - %d\n", radix);
  1379.           mcs_printf(print_str);
  1380. #endif
  1381.           return(-1);
  1382.      }
  1383.  
  1384.      x = cmfld(xhlp, xdef, &s);
  1385.  
  1386.      if (deblog) debug(F101, "cmnum: cmfld", "", x);
  1387.  
  1388.      if (x < 0)
  1389.           return(x);    /* Parse a field */
  1390.  
  1391.      if (digits(s)) {               /* Convert to number */
  1392.           *n = atoi(s);
  1393.           return(x);
  1394.      } else {
  1395. #ifndef MCS_FLAG
  1396.       /* In IVS-Kermit, back spaces are handled by IVS, so there is
  1397.        * no chance of encountering a back space character. */
  1398.  
  1399.           printf("\n?not a number - %s\n", s);
  1400.           return(-2);
  1401. #else
  1402.       /* In MCS-Kermit, the kermit logic itself handles back space
  1403.        * characters.  So, if the current field is not a number,
  1404.        * then maybe the user entered back spaces later on in the
  1405.        * command line.  In order to reparse the command, we will
  1406.        * dummy up the return value and integer pointer.  The setnum
  1407.        * routine will see the changes and put out an error message
  1408.        * if no back spaces were entered.  If back spaces were
  1409.        * entered, then the setnum routine will return a value that
  1410.        * will cause the entire command to be reparsed. */
  1411.  
  1412.       /*  sprintf(print_str,"\n?not a number - %s\n", s);
  1413.        *  mcs_printf(print_str); */
  1414.  
  1415.           *n = -562;     /* unusual number to signify error */
  1416.           return(0);
  1417. #endif
  1418.      }
  1419. }
  1420.  
  1421.  
  1422. /*  C M O F I  --  Parse the name of an output file  */
  1423.  
  1424. /*
  1425.  Depends on the external function zchko(); if zchko() not available, use
  1426.  cmfld() to parse output file names.
  1427.  
  1428.  Returns
  1429.    -3 if no input present when required,
  1430.    -2 if permission would be denied to create the file,
  1431.    -1 if reparse needed,
  1432.     0 or 1 otherwise, with xp pointing to name.
  1433. */
  1434. cmofi(xhlp, xdef, xp)
  1435. char     *xhlp, *xdef, **xp;
  1436. {
  1437.      int     x;
  1438.      char     *s;
  1439.  
  1440.      if (*xhlp == NUL)
  1441.           xhlp = "Output file";
  1442.      *xp = "";
  1443.  
  1444.      if ((x = cmfld(xhlp, xdef, &s)) < 0)
  1445.           return(x);
  1446.  
  1447.      if (chkwld(s)) {
  1448. #ifndef MCS_FLAG
  1449.           printf("\n?Wildcards not allowed - %s\n", s);
  1450. #else
  1451.           sprintf(print_str,"\n?Wildcards not allowed - %s\n", s);
  1452.           mcs_printf(print_str);
  1453. #endif
  1454.           return(-2);
  1455.      }
  1456.      if (zchko(s) < 0) {
  1457. #ifndef MCS_FLAG
  1458.           printf("\n?Write permission denied - %s\n", s);
  1459. #else
  1460.           sprintf(print_str,"\n?Write permission denied - %s\n", s);
  1461.           mcs_printf(print_str);
  1462. #endif
  1463.           return(-2);
  1464.      } else {
  1465.           *xp = s;
  1466.           return(x);
  1467.      }
  1468. }
  1469.  
  1470.  
  1471. /*  C M I F I  --  Parse the name of an existing file  */
  1472.  
  1473. /*
  1474.  This function depends on the external functions:
  1475.    zchki()  - Check if input file exists and is readable.
  1476.    zxpand() - Expand a wild file specification into a list.
  1477.    znext()  - Return next file name from list.
  1478.  If these functions aren't available, then use cmfld() to parse filenames.
  1479. */
  1480. /*
  1481.  Returns
  1482.    -4 EOF
  1483.    -3 if no input present when required,
  1484.    -2 if file does not exist or is not readable,
  1485.    -1 if reparse needed,
  1486.     0 or 1 otherwise, with:
  1487.         xp pointing to name,
  1488.         wild = 1 if name contains '*' or '?', 0 otherwise.
  1489. */
  1490. cmifi(xhlp, xdef, xp, wild)
  1491. char     *xhlp, *xdef, **xp;
  1492. int     *wild;
  1493. {
  1494.      int     i, x, xc;
  1495.      long     y;
  1496.      char     *sp;
  1497.  
  1498.      cc = xc = 0;                        /* Initialize counts & pointers */
  1499.      *xp = "";
  1500.      if ((x = cmflgs) != 1) {            /* Already confirmed? */
  1501.           x = gtword();                   /* No, get a word */
  1502.      } else {
  1503.           cc = setatm(xdef);              /* If so, use default, if any. */
  1504.      }
  1505.      *xp = atmbuf;                       /* Point to result. */
  1506.      *wild = chkwld(*xp);
  1507.  
  1508.      while (1) {
  1509.           xc += cc;                       /* Count the characters. */
  1510.           if (deblog) debug(F111, "cmifi: gtword", atmbuf, xc);
  1511.           switch (x) {
  1512.           case -4:                    /* EOF */
  1513.           case -2:                    /* Out of space. */
  1514.           case -1:                    /* Reparse needed */
  1515.                return(x);
  1516.  
  1517.           case 0:                     /* SP or NL */
  1518.           case 1:
  1519.                if (xc == 0)
  1520.                     *xp = xdef;    /* If no input, return default. */
  1521.                else
  1522.                     *xp = atmbuf;
  1523.                if (**xp == NUL)
  1524.                     return(-3); /* If field empty, return -3. */
  1525.  
  1526.                /* If filespec is wild, see if there are any matches */
  1527.  
  1528.                *wild = chkwld(*xp);
  1529.                if (deblog) debug(F101, " *wild", "", *wild);
  1530.                if (*wild != 0) {
  1531.                     y = zxpand(*xp);
  1532.                     if (y == 0) {
  1533. #ifndef MCS_FLAG
  1534.                          printf("\n?No files match - %s\n", *xp);
  1535. #else
  1536.                          sprintf(print_str,"\n?No files match - %s\n", *xp);
  1537.                          mcs_printf(print_str);
  1538. #endif
  1539.                          return(-2);
  1540.                     } else if (y < 0) {
  1541. #ifndef MCS_FLAG
  1542.                          printf("\n?Too many files match - %s\n", *xp);
  1543. #else
  1544.                          sprintf(print_str,"\n?Too many files match - %s\n",
  1545.                                  *xp);
  1546.                          mcs_printf(print_str);
  1547. #endif
  1548.                          return(-2);
  1549.                     } else
  1550.                          return(x);
  1551.                }
  1552.  
  1553.                /* If not wild, see if it exists and is readable. */
  1554.  
  1555.                y = zchki(*xp);
  1556.                if (y == -3) {
  1557. #ifndef MCS_FLAG
  1558.                     printf("\n?Read permission denied - %s\n", *xp);
  1559. #else
  1560.                     sprintf(print_str,"\n?Read permission denied - %s\n", *xp);
  1561.                     mcs_printf(print_str);
  1562. #endif
  1563.                     return(-2);
  1564.                } else if (y == -2) {
  1565. #ifndef MCS_FLAG
  1566.                     printf("\n?File not readable - %s\n", *xp);
  1567. #else
  1568.                     sprintf(print_str,"\n?File not readable - %s\n", *xp);
  1569.                     mcs_printf(print_str);
  1570. #endif
  1571.                     return(-2);
  1572.                } else if (y < 0) {
  1573. #ifndef MCS_FLAG
  1574.                     printf("\n?File not found - %s\n", *xp);
  1575. #else
  1576.                     sprintf(print_str,"\n?File not found - %s\n", *xp);
  1577.                     mcs_printf(print_str);
  1578. #endif
  1579.                     return(-2);
  1580.                }
  1581.                return(x);
  1582.  
  1583.     /*       case 2:                     * ESC *
  1584.     *           if (xc == 0) {
  1585.     *               if (*xdef != '\0') {
  1586.     *                   printf("%s ",xdef); * If at beginning of field, *
  1587.     *                   addbuf(xdef);   * supply default. *
  1588.     *                   cc = setatm(xdef);
  1589.     *               } else {            * No default *
  1590.     *                   putchar(BEL);
  1591.     *               }
  1592.     *               break;
  1593.     *           }
  1594.     *           if (*wild = chkwld(*xp)) {  * No completion if wild *
  1595.     *               putchar(BEL);
  1596.     *               break;
  1597.     *           }
  1598.     *           sp = atmbuf + cc;
  1599.     *           *sp++ = '*';
  1600.     *           *sp-- = '\0';
  1601.     *           y = zxpand(atmbuf);     * Add * and expand list. *
  1602.     *           *sp = '\0';             * Remove *. *
  1603.     *
  1604.     *           if (y == 0) {
  1605.     *               printf("\n?No files match - %s\n",atmbuf);
  1606.     *               return(-2);
  1607.     *           } else if (y < 0) {
  1608.     *               printf("\n?Too many files match - %s\n",atmbuf);
  1609.     *               return(-2);
  1610.     *           } else if (y > 1) {     * Not unique, just beep. *
  1611.     *              putchar(BEL);
  1612.     *           } else {                * Unique, complete it.  *
  1613.     *               znext(filbuf);      * Get whole name of file. *
  1614.     *               sp = filbuf + cc;   * Point past what user typed. *
  1615.     *               printf("%s ",sp);   * Complete the name. *
  1616.     *               addbuf(sp);         * Add the characters to cmdbuf. *
  1617.     *               setatm(pp);         * And to atmbuf. *
  1618.     *               *xp = atmbuf;       * Return pointer to atmbuf. *
  1619.     *               return(cmflgs = 0);
  1620.     *           }
  1621.     *           break;
  1622.     */
  1623.  
  1624.           case 3:                     /* Question mark */
  1625.                if (*xhlp == NUL)
  1626. #ifndef MCS_FLAG
  1627.                     printf(" Input file specification");
  1628. #else
  1629.                     mcs_printf(" Input file specification");
  1630. #endif
  1631.                else
  1632. #ifndef MCS_FLAG
  1633.                     printf(" %s", xhlp);
  1634. #else
  1635.                     sprintf(print_str," %s", xhlp);
  1636.                     mcs_printf(print_str);
  1637. #endif
  1638.                if (xc > 0) {
  1639.                     sp = atmbuf + cc;   /* Insert * at end */
  1640.                     *sp++ = '*';
  1641.                     *sp-- = '\0';
  1642.                     y = zxpand(atmbuf);
  1643.                     *sp = '\0';
  1644.                     if (y == 0) {
  1645. #ifndef MCS_FLAG
  1646.                          printf("\n?No files match - %s\n", atmbuf);
  1647. #else
  1648.                          sprintf(print_str,"\n?No files match - %s\n", atmbuf);
  1649.                          mcs_printf(print_str);
  1650. #endif
  1651.                          return(-2);
  1652.                     } else if (y < 0) {
  1653. #ifndef MCS_FLAG
  1654.                          printf("\n?Too many file match - %s\n",
  1655.                               atmbuf);
  1656. #else
  1657.                          sprintf(print_str,"\n?Too many file match - %s\n",
  1658.                               atmbuf);
  1659.                          mcs_printf(print_str);
  1660. #endif
  1661.                          return(-2);
  1662.                     } else {
  1663. #ifndef MCS_FLAG
  1664.                          printf(", one of the following:\n");
  1665. #else
  1666.                          mcs_printf(", one of the following:\n");
  1667. #endif
  1668.                          clrhlp();
  1669.                          for (i = 0; i < y; i++) {
  1670.                               znext(filbuf);
  1671.                               addhlp(filbuf);
  1672.                          }
  1673.                          dmphlp();
  1674.                     }
  1675.                } else
  1676. #ifndef MCS_FLAG
  1677.                     printf("\n");
  1678. #else
  1679.                     mcs_printf("\n");
  1680. #endif
  1681. #ifndef MCS_FLAG
  1682.                printf("%s%s", cmprom, cmdbuf);
  1683. #else
  1684.                sprintf(print_str,"%s%s", cmprom, cmdbuf);
  1685.                mcs_printf(print_str);
  1686. #endif
  1687.                break;
  1688.           }
  1689.           x = gtword();
  1690.      }
  1691. }
  1692.  
  1693.  
  1694.  
  1695. /*  C H K W L D  --  Check for wildcard characters '*' or '?'  */
  1696.  
  1697. chkwld(s)
  1698. char     *s;
  1699. {
  1700.  
  1701.      for ( ; *s != '\0'; s++) {
  1702.           if ((*s == '*') || (*s == '?'))
  1703.                return(1);
  1704.      }
  1705.      return(0);
  1706. }
  1707.  
  1708.  
  1709. /*  C M F L D  --  Parse an arbitrary field  */
  1710. /*
  1711.  Returns
  1712.    -3 if no input present when required,
  1713.    -2 if field too big for buffer,
  1714.    -1 if reparse needed,
  1715.     0 otherwise, xp pointing to string result.
  1716. */
  1717. cmfld(xhlp, xdef, xp)
  1718. char     *xhlp, *xdef, **xp;
  1719. {
  1720.      int     x, xc;
  1721.  
  1722.      cc = xc = 0;                        /* Initialize counts & pointers */
  1723.      *xp = "";
  1724.      if ((x = cmflgs) != 1) {            /* Already confirmed? */
  1725.           x = gtword();                   /* No, get a word */
  1726.      } else {
  1727.           cc = setatm(xdef);              /* If so, use default, if any. */
  1728.      }
  1729.      *xp = atmbuf;                       /* Point to result. */
  1730.  
  1731.      while (1) {
  1732.           xc += cc;                       /* Count the characters. */
  1733.           if (deblog) debug(F111, "cmfld: gtword", atmbuf, xc);
  1734.           if (deblog) debug(F101, " x", "", x);
  1735.           switch (x) {
  1736.           case -4:                    /* EOF */
  1737.           case -2:                    /* Out of space. */
  1738.           case -1:                    /* Reparse needed */
  1739.                return(x);
  1740.           case 0:                     /* SP or NL */
  1741.           case 1:
  1742.                if (xc == 0)
  1743.                     *xp = xdef;    /* If no input, return default. */
  1744.                else
  1745.                     *xp = atmbuf;
  1746.                if (**xp == NUL)
  1747.                     x = -3;    /* If field empty, return -3. */
  1748.                return(x);
  1749.  
  1750.    /*      case 2:                     * ESC *
  1751.     *            if (xc == 0) {
  1752.     *                printf("%s ",xdef); * If at beginning of field, *
  1753.     *                addbuf(xdef);       * supply default. *
  1754.     *                cc = setatm(xdef);  * Return as if whole field *
  1755.     *                return(0);          * typed, followed by space. *
  1756.     *            } else {
  1757.     *                putchar(BEL);       * Beep if already into field. *
  1758.     *            }
  1759.     *            break;
  1760.     */
  1761.  
  1762.           case 3:                     /* Question mark */
  1763.                if (*xhlp == NUL)
  1764. #ifndef MCS_FLAG
  1765.                     printf(" Please complete this field");
  1766. #else
  1767.                     mcs_printf(" Please complete this field");
  1768. #endif
  1769.                else
  1770. #ifndef MCS_FLAG
  1771.                     printf(" %s", xhlp);
  1772. #else
  1773.                     sprintf(print_str," %s", xhlp);
  1774.                     mcs_printf(print_str);
  1775. #endif
  1776. #ifndef MCS_FLAG
  1777.                printf("\n%s%s", cmprom, cmdbuf);
  1778. #else
  1779.                sprintf(print_str,"\n%s%s", cmprom, cmdbuf);
  1780.                mcs_printf(print_str);
  1781. #endif
  1782.                break;
  1783.           }
  1784.           x = gtword();
  1785.      }
  1786. }
  1787.  
  1788.  
  1789. /*  C M T X T  --  Get a text string, including confirmation  */
  1790.  
  1791. /*
  1792.   Print help message 'xhlp' if ? typed, supply default 'xdef' if null
  1793.   string typed.  Returns
  1794.  
  1795.    -1 if reparse needed or buffer overflows.
  1796.     1 otherwise.
  1797.  
  1798.   with cmflgs set to return code, and xp pointing to result string.
  1799. */
  1800.  
  1801. cmtxt(xhlp, xdef, xp)
  1802. char     *xhlp;
  1803. char     *xdef;
  1804. char     **xp;
  1805. {
  1806.      int     x;
  1807.      static int     xc;
  1808.  
  1809.      if (deblog) debug(F101, "cmtxt: cmflgs", "", cmflgs);
  1810.      cc = 0;                             /* Start atmbuf counter off at 0 */
  1811.      if (cmflgs == -1) {                 /* If reparsing, */
  1812.           xc = strlen(*xp);               /* get back the total text length, */
  1813.      } else {                            /* otherwise, */
  1814.           *xp = "";                       /* start fresh. */
  1815.           xc = 0;
  1816.      }
  1817.      *atmbuf = NUL;                      /* And empty atom buffer. */
  1818.      if ((x = cmflgs) != 1) {
  1819.           x = gtword();                   /* Get first word. */
  1820.           *xp = pp;                       /* Save pointer to it. */
  1821.      }
  1822.      while (1) {
  1823.           xc += cc;                       /* Char count for all words. */
  1824.           if (deblog) debug(F111, "cmtxt: gtword", atmbuf, xc);
  1825.           if (deblog) debug(F101, " x", "", x);
  1826.           switch (x) {
  1827.           case -4:                    /* EOF */
  1828.           case -2:                    /* Overflow */
  1829.           case -1:                    /* Deletion */
  1830.                return(x);
  1831.           case 0:                     /* Space */
  1832.                xc++;                   /* Just count it */
  1833.                break;
  1834.           case 1:                     /* CR or LF */
  1835.                if (xc == 0)
  1836.                     *xp = xdef;
  1837.                return(x);
  1838.  
  1839.    /*     case 2:                     * ESC *
  1840.     *           if (xc == 0) {
  1841.     *               printf("%s ",xdef);
  1842.     *               cc = addbuf(xdef);
  1843.     *           } else {
  1844.     *               putchar(BEL);
  1845.     *           }
  1846.     *           break;
  1847.     */
  1848.  
  1849.           case 3:                     /* Question Mark */
  1850.                if (*xhlp == NUL)
  1851. #ifndef MCS_FLAG
  1852.                     printf(" Text string");
  1853. #else
  1854.                     mcs_printf(" Text string");
  1855. #endif
  1856.                else
  1857. #ifndef MCS_FLAG
  1858.                     printf(" %s", xhlp);
  1859. #else
  1860.                     sprintf(print_str," %s", xhlp);
  1861.                     mcs_printf(print_str);
  1862. #endif
  1863. #ifndef MCS_FLAG
  1864.                  printf("\n%s%s", cmprom, cmdbuf);
  1865. #else
  1866.                  sprintf(print_str,"\n%s%s", cmprom, cmdbuf);
  1867.                  mcs_printf(print_str);
  1868. #endif
  1869.                break;
  1870.           default:
  1871. #ifndef MCS_FLAG
  1872.                printf("\n?Unexpected return code from gtword() - %d\n",
  1873.                     x);
  1874. #else
  1875.                sprintf(print_str,
  1876.                    "\n?Unexpected return code from gtword() - %d\n",x);
  1877.                mcs_printf(print_str);
  1878. #endif
  1879.                return(-2);
  1880.           }
  1881.           x = gtword();
  1882.      }
  1883. }
  1884.  
  1885.  
  1886. /*  C M K E Y  --  Parse a keyword  */
  1887.  
  1888. /*
  1889.  Call with:
  1890.    table    --  keyword table, in 'struct keytab' format;
  1891.    n        --  number of entries in table;
  1892.    xhlp     --  pointer to help string;
  1893.    xdef     --  pointer to default keyword;
  1894.  
  1895.  Returns:
  1896.    -3       --  no input supplied and no default available
  1897.    -2       --  input doesn't uniquely match a keyword in the table
  1898.    -1       --  user deleted too much, command reparse required
  1899.     n >= 0  --  value associated with keyword
  1900. */
  1901.  
  1902. cmkey(table, n, xhlp, xdef)
  1903. struct keytab table[];
  1904. int     n;
  1905. char     *xhlp, *xdef;
  1906. {
  1907.      int     i, y, z, zz, xc;
  1908.      char    *xp;
  1909.  
  1910.      xc = cc = 0;                        /* Clear character counters. */
  1911.  
  1912.      if ((zz = cmflgs) == 1)             /* Command already entered? */
  1913.           setatm(xdef);
  1914.      else
  1915.           zz = gtword();
  1916.  
  1917.      if (deblog) {
  1918.           debug(F101, "cmkey: table length", "", n);
  1919.           debug(F101, " cmflgs", "", cmflgs);
  1920.           debug(F101, " zz", "", zz);
  1921.      }
  1922.      while (1) {
  1923.           xc += cc;
  1924.           if (deblog) debug(F111, "cmkey: gtword", atmbuf, xc);
  1925.  
  1926.           switch (zz) {
  1927.           case -4:                        /* EOF */
  1928.           case -2:                        /* Buffer overflow */
  1929.           case -1:                        /* Or user did some deleting. */
  1930.                return(zz);
  1931.  
  1932.           case 0:                         /* User terminated word with space */
  1933.           case 1:                         /* or newline */
  1934.                if (cc == 0) setatm(xdef);
  1935.                y = lookup(table, atmbuf, n, &z);
  1936.                switch (y) {
  1937.                case -2:
  1938. #ifndef MCS_FLAG
  1939.                     printf("\n?Ambiguous - %s\n", atmbuf);
  1940. #else
  1941.                     sprintf(print_str,"\n?Ambiguous - %s\n", atmbuf);
  1942.                     mcs_printf(print_str);
  1943. #endif
  1944.                     return(cmflgs = -2);
  1945.                case -1:
  1946.                     /* User entered an item not in the current table.
  1947.                      * They might have entered a help command like,
  1948.                      * 'SET ?' but have backspaced to enter a new
  1949.                      * command.  In IVS-Kermit, we don't see the
  1950.                      * space characters, so we need to handle the
  1951.                      * situation here.  Check the command table.  If
  1952.                      * a match is found, reset the command table and
  1953.                      * reparse the whole command again.
  1954.                      */
  1955.                     y = lookup(cmdtab,atmbuf,ncmd,&z);
  1956.                     if (y >= 0) {              /* must be new command */
  1957.                       cmres();                 /* reset buffer pointers */
  1958.                       strcpy(cmdbuf,atmbuf);   /* move new cmd into buf */
  1959.                       strcat(cmdbuf," ");      /* space is word terminator */
  1960.                       np = cmdbuf + strlen(cmdbuf); /* reset next field ptr */
  1961.                       return(cmflgs = -1);     /* reparse the command */
  1962.                     }
  1963.  
  1964.                     /* user entered invalid command */
  1965. #ifndef MCS_FLAG
  1966.                     printf("\n?Invalid - %s\n", atmbuf);
  1967. #else
  1968.                     sprintf(print_str,"\n?Invalid - %s\n", atmbuf);
  1969.                     mcs_printf(print_str);
  1970. #endif
  1971.                     return(cmflgs = -2);
  1972.                default:
  1973.                     break;
  1974.                }
  1975.                return(y);
  1976.  
  1977.    /*     case 2:          * User terminated word with ESC *
  1978.     *        if (cc == 0) {
  1979.     *            if (*xdef != NUL) {     * Nothing in atmbuf *
  1980.     *                printf("%s ",xdef); * Supply default if any *
  1981.     *                addbuf(xdef);
  1982.     *                cc = setatm(xdef);
  1983.     *                if (deblog) debug(F111,"cmkey: default",atmbuf,cc);
  1984.     *            } else {
  1985.     *                putchar(BEL);       * No default, just beep *
  1986.     *                break;
  1987.     *            }
  1988.     *        }
  1989.     *        y = lookup(table,atmbuf,n,&z); * Something in atmbuf *
  1990.     *        if (deblog) debug(F111,"cmkey: esc",atmbuf,y);
  1991.     *        if (y == -2) {
  1992.     *            putchar(BEL);
  1993.     *            break;
  1994.     *        }
  1995.     *        if (y == -1) {
  1996.     *            printf("\n?Invalid - %s\n",atmbuf);
  1997.     *            return(cmflgs = -2);
  1998.     *        }
  1999.     *        xp = table[z].kwd + cc;
  2000.     *        printf("%s ",xp);
  2001.     *        addbuf(xp);
  2002.     *        if (deblog) debug(F110,"cmkey: addbuf",cmdbuf,0);
  2003.     *        return(y);
  2004.     */
  2005.  
  2006.           case 3:                         /* User terminated word with "?" */
  2007.                y = lookup(table, atmbuf, n, &z);
  2008.                if (y > -1) {
  2009. #ifndef MCS_FLAG
  2010.                     printf(" %s\n%s%s", table[z].kwd, cmprom, cmdbuf);
  2011. #else
  2012.                     sprintf(print_str," %s\n%s%s", table[z].kwd,
  2013.                             cmprom, cmdbuf);
  2014.                     mcs_printf(print_str);
  2015. #endif
  2016.                     break;
  2017.                } else if (y == -1) {
  2018. #ifndef MCS_FLAG
  2019.                     printf("\n?Invalid\n");
  2020. #else
  2021.                     mcs_printf("\n?Invalid\n");
  2022. #endif
  2023.                     return(cmflgs = -2);
  2024.                }
  2025.  
  2026.                if (*xhlp == NUL)
  2027. #ifndef MCS_FLAG
  2028.                     printf(" One of the following:\n");
  2029. #else
  2030.                     mcs_printf(" One of the following:\n");
  2031. #endif
  2032.                else
  2033. #ifndef MCS_FLAG
  2034.                     printf(" %s, one of the following:\n", xhlp);
  2035. #else
  2036.                     sprintf(print_str," %s, one of the following:\n", xhlp);
  2037.                     mcs_printf(print_str);
  2038. #endif
  2039.  
  2040.                clrhlp();
  2041.                for (i = 0; i < n; i++) {
  2042.                     if (!strncmp(table[i].kwd, atmbuf, cc)
  2043.                         && !test(table[i].flgs, CM_INV))
  2044.                          addhlp(table[i].kwd);
  2045.                }
  2046.                dmphlp();
  2047. #ifndef MCS_FLAG
  2048.                printf("%s%s", "Again>", cmdbuf);
  2049. #else
  2050.                sprintf(print_str,"%s%s", "Again>",cmdbuf);
  2051.                mcs_printf(print_str);
  2052. #endif
  2053.                break;
  2054.  
  2055.           default:
  2056. #ifndef MCS_FLAG
  2057.                printf("\n%d - Unexpected return code from gtword\n", zz);
  2058. #else
  2059.                sprintf(print_str,
  2060.                   "\n%d - Unexpected return code from gtword\n", zz);
  2061.                mcs_printf(print_str);
  2062. #endif
  2063.                return(cmflgs = -2);
  2064.           }
  2065.           zz = gtword();
  2066.      }
  2067. }
  2068.  
  2069.  
  2070. /*  C M C F M  --  Parse command confirmation (end of line)  */
  2071.  
  2072. /*
  2073.  Returns
  2074.    -2: User typed anything but whitespace or newline
  2075.    -1: Reparse needed
  2076.     0: Confirmation was received
  2077. */
  2078.  
  2079. cmcfm()
  2080. {
  2081.      int     x, xc;
  2082.  
  2083.      if (deblog) debug(F101, "cmcfm: cmflgs", "", cmflgs);
  2084.  
  2085.      xc = cc = 0;
  2086.      if (cmflgs == 1)
  2087.           return(0);
  2088.  
  2089.      while (1) {
  2090.           x = gtword();
  2091.           xc += cc;
  2092.           if (deblog) debug(F111, "cmcfm: gtword", atmbuf, xc);
  2093.           switch (x) {
  2094.           case -4:                    /* EOF */
  2095.           case -2:
  2096.           case -1:
  2097.                return(x);
  2098.  
  2099.           case 0:                     /* Space */
  2100.                continue;
  2101.           case 1:                     /* End of line */
  2102.                if (xc > 0) {
  2103. #ifndef MCS_FLAG
  2104.                     printf("?Not confirmed - %s\n", atmbuf);
  2105. #else
  2106.                     sprintf(print_str,"?Not confirmed - %s\n", atmbuf);
  2107.                     mcs_printf(print_str);
  2108. #endif
  2109.                     return(-2);
  2110.                } else
  2111.                     return(0);
  2112.  
  2113.   /*      case 2:
  2114.    *            putchar(BEL);
  2115.    *            continue;
  2116.    */
  2117.  
  2118.           case 3:
  2119.                if (xc > 0) {
  2120. #ifndef MCS_FLAG
  2121.                     printf("\n?Not confirmed - %s\n", atmbuf);
  2122. #else
  2123.                     sprintf(print_str,"\n?Not confirmed - %s\n", atmbuf);
  2124.                     mcs_printf(print_str);
  2125. #endif
  2126.                     return(-2);
  2127.                }
  2128. #ifndef MCS_FLAG
  2129.                printf("\n Type a carriage return to confirm the command\n");
  2130.                printf("%s%s", cmprom, cmdbuf);
  2131. #else
  2132.                mcs_printf("\n Type a carriage return to confirm the command\n");
  2133.                sprintf(print_str,"%s%s", cmprom, cmdbuf);
  2134.                mcs_printf(print_str);
  2135. #endif
  2136.                continue;
  2137.           }
  2138.      }
  2139. }
  2140.  
  2141.  
  2142. /* Keyword help routines */
  2143.  
  2144.  
  2145. /*  C L R H L P -- Initialize/Clear the help line buffer  */
  2146.  
  2147. clrhlp()
  2148. {                              /* Clear the help buffer */
  2149.      hlpbuf[0] = NUL;
  2150.      hh = hx = 0;
  2151. }
  2152.  
  2153.  
  2154. /*  A D D H L P  --  Add a string to the help line buffer  */
  2155.  
  2156. addhlp(s)
  2157. char     *s;
  2158. {                    /* Add a word to the help buffer */
  2159.      int     j;
  2160.  
  2161.      hh++;                               /* Count this column */
  2162.  
  2163.      for (j = 0; (j < hc) && (*s != NUL); j++) { /* Fill the column */
  2164.           hlpbuf[hx++] = *s++;
  2165.      }
  2166.      if (*s != NUL)                      /* Still some chars left in string? */
  2167.           hlpbuf[hx-1] = '+';             /* Mark as too long for column. */
  2168.  
  2169.      if (hh < (hw / hc)) {               /* Pad col with spaces if necessary */
  2170.           for (; j < hc; j++) {
  2171.                hlpbuf[hx++] = SP;
  2172.           }
  2173.      } else {                            /* If last column, */
  2174.           hlpbuf[hx++] = NUL;             /* no spaces. */
  2175.           dmphlp();                       /* Print it. */
  2176.           return;
  2177.      }
  2178. }
  2179.  
  2180.  
  2181. /*  D M P H L P  --  Dump the help line buffer  */
  2182.  
  2183. dmphlp()
  2184. {                              /* Print the help buffer */
  2185.      hlpbuf[hx++] = NUL;
  2186. #ifndef MCS_FLAG
  2187.      printf(" %s\n", hlpbuf);
  2188. #else
  2189.      sprintf(print_str," %s\n", hlpbuf);
  2190.      mcs_printf(print_str);
  2191. #endif
  2192.      clrhlp();
  2193. }
  2194.  
  2195.  
  2196. /*  L O O K U P  --  Lookup the string in the given array of strings  */
  2197.  
  2198. /*
  2199.  Call this way:  v = lookup(table,word,n,&x);
  2200.  
  2201.    table - a 'struct keytab' table.
  2202.    word  - the target string to look up in the table.
  2203.    n     - the number of elements in the table.
  2204.    x     - address of an integer for returning the table array index.
  2205.  
  2206.  The keyword table must be arranged in ascending alphabetical order, and
  2207.  all letters must be lowercase.
  2208.  
  2209.  Returns the keyword's associated value ( zero or greater ) if found,
  2210.  with the variable x set to the array index, or:
  2211.  
  2212.   -3 if nothing to look up (target was null),
  2213.   -2 if ambiguous,
  2214.   -1 if not found.
  2215.  
  2216.  A match is successful if the target matches a keyword exactly, or if
  2217.  the target is a prefix of exactly one keyword.  It is ambiguous if the
  2218.  target matches two or more keywords from the table.
  2219. */
  2220.  
  2221. lookup(table, cmd, n, x)
  2222. char     *cmd;
  2223. struct keytab table[];
  2224. int     n, *x;
  2225. {
  2226.  
  2227.      int     i, v, cmdlen;
  2228.  
  2229.      /* Lowercase & get length of target, if it's null return code -3. */
  2230.  
  2231.      if ((((cmdlen = lower(cmd))) == 0) || (n < 1))
  2232.           return(-3);
  2233.  
  2234.      /* Not null, look it up */
  2235.  
  2236.      for (i = 0; i < n - 1; i++) {
  2237.           if (!strcmp(table[i].kwd, cmd) ||  ((v = !strncmp(table[i].kwd,
  2238.                cmd, cmdlen)) &&  strncmp(table[i+1].kwd, cmd, cmdlen))) {
  2239.                *x = i;
  2240.                return(table[i].val);
  2241.           }
  2242.           if (v) return(-2);
  2243.      }
  2244.  
  2245.      /* Last (or only) element */
  2246.  
  2247.      if (!strncmp(table[n-1].kwd, cmd, cmdlen)) {
  2248.           *x = n - 1;
  2249.           return(table[n-1].val);
  2250.      } else
  2251.           return(-1);
  2252. }
  2253.  
  2254.  
  2255. /*  G E T W D  --  Gets a "word" from the command input stream  */
  2256.  
  2257. /*
  2258. Usage: retcode = gtword();
  2259.  
  2260. Returns:
  2261.  -4 if end of file (e.g. pipe broken)
  2262.  -2 if command buffer overflows
  2263.  -1 if user did some deleting
  2264.   0 if word terminates with SP or tab
  2265.   1 if ... CR
  2266.   3 if ... ?
  2267.  
  2268. With:
  2269.   pp pointing to beginning of word in buffer
  2270.   bp pointing to after current position
  2271.   atmbuf containing a copy of the word
  2272.   cc containing the number of characters in the word copied to atmbuf
  2273. */
  2274. gtword()
  2275. {
  2276.      int     c;                              /* Current char */
  2277.      static int     inword = 0;              /* Flag for start of word found */
  2278.      int     quote = 0;                      /* Flag for quote character */
  2279.      int     echof = 0;                      /* Flag for whether to echo */
  2280.      int     ignore = 0;
  2281.  
  2282.      pp = np;                                /* Start of current field */
  2283.      if (deblog) {
  2284.           debug(F101, "gtword: cmdbuf", "", (int) cmdbuf);
  2285.           debug(F101, " bp", "", (int) bp);
  2286.           debug(F101, " pp", "", (int) pp);
  2287.           debug(F110, " cmdbuf", cmdbuf, 0);
  2288.      }
  2289.  
  2290.      while (bp < cmdbuf + CMDBL) {         /* Loop */
  2291.  
  2292.           ignore = echof = 0;              /* Flag for whether to echo */
  2293.  
  2294.           if ((c = *bp) == NUL) {          /* Get next character */
  2295.                if (dpx) echof = 1;         /* from reparse buffer */
  2296.                c = getchar();              /* or from tty. */
  2297.                if (c == EOF) {
  2298.                     errhdlr("ckucmd: gtword getchar");
  2299.                     return(-4);
  2300.                }
  2301.                c &= 127;                   /* Strip any parity bit. */
  2302.           } else
  2303.                ignore = 1;
  2304.  
  2305.           if (quote == 0) {
  2306.                if (!ignore && (c == '\\')) { /* Quote character */
  2307.                     quote = 1;
  2308.                     continue;
  2309.                }
  2310.                if (c == FF) {               /* Formfeed. */
  2311.                     c = NL;                 /* Replace with newline */
  2312.                     SYSTEM("clear");        /* and clear the screen. */
  2313.                }
  2314.  
  2315.                if (c == HT)
  2316.                     c = ESC;                /* Substitute ESC for tab */
  2317.  
  2318.                if (c == SP) {               /* If space */
  2319.                     *bp++ = c;              /* deposit it in buffer. */
  2320.                     if (echof)
  2321.                          putchar(c);        /* echo it. */
  2322.                     if (inword == 0) {      /* If leading, gobble it. */
  2323.                          pp++;
  2324.                          continue;
  2325.                     } else {                /* If terminating, return. */
  2326.                          np = bp;
  2327.                          setatm(pp);
  2328.                          inword = 0;
  2329.                          return(cmflgs = 0);
  2330.                     }
  2331.                }
  2332.                if (c == NL || c == CR) {    /* CR, LF */
  2333.                     *bp = NUL;              /* End the string */
  2334.                     if (echof) {            /* If echoing, */
  2335.                          putchar(c);        /* echo the typein */
  2336.                          if (c == CR) putchar(NL);
  2337.                     }
  2338.                     np = bp;           /* Where to start next field. */
  2339.                     setatm(pp);        /* Copy this field to atom buffer. */
  2340.                     inword = 0;
  2341.                     return(cmflgs = 1);
  2342.                }
  2343.                if (!ignore && (c == '?')) { /* Question mark */
  2344.                     putchar(c);
  2345.                     *bp = NUL;
  2346.                     setatm(pp);
  2347.  
  2348.                    /* Question mark triggers help message. So, we want
  2349.                     to flush the rest of the input line including the
  2350.                     new line so that the command is not accidently
  2351.                     executed after the help message. */
  2352.  
  2353.                     while ((c = getchar()) != NL && c != CR) ;
  2354.  
  2355.                     return(cmflgs = 3);
  2356.               }
  2357.  
  2358.    /*         if (c == ESC) {             * ESC *
  2359.     *            *bp = NUL;
  2360.     *            setatm(pp);
  2361.     *            return(cmflgs = 2);
  2362.     *        }
  2363.     */
  2364.              if (c == BS || c == RUB) {  /* Character deletion */
  2365.                 if (bp > cmdbuf) {      /* If still in buffer... */
  2366. #ifndef MCS_FLAG
  2367.                     printf("\b \b");    /* erase character from screen, */
  2368. #else
  2369.                     mcs_printf("\b \b");
  2370. #endif
  2371.                     bp--;               /* point behind it, */
  2372.                     if (*bp == SP) inword = 0; /* Flag if current field gone */
  2373.                     *bp = NUL;          /* Erase character from buffer. */
  2374.                 } else {                /* Otherwise, */
  2375.                     putchar(BEL);       /* beep, */
  2376.                     cmres();            /* and start parsing a new command. */
  2377.                 }
  2378.                 if (pp < bp) continue;
  2379.                 else {
  2380.                   cmres();                      /* DRE 5-16-90  Test */
  2381.                   return(cmflgs = -1);
  2382.                 }
  2383.             }
  2384.  
  2385.    /*       if (c == LDEL) {            * ^U, line deletion *
  2386.     *            while ((bp--) > cmdbuf) {
  2387.     *                printf("\b \b");
  2388.     *                *bp = NUL;
  2389.     *            }
  2390.     *            cmres();                * Restart the command. *
  2391.     *            inword = 0;
  2392.     *            return(cmflgs = -1);
  2393.     *        }
  2394.     *
  2395.     *  if (c == WDEL) {            * ^W, word deletion *
  2396.     *            if (bp <= cmdbuf) {     * Beep if nothing to delete *
  2397.     *                putchar(BEL);
  2398.     *                cmres();
  2399.     *                return(cmflgs = -1);
  2400.     *            }
  2401.     *            bp--;
  2402.     *            for ( ; (bp >= cmdbuf) && (*bp == SP) ; bp--) {
  2403.     *                printf("\b \b");
  2404.     *                *bp = NUL;
  2405.     *            }
  2406.     *            for ( ; (bp >= cmdbuf) && (*bp != SP) ; bp--) {
  2407.     *                printf("\b \b");
  2408.     *                *bp = NUL;
  2409.     *            }
  2410.     *            bp++;
  2411.     *            inword = 0;
  2412.     *            return(cmflgs = -1);
  2413.     *        }
  2414.     *        if (c == RDIS) {            * ^R, redisplay *
  2415.     *            *bp = NUL;
  2416.     *            printf("\n%s%s",cmprom,cmdbuf);
  2417.     *            continue;
  2418.     *        }
  2419.     */
  2420.           }
  2421.           if (echof) putchar(c);          /* If tty input, echo */
  2422.           inword = 1;                     /* Flag we're in a word. */
  2423.           if (quote == 0 || c != NL)
  2424.                *bp++ = c;   /* And deposit it. */
  2425.           quote = 0;                      /* Turn off quote. */
  2426.      }                                   /* end of big while */
  2427.      putchar(BEL);                       /* Get here if... */
  2428. #ifndef MCS_FLAG
  2429.      printf("\n?Buffer full\n");
  2430. #else
  2431.      mcs_printf("\n?Buffer full\n");
  2432. #endif
  2433.      return(cmflgs = -2);
  2434. }
  2435.  
  2436.  
  2437. /* Utility functions */
  2438.  
  2439. /* A D D B U F  -- Add the string pointed to by cp to the command buffer  */
  2440.  
  2441. addbuf(cp)
  2442. char     *cp;
  2443. {
  2444.      int     len = 0;
  2445.      while ((*cp != NUL) && (bp < cmdbuf + CMDBL)) {
  2446.           *bp++ = *cp++;                  /* Copy and */
  2447.           len++;                          /* count the characters. */
  2448.      }
  2449.      *bp++ = SP;                         /* Put a space at the end */
  2450.      *bp = NUL;                          /* Terminate with a null */
  2451.      np = bp;                            /* Update the next-field pointer */
  2452.      return(len);                        /* Return the length */
  2453. }
  2454.  
  2455.  
  2456. /*  S E T A T M  --  Deposit a string in the atom buffer  */
  2457.  
  2458. setatm(cp)
  2459. char     *cp;
  2460. {
  2461.      char     *ap;
  2462.      cc = 0;
  2463.      ap = atmbuf;
  2464.      *ap = NUL;
  2465.      while (*cp == SP)  cp++;
  2466.      while ((*cp != SP) && (*cp != NL) && (*cp != NUL) && (*cp != CR)) {
  2467.           *ap++ = *cp++;
  2468.           cc++;
  2469.      }
  2470.      *ap++ = NUL;
  2471.      return(cc);                         /* Return length */
  2472. }
  2473.  
  2474.  
  2475. /*  D I G I T S  -- Verify that all the characters in line are digits  */
  2476.  
  2477. digits(s)
  2478. char     *s;
  2479. {
  2480.      while (*s) {
  2481.           if (!isdigit(*s))
  2482.                return(0);
  2483.           s++;
  2484.      }
  2485.      return(1);
  2486. }
  2487.  
  2488.  
  2489. /*  L O W E R  --  Lowercase a string  */
  2490.  
  2491. lower(s)
  2492. char     *s;
  2493. {
  2494.      int     n = 0;
  2495.      while (*s) {
  2496.           if (isupper(*s))
  2497.                *s = tolower(*s);
  2498.           s++, n++;
  2499.      }
  2500.      return(n);
  2501. }
  2502.  
  2503.  
  2504. /*  T E S T  --  Bit test  */
  2505.  
  2506. test(x, m)
  2507. int     x, m;
  2508. { /*  Returns 1 if any bits from m are on in x, else 0  */
  2509.      return((x & m) ? 1 : 0);
  2510. }
  2511. <<< ckvcon.c >>>
  2512. char     *connv = "Connect Command for VRX/E, V4E(017) 10 May 90";
  2513.  
  2514. /*  C K V C O N  --  Dumb terminal connection to remote system, for NCR-VRX  */
  2515.  
  2516. /**********************************************************************
  2517. *                                                                      *
  2518. * IVS / MCS-Kermit REL 2                                              *
  2519. * source code                                                         *
  2520. *                                                                     *
  2521. * Change History:                                                     *
  2522. *                                                                     *
  2523. *                1. Modify C-Kermit(4E) source code to                *
  2524. *                   produce new module for MCS/IVS-Kermit             *
  2525. *                   ORIGINAL RELEASE                                  *
  2526. *                   June 22, 1990                                     *
  2527. *                                                                     *
  2528. *                                                                     *
  2529. ***********************************************************************/
  2530.  
  2531.  
  2532. /*
  2533.  This module should work under all versions of NCR-VRX.  It calls externally
  2534.  defined system-dependent functions for i/o, but depends upon the existence
  2535.  of the FORK() function.
  2536.  
  2537.  Author: Frank da Cruz (SY.FDC@CU20B),
  2538.  Columbia University Center for Computing Activities, January 1985.
  2539.  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
  2540.  Permission is granted to any individual or institution to use, copy, or
  2541.  redistribute this software so long as it is not sold for profit, provided this
  2542.  copyright notice is retained.
  2543.  
  2544.  Enhanced by H. Fischer to detect when child process (modem reader)
  2545.  reports that the communications line has been broken and hang up.
  2546.  Also enhanced to allow escaping from connect state to command
  2547.  interpreter, to allow sending/receiving without breaking connection.
  2548. */
  2549.  
  2550. #include <stdio.h>
  2551. #include <ctype.h>                      /* Character types */
  2552. #include "ckcdeb.h"
  2553. #include "ckcker.h"
  2554. #include <signal.h>
  2555. #include "kermisc.h"
  2556. #include <setjmp.h>                     /* Longjumps */
  2557. #ifdef MCS_FLAG
  2558. #include "mcs.h"
  2559. #endif
  2560.  
  2561. #ifndef SIGUSR1
  2562. #define SIGUSR1 16
  2563. #endif
  2564.  
  2565. extern int     local, speed, escape, duplex, parity, flow, seslog, mdmtyp;
  2566. extern int     errno, cmask, fmask, deblog;
  2567. extern char     ttname[], sesfil[];
  2568. extern CHAR dopar();
  2569. extern void errhdlr();
  2570.  
  2571. int     i, active;             /* Variables global to this module */
  2572. int     io_retry = 0;
  2573. char     *chstr();
  2574. char     temp[50];
  2575.  
  2576. #define LBUFL 200                       /* Line buffer */
  2577. char     lbuf[LBUFL];
  2578.  
  2579. /* Connect state parent/child communication signal handlers */
  2580.  
  2581. static jmp_buf env_con;                 /* Envir ptr for connect errors */
  2582.  
  2583. static
  2584. conn_int()
  2585. {                            /* Modem read failure handler, */
  2586.      longjmp(env_con, 1);    /* notifies parent process to stop */
  2587. }
  2588.  
  2589.  
  2590. /*  C O N E C T  --  Perform terminal connection  */
  2591.  
  2592. conect()
  2593. {
  2594.      int     pid,                    /* process id of child (modem reader) */
  2595.      parent_id,              /* process id of parent (keyboard reader) */
  2596.      n;
  2597.      int     c;                      /* c is a character, but must be signed
  2598.                                    integer to pass thru -1, which is the
  2599.                                    modem disconnection signal, and is
  2600.                                         different from the character 0377 */
  2601.      char     errmsg[50], *erp;
  2602.  
  2603.      if (!local) {
  2604. #ifndef MCS_FLAG
  2605.           printf("Sorry, you must 'set line' first\n");
  2606. #else
  2607.           mcs_printf("Sorry, you must 'set line' first\n");
  2608. #endif
  2609.           return(-2);
  2610.      }
  2611.      if (speed < 0) {
  2612. #ifndef MCS_FLAG
  2613.           printf("Sorry, you must 'set speed' first\n");
  2614. #else
  2615.           mcs_printf("Sorry, you must 'set speed' first\n");
  2616. #endif
  2617.           return(-2);
  2618.      }
  2619.      if ((escape < 0) || (escape > 0177)) {
  2620. #ifndef MCS_FLAG
  2621.           printf("Your escape character is not ASCII - %d\n",
  2622.               escape);
  2623. #else
  2624.           sprintf(print_str,"Your escape character is not ASCII - %d\n",
  2625.               escape);
  2626.           mcs_printf(print_str);
  2627. #endif
  2628.           return(-2);
  2629.      }
  2630.      if (ttopen(ttname, &local, mdmtyp) < 0) {
  2631.           erp = errmsg;
  2632.           sprintf(erp, "conect: Sorry, can't open %s", ttname);
  2633.           errhdlr(errmsg);
  2634.           return(-2);
  2635.      }
  2636. #ifndef MCS_FLAG
  2637.      printf("Connecting thru %s, speed %d.\r\n", ttname, speed);
  2638.      printf("The escape character is %s (%d).\r\n", chstr(escape),
  2639.           escape);
  2640.      printf("Type the escape character followed by C to get back,\r\n");
  2641.      printf("or followed by ? to see other options.\r\n");
  2642. #else
  2643.      sprintf(print_str,"Connecting thru %s, speed %d.\r\n", ttname, speed);
  2644.      mcs_printf(print_str);
  2645.      sprintf(print_str,"The escape character is %s (%d).\r\n", chstr(escape),
  2646.           escape);
  2647.      mcs_printf(print_str);
  2648.      mcs_printf("Type the escape character followed by C to get back,\r\n");
  2649.      mcs_printf("or followed by ? to see other options.\r\n");
  2650. #endif
  2651.  
  2652.      /* Condition console terminal and communication line */
  2653.  
  2654.      if (conbin(escape) < 0) {
  2655. #ifndef MCS_FLAG
  2656.           printf("Sorry, can't condition console terminal\n");
  2657. #else
  2658.           mcs_printf("Sorry, can't condition console terminal\n");
  2659. #endif
  2660.           return(-2);
  2661.      }
  2662.      if (ttvt(speed, flow) < 0) {
  2663.           conres();
  2664. #ifndef MCS_FLAG
  2665.           printf("Sorry, Can't condition communication line\n");
  2666. #else
  2667.           mcs_printf("Sorry, Can't condition communication line\n");
  2668. #endif
  2669.           return(-2);
  2670.      }
  2671.  
  2672.      parent_id = getpid();           /* Get parent id for signalling */
  2673.      SIGNAL(SIGUSR1, SIG_IGN);        /* Don't KILL parent */
  2674.      pid = FORK();                   /* All ok, make a FORK */
  2675.      if (pid == -1) {
  2676.           conres();                   /* Reset the console. */
  2677.           errhdlr("conect: Can't create keyboard FORK");
  2678. #ifndef MCS_FLAG
  2679.           printf("[Back at Local System]\n");
  2680. #else
  2681.           mcs_printf("[Back at Local System]\n");
  2682. #endif
  2683.           return(0);
  2684.      }
  2685.      io_retry = 0;
  2686.      if (pid) {
  2687.           active = 1;                   /* This FORK reads, sends keystrokes */
  2688.           if (!setjmp(env_con)) {       /* comm error in child process */
  2689.                SIGNAL(SIGUSR1, conn_int); /* routine for child process exit */
  2690.                while (active) {
  2691.                     c = coninc(0) & cmask;  /* Get character from keyboard */
  2692.                     if ((c & 0177) == escape) { /* Look for escape char */
  2693.                          c = coninc(0) & 0177;   /* Got esc, get its arg */
  2694.                          doesc(c);               /* And process it */
  2695.                     } else {                /* Ordinary character */
  2696.                          if (ttoc(dopar(c)) > -1) {
  2697.                               if (duplex) {       /* Half duplex? */
  2698.                                    conoc(c);       /* Yes, also echo it. */
  2699.                                    if (seslog)     /* And maybe log it. */
  2700. /* code folded from here */
  2701.      if (zchout(ZSFILE, c) < 0)
  2702.           seslog = 0;
  2703. /* unfolding */
  2704.                               }
  2705.                          } else {
  2706.                               errhdlr("conect: Can't send character");
  2707.                               active = 0;
  2708.                          }
  2709.                     }
  2710.                }
  2711.           }                           /* Come here on death of child */
  2712.           KILL(pid, 9);                /* Done, KILL inferior FORK. */
  2713.           WAIT((int *)0);             /* Wait till gone. */
  2714.           conres();                   /* Reset the console. */
  2715. #ifndef MCS_FLAG
  2716.           printf("\r[Back at Local System]\n");
  2717. #else
  2718.           mcs_printf("\r[Back at Local System]\n");
  2719. #endif
  2720.           return(0);
  2721.  
  2722.      } else {                        /* Inferior reads, prints port input */
  2723.  
  2724.           sleep(1);                   /* Wait for parent's handler setup */
  2725.           while (1) {                 /* Fresh read, WAIT for a character */
  2726.                if ((c = ttinc(0)) < 0) { /* Comm line hangup detected */
  2727.                     if (errno == 9999)  /* this value set by myread() */
  2728. #ifndef MCS_FLAG
  2729.                          printf("\r\nCommunications disconnect ");
  2730. #else
  2731.                          mcs_printf("\r\nCommunications disconnect ");
  2732. #endif
  2733.                     else if (io_retry++ < 3) {
  2734.                          tthang();
  2735.                          continue;
  2736.                     }
  2737.                     errhdlr("conect: Can't get character");
  2738.                     KILL(parent_id, SIGUSR1); /* notify parent. */
  2739.                     PAUSE();            /* Wait to be KILLed by parent. */
  2740.                }
  2741.                c &= cmask;             /* Got a char, strip parity, etc */
  2742.                conoc(c);               /* Put it on the screen. */
  2743.                if (seslog)
  2744.                     zchout(ZSFILE, c);   /* If logging, log it. */
  2745.                while ((n = ttchk()) > 0) {     /* Any more left in buffer? */
  2746.                     if (n > LBUFL)
  2747.                          n = LBUFL;   /* Get them all at once. */
  2748.                     if ((n = ttxin(n, lbuf)) > 0) {
  2749.                          for (i = 0; i < n; i++)
  2750.                               lbuf[i] &= cmask;  /* Strip */
  2751.                          conxo(n, lbuf);         /* Output */
  2752.                          if (seslog)
  2753.                               zsoutx(ZSFILE, lbuf,
  2754.                                    n);         /* Log */
  2755.                     }
  2756.                }
  2757.           }
  2758.      }
  2759. }
  2760.  
  2761.  
  2762. /*  H C O N N E  --  Give help message for connect.  */
  2763.  
  2764. hconne()
  2765. {
  2766.      int     c;
  2767.      static char     *hlpmsg[] = {
  2768.           "\r\n  C to close the connection, or:",
  2769.           "\r\n  0 (zero) to send a null",
  2770.           "\r\n  B to send a BREAK",
  2771.           "\r\n  H to hangup and close connection",
  2772.           "\r\n  S for status",
  2773.           "\r\n  ? for help",
  2774.           "\r\n escape character twice to send the escape character.\r\n\r\n",
  2775.                ""      };
  2776.  
  2777.      conola(hlpmsg);                     /* Print the help message. */
  2778.      conol("Command>");                  /* Prompt for command. */
  2779.      c = coninc(0) & 0177;               /* Get character, strip any parity. */
  2780.      conoc(c);                           /* Echo it. */
  2781.      conoll("");
  2782.      return(c);                          /* Return it. */
  2783. }
  2784.  
  2785.  
  2786. /*  C H S T R  --  Make a printable string out of a character  */
  2787.  
  2788. char     *
  2789. chstr(c)
  2790. int     c;
  2791. {
  2792.      static char     s[8];
  2793.      char     *cp = s;
  2794.  
  2795.      if (c < SP) {
  2796.           sprintf(cp, "CTRL-%c", ctl(c));
  2797.      } else
  2798.           sprintf(cp, "'%c'\n", c);
  2799.      cp = s;
  2800.      return(cp);
  2801. }
  2802.  
  2803.  
  2804. /*  D O E S C  --  Process an escape character argument  */
  2805.  
  2806. doesc(c)
  2807. char     c;
  2808. {
  2809.      CHAR d;
  2810.  
  2811.      while (1) {
  2812.           if (c == escape) {              /* Send escape character */
  2813.                d = dopar(c);
  2814.                ttoc(d);
  2815.                return;
  2816.           } else if /* Or else look it up below. */
  2817.           (isupper(c))
  2818.                c = tolower(c);
  2819.  
  2820.           switch (c) {
  2821.  
  2822.           case 'c':                       /* Close connection */
  2823.           case '\03':
  2824.                active = 0;
  2825.                conol("\r\n");
  2826.                return;
  2827.  
  2828.           case 'b':                       /* Send a BREAK signal */
  2829.           case '\02':
  2830.                ttsndb();
  2831.                return;
  2832.  
  2833.           case 'h':                       /* Hangup */
  2834.           case '\010':
  2835.                tthang();
  2836.                active = 0;
  2837.                conol("\r\n");
  2838.                return;
  2839.  
  2840.           case 's':                       /* Status */
  2841.                conol("\r\nConnected thru ");
  2842.                conol(ttname);
  2843.                if (speed >= 0) {
  2844.                     sprintf(temp, ", speed %d", speed);
  2845.                     conol(temp);
  2846.                }
  2847.                sprintf(temp, ", %d bits", (cmask == 0177) ?
  2848.                    7 : 8);
  2849.                if (parity) {
  2850.                     conol(", ");
  2851.                     switch (parity) {
  2852.                     case 'e':
  2853.                          conol("even");
  2854.                          break;
  2855.                     case 'o':
  2856.                          conol("odd");
  2857.                          break;
  2858.                     case 's':
  2859.                          conol("space");
  2860.                          break;
  2861.                     case 'm':
  2862.                          conol("mark");
  2863.                          break;
  2864.                     }
  2865.                     conol(" parity");
  2866.                }
  2867.                if (seslog) {
  2868.                     conol(", logging to ");
  2869.                     conol(sesfil);
  2870.                }
  2871.                conoll("");
  2872.                return;
  2873.  
  2874.           case '?':                       /* Help */
  2875.                c = hconne();
  2876.                continue;
  2877.  
  2878.           case '0':                       /* Send a null */
  2879.                c = '\0';
  2880.                d = dopar(c);
  2881.                ttoc(d);
  2882.                return;
  2883.  
  2884.           case SP:                        /* Space, ignore */
  2885.                return;
  2886.  
  2887.           default:                        /* Other */
  2888.                conoc(BEL);
  2889.                return;         /* Invalid esc arg, beep */
  2890.           }
  2891.      }
  2892. }
  2893. <<< ckvdia.c >>>
  2894. char     *dialv = "Dial Command, V2.0(010) 10 May 90";
  2895.  
  2896. /*  C K V D I A  --  Dialing program for connection to remote system */
  2897.  
  2898. /**********************************************************************
  2899. *                                                                     *
  2900. * IVS / MCS-Kermit REL 2                                              *
  2901. * source code                                                         *
  2902. *                                                                     *
  2903. * Change History:                                                     *
  2904. *                                                                     *
  2905. *                1. Modify C-Kermit(4E) source code to                *
  2906. *                   produce new module for MCS/IVS-Kermit             *
  2907. *                   ORIGINAL RELEASE                                  *
  2908. *                   June 22, 1990                                     *
  2909. *                                                                     *
  2910. *                                                                     *
  2911. ***********************************************************************/
  2912.  
  2913.  
  2914. /*
  2915.  Original author: Herm Fischer (HFISCHER@USC-ECLB).
  2916.  Contributed to Columbia University for inclusion in C-Kermit.
  2917.  Copyright (C) 1985, Herman Fischer, 16400 Ventura Blvd, Encino CA 91436.
  2918.  Permission is granted to any individual or institution to use, copy, or
  2919.  redistribute this software so long as it is not sold for profit, provided this
  2920.  copyright notice is retained.
  2921.  
  2922.  ------
  2923.  
  2924.  This module should work under all versions of NCR-VRX.  It calls externally
  2925.  defined system-depended functions for i/o, but depends upon the existence
  2926.  of various modem control functions.
  2927.  
  2928.  This module, and the supporting routines in the ckutio.c module, assume
  2929.  that the computer and modem properly utilize the following data communi-
  2930.  cations signals (that means one should prepare the modem to use, not
  2931.  circumvent, these signals):
  2932.  
  2933.      Data Terminal Ready:  This signal is asserted by the computer
  2934.      when Kermit is about to ask the modem to dial a call, and is
  2935.      removed when Kermit wishes to have the modem hang up a call.
  2936.      The signal is asserted both while Kermit is asking the modem
  2937.      to dial a specific number, and after connection, while Kermit
  2938.      is in a data exchange mode.
  2939.  
  2940.      Carrier detect:  This signal must be asserted by the modem when
  2941.      a carrier is detected from a remote modem on a communications
  2942.      circuit.  It must be removed by the modem when the circuit
  2943.      disconnects or is hung up.  (Carrier detect is ignored while
  2944.      Kermit is asking the modem to dial the call, because there is
  2945.      no consistant usage of this signal during the dialing phase
  2946.      among different modem manufacturers.)
  2947.  
  2948. */
  2949.  
  2950. /*
  2951.  * Modifications:
  2952.  *
  2953.  *      21-Jul-85       Fixed failure returns hanging on no carrier signal
  2954.  *                      Requires tthang change too (ckutio.c revision)
  2955.  *                                                      -- Herm Fischer
  2956.  *
  2957.  *      28-Jun-85       Fixed bug with defaulting the modem-failure message
  2958.  *                      in lbuf.
  2959.  *                                                      -- Dan Schullman
  2960.  *
  2961.  *      27-Jun-85       Merged in code from Joe Orost at Berkeley for
  2962.  *                      supporting the US Robotics modem, which included
  2963.  *                      changing the single characters in MDMINF into
  2964.  *                      multi-character strings and modifying waitFor.
  2965.  *                                                      -- Dan Schullman
  2966.  *
  2967.  *      26-Jun-85       Allow interrupts to be used to abort dialing,
  2968.  *                      and ring the bell when a connection is made.
  2969.  *                      Reorganized some of the failure paths to use the
  2970.  *                      same code, and now close the line on failures.
  2971.  *                      Allow use of stored numbers with the DF100 and
  2972.  *                      DF200 modems.  Handlers now declared after the
  2973.  *                      call to setjmp.
  2974.  *                                                      -- Dan Schullman
  2975.  *
  2976.  *      24-May-85       DF03, DF100-series, DF200-series, and "unknown" modem
  2977.  *                      support added.  Also restructured the various data
  2978.  *                      tables, fixed some bugs related to missing data and
  2979.  *                      missing case labels, and modified the failure message
  2980.  *                      to display the "reason" given by the modem.
  2981.  *                                                      -- Dan Schullman
  2982.  *      16-Mar-87       Support for the ATT7300 UNIX PC internal modem was
  2983.  *                      added.
  2984.  *                                                      -- Richard E. Hill
  2985.  *
  2986.  *      14-Mar-88       Rewrite code for ATT7300 (here and in ckutio.c)
  2987.  *                      Avoids dial(3c) with it's LCK files, hangs up line
  2988.  *                      correctly, enables user interrupts and timeouts,
  2989.  *                      turns on/off the system getty() login procedure.
  2990.  *                      Correct Hayes command sequence at little.
  2991.  *                      Procedures: attdial, atthang, ongetty, offgetty.
  2992.  *                      Parts adapted from work of Richard E. Hill and
  2993.  *                      Kevin O'Gorman.
  2994.  *                                                      -- Joe R. Doupnik
  2995.  *
  2996.  * 13-Jan-89 Add IBM/Siemens/Rolm CBX dialing support.  - F. da Cruz
  2997.  *
  2998.  */
  2999.  
  3000. /*
  3001.  * To add support for another modem, do the following:
  3002.  *
  3003.  *      Define a modem number symbol (n_XXX) for it, keeping the list
  3004.  *      in alphabetical and numerical order, and renumbering the values
  3005.  *      as necessary.
  3006.  *
  3007.  *      Create a MDMINF structure for it, again keeping the list alphabetical
  3008.  *      for sanity's sake.
  3009.  *
  3010.  *      Add the address of the MDMINF structure to the ptrtab array, again
  3011.  *      in alphabetical and numerical order.
  3012.  *
  3013.  *      Add the "user visible" modem name and corresponding modem number to
  3014.  *      the mdmtab array, again in alphabetical order.
  3015.  *
  3016.  *      Read through the code and add modem-specific sections as necessary.
  3017.  */
  3018.  
  3019. /*
  3020.  * The intent of the "unknown" modem is hopefully to allow KERMIT to support
  3021.  * unknown modems by having the user type the entire autodial sequence
  3022.  * (possibly including control characters, etc.) as the "phone number".
  3023.  * The only reason that the CONNECT command cannot be used to do this is
  3024.  * that a remote line cannot normally be opened unless carrier is present.
  3025.  *
  3026.  * The protocol and other characteristics of this modem are unknown, with
  3027.  * some "reasonable" values being chosen for some of them.  The only way to
  3028.  * detect if a connection is made is to look for carrier present.
  3029.  *
  3030.  * SUPPORT IS CURRENTLY ONLY PARTIALLY SKETCHED OUT FOR THIS.  ALSO, IT
  3031.  * SHOULD PERHAPS BE HANDLED MUCH EARLIER, SIMPLY READING USER INPUT AND
  3032.  * SENDING IT TO THE MODEM AND ECHOING MODEM RESPONSES BACK TO THE USER,
  3033.  * ALL THE TIME LOOKING FOR CARRIER.  OF COURSE, THE PROBLEM THEN BECOMES
  3034.  * ONE OF ALLOWING THE USER TO CANCEL THE DIALING.  WE COULD CHOOSE SOME
  3035.  * PHRASE THAT WOULD PRESUMABLY NEVER BE A PART OF A VALID AUTODIAL SEQUENCE
  3036.  * (E.G., "QUIT" and "quit"). -- DS
  3037.  */
  3038. #include "ckcdeb.h"
  3039. #include <stdio.h>
  3040. #include <ctype.h>
  3041. #include <signal.h>
  3042. #include "ckcker.h"
  3043. #include "ckucmd.h"
  3044. #include "kermisc.h"
  3045. #include <setjmp.h>                     /* Longjumps */
  3046. #ifdef MCS_FLAG
  3047. #include "mcs.h"
  3048. #endif
  3049.  
  3050. extern int     flow, local, mdmtyp, quiet, speed, parity, seslog, ttyfd;
  3051. extern char    ttname[], sesfil[], deblog;
  3052. extern void    errhdlr();
  3053.  
  3054. #define MDMINF  struct mdminf
  3055.  
  3056. MDMINF          /* structure for modem-specific information */
  3057. {
  3058.      int     dial_time;      /* time modem allows for dialing (secs) */
  3059.      char     *pause_chars;   /* character(s) to tell modem to pause */
  3060.      int     pause_time;     /* time associated with pause chars (secs) */
  3061.      char     *wake_str;      /* string to wakeup modem & put in cmd mode */
  3062.      int     wake_rate;      /* delay between wake_str characters (msecs) */
  3063.      char     *wake_prompt;   /* string prompt after wake_str */
  3064.      char     *dmode_str;     /* string to put modem in dialing mode */
  3065.      char     *dmode_prompt;  /* string prompt for dialing mode */
  3066.      char     *dial_str;      /* dialing string, with "%s" for number */
  3067.      int     dial_rate;      /* delay between dialing characters (msecs) */
  3068. };
  3069.  
  3070.  
  3071. /*
  3072.  * Define symbolic modem numbers.
  3073.  *
  3074.  * The numbers MUST correspond to the ordering of entries
  3075.  * within the ptrtab array, and start at one (1).
  3076.  *
  3077.  * It is assumed that there are relatively few of these
  3078.  * values, and that the high(er) bytes of the value may
  3079.  * be used for modem-specific mode information.
  3080.  *
  3081.  * REMEMBER that only the first eight characters of these
  3082.  * names are guaranteed to be unique.
  3083.  */
  3084.  
  3085. #define         n_CERMETEK       1
  3086. #define         n_DF03           2
  3087. #define         n_DF100          3
  3088. #define         n_DF200          4
  3089. #define         n_GDC            5
  3090. #define         n_HAYES          6
  3091. #define         n_PENRIL         7
  3092. #define         n_RACAL          8
  3093. #define         n_UNKNOWN        9
  3094. #define         n_USROBOT       10
  3095. #define         n_VENTEL        11
  3096. #define         n_CONCORD       12
  3097. #define         n_ATTUPC        13      /* aka NCR-VRX PC and ATT7300 */
  3098. #define         n_ROLM          14      /* Rolm CBX */
  3099.  
  3100. /*
  3101.  * Declare modem "variant" numbers for any of the above for which it is
  3102.  * necessary to note various operational modes, using the second byte
  3103.  * of a modem number.
  3104.  *
  3105.  * It is assumed that such modem modes share the same modem-specific
  3106.  * information (see MDMINF structure) but may differ in some of the actions
  3107.  * that are performed.
  3108.  */
  3109. #define         n_HAYESNV       ( n_HAYES + ( 1<<8 ) )
  3110.  
  3111. /*
  3112.  * Declare structures containing modem-specific information.
  3113.  *
  3114.  * REMEMBER that only the first SEVEN characters of these
  3115.  * names are guaranteed to be unique.
  3116.  */
  3117.  
  3118. static
  3119. MDMINF CERMETEK =       /* information for "Cermetek Info-Mate 212 A" modem */
  3120. {
  3121.      20,                 /* dial_time */
  3122.      "BbPpTt",           /* pause_chars */
  3123.      0,                  /* pause_time */        /** unknown -- DS **/
  3124.      "  XY\016R\r",      /* wake_str */
  3125.      200,                /* wake_rate */
  3126.      "",                 /* wake_prompt */
  3127.      "",                 /* dmode_str */
  3128.      "",                 /* dmode_prompt */
  3129.      "\016D '%s'\r",     /* dial_str */
  3130.      200                 /* dial_rate */
  3131. };
  3132.  
  3133.  
  3134. static
  3135. MDMINF DF03 =           /* information for "DEC DF03-AC" modem */
  3136. {
  3137.      27,                 /* dial_time */
  3138.      "=",                /* pause_chars */  /* wait for second dial tone */
  3139.      15,                 /* pause_time */
  3140.      "\001\002",         /* wake_str */
  3141.      0,                  /* wake_rate */
  3142.      "",                 /* wake_prompt */
  3143.      "",                 /* dmode_str */
  3144.      "",                 /* dmode_prompt */
  3145.      "%s",               /* dial_str */
  3146.      0                   /* dial_rate */
  3147. };
  3148.  
  3149.  
  3150. static
  3151. MDMINF DF100 =          /* information for "DEC DF100-series" modem */
  3152. /*
  3153.                          * The telephone "number" can include "P"s and/or "T"s
  3154.                          * within it to indicate that subsequent digits are
  3155.                          * to be dialed using pulse or tone dialing.  The
  3156.                          * modem defaults to pulse dialing.  You may modify
  3157.                          * the dial string below to explicitly default all
  3158.                          * dialing to pulse or tone, but doing so prevents
  3159.                          * the use of phone numbers that you may have stored
  3160.                          * in the modem's memory.
  3161.                          */
  3162. {
  3163.      30,                 /* dial_time */
  3164.      "=",                /* pause_chars */ /* wait for second dial tone */
  3165.      15,                 /* pause_time */
  3166.      "\001",             /* wake_str */
  3167.      0,                  /* wake_rate */
  3168.      "",                 /* wake_prompt */
  3169.      "",                 /* dmode_str */
  3170.      "",                 /* dmode_prompt */
  3171.      "%s#",              /* dial_str */
  3172.      0                   /* dial_rate */
  3173. };
  3174.  
  3175.  
  3176. static
  3177. MDMINF DF200 =          /* information for "DEC DF200-series" modem */
  3178. /*
  3179.                          * The telephone "number" can include "P"s and/or "T"s
  3180.                          * within it to indicate that subsequent digits are
  3181.                          * to be dialed using pulse or tone dialing.  The
  3182.                          * modem defaults to pulse dialing.  You may modify
  3183.                          * the dial string below to explicitly default all
  3184.                          * dialing to pulse or tone, but doing so prevents
  3185.                          * the use of phone numbers that you may have stored
  3186.                          * in the modem's memory.
  3187.                          */
  3188. {
  3189.      30,                 /* dial_time */
  3190.      "=W",               /* pause_chars */   /* =: second tone; W: 5 secs */
  3191.      15,                 /* pause_time */    /* worst case */
  3192.      "\002",             /* wake_str */      /* allow stored number usage */
  3193.      0,                  /* wake_rate */
  3194.      "",                 /* wake_prompt */
  3195.      "",                 /* dmode_str */
  3196.      "",                 /* dmode_prompt */
  3197.      "%s!",              /* dial_str */
  3198.      0                   /* dial_rate */
  3199. };
  3200.  
  3201.  
  3202. static
  3203. MDMINF GDC =            /* information for "GeneralDataComm 212A/ED" modem */
  3204. {
  3205.      32,                 /* dial_time */
  3206.      "%",                /* pause_chars */
  3207.      3,                  /* pause_time */
  3208.      "\r\r",             /* wake_str */
  3209.      500,                /* wake_rate */
  3210.      "$",                /* wake_prompt */
  3211.      "D\r",              /* dmode_str */
  3212.      ":",                /* dmode_prompt */
  3213.      "T%s\r",            /* dial_str */
  3214.      0                   /* dial_rate */
  3215. };
  3216.  
  3217.  
  3218. static
  3219. MDMINF HAYES =          /* information for "Hayes" modem */
  3220. {
  3221.      35,                 /* dial_time */
  3222.      ",",                /* pause_chars */
  3223.      2,                  /* pause_time */
  3224.      "AT\r",             /* wake_str */
  3225.      0,                  /* wake_rate */
  3226.      "",                 /* wake_prompt */
  3227.      "",                 /* dmode_str */
  3228.      "",                 /* dmode_prompt */
  3229.      "ATD%s\r",          /* dial_str, note: user can supply D or T */
  3230.      0                   /* dial_rate */
  3231. };
  3232.  
  3233.  
  3234. static
  3235. MDMINF PENRIL =         /* information for "Penril" modem */
  3236. {
  3237.      50,                 /* dial_time */
  3238.      "",                 /* pause_chars */       /** unknown -- HF **/
  3239.      0,                  /* pause_time */
  3240.      "\r\r",             /* wake_str */
  3241.      300,                /* wake_rate */
  3242.      ">",                /* wake_prompt */
  3243.      "k\r",              /* dmode_str */
  3244.      ":",                /* dmode_prompt */
  3245.      "%s\r",             /* dial_str */
  3246.      0                   /* dial_rate */
  3247. };
  3248.  
  3249.  
  3250. static
  3251. MDMINF RACAL =          /* information for "Racal Vadic" modem */
  3252. {
  3253.      35,                 /* dial_time */
  3254.      "Kk",               /* pause_chars */
  3255.      5,                  /* pause_time */
  3256.      "\005\r",           /* wake_str */
  3257.      50,                 /* wake_rate */
  3258.      "*",                /* wake_prompt */
  3259.      "D\r",              /* dmode_str */
  3260.      "?",                /* dmode_prompt */
  3261.      "%s\r",             /* dial_str */
  3262.      0                   /* dial_rate */
  3263. };
  3264.  
  3265.  
  3266. static
  3267. MDMINF UNKNOWN =        /* information for "Unknown" modem */
  3268. {
  3269.      30,                 /* dial_time */
  3270.      "",                 /* pause_chars */
  3271.      0,                  /* pause_time */
  3272.      "",                 /* wake_str */
  3273.      0,                  /* wake_rate */
  3274.      "",                 /* wake_prompt */
  3275.      "",                 /* dmode_str */
  3276.      "",                 /* dmode_prompt */
  3277.      "%s\r",             /* dial_str */
  3278.      0                   /* dial_rate */
  3279. };
  3280.  
  3281.  
  3282. static
  3283. MDMINF USROBOT =        /* information for "US Robotics 212A" modem */
  3284. {
  3285.      30,                 /* dial_time */
  3286.      ",",                /* pause_chars */
  3287.      2,                  /* pause_time */
  3288.      "ATS2=01\r",        /* wake_str */
  3289.      0,                  /* wake_rate */
  3290.      "OK\r",             /* wake_prompt */
  3291.      "",                 /* dmode_str */
  3292.      "",                 /* dmode_prompt */
  3293.      "ATTD%s\r",         /* dial_str */
  3294.      0                   /* dial_rate */
  3295. };
  3296.  
  3297.  
  3298. static
  3299. MDMINF VENTEL =         /* information for "Ventel" modem */
  3300. {
  3301.      20,                 /* dial_time */
  3302.      "%",                /* pause_chars */
  3303.      5,                  /* pause_time */
  3304.      "\r\r\r",           /* wake_str */
  3305.      300,                /* wake_rate */
  3306.      "$",                /* wake_prompt */
  3307.      "",                 /* dmode_str */
  3308.      "",                 /* dmode_prompt */
  3309.      "<K%s\r>",          /* dial_str */
  3310.      0                   /* dial_rate */
  3311. };
  3312.  
  3313.  
  3314. static
  3315. MDMINF CONCORD =        /* Info for Condor CDS 220 2400b modem */
  3316. {
  3317.      35,                 /* dial_time */
  3318.      ",",                /* pause_chars */
  3319.      2,                  /* pause_time */
  3320.      "\r\r",             /* wake_str */
  3321.      20,                 /* wake_rate */
  3322.      "CDS >",            /* wake_prompt */
  3323.      "",                 /* dmode_str */
  3324.      "",                 /* dmode_prompt */
  3325.      "<D M%s\r>",        /* dial_str */
  3326.      0                   /* dial_rate */
  3327. };
  3328.  
  3329.  
  3330. static
  3331. MDMINF ATTUPC = /* dummy information for "ATT7300/NCR-VRX PC" internal modem */
  3332. {
  3333.      20,                 /* dial_time */
  3334.      "",                 /* pause_chars */
  3335.      0,                  /* pause_time */
  3336.      "",                 /* wake_str */
  3337.      0,                  /* wake_rate */
  3338.      "",                 /* wake_prompt */
  3339.      "",                 /* dmode_str */
  3340.      "",                 /* dmode_prompt */
  3341.      "%s\r",             /* dial_str */
  3342.      0                   /* dial_rate */
  3343. };
  3344.  
  3345.  
  3346. static
  3347. MDMINF ROLM =           /* IBM (Siemens) / Rolm CBX */
  3348. {
  3349.      60,                 /* dial_time */
  3350.      "",                 /* pause_chars */
  3351.      0,                  /* pause_time */
  3352.      "\r\r",             /* wake_str */
  3353.      5,                  /* wake_rate */
  3354.      "MODIFY?",          /* wake_prompt */
  3355.      "",                 /* dmode_str */
  3356.      "",                 /* dmode_prompt */
  3357.      "CALL %s\r",        /* dial_str */
  3358.      0                   /* dial_rate */
  3359. };
  3360.  
  3361.  
  3362. /*
  3363.  * Declare table for converting modem numbers to information pointers.
  3364.  *
  3365.  * The entries MUST be in ascending order by modem number, without any
  3366.  * "gaps" in the numbers, and starting from one (1).
  3367.  *
  3368.  * This table should NOT include entries for the "variant" modem numbers,
  3369.  * since it is assumed that they share the same information as the normal
  3370.  * value.
  3371.  */
  3372. static
  3373. MDMINF *ptrtab[] =
  3374. {
  3375.      &CERMETEK, &DF03, &DF100, &DF200, &GDC, &HAYES, &PENRIL, &RACAL,
  3376.      &UNKNOWN, &USROBOT, &VENTEL, &CONCORD,
  3377.      &ATTUPC, /* ATT7300 internal modem, jrd*/
  3378.      &ROLM    /* Rolm CBX, fdc */
  3379. };
  3380.  
  3381.  
  3382. /*
  3383.  * Declare modem names and associated numbers for command parsing,
  3384.  * and also for doing number-to-name translation.
  3385.  *
  3386.  * The entries MUST be in alphabetical order by modem name.
  3387.  */
  3388. struct keytab mdmtab[] =
  3389. {
  3390.      "att7300",          n_ATTUPC,       0,
  3391.      "cermetek",         n_CERMETEK,     0,
  3392.      "concord",          n_CONCORD,      0,
  3393.      "df03-ac",          n_DF03,         0,
  3394.      "df100-series",     n_DF100,        0,
  3395.      "df200-series",     n_DF200,        0,
  3396.      "direct",           0,              0,
  3397.      "gendatacomm",      n_GDC,          0,
  3398.      "hayes",            n_HAYES,        0,
  3399.      "penril",           n_PENRIL,       0,
  3400.      "racalvadic",       n_RACAL,        0,
  3401.      "rolm",             n_ROLM,         0,
  3402.      "unknown",          n_UNKNOWN,      0,
  3403.      "usrobotics-212a",  n_USROBOT,      0,
  3404.      "ventel",           n_VENTEL,       0
  3405. };
  3406.  
  3407.  
  3408. int     nmdm = (sizeof(mdmtab)
  3409.  / sizeof(struct keytab )
  3410. );    /* number of modems */
  3411.  
  3412. #define DIALING 4               /* for ttpkt parameter */
  3413. #define CONNECT 5
  3414.  
  3415. #define CONNECTED 1             /* for completion status */
  3416. #define FAILED    2
  3417.  
  3418. /*
  3419.  * Failure reasons for use with the 'longjmp' exit.
  3420.  */
  3421. #define F_time          1       /* timeout */
  3422. #define F_int           2       /* interrupt */
  3423. #define F_modem         3       /* modem-detected failure */
  3424. #define F_minit         4       /* cannot initialize modem */
  3425.  
  3426. static
  3427. char     *F_reason[5] = {           /* failure reasons for message */
  3428.      "Unknown",  "Timeout", "Interrupt", "Modem", "Initialize" };
  3429.  
  3430.  
  3431. static int     tries = 0;
  3432.  
  3433. #define LBUFL 100
  3434. static char     lbuf[LBUFL];
  3435.  
  3436. static jmp_buf sjbuf;
  3437.  
  3438. static SIGTYP (*savAlrm)();     /* for saving alarm handler */
  3439. static SIGTYP (*savInt)();      /* for saving interrupt handler */
  3440.  
  3441. dialtime()
  3442. {                    /* timer interrupt handler */
  3443.      longjmp( sjbuf, F_time );
  3444. }
  3445.  
  3446.  
  3447. dialint()                       /* user-interrupt handler */
  3448. {
  3449.      longjmp( sjbuf, F_int );
  3450. }
  3451.  
  3452.  
  3453. static
  3454. ttolSlow(s, millisec)
  3455. char     *s;
  3456. int     millisec;
  3457. {  /* output s-l-o-w-l-y */
  3458.      for (; *s; s++) {
  3459.           ttoc(*s);
  3460.           msleep(millisec);
  3461.      }
  3462. }
  3463.  
  3464.  
  3465. /*
  3466.  * Wait for a string of characters.
  3467.  *
  3468.  * The characters are waited for individually, and other characters may
  3469.  * be received "in between".  This merely guarantees that the characters
  3470.  * ARE received, and in the order specified.
  3471.  */
  3472. static
  3473. waitFor(s)
  3474. char     *s;
  3475. {
  3476.      CHAR c;
  3477.      while ( c = *s++)                  /* while more characters remain... */
  3478.           while ( ( ttinc(0) & 0177 ) != c )
  3479.                ;    /* wait for the character */
  3480. }
  3481.  
  3482.  
  3483. static
  3484. didWeGet(s, r)
  3485. char     *s, *r;
  3486. {    /* Looks in string s for response r */
  3487.      int     lr = strlen(r);         /*  0 means not found, 1 means found it */
  3488.      int     i;
  3489.      if (deblog)
  3490.           debug(F110, "didWeGet", r, 0);
  3491.      if (deblog)
  3492.           debug(F110, " in", s, 0);
  3493.      for (i = strlen(s) - lr; i >= 0; i--)
  3494.           if ( s[i] == r[0] )
  3495.                if ( !strncmp(s + i, r, lr) )
  3496.                     return( 1 );
  3497.      return( 0 );
  3498. }
  3499.  
  3500.  
  3501. /* R E S E T -- Reset alarms, etc. on exit. */
  3502.  
  3503. static
  3504. reset ()
  3505. {
  3506.      ALARM(0);
  3507.      SIGNAL(SIGALRM, savAlrm);            /* restore alarm handler */
  3508.      SIGNAL(SIGINT, savInt);              /* restore interrupt handler */
  3509. }
  3510.  
  3511.  
  3512. /*  C K D I A L  --  Dial up the remote system */
  3513.  
  3514. ckdial(telnbr)
  3515. char     *telnbr;
  3516. {
  3517.  
  3518.      char     c;
  3519.      char     *i, *j;
  3520.      int     waitct, status;
  3521.      char     errmsg[50], *erp;
  3522.      MDMINF * pmdminf;    /* pointer to modem-specific info */
  3523.      int     augmdmtyp;   /* "augmented" modem type, to handle modem modes */
  3524.      int     mdmEcho = 0; /* assume modem does not echo */
  3525.      int     n, n1;
  3526.      char     *pc;           /* pointer to a character */
  3527.  
  3528.      if (!mdmtyp) {
  3529. #ifndef MCS_FLAG
  3530.           printf("Sorry, you must 'set modem' first\n");
  3531. #else
  3532.           mcs_printf("Sorry, you must 'set modem' first\n");
  3533. #endif
  3534.           return(-2);
  3535.      }
  3536.      if (!local) {
  3537. #ifndef MCS_FLAG
  3538.           printf("Sorry, you must 'set line' first\n");
  3539. #else
  3540.           mcs_printf("Sorry, you must 'set line' first\n");
  3541. #endif
  3542.           return(-2);
  3543.      }
  3544.      if (speed < 0) {
  3545. #ifndef MCS_FLAG
  3546.           printf("Sorry, you must 'set speed' first\n");
  3547. #else
  3548.           mcs_printf("Sorry, you must 'set speed' first\n");
  3549. #endif
  3550.           return(-2);
  3551.      }
  3552.      if (deblog)
  3553.           debug(F110, "dial", telnbr, 0);
  3554.  
  3555.      /* Carrier no-wait can be invalidated by ckutio fun and games, jrd */
  3556.      if (ttopen(ttname, &local, mdmtyp) < 0) { /* Open, no carrier wait */
  3557.           erp = errmsg;
  3558.           sprintf(erp, "ckdail: Can't open %s", ttname);
  3559.           perror(errmsg);
  3560.           return(-2);
  3561.      }
  3562.      pmdminf = ptrtab[mdmtyp-1];     /* set pointer to modem info */
  3563.      augmdmtyp = mdmtyp;             /* initialize "augmented" modem type */
  3564.  
  3565.      /* cont'd... */
  3566.  
  3567.      /* interdigit waits for tone dial */
  3568.      /* ...dial, cont'd */
  3569.  
  3570.  
  3571.      waitct = 1 * strlen(telnbr) ;     /* compute time to dial worst case */
  3572.      waitct += pmdminf->dial_time;   /* dialtone + completion wait times */
  3573.      for (i = telnbr; *i; i++)         /* add in pause characters time */
  3574.           for (j = pmdminf->pause_chars; *j; j++)
  3575.                if (*i == *j) {
  3576.                     waitct += pmdminf->pause_time;
  3577.                     break;
  3578.                }
  3579.  
  3580. #ifndef MCS_FLAG
  3581.      printf("Dialing thru %s, speed %d, number %s.\r\n", ttname,
  3582.          speed, telnbr);
  3583.      printf("The timeout for completing the call is %d seconds.\r\n",
  3584.           waitct);
  3585.      printf("Type the interrupt character (^C) to cancel the dialing.\r\n");
  3586. #else
  3587.      sprintf(print_str,"Dialing thru %s, speed %d, number %s.\r\n", ttname,
  3588.          speed, telnbr);
  3589.      mcs_printf(print_str);
  3590.      mcs_printf("The timeout for completing the call is %d seconds.\r\n",
  3591.           waitct);
  3592.      mcs_printf(
  3593.         "Type the interrupt character (^C) to cancel the dialing.\r\n");
  3594. #endif
  3595.      if (deblog)
  3596.           debug(F101, ttname, "", speed);
  3597.      if (deblog)
  3598.           debug(F101, "timeout", "", waitct);
  3599.  
  3600.      /* Hang up the modem (in case it wasn't "on hook") */
  3601.  
  3602.      if ( tthang() < 0 ) {
  3603. #ifndef MCS_FLAG
  3604.           printf("Sorry, Can't hang up tty line\n");
  3605. #else
  3606.           mcs_printf("Sorry, Can't hang up tty line\n");
  3607. #endif
  3608.           return(-2);
  3609.      }
  3610.  
  3611.      /* Condition console terminal and communication line */
  3612.      /* place line into "clocal" dialing state */
  3613.      if ( ttpkt(speed, DIALING, parity) < 0 )  {
  3614. #ifndef MCS_FLAG
  3615.           printf("Sorry, Can't condition communication line\n");
  3616. #else
  3617.           mcs_printf("Sorry, Can't condition communication line\n");
  3618. #endif
  3619.           return(-2);
  3620.      }
  3621.  
  3622.      /*
  3623.  * Establish jump vector, or handle "failure" jumps.
  3624.  */
  3625.  
  3626.      if ( n = setjmp(sjbuf) )         /* if a "failure jump" was taken... */ {
  3627.           ALARM ( 0 );                /* disable timeouts */
  3628.  
  3629.           if ( n1 = setjmp(sjbuf) )   /* failure while handling failure */ {
  3630. #ifndef MCS_FLAG
  3631.                printf ( "%s failure while handling failure.\r\n",
  3632.                     F_reason[n1] );
  3633. #else
  3634.                mcs_printf ( "%s failure while handling failure.\r\n",
  3635.                     F_reason[n1] );
  3636. #endif
  3637.           } else /* first (i.e., non-nested) failure */            {
  3638.                SIGNAL ( SIGALRM, dialtime );   /* be sure to catch signals */
  3639.                if ( SIGNAL ( SIGINT, SIG_IGN ) != SIG_IGN )
  3640.                     SIGNAL ( SIGINT, dialint );
  3641.                ALARM ( 10 );               /* be sure to exit this section */
  3642.                ttclos ();                  /* hangup and close the line */
  3643.           }
  3644.           switch ( n )                /* type of failure */ {
  3645.           case F_time:                /* timed out */
  3646.                 {
  3647. #ifndef MCS_FLAG
  3648.                     printf("No connection made in the allotted time.\r\n");
  3649. #else
  3650.                     mcs_printf("No connection made in the allotted time.\r\n");
  3651. #endif
  3652.                     if (deblog)
  3653.                          debug(F110, "dial", "timeout",
  3654.                               0);
  3655.                     break;
  3656.                }
  3657.           case F_int:                 /* dialing interrupted */
  3658.                 {
  3659. #ifndef MCS_FLAG
  3660.                     printf ( "Dialing interrupted.\r\n" );
  3661. #else
  3662.                     mcs_printf ( "Dialing interrupted.\r\n" );
  3663. #endif
  3664.                     if (deblog)
  3665.                          debug(F110, "dial", "interrupted",
  3666.                               0);
  3667.                     break;
  3668.                }
  3669.           case F_modem:               /* modem detected a failure */
  3670.                 {
  3671. #ifndef MCS_FLAG
  3672.                     printf ( "Failed (\"" );
  3673. #else
  3674.                     mcs_printf ( "Failed (\"" );
  3675. #endif
  3676.                     for ( pc = lbuf; *pc; pc++)
  3677.                          if ( isprint(*pc) )
  3678.                               putchar(*pc);   /* display printable reason */
  3679. #ifndef MCS_FLAG
  3680.                     printf ( "\").\r\n" );
  3681. #else
  3682.                     mcs_printf ( "\").\r\n" );
  3683. #endif
  3684.                     if (deblog)
  3685.                          debug(F110, "dial", lbuf, 0);
  3686.                     break;
  3687.                }
  3688.           case F_minit:               /* cannot initialize modem */
  3689.                 {
  3690. #ifndef MCS_FLAG
  3691.                     printf ( "Cannot initialize modem.\r\n" );
  3692. #else
  3693.                     mcs_printf ( "Cannot initialize modem.\r\n" );
  3694. #endif
  3695.                     if (deblog)
  3696.                          debug(F110, "dial", "modem init",
  3697.                               0);
  3698.                     break;
  3699.                }
  3700.           }
  3701.           reset();                        /* reset alarms, etc. */
  3702.           return ( -2 );                  /* exit with failure code */
  3703.      }
  3704.  
  3705.      /*
  3706.  * Set timer and interrupt handlers.
  3707.  */
  3708.      ttflui();                   /* flush input buffer if any */
  3709.  
  3710.      savAlrm = SIGNAL(SIGALRM, dialtime); /* set alarm handler */
  3711.      if ( ( savInt = SIGNAL ( SIGINT, SIG_IGN ) ) != SIG_IGN )
  3712.           SIGNAL ( SIGINT, dialint );     /* set int handler if not ignored */
  3713.      ALARM(10);                  /* give modem 10 seconds to wake up */
  3714.  
  3715.      /*
  3716.  * Put modem in command mode.
  3717.  */
  3718.  
  3719. #define OKAY 1                  /* modem attention attempt status */
  3720. #define IGNORE 2
  3721. #define GOT_O -2
  3722. #define GOT_A -3
  3723.  
  3724.      switch (augmdmtyp) {
  3725.  
  3726.      case n_HAYES:
  3727.      case n_HAYESNV:
  3728.           while (tries++ < 4) {
  3729.                ttol( HAYES.wake_str, strlen(HAYES.wake_str) );     /* wakeup */
  3730.                status = 0;
  3731.                while ( status <= 0 ) {
  3732.                     switch (ttinc(0) & 0177) {
  3733.                     case 'A':                   /* echoing, ignore */
  3734.                          status = GOT_A;
  3735.                          break;
  3736.                     case 'T':
  3737.                          if (status == GOT_A) {
  3738.                               mdmEcho = 1;        /* expect echoing later */
  3739.                               status = 0;
  3740.                               break;
  3741.                          }
  3742.                          status = IGNORE;
  3743.                          break;
  3744.                     case '\n':
  3745.                     case '\r':
  3746.                          status = 0;
  3747.                          break;
  3748.                     case '0':                   /* numeric result code */
  3749.                          augmdmtyp = n_HAYESNV;  /* nonverbal result codes */
  3750.                          status = OKAY;
  3751.                          break;
  3752.                     case 'O':                   /* maybe English result code*/
  3753.                          status = GOT_O;
  3754.                          break;
  3755.                     case 'K':
  3756.                          if (status == GOT_O) {
  3757.                               augmdmtyp = n_HAYES;
  3758.                               status = OKAY;
  3759.                               break;
  3760.                          }                       /* else its default anyway */
  3761.                     default:
  3762.                          status = IGNORE;
  3763.                          break;
  3764.                     }
  3765.                }
  3766.                if (status == OKAY)
  3767.                     break;
  3768.                if (status == IGNORE)
  3769.                     ttflui();
  3770.                sleep(1);           /* wait before retrying */
  3771.           }
  3772.           if (status != 0)
  3773.                break;
  3774.           longjmp( sjbuf, F_minit );      /* modem-initialization failure */
  3775.  
  3776.           /* cont'd... */
  3777.  
  3778.           /* interdigit waits for tone dial */
  3779.           /* ...dial, cont'd */
  3780.  
  3781.      default:                    /* place modem into command mode */
  3782.           ttolSlow(pmdminf->wake_str, pmdminf->wake_rate);
  3783.           waitFor(pmdminf->wake_prompt);
  3784.           break;
  3785.      }
  3786.      ALARM(0);                   /* turn off alarm */
  3787.      msleep(500);                /* give things settling time */
  3788.      ALARM(10);                  /* alarm on dialing prompts */
  3789.  
  3790.  
  3791.      /* Dial the number */
  3792.      /* put modem into dialing mode */
  3793.      ttolSlow(pmdminf->dmode_str, pmdminf->dial_rate);
  3794.      if (pmdminf->dmode_prompt) {        /* wait for prompt, if any expected */
  3795.           waitFor(pmdminf->dmode_prompt);
  3796.           msleep(300);
  3797.      }
  3798.  
  3799.      ALARM(0);                   /* turn off alarm on dialing prompts */
  3800.      ALARM(waitct);              /* time to allow for connecting */
  3801.      ttflui();                   /* clear out stuff from waking modem up */
  3802.      sprintf(lbuf, pmdminf->dial_str, telnbr); /* form dialing string */
  3803.      if (deblog)
  3804.           debug(F110, "dialing", lbuf);
  3805.      ttolSlow(lbuf, pmdminf->dial_rate);  /* send dialing string */
  3806.  
  3807.      if (augmdmtyp == n_RACAL) { /* acknowledge printout of dialing string */
  3808.           sleep(3);
  3809.           ttflui();
  3810.           ttoc('\r');
  3811.      }
  3812.  
  3813.      /* cont'd... */
  3814.  
  3815.      /* interdigit waits for tone dial */
  3816.      /* ...dial, cont'd */
  3817.  
  3818.  
  3819.      /* Check for connection */
  3820.  
  3821.      /*
  3822.  * I believe we also need to look for carrier in order to determine if a
  3823.  * connection has been made.  In fact, for many we may only want to look for
  3824.  * the "failure" responses in order to short-circuit the timeout, and let
  3825.  * carrier be the determination of whether a connection has been made. -- DS
  3826.  */
  3827.  
  3828.      status = 0;
  3829.      strcpy(lbuf, "No Connection");       /* default failure reason */
  3830.      while (status == 0) {
  3831.           switch (augmdmtyp) {
  3832.           default:
  3833.                for (n = 0; n < LBUFL; n++) { /* accumulate response */
  3834.                     lbuf[n] = (ttinc(0) & 0177);
  3835.                     if ( lbuf[n] == '\r' || lbuf[n] == '\n' )
  3836.                          break;
  3837.                }
  3838.                lbuf[n] = '\0';             /* terminate response from modem */
  3839.                if (deblog)
  3840.                     debug(F110, "dial modem response", lbuf,
  3841.                          0);
  3842.                if (n) {          /* if one or more characters present */
  3843.                     switch (augmdmtyp) {
  3844.                     case n_CERMETEK:
  3845.                          if (didWeGet(lbuf, "\016A")) {
  3846.                               status = CONNECTED;
  3847.                               ttolSlow("\016U 1\r",
  3848.                                    200);      /* make transparent*/
  3849.                          }
  3850.                          break;
  3851.                     case n_DF100:      /* DF100 won't generate some of these */
  3852.                     case n_DF200:
  3853.                          if (didWeGet(lbuf, "Attached"))
  3854.                               status = CONNECTED;
  3855.                          /*
  3856.                      * The DF100 will respond with "Attached" even if DTR
  3857.                      * and/or carrier are not present.  Another reason to
  3858.                      * (also) wait for carrier?
  3859.                      */
  3860.                          if (didWeGet(lbuf, "Busy"))
  3861.                               status = FAILED;
  3862.                          if (didWeGet(lbuf, "Disconnected"))
  3863.                               status = FAILED;
  3864.                          if (didWeGet(lbuf, "Error"))
  3865.                               status = FAILED;
  3866.                          if (didWeGet(lbuf, "No answer"))
  3867.                               status = FAILED;
  3868.                          if (didWeGet(lbuf, "No dial tone"))
  3869.                               status = FAILED;
  3870.                          if (didWeGet(lbuf, "Speed:"))
  3871.                               status = FAILED;
  3872.                          /*
  3873.                      * It appears that the "Speed:..." response comes after an
  3874.                      * "Attached" response, so this is never seen.  HOWEVER,
  3875.                      * it would be very handy to detect this and temporarily
  3876.                      * reset the speed, since it's a nuiscance otherwise.
  3877.                      * If we wait for some more input from the modem, how do
  3878.                      * we know if it's from the remote host or the modem?
  3879.                      * Carrier reportedly doesn't get set until after the
  3880.                      * "Speed:..." response (if any) is sent.  Another reason
  3881.                      * to (also) wait for carrier.
  3882.                      */
  3883.                          break;
  3884.                     case n_GDC:
  3885.                          if (didWeGet(lbuf, "ON LINE"))
  3886.                               status = CONNECTED;
  3887.                          if (didWeGet(lbuf, "NO CONNECT"))
  3888.                               status = FAILED;
  3889.                          break;
  3890.                     case n_HAYES:
  3891.                     case n_USROBOT:
  3892.                          if (didWeGet(lbuf, "CONNECT"))
  3893.                               status = CONNECTED;
  3894.                          if (didWeGet(lbuf, "NO CARRIER"))
  3895.                               status = FAILED;
  3896.                          break;
  3897.                     case n_PENRIL:
  3898.                          if (didWeGet(lbuf, "OK"))
  3899.                               status = CONNECTED;
  3900.                          if (didWeGet(lbuf, "BUSY"))
  3901.                               status = FAILED;
  3902.                          if (didWeGet(lbuf, "NO RING"))
  3903.                               status = FAILED;
  3904.                          break;
  3905.                     case n_RACAL:
  3906.                          if (didWeGet(lbuf, "ON LINE"))
  3907.                               status = CONNECTED;
  3908.                          if (didWeGet(lbuf, "FAILED CALL"))
  3909.                               status = FAILED;
  3910.                          break;
  3911.                     case n_ROLM:
  3912.                          if (didWeGet(lbuf, "CALLING"))
  3913.                               status = 0;
  3914.                          if (didWeGet(lbuf, "COMPLETE"))
  3915.                               status = CONNECTED;
  3916.                          if (didWeGet(lbuf, "FAILED"))
  3917.                               status = FAILED;
  3918.                          if (didWeGet(lbuf, "NOT AVAILABLE"))
  3919.                               status = FAILED;
  3920.                          if (didWeGet(lbuf, "LACKS PERMISSION"))
  3921.                               status = FAILED;
  3922.                          /*
  3923.                       The Rolm CBX does not give a CALL COMPLETE indication
  3924.                       when dialing an outpool number, but it does seem to
  3925.                       return a long string of DELs at that point.
  3926.                     */
  3927.                          if (didWeGet(lbuf, "\177\177\177"))
  3928.                               status = CONNECTED;
  3929.                          break;
  3930.                     case n_VENTEL:
  3931.                          if (didWeGet(lbuf, "ONLINE!"))
  3932.                               status = CONNECTED;
  3933.                          if (didWeGet(lbuf, "BUSY"))
  3934.                               status = FAILED;
  3935.                          if (didWeGet(lbuf, "DEAD PHONE"))
  3936.                               status = FAILED;
  3937.                          break;
  3938.                     case n_CONCORD:
  3939.                          if (didWeGet(lbuf, "INITIATING"))
  3940.                               status = CONNECTED;
  3941.                          if (didWeGet(lbuf, "BUSY"))
  3942.                               status = FAILED;
  3943.                          if (didWeGet(lbuf, "CALL FAILED"))
  3944.                               status = FAILED;
  3945.                          break;
  3946.                     }
  3947.                }
  3948.                break;
  3949.  
  3950.           case n_DF03:                    /* because response lacks CR or NL */
  3951.                c = ttinc(0) & 0177;
  3952.                if ( c == 'A' )
  3953.                     status = CONNECTED;
  3954.                if ( c == 'B' )
  3955.                     status = FAILED;
  3956.                break;
  3957.  
  3958.           case n_HAYESNV:
  3959.                c = ttinc(0) & 0177;
  3960.                if (mdmEcho) {              /* sponge up dialing string */
  3961.                     mdmEcho = c != '\r';      /* until return is echoed */
  3962.                     break;
  3963.                }
  3964.                if (c == '1')
  3965.                     status = CONNECTED;
  3966.                if (c == '3')
  3967.                     status = FAILED;
  3968.                if (c == '5')
  3969.                     status = CONNECTED;
  3970.                break;
  3971.  
  3972.           case n_UNKNOWN:
  3973.                /** SHOULD WAIT FOR CARRIER OR TIMEOUT -- DS **/
  3974.                break;
  3975.           }                               /* switch (augmdmtyp) */
  3976.      }                                   /* while status == 0 */
  3977.      ALARM(0);                           /* turn off alarm on connecting */
  3978.      if ( status != CONNECTED )          /* modem-detected failure */
  3979.           longjmp( sjbuf, F_modem );      /* exit (with reason in lbuf) */
  3980.      msleep(500);                        /* allow some time...  */
  3981.      ALARM(3);                           /* precaution in case of trouble */
  3982.      if (deblog)
  3983.           debug(F110, "dial", "succeeded", 0);
  3984.      if (augmdmtyp != n_ROLM)            /* Rolm has wierd modem signaling */
  3985.           ttpkt(speed, CONNECT, parity);      /* cancel dialing state ioctl */
  3986.      reset ();                           /* reset alarms, etc. */
  3987.      if ( !quiet )
  3988. #ifndef MCS_FLAG
  3989.           printf ( "Call completed.\07\r\n" );
  3990. #else
  3991.           mcs_printf ( "Call completed.\07\r\n" );
  3992. #endif
  3993.      return ( 0 );                       /* return, and presumably connect */
  3994. }
  3995. <<< ckvfi2.c >>>
  3996. char     *ckzv = "VRX/VE file support, 4E(038) 30 May 90";
  3997.  
  3998. /* C K U F I 2  --  Kermit file system support for VRX/VE systems */
  3999.  
  4000. /**********************************************************************
  4001. *                                                                     *
  4002. * IVS / MCS-Kermit REL 2                                              *
  4003. * source code                                                         *
  4004. *                                                                     *
  4005. * Change History:                                                     *
  4006. *                                                                     *
  4007. *                1. Modify C-Kermit(4E) source code to                *
  4008. *                   produce new module for MCS/IVS-Kermit             *
  4009. *                   ORIGINAL RELEASE                                  *
  4010. *                   June 22, 1990                                     *
  4011. *                                                                     *
  4012. *                                                                     *
  4013. ***********************************************************************/
  4014.  
  4015.  
  4016. /*
  4017.  Author: Frank da Cruz (SY.FDC@CU20B),
  4018.  Columbia University Center for Computing Activities, January 1985.
  4019.  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
  4020.  Permission is granted to any individual or institution to use, copy, or
  4021.  redistribute this software so long as it is not sold for profit, provided this
  4022.  copyright notice is retained.
  4023. */
  4024.  
  4025. /* ******************************************************************
  4026.          DO NOT COMPILE THIS MODULE WITH
  4027.          #include <mcs.h>
  4028.          THIS INCLUDE CAUSES A PERFORMANCE DEGRADATION
  4029.          PEG  May 04, 1990
  4030. ********************************************************************* */
  4031.  
  4032. /*
  4033. *********************************************************************
  4034.  
  4035.      May 9, 1990
  4036.  
  4037.      The following features were removed from the user
  4038.      display and disabled from use.
  4039.  
  4040.      add-linenum id-fields line-numbers renumber
  4041.  
  4042.      May 21, 1990
  4043.  
  4044.      We added reset logic for errno == EMINR. This
  4045.      (?)error appends spaces characters to line
  4046.      end. Earlier releases we treated this as
  4047.      corruption. This release (V-KERMIT 2.01)
  4048.      we are treating it as normal for the VRX / VE
  4049.      file systems. I did not test for errno (EMINR)
  4050.      directly, I reset it when say an fputs terminates
  4051.      normally, and errno != EMINR.
  4052.  
  4053. *********************************************************************/
  4054.  
  4055. /* Includes */
  4056. #include "ckcker.h"   /* Kermit definitions */
  4057. #include "ckcdeb.h"   /* Typedefs, debug formats, etc */
  4058. #include "vrx.h"      /* VRX SPUR File definitions */
  4059. #include <ctype.h>    /* Character types */
  4060. #include <stdio.h>    /* Standard i/o */
  4061. #include <string.h>   /* String routines */
  4062. #include <errno.h>
  4063. #include <time.h>
  4064.  
  4065. char     *ckzsys = " NCR VRX/VE";
  4066.  
  4067. /*
  4068.   Functions (n is one of the predefined file numbers from ckermi.h):
  4069.  
  4070.    zopeni(n,name)   -- Opens an existing file for input.
  4071.    zopeno(n,name)   -- Opens a new file for output.
  4072.    zclose(n)        -- Closes a file.
  4073.    zchin(n,&c)      -- Gets the next character from an input file.
  4074.    zsout(n,s)       -- Write a null-terminated string to output file, buffered.
  4075.    zsoutl(n,s)      -- Like zsout, but appends a line terminator.
  4076.    zsoutx(n,s,x)    -- Write x characters to output file, unbuffered.
  4077.    zchout(n,c)      -- Add a character to an output file, unbuffered.
  4078.    zchki(name)      -- Check if named file exists and is readable, return size.
  4079.    zchko(name)      -- Check if named file can be created.
  4080.    znewn(name,s)    -- Make a new unique file name based on the given name.
  4081.    zdelet(name)     -- Delete the named file.
  4082.    zxpand(string)   -- Expands the given wildcard string into a list of files.
  4083.    znext(string)    -- Returns the next file from the list in "string".
  4084.    zxcmd(cmd)       -- Execute the command in a lower fork.
  4085.    zclosf()         -- Close input file associated with zxcmd()'s lower fork.
  4086.    zrtol(n1,n2)     -- Convert remote filename into local form.
  4087.    zltor(n1,n2)     -- Convert local filename into remote form.
  4088.    zchdir(dirnam)   -- Change working directory.
  4089.    zhome()          -- Return pointer to home directory name string.
  4090.    zkself()         -- Kill self, log out own job.
  4091.  */
  4092.  
  4093. /* Some systems define these symbols in include files, others don't... */
  4094.  
  4095. #ifndef MAXNAMLEN
  4096. #define MAXNAMLEN 14              /* If still not defined... */
  4097. #endif
  4098.  
  4099. #define MAXWLD 500
  4100.  
  4101. #define SRCLNLEN 82     /* source or control string max
  4102.                            line length March 8, 1990      */
  4103.  
  4104. #define OPEN 1          /* resetopen processing           */
  4105. #define CLOSE 0
  4106.  
  4107. /* Declarations */
  4108.  
  4109. extern long    time();
  4110. extern int     debug();
  4111. extern int     fncnv, send_id, recv_id, send_num, recv_num, recv_renum,
  4112.                keep;
  4113. extern int     server, recv_addnum, send_addnum, send_renum, deblog, binary;
  4114. extern char    *sys_errlist[];
  4115. extern int     sys_nerr;
  4116. extern void    perror();
  4117. /*  ^   extern int errno already declared in errno.h.
  4118.     |   why they didnot declare these three are anyone's
  4119.     |   guess.  March 7, 1990                           */
  4120.  
  4121. /* forward declarations */
  4122. void    errhdlr(), resetopen();
  4123. int     lenchk();
  4124.  
  4125. FILE *fp[ZNFILS] = { /* File pointers */
  4126.      NULL, NULL, NULL, NULL, NULL, NULL, NULL };
  4127.  
  4128.  
  4129. static int     list_count;               /* # matches file names == 1 */
  4130. static int     pid = 0;                  /* pid of child fork */
  4131. static int     fcount;                   /* Number of files in wild group */
  4132. static char    nambuf[MAXNAMLEN+2];     /* Buffer for a filename */
  4133. char           *malloc(), *strcpy();           /* System functions */
  4134.  
  4135. static char     *mtchs[MAXWLD],          /* Matches found for filename */
  4136.                **mtchptr;                /* Pointer to current match */
  4137.  
  4138. static char     file_type[9];            /* type of current file */
  4139. static int     char_count;               /* number of characters written */
  4140.  
  4141. static int     spur_type;
  4142.  
  4143. /* 1=NCRL 2=BASIC 3=FORTB 4=FORTI 5=FORTF 6=FORTV 7=NEAT/3          */
  4144. /* 8=NEAT/VS 9=NEAT/C 10=COBOL 11=COBOL/6 12=COBOL/7 13=COBOL/8     */
  4145. /* 14=HEADCS 15=PROC,16=PROCN,17=COBOL1,18=COBOL1/6 19=COBOL1/7     */
  4146. /* 20=COBOL1/8 21=COBOL4                                            */
  4147.  
  4148. static char    language[7];
  4149. static int     suffix;
  4150. static int     spur_eof = 0;
  4151. static int     linenumber;
  4152. static char    spur_data[400];        /* Area to hold packet data */
  4153. static char    *nxtspur_data;
  4154. static char    pcard[100];            /* VRX Control String header record */
  4155.  
  4156. static int     objopen = CLOSE;       /* incomplete object files left
  4157.                                          open by aborted transfers       */
  4158. static char    fn_temp[10];           /* to DELETE incomplete files
  4159.                                          leftover from interuptions   */
  4160.  
  4161. /*  Z K S E L F  --  Kill Self: log out own job, if possible.  */
  4162.  
  4163. /* Note, should get current pid, but if your system doesn't have */
  4164. /* getppid(), then just kill(0,9)...  */
  4165.  
  4166. zkself()
  4167. {                    /* For "bye", but no guarantee! */
  4168.      return(0);
  4169. }
  4170.  
  4171.  
  4172. /*  Z O P E N I  --  Open an existing file for input. */
  4173.  
  4174. zopeni(n, name)
  4175. int     n;
  4176. char     *name;
  4177. {
  4178.      char     buff[100];
  4179.  
  4180.      if (deblog) {
  4181.           debug(F111, " zopeni", name, n);
  4182.           debug(F101, "  fp", "", (int) fp[n]);
  4183.      }
  4184.  
  4185.      if (n == ZIFILE)
  4186.           resetopen();
  4187.  
  4188.      if (access(name, 0) != 0) {
  4189.           errhdlr("zopeni");
  4190.           fprintf(stderr,"file does not exist: %s\n",name);
  4191.           return(-1);
  4192.      }
  4193.  
  4194.      if ((suffix == BINARY || suffix == L_BINARY)
  4195.          && !(binary) && (n == ZIFILE)) {
  4196.           errhdlr("file mismatch see STDERR");
  4197.           fprintf(stderr,"FILE TYPE is set to TEXT\n");
  4198.           fprintf(stderr,"BINARY file type requested\n");
  4199.           fprintf(stderr,"set file type to binary 8\n");
  4200.           fprintf(stderr,"file transport will proceed\n");
  4201.           return(-1);
  4202.      }
  4203.  
  4204.      if (chkfn(n) != 0)
  4205.           return(0);
  4206.  
  4207.      if (n == ZSYSFN || n == ZSTDIO)      /* Input from a system function
  4208.                                              or stdio                     */
  4209.           return(0);                      /* VRX invailid */
  4210.  
  4211.      /*
  4212.        * VKERMIT code:
  4213.        * Special handling open required for object files on NCR's VRX/E
  4214.        */
  4215.  
  4216.      if (*file_type == 'O' && n == ZIFILE) {
  4217.  
  4218.           /* note difference in return numbers for voopen and zopen */
  4219.  
  4220.           if (voopeni(n, name) == 0) {        /* OK */
  4221.                fp[n] = (FILE *) 1; /* bogus fp to keep ckermit happy */
  4222.                strcpy(fn_temp, name);
  4223.                objopen = OPEN;
  4224.                fprintf(stderr, "downloading to PC\n");
  4225.                return(1);
  4226.           } else {
  4227.                errhdlr("zopeni vopeni bad outcome");
  4228.                return(0);
  4229.           }
  4230.      }
  4231.      /* end VKERMIT code */
  4232.  
  4233.       if (binary)
  4234.            fp[n] = fopen(name, "rb");  /* Real binary file. */
  4235.       else
  4236.            fp[n] = fopen(name, "r");   /* Real file. */
  4237.  
  4238.      if (fp[n] == NULL) {
  4239.           errhdlr("zopeni fp NULL see STDERR");
  4240.           fprintf(stderr,"input file open failure: %s\n",name);
  4241.           if (binary) {
  4242.                 fprintf(stderr,"check V-Kermit set up...an input text file\n");
  4243.                 fprintf(stderr,"can not be opened as a binary file\n");
  4244.                 fprintf(stderr,"text files include source, control\n");
  4245.                 fprintf(stderr,"string, and data file types...\n");
  4246.           }
  4247.      } else {
  4248.           spur_data[0] = '\0';
  4249.           nxtspur_data = &spur_data[0];
  4250.           linenumber = INCREMENT;
  4251.           spur_eof = 0;
  4252.           strcpy(fn_temp, name);
  4253.           fprintf(stderr, "downloading to PC\n");
  4254.      }
  4255.  
  4256.      if (deblog)
  4257.           debug(F111, " zopeni", name, (int) fp[n]);
  4258.  
  4259.      return((fp[n] != NULL) ? 1 : 0);
  4260. }
  4261.  
  4262.  
  4263. /*  Z O P E N O  --  Open a new file for output.  */
  4264.  
  4265. zopeno(n, name)
  4266. int     n;
  4267. char     *name;
  4268. {
  4269.  
  4270.      if (deblog)
  4271.           debug(F111, " zopeno", name, n);
  4272.  
  4273.      if (n == ZOFILE)
  4274.           resetopen();
  4275.  
  4276.      if ((suffix == BINARY || suffix == L_BINARY)
  4277.          && !(binary) && (n == ZOFILE)) {
  4278.           errhdlr("file mismatch see STDERR");
  4279.           fprintf(stderr,"FILE TYPE is set to TEXT\n");
  4280.           fprintf(stderr,"BINARY file type requested\n");
  4281.           fprintf(stderr,"set file type to binary 8\n");
  4282.           fprintf(stderr,"file transport will proceed\n");
  4283.           return(-1);
  4284.      }
  4285.  
  4286.      if (chkfn(n) != 0)
  4287.           return(0);
  4288.  
  4289.      if ((n == ZCTERM) || (n == ZSTDIO) ||
  4290.          (n == ZSFILE))                   /* Terminal or standard output */
  4291.                                           /* or SESIONLOG                */
  4292.           return (0);                     /* Invalid for VRX             */
  4293.  
  4294.      /*
  4295.         * VKERMIT code:
  4296.         * Use special open for object files on NCR's VRX/E
  4297.         */
  4298.  
  4299.      if (*file_type == 'O' && n == ZOFILE) {
  4300.           /* note difference in return numbers in voopen and zopen */
  4301.           if (voopeno(n, name) == 0) {
  4302.                /* OK */ /* bogus file pointer to keep ckermit happy */
  4303.                fp[n] = (FILE *) 1;
  4304.                strcpy(fn_temp, name);
  4305.                objopen = OPEN;
  4306.                fprintf(stderr, "uploading from PC\n");
  4307.                return(1);
  4308.           } else {
  4309.                errhdlr("voopeno can't open");
  4310.                fprintf(stderr, "Error opening upload file %s\n",
  4311.                        name);
  4312.                return(0);
  4313.           }
  4314.      }
  4315.      /* end VKERMIT code */
  4316.  
  4317.      /*
  4318.            FCL references for the log files
  4319.            April 5, 1990
  4320.                                                   */
  4321.  
  4322.      switch (n) {
  4323.          char     vtmp [45];
  4324.  
  4325.      case ZTFILE:
  4326.           {
  4327.                sprintf(vtmp, "LOGTRANS(NAME=%s)", name);
  4328.                fp[n] = fopen(vtmp, "w");
  4329.           }
  4330.           break;
  4331.  
  4332.      case ZDFILE:
  4333.           {
  4334.                sprintf(vtmp, "LOGDEBUG(NAME=%s)", name);
  4335.                fp[n] = fopen(vtmp, "w");
  4336.           }
  4337.           break;
  4338.  
  4339.      case ZPFILE:
  4340.           {
  4341.                sprintf(vtmp, "LOGPACKET(NAME=%s)", name);
  4342.                fp[n] = fopen(vtmp, "w");
  4343.           }
  4344.           break;
  4345.  
  4346.      default:
  4347.  
  4348.           if (binary && n == ZOFILE)
  4349.                fp[n] = fopen(name, "wb");
  4350.           else
  4351.                fp[n] = fopen(name, "w");
  4352.  
  4353.           if (fp[n] != NULL) {
  4354.                strcpy(fn_temp, name);
  4355.                fprintf(stderr, "uploading from PC\n");
  4356.           }
  4357.           else {
  4358.                errhdlr("zopeno can't open");
  4359.                fprintf(stderr, "Error opening: %s\n", name);
  4360.                return (0);
  4361.      }
  4362.           break;
  4363.  
  4364.      }
  4365.  
  4366.      if ((*file_type == 'C' || *file_type == 'S') && n == ZOFILE) {
  4367.           fputc(0, fp[n]);    /* space count = 0 on pcard */
  4368.  
  4369.           if (ferror(fp[n]) != 0 && errno != EMAXR && errno !=
  4370.               EMINR) {
  4371.                errhdlr("zopeno PCARD");
  4372.                fprintf(stderr, "write error: space count PCARD\n");
  4373.                return(0);
  4374.           } else
  4375.                errno = 0;  /*    reset errno = EMAXR for pcard write
  4376.                                  no big deal happens half the time
  4377.                                  errno EMAXR is the message Maximum
  4378.                                  record length error (line truncated)
  4379.                                  April 12, 1990
  4380.  
  4381. */
  4382.  
  4383.           if (zsoutl(n, pcard) == -1)
  4384.                return (0);
  4385.           char_count = 0;
  4386.      }
  4387.  
  4388.      spur_data[0] = '\0';
  4389.      nxtspur_data = &spur_data[0];
  4390.      linenumber = INCREMENT;
  4391.      if (deblog)
  4392.           debug(F101, " fp[n]", "", (int) fp[n]);
  4393.  
  4394.      return((fp[n] != NULL) ? 1 : 0);
  4395. }
  4396.  
  4397.  
  4398. /*  Z C L O S E  --  Close the given file.  */
  4399.  
  4400. /*  Returns 0 if arg out of range, 1 if successful, -1 if close failed.  */
  4401.  
  4402. zclose(n)
  4403. int     n;
  4404. {
  4405.      int     x;
  4406.  
  4407.      if (chkfn(n) < 1)
  4408.           return(0); /* Check range of n */
  4409.  
  4410.      /*
  4411.      * VKERMIT code:
  4412.      * Use special close for NCR's VRX/E object files
  4413.      */
  4414.  
  4415.      if (*file_type == 'O' && (n == ZIFILE || n == ZOFILE)) {
  4416.           if (voclose(n) == 0) {
  4417.                fp[n] = NULL;             /* March 7, 1990 */
  4418.                objopen = CLOSE;
  4419.                return(1);
  4420.           } else {
  4421.                fp[n] = NULL;
  4422.                objopen = CLOSE;
  4423.                return(-1);
  4424.           }
  4425.      }
  4426.      /* end VKERMIT code */
  4427.  
  4428.      if ((fp[n] != stdin) && (fp[n] != stdout))
  4429.          x = fclose(fp[n]);
  4430.  
  4431.      fp[n] = NULL;
  4432.  
  4433.      if (x == EOF) {
  4434.          errhdlr("zclose");
  4435.          fprintf(stderr,"Can't close file fclose returned: EOF\n");
  4436.      }
  4437.  
  4438.      strcpy(fn_temp, "\0");
  4439.  
  4440.      return((x == EOF) ? -1 : 1);
  4441. }
  4442.  
  4443.  
  4444. /*  Z C H I N  --  Get a character from the input file.  */
  4445.  
  4446. /*  Returns -1 if EOF, 0 otherwise with character returned in argument  */
  4447. /*  removes NULL and DEL characters in Control String and Source files */
  4448.  
  4449. zchin(n, c)
  4450. int     n;
  4451. char     *c;
  4452. {
  4453.      int     a;
  4454.      int     i = 10;
  4455.  
  4456.      if (*file_type == 'S' || *file_type == 'C') {
  4457.           if (*nxtspur_data == '\0') {
  4458.                spur_data[0] = '\0';
  4459.                switch (zsreci(n)) {
  4460.                case 0:
  4461.                     spur_eof++;
  4462.                     break;
  4463.                case 1:
  4464.                     break;
  4465.                case -1:
  4466.                     return(-1);
  4467.                }
  4468.                if ((spur_eof) && (strlen(spur_data) == 0))
  4469.                     return(-1);
  4470.                nxtspur_data = &spur_data[0];
  4471.           }
  4472.           a = *nxtspur_data++;
  4473.  
  4474.      } else if (*file_type == 'O') {
  4475.  
  4476.           /* VKERMIT code for VRX/E object files */
  4477.  
  4478.           /* vogetc returns -1 on end of file and also on
  4479.              error conditions after outputing an appropriate
  4480.              error message. */
  4481.  
  4482.           if ((a = vogetc(n)) == -1)
  4483.                return(-1);
  4484.  
  4485.      } else {
  4486.  
  4487.           if (chkfn(n) < 1)   /* check file address */
  4488.                return(-1);
  4489.  
  4490.           a = getc(fp[n]);  /* place character in a */
  4491.  
  4492.           if (ferror(fp[n]) != 0) {
  4493.                errhdlr("zchin");
  4494.                fprintf(stderr, "read error: zchin\n");
  4495.                return(-1);
  4496.           }
  4497.  
  4498.  
  4499.  
  4500.           if (a == EOF)    /* if EOF, return -1    */
  4501.                return(-1);
  4502.      }
  4503.      *c = a & 0xFF;   /* strip top bit     */
  4504.  
  4505.      return(0);
  4506. }
  4507.  
  4508.  
  4509. /*  Z S O U T  --  Write a string to the given file, buffered.  */
  4510.  
  4511. zsout(n, s)
  4512. int     n;
  4513. char     *s;
  4514. {
  4515.  
  4516.      if (chkfn(n) < 1)
  4517.           return(-1);
  4518.  
  4519.      if ((*file_type == 'C' || *file_type == 'S') && n == ZOFILE) {
  4520.           char     *sptr;
  4521.           sptr = s;
  4522.           if (sptr == NULL)
  4523.                return(0);
  4524.           while (*sptr++ != '\0') {
  4525.                if (*sptr == '\n') {
  4526.                     if (putc('\377', fp[n]) == EOF) {
  4527.                          errhdlr("zsout/377");
  4528.                          return((ferror(fp[n]) == 0) ?
  4529.                              0 : -1);
  4530.                     }
  4531.                     if (putc('\n', fp[n]) == EOF) {
  4532.                          errhdlr("zsout NL");
  4533.                          return((ferror(fp[n]) == 0) ?
  4534.                              0 : -1);
  4535.                     }
  4536.                     if (putc('\000', fp[n]) == EOF) {
  4537.                          errhdlr("zsout/000");
  4538.                          return((ferror(fp[n]) == 0) ?
  4539.                              0 : -1);
  4540.                     }
  4541.                } else if (putc(*sptr, fp[n]) == EOF) {
  4542.                     errhdlr("zsout/*sptr");
  4543.                     return((ferror(fp[n]) == 0) ? 0 : -1);
  4544.                }
  4545.           }
  4546.      } else if (fputs(s, fp[n]) == NULL) {
  4547.           errhdlr("zsout/fputs");
  4548.           return((ferror(fp[n]) == 0) ? 0 : -1);
  4549.      }
  4550.      return(0);
  4551. }
  4552.  
  4553.  
  4554. /*  Z S O U T L  --  Write string to file, with line terminator, buffered  */
  4555.  
  4556. zsoutl(n, s)
  4557. int     n;
  4558. char     *s;
  4559. {
  4560.      char     *ptr;
  4561.  
  4562.      if (chkfn(n) < 1)
  4563.           return(-1);
  4564.  
  4565.      if (lenchk(s, n)) {
  4566.  
  4567.           switch (spur_type) {
  4568.           case 9:
  4569.           case 11:
  4570.                errhdlr("zsoutl: writing ln > max len");
  4571.                fprintf(stderr, "writing line > %d char\n",
  4572.                    SRCLNLEN + 1);
  4573.                fprintf(stderr, "line length was %d\n", strlen(s));
  4574.                fprintf(stderr, "%s\n", s);
  4575.                return(-1);
  4576.           default:
  4577.                errhdlr("zsoutl: writing ln > max len");
  4578.                fprintf(stderr, "writing line > %d char\n",
  4579.                    SRCLNLEN);
  4580.                fprintf(stderr, "line length was %d\n", strlen(s));
  4581.                fprintf(stderr, "%s\n", s);
  4582.                return(-1);
  4583.           }
  4584.      }
  4585.  
  4586.      if (fputs(s, fp[n]) == NULL) {
  4587.           errhdlr("zsoutl/fputs");
  4588.           return(-1);
  4589.      }
  4590.  
  4591.      if ((*file_type == 'C' || *file_type == 'S') && n == ZOFILE) {
  4592.  
  4593.           if (putc('\377', fp[n]) == EOF) {  /* end sentinal character */
  4594.                errhdlr("zsoutl/377");
  4595.                return((ferror(fp[n]) == 0) ? 0 : -1);
  4596.           }
  4597.  
  4598.           if (putc('\n', fp[n]) == EOF) {
  4599.                errhdlr("zsoutl/LN CS");
  4600.                return((ferror(fp[n]) == 0) ? 0 : -1);
  4601.           }
  4602.      } else if (putc('\n', fp[n]) == EOF) {
  4603.           errhdlr("zsoutl/LN");
  4604.           return((ferror(fp[n]) == 0) ? 0 : -1);
  4605.      }
  4606.      return(0);
  4607. }
  4608.  
  4609.  
  4610. /*  Z S O U T X  --  Write x characters to file, unbuffered.  */
  4611.  
  4612. zsoutx(n, s, x)
  4613. int     n, x;
  4614. char     *s;
  4615. {
  4616.  
  4617.      int     i;
  4618.  
  4619.      if (chkfn(n) < 1)
  4620.           return(-1);
  4621.  
  4622.      if ((i = write(fp[n]->_file, s, x)) == -1) {
  4623.           errhdlr("zsoutx");
  4624.           return(-1);
  4625.      } else {
  4626.           return(i);
  4627.      }
  4628.  
  4629. }
  4630.  
  4631.  
  4632. /*  Z C H O U T  --  Add a character to the given file.  */
  4633.  
  4634. /*  Should return 0 or greater on success, -1 on failure (e.g. disk full)  */
  4635.  
  4636. zchout(n, c)
  4637. int     n;
  4638. char     c;
  4639. {
  4640.      int     i;
  4641.  
  4642.      if (chkfn(n) < 1)
  4643.           return(-1);
  4644.  
  4645.      /* April 5, 1990
  4646.  
  4647.           This switch statement is courtesy of the corruption
  4648.           in ZSFILE (sessionlog).
  4649.  
  4650.           We now check every character we write to verify
  4651.           it is a printable character.
  4652.  
  4653.           If SET FILE TYPE TEXT is set: (int binary == 0)
  4654.              we verify character for ZOFILE (output file)
  4655.  
  4656.           IF a LOG file we verify whether binary set or
  4657.           not.
  4658.  
  4659.                 if a nonprintable character is encountered
  4660.                 output to stderr
  4661.                 return -1
  4662.  
  4663.        */
  4664.  
  4665.      switch (n) {
  4666.                char     err_tmp[35];
  4667.  
  4668.      case ZOFILE:
  4669.           if (binary)
  4670.                break;
  4671.           if (c == 0x1A)
  4672.                return(0);
  4673.           if (!(isprint(c) || isspace(c))) {
  4674.                sprintf(err_tmp, "zchout nonprint char: %X",
  4675.                     c);
  4676.                errhdlr(err_tmp);
  4677.                return(-1);
  4678.           }
  4679.           break;
  4680.  
  4681.      case ZSFILE:
  4682.      case ZTFILE:
  4683.      case ZDFILE:
  4684.      case ZPFILE:
  4685.           if (!(isprint(c) || isspace(c))) {
  4686.                sprintf(err_tmp, "zchout: nonprint char: %X",
  4687.                     c);
  4688.                errhdlr(err_tmp);
  4689.                fprintf(stderr, "error writing log file: %X\n",
  4690.                     n);
  4691.                return(-1);
  4692.           }
  4693.           break;
  4694.      default:
  4695.           /* we should never execute this BUT
  4696.              if I do not put in in I'll be
  4697.              sorry later
  4698.                                                           */
  4699.           errhdlr("zchout dead code");
  4700.           fprintf(stderr, "Executing in dead code area: %d\n",
  4701.                n);
  4702.           return(-1);
  4703.      }
  4704.  
  4705.      if (n == ZSFILE)       /* Use unbuffered for session log */
  4706.           return(write(fp[n]->_file, &c, 1));
  4707.  
  4708.      else {    /* Buffered for everything else */
  4709.  
  4710.           if (*file_type == 'O' && n == ZOFILE)
  4711.                return(voputc(c, n));
  4712.           else if ((*file_type == 'C' || *file_type == 'S') &&
  4713.               n == ZOFILE) {
  4714.  
  4715.                if (c == '\n') {
  4716.                     if (zsreco(n) == -1)
  4717.                          return (-1);
  4718.                     spur_data[0] = '\0';
  4719.                     nxtspur_data = &spur_data[0];
  4720.  
  4721.                } else {
  4722.                     *nxtspur_data++ = c;
  4723.                     *nxtspur_data = '\0';
  4724.                }
  4725.                return(0);
  4726.  
  4727.           } else {
  4728.                if (putc(c, fp[n]) == EOF) {
  4729.                                             /* If true, maybe an error */
  4730.                          errhdlr("ZCHOUT");
  4731.                                             /* Check to make sure */
  4732.                          return((ferror(fp[n]) == 0) ?
  4733.                              0 : -1);
  4734.                }
  4735.           }
  4736.      }
  4737. }
  4738.  
  4739.  
  4740. /*  C H K F N  --  Internal function to verify file number is ok  */
  4741.  
  4742. /*
  4743.  Returns:
  4744.   -1: File number n is out of range
  4745.    0: n is in range, but file is not open
  4746.    1: n in range and file is open
  4747. */
  4748.  
  4749. chkfn(n)
  4750. int     n;
  4751. {
  4752.  
  4753.      switch (n) {
  4754.      case ZCTERM:
  4755.      case ZSTDIO:
  4756.      case ZIFILE:
  4757.      case ZOFILE:
  4758.      case ZDFILE:
  4759.      case ZTFILE:
  4760.      case ZPFILE:
  4761.      case ZSFILE:
  4762.      case ZSYSFN:
  4763.           break;
  4764.      default:
  4765.           if (deblog)
  4766.                debug(F101, "chkfn: file number out of range",
  4767.                     "", n);
  4768.           errhdlr("chkfn");
  4769.           fprintf(stderr, "File number out of range - %d\n", n);
  4770.           return(-1);
  4771.      }
  4772.  
  4773.      return( (fp[n] == NULL) ? 0 : 1 );
  4774. }
  4775.  
  4776.  
  4777. /*  Z C H K I  --  Check if input file exists and is readable  */
  4778.  
  4779. /*
  4780.   Returns:
  4781.    >= 0 if the file can be read (returns the size).
  4782.      -1 if file doesn't exist or can't be accessed,
  4783.      -2 if file exists but is not readable (e.g. a directory file).
  4784.      -3 if file exists but protected against read access.
  4785. */
  4786.  
  4787.  
  4788. long     zchki(name)
  4789. char     *name;
  4790. {
  4791.  
  4792.      FILE * fptr;
  4793.      long     length;
  4794.  
  4795.      if (access(name, 0) != 0)
  4796.           return(-1);
  4797.  
  4798.      if ((fptr = fopen(name, "r")) != NULL) {
  4799.           fseek(fptr, 0L, 2);
  4800.           length = ftell(fptr);
  4801.           close(fptr);
  4802.           return(length);
  4803.      } else
  4804.           return(-1);
  4805. }
  4806.  
  4807.  
  4808. /*  Z C H K O  --  Check if output file can be created  */
  4809.  
  4810. /*
  4811.  Returns -1 if write permission for the file would be denied, 0 otherwise.
  4812. */
  4813. zchko(name)
  4814. char     *name;
  4815. {
  4816.      return(0);
  4817. }
  4818.  
  4819.  
  4820. /*  Z D E L E T  --  Delete the named file.  */
  4821.  
  4822. zdelet(name)
  4823. char     *name;
  4824. {
  4825.      unlink(name);
  4826. }
  4827.  
  4828.  
  4829. /*  Z R T O L  --  Convert remote filename into local form  */
  4830.  
  4831. /*
  4832.  *  For VRX, this means:
  4833.  *                 truncating to 8/10 characters
  4834.  *                 changing lowercase to upper case
  4835.  *                 changing periods (.) to underscore (_)
  4836.  *  If the filename contains an extension of the form: filename.extension
  4837.  *  then the parameter "type" is set the file type. If there is no extension,
  4838.  *  "type" is set to type DATA.
  4839.  *  possible extensions are:
  4840.  *     .OBJ - object files
  4841.  *     .BIN - binary data file
  4842.  *     .CS  - Control String file
  4843.  *     .PRO - Procedure file
  4844.  *     .DAT - default data file
  4845.  *     .NCR - NCRL SPUR file
  4846.  *     .BAS - BASIC SPUR file
  4847.  *     .FB  - Fortran/B SPUR file
  4848.  *     .FI  - Fortran/I SPUR file
  4849.  *     .FF  - Fortran/F SPUR file
  4850.  *     .FV  - Fortran/V SPUR file
  4851.  *     .N3  - NEAT/3 SPUR file
  4852.  *     .NVS - NEAT/VS SPUR file
  4853.  *     .NC  - NEAT/C SPUR file
  4854.  *     .CO  - COBOL/0 SPUR file
  4855.  *     .CO6 - COBOL/6 SPUR file
  4856.  *     .CO7 - COBOL/7 SPUR file
  4857.  *     .CO1 - COBOL1/0 SPUR file
  4858.  *     .C16 - COBOL1/6 SPUR file
  4859.  *     .C17 - COBOL1/7 SPUR file
  4860.  *     .C18 - COBOL1/8 SPUR file
  4861.  *     .CO4 - COBOL4 SPUR file
  4862.  *     .D100 - fixed length data file with 100 byte records
  4863.  *     .D1-100 - variable length data file with 1 to 100 byte records
  4864.  */
  4865.  
  4866. #define REC_SIZE(ptr) { for(fptr = ((ptr) + 1); *fptr != '\0'; fptr++) {\
  4867.     if (*fptr == '-') *fptr = '/';\
  4868.     else if (*fptr < '0' || *fptr > '9') break;\
  4869.    }\
  4870.    if (*fptr == '\0') record_sized++;\
  4871.         }
  4872.  
  4873. zrtol(name, name2)
  4874. char     *name, *name2;
  4875. {
  4876.      char    *ftype, *subtype, *fptr, *namep, *strrchr();
  4877.      int     suffix_len, i, n, max, record_sized = 0;
  4878.      long    stamp;
  4879.  
  4880.      spur_type = 0;
  4881.      suffix = 0;
  4882.      *name2 = '\0';
  4883.      if (deblog)
  4884.           debug(F100, "funct: zrtol    ", "", 0);
  4885.  
  4886.      /* time stamp stderr output */
  4887.      /* May 4, 1990              */
  4888.      stamp = time((long *) 0);
  4889.      fprintf(stderr, "\n%s", ctime(&stamp));
  4890.  
  4891.      fprintf(stderr, "name = <%s>\n", name);
  4892.  
  4893.      if ((ftype = strrchr(name, '.')) == NULL) {
  4894.           strcpy(file_type, "DATAFILE");             /* peg 0190 */
  4895.           max = 10;
  4896.  
  4897.      } else {
  4898.           suffix_len = strlen(++ftype);
  4899.           for (i = 0; i < 4; i++) {
  4900.                if (i >= suffix_len)
  4901.                     n = 0;
  4902.                else
  4903.                     n = ftype[i];
  4904.                suffix = (suffix << 8) | n;
  4905.           }
  4906.           switch (suffix) {
  4907.           case L_OBJECT:
  4908.           case OBJECT:
  4909.                strcpy(file_type, "OBJFILE");  /* peg 0190 */
  4910.                max = 8;
  4911.                *(ftype - 1) = '\0';
  4912.                break;
  4913.           case L_BINARY:
  4914.           case BINARY:
  4915.                strcpy(file_type, "DATAFILE");  /* peg 0190 */
  4916.                max = 10;
  4917.                *(ftype - 1) = '\0';
  4918.                break;
  4919.           case L_DATA:
  4920.           case DATA:
  4921.                strcpy(file_type, "DATAFILE");
  4922.                max = 10;
  4923.                *(ftype - 1) = '\0';
  4924.                break;
  4925.           case L_NCRL:
  4926.           case NCRL:
  4927.                strcpy(file_type, "SRCFILE");  /* peg 0190 */
  4928.                spur_type = 1;
  4929.                strcpy(language, "NCRL  ");
  4930.                max = 8;
  4931.                *(ftype - 1) = '\0';
  4932.                break;
  4933.           case L_BASIC:
  4934.           case BASIC:
  4935.                strcmp(file_type, "SRCFILE");  /* peg 0190 */
  4936.                spur_type = 2;
  4937.                strcpy(language, "BASIC ");
  4938.                max = 8;
  4939.                *(ftype - 1) = '\0';
  4940.                break;
  4941.           case L_FORTB:
  4942.           case FORTB:
  4943.                strcpy(file_type, "SRCFILE");  /* peg 0190 */
  4944.                spur_type = 3;
  4945.                strcpy(language, "FORT/B");
  4946.                max = 8;
  4947.                *(ftype - 1) = '\0';
  4948.                break;
  4949.           case L_FORTI:
  4950.           case FORTI:
  4951.                strcpy(file_type, "SRCFILE"); /* peg 0190 */
  4952.                spur_type = 4;
  4953.                strcpy(language, "FORT/I");
  4954.                max = 8;
  4955.                *(ftype - 1) = '\0';
  4956.                break;
  4957.           case L_FORTF:
  4958.           case FORTF:
  4959.                strcpy(file_type, "SRCFILE");    /* peg 0190 */
  4960.                spur_type = 5;
  4961.                strcpy(language, "FORT/F");
  4962.                max = 8;
  4963.                *(ftype - 1) = '\0';
  4964.                break;
  4965.           case L_FORTV:
  4966.           case FORTV:
  4967.                strcpy(file_type, "SRCFILE");   /* peg 0190 */
  4968.                spur_type = 6;
  4969.                strcpy(language, "FORT/V");
  4970.                max = 8;
  4971.                *(ftype - 1) = '\0';
  4972.                break;
  4973.           case L_NEAT3:
  4974.           case NEAT3:
  4975.                strcpy(file_type, "SRCFILE");  /* peg 0190 */
  4976.                spur_type = 7;
  4977.                strcpy(language, "NEAT/3");
  4978.                max = 8;
  4979.                *(ftype - 1) = '\0';
  4980.                break;
  4981.           case L_NEATVS:
  4982.           case NEATVS:
  4983.                strcpy(file_type, "SRCFILE");   /* peg 0190 */
  4984.                spur_type = 8;
  4985.                strcpy(language, "NEATVS");
  4986.                max = 8;
  4987.                *(ftype - 1) = '\0';
  4988.                break;
  4989.           case L_NEATC:
  4990.           case NEATC:
  4991.                strcpy(file_type, "SRCFILE");
  4992.                spur_type = 9;
  4993.                strcpy(language, "NEAT/C");
  4994.                max = 8;
  4995.                *(ftype - 1) = '\0';
  4996.                break;
  4997.           case L_COBOL:
  4998.           case COBOL:
  4999.                strcpy(file_type, "SRCFILE");   /* peg 0190 */
  5000.                spur_type = 10;
  5001.                strcpy(language, "COBOL ");
  5002.                max = 8;
  5003.                *(ftype - 1) = '\0';
  5004.                break;
  5005.           case L_COBOL6:
  5006.           case COBOL6:
  5007.                strcpy(file_type, "SRCFILE");   /* peg 0190 */
  5008.                spur_type = 11;
  5009.                strcpy(language, "COBOL ");
  5010.                max = 8;
  5011.                *(ftype - 1) = '\0';
  5012.                break;
  5013.           case L_COBOL7:
  5014.           case COBOL7:
  5015.                strcmp(file_type, "SRCFILE");  /* peg 0190 */
  5016.                spur_type = 12;
  5017.                strcpy(language, "COBOL ");
  5018.                max = 8;
  5019.                *(ftype - 1) = '\0';
  5020.                break;
  5021.           case L_COBOL8:
  5022.           case COBOL8:
  5023.                strcpy(file_type, "SRCFILE");  /* peg 0190 */
  5024.                spur_type = 13;
  5025.                strcpy(language, "COBOL ");
  5026.                max = 8;
  5027.                *(ftype - 1) = '\0';
  5028.                break;
  5029.           case L_CS:
  5030.           case CS:
  5031.                strcpy(file_type, "CSFILE");   /* peg 0190 */
  5032.                spur_type = 14;
  5033.                strcpy(language, "HEADCS");
  5034.                max = 8;
  5035.                *(ftype - 1) = '\0';
  5036.                break;
  5037.           case L_PROC:
  5038.           case PROC:
  5039.                strcpy(file_type, "CSFILE");    /* peg 0190 */
  5040.                spur_type = 15;
  5041.                strcpy(language, "HEADCS");
  5042.                max = 8;
  5043.                *(ftype - 1) = '\0';
  5044.                break;
  5045.           case L_PROCN:
  5046.           case PROCN:
  5047.                strcmp(file_type, "CSFILE");    /* peg 0190 */
  5048.                spur_type = 16;
  5049.                strcpy(language, "HEADCS");
  5050.                max = 8;
  5051.                *(ftype - 1) = '\0';
  5052.                break;
  5053.           case L_COBOL1:
  5054.           case COBOL1:
  5055.                strcpy(file_type, "SRCFILE");   /* peg 0190 */
  5056.                spur_type = 17;
  5057.                strcpy(language, "COBOL1");
  5058.                max = 8;
  5059.                *(ftype - 1) = '\0';
  5060.                break;
  5061.           case L_COBOL16:
  5062.           case COBOL16:
  5063.                strcpy(file_type, "SRCFILE");    /* peg 0190 */
  5064.                spur_type = 18;
  5065.                strcpy(language, "COBOL1");
  5066.                max = 8;
  5067.                *(ftype - 1) = '\0';
  5068.                break;
  5069.           case L_COBOL17:
  5070.           case COBOL17:
  5071.                strcpy(file_type, "SRCFILE");   /* peg 0190 */
  5072.                spur_type = 19;
  5073.                strcpy(language, "COBOL1");
  5074.                max = 8;
  5075.                *(ftype - 1) = '\0';
  5076.                break;
  5077.           case L_COBOL18:
  5078.           case COBOL18:
  5079.                strcpy(file_type, "SRCFILE");    /* peg 0190 */
  5080.                spur_type = 20;
  5081.                strcpy(language, "COBOL1");
  5082.                max = 8;
  5083.                *(ftype - 1) = '\0';
  5084.                break;
  5085.           case L_COBOL4:
  5086.           case COBOL4:
  5087.                strcpy(file_type, "SRCFILE");   /* peg 0190 */
  5088.                spur_type = 21;
  5089.                strcpy(language, "COBOL4");
  5090.                max = 8;
  5091.                *(ftype - 1) = '\0';
  5092.                break;
  5093.           default:
  5094.                if (*ftype == 'B' || *ftype == 'b') {
  5095.                     suffix = BINARY;
  5096.                     if (*(ftype + 1) != '\0')
  5097.                          REC_SIZE(ftype);
  5098.  
  5099.                     if (record_sized) {
  5100.                          *(ftype) = '\0';
  5101.                     }
  5102.                }
  5103.  
  5104.                if ((*ftype == 'd') || (*ftype == 'D')) {
  5105.                     if (*(ftype + 1) != '\0')
  5106.                          REC_SIZE(ftype);
  5107.  
  5108.                     if (record_sized)
  5109.                          *(ftype) = '\0';
  5110.  
  5111.                }
  5112.                strcpy(file_type, "DATAFILE");
  5113.                max = 10;
  5114.                break;
  5115.           }
  5116.      }
  5117.  
  5118.      /* convert periods to underscores, lowercase to uppercase */
  5119.  
  5120.      namep = name;
  5121.  
  5122.      for (i = 0; *namep != '\0', i < max; namep++, i++) {
  5123.  
  5124.           if (*namep == '.')
  5125.                *namep = '_';
  5126.           if (*namep == '~')
  5127.                *namep = 'X';
  5128.           if (*namep == '$')
  5129.                *namep = '_';
  5130.           else if (islower(*namep) && fncnv)
  5131.                toupper(*namep);
  5132.      }
  5133.      *namep = '\0';
  5134.  
  5135.      if (record_sized) {
  5136.           /*
  5137.                            first the recordsize is truncated
  5138.                            now the displayed name contains
  5139.                            additional underscores, this fix
  5140.                            truncates everything past the
  5141.                            FINAL underscore
  5142.                            April 13, 1990
  5143.                                                                */
  5144.           char     *s_tmp;
  5145.  
  5146.           s_tmp = strrchr(name, '_');
  5147.           if (s_tmp != NULL)
  5148.                *s_tmp = '\0';
  5149.  
  5150.           sprintf(name2, "%s(NAME=%s,RECORDSIZE=%s)", file_type,
  5151.                              name, (ftype + 1));
  5152.      }  else
  5153.           sprintf(name2, "%s(NAME=%s)", file_type, name);
  5154.  
  5155.      if (*file_type == 'S' || *file_type == 'C')
  5156.           zpcrd(name);
  5157.  
  5158.      if (spur_type != 0)
  5159.           fprintf(stderr, "final name2 = <%s>  spur_type=%d\n",
  5160.                              name2, spur_type);
  5161.      else
  5162.           fprintf(stderr, "final name2 = <%s>\n", name2);
  5163.  
  5164.      if (deblog)
  5165.           debug(F110, "zrtol:", name2, 0);
  5166. }
  5167.  
  5168.  
  5169. /*  Z L T O R  --  Local TO Remote */
  5170.  
  5171. /*  Convert filename from local format to common (remote) form.  */
  5172.  
  5173. zltor(name, name2)
  5174. char     *name, *name2;
  5175. {
  5176.      char     work[100], *cp, *pp;
  5177.      int     dc = 0;
  5178.  
  5179.      if (deblog) {
  5180.           debug(F100, "funct: zltor    ", "", 0);
  5181.           debug(F110, "zltor", name, 0);
  5182.      }
  5183.      pp = work;
  5184.  
  5185.      for (cp = name; *cp != '\0'; cp++) { /* strip path name */
  5186.  
  5187.           if (*cp == '/') {
  5188.                dc = 0;
  5189.                pp = work;
  5190.           }  else if (islower(*cp))
  5191.                *pp++ = toupper(*cp); /* Uppercase letters */
  5192.  
  5193.           else if (*cp == '~')
  5194.                *pp++ = 'X'; /* Change tilde to 'X' */
  5195.  
  5196.           else if (*cp == '#')
  5197.                *pp++ = 'X'; /* Change number sign to 'X' */
  5198.  
  5199.                /*          else if (*cp == '.')
  5200.                *pp++ = '_';  */ /* & extra dots */
  5201.  
  5202.           else if (*cp == '$')
  5203.                *pp++ = '_';
  5204.  
  5205.           else
  5206.                *pp++ = *cp;
  5207.      }
  5208.      *pp = '\0';                        /* Tie it off. */
  5209.      cp = name2;                        /* If nothing before dot, */
  5210.      if (*work == '.')
  5211.           *cp++ = 'X';     /* insert 'X' */
  5212.      strcpy(cp, work);
  5213.      if (deblog)
  5214.           debug(F110, "zltor<name2>", name2, 0);
  5215. }
  5216.  
  5217.  
  5218. /*  Z C H D I R  --  Change directory  */
  5219.  
  5220. zchdir(dirnam)
  5221. char     *dirnam;
  5222. {
  5223.      /* not implemented */
  5224. }
  5225.  
  5226.  
  5227. /*  Z H O M E  --  Return pointer to user's home directory  */
  5228.  
  5229. char     *
  5230. zhome()
  5231. {
  5232.      return("home");
  5233. }
  5234.  
  5235.  
  5236. /*  Z G T D I R  --  Return pointer to user's current directory  */
  5237.  
  5238. char     *
  5239. zgtdir()
  5240. {
  5241.      return("(directory unknown)");
  5242. }
  5243.  
  5244.  
  5245. /*  Z X C M D -- Run a system command so its output can be read like a file */
  5246.  
  5247. zxcmd(comand)
  5248. char     *comand;
  5249. {
  5250.      return(0);               /* not implemented */
  5251. }
  5252.  
  5253.  
  5254. /*  Z C L O S F  - wait for the child fork to terminate and close the pipe. */
  5255.  
  5256. zclosf()
  5257. {
  5258.      int     wstat;
  5259.      if (deblog)
  5260.           debug(F100, "funct: zclosf   ", "", 0);
  5261.      fclose(fp[ZIFILE]);
  5262.      fp[ZIFILE] = fp[ZSYSFN] = NULL;
  5263.      while ((wstat = WAIT(0)) != pid && wstat != -1)
  5264.           ;
  5265.      return(1);
  5266. }
  5267.  
  5268.  
  5269. /*  Z X P A N D  --  Expand a wildcard string into an array of strings  */
  5270. /*
  5271.   Returns the number of files that match fn1, with data structures set up
  5272.   so that first file (if any) will be returned by the next znext() call.
  5273. */
  5274.  
  5275. zxpand(fn)
  5276. char     *fn;
  5277. {
  5278.      mtchs[0] = (char *) malloc(sizeof(char)*strlen(fn));
  5279.      strcpy(mtchs[0], fn);
  5280.      list_count = 1;
  5281.      return(1);
  5282. }
  5283.  
  5284.  
  5285. /*  Z N E X T  --  Get name of next file from list created by zxpand(). */
  5286. /*
  5287.  Returns >0 if there's another file, with its name copied into the arg string,
  5288.  or 0 if no more files in list.
  5289. */
  5290.  
  5291. znext(fn)
  5292. char     *fn;
  5293. {
  5294.      int     temp;
  5295.      temp = list_count;
  5296.      if (list_count)
  5297.           list_count = 0;
  5298.      strcpy(fn, mtchs[0]);
  5299.      return(temp);
  5300. }
  5301.  
  5302.  
  5303. /*  Z N E W N  --  Make a new name for the given file  */
  5304.  
  5305. znewn(fn, s)
  5306. char     *fn, **s;
  5307. {
  5308. }
  5309.  
  5310.  
  5311. /* Directory Functions for Unix, written by Jeff Damens, CUCCA, 1984. */
  5312.  
  5313. /*
  5314.  * The path structure is used to represent the name to match.
  5315.  * Each slash-separated segment of the name is kept in one
  5316.  * such structure, and they are linked together, to make
  5317.  * traversing the name easier.
  5318.  */
  5319.  
  5320. /*
  5321.  * splitpath:
  5322.  *  takes a string and splits the slash-separated portions into
  5323.  *  a list of path structures.  Returns the head of the list.  The
  5324.  *  structures are allocated by malloc, so they must be freed.
  5325.  *  Splitpath is used internally by the filename generator.
  5326.  *
  5327.  * Input: A string.
  5328.  * Returns: A linked list of the slash-separated segments of the input.
  5329.  */
  5330.  
  5331. struct path *
  5332. splitpath(p)
  5333. char     *p;
  5334. {
  5335. }
  5336.  
  5337.  
  5338. /*
  5339.  * fgen:
  5340.  *  This is the actual name generator.  It is passed a string,
  5341.  *  possibly containing wildcards, and an array of character pointers.
  5342.  *  It finds all the matching filenames and stores them into the array.
  5343.  *  The returned strings are allocated from a static buffer local to
  5344.  *  this module (so the caller doesn't have to worry about deallocating
  5345.  *  them); this means that successive calls to fgen will wipe out
  5346.  *  the results of previous calls.  This isn't a problem here
  5347.  *  because we process one wildcard string at a time.
  5348.  *
  5349.  * Input: a wildcard string, an array to write names to, the
  5350.  *        length of the array.
  5351.  * Returns: the number of matches.  The array is filled with filenames
  5352.  *          that matched the pattern.  If there wasn't enough room in the
  5353.  *     array, -1 is returned.
  5354.  * By: Jeff Damens, CUCCA, 1984.
  5355.  */
  5356.  
  5357. fgen(pat, resarry, len)    /* VRX version, no expansion of file names */
  5358. char     *pat, *resarry[];
  5359. int     len;
  5360. {
  5361. }
  5362.  
  5363.  
  5364. /* traverse:
  5365.  *  Walks the directory tree looking for matches to its arguments.
  5366.  *  The algorithm is, briefly:
  5367.  *   If the current pattern segment contains no wildcards, that
  5368.  *   segment is added to what we already have.  If the name so far
  5369.  *   exists, we call ourselves recursively with the next segment
  5370.  *   in the pattern string; otherwise, we just return.
  5371.  *
  5372.  *   If the current pattern segment contains wildcards, we open the name
  5373.  *   we've accumulated so far (assuming it is really a directory), then read
  5374.  *   each filename in it, and, if it matches the wildcard pattern segment, add
  5375.  *   that filename to what we have so far and call ourselves recursively on the
  5376.  *   next segment.
  5377.  *
  5378.  *   Finally, when no more pattern segments remain, we add what's accumulated
  5379.  *   so far to the result array and increment the number of matches.
  5380.  *
  5381.  * Input: a pattern path list (as generated by splitpath), a string
  5382.  *   pointer that points to what we've traversed so far (this
  5383.  *   can be initialized to "/" to start the search at the root
  5384.  *   directory, or to "./" to start the search at the current
  5385.  *   directory), and a string pointer to the end of the string
  5386.  *   in the previous argument.
  5387.  * Returns: nothing.
  5388.  */
  5389. traverse(pl, sofar, endcur)
  5390. struct path *pl;
  5391. char     *sofar, *endcur;
  5392. {
  5393. }
  5394.  
  5395.  
  5396. /*
  5397.  * addresult:
  5398.  *  Adds a result string to the result array.  Increments the number
  5399.  *  of matches found, copies the found string into our string
  5400.  *  buffer, and puts a pointer to the buffer into the caller's result
  5401.  *  array.  Our free buffer pointer is updated.  If there is no
  5402.  *  more room in the caller's array, the number of matches is set to -1.
  5403.  * Input: a result string.
  5404.  * Returns: nothing.
  5405.  */
  5406.  
  5407. addresult(str)
  5408. char     *str;
  5409. {
  5410. }
  5411.  
  5412.  
  5413. iswild(str)
  5414. char     *str;
  5415. {
  5416.      char     c;
  5417.      if (deblog)
  5418.           debug(F100, "funct: iswild   ", "", 0);
  5419.      while ((c = *str++) != '\0')
  5420.           if (c == '*' || c == '?')
  5421.                return(1);
  5422.      return(0);
  5423. }
  5424.  
  5425.  
  5426. /*
  5427.  * match:
  5428.  *  pattern matcher.  Takes a string and a pattern possibly containing
  5429.  *  the wildcard characters '*' and '?'.  Returns true if the pattern
  5430.  *  matches the string, false otherwise.
  5431.  * by: Jeff Damens, CUCCA
  5432.  *
  5433.  * Input: a string and a wildcard pattern.
  5434.  * Returns: 1 if match, 0 if no match.
  5435.  */
  5436.  
  5437. match(pattern, string)
  5438. char     *pattern, *string;
  5439. {
  5440.      char     *psave, *ssave;   /* back up pointers for failure */
  5441.      psave = ssave = NULL;
  5442.      if (deblog)
  5443.           debug(F100, "funct: matck    ", "", 0);
  5444.      while (1) {
  5445.           for (; *pattern == *string; pattern++, string++)  /* skip first */
  5446.                if (*string == '\0')
  5447.                     return(1); /* end of strings, succeed */
  5448.           if (*string != '\0' && *pattern == '?') {
  5449.                pattern++;   /* '?', let it match */
  5450.                string++;
  5451.           } else if (*pattern == '*') { /* '*' ... */
  5452.                psave = ++pattern;  /* remember where we saw it */
  5453.                ssave = string;  /* let it match 0 chars */
  5454.           } else if (ssave != NULL && *ssave != '\0') { /* if not at end  */
  5455.                /* ...have seen a star */
  5456.                string = ++ssave;  /* skip 1 char from string */
  5457.                pattern = psave;  /* and back up pattern */
  5458.           } else
  5459.                return(0);  /* otherwise just fail */
  5460.      }
  5461. }
  5462.  
  5463.  
  5464. /*  Z P C R D  --  Make a pcard for a CSFILE or a SRCFILE  */
  5465.  
  5466. zpcrd(name)
  5467. char     *name;
  5468. {
  5469.      int     i;
  5470.  
  5471.      pcard[0] = '\0';
  5472.      strcat(pcard, "000000");
  5473.      if ((spur_type == 14) || (spur_type == 15) || (spur_type ==
  5474.          16)) {
  5475.           if (!recv_num && (spur_type == 16))
  5476.                spur_type = 15;
  5477.           strcat(pcard, "P");
  5478.           strcat(pcard, name);
  5479.           for (i = 0; i < (10 - strlen(name)); i++)
  5480.                strcat(pcard, " ");
  5481.           strcat(pcard, language);
  5482.           strcat(pcard, "                ");
  5483.           switch (spur_type) {
  5484.           case 14:
  5485.                strcat(pcard, "       ");
  5486.                break;
  5487.           case 15:
  5488.                strcat(pcard, "PROC-01");
  5489.                break;
  5490.           case 16:
  5491.                strcat(pcard, "PROC-07");
  5492.                break;
  5493.           }
  5494.           strcat(pcard, "                                  ");
  5495.      } else {
  5496.           strcat(pcard, "       ");
  5497.           strcat(pcard, "P");
  5498.           strcat(pcard, name);
  5499.           for (i = 0; i < (10 - strlen(name)); i++)
  5500.                strcat(pcard, " ");
  5501.           strcat(pcard, language);
  5502.           strcat(pcard, "             ");
  5503.           switch (spur_type) {
  5504.           case 10:
  5505.                strcat(pcard, "0");
  5506.                break;
  5507.           case 11:
  5508.                strcat(pcard, "6");
  5509.                break;
  5510.           case 12:
  5511.                strcat(pcard, "7");
  5512.                break;
  5513.           default:
  5514.                strcat(pcard, " ");
  5515.                break;
  5516.           }
  5517.           strcat(pcard, "                                    ");
  5518.      }
  5519. }
  5520.  
  5521.  
  5522. /*  Z S R E C I  --  Gather SPUR records for input  */
  5523.  
  5524. zsreci(n)
  5525. int     n;
  5526. {
  5527.      char     idfield[MAX_FIELD+2];
  5528.      char     line[LINE_LEN];
  5529.      char     tail[TAIL_LEN];
  5530.      char     oldnum[10];
  5531.      int     id_start = spur_info[MAX_SPURTYPE*ID_START + spur_type -1];
  5532.      int     id_len = spur_info[MAX_SPURTYPE*ID_LEN + spur_type -1];
  5533.      int     rec_len = spur_info[MAX_SPURTYPE*REC_LEN + spur_type -1];
  5534.      int     num_field_len =
  5535.      spur_info[MAX_SPURTYPE*NUM_FIELD_LEN + spur_type -1];
  5536.      int     spaces;
  5537.      int     length;
  5538.      int     i;
  5539.  
  5540.      if (deblog)
  5541.           debug(F111, "zsreci: ", "n", n);
  5542.  
  5543.      /****************************************************************
  5544.      *  Initialize the array 'spur_data' and begin to add to this   *
  5545.      *  array the "V-Kermit-prepared" records from the file fp[n].  *
  5546.      ****************************************************************/
  5547.  
  5548.      spur_data[0] = '\0';
  5549.  
  5550.      while (strlen(spur_data) < 315) {
  5551.           if ((spaces = fgetc(fp[n])) == EOF) {
  5552.                if (deblog)
  5553.                    fprintf(stderr, "zsreci: fgetc == EOF\n");
  5554.                return((ferror(fp[n]) == 0) ? 0 : -1);
  5555.           }
  5556.  
  5557.           if (fgets(line, LINE_LEN, fp[n]) == NULL) {
  5558.                errhdlr("zsreci / NULL");
  5559.                fprintf(stderr, "zsreci: fgets == NULL\n");
  5560.                return(-1);
  5561.           }
  5562.  
  5563.           if (lenchk(line, n)) {
  5564.  
  5565.                switch (spur_type) {
  5566.                case 9:
  5567.                case 11:
  5568.                      {
  5569.                          errhdlr("zsreci");
  5570.                          fprintf(stderr, "reading line > %d char\n",
  5571.                                  SRCLNLEN+1);
  5572.                          fprintf(stderr, "line length was %d\n",
  5573.                                           strlen(line));
  5574.                          fprintf(stderr, "%s\n", line);
  5575.                          return(-1);
  5576.                     }
  5577.                default:
  5578.                      {
  5579.                          errhdlr("zsreci");
  5580.                          fprintf(stderr, "reading line > %d char\n",
  5581.                                                                 SRCLNLEN);
  5582.                          fprintf(stderr, "line length was %d\n",
  5583.                                                                 strlen(line));
  5584.                          fprintf(stderr, "%s\n", line);
  5585.                          return(-1);
  5586.                     }
  5587.                }
  5588.  
  5589.           }
  5590.  
  5591.           if (strncmp(line, "000000", 6) == 0) {
  5592.                if (deblog)
  5593.                     fprintf(stderr, "zsreci: Throwing away Pcard.\n");
  5594.                /* throw away the Pcard */
  5595.                continue;
  5596.           }
  5597.  
  5598.      /****************************************************************
  5599.      *  If we get this far, a record was successfully read from the *
  5600.      *  file pointer fp[n].                                         *
  5601.      ****************************************************************/
  5602.  
  5603.           length = rec_len - spaces;
  5604.           if (deblog) {
  5605.                debug(F111, " ", "record length", length);
  5606.                debug(F111, " ", "id start", id_start);
  5607.                debug(F111, " ", "id len", id_len);
  5608.           }
  5609.  
  5610.     /****************************************************************
  5611.      *  If the file has an id field (i.e. id_start != 0), then      *
  5612.      *  copy it into 'idfield' and let 'tail' point to the rest     *
  5613.      *  of the record after the id field.  If there is no id field, *
  5614.      *  let 'tail' point at the remaining record after the line     *
  5615.      *  number field.                                               *
  5616.      ****************************************************************/
  5617.  
  5618.           if (id_start) {
  5619.                strncpy(idfield, &line[id_start], id_len);
  5620.                strcpy(tail, &line[id_start+id_len]);
  5621.                if (deblog)
  5622.                     debug(F111, " id field", idfield, 0);
  5623.           } else {
  5624.                strcpy(tail, &line[HEAD_END]);
  5625.           }
  5626.           if (deblog)
  5627.                debug(F110, " tail", tail, 0);
  5628.  
  5629.     /****************************************************************
  5630.      *  If !send_addnum && ......                                   *
  5631.      *              send_num && !send_renum - use the first six     *
  5632.      *                                        characters of the     *
  5633.      *                                        record.               *
  5634.      *              send_num && send_renum  - replace the first six *
  5635.      *                                        characters of the     *
  5636.      *                                        record with a multi-  *
  5637.      *                                        ple of INCREMENT.     *
  5638.      *              !send_num               - do not use the first  *
  5639.      *                                        six characters of the *
  5640.      *                                        record.               *
  5641.      *     send_addnum                      - Add a multiple        *
  5642.      ****************************************************************/
  5643.  
  5644.           if (!send_addnum) {
  5645.                if (send_num) {
  5646.                     if (send_renum) {
  5647.                          sprintf(line, "%0.*d", num_field_len,
  5648.                                                            linenumber);
  5649.                          if (num_field_len == 5)
  5650.                               strcat(line, " ");
  5651.                          linenumber += INCREMENT;
  5652.                     } else {
  5653.                          line[HEAD_END] = '\0';
  5654.                     }
  5655.                } else {
  5656.                     line[0] = '\0';
  5657.                }
  5658.           } else {
  5659.                strncpy(oldnum, line, HEAD_END);
  5660.                sprintf(line, "%0.*d", num_field_len, linenumber);
  5661.                if (num_field_len == 5)
  5662.                     strcat(line, " ");
  5663.                linenumber += INCREMENT;
  5664.                strncat(line, oldnum, HEAD_END);
  5665.                length += 6;
  5666.           }
  5667.  
  5668.           if (deblog)
  5669.                debug(F110, " line number", line, 0);
  5670.  
  5671.     /****************************************************************
  5672.      *  Add the data to the line.                                   *
  5673.      ****************************************************************/
  5674.  
  5675.           strcat(line, tail);
  5676.  
  5677.     /****************************************************************
  5678.      *  If sending the id field, pad the line with spaces and add   *
  5679.      *  the id field to the end of the line.                        *
  5680.      ****************************************************************/
  5681.  
  5682.           if (send_id) {
  5683.                for (i = length - 6 + ((send_addnum || send_num)
  5684.                    *6); i < (80 - id_len); i++)
  5685.                     line[i] = ' ';
  5686.                line[80-id_len] = '\0';
  5687.                idfield[id_len] = '\n';
  5688.                idfield[id_len+1] = '\0';
  5689.                strcat(line, idfield);
  5690.           } else {
  5691.                line[length-6+((send_addnum || send_num)*6)] =
  5692.                    '\n';
  5693.                line[length-6+((send_addnum || send_num)*6)+1] =
  5694.                    0;
  5695.           }
  5696.           strcat(spur_data, line);
  5697.      }
  5698.      return(1);
  5699. }
  5700.  
  5701.  
  5702. /*  Z S R E C O -- Prepare data to output into SPUR records  */
  5703.  
  5704. zsreco(n)
  5705. int     n;
  5706. {
  5707.      int     id_start = spur_info[MAX_SPURTYPE*ID_START + spur_type - 1];
  5708.      int     id_len = spur_info[MAX_SPURTYPE*ID_LEN + spur_type - 1];
  5709.      int     num_field_len = spur_info[MAX_SPURTYPE*NUM_FIELD_LEN+spur_type-1];
  5710.      char     idfield[10];
  5711.      char     linefield[8];
  5712.      char     record[100];
  5713.      char     data[DATA_LEN];
  5714.      char     temp[DATA_LEN];
  5715.      int     number_len, i, len_char, nulls, data_len = strlen(spur_data);
  5716.  
  5717.     /****************************************************************
  5718.      * Get id field at the end of the line if there is one.         *
  5719.      * If the spur_type has an id field and there are no characters *
  5720.      * in columns (80 - id_len) to 80, the new id field will be     *
  5721.      * spaces.  If recv_id = 0, the new id field will be spaces.    *
  5722.      ****************************************************************/
  5723.  
  5724.      if (deblog) {
  5725.           debug(F111, "zsreco: ", "n", n);
  5726.           debug(F111, " ", "data length", data_len);
  5727.           debug(F111, " ", "id start", id_start);
  5728.           debug(F111, " ", "id len", id_len);
  5729.      }
  5730.  
  5731.      if (id_start) {
  5732.           if ((data_len > 72) && recv_id) {
  5733.                strncpy(idfield, &spur_data[80-id_len], id_len);
  5734.                if ((i = strlen(idfield)) < id_len) {
  5735.                     for (; i < id_len; i++)
  5736.                          idfield[i] = ' ';
  5737.                }
  5738.                idfield[id_len] = '\0';
  5739.           } else {
  5740.                for (i = 0; i < id_len; i++)
  5741.                     idfield[i] = ' ';
  5742.                idfield[id_len] = '\0';
  5743.           }
  5744.           spur_data[80-id_len] = '\0';
  5745.           if (data_len > 6)
  5746.                strncpy(data, &spur_data[NUM_LEN], 80);
  5747.           else
  5748.                data[0] = '\0';
  5749.      } else {
  5750.           idfield[0] = '\0';
  5751.           if (data_len > 6)
  5752.                strcpy(data, &spur_data[NUM_LEN]);
  5753.           else
  5754.                data[0] = '\0';
  5755.      }
  5756.      if (deblog)
  5757.           debug(F110, " id field", idfield, 0);
  5758.  
  5759.    /**********************************************************************
  5760.     * If =>  !recv_addnum && .....                                       *
  5761.     *            recv_num && !recv_renum - Keep the original first six   *
  5762.     *                                      columns from the incoming     *
  5763.     *                                      record.                       *
  5764.     *            recv_num && recv_renum  - Replace the first six columns *
  5765.     *                                      with linenumber and increment *
  5766.     *                                      by the constant INCREMENT.    *
  5767.     *            !recv_num               - Replace the first six columns *
  5768.     *                                      with spaces. (ASCII 0x20)     *
  5769.     *        recv_addnum                 - Insert new line numbers at    *
  5770.     *                                      the beginning of every new    *
  5771.     **********************************************************************/
  5772.  
  5773.      linefield[0] = '\0';
  5774.      if (recv_num && !recv_addnum) {
  5775.           if (recv_renum) {
  5776.                sprintf(linefield, "%0.*d", num_field_len, linenumber);
  5777.                if (num_field_len == 5)
  5778.                     strcat(linefield, " ");
  5779.                linenumber += INCREMENT;
  5780.           } else {
  5781.                strncpy(linefield, spur_data, NUM_LEN);
  5782.                if ((i = strlen(linefield)) < 6) {
  5783.                     for (; i < 6; i++)
  5784.                          strcat(linefield, " ");
  5785.                }
  5786.                linefield[NUM_LEN] = 0;
  5787.           }
  5788.      } else if (recv_addnum) {
  5789.           sprintf(linefield, "%0.*d", num_field_len, linenumber);
  5790.           if (num_field_len == 5)
  5791.                strcat(linefield, " ");
  5792.           linenumber += INCREMENT;
  5793.           strncpy(temp, spur_data, NUM_LEN);
  5794.           temp[NUM_LEN] = '\0';
  5795.           strcat(temp, data);
  5796.           strcpy(data, temp);
  5797.      }
  5798.      if (deblog) {
  5799.           debug(F110, " line number", linefield, 0);
  5800.           debug(F110, " data", data, 0);
  5801.      }
  5802.  
  5803.  
  5804.    /**********************************************************************
  5805.     * peel off the spaces at the end of the remaining data unless we     *
  5806.     * have a Control String or a Procedure file (spur_type=14,15,16)     *
  5807.     **********************************************************************/
  5808.  
  5809.      if ((spur_type == 14) || (spur_type == 15) || (spur_type ==
  5810.          16)) {
  5811.           i = strlen(data);
  5812.           for (; i < (80 - (6 * recv_num)); i++)
  5813.                data[i] = ' ';
  5814.           data[i] = '\0';
  5815.           len_char = 0;
  5816.      } else {
  5817.           i = strlen(data);
  5818.           while (i && (data[i-1] == ' '))
  5819.                i--;
  5820.           data[i] = '\0';
  5821.           if ((!recv_num) && ((i = strlen(data)) < 6)) {
  5822.                for (; i < 6; i++)
  5823.                     strcat(data, " ");
  5824.           }
  5825.           if (recv_num || recv_addnum)
  5826.                number_len = 6;
  5827.           else
  5828.                number_len = 0;
  5829.           len_char = 80 - id_len - strlen(data) - number_len;
  5830.           if (deblog)
  5831.                fprintf(stderr, "zsreco: len_char = %d.\n",
  5832.                    len_char);
  5833.  
  5834.    /****************************************************************
  5835.     * The following must be done since we can not output the ASCII *
  5836.     * characters 0x09 and 0x0a                                     *
  5837.     ****************************************************************/
  5838.  
  5839.           if (len_char == 9) {
  5840.  
  5841.                if (deblog)
  5842.                     fprintf(stderr, "zsreco: app 1 (0x20) on rec end.\n");
  5843.  
  5844.                strcat(data, " ");
  5845.                len_char = 8;
  5846.  
  5847.                if (deblog)
  5848.                     fprintf(stderr, "zsreco: len_char is now %d.\n",
  5849.                                                  len_char);
  5850.  
  5851.           }
  5852.           if (len_char == 10) {
  5853.                if (deblog)
  5854.                     fprintf(stderr, "zsreco: app 2 (0x20) on rec end.\n");
  5855.                strcat(data, "  ");
  5856.                len_char = 8;
  5857.                if (deblog)
  5858.                     fprintf(stderr, "zsreco: len_char is now %d.\n",
  5859.                                                  len_char);
  5860.           }
  5861.      }
  5862.  
  5863.      /* output the space character to column 1 */
  5864.      fputc(len_char, fp[n]);
  5865.      if (ferror(fp[n]) != 0) {
  5866.           errhdlr("zsrceo");
  5867.           fprintf(stderr, "write error: zsrceo len_char\n");
  5868.           return(-1);
  5869.      }
  5870.  
  5871.      /* build the record and output it */
  5872.      record[0] = '\0';
  5873.      if (recv_num || recv_addnum)
  5874.           strcat(record, linefield);
  5875.      else
  5876.           strncat(record, data, NUM_LEN);
  5877.      switch (spur_type) {
  5878.      case 9:
  5879.      case 11:
  5880.           nulls = 2;
  5881.           break;
  5882.      case 12:
  5883.           nulls = 1;
  5884.           break;
  5885.      default:
  5886.           nulls = 0;
  5887.      }
  5888.      for (i = 0; i < nulls; i++)
  5889.           strcat(record, " ");
  5890.      strcat(record, idfield);
  5891.      if (recv_num || recv_addnum)
  5892.           strcat(record, data);
  5893.      else
  5894.           strcat(record, &data[NUM_LEN]);
  5895.  
  5896.      return(zsoutl(n, record));
  5897.  
  5898. }
  5899.  
  5900.  
  5901. /* E R R H D L R - errhdlr for all unpleasant outcomes
  5902.                    PEG May 14, 1990
  5903. */
  5904.  
  5905. void errhdlr(wherefrm)
  5906. char     *wherefrm;
  5907. {
  5908.      char     s[90];
  5909.      long     errclk;
  5910.      int      geterr = errno;         /* we grab the error number
  5911.                                          due the timestamp fprintf
  5912.                                          setting errno to EMINR
  5913.                                          May 22, 1990              */
  5914.  
  5915.      /* time stamp stderr output */
  5916.      /* May 4, 1990              */
  5917.  
  5918.      errclk = time((long *) 0);
  5919.      fprintf(stderr, "\n%s", ctime(&errclk));
  5920.  
  5921. /* we do not want to print anymore EMINR messages */
  5922.  
  5923.      if ((geterr) && (geterr != EMINR)) {
  5924.           sprintf(s, "%s: %s", wherefrm, sys_errlist[geterr]);
  5925.           perror(wherefrm);
  5926.           if (!server)
  5927.                screen(SCR_EM, 0, 0l, s);
  5928.           else
  5929.                errpkt(s);
  5930.           errno = 0;
  5931.           return;
  5932.      } else {
  5933.           sprintf(s, "Error occured: %s", wherefrm);
  5934.           fprintf(stderr, "%s\n", s);
  5935.           if (!server)
  5936.                screen(SCR_EM, 0, 0l, s);
  5937.           else
  5938.                errpkt(s);
  5939.           errno = 0;
  5940.           return;
  5941.      }
  5942. } /* errhdlr end */
  5943.  
  5944.  
  5945. /* L E N C H K - lenchk: checks spur records after read or
  5946.                          before right to verify that they do not
  5947.                          exceed maximum values defined by SRCLNLEN
  5948.                                                                     */
  5949. int     lenchk(s, n)
  5950. char     *s;            /* string ptr for examing line length */
  5951. int     n;             /* file number... index into fp[]  */
  5952. {
  5953.  
  5954.      if ((n != ZIFILE && n != ZOFILE) || binary)
  5955.           return(0);
  5956.  
  5957.      if ((*file_type == 'C') || (*file_type == 'S')) {
  5958.  
  5959.           switch (spur_type) {
  5960.           case 9:
  5961.           case 11:
  5962.                 {
  5963.                     if (strlen(s) > SRCLNLEN + 1)
  5964.                          return (-1);
  5965.                     else
  5966.                          return(0);
  5967.                }
  5968.           default:
  5969.                 {
  5970.                     if (strlen(s) > SRCLNLEN)
  5971.                          return (-1);
  5972.                     else
  5973.                          return(0);
  5974.                }
  5975.           }
  5976.  
  5977.      } else
  5978.           return(0);
  5979.  
  5980. } /* end lenchk */
  5981.  
  5982.  
  5983. /* R E S E T O P E N resetopen: closes ZOFILE or ZIFILE left open
  5984.                                 from previous aborted file transfers
  5985.                                 May 30, 1990
  5986.                                                                      */
  5987.  
  5988. void resetopen()
  5989. {
  5990.   int n;
  5991.  
  5992.      if ((fp[ZOFILE] == NULL) && (fp[ZIFILE] == NULL))
  5993.          return;
  5994.  
  5995.      if (fp[ZOFILE] != NULL)
  5996.          n = ZOFILE;
  5997.      else
  5998.          n = ZIFILE;
  5999.  
  6000.      if (objopen) {              /* March 12, 1990 */
  6001.                if (voclose(n) == 0) {
  6002.                    if ((!keep) && (n == ZOFILE)) {
  6003.                          if (unlink(fn_temp) != 0) {
  6004.                               errhdlr("resetopen UNLINK");
  6005.                               fprintf(stderr, "unlink failed %s\n",
  6006.                                       fn_temp);
  6007.                          }
  6008.                     }
  6009.                }
  6010.                objopen = CLOSE;
  6011.      }
  6012.      else {
  6013.                if (fclose(fp[n]) == EOF) {
  6014.                   errhdlr("resetopen fclose error");
  6015.                   fprintf(stderr,"file name: %s\n",fn_temp);
  6016.                }
  6017.  
  6018.                if ((!keep) && (n == ZOFILE))
  6019.                     if (unlink(fn_temp) != 0) {
  6020.                          errhdlr("resetopen UNLINK");
  6021.                          fprintf(stderr, "unlink failed %s\n",
  6022.                                  fn_temp);
  6023.                     }
  6024.      }
  6025.      strcpy(fn_temp, "\0");
  6026.      fp[n] = NULL;
  6027.      return;
  6028. }
  6029. <<< ckvfio.c >>>
  6030. /* C K V F I O      object module transfer      */
  6031.  
  6032. /**********************************************************************
  6033. *                                                                     *
  6034. * IVS / MCS-Kermit REL 2                                              *
  6035. * source code                                                         *
  6036. *                                                                     *
  6037. * Change History:                                                     *
  6038. *                                                                     *
  6039. *                1. Modify C-Kermit(4E) source code to                *
  6040. *                   produce new module for MCS/IVS-Kermit             *
  6041. *                   ORIGINAL RELEASE                                  *
  6042. *                   June 22, 1990                                     *
  6043. *                                                                     *
  6044. *                                                                     *
  6045. ***********************************************************************/
  6046.  
  6047. /*
  6048.    update May 10, 1990
  6049.    PEG
  6050.    Modified error handling
  6051.    to reflect changes to
  6052.    other modules to use
  6053.    errhdlr()
  6054.  
  6055.    update May 23, 1990
  6056.    OBJECT FILE message flawed
  6057.    PEG
  6058.  
  6059.   VKOFIO - Object file I/O for VKERMIT.
  6060.   This module interfaces to and does buffering for
  6061.   VRX/E object files.
  6062.  
  6063.   In order for object file transfer to work, the file type must be
  6064.   set to binary for both sides of the kermit file transfer. No translation
  6065.   of CR or LF can be allowed.
  6066.  
  6067.   Vkermit can only receive and create object files which have been
  6068.   sent previously by vkermit. It cannot handle object files transferred
  6069.   to the remote system by some other means. Nor is the format of a vkermit
  6070.   sent object file suitable for ANY use other than being transferred back
  6071.   to a VRX system by vkermit.
  6072.  
  6073.   FCL is necessary to properly open the object file. The default file
  6074.   reference name is OBJFILE.
  6075.   The VRX file type must be set to object and the record size must be set
  6076.   to 1/490.
  6077.  
  6078.   The following routines are to be called by the ckufio module
  6079.   when it detects that a VRX object file is being transported.
  6080.     voopeni - to open an object file for input (download)
  6081.               Called by zopeni.
  6082.     voopeno - to open an object file for output (upload)
  6083.               Called by zopeno.
  6084.     vogetc - to get the next character from a VRX object file.
  6085.              Called by zchin.
  6086.     voputc - to put the next character to a vrx object.
  6087.              Called by zchout.
  6088.     voclose - to close a VRX object file. Called by zclose.
  6089.  
  6090.   This module contains data structures to buffer the characters
  6091.   and keep track of the object file(s) currently open.
  6092.   In this implementation, there is only one VRX object file open
  6093.   at a time.
  6094.  
  6095.   Since VRX object files are variable length, a two byte VLI is
  6096.   prepended to each data record. This module creates the VLI for
  6097.   downloading and interprets the VLI for uploading. The rest of
  6098.   kermit does not even know these VLIs are there and treats them
  6099.   as data. Since binary file type transfer is being used, the non-ASCII
  6100.   nature of these VLIs is unimportant.
  6101.  
  6102.   Using VLIs as part of the data stream is the only way to recreate
  6103.   the object file on VRX. Object files must be written with variable
  6104.   length records. When an object file is written, the VLI is stripped
  6105.   off of the buffer and the rest of the buffer is written as the record.
  6106.   The implicit length of the string determines the record size and VRX
  6107.   file management takes care of the internals necessary for variable
  6108.   length records.
  6109.  
  6110.   Although buffering is done by this module, the actual I/O's
  6111.   are done by a separate module written in NCRL which uses
  6112.   NCRL IO.
  6113.  */
  6114. #include <stdio.h>
  6115. #include "ckcker.h"              /* March 2, 1990 */
  6116. #include <errno.h>
  6117.  
  6118. /*
  6119.  * Constants used by this module
  6120.  */
  6121.  
  6122. /*
  6123.    *  Errors returned by NCRL I/O service routines
  6124.    */
  6125. #define NIOOK    0
  6126. #define NIOBAD   1
  6127. #define NIOEOF   2
  6128.  
  6129. /*
  6130.    *  Sizes of various structures and strings
  6131.    */
  6132. #define LEGRECSIZ 200        /* The size of the NCRL legible type */
  6133. /* Actual size is probably less - e.g.
  6134.                                 134 bytes on 4-85, but the size is
  6135.                                 not guaranteed to remain constant from
  6136.                                 release to release. */
  6137. #define MAXOBJDAT 490        /* Max size of object record data  */
  6138. #define REFSIZ 31            /* Standard size for VRX file reference */
  6139. #define OBJREFSIZ 7          /* Size of default reference name */
  6140. #define VLISIZE 2            /* The size of the added VLIs */
  6141. #define MAXOBJREC MAXOBJDAT+VLISIZE  /* The maximum size of the
  6142.                                         buffer used for objects
  6143.                                         including the vli * /
  6144.  
  6145. /* dummy type for access() */
  6146.  
  6147. #define file_EXIST 0
  6148.  
  6149. /*
  6150.  * Types declared for this module
  6151.  */
  6152.  
  6153. /* legible - This is an NCRL type used for I/O.  */
  6154. typedef char     legible[LEGRECSIZ];
  6155.  
  6156. /* objrec - This type allows access of the buffer
  6157.    as a string and also direct reference of the VLI and data
  6158.    portions of the buffer. The NCRL IO routines actually
  6159.    fill in the VLI and data, but this module must have access
  6160.    of the number of bytes in order to determine when a new
  6161.    record must be read or written.
  6162.   */
  6163. typedef union objrec {
  6164.      char     buffer[MAXOBJREC];
  6165.      struct {
  6166.           short     vli;       /* does not include size of the vli itself */
  6167.           /* must be on a two byte boundary          */
  6168.           char     data[MAXOBJREC - VLISIZE];
  6169.      } vlianddata;
  6170. };
  6171.  
  6172. /*
  6173.    * This series of types is declared so that variable length strings
  6174.      can be passed to an NCRL routine. A NCRL string consists of
  6175.      a four byte length indicator and a pointer to the text of the
  6176.      string. The C strings passed as parameters must be translated
  6177.      into this form in order for NCRL IO to work properly.
  6178.  
  6179.    NCRLptr - a definition of NCRL's 3 byte pointers.
  6180.    ptr_param - a definition of the 4 byte pointer format of NCRL
  6181.      pointers used when passing pointers as parameters (the first
  6182.      byte is ignored as serves only to align the pointer).
  6183.    c2vrx_ptr - a union constructs that allows casting of integers
  6184.      into the four byte pointer format.
  6185.    ncrl_string - a definition of NCRL variable strings as a four
  6186.      byte length and a four byte pointer.
  6187.   */
  6188. struct NCRLptr {
  6189.      char     byte1;
  6190.      char     byte2;
  6191.      char     byte3;
  6192. };
  6193.  
  6194. struct ptr_param {
  6195.      char     zero_fill;
  6196.      struct NCRLptr ptr;
  6197. };
  6198.  
  6199. union c2vrx_ptr {
  6200.      int     *int_ptr;
  6201.      struct ptr_param ncr_ptr;
  6202. };
  6203.  
  6204. struct ncrl_string {
  6205.      int     len;
  6206.      union c2vrx_ptr ptr;
  6207. };
  6208.  
  6209. /*
  6210.  * Global variables -
  6211.  *  These variables are directly referenced only be this module but
  6212.  *  must retain their values until changed (if at all) by this module.
  6213.  */
  6214.  
  6215. /* objref - The default reference name. A different reference name
  6216.    can be passed in as part of the name parameter of the open routines.
  6217.    An FCL file reference must be used on the invocation of vkermit in
  6218.    order to open the file correctly.
  6219.   */
  6220. char     objref[OBJREFSIZ+1] = "OBJFILE";  /* The default reference name */
  6221. union objrec buf;                      /* The buffer used for object IO */
  6222. struct ncrl_string buffer_string;      /* The NCRL string used to pass the
  6223.                                        buffer to the NCRL IO routines
  6224.                                        (see discussion under types).  */
  6225. int     nBufSiz, nBufNdx;        /* Current buffer size (including VLI)
  6226.                                 and current char in buffer being accessed */
  6227. legible objf;                /* The object file definition structure
  6228.                              The legible construct is filled in by the
  6229.                              NCRL OPEN and is then used to refer to the
  6230.                              file for all subsequent IO operations.  */
  6231. /* There is only ONE object file open at a time */
  6232.  
  6233. /*
  6234.  * Declaration of all procedures in the NCRL IO service module.
  6235.  * This module must be compiled with COPT='-Xv' to avoid
  6236.  * adding an additional return parameter to these void declared
  6237.  * procedures.
  6238.  */
  6239. extern void OBJOPENI();
  6240. extern void OBJOPENO();
  6241. extern void OBJCLOSE();
  6242. extern void OBJRECIN();      /* Reads an entire object record, prepending data
  6243.                              with a VLI. */
  6244. extern void OBJRECOUT();     /* Writes one variable record */
  6245.  
  6246. extern int     errhdlr();
  6247. extern int     access();
  6248. int            ERRCELL;     /* set in VKNCRLIO by bad vrxoutcome    */
  6249.  
  6250. /* forward procedure declaration */
  6251. setupvbuf();
  6252.  
  6253. voopeni(n, in_name)
  6254. int     n;      /* file number*/
  6255. char     *in_name;
  6256. /*
  6257.  voopeni - prepare for open of VRX object file by NCRL I/O
  6258.  refandname may be of the form "fileref(NAME=filename)" or may
  6259.  just contain the file name. If the complex form is present,
  6260.  it must be broken into its components for usage by NCRL I/O.
  6261.  The n parameter is the file number and is ignored since only one
  6262.  object file is opened at a time.
  6263.  
  6264.  Return values:
  6265.    0 if open successful
  6266.    -1 if unsuccessful
  6267. */
  6268. {
  6269.      char     result;
  6270.      struct ncrl_string ncrl_name, ncrl_refname;
  6271.      char     name[REFSIZ+1];
  6272.      char     refname[REFSIZ+1];
  6273.      char     refandname[REFSIZ+4];
  6274.      char     *temp;
  6275.      int     i;
  6276.  
  6277.      /* before we go through several levels of code, parsing
  6278.      the final file name, etc, etc. Let's save some processing
  6279.      time and some nasty errors by verifying the file is
  6280.      present. In order for this to work the FCL reference
  6281.      OBJFILE must exist. Otherwise we maybe back at square one.
  6282.  
  6283.      PEG March 7, 1990
  6284.                                                                 */
  6285.  
  6286.      if (in_name != NULL)
  6287.         strcpy(refandname,in_name);
  6288.      else
  6289.         return(-1);
  6290.  
  6291.      if ((i = access(refandname, file_EXIST)) != 0)
  6292.           return(-1);
  6293.  
  6294.      if (in_name != NULL)
  6295.         strcpy(refandname,in_name);
  6296.      else
  6297.         return(-1);
  6298.  
  6299.      /* determine type of format of refandname and parse it */
  6300.      if ((temp = strrchr(refandname, ')')) != NULL) {
  6301.                                                            /* complex form */
  6302.                                             /* eliminate final parenthesis */
  6303.           temp[0] = '\0';
  6304.           if ((temp = strrchr(refandname, '=')) != NULL) {
  6305.                                    /* now temp points just before file name */
  6306.                temp++;
  6307.                strcpy(name, temp);
  6308.                                          /* continue to parse for refname */
  6309.                if ((temp = strchr(refandname, '(')) != NULL) {
  6310.                     /* eliminate first parenthesis - what is left is refname */
  6311.                     temp[0] = '\0';
  6312.                     strcpy(refname, refandname);
  6313.                } else {
  6314.                                                               /* error! */
  6315.                     errhdlr("voopeni");
  6316.                     fprintf(stderr,"voopeni: name format1 error: %s",
  6317.                               refandname);
  6318.                     return(-1);
  6319.                }
  6320.           } else {
  6321.                                                               /* error ! */
  6322.                errhdlr("voopeni");
  6323.                fprintf(stderr, "name format2 error: %s",
  6324.                     refandname);
  6325.                return(-1);
  6326.           }
  6327.      } else {
  6328.           /* must be in simple format -
  6329.        use parameter as filename and use default refname
  6330.     */
  6331.           strcpy(name, refandname);
  6332.           strcpy(refname, objref);
  6333.      }
  6334.      ncrl_name.len = strlen(name);
  6335.      ncrl_name.ptr.int_ptr = (int *) name;
  6336.      ncrl_refname.len = strlen(refname);
  6337.      ncrl_refname.ptr.int_ptr = (int *) refname;
  6338.      OBJOPENI(&ncrl_name, &ncrl_refname, objf, &result);
  6339.  
  6340.      if (result != NIOOK) {
  6341.           /*
  6342.                               When a lousy outcome is returned from
  6343.                               VKNCRLIO we output an error message
  6344.                               PEG March 6, 1990
  6345.                            */
  6346.  
  6347.       errhdlr("voopeni");
  6348.           fprintf(stderr, "objfile (i)open failure outcome: %d\n", ERRCELL);
  6349.           return(-1);
  6350.  
  6351.      }
  6352.  
  6353.      setupvbuf();
  6354.      return(0);
  6355. }
  6356.  
  6357.  
  6358. voopeno(n, in_name)
  6359. int     n;      /* file number*/
  6360. char     *in_name;
  6361. /*
  6362.  voopeno - prepare for open of VRX object file by NCRL I/O
  6363.  refandname may be of the form "fileref(NAME=filename)" or may
  6364.  just contain the file name. If the complex form is present,
  6365.  it must be broken into its components for usage by NCRL I/O.
  6366.  The n parameter is the file number and is ignored since file numbers
  6367.  are not used when files are opend by NCRL IO.
  6368.  
  6369.  Return values:
  6370.    0 if open successful
  6371.    -1 if unsuccessful
  6372. */
  6373. {
  6374.      char     result;
  6375.      struct ncrl_string ncrl_name, ncrl_refname;
  6376.      char     name[REFSIZ+1];
  6377.      char     refname[REFSIZ+1];
  6378.      char     refandname[REFSIZ+1];
  6379.      char     *temp;
  6380.  
  6381.      if (in_name  != NULL)
  6382.         strcpy(refandname,in_name);
  6383.      else
  6384.         return(-1);
  6385.  
  6386.      /* determine type of format of refandname and parse it */
  6387.      if ((temp = strrchr(refandname, ')')) != NULL) {
  6388.           /* complex form */
  6389.           /* eliminate final parenthesis */
  6390.           temp[0] = '\0';
  6391.           if ((temp = strrchr(refandname, '=')) != NULL) {
  6392.                /* now temp points just before file name */
  6393.                temp++;
  6394.                strcpy(name, temp);
  6395.                /* continue to parse for refname */
  6396.                if ((temp = strchr(refandname, '(')) != NULL) {
  6397.                     /* eliminate first parenthesis - what is left is refname */
  6398.                     temp[0] = '\0';
  6399.                     strcpy(refname, refandname);
  6400.                } else {
  6401.                                                          /* error! */
  6402.                     errhdlr("voopeno");
  6403.                     fprintf(stderr, "name format1 error: %s\n",
  6404.                          refandname);
  6405.                     return(-1);
  6406.                }
  6407.           } else {
  6408.                                                             /* error ! */
  6409.                errhdlr("voopeno");
  6410.                fprintf(stderr, "name format2 error: %s\n",
  6411.                     refandname);
  6412.                return(-1);
  6413.           }
  6414.      } else {
  6415.           /* must be in simple format -
  6416.          use parameter as filename and use default refname
  6417.                                                                 */
  6418.           strcpy(name, refandname);
  6419.           strcpy(refname, objref);
  6420.      }
  6421.      ncrl_name.len = strlen(name);
  6422.      ncrl_name.ptr.int_ptr = (int *) name;
  6423.      ncrl_refname.len = strlen(refname);
  6424.      ncrl_refname.ptr.int_ptr = (int *) refname;
  6425.  
  6426.      OBJOPENO(&ncrl_name, &ncrl_refname, objf, &result);
  6427.  
  6428.      if (result != NIOOK) {
  6429.           /*
  6430.                               When a lousy outcome is returned from
  6431.                               VKNCRLIO we output an error message
  6432.                               PEG March 6, 1990
  6433.                            */
  6434.  
  6435.           errhdlr("voopeno");
  6436.           fprintf(stderr,"object (o)file failure outcome: %d\n",ERRCELL);
  6437.           return(-1);
  6438.      }
  6439.  
  6440.      setupvbuf();
  6441.      return(0);
  6442. }
  6443.  
  6444.  
  6445. setupvbuf()
  6446. {
  6447.      /* SETUPVBUF -
  6448.  *  Initialize buffer variables in preparation for IO
  6449.  */
  6450.      buffer_string.len = MAXOBJREC;
  6451.      buffer_string.ptr.int_ptr = (int *) & buf;
  6452.      nBufSiz = nBufNdx = 0;
  6453. }
  6454.  
  6455.  
  6456. /* VOGETC -
  6457.  *  Return the next characters from the object file.
  6458.  *  In most cases, this just returns the next character in the object
  6459.  *  record buffer. When the last character in the buffer has been
  6460.  *  used, objrecin is called to read in another record. Note that
  6461.  *  the VLI itself is returned to the caller as part of the data.
  6462.  *  The calling kermit routine does not need to know this.
  6463.  *  The VLI must be made part of the data in order to reconstruct
  6464.  *  an object file when the file is later received by vkermit (see voputc).
  6465.  *
  6466.  *  Return values:
  6467.  *    -1 if error or EOF
  6468.  *    otherwise the character read
  6469.  */
  6470. vogetc(n)
  6471. int     n;
  6472. {
  6473.      char     result;
  6474.  
  6475.      if (nBufNdx < nBufSiz) {
  6476.           nBufNdx++;
  6477.           return(buf.buffer[nBufNdx-1]);
  6478.      } else {
  6479.           /* get new buffer */
  6480.           OBJRECIN(objf, &buffer_string, &nBufSiz, &result);
  6481.  
  6482.           if (result != NIOOK) {
  6483.                if (result != NIOEOF) {
  6484.                     /*
  6485.                               When a lousy outcome is returned from
  6486.                               VKNCRLIO we output an error message
  6487.                               PEG March 6, 1990
  6488.                            */
  6489.  
  6490.                     errhdlr("vogetc");
  6491.                     fprintf(stderr,"READ FAILURE OUTCOME: %d\n",ERRCELL);
  6492.                     return(-1);
  6493.  
  6494.                } else /* end of file */
  6495.                     return(-1);               /* DRE 030990 */
  6496.  
  6497.           } else {  /* good i-o */
  6498.  
  6499.                if (buf.vlianddata.vli > MAXOBJDAT) {  /* March 2, 1990  */
  6500.  
  6501.                     char errbuf[40];
  6502.  
  6503.                     sprintf(errbuf,"vogetc: obj vli exceeds max: %#X",
  6504.                             buf.vlianddata.vli);
  6505.                     errhdlr(errbuf);
  6506.                     fprintf(stderr,"current vli maximum: %#X\n", MAXOBJDAT);
  6507.                     return(-1);
  6508.                }
  6509.  
  6510.                nBufNdx = 1;
  6511.                nBufSiz += VLISIZE;
  6512.                return(buf.buffer[0]);
  6513.           }
  6514.      }
  6515. }
  6516.  
  6517.  
  6518. /* VOPUTC -
  6519.  *  Put a single character into the destination object file.
  6520.  *  The first two characters are used to calculate the size of
  6521.  *  the record next to be written. When that many characters have
  6522.  *  been transferred into the buffer, the buffer is written using
  6523.  *  OBJRECOUT. A ncrl_string type must be used to create a string
  6524.  *  with a known (to NCRL) length.
  6525.  *
  6526.  *  Return values:
  6527.  *    0 if successful
  6528.  *   -1 if failure
  6529.  */
  6530. voputc(c, n)
  6531. char     c;
  6532. int     n;
  6533. {
  6534.      char     result;
  6535.  
  6536.      /* check if we just got a full vli */
  6537.      if (nBufNdx == 1) {
  6538.           /*calculate size of record to write */
  6539.           /* Note that the buffer size includes the size of the VLI
  6540.              but the VLI itself does not include the size of the VLI */
  6541.           buf.buffer[1] = c;
  6542.  
  6543.           if (buf.vlianddata.vli > MAXOBJDAT) {  /* March 2, 1990  */
  6544.  
  6545.                     char errbuf[40];
  6546.  
  6547.                     sprintf(errbuf,"voputc: obj vli exceeds max: %#X",
  6548.                             buf.vlianddata.vli);
  6549.                     errhdlr(errbuf);
  6550.                     fprintf(stderr,"current vli maximum: %#X\n", MAXOBJDAT);
  6551.                     return(-1);
  6552.  
  6553.           }
  6554.  
  6555.           nBufSiz = buf.vlianddata.vli + VLISIZE;
  6556.      }
  6557.      buf.buffer[nBufNdx] = c;   /* when nBufNdx = 1 c is written twice */
  6558.      nBufNdx++;
  6559.      if (nBufNdx >= nBufSiz) {
  6560.           /* clear the current buffer by writing it out */
  6561.           /* unless it is the first time */
  6562.  
  6563.           if (nBufSiz > 0) {                          /* March 2, 1990 */
  6564.                OBJRECOUT(objf, &buffer_string, &result);
  6565.  
  6566.                if (result != NIOOK) {
  6567.  
  6568.                     /*
  6569.                               When a lousy outcome is returned from
  6570.                               VKNCRLIO we output an error message
  6571.                               PEG March 6, 1990
  6572.                            */
  6573.                     errhdlr("voputc");
  6574.                     fprintf(stderr,"write failure outcome: %d\n",ERRCELL);
  6575.                     return(-1);
  6576.  
  6577.                }
  6578.  
  6579.                nBufNdx = 0;
  6580.                /* Note actual size of buffer is not calculated until
  6581.                   second byte arrives. */
  6582.           }
  6583.      }
  6584.      return(0);
  6585. }
  6586.  
  6587.  
  6588. voclose(n)
  6589. int     n;
  6590. {
  6591.      char     result;
  6592.  
  6593.      OBJCLOSE(objf, result);
  6594.      if (result == NIOBAD) {    /*
  6595.                               When a lousy outcome is returned from
  6596.                               VKNCRLIO we output an error message
  6597.                               PEG March 6, 1990
  6598.                                   */
  6599.  
  6600.           errhdlr("voclose");
  6601.           fprintf(stderr,"error closing file outcome: %d\n",ERRCELL);
  6602.           return(-1);
  6603.      }
  6604.      else return(0);
  6605. }
  6606. <<< ckvfn2.c >>>
  6607. /*  C K v F N 2  --  System-independent Kermit protocol support functions... */
  6608.  
  6609. /**********************************************************************
  6610. *                                                                     *
  6611. * IVS / MCS-Kermit REL 2                                              *
  6612. * source code                                                         *
  6613. *                                                                     *
  6614. * Change History:                                                     *
  6615. *                                                                     *
  6616. *                1. Modify C-Kermit(4E) source code to                *
  6617. *                   produce new module for MCS/IVS-Kermit             *
  6618. *                   ORIGINAL RELEASE                                  *
  6619. *                   June 22, 1990                                     *
  6620. *                                                                     *
  6621. *                                                                     *
  6622. ***********************************************************************/
  6623.  
  6624.  
  6625. /*  ...Part 2 (continued from ckcfns.c)  */
  6626.  
  6627. /*
  6628.  Author: Frank da Cruz (fdc@cunixc.cc.columbia.edu, FDCCU@CUVMA.BITNET),
  6629.  Columbia University Center for Computing Activities.
  6630.  First released January 1985.
  6631.  Copyright (C) 1985, 1989, Trustees of Columbia University in the City of New
  6632.  York.  Permission is granted to any individual or institution to use, copy, or
  6633.  redistribute this software so long as it is not sold for profit, provided this
  6634.  copyright notice is retained.
  6635. */
  6636.  
  6637. /*
  6638.  Note -- if you change this file, please amend the version number and date at
  6639.  the top of ckcfns.c accordingly.
  6640. */
  6641.  
  6642. #include <time.h>
  6643. #include "ckcsym.h"             /* Conditional compilation (for Macintosh) */
  6644. #include "ckcker.h"
  6645. #include "ckcdeb.h"
  6646.  
  6647. extern long time();
  6648. extern int     spsiz, rpsiz, timint, npad, ebq, ebqflg, rpt, rptq, rptflg,
  6649.                capas;
  6650. extern int     osize, pktnum, prvpkt, sndtyp, bctr, bctu, rsn, rln, maxtry,
  6651.                size;
  6652. extern int     maxsize, spktl, nfils, stdouf, /* warn,*/  timef, parity,
  6653.                speed;
  6654. extern int     turn, turnch,  delay, displa, pktlog, tralog, seslog, xflg,
  6655.                mypadn, userpad;
  6656. extern int     deblog, hcflg, binary, fncnv, local, server, cxseen, czseen;
  6657. extern long    filcnt, ffc, flci, flco, tlci, tlco, tfc, fsize;
  6658. extern char    *cmarg, *cmarg2, **cmlist;
  6659. extern CHAR    padch, mypadc, eol, seol, ctlq, myctlq, sstate, *hlptxt;
  6660. extern CHAR    filnam[], sndpkt[], recpkt[], data[], srvcmd[];
  6661. extern CHAR    *srvptr, stchr, mystch, *rdatap;
  6662.  
  6663. char     *strcpy();                         /* Forward declarations */
  6664. unsigned int     chk2();                    /* of non-int functions */
  6665. unsigned int     chk3();
  6666. CHAR dopar();                           /* ... */
  6667.  
  6668. static CHAR partab[] = {                /* Even parity table for dopar() */
  6669.  
  6670.      '\000', '\201', '\202', '\003', '\204', '\005', '\006', '\207',
  6671.              '\210', '\011', '\012', '\213', '\014', '\215', '\216',
  6672.          '\017',
  6673.      '\220', '\021', '\022', '\223', '\024', '\225', '\226', '\027',
  6674.              '\030', '\231', '\232', '\033', '\234', '\035', '\036',
  6675.          '\237',
  6676.      '\240', '\041', '\042', '\243', '\044', '\245', '\246', '\047',
  6677.              '\050', '\251', '\252', '\053', '\254', '\055', '\056',
  6678.          '\257',
  6679.      '\060', '\261', '\262', '\063', '\264', '\065', '\066', '\267',
  6680.              '\270', '\071', '\072', '\273', '\074', '\275', '\276',
  6681.          '\077',
  6682.      '\300', '\101', '\102', '\303', '\104', '\305', '\306', '\107',
  6683.              '\110', '\311', '\312', '\113', '\314', '\115', '\116',
  6684.          '\317',
  6685.      '\120', '\321', '\322', '\123', '\324', '\125', '\126', '\327',
  6686.              '\330', '\131', '\132', '\333', '\134', '\335', '\336',
  6687.          '\137',
  6688.      '\140', '\341', '\342', '\143', '\344', '\145', '\146', '\347',
  6689.              '\350', '\151', '\152', '\353', '\154', '\355', '\356',
  6690.          '\157',
  6691.      '\360', '\161', '\162', '\363', '\164', '\365', '\366', '\167',
  6692.              '\170', '\371', '\372', '\173', '\374', '\175', '\176',
  6693.          '\377'
  6694. };
  6695.  
  6696.  
  6697. /* CRC generation tables */
  6698.  
  6699. static unsigned int     crcta[16] = {
  6700.      0, 010201, 020402, 030603, 041004,
  6701.      051205, 061406, 071607, 0102010, 0112211, 0122412, 0132613,
  6702.          0143014,
  6703.      0153215, 0163416, 0173617};
  6704.  
  6705.  
  6706. static unsigned int     crctb[16] = {
  6707.      0, 010611, 021422, 031233, 043044,
  6708.      053655, 062466, 072277, 0106110, 0116701, 0127532, 0137323,
  6709.      0145154, 0155745, 0164576, 0174367};
  6710.  
  6711.  
  6712. /*  I N P U T  --  Attempt to read packet number 'pktnum'.  */
  6713.  
  6714. /*
  6715.  This is the function that feeds input to Kermit's finite state machine.
  6716.  
  6717.  If a special start state is in effect, that state is returned as if it were
  6718.  the type of an incoming packet.  Otherwise:
  6719.  
  6720.  . If the desired packet arrives within MAXTRY tries, return its type,
  6721.    with its data stored in the global 'data' array.
  6722.  
  6723.  . If the previous packet arrives again, resend the last packet and wait for
  6724.    another to come in.
  6725.  
  6726.  . If the desired packet does not arrive within MAXTRY tries, return indicating
  6727.    that an error packet should be sent.
  6728. */
  6729.  
  6730. input()
  6731. {
  6732.      int     type, numtry;
  6733.  
  6734.      if (sstate != 0) {                  /* If a start state is in effect, */
  6735.           type = sstate;                  /* return it like a packet type, */
  6736.           sstate = 0;                     /* and then nullify it. */
  6737.           return(type);
  6738.      } else
  6739.           type = rpack();              /* Else, try to read a packet. */
  6740.  
  6741.      if (deblog)
  6742.           debug(F111, "input", rdatap, type);
  6743.  
  6744.      /* If it's the same packet we just sent, it's an echo.  Read another. */
  6745.  
  6746.      if (type == sndtyp)
  6747.           type = rpack();
  6748.  
  6749.      chkint();                           /* Check for console interrupts. */
  6750.      /*
  6751.  If previous packet again, a timeout pseudopacket, or a bad packet, try again.
  6752. */
  6753.      for (numtry = 0;  (rsn == prvpkt || type == 'T' || type == 'Q' ||
  6754.          type == 'N');  numtry++) {
  6755.           if (numtry > maxtry) {           /* If too many tries, give up */
  6756.                strcpy(data, "Timed out."); /* and send a timeout */
  6757.                                            /* error packet, */
  6758.                rdatap = data;              /* and pretend we read one. */
  6759.                return('E');
  6760.           }
  6761.           if (type == 'E')
  6762.                return('E');   /* Don't even bother about seq no */
  6763.           if ((type == 'N') && (rsn == ((pktnum + 1) & 63))) {
  6764.                /* NAK for next packet */
  6765.                return('Y');                /* is ACK for current. */
  6766.           } else {
  6767.                resend();                   /* Else, send last packet again, */
  6768.           }
  6769.           if (sstate != 0) {              /* If an interrupt routine has set */
  6770.                type = sstate;              /* sstate behind our back, return */
  6771.                sstate = 0;                 /* that. */
  6772.                *data = '\0';
  6773.                return(type);
  6774.           } else
  6775.                type = rpack();          /* Else try to read a packet. */
  6776.           chkint();                       /* Look again for interruptions. */
  6777.           if (type == sndtyp)
  6778.                type = rpack();
  6779.      }
  6780.      ttflui();                   /* Got what we want, clear input buffer. */
  6781.      return(type);               /* Success, return packet type. */
  6782. }
  6783.  
  6784.  
  6785. /*  S P A C K  --  Construct and send a packet  */
  6786.  
  6787. /*
  6788.  spack() sends a packet of the given type, sequence number n, with len
  6789.  data characters pointed to by d, in either a regular or extended-
  6790.  length packet, depending on length.  Returns the number of bytes
  6791.  actually sent, or else -1 upon failure.  Uses global npad, padch,
  6792.  mystch, bctu.  Leaves packet in null-terminated global sndpkt[] array for
  6793.  later retransmission.  Updates global sndpktl (send-packet length).
  6794. */
  6795.  
  6796. spack(type, n, len, d)
  6797. char     type, *d;
  6798. int     n, len;
  6799. {
  6800.      int     i, j, lp;
  6801.      CHAR * sohp = sndpkt;
  6802.      CHAR pc;
  6803.      unsigned     crc;
  6804.  
  6805.      if (padch == 0)
  6806.           padch = userpad;         /* we can not allow binary
  6807.                                    zero (NULL) pad characters
  6808.                                    due to the usage of the
  6809.                                    string functions in mcs
  6810.                                    functions.                */
  6811.      if (deblog) {
  6812.           debug(F100, "funct: spack", "", 0);
  6813.           debug(F111, "spack", "type", type);
  6814.           debug(F111, "spack", "n", n);
  6815.           debug(F111, "spack", "len", len);
  6816.      }
  6817.  
  6818.      spktl = 0;
  6819.      pc = dopar(padch);                  /* The pad character, if any. */
  6820.      for (i = 0; i < npad; sndpkt[i++] = pc) /* Do any requested padding */
  6821.           sohp++;
  6822.      sndpkt[i++] = dopar(mystch);        /* MARK */
  6823.      lp = i++;                           /* Position of LEN, fill in later */
  6824.      sndpkt[i++] = dopar(tochar(n));     /* SEQ field */
  6825.      sndpkt[i++] = dopar(sndtyp = type); /* TYPE field */
  6826.      j = len + bctu;                     /* Length of data + block check */
  6827.      if (j + 2 > MAXPACK) {                /* Long packet? */
  6828.           sndpkt[lp] = dopar(tochar(0));  /* Yes, set LEN to zero */
  6829.           sndpkt[i++] = dopar(tochar(j / 95)); /* High part */
  6830.           sndpkt[i++] = dopar(tochar(j % 95)); /* Low part */
  6831.           sndpkt[i] = '\0';               /* Header checksum */
  6832.           sndpkt[i++] = dopar(tochar(chk1(sndpkt + lp)));
  6833.      } else
  6834.           sndpkt[lp] = dopar(tochar(j + 2)); /* Normal LEN */
  6835.  
  6836.      if (deblog)
  6837.           debug(F110, "spack: data=", d, 0);
  6838.      while (len-- > 0)
  6839.           sndpkt[i++] = dopar(*d++); /* Packet data */
  6840.      sndpkt[i] = '\0';                   /* Null-terminate */
  6841.      if (deblog)
  6842.           debug(F110, "spack: packet data=", sndpkt + lp + 6, 0);
  6843.  
  6844.      switch (bctu) {                     /* Block check */
  6845.      case 1:                         /* 1 = 6-bit chksum */
  6846.           sndpkt[i++] = dopar(tochar(chk1(sndpkt + lp)));
  6847.           if (deblog)
  6848.                debug(F111, "spack", "checksum", sndpkt[i-1]);
  6849.           break;
  6850.      case 2:                         /* 2 = 12-bit chksum */
  6851.           j = chk2(sndpkt + lp);
  6852.           sndpkt[i++] = dopar((unsigned)tochar((j >> 6) & 077));
  6853.           sndpkt[i++] = dopar((unsigned)tochar(j & 077));
  6854.           break;
  6855.      case 3:                         /* 3 = 16-bit CRC */
  6856.           crc = chk3(sndpkt + lp);
  6857.           sndpkt[i++] = dopar((unsigned)tochar(((crc & 0170000)) >>
  6858.               12));
  6859.           sndpkt[i++] = dopar((unsigned)tochar((crc >> 6) & 077));
  6860.           sndpkt[i++] = dopar((unsigned)tochar(crc & 077));
  6861.           break;
  6862.      }
  6863.      sndpkt[i++] = dopar(seol);          /* End of line (packet terminator) */
  6864.      sndpkt[i] = '\0';                   /* Terminate string */
  6865.      if (ttol(sndpkt, i) < 0)
  6866.           return(-1); /* Send the packet */
  6867.      spktl = i;                          /* Remember packet length */
  6868.      flco += spktl;                      /* Count the characters */
  6869.      tlco += spktl;
  6870.      if (pktlog) {                       /* If logging packets, log it */
  6871.  
  6872.           long stamp;                    /* time stamp for packet logging */
  6873.  
  6874.           stamp = time((long *) 0);      /* get the time */
  6875.           zsoutl(ZPFILE,ctime(&stamp));
  6876.  
  6877.           /* this for loop transforms cntl chars to their
  6878.              printable form                               */
  6879.  
  6880.           zsout(ZPFILE, "s-");
  6881.           if (*sndpkt)
  6882.                zsoutl(ZPFILE,sndpkt);
  6883.           else
  6884.                zsoutl(ZPFILE, sohp);
  6885.      }
  6886.      screen(SCR_PT, type, (long)n, sohp);   /* Update screen */
  6887.      return(i);                             /* Return length */
  6888. }
  6889.  
  6890.  
  6891. /*  D O P A R  --  Add an appropriate parity bit to a character  */
  6892.  
  6893. CHAR
  6894. dopar(ch)
  6895. CHAR ch;
  6896. {
  6897.      unsigned int     a;
  6898.      if (!parity)
  6899.           return(ch & 255);
  6900.      else
  6901.           a = ch & 127;
  6902.      switch (parity) {
  6903.      case 'e':
  6904.           return(partab[a]);       /* Even */
  6905.      case 'm':
  6906.           return(a | 128);         /* Mark */
  6907.      case 'o':
  6908.           return(partab[a] ^ 128); /* Odd */
  6909.      case 's':
  6910.           return(a);               /* Space */
  6911.      default:
  6912.           return(a);
  6913.      }
  6914. }
  6915.  
  6916.  
  6917. /*  C H K 1  --  Compute a type-1 Kermit 6-bit checksum.  */
  6918.  
  6919. chk1(pkt)
  6920. char     *pkt;
  6921. {
  6922.      unsigned int     chk;
  6923.      chk = chk2(pkt);
  6924.      chk = (((chk & 0300) >> 6) + chk) & 077;
  6925.      return(chk);
  6926. }
  6927.  
  6928.  
  6929. /*  C H K 2  --  Compute the numeric sum of all the bytes in the packet.  */
  6930.  
  6931. unsigned int
  6932. chk2(pkt)
  6933. CHAR *pkt;
  6934. {
  6935.      long     chk;
  6936.      unsigned int     m;
  6937.  
  6938.      m = (parity) ? 0177 : 0377;
  6939.      for (chk = 0; *pkt != '\0'; pkt++) {
  6940.           chk += *pkt & m;
  6941.      }
  6942.      return(chk & 07777);
  6943. }
  6944.  
  6945.  
  6946. /*  C H K 3  --  Compute a type-3 Kermit block check.  */
  6947. /*
  6948.  Calculate the 16-bit CRC-CCITT of a null-terminated string using a lookup
  6949.  table.  Assumes the argument string contains no embedded nulls.
  6950. */
  6951. unsigned int
  6952. chk3(pkt)
  6953. CHAR *pkt;
  6954. {
  6955.      LONG c, crc;
  6956.      unsigned int     m;
  6957.      m = (parity) ? 0177 : 0377;
  6958.      for (crc = 0; *pkt != '\0'; pkt++) {
  6959.           c = (*pkt & m) ^ crc;
  6960.           crc = (crc >> 8) ^ (crcta[(c & 0xF0) >> 4] ^ crctb[c & 0x0F]);
  6961.      }
  6962.      return(crc & 0xFFFF);
  6963. }
  6964.  
  6965.  
  6966. /* Functions for sending various kinds of packets */
  6967.  
  6968. ack()
  6969. {                                 /* Send an ordinary acknowledgment. */
  6970.      spack('Y', pktnum, 0, "");             /* No data. */
  6971.      nxtpkt(&pktnum);                    /* Increment the packet number. */
  6972. }                                       /* Note, only call this once! */
  6973.  
  6974.  
  6975. ack1(s)
  6976. char     *s;
  6977. {                      /* Send an ACK with data. */
  6978.      spack('Y', pktnum, strlen(s), s);      /* Send the packet. */
  6979.      nxtpkt(&pktnum);                    /* Increment the packet number. */
  6980. }                                       /* Only call this once! */
  6981.  
  6982.  
  6983. nack()
  6984. {                                /* Negative acknowledgment. */
  6985.      spack('N', pktnum, 0, "");             /* NAK's never have data. */
  6986. }
  6987.  
  6988.  
  6989. resend()
  6990. {                              /* Send the old packet again. */
  6991.      if (spktl)                          /* If buffer has something, */
  6992.           ttol(sndpkt, spktl);             /* resend it, */
  6993.      else
  6994.           nack();                        /* otherwise send a NAK. */
  6995.  
  6996.      if (deblog)
  6997.           debug(F111, "resend", sndpkt, spktl);
  6998.      screen(SCR_PT, '%', (long)pktnum, "(resend)"); /* Say resend occurred */
  6999.  
  7000.      if (pktlog) {
  7001.           long sstamp;                    /* time stamp for packet logging */
  7002.  
  7003.           sstamp = time((long *) 0);      /* get the time */
  7004.           zsoutl(ZPFILE,ctime(&sstamp));
  7005.  
  7006.           zsout(ZPFILE, "s-");
  7007.           zsoutl(ZPFILE, "(resend)"); /* Log packet if desired */
  7008.      }
  7009. }
  7010.  
  7011.  
  7012. errpkt(reason)
  7013. char     *reason;
  7014. {          /* Send an error packet. */
  7015.      encstr(reason);
  7016.      spack('E', pktnum, size, data);
  7017.      clsif();
  7018.      clsof(1);
  7019.      screen(SCR_TC, 0, 0l, "");
  7020. }
  7021.  
  7022.  
  7023. scmd(t, dat)
  7024. char     t, *dat;
  7025. {             /* Send a packet of the given type */
  7026.      encstr(dat);                        /* Encode the command string */
  7027.      spack(t, pktnum, size, data);
  7028. }
  7029.  
  7030.  
  7031. srinit()
  7032. {                                        /* Send R (GET) packet */
  7033.      encstr(cmarg);                      /* Encode the filename. */
  7034.      spack('R', pktnum, size, data);     /* Send the packet. */
  7035. }
  7036.  
  7037.  
  7038. nxtpkt(num)
  7039. int     *num;
  7040. {
  7041.      prvpkt = *num;                      /* Save previous */
  7042.      *num = (*num + 1) % 64;             /* Increment packet number mod 64 */
  7043. }
  7044.  
  7045.  
  7046. sigint()
  7047. {                              /* Terminal interrupt handler */
  7048.      errpkt("User typed ^C");
  7049.      doexit(GOOD_EXIT);                  /* Exit program */
  7050. }
  7051.  
  7052.  
  7053. /* R P A C K  --  Read a Packet */
  7054.  
  7055. /*
  7056.  rpack reads a packet and returns the packet type, or else Q if the
  7057.  packet was invalid, or T if a timeout occurred.  Upon successful return, sets
  7058.  the values of global rsn (received sequence number),  rln (received
  7059.  data length), and rdatap (pointer to null-terminated data field).
  7060. */
  7061. rpack()
  7062. {
  7063.      int     i, j, x, try, type, lp;         /* Local variables */
  7064.      int     amtread, pktstart, pktlength;
  7065.      unsigned     crc;
  7066.      CHAR pbc[4];                        /* Packet block check */
  7067.      CHAR * sohp = recpkt;               /* Pointer to SOH */
  7068.      CHAR e;                             /* Packet end character */
  7069.  
  7070.      rsn = rln = -1;                     /* In case of failure. */
  7071.      *recpkt = '\0';                     /* Clear receive buffer. */
  7072.      rdatap = recpkt;                    /* Initialize this. */
  7073.  
  7074.      amtread = pktstart = pktlength = 0; /* Initialize */
  7075.  
  7076.      e = (turn) ? turnch : eol;          /* Use any handshake char for eol */
  7077.  
  7078.      /* Try several times to get a "line".  This allows for hosts that
  7079.      echo our normal CR packet terminator as CRLF.  Don't diagnose CRLF
  7080.      as an invalid packet. */
  7081.  
  7082. #define TTITRY 3
  7083.  
  7084.      for (try = 0; try < TTITRY; try++) {  /* Try x times to get a "line" */
  7085.        j = ttinl(recpkt, MAXRP, timint, e);
  7086.        if (j < 0) {
  7087.          if (j < -1) doexit(BAD_EXIT);    /* Bail out if ^C^C typed. */
  7088.          if (deblog) debug(F101, "rpack: ttinl fails", "", amtread);
  7089.          screen(SCR_PT, 'T', (long)pktnum, "");
  7090.          return('T');                     /* Otherwise, call it a timeout. */
  7091.        }
  7092.        amtread = j - 2;                   /* forget eol and null character */
  7093.        tlci += amtread;                   /* All OK, Count the characters. */
  7094.        flci += amtread;
  7095.  
  7096.        for (i = 0; (recpkt[i] != stchr) && (i < amtread); i++)
  7097.          sohp++;                          /* Find mark */
  7098.        pktstart = i;
  7099.        if (i++ < amtread)  break;         /* Found it */
  7100.      }
  7101.  
  7102.      if (try >= TTITRY)  return('Q');     /* Diagnose bad packet */
  7103.  
  7104.      lp = i;                              /* Remember LEN position. */
  7105.  
  7106.      if ((j = xunchar(recpkt[i++])) == 0) {    /* Long packet */
  7107.        if ((j = lp + 5) > MAXRP)  return('Q');
  7108.        x = recpkt[j];                     /* Header checksum. */
  7109.        recpkt[j] = '\0';                  /* Calculate & compare. */
  7110.        if (xunchar(x) != chk1(recpkt + lp))
  7111.          return('Q');
  7112.        recpkt[j] = x;                     /* Checksum ok. */
  7113.        rln = xunchar(recpkt[j-2]) * 95 + xunchar(recpkt[j-1]) -
  7114.          bctu;
  7115.        pktlength = rln + bctu + 6;        /* packet length */
  7116.        j = 3;                             /* Data offset. */
  7117.      } else if (j < 3) {
  7118.           if (deblog)
  7119.             debug(F101, "rpack: packet length less than 3", "", j);
  7120.           return('Q');
  7121.      } else {
  7122.           rln = j - bctu - 2;             /* Regular packet */
  7123.           pktlength = rln + bctu + 3;     /* packet length */
  7124.           j = 0;                          /* No extended header */
  7125.      }
  7126.      rsn = xunchar(recpkt[i++]);         /* Sequence number */
  7127.      type = recpkt[i++];                 /* Packet type */
  7128.      i += j;                             /* Where data begins */
  7129.      rdatap = recpkt + i;                /* The data itself */
  7130.  
  7131.      while (amtread < (pktstart + pktlength)) {
  7132.         /* If we didn't initially read the entire packet, then
  7133.         we'll keep reading here until we get it into the buffer. */
  7134.  
  7135.         j = ttinl(recpkt + amtread, MAXRP, timint, e);
  7136.         if (j < 0) {                            /* bad read */
  7137.           if (j < -1)  doexit(BAD_EXIT);
  7138.           if (deblog)  debug(F101,"rpack: ttinl fails","",j);
  7139.           return('T');
  7140.         }
  7141.         amtread += (j - 2);               /* bump up amount read */
  7142.         tlci += (j - 2);                  /* forget eol and null */
  7143.         flci += (j - 2);
  7144.      }
  7145.  
  7146.      if (deblog)  debug(F111,"rpack: ttinl",sohp,amtread);
  7147.  
  7148.      if (pktlog)  {                    /* log packet if requested */
  7149.         long rstamp;
  7150.  
  7151.         rstamp = time((long *) 0);
  7152.         zsoutl(ZPFILE,ctime(&rstamp));  /* time stamp for packet */
  7153.         zsout(ZPFILE,"r-");
  7154.         zsoutl(ZPFILE,sohp);
  7155.      }
  7156.  
  7157.      if ((j = rln + i) > MAXRP ) {
  7158.        if (deblog)
  7159.          debug(F101, "rpack: packet sticks out too far", "", j);
  7160.        return('Q');
  7161.      }
  7162.  
  7163.      for (x = 0; x < bctu; x++)          /* Copy block check */
  7164.           pbc[x] = recpkt[j+x];
  7165.  
  7166.      pbc[x] = '\0';
  7167.      recpkt[j] = '\0';                   /* Null-terminate data */
  7168.  
  7169.      switch (bctu) {                     /* Check the block check */
  7170.      case 1:
  7171.           if (xunchar(*pbc) != chk1(recpkt + lp)) {
  7172.             if (deblog) {
  7173.               debug(F110, "checked chars", recpkt + lp, 0);
  7174.               debug(F101, "block check", "", xunchar(*pbc));
  7175.               debug(F101, "should be", "", chk1(recpkt + lp));
  7176.             }
  7177.             return('Q');
  7178.           }
  7179.           break;
  7180.      case 2:
  7181.           x = xunchar(*pbc) << 6 | xunchar(pbc[1]);
  7182.           if (x != chk2(recpkt + lp)) {
  7183.             if (deblog) {
  7184.               debug(F110, "checked chars", recpkt + lp, 0);
  7185.               debug(F101, "block check", "", x);
  7186.               debug(F101, "should be", "", chk2(recpkt + lp));
  7187.             }
  7188.             return('Q');
  7189.           }
  7190.           break;
  7191.      case 3:
  7192.           crc = (xunchar(pbc[0]) << 12)
  7193.            | (xunchar(pbc[1]) << 6)
  7194.            | (xunchar(pbc[2]));
  7195.           if (crc != chk3(recpkt + lp)) {
  7196.             if (deblog) {
  7197.               debug(F110, "checked chars", recpkt + lp, 0);
  7198.               debug(F101, "block check", "", xunchar(*pbc));
  7199.               debug(F101, "should be", "", chk3(recpkt + lp));
  7200.             }
  7201.             return('Q');
  7202.           }
  7203.           break;
  7204.      default:
  7205.           return('Q');
  7206.      }
  7207.      screen(SCR_PT, type, (long)rsn, sohp); /* Update screen */
  7208.      return(type);                       /* Return packet type */
  7209. }
  7210. <<< ckvfns.c >>>
  7211. char *fnsv = "V-Kermit functions, 4E(054) 29 May 90";
  7212.  
  7213. /*  C K V F N S  --  System-independent Kermit protocol support functions.  */
  7214.  
  7215. /**********************************************************************
  7216. *                                                                     *
  7217. * IVS / MCS-Kermit REL 2                                              *
  7218. * source code                                                         *
  7219. *                                                                     *
  7220. * Change History:                                                     *
  7221. *                                                                     *
  7222. *                1. Modify C-Kermit(4E) source code to                *
  7223. *                   produce new module for MCS/IVS-Kermit             *
  7224. *                   ORIGINAL RELEASE                                  *
  7225. *                   June 22, 1990                                     *
  7226. *                                                                     *
  7227. *                                                                     *
  7228. ***********************************************************************/
  7229.  
  7230.  
  7231. /*  ...Part 1 (others moved to ckcfn2 to make this module small enough) */
  7232.  
  7233. /*
  7234.  Author: Frank da Cruz (fdc@cunixc.cc.columbia.edu, FDCCU@CUVMA.BITNET),
  7235.  Columbia University Center for Computing Activities.
  7236.  First released January 1985.
  7237.  Copyright (C) 1985, 1989, Trustees of Columbia University in the City of New
  7238.  York.  Permission is granted to any individual or institution to use, copy, or
  7239.  redistribute this software so long as it is not sold for profit, provided this
  7240.  copyright notice is retained.
  7241. */
  7242. /*
  7243.  System-dependent primitives defined in:
  7244.  
  7245.    ck?tio.c -- terminal i/o
  7246.    ck?fio.c -- file i/o, directory structure
  7247. */
  7248. #include "ckcsym.h"            /* Need this for Mac */
  7249. #include "ckcker.h"            /* Symbol definitions for Kermit */
  7250. #include "ckcdeb.h"            /* Debug formats, typedefs, etc. */
  7251.  
  7252. #ifndef NULL
  7253. #define NULL 0
  7254. #endif
  7255.  
  7256. /* Externals from ckcmai.c */
  7257. extern int spsiz, rpsiz, timint, rtimo, npad, ebq, ebqflg, rpt, rptq,
  7258.  rptflg, capas, keep;
  7259. extern int pktnum, prvpkt, sndtyp, bctr, bctu, fmask,
  7260.  size, osize, maxsize, spktl, nfils, stdouf, /* warn, */ timef, spsizf;
  7261. extern int parity, speed, turn, turnch,
  7262.  delay, displa, pktlog, tralog, seslog, xflg, mypadn;
  7263. extern long filcnt, ffc, flci, flco, tlci, tlco, tfc, fsize;
  7264. extern int tsecs;
  7265. extern int deblog, hcflg, binary, savmod, fncnv, local, server, cxseen, czseen;
  7266. extern int rq, rqf, sq, wsize, urpsiz, rln;
  7267. extern int atcapr, atcapb, atcapu;
  7268. extern int lpcapr, lpcapb, lpcapu;
  7269. extern int swcapr, swcapb, swcapu;
  7270. extern CHAR padch, mypadc, eol, seol, ctlq, myctlq, sstate;
  7271. extern CHAR filnam[], sndpkt[], recpkt[], data[], srvcmd[], stchr, mystch;
  7272. extern char *cmarg, *cmarg2, *hlptxt, **cmlist;
  7273. extern CHAR *srvptr;
  7274. extern char *rdatap;
  7275. long zchki();
  7276. char *strcpy();
  7277. CHAR *rpar();
  7278.  
  7279. /* Variables local to this module */
  7280.  
  7281. static char *memptr;            /* Pointer for memory strings */
  7282.  
  7283. static char cmdstr[100];        /* NCR-VRX system command string */
  7284.  
  7285. static int  sndsrc;            /* Flag for where to send from: */
  7286.                     /* -1: name in cmdata */
  7287.                     /*  0: stdin          */
  7288.                     /* >0: list in cmlist */
  7289.  
  7290. static int  memstr,            /* Flag for input from memory string */
  7291.     first;                /* Flag for first char from input */
  7292. static CHAR t,                /* Current character */
  7293.     next;                /* Next character */
  7294.  
  7295. /*  E N C S T R  --  Encode a string from memory. */
  7296.  
  7297. /*  Call this instead of getpkt() if source is a string, rather than a file. */
  7298.  
  7299. encstr(s) char* s; {
  7300.     int m; char *p;
  7301.  
  7302.     m = memstr; p = memptr;        /* Save these. */
  7303.  
  7304.     memptr = s;                /* Point to the string. */
  7305.     memstr = 1;                /* Flag memory string as source. */
  7306.     first = 1;                /* Initialize character lookahead. */
  7307.     getpkt(spsiz-bctu-3);        /* Fill a packet from the string. */
  7308.     memstr = m;                /* Restore memory string flag */
  7309.     memptr = p;                /* and pointer */
  7310.     first = 1;                /* Put this back as we found it. */
  7311. }
  7312.  
  7313. /* E N C O D E - Kermit packet encoding procedure */
  7314.  
  7315. encode(a) CHAR a; {            /* The current character */
  7316.     int a7;                /* Low order 7 bits of character */
  7317.     int b8;                /* 8th bit of character */
  7318.  
  7319.     if (rptflg)    {                   /* Repeat processing? */
  7320.         if (a == next && (first == 0)) { /* Got a run... */
  7321.         if (++rpt < 94)        /* Below max, just count */
  7322.                 return;
  7323.         else if (rpt == 94) {    /* Reached max, must dump */
  7324.                 data[size++] = rptq;
  7325.                 data[size++] = tochar(rpt);
  7326.                 rpt = 0;
  7327.         }
  7328.         } else if (rpt == 1) {        /* Run broken, only 2? */
  7329.             rpt = 0;            /* Yes, reset repeat flag & count. */
  7330.         encode(a);            /* Do the character twice. */
  7331.         if (size <= maxsize) osize = size;
  7332.         rpt = 0;
  7333.         encode(a);
  7334.         return;
  7335.     } else if (rpt > 1) {        /* More than two */
  7336.             data[size++] = rptq;    /* Insert the repeat prefix */
  7337.             data[size++] = tochar(++rpt); /* and count. */
  7338.             rpt = 0;            /* Reset repeat counter. */
  7339.         }
  7340.     }
  7341.     a7 = a & 0177;            /* Isolate ASCII part */
  7342.     b8 = a & 0200;            /* and 8th (parity) bit. */
  7343.  
  7344.     if (ebqflg && b8) {            /* Do 8th bit prefix if necessary. */
  7345.         data[size++] = ebq;
  7346.         a = a7;
  7347.     }
  7348.     if ((a7 < SP) || (a7==DEL))    {    /* Do control prefix if necessary */
  7349.         data[size++] = myctlq;
  7350.     a = ctl(a);
  7351.     }
  7352.     if (a7 == myctlq)            /* Prefix the control prefix */
  7353.         data[size++] = myctlq;
  7354.  
  7355.     if ((rptflg) && (a7 == rptq))    /* If it's the repeat prefix, */
  7356.         data[size++] = myctlq;        /* quote it if doing repeat counts. */
  7357.  
  7358.     if ((ebqflg) && (a7 == ebq))    /* Prefix the 8th bit prefix */
  7359.         data[size++] = myctlq;        /* if doing 8th-bit prefixes */
  7360.  
  7361.     data[size++] = a;            /* Finally, insert the character */
  7362.     data[size] = '\0';            /* itself, and mark the end. */
  7363. }
  7364.  
  7365. /* D E C O D E  --  Kermit packet decoding procedure */
  7366.  
  7367. /* Call with string to be decoded and an output function. */
  7368. /* Returns 0 on success, -1 on failure (e.g. disk full).  */
  7369.  
  7370. decode(buf,fn) CHAR *buf; int (*fn)(); {
  7371.     unsigned int a, a7, b8;        /* Low order 7 bits, and the 8th bit */
  7372.  
  7373.     rpt = 0;                /* Initialize repeat count. */
  7374.  
  7375.     while ((a = *buf++) != '\0') {
  7376.     if (rptflg) {            /* Repeat processing? */
  7377.         if (a == rptq) {        /* Yes, got a repeat prefix? */
  7378.         rpt = xunchar(*buf++);    /* Yes, get the repeat count, */
  7379.         a = *buf++;        /* and get the prefixed character. */
  7380.         }
  7381.     }
  7382.     b8 = 0;                /* Check high order "8th" bit */
  7383.     if (ebqflg) {            /* 8th-bit prefixing? */
  7384.         if (a == ebq) {        /* Yes, got an 8th-bit prefix? */
  7385.         b8 = 0200;        /* Yes, remember this, */
  7386.         a = *buf++;        /* and get the prefixed character. */
  7387.         }
  7388.     }
  7389.     if (a == ctlq) {        /* If control prefix, */
  7390.         a  = *buf++;        /* get its operand. */
  7391.         a7 = a & 0177;        /* Only look at low 7 bits. */
  7392.         if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') /* Uncontrollify */
  7393.         a = ctl(a);            /* if in control range. */
  7394.     }
  7395.     a |= b8;            /* OR in the 8th bit */
  7396.     if (rpt == 0) rpt = 1;        /* If no repeats, then one */
  7397. #ifdef NLCHAR
  7398.     if (!binary) {            /* If in text mode, */
  7399.         if (a == CR) continue;    /* discard carriage returns, */
  7400.             if (a == LF) a = NLCHAR;     /* convert LF to system's newline. */
  7401.         }
  7402. #endif
  7403.     for (; rpt > 0; rpt--) {    /* Output the char RPT times */
  7404.         if ((*fn)(a) < 0) return(-1); /* Send it to the output function. */
  7405.         ffc++, tfc++;        /* Count the character */
  7406.     }
  7407.     }
  7408.     return(0);
  7409. }
  7410.  
  7411.  
  7412. /*  Output functions passed to 'decode':  */
  7413.  
  7414. putsrv(c) char c; {     /*  Put character in server command buffer  */
  7415.     *srvptr++ = c;
  7416.     *srvptr = '\0';    /* Make sure buffer is null-terminated */
  7417.     return(0);
  7418. }
  7419.  
  7420. puttrm(c) char c; {     /*  Output character to console.  */
  7421.     conoc(c);
  7422.     return(0);
  7423. }
  7424.  
  7425. putfil(c) char c; {            /*  Output char to file. */
  7426.     if (zchout(ZOFILE, c & fmask) < 0) {
  7427.     czseen = 1;               /* If write error... */
  7428.     if (deblog) debug(F101,"putfil zchout write error, setting czseen","",1);
  7429.     return(-1);
  7430.     }
  7431.     return(0);
  7432. }
  7433.  
  7434. /*  G E T P K T -- Fill a packet data field  */
  7435.  
  7436. /*
  7437.  Gets characters from the current source -- file or memory string.
  7438.  Encodes the data into the packet, filling the packet optimally.
  7439.  Set first = 1 when calling for the first time on a given input stream
  7440.  (string or file).
  7441.  
  7442.  Uses global variables:
  7443.  t     -- current character.
  7444.  first -- flag: 1 to start up, 0 for input in progress, -1 for EOF.
  7445.  next  -- next character.
  7446.  data  -- the packet data buffer.
  7447.  size  -- number of characters in the data buffer.
  7448.  
  7449. Returns the size as value of the function, and also sets global size,
  7450. and fills (and null-terminates) the global data array.  Returns 0 upon eof.
  7451. */
  7452.  
  7453. getpkt(bufmax) int bufmax; {        /* Fill one packet buffer */
  7454.   int i, x;                /* Loop index. */
  7455.  
  7456.   static char leftover[6] = { '\0', '\0', '\0', '\0', '\0', '\0' };
  7457.  
  7458.   if (deblog) debug(F111,"getpkt","bufmax",bufmax);
  7459.  
  7460.   if (first == 1) {        /* If first time thru...  */
  7461.        first = 0;        /* remember, */
  7462.        *leftover = '\0';       /* discard any interrupted leftovers, */
  7463.        x = getchx(&t);        /* get first character of file into t, */
  7464.        if (x == 0) {            /* watching out for null file, */
  7465.          first = -1;
  7466.          return(size = 0);
  7467.        }
  7468.   } else if ((first == -1) && (*leftover == '\0')) /* EOF from last time? */
  7469.       return(size = 0);
  7470.  
  7471.   /* Do any leftovers */
  7472.  
  7473.   for (size = 0; (data[size] = leftover[size]) != '\0'; size++)
  7474.        ;
  7475.   *leftover = '\0';
  7476.   if (first == -1) return(size);    /* Handle final leftovers leftovers */
  7477.  
  7478.     /* Now fill up the rest of the packet. */
  7479.  
  7480.     rpt = 0;                /* Clear out any old repeat count. */
  7481.     while (first > -1) {        /* Until EOF... */
  7482.          x = getchx(&next);        /* Get next character for lookahead. */
  7483.          if (x == 0) first = -1;        /* Flag eof for next time. */
  7484.          osize = size;            /* Remember current position. */
  7485.       encode(t);            /* Encode the current character. */
  7486.          t = next;            /* Next is now current. */
  7487.  
  7488.          if (size == bufmax) {         /* If the packet is exactly full, */
  7489.         if (deblog) debug(F101,"getpkt exact fit","",size);
  7490.         return(size);        /* ... return. */
  7491.          }
  7492.          if (size > bufmax) {        /* If too big, save some for next. */
  7493.            for (i = 0; (leftover[i] = data[osize+i]) != '\0'; i++)
  7494.                 ;
  7495.            if (deblog) debug(F111,"getpkt leftover",leftover,size);
  7496.            if (deblog) debug(F101," osize","",osize);
  7497.            size = osize;        /* Return truncated packet. */
  7498.            data[size] = '\0';
  7499.            return(size);
  7500.          }
  7501.     }                       /* Otherwise, keep filling. */
  7502.     if (deblog) debug(F111,"getpkt eof/eot",data,size);
  7503.                            /* Fell thru before packet full, */
  7504.     return(size);           /* return partially filled last packet. */
  7505. }
  7506.  
  7507. /*  G E T C H X  --  Get the next character from file (or pipe). */
  7508.  
  7509. /*
  7510.  On systems like NCR-VRX, the Macintosh, etc, that use a single character
  7511.  (NLCHAR, defined in ckcdeb.h) to separate lines in text files, and
  7512.  when in text/ascii mode (binary == 0), this function maps the newline
  7513.  character to CRLF.  If NLCHAR is not defined, then this mapping is
  7514.  not done, even in text mode.
  7515.  
  7516.  Returns 1 on success with ch set to the character, or 0 on failure (EOF)
  7517. */
  7518. getchx(ch) char *ch; {            /* Get next character */
  7519.     int x; CHAR a;            /* The character to return. */
  7520.     static int b = 0;            /* A character to remember. */
  7521.  
  7522.     if (b > 0) {            /* Do we have a LF saved? */
  7523.     b = 0;                /* Yes, return that. */
  7524.     *ch = LF;
  7525.     return(1);
  7526.     }
  7527.  
  7528.     if (memstr)                /* Try to get the next character */
  7529.         x = ((a = *memptr++) == '\0');    /* from the appropriate source, */
  7530.     else                /* memory or the current file. */
  7531.         x = (zchin(ZIFILE,&a) == -1);
  7532.  
  7533.     if (x)
  7534.         return(0);            /* No more, return 0 for EOF. */
  7535.     else {                /* Otherwise, read the next char. */
  7536.     ffc++, tfc++;            /* Count it. */
  7537.     a &= fmask;            /* Bytesize mask. */
  7538. #ifdef NLCHAR
  7539.     if (!binary && (a == NLCHAR)) {    /* If nl and we must do nl-CRLF */
  7540.         b = 1;            /* mapping, remember a linefeed, */
  7541.         *ch = CR;            /* and return a carriage return. */
  7542.         return(1);
  7543.     } else {
  7544.         *ch = a;            /*  General case, return the char. */
  7545.         return(1);
  7546.         }
  7547. #else
  7548.         *ch = a;
  7549.         return(1);
  7550. #endif
  7551.     }
  7552. }
  7553.  
  7554.  
  7555. /*  C A N N E D  --  Check if current file transfer cancelled */
  7556.  
  7557. canned(buf) char *buf; {
  7558.     if (*buf == 'X') cxseen = 1;
  7559.     if (*buf == 'Z') czseen = 1;
  7560.     if (deblog) debug(F101,"canned: cxseen","",cxseen);
  7561.     if (deblog) debug(F101," czseen","",czseen);
  7562.     return((czseen || cxseen) ? 1 : 0);
  7563. }
  7564.  
  7565. /*  R E S E T C  --  Reset per-transaction character counters */
  7566. resetc() {
  7567.     tfc = tlci = tlco = 0;    /* Total file chars, line chars in & out */
  7568. }
  7569.  
  7570.  
  7571. /*  T I N I T  --  Initialize a transaction  */
  7572.  
  7573. tinit() {
  7574.     xflg = 0;                /* Reset x-packet flag */
  7575.     rqf = -1;                /* Reset 8th-bit-quote request flag */
  7576.     memstr = 0;                /* Reset memory-string flag */
  7577.     memptr = NULL;            /*  and pointer */
  7578.     bctu = 1;                /* Reset block check type to 1 */
  7579.     ebq = ebqflg = 0;            /* Reset 8th-bit quoting stuff */
  7580.     if (savmod) {            /* If binary file mode was saved, */
  7581.         binary = 1;            /*  restore it, */
  7582.     savmod = 0;            /*  unsave it. */
  7583.     }
  7584.     prvpkt = -1;            /* Reset packet number */
  7585.     pktnum = 0;
  7586.     cxseen = czseen = 0;        /* Reset interrupt flags */
  7587.     *filnam = '\0';            /* Clear file name */
  7588.     *sndpkt = '\0';            /* Clear retransmission buffer */
  7589.     if (server)             /* If acting as server, */
  7590.     timint = 30;            /* Use 30 second timeout, */
  7591. }
  7592.  
  7593.  
  7594. /*  R I N I T  --  Respond to S packet  */
  7595.  
  7596. rinit(d) char *d; {
  7597.     char *tp;
  7598.     ztime(&tp);
  7599.     tlog(F110,"Transaction begins",tp,0l); /* Make transaction log entry */
  7600.     filcnt = 0;                /* Init file counter */
  7601.     spar(d);
  7602.     ack1(rpar());
  7603. }
  7604.  
  7605. /*  S I N I T  --  Make sure file exists, then send Send-Init packet */
  7606.  
  7607. sinit() {
  7608.     int x; char *tp;
  7609.     int type;
  7610.     filcnt = 0;
  7611.     sndsrc = nfils;            /* Where to look for files to send */
  7612.     ztime(&tp);
  7613.     tlog(F110,"Transaction begins",tp,0l); /* Make transaction log entry */
  7614.     if (deblog) debug(F101,"sinit: sndsrc","",sndsrc);
  7615.     if (sndsrc < 0) {            /* Must expand from 'send' command */
  7616.     nfils = zxpand(cmarg);        /* Look up literal name. */
  7617.     if (nfils < 0) {
  7618.         screen(SCR_EM,0,0l,"Too many files");
  7619.         return(0);
  7620.         } else if (nfils == 0) {    /* If none found, */
  7621.         char xname[100];        /* convert the name. */
  7622.         zrtol(cmarg,xname, &type);
  7623.         nfils = zxpand(xname);     /* Look it up again. */
  7624.     }
  7625.     if (nfils < 1) {        /* If no match, report error. */
  7626.         if (server)
  7627.             errpkt("File not found");
  7628.         else
  7629.         screen(SCR_EM,0,0l,"File not found");
  7630.         return(0);
  7631.     }
  7632.     x = gnfile();            /* Position to first file. */
  7633.     if (x < 1) {
  7634.         if (!server)
  7635.             screen(SCR_EM,0,0l,"No readable file to send");
  7636.             else
  7637.             errpkt("No readable file to send");
  7638.         return(0);
  7639.         }
  7640.     } else if (sndsrc > 0) {        /* Command line arglist -- */
  7641.     x = gnfile();            /* Get the first file from it. */
  7642.     if (x < 1) return(0);        /* (if any) */
  7643.     } else if (sndsrc == 0) {        /* stdin or memory always exist... */
  7644.     if ((cmarg2 != NULL) && (*cmarg2)) {
  7645.         strcpy(filnam,cmarg2);    /* If F packet, "as" name is used */
  7646.         cmarg2 = "";        /* if provided, */
  7647.         } else                /* otherwise */
  7648.         strcpy(filnam,"stdin");    /* just use this. */
  7649.     }
  7650.     if (deblog) debug(F101,"sinit: nfils","",nfils);
  7651.     if (deblog) debug(F110," filnam",filnam,0);
  7652.     if (deblog) debug(F110," cmdstr",cmdstr,0);
  7653.     ttflui();                /* Flush input buffer. */
  7654.     if (!local && !server) sleep(delay);
  7655.     sipkt('S');                /* Send the Send-Init packet. */
  7656.     return(1);
  7657. }
  7658.  
  7659. sipkt(c) char c; {            /* Send S or I packet. */
  7660.     CHAR *rp;
  7661.     ttflui();                /* Flush pending input. */
  7662.     rp = rpar();            /* Get parameters. */
  7663.     spack(c,pktnum,strlen(rp),rp);
  7664. }
  7665.  
  7666. /*  R C V F I L -- Receive a file  */
  7667.  
  7668. rcvfil() {
  7669.     int x;
  7670.     ffc = flci = flco = 0;        /* Init per-file counters */
  7671.     srvptr = srvcmd;            /* Decode file name from packet. */
  7672.     decode(rdatap,putsrv);
  7673.     if (*srvcmd == '\0')        /* Watch out for null F packet. */
  7674.         strcpy(srvcmd,"NONAME");
  7675.     screen(SCR_FN,0,0l,srvcmd);        /* Put it on screen */
  7676.     tlog(F110,"Receiving",srvcmd,0l);    /* Transaction log entry */
  7677.     if (cmarg2 != NULL) {               /* Check for alternate name */
  7678.         if (*cmarg2 != '\0') {
  7679.             strcpy(srvcmd,cmarg2);    /* Got one, use it. */
  7680.         *cmarg2 = '\0';
  7681.         }
  7682.     }
  7683.     x = openo(srvcmd,filnam);        /* Try to open it */
  7684.     if (x) {
  7685.     tlog(F110," as",filnam,0l);
  7686.     screen(SCR_AN,0,0l,filnam);
  7687.     intmsg(++filcnt);
  7688.     } else {
  7689.         tlog(F110,"Failure to open",filnam,0l);
  7690.     screen(SCR_EM,0,0l,"Can't open file");
  7691.     }
  7692.     return(x);                /* Pass on return code from openo */
  7693. }
  7694.  
  7695. /*  R E O F  --  Receive End Of File  */
  7696.  
  7697. reof() {
  7698.     int x;
  7699.     if (cxseen == 0) cxseen = (*rdatap == 'D');    /* Got discard directive? */
  7700.     x = clsof(cxseen | czseen);
  7701.     if (cxseen || czseen) {
  7702.     tlog(F100," *** Discarding","",0l);
  7703.     cxseen = 0;
  7704.     } else
  7705.     fstats();
  7706.     return(x);
  7707. }
  7708.  
  7709.  
  7710. /*  R E O T  --  Receive End Of Transaction  */
  7711.  
  7712. reot() {
  7713.     cxseen = czseen = 0;        /* Reset interruption flags */
  7714.     tstats();
  7715. }
  7716.  
  7717. /*  S F I L E -- Send File header or teXt header packet  */
  7718.  
  7719. /*  Call with x nonzero for X packet, zero for F packet  */
  7720. /*  Returns 1 on success, 0 on failure                   */
  7721.  
  7722. sfile(x) int x; {
  7723.     char pktnam[100];            /* Local copy of name */
  7724.     char *s;
  7725.  
  7726.     if (x == 0) {            /* F-Packet setup */
  7727.  
  7728.         if (*cmarg2 != '\0') {        /* If we have a send-as name, */
  7729.         strcpy(pktnam,cmarg2);    /* copy it literally, */
  7730.         cmarg2 = "";        /* and blank it out for next time. */
  7731.         } else {            /* Otherwise use actual file name: */
  7732.         if (fncnv) {        /* If converting names, */
  7733.             zltor(filnam,pktnam);    /* convert it to common form, */
  7734.         } else {            /* otherwise, */
  7735.             strcpy(pktnam,filnam);    /* copy it literally. */
  7736.             }
  7737.         }
  7738.         if (deblog) debug(F110,"sfile",filnam,0);    /* Log debugging info */
  7739.         if (deblog) debug(F110," pktnam",pktnam,0);
  7740.         if (openi(filnam) == 0)     /* Try to open the file */
  7741.         return(0);
  7742.         s = pktnam;            /* Name for packet data field */
  7743.  
  7744.     } else {                /* X-packet setup */
  7745.  
  7746.         if (deblog) debug(F110,"sxpack",cmdstr,0);    /* Log debugging info */
  7747.         s = cmdstr;            /* Name for data field */
  7748.     }
  7749.  
  7750.     flci = flco = ffc = 0;        /* Init counters, etc. */
  7751.     encstr(s);                /* Encode the name into data[]. */
  7752.     nxtpkt(&pktnum);            /* Increment the packet number */
  7753.     spack(x ? 'X' : 'F', pktnum, size, data); /* Send the F or X packet */
  7754.  
  7755.     if (x == 0) {            /* Display for F packet */
  7756.         if (displa) {            /* Screen */
  7757.         screen(SCR_FN,'F',(long)pktnum,filnam);
  7758.         screen(SCR_AN,0,0l,pktnam);
  7759.         screen(SCR_FS,0,(long)fsize,"");
  7760.         }
  7761.         tlog(F110,"Sending",filnam,0l);    /* Transaction log entry */
  7762.         tlog(F110," as",pktnam,0l);
  7763.  
  7764.     } else {                /* Display for X-packet */
  7765.  
  7766.         screen(SCR_XD,'X',(long)pktnum,cmdstr);    /* Screen */
  7767.         tlog(F110,"Sending from:",cmdstr,0l);    /* Transaction log */
  7768.     }
  7769.     intmsg(++filcnt);            /* Count file, give interrupt msg */
  7770.     first = 1;                /* Init file character lookahead. */
  7771.     return(1);
  7772. }
  7773.  
  7774. /*  S D A T A -- Send a data packet */
  7775.  
  7776. /*  Return -1 if no data to send, else send packet and return length  */
  7777.  
  7778. sdata() {
  7779.     int len;
  7780.     if (deblog) debug(F111,"sdata","spsiz",spsiz);
  7781.     if (cxseen || czseen) return(-1);    /* If interrupted, done. */
  7782.     if ((len = getpkt(spsiz-bctu-3)) == 0) /* Done if no data. */
  7783.         return(-1);
  7784.     nxtpkt(&pktnum);            /* Increment the packet number */
  7785.     spack('D',pktnum,len,data);        /* Send the packet */
  7786.     return(len);
  7787. }
  7788.  
  7789.  
  7790. /*  S E O F -- Send an End-Of-File packet */
  7791.  
  7792. /*  Call with a string pointer to character to put in the data field, */
  7793. /*  or else a null pointer or "" for no data.  */
  7794.  
  7795. seof(s) char *s; {
  7796.     nxtpkt(&pktnum);            /* Increment the packet number */
  7797.     if ((s != NULL) && (*s != '\0')) {
  7798.     spack('Z',pktnum,1,s);
  7799.     tlog(F100," *** interrupted, sending discard request","",0l);
  7800.     } else {
  7801.     spack('Z',pktnum,0,"");
  7802.     fstats();
  7803.     }
  7804. }
  7805.  
  7806.  
  7807. /*  S E O T -- Send an End-Of-Transaction packet */
  7808.  
  7809. seot() {
  7810.     nxtpkt(&pktnum);            /* Increment the packet number */
  7811.     spack('B',pktnum,0,"");        /* Send the EOT packet */
  7812.     cxseen = czseen = 0;        /* Reset interruption flags */
  7813.     tstats();                /* Log timing info */
  7814. }
  7815.  
  7816. /*   R P A R -- Fill the data array with my send-init parameters  */
  7817.  
  7818. CHAR *
  7819. rpar() {
  7820.     if (rpsiz > MAXPACK)        /* Biggest normal packet I want. */
  7821.       data[1] = tochar(MAXPACK);    /* If > 94, use 94, but specify */
  7822.     else                /* extended packet length below... */
  7823.       data[1] = tochar(rpsiz);        /* else use what the user said. */
  7824.     data[2] = tochar(rtimo);        /* When I want to be timed out */
  7825.     data[3] = tochar(mypadn);        /* How much padding I need (none) */
  7826.     data[4] = ctl(mypadc);        /* Padding character I want */
  7827.  
  7828.     if (eol == LF)
  7829.            data [5] = tochar (CR);      /* for vrx ivs use only */
  7830.        else
  7831.            data[5] = tochar(eol);        /* End-Of-Line character I want */
  7832.  
  7833.     data[6] = '#';            /* Control-Quote character I send */
  7834.     switch (rqf) {            /* 8th-bit prefix */
  7835.     case -1:
  7836.     case  1: if (parity) ebq = sq = '&'; break;
  7837.     case  0:
  7838.     case  2: break;
  7839.     }
  7840.     data[7] = sq;
  7841.     data[8] = bctr + '0';        /* Block check type */
  7842.     if (rptflg)                /* Run length encoding */
  7843.         data[9] = rptq;            /* If receiving, agree. */
  7844.     else
  7845.         data[9] = '~';
  7846.  
  7847.     data[10] = tochar((atcapr?atcapb:0)|(lpcapr?lpcapb:0)|(swcapr?swcapb:0));
  7848.     data[capas+1] = tochar(swcapr ? wsize : 0);    /* Window size */
  7849.  
  7850.     rpsiz = urpsiz;            /* Long packets ... */
  7851.     data[capas+2] = tochar(rpsiz / 95);    /* Long packet size, big part */
  7852.     data[capas+3] = tochar(rpsiz % 95);    /* Long packet size, little part */
  7853.     data[capas+4] = '\0';        /* Terminate the init string */
  7854.     if (deblog) {
  7855.     if (deblog) debug(F110,"rpar",data+1,0);
  7856.     rdebu(capas+2);
  7857.     }
  7858.     return(data+1);            /* Return pointer to string. */
  7859. }
  7860.  
  7861. /* S P A R --Get the other system's Send-Init parameters */
  7862.  
  7863.  
  7864. spar(s) char *s; {            /* Set parameters */
  7865.     int x, lpsiz;
  7866.  
  7867.     s--;                /* Line up with field numbers. */
  7868.  
  7869. if (deblog) debug(F101,"spar rln","",rln);
  7870.  
  7871. /* Limit on size of outbound packets */
  7872.     x = (rln >= 1) ? xunchar(s[1]) : 80;
  7873.     lpsiz = spsiz;            /* Remember what they SET. */
  7874.     if (spsizf) {            /* SET-command override? */
  7875.     if (x < spsiz) spsiz = x;    /* Ignore LEN unless smaller */
  7876.     } else {                /* otherwise */
  7877.     spsiz = (x < 10) ? 80 : x;    /* believe them if reasonable */
  7878.     }
  7879.  
  7880. /* Timeout on inbound packets */
  7881.     if (!timef) {            /* Only if not SET-cmd override */
  7882.     x = (rln >= 2) ? xunchar(s[2]) : 5;
  7883.     timint = (x < 0) ? 5 : x;
  7884.     }
  7885.  
  7886. /* Outbound Padding */
  7887.     npad = 0; padch = SNDPADC;
  7888.     if (rln >= 3) {
  7889.     npad = xunchar(s[3]);
  7890.     if (rln >= 4) padch = ctl(s[4]); else padch = SNDPADC;
  7891.     }
  7892.  
  7893. /* Outbound Packet Terminator */
  7894.     seol = (rln >= 5) ? xunchar(s[5]) : '\r';
  7895.     if ((seol < 2) || (seol > 31)) seol = '\r';
  7896.     if (seol == '\r') seol = '\n';  /* VRX IVS ONLY */
  7897.  
  7898. /* Control prefix */
  7899.     x = (rln >= 6) ? s[6] : '#';
  7900.     myctlq = ((x > 32 && x < 63) || (x > 95 && x < 127)) ? x : '#';
  7901.  
  7902. /* 8th-bit prefix */
  7903.     rq = (rln >= 7) ? s[7] : 0;
  7904.     if (rq == 'Y') rqf = 1;
  7905.       else if ((rq > 32 && rq < 63) || (rq > 95 && rq < 127)) rqf = 2;
  7906.         else rqf = 0;
  7907.     switch (rqf) {
  7908.     case 0: ebqflg = 0; break;
  7909.     case 1: if (parity) { ebqflg = 1; ebq = '&'; } break;
  7910.     case 2: if (ebqflg = (ebq == sq || sq == 'Y')) ebq = rq;
  7911.     }
  7912.  
  7913. /* Block check */
  7914.     x = 1;
  7915.     if (rln >= 8) {
  7916.     x = s[8] - '0';
  7917.     if ((x < 1) || (x > 3)) x = 1;
  7918.     }
  7919.     bctr = x;
  7920.  
  7921. /* Repeat prefix */
  7922.     if (rln >= 9) {
  7923.     rptq = s[9];
  7924.     rptflg = ((rptq > 32 && rptq < 63) || (rptq > 95 && rptq < 127));
  7925.     } else rptflg = 0;
  7926.  
  7927. /* Capabilities */
  7928.     atcapu = lpcapu = swcapu = 0;
  7929.     if (rln >= 10) {
  7930.         x = xunchar(s[10]);
  7931.         atcapu = (x & atcapb) && atcapr;
  7932.     lpcapu = (x & lpcapb) && lpcapr;
  7933.     swcapu = (x & swcapb) && swcapb;
  7934.     for (capas = 10; (xunchar(s[capas]) & 1) && (rln >= capas); capas++) ;
  7935.     }
  7936.  
  7937. /* Long Packets */
  7938.     if (lpcapu) {
  7939.         if (rln > capas+2) {
  7940.         x = xunchar(s[capas+2]) * 95 + xunchar(s[capas+3]);
  7941.         if (spsizf) {        /* If overriding negotiations */
  7942.         spsiz = (x < lpsiz) ? x : lpsiz; /* do this, */
  7943.         } else {                     /* otherwise */
  7944.         spsiz = (x > MAXSP) ? MAXSP : x; /* do this. */
  7945.         }
  7946.         if (spsiz < 10) spsiz = 80;    /* Be defensive... */
  7947.     }
  7948.     }
  7949.  
  7950. /* Sliding Windows */
  7951.     if (swcapu) {
  7952.         if (rln > capas+1) {
  7953.         x = xunchar(s[capas+1]);
  7954.         wsize = x > MAXWS ? MAXWS : x;
  7955.     }
  7956.     else wsize = 1;
  7957.     }
  7958.     if (deblog) sdebu(rln);        /* Record parameters in debug log */
  7959. }
  7960.  
  7961. /*  G N F I L E  --  Get the next file name from a file group.  */
  7962.  
  7963. /*  Returns 1 if there's a next file, 0 otherwise  */
  7964.  
  7965. gnfile() {
  7966.     int x; long y;
  7967.  
  7968. /* If file group interruption (C-Z) occured, fail.  */
  7969.  
  7970.     if (deblog) debug(F101,"gnfile: czseen","",czseen);
  7971.  
  7972.     if (czseen) {
  7973.     tlog(F100,"Transaction cancelled","",0l);
  7974.     return(0);
  7975.     }
  7976.  
  7977. /* If input was stdin or memory string, there is no next file.  */
  7978.  
  7979.     if (sndsrc == 0) return(0);
  7980.  
  7981. /* If file list comes from command line args, get the next list element. *
  7982.  *
  7983.  *  y = -1;
  7984.  *  while (y < 0) {                     * Keep trying till we get one... *
  7985.  *
  7986.  *  if (sndsrc > 0) {
  7987.  *   if (nfils-- > 0) {
  7988.  *
  7989.  *      strcpy(filnam,*cmlist++);
  7990.  *        if (deblog) debug(F111,"gnfile: cmlist filnam",filnam,nfils);
  7991.  *
  7992.  *        } else {
  7993.  *        *filnam = '\0';
  7994.  *         if (deblog) debug(F101,"gnfile cmlist: nfils","",nfils);
  7995.  *        return(0);
  7996.  *        }
  7997.  *    }
  7998. */
  7999.  
  8000. /* Otherwise, step to next element of internal wildcard expansion list. */
  8001.  
  8002. /*    if (sndsrc < 0) {
  8003.  *        x = znext(filnam);
  8004.  *        if (deblog) debug(F111,"gnfile znext: filnam",filnam,x);
  8005.  *        if (x == 0) return(0);
  8006.  *    }
  8007. */
  8008.  
  8009. /* Get here with a filename. */
  8010.  
  8011. /*
  8012.  *      y = zchki(filnam);              * Check if file readable *
  8013.  *    if (y < 0) {
  8014.  *        if (deblog) debug(F110,"gnfile skipping:",filnam,0);
  8015.  *        tlog(F111,filnam,"not sent, reason",(long)y);
  8016.  *        screen(SCR_ST,ST_SKIP,0l,filnam);
  8017.  *    } else fsize = y;
  8018.  *   }
  8019.  */
  8020.  
  8021.  /* **********************************************************
  8022.  
  8023.            the two lines added above the return statement
  8024.            were not ported correctly during the 4E code
  8025.            port to VRX. I confess I did it with diff
  8026.            output. If maybe appropriate to mention, when
  8027.            using diff (unix) care must be exercised to
  8028.            prevent missed code lines as these.
  8029.  
  8030.     PEG 01/26/90
  8031.  
  8032.     ********************************************************** */
  8033.  
  8034.  
  8035.  
  8036.       y = -1;            /* this line probably useless but MCDAID
  8037.                             ported it, so why change              */
  8038.  
  8039.       x = znext(filnam);
  8040.       return(x);
  8041.  
  8042. }
  8043.  
  8044. /*  O P E N I  --  Open an existing file for input  */
  8045.  
  8046. openi(name) char *name; {
  8047.     int x, filno;
  8048.     int type;
  8049.     char xname [100];
  8050.  
  8051.     if (memstr) return(1);        /* Just return if file is memory. */
  8052.  
  8053.     if (deblog) debug(F110,"openi",name,0);
  8054.     if (deblog) debug(F101," sndsrc","",sndsrc);
  8055.  
  8056.     filno = (sndsrc == 0) ? ZSTDIO : ZIFILE;    /* ... */
  8057.  
  8058.     if (deblog) debug(F101," file number","",filno);
  8059.  
  8060.     zrtol(name,xname,&type);        /* to local form and then */
  8061.     x = zopeni(filno,xname,type);    /* try opening it again. */
  8062.     if (deblog) debug(F101," zopeni","",x);
  8063.     if (x) {
  8064.         if (deblog) debug(F110," ok",xname,0);
  8065.         return(1);            /* It worked. */
  8066.         } else {
  8067.         screen(SCR_EM,0,0l,"Can't open file");  /* It didn't work. */
  8068.         tlog(F110,xname,"could not be opened",0l);
  8069.         if (deblog) debug(F110," openi failed",xname,0);
  8070.         return(0);
  8071.         }
  8072. }
  8073.  
  8074. /*  O P E N O  --  Open a new file for output.  */
  8075.  
  8076. /*  Returns actual name under which the file was opened in string 'name2'. */
  8077.  
  8078. openo(name,name2)
  8079.     char *name, *name2;
  8080.     {
  8081.     char xname[100], *xp;
  8082.     int  type;
  8083.  
  8084.     if (stdouf)                /* Receiving to stdout? */
  8085.     return(zopeno(ZSTDIO,"",0));
  8086.  
  8087.     if (deblog) debug(F110,"openo: name",name,0);
  8088.  
  8089.     if (cxseen || czseen) {        /* If interrupted, get out before */
  8090.     if (deblog) debug(F100," open cancelled","",0);
  8091.                                 /* destroying existing file. */
  8092.     return(1);            /* Pretend to succeed. */
  8093.     }
  8094.     xp = xname;                /* OK to proceed. */
  8095.     zrtol (name,xp,&type);               /* convert name to local form */
  8096.     if (deblog) debug(F110,"openo: xname",xname,0);
  8097.  
  8098. /*  if (warn) {                 * File collision avoidance? *
  8099.  *  if (zchki(xname) != -1) {     * Yes, file exists? *
  8100.  *        znewn(xname,&xp);         * Yes, make new name. *
  8101.  *        strcpy(xname,xp);
  8102.  *        if (deblog) debug(F110," exists, new name ",xname,0);
  8103.  *       }
  8104.  *   }
  8105.  */
  8106.  
  8107.     if (zopeno(ZOFILE,xname,type) == 0) {    /* Try to open the file */
  8108.     if (deblog) debug(F110,"openo failed",xname,0);
  8109.     tlog(F110,"Failure to open",xname,0l);
  8110.     return(0);
  8111.     } else {
  8112.     strcpy(name2,xname);
  8113.     if (deblog) debug(F110,"openo ok, name2",name2,0);
  8114.     return(1);
  8115.     }
  8116. }
  8117.  
  8118. /*  O P E N T  --  Open the terminal for output, in place of a file  */
  8119.  
  8120. opent() {
  8121.     ffc = tfc = 0;
  8122.     return(zopeno(ZCTERM,"",0));
  8123. }
  8124.  
  8125. /*  C L S I F  --  Close the current input file. */
  8126.  
  8127. clsif() {
  8128.     if (memstr) {            /* If input was memory string, */
  8129.     memstr = 0;            /* indicate no more. */
  8130.     } else zclose(ZIFILE);        /* else close input file. */
  8131.  
  8132.     if (czseen || cxseen)
  8133.         screen(SCR_ST,ST_DISC,0l,"");
  8134.     else
  8135.         screen(SCR_ST,ST_OK,0l,"");
  8136.     cxseen = hcflg = 0;            /* Reset flags, */
  8137.     *filnam = '\0';            /* and current file name */
  8138. }
  8139.  
  8140.  
  8141. /*  C L S O F  --  Close an output file.  */
  8142.  
  8143. /*  Call with disp != 0 if file is to be discarded.  */
  8144. /*  Returns -1 upon failure to close, 0 or greater on success. */
  8145.  
  8146. clsof(disp) int disp; {
  8147.     int x;
  8148.     if ((x = zclose(ZOFILE)) < 0) {    /* Try to close the file */
  8149.     tlog(F100,"Failure to close",filnam,0l);
  8150.     screen(SCR_ST,ST_ERR,0l,"");
  8151.     } else if (disp && (keep == 0)) {    /* Delete it if interrupted, */
  8152.     if (*filnam) zdelet(filnam);    /* and not keeping incomplete files */
  8153.     if (deblog) debug(F100,"Discarded","",0);
  8154.     tlog(F100,"Discarded","",0l);
  8155.     screen(SCR_ST,ST_DISC,0l,"");
  8156.     } else {                /* Nothing wrong, just keep it */
  8157.     if (deblog) debug(F100,"Closed","",0);    /* and give comforting messages. */
  8158.     screen(SCR_ST,ST_OK,0l,"");
  8159.     }
  8160.     *filnam = '\0';            /* Zero the current file name. */
  8161.     return(x);                /* Send back zclose() return code. */
  8162. }
  8163.  
  8164. /*  S N D H L P  --  Routine to send builtin help  */
  8165.  
  8166. sndhlp() {
  8167.     nfils = 0;                /* No files, no lists. */
  8168.     xflg = 1;                /* Flag we must send X packet. */
  8169.     strcpy(cmdstr,"help text");        /* Data for X packet. */
  8170.     first = 1;                /* Init getchx lookahead */
  8171.     memstr = 1;                /* Just set the flag. */
  8172.     memptr = hlptxt;            /* And the pointer. */
  8173.     if (binary) {            /* If file mode is binary, */
  8174.     binary = 0;            /*  turn it back to text for this, */
  8175.     savmod = 1;            /*  remember to restore it later. */
  8176.     }
  8177.     return(sinit());
  8178. }
  8179.  
  8180.  
  8181. /*  C W D  --  Change current working directory  */
  8182.  
  8183. /*
  8184.  String passed has first byte as length of directory name, rest of string
  8185.  is name.  Fails if can't connect, else ACKs (with name) and succeeds.
  8186. */
  8187.  
  8188. cwd(vdir) char *vdir; {
  8189.     char *cdd, *zgtdir();
  8190.     vdir[xunchar(*vdir) + 1] = '\0';    /* End with a null */
  8191.     if (zchdir(vdir+1)) {
  8192.     cdd = zgtdir();            /* Get new working directory. */
  8193.     encstr(cdd);
  8194.     ack1(data);
  8195.     tlog(F110,"Changed directory to",cdd,0l);
  8196.     return(1);
  8197.     } else {
  8198.     tlog(F110,"Failed to change directory to",vdir+1,0l);
  8199.     return(0);
  8200.     }
  8201. }
  8202.  
  8203.  
  8204. /*  S Y S C M D  --  Do a system command  */
  8205.  
  8206. /*  Command string is formed by concatenating the two arguments.  */
  8207.  
  8208. syscmd(prefix,suffix) char *prefix, *suffix; {
  8209.     char *cp;
  8210.  
  8211.     if (prefix == NULL || *prefix == '\0') return(0);
  8212.  
  8213.     for (cp = cmdstr; *prefix != '\0'; *cp++ = *prefix++) ;
  8214.     while (*cp++ = *suffix++) ;
  8215.  
  8216.     if (deblog) debug(F110,"syscmd",cmdstr,0);
  8217.     if (zopeni(ZSYSFN,cmdstr,0) > 0) {
  8218.     if (deblog) debug(F100,"syscmd zopeni ok",cmdstr,0);
  8219.     nfils = sndsrc = 0;        /* Flag that input from stdin */
  8220.     xflg = hcflg = 1;        /* And special flags for pipe */
  8221.     if (binary) {            /* If file mode is binary, */
  8222.         binary = 0;            /*  turn it back to text for this, */
  8223.         savmod = 1;            /*  remember to restore it later. */
  8224.     }
  8225.     return (sinit());        /* Send S packet */
  8226.     } else {
  8227.     if (deblog) debug(F100,"syscmd zopeni failed",cmdstr,0);
  8228.     return(0);
  8229.     }
  8230. }
  8231. <<< ckvmai.c >>>
  8232. #ifndef MCS_FLAG
  8233. char     *versio = "IVS-Kermit, 4E(072) 06 June 90";
  8234. #else
  8235. char     *versio = "MCS-Kermit, 4E(072) 06 June 90";
  8236. #endif
  8237.  
  8238. /*  C K V M A I  --  V-Kermit Main program  */
  8239.  
  8240. /**********************************************************************
  8241. *                                                                     *
  8242. * IVS / MCS-Kermit REL 2                                              *
  8243. * source code                                                         *
  8244. *                                                                     *
  8245. * Change History:                                                     *
  8246. *                                                                     *
  8247. *                1. Modify C-Kermit(4E) source code to                *
  8248. *                   produce new module for MCS/IVS-Kermit             *
  8249. *                   ORIGINAL RELEASE                                  *
  8250. *                   June 22, 1990                                     *
  8251. *                                                                     *
  8252. *                                                                     *
  8253. ***********************************************************************/
  8254.  
  8255.  
  8256. /*
  8257.  4E, add long packet support, plus changes for Apollo and Data General
  8258.  support from SAS Institute, and for Macintosh from Planning Research Corp,
  8259.  plus several important bug fixes.
  8260.  
  8261.  Author: Frank da Cruz (fdc@cunixc.cc.columbia.edu, FDCCU@CUVMA.BITNET),
  8262.  Columbia University Center for Computing Activities.
  8263.  First released January 1985.
  8264.  Copyright (C) 1985, 1989, Trustees of Columbia University in the City of New
  8265.  York.  Permission is granted to any individual or institution to use, copy, or
  8266.  redistribute this software so long as it is not sold for profit, provided this
  8267.  copyright notice is retained.
  8268.  
  8269.  The Kermit file transfer protocol was developed at Columbia University.
  8270.  It is named after Kermit the Frog, star of the television series THE
  8271.  MUPPET SHOW; the name is used by permission of Henson Associates, Inc.
  8272.  "Kermit" is also Celtic for "free".
  8273.  
  8274.  Thanks to Herm Fischer of Encino CA for extensive contributions to version 4,
  8275.  and to the following people for their contributions over the years:
  8276.  
  8277.    Larry Afrin, Clemson U
  8278.    Robert Andersson, Oslo, Norway
  8279.    Stan Barber, Rice U
  8280.    Charles Brooks, EDN
  8281.    Mike Brown, Purdue U
  8282.    Bill Catchings, formerly of CUCCA
  8283.    Bob Cattani, Columbia U CS Dept
  8284.    Howard Chu, U of Michigan
  8285.    Bill Coalson, McDonnell Douglas
  8286.    Alan Crosswell, CUCCA
  8287.    Jeff Damens, formerly of CUCCA
  8288.    Joe R. Doupnik, Utah State U
  8289.    Glenn Everhart, RCA Labs
  8290.    Carl Fongheiser, CWRU
  8291.    John Gilmore, UC Berkeley
  8292.    Yekta Gursel, MIT
  8293.    Jim Guyton, Rand Corp
  8294.    Stan Hanks, Rice U.
  8295.    Ken Harrenstein, SRI
  8296.    Chuck Hedrick, Rutgers U
  8297.    Ron Heiby, Motorola Micromputer Division
  8298.    Steve Hemminger, Tektronix
  8299.    Randy Huntziger, NLM
  8300.    Phil Julian, SAS Institute
  8301.    Jim Knutson, U of Texas at Austin
  8302.    John Kunze, UC Berkeley
  8303.    David Lawyer, UC Irvine
  8304.    S.O. Lidie, Lehigh U
  8305.    Chris Maio, Columbia U CS Dept
  8306.    Leslie Mikesall, American Farm Bureau
  8307.    Martin Minow, DEC
  8308.    Ray Moody, Purdue U
  8309.    Tony Movshon, NYU
  8310.    Dan Murphy, ???
  8311.    Jim Noble, Planning Research Corporation
  8312.    Paul Placeway, Ohio State U
  8313.    Ken Poulton, HP Labs
  8314.    Frank Prindle, NADC
  8315.    Anton Rang, ???
  8316.    Scott Ribe, ???
  8317.    Jack Rouse, SAS Institute
  8318.    Stew Rubenstein, Harvard
  8319.    Dan Schullman, DEC
  8320.    Gordon Scott, Micro Focus, Newbury UK
  8321.    David Sizeland, U of London Medical School
  8322.    Bradley Smith, UCLA
  8323.    Andy Tanenbaum, THE, Netherlands
  8324.    Markku Toijala, Helsinki U of Technology
  8325.    Dave Tweten, AMES-NAS
  8326.    Walter Underwood, Ford Aerospace
  8327.    Pieter Van Der Linden, Centre Mondial (Paris)
  8328.    Wayne Van Pelt, GE/CRD
  8329.    Mark Vasoll & Gregg Wonderly, Oklahoma State University
  8330.    Stephen Walton, Ametek Computer
  8331.    Lauren Weinstein
  8332.    Joachim Wiesel, U of Karlsruhe
  8333.    Dave Woolley, CAP Communication Systems, London
  8334.    John Zeeff, Ann Arbor, MI
  8335.    Paul E. Gladden, NCR Corp., E&M San Diego
  8336.    Darrell Edwards, NCR Corp., E&M San Diego
  8337.    Paul Shaffer, NCR Corp., E&M San Diego
  8338.  and many others.
  8339. */
  8340.  
  8341. #include "ckcsym.h"
  8342. #include "ckcker.h"
  8343. #include "ckcdeb.h"
  8344.  
  8345. #ifdef MCS_FLAG
  8346. #include "mcs_defs_h"
  8347. #endif
  8348.  
  8349. char  *hlptxt="VRX Kermit Commands Supported: GET, SEND FINISH\r\n\0";
  8350.  
  8351. char  *srvtxt = "\r\n Kermit-VRX server starting. \r\n\0";
  8352.  
  8353. /* Declarations for Send-Init Parameters */
  8354.  
  8355. int     spsiz = DSPSIZ,             /* Biggest packet size we can send */
  8356. spsizf = 0,                         /* Flag to override what you ask for */
  8357. rpsiz = DRPSIZ,                     /* Biggest we want to receive */
  8358. urpsiz = DRPSIZ,                    /* User-requested rpsiz */
  8359. maxrps = MAXRP,                     /* Maximum incoming long packet size */
  8360. maxsps = MAXSP,                     /* Maximum outbound l.p. size */
  8361. maxtry = MAXTRY,                    /* Maximum retries per packet */
  8362. wsize = 1,                          /* Window size */
  8363. timint = DMYTIM,                    /* Timeout interval I use */
  8364. rtimo = URTIME,                     /* Timeout I want you to use */
  8365. timef = 0,                          /* Flag to override what you ask */
  8366. npad = MYPADN,                      /* How much padding to send */
  8367. mypadn = MYPADN,                    /* How much padding to ask for */
  8368. bctr = 1,                           /* Block check type requested */
  8369. bctu = 1,                           /* Block check type used */
  8370. ebq =  MYEBQ,                       /* 8th bit prefix */
  8371. ebqflg = 0,                         /* 8th-bit quoting flag */
  8372. rqf = -1,                           /* Flag used in 8bq negotiation */
  8373. rq = 0,                             /* Received 8bq bid */
  8374. sq = 'Y',                           /* Sent 8bq bid */
  8375. rpt = 0,                            /* Repeat count */
  8376. rptq = MYRPTQ,                      /* Repeat prefix */
  8377. rptflg = 0;                         /* Repeat processing flag */
  8378.  
  8379. int     capas = 10,                 /* Position of Capabilities */
  8380. atcapb = 8,                         /* Attribute capability */
  8381. atcapr = 0,                         /*  requested */
  8382. atcapu = 0,                         /*  used */
  8383. swcapb = 4,                         /* Sliding Window capability */
  8384. swcapr = 0,                         /*  requested */
  8385. swcapu = 0,                         /*  used */
  8386. lpcapb = 2,                         /* Long Packet capability */
  8387. lpcapr = 1,                         /*  requested */
  8388. lpcapu = 0;                         /*  used */
  8389.  
  8390. CHAR padch = SNDPADC,                /* Padding character to send */
  8391. mypadc = MYPADC,                    /* Padding character to ask for */
  8392. seol = MYEOL,                       /* End-Of-Line character to send */
  8393. eol = LF,                           /* End-Of-Line character to look for */
  8394. ctlq = CTLQ,                        /* Control prefix in incoming data */
  8395. myctlq = CTLQ;                      /* Outbound control character prefix */
  8396.  
  8397.  
  8398. /* Packet-related variables */
  8399.  
  8400. int     pktnum = 0,                 /* Current packet number */
  8401. prvpkt = -1,                        /* Previous packet number */
  8402. sndtyp,                             /* Type of packet just sent */
  8403. rsn,                                /* Received packet sequence number */
  8404. rln,                                /* Received packet length */
  8405. size,                               /* Current size of output pkt data */
  8406. osize,                              /* Previous output packet data size */
  8407. maxsize,                            /* Max size for building data field */
  8408. spktl = 0;                          /* Length packet being sent */
  8409.  
  8410. CHAR sndpkt[MAXSP+100],             /* Entire packet being sent */
  8411. recpkt[MAXRP+200],                  /* Packet most recently received */
  8412. *rdatap,                            /* Pointer to received packet data */
  8413. data[MAXSP+4],                      /* Packet data buffer */
  8414. srvcmd[MAXRP+4],                    /* Where to decode server command */
  8415. *srvptr,                            /* Pointer to above */
  8416. mystch = SOH,                       /* Outbound packet-start character */
  8417. stchr = SOH;                        /* Incoming packet-start character */
  8418.  
  8419. /* File-related variables */
  8420.  
  8421. CHAR filnam[50];                        /* Name of current file. */
  8422.  
  8423. int     nfils;                              /* Number of files in file group */
  8424. long     fsize;                             /* Size of current file */
  8425.  
  8426. /* Communication line variables */
  8427.  
  8428. CHAR ttname[50];                        /* Name of communication line. */
  8429.  
  8430. int     parity,                     /* Parity specified, 0,'e','o',etc */
  8431. flow,                               /* Flow control, 1 = xon/xoff */
  8432. speed = -1,                         /* Line speed */
  8433. turn = 0,                           /* Line turnaround handshake flag */
  8434. turnch = XON,                       /* Line turnaround character */
  8435. duplex = 0,                         /* Duplex, full by default */
  8436. escape = 034,                       /* Escape character for connect */
  8437. delay = DDELAY,                     /* Initial delay before sending */
  8438. mdmtyp = 0;                         /* Modem type (initially none)  */
  8439.  
  8440. int     tlevel = -1;                    /* Take-file command level */
  8441.  
  8442. /* Statistics variables */
  8443.  
  8444. long     filcnt,            /* Number of files in transaction */
  8445. flci,                       /* Characters from line, current file */
  8446. flco,                       /* Chars to line, current file  */
  8447. tlci,                       /* Chars from line in transaction */
  8448. tlco,                       /* Chars to line in transaction */
  8449. ffc,                        /* Chars to/from current file */
  8450. tfc;                        /* Chars to/from files in transaction */
  8451.  
  8452. int     tsecs;              /* Seconds for transaction */
  8453.  
  8454. /* Flags */
  8455.  
  8456. int     deblog = 0,                 /* Flag for debug logging */
  8457. pktlog = 0,                         /* Flag for packet logging */
  8458. seslog = 0,                         /* Session logging */
  8459. tralog = 0,                         /* Transaction logging */
  8460. displa = 0,                         /* File transfer display on/off */
  8461. stdouf = 0,                         /* Flag for output to stdout */
  8462. xflg   = 0,                         /* Flag for X instead of F packet */
  8463. hcflg  = 0,                         /* Doing Host command */
  8464. fncnv  = 1,                         /* Flag for file name conversion */
  8465. binary = 0,                         /* Flag for binary file */
  8466. savmod = 0,                         /* Saved file mode */
  8467. cmask  = 0177,                      /* Connect byte mask */
  8468. fmask  = 0377,                      /* File byte mask */
  8469. /* warn   = 0,                      Flag for file warning */
  8470. quiet  = 0,                         /* Be quiet during file transfer */
  8471. local  = 0,                         /* Flag for external tty vs stdout */
  8472. server = 0,                         /* Flag for being a server */
  8473. cnflg  = 0,                         /* Connect after transaction */
  8474. cxseen = 0,                         /* Flag for cancelling a file */
  8475. czseen = 0,                         /* Flag for cancelling file group */
  8476. send_id = 1,         /* Flag for keeping id-fields in SPUR files */
  8477. recv_id = 1,         /* Flag for keeping id-fields in SPUR files */
  8478. send_num = 1,        /* Flag for keeping line numbers in SPUR files */
  8479. recv_num = 1,        /* Flag for keeping line numbers in SPUR files */
  8480. send_renum = 0,      /* Flag for renumbering line numbers in SPUR files */
  8481. recv_renum = 0,      /* Flag for renumbering line numbers in SPUR files */
  8482. send_addnum = 0,
  8483. recv_addnum = 0,
  8484. keep = 0;                           /* Keep incomplete files */
  8485.  
  8486. /* Variables passed from command parser to protocol module */
  8487.  
  8488. char     parser();                          /* The parser itself */
  8489. char     sstate  = 0;                       /* Starting state for automaton */
  8490. char     *cmarg  = "";                      /* Pointer to command data */
  8491. char     *cmarg2 = "";                      /* Pointer to 2nd command data */
  8492. char     **cmlist;                          /* Pointer to file list in argv */
  8493.  
  8494. /* Miscellaneous */
  8495.  
  8496. char     **xargv;                           /* Global copies of argv */
  8497. int     xargc;                             /* and argc  */
  8498.  
  8499. extern char     *dftty;                 /* Default tty name from ckx???.c */
  8500. extern int     dfloc;                   /* Default location: remote/local */
  8501. extern int     dfprty;                  /* Default parity */
  8502. extern int     dfflow;                  /* Default flow control */
  8503.  
  8504. /*  M A I N  --  C-Kermit main program  */
  8505.  
  8506. main(argc, argv)
  8507. int     argc;
  8508. char     **argv;
  8509. {
  8510.  
  8511.      char     *strcpy();
  8512. #ifdef MCS_FLAG
  8513.      char     status[3];
  8514. #endif
  8515.  
  8516.      /* Do some initialization */
  8517.  
  8518. #ifdef MCS_FLAG
  8519.      mcs_enable("r",QUEUENAME,status);
  8520.      mcs_enable("w",QUEUENAME,status);
  8521. #endif
  8522.      xargc = argc;                       /* Make global copies of argc */
  8523.      xargv = argv;                       /* ...and argv. */
  8524.      sstate = 0;                         /* No default start state. */
  8525.      strcpy(ttname, dftty);               /* Set up default tty name. */
  8526.      local = dfloc;                      /* And whether it's local
  8527.                                             or remote.            */
  8528.      parity = dfprty;                    /* Set initial parity, */
  8529.      flow = dfflow;                      /* and flow control. */
  8530.      if (sysinit() < 0)
  8531.           doexit(BAD_EXIT); /* And system-dependent things. */
  8532.  
  8533.      /*** attempt to take ini file before doing command line ***/
  8534.  
  8535.      cmdini();                           /* Sets tlevel */
  8536.      while (tlevel > -1) {               /* Execute init file. */
  8537.           sstate = parser();              /* Loop getting commands. */
  8538.           if (sstate)
  8539.                proto();            /* Enter protocol if requested. */
  8540.      }
  8541.  
  8542.      /* Look for a UNIX-style command line... */
  8543.  
  8544.      if (argc > 1) {                     /* Command line arguments? */
  8545.           sstate = cmdlin();              /* Yes, parse. */
  8546.           if (sstate) {
  8547.                proto();                    /* Take any requested action,
  8548.                                               then */
  8549.                if (!quiet)
  8550.                     conoll("");     /* put cursor back at left margin, */
  8551.                if (cnflg)
  8552.                     conect();        /* connect if requested, */
  8553.                doexit(GOOD_EXIT);          /* and then exit with status 0. */
  8554.           }
  8555.      }
  8556.  
  8557.      /* If no action requested on command line, enter interactive parser */
  8558.  
  8559.      herald();                           /* Display program herald. */
  8560.      while (1) {                          /* Loop getting commands. */
  8561.           sstate = parser();
  8562.           if (sstate)
  8563.                proto();            /* Enter protocol if requested. */
  8564.      }
  8565. }
  8566. <<< ckvmcs.c >>>
  8567. /* CKVMCS_C MCS I/F routines June 14, 1990  */
  8568.  
  8569. /**********************************************************************
  8570. *                                                                     *
  8571. * MCS-Kermit REL 2                                                    *
  8572. * source code                                                         *
  8573. *                                                                     *
  8574. * Change History:                                                     *
  8575. *                                                                     *
  8576. *                1. Modify C-Kermit(4E) source code to                *
  8577. *                   produce new module for MCS/IVS-Kermit             *
  8578. *                   ORIGINAL RELEASE                                  *
  8579. *                   June 22, 1990                                     *
  8580. *                                                                     *
  8581. *                                                                     *
  8582. ***********************************************************************/
  8583.  
  8584. #include <stdio.h>
  8585. #include <ctype.h>
  8586. #include <string.h>
  8587. #include <errno.h>
  8588. #include <fcntl.h>
  8589. #include <time.h>
  8590. #include "mcs_defs_h"
  8591. #include "ckcdeb.h"     /* DRE 020190 */
  8592. #include "ckcker.h"     /* DRE 060690 */
  8593.  
  8594. #define SCR_EM 9        /* PEG 013090 */
  8595. #define MCSLIMIT 200
  8596.  
  8597. extern int     server;     /* PEG 013090 */
  8598. extern char     *free();
  8599. extern char     *malloc();
  8600. extern int     deblog;       /* DRE 021690 */
  8601. extern int     doexit();
  8602.  
  8603. static struct OutputCD *OCDptr = &OutCD;
  8604. static struct InputCD *ICDptr = &InCD;
  8605. static struct SParBlck *SPBptr = &SParBlock;
  8606. static struct RParBlck *RPBptr = &RParBlock;
  8607. static struct ParBlck *PBptr  = &ParBlock;
  8608. static char     mcs_tmpstr[MCSLIMIT];
  8609. static char     *blanks = "                                   ";
  8610. static char     *spb_param = NULL;                  /* DRE 020190 */
  8611.  
  8612. static char     realmesg[MAXSP];                    /* DRE 060690 */
  8613.  
  8614.  
  8615. /*******************************************************************
  8616. *                                                                  *
  8617. *                   str_convert                                    *
  8618. *                                                                  *
  8619. *    converts non-printable MCS structures to a hex format         *
  8620. *                                                                  *
  8621. *    PEG  June 4, 1990                                             *
  8622. *                                                                  *
  8623. ********************************************************************/
  8624.  
  8625. void str_convert(mcs_ptr, lgth)
  8626. char     *mcs_ptr;
  8627. int     lgth;
  8628. {
  8629.      char     *cptr;
  8630.      int     i, j, flag = 0;
  8631.      static char     hexchar[] = {
  8632.           '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
  8633.                                       'B', 'C', 'D', 'E', 'F'          };
  8634.  
  8635.      if ((lgth * 2) > MCSLIMIT) {
  8636.           fprintf(stderr, "\nstr_convert lgth over MCSLIMIT...\n\n");
  8637.           mcs_tmpstr[0] = '\0';
  8638.           return;
  8639.      }
  8640.  
  8641.      for (j = 0, cptr = mcs_ptr; j < lgth; j++, cptr++)
  8642.           if (!isprint(*cptr))
  8643.                flag = 1;
  8644.  
  8645.      if (!flag) {
  8646.           strncpy(mcs_tmpstr, mcs_ptr, lgth);
  8647.           *(mcs_ptr + lgth + 1) = '\0';
  8648.           return;
  8649.      } else {
  8650.           for (j = 0, i = 0; j < lgth; j++) {
  8651.  
  8652.                if (*cptr < 0x10)             /* high order bits */
  8653.                     mcs_tmpstr[i++] = '0';
  8654.                else
  8655.                     mcs_tmpstr[i++] = hexchar[*cptr++ / 0x10];
  8656.  
  8657.                if (*cptr == 0x00)           /* low order bits */
  8658.                     mcs_tmpstr[i++] = '0';
  8659.                else
  8660.                     mcs_tmpstr[i++] = hexchar[*cptr++ % 0x10];
  8661.           }
  8662.           mcs_tmpstr[i] = '\0';
  8663.  
  8664.           if (i + 25 > MCSLIMIT)
  8665.                fprintf(stderr, "Next line converted to HEX...\n");
  8666.           else
  8667.                strcat(mcs_tmpstr, " *** converted to hex *** ");
  8668.      }
  8669. }
  8670.  
  8671.  
  8672. /*******************************************************************
  8673. *                                                                  *
  8674. *                   dump routines                                  *
  8675. *                                                                  *
  8676. *    dumps MCS control structures for mcs_send                      *
  8677. *                                     mcs_recv                      *
  8678. *                                                                  *
  8679. *    PEG  June 4, 1990                                             *
  8680. *                                                                  *
  8681. ********************************************************************/
  8682.  
  8683. void dump_OCD()
  8684. {
  8685.      fprintf(stderr, "\nDumping OCDptr...\n");
  8686.      str_convert(OCDptr->destcnt, 4);
  8687.      fprintf(stderr, "OCDptr->destcnt: %s\n", mcs_tmpstr);
  8688.      str_convert(OCDptr->textlen, 4);
  8689.      fprintf(stderr, "OCDptr->textlen: %s\n", mcs_tmpstr);
  8690.      str_convert(OCDptr->statkey, 2);
  8691.      fprintf(stderr, "OCDptr->statkey: %s\n", mcs_tmpstr);
  8692.      fprintf(stderr, "OCDptr->errkey: %#X\n", OCDptr->errkey);
  8693.      str_convert(OCDptr->symdest, 12);
  8694.      fprintf(stderr, "OCDptr->symdest: %s\n", mcs_tmpstr);
  8695.      fprintf(stderr, "OCDptr->ExOutCD.xoformat: %#X\n",
  8696.                       OCDptr->ExOutCD.xoformat);
  8697.      str_convert(OCDptr->ExOutCD.tcfunction, 3);
  8698.      fprintf(stderr, "OCDptr->ExOutCD.tcfunction: %s\n", mcs_tmpstr);
  8699.      str_convert(OCDptr->ExOutCD.tcqualifier, 3);
  8700.      fprintf(stderr, "OCDptr->ExOutCD.tcqualifier: %s\n", mcs_tmpstr);
  8701.      fprintf(stderr, "OCDptr->ExOutCD.tcoutput_reset: %#X\n",
  8702.                       OCDptr->ExOutCD.tcoutput_reset);
  8703. }
  8704.  
  8705.  
  8706. void dump_ICD()
  8707. {
  8708.      fprintf(stderr, "\nDumping ICDptr...\n");
  8709.      str_convert(ICDptr->q, 12);
  8710.      fprintf(stderr, "ICDptr->q: %s\n", mcs_tmpstr);
  8711.      str_convert(ICDptr->symq1, 12);
  8712.      fprintf(stderr, "ICDptr->symq1: %s\n", mcs_tmpstr);
  8713.      str_convert(ICDptr->symq2, 12);
  8714.      fprintf(stderr, "ICDptr->symq2: %s\n", mcs_tmpstr);
  8715.      str_convert(ICDptr->symq3, 12);
  8716.      fprintf(stderr, "ICDptr->symq3: %s\n", mcs_tmpstr);
  8717.      str_convert(ICDptr->mdate, 6);
  8718.      fprintf(stderr, "ICDptr->mdate: %s\n", mcs_tmpstr);
  8719.      str_convert(ICDptr->mtime, 8);
  8720.      fprintf(stderr, "ICDptr->mtime: %s\n", mcs_tmpstr);
  8721.      str_convert(ICDptr->source, 12);
  8722.      fprintf(stderr, "ICDptr->source: %s\n", mcs_tmpstr);
  8723.      str_convert(ICDptr->len, 4);
  8724.      fprintf(stderr, "ICDptr->len: %s\n", mcs_tmpstr);
  8725.      fprintf(stderr, "ICDptr->endkey: %#X\n", ICDptr->endkey);
  8726.      str_convert(ICDptr->statkey, 2);
  8727.      fprintf(stderr, "ICDptr->statkey: %s\n", mcs_tmpstr);
  8728.      str_convert(ICDptr->msgcnt, 6);
  8729.      fprintf(stderr, "ICDptr->msgcnt: %s\n", mcs_tmpstr);
  8730.      fprintf(stderr, "ICDptr->ExInCD.xiformat: %#X\n",
  8731.                       ICDptr->ExInCD.xiformat);
  8732.      str_convert(ICDptr->ExInCD.xistatus, 2);
  8733.      fprintf(stderr, "ICDptr->ExInCD.xistatus: %s\n", mcs_tmpstr);
  8734.      str_convert(ICDptr->ExInCD.xipassthru, 10);
  8735.      fprintf(stderr, "ICDptr->ExInCD.xipassthru: %s\n", mcs_tmpstr);
  8736. }
  8737.  
  8738.  
  8739. void dump_SPB()
  8740. {
  8741.      fprintf(stderr, "\nDumping SDBptr...\n");
  8742.      fprintf(stderr, "SPBptr->length: %d\n", SPBptr->length);
  8743.      fprintf(stderr, "SPBptr->complver: % #X\n", SPBptr->complver);
  8744.      fprintf(stderr, "SPBptr->linenum: %#X\n", SPBptr->linenum);
  8745.      fprintf(stderr, "SPBptr->indicator: %#X\n", SPBptr->indicator);
  8746.      fprintf(stderr, "SPBptr->advancing: %#X\n", SPBptr->advancing);
  8747.      fprintf(stderr, "SPBptr->position: %#X\n", SPBptr->position);
  8748.      fprintf(stderr, "SPBptr->sendcount: %#X\n", SPBptr->sendcount);
  8749.      str_convert(SPBptr->mnemonic, 4);
  8750.      fprintf(stderr, "SPBptr->mnemonic: %s\n", mcs_tmpstr);
  8751. }
  8752.  
  8753.  
  8754. void dump_RPB()
  8755. {
  8756.      fprintf(stderr, "\nDumping RPBptr...\n");
  8757.      fprintf(stderr, "RPBptr->length: %d\n", RPBptr->length);
  8758.      fprintf(stderr, "RPBptr->complver: %#X\n", RPBptr->complver);
  8759.      fprintf(stderr, "RPBptr->avail: %#X\n", RPBptr->avail);
  8760.      fprintf(stderr, "RPBptr->indicator: %#X\n", RPBptr->indicator);
  8761. }
  8762.  
  8763.  
  8764. /********************************************************************
  8765. *                                                                   *
  8766. *                  Function mcserr                                  *
  8767. *                  called when status returned by MCS               *
  8768. *                  routines return anything other than 00           *
  8769. *                  outputs an error message                         *
  8770. *                                                                   *
  8771. *                  Paul E. Gladden                                  *
  8772. *                  May 3, 1990                                      *
  8773. *                  June 14, 1990 update dump ICD / OCD struct       *
  8774. *                                                                   *
  8775. *                  assumes status bytes are ascii                   *
  8776. *                  chars                                            *
  8777. *                                                                   *
  8778. *********************************************************************/
  8779.  
  8780. void mcserr(cin, status, errsend)
  8781. char     cin;
  8782. char     status[2];
  8783. char     errsend;
  8784. {
  8785.  
  8786.      char     str1[100];
  8787.      long     errclk;
  8788.      char     *cptr;
  8789.  
  8790.      str1[0] = '\0';
  8791.  
  8792.      errclk = time((long *) 0);               /* time stamping mcs errors */
  8793.      sprintf(str1, "\n%s", ctime(&errclk));
  8794.      cptr = strrchr(str1, '\n');
  8795.      if (cptr != NULL) {
  8796.           *cptr++ = ' ';         /* removing \n put in by ctime */
  8797.           *cptr = '\0';
  8798.      }
  8799.  
  8800.      switch (cin)  {
  8801.      case 'd' :
  8802.           strcat(str1, "MCS Error Status: Disable ");
  8803.           break;
  8804.      case 'e' :
  8805.           strcat(str1, "MCS Error Status: Enable ");
  8806.           break;
  8807.      case 'a' :
  8808.           strcat(str1, "MCS Error Status: Accept ");
  8809.           break;
  8810.      case 's' :
  8811.           strcat(str1, "MCS Error Status: Send ");
  8812.           break;
  8813.      case 'r' :
  8814.           strcat(str1, "MCS Error Status: Receive ");
  8815.           break;
  8816.      default :
  8817.           strcat(str1, "MCS Error Status: Unknown ");
  8818.           break;
  8819.      }
  8820.  
  8821.      strncat (str1, status, 2);
  8822.  
  8823.      if ( cin == 's' )  {      /* moves errorkey char into error output */
  8824.           char     valtmp[3];  /* with an error condition occurs with a */
  8825.                                /* mcs_send   PEG 020590                 */
  8826.           valtmp[0] = ' ';
  8827.           valtmp[1] = errsend;
  8828.           valtmp[2] = '\0';
  8829.  
  8830.           strncat(str1, valtmp, 2);
  8831.      }
  8832.  
  8833.      strncat(str1, "\n", 1);                             /* DRE 021690 */
  8834.      write(2, str1, (unsigned)(strlen(str1)));
  8835.      if (deblog)
  8836.           debug(F110, "funct: mcserr> ", str1, 0);
  8837.  
  8838.      if (cin == 'e' && !(strncmp(status, "00", 2))) {       /* enable failed
  8839.                                                                exiting...     */
  8840.           if (!(strncmp(status, "12", 2)))
  8841.                return;
  8842.  
  8843.           sprintf(str1, "MCSENABLE failed...program exiting...\n");
  8844.           write(2, str1, (unsigned)(strlen(str1)));
  8845.           doexit(BAD_EXIT);
  8846.      }
  8847.      if (deblog) {
  8848.           if ( cin == 's' ) {
  8849.                dump_OCD();
  8850.                dump_SPB();
  8851.           }
  8852.  
  8853.           if ( cin == 'r' ) {
  8854.                dump_ICD();
  8855.                dump_RPB();
  8856.           }
  8857.      }
  8858.  
  8859. }
  8860.  
  8861.  
  8862. mcs_disable(io, qname, status)
  8863. char     *io;
  8864. char     *qname;
  8865. char     status[3];
  8866. {
  8867.      char     passwd[PWDLEN];
  8868.  
  8869.      init_pwd(passwd);
  8870.  
  8871.      if (deblog)
  8872.           debug(F100, "funct: mcs_disable", "", 0);
  8873.  
  8874.      if ((*io == 'r') || (*io == 'R')) {
  8875.           /* disable the input queue */
  8876.           init_ipb();
  8877.           init_icd(qname);
  8878.           MCS\:DSABLE(ICDptr, passwd, PBptr);     /* DRE 013190 */
  8879.           status[0] = ICDptr->statkey[0];       /* DRE 013190 */
  8880.           status[1] = ICDptr->statkey[1];       /* DRE 013190 */
  8881.           status[2] = '\0';                     /* DRE 013190 */
  8882.      } else {
  8883.           /* disable the output */
  8884.           init_opb();                           /* DRE 012990 */
  8885.           init_ocd();                           /* DRE 012990 */
  8886.           MCS\:DSABLE(OCDptr, passwd, PBptr);     /* DRE 013190 */
  8887.           status[0] = OCDptr->statkey[0];       /* DRE 013190 */
  8888.           status[1] = OCDptr->statkey[1];       /* DRE 013190 */
  8889.           status[2] = '\0';                     /* DRE 013190 */
  8890.      }
  8891.  
  8892.      if ((status[0] != '0') || (status[1] != '0'))  /* PEG 013090 */
  8893.           mcserr ('d', status, 'x');
  8894.  
  8895. }
  8896.  
  8897.  
  8898. mcs_enable(io, qname, status)
  8899. char     *io;
  8900. char     *qname;
  8901. char     status[3];
  8902. {
  8903.      char     passwd[PWDLEN];
  8904.  
  8905.      init_pwd(passwd);
  8906.  
  8907.      if (deblog)
  8908.           debug(F100, "funct: mcs_enable", "", 0);
  8909.  
  8910.      if ((*io == 'r') || (*io == 'R')) {
  8911.           /* enable the input */
  8912.           init_ipb();
  8913.           init_icd(qname);
  8914.           init_rpb();     /* DRE 021690 - Done here for performance */
  8915.           MCS\:ENABLE(ICDptr, passwd, PBptr);     /* DRE 013190 */
  8916.           status[0] = ICDptr->statkey[0];       /* DRE 013190 */
  8917.           status[1] = ICDptr->statkey[1];       /* DRE 013190 */
  8918.           status[2] = '\0';                     /* DRE 013190 */
  8919.      } else {
  8920.           /* enable the output */
  8921.           init_opb();                           /* DRE 012990 */
  8922.           init_ocd();                           /* DRE 012990 */
  8923.           init_spb();   /* DRE 021690 - Done here for performance */
  8924.           MCS\:ENABLE(OCDptr, passwd, PBptr);     /* DRE 013190 */
  8925.           status[0] = OCDptr->statkey[0];       /* DRE 013190 */
  8926.           status[1] = OCDptr->statkey[1];       /* DRE 013190 */
  8927.           status[2] = '\0';                     /* DRE 013190 */
  8928.      }
  8929.  
  8930.      if ((status[0] != '0') || (status[1] != '0'))   /* PEG 013090 */
  8931.           mcserr ('e', status, 'x');
  8932.  
  8933. }
  8934.  
  8935.  
  8936. init_pwd(passwd)
  8937. char     *passwd;
  8938. {
  8939.  
  8940.      strncpy(passwd, blanks, PWDLEN);
  8941.      strncpy(passwd, PASSWD, strlen(PASSWD));
  8942. }
  8943.  
  8944.  
  8945. init_icd(qname)
  8946. char     *qname;
  8947. {
  8948.      strncpy(ICDptr->q, blanks, 12);
  8949.      strncpy(ICDptr->q, qname, strlen(qname));
  8950.      strncpy(ICDptr->symq1, blanks, 12);
  8951.      strncpy(ICDptr->symq2, blanks, 12);
  8952.      strncpy(ICDptr->symq3, blanks, 12);
  8953.      strncpy(ICDptr->mdate, blanks, 6);
  8954.      strncpy(ICDptr->mtime, blanks, 8);
  8955.      strncpy(ICDptr->source, blanks, 12);
  8956.      strncpy(ICDptr->source, IN_TERM, strlen(IN_TERM));
  8957.      strncpy(ICDptr->len, blanks, 4);
  8958.      strncpy(ICDptr->statkey, blanks, 2);
  8959.      strncpy(ICDptr->msgcnt, blanks, 6);             /* DRE 020290 */
  8960.  
  8961.      /* DRE 012990 - removed reference to filler and
  8962.         msgcnt3 parameters */
  8963.  
  8964.      strncpy(ICDptr->ExInCD.xistatus, blanks, 2);
  8965.      strncpy(ICDptr->ExInCD.xipassthru, blanks, 3);
  8966.      ICDptr->endkey = 0x20;
  8967.      ICDptr->ExInCD.xiformat = 0x20;
  8968.      strncpy(ICDptr->ExInCD.xifiller, blanks, 27);   /* DRE 012990 */
  8969. }
  8970.  
  8971.  
  8972. init_recv_icd()
  8973. {
  8974.      ICDptr->endkey = 0x32;
  8975.      strncpy(ICDptr->statkey, "00", 2);
  8976.      ICDptr->ExInCD.xiformat = 0x30;
  8977.      strncpy(ICDptr->ExInCD.xistatus, blanks, 2);
  8978.      strncpy(ICDptr->ExInCD.xipassthru, blanks, 10);
  8979. }
  8980.  
  8981.  
  8982. init_ocd()
  8983. {
  8984.      strncpy(OCDptr->destcnt, "0001", 4);
  8985.      strncpy(OCDptr->textlen, blanks, 4);
  8986.      strncpy(OCDptr->statkey, blanks, 2);
  8987.      OCDptr->errkey = 0x20;
  8988.      strncpy(OCDptr->symdest, blanks, 12);           /* DRE 012990 */
  8989.      strncpy(OCDptr->symdest, OUT_TERM, strlen(OUT_TERM));
  8990.      OCDptr->ExOutCD.xoformat = 0x30;
  8991.      strncpy(OCDptr->ExOutCD.tcfunction, blanks, 3);
  8992.      strncpy(OCDptr->ExOutCD.tcqualifier, blanks, 3);
  8993.      strncpy(OCDptr->ExOutCD.xofiller, blanks, 33);  /* DRE 012990 */
  8994.      OCDptr->ExOutCD.tcoutput_reset = 0x20;        /* DRE 012990 */
  8995. }
  8996.  
  8997.  
  8998. init_write_ocd(mesglength, destination)
  8999. int     mesglength;
  9000. char     *destination;
  9001. {
  9002.      char     len[5];
  9003.  
  9004.      sprintf(len, "%0.4d", mesglength);
  9005.      strncpy(OCDptr->textlen, len, 4);
  9006.      SPBptr->length = (short)mesglength;
  9007.      strncpy(OCDptr->statkey, "00", 2);
  9008.      OCDptr->errkey = 0x30;
  9009.      strncpy(OCDptr->symdest, blanks, 12);
  9010.      strncpy(OCDptr->symdest, destination, strlen(destination));
  9011. }
  9012.  
  9013.  
  9014. init_ipb()
  9015. {
  9016.      PBptr->denabltyp = IPPHASE;
  9017.      PBptr->passwdlen = PWDLEN;
  9018.      PBptr->complver = COMPVER;
  9019.      PBptr->destcount = 0x00;
  9020.      strncpy(PBptr->filler, blanks, 8);              /* DRE 012990 */
  9021.      /* DRE 012990 - remove references to indicator,
  9022.         advancing, position, sendcount, and mnemonic fields */
  9023. }
  9024.  
  9025.  
  9026. init_opb()
  9027. {
  9028.      PBptr->denabltyp = OPPHASE;
  9029.      PBptr->passwdlen = PWDLEN;
  9030.      PBptr->complver = COMPVER;
  9031.      PBptr->destcount = 0x00;
  9032.      strncpy(PBptr->filler, blanks, 8);              /* DRE 012990 */
  9033.      /* DRE 012990 - remove references to indicator,
  9034.         advancing, position, sendcount, and mnemonic fields */
  9035. }
  9036.  
  9037.  
  9038. init_rpb()
  9039. {
  9040.      RPBptr->length = 0x0050;
  9041.      RPBptr->complver = COMPVER;
  9042.      RPBptr->avail = 0x02;          /* suspend if input Q empty */
  9043.      RPBptr->indicator = EMI;
  9044.      strncpy(RPBptr->filler, blanks, 7);             /* DRE 012990 */
  9045.      /* DRE 012990 - remove references to advancing and
  9046.         position fields */
  9047. }
  9048.  
  9049.  
  9050. init_spb()
  9051. {
  9052.      /* length field set by init_write_ocd */
  9053.      SPBptr->complver = COMPVER;
  9054.      SPBptr->linenum = 0x00;
  9055.      SPBptr->indicator = EMI;
  9056.      /*      SPBptr->advancing = AFTER;  */
  9057.      SPBptr->advancing = 0x00;                     /* DRE 020990 */
  9058.      SPBptr->position = 0x00;                      /* DRE 020990 */
  9059.      /*      SPBptr->position = LINE;  */
  9060.      SPBptr->sendcount = 0x01;                     /* DRE 012990 */
  9061.      /*      SPBptr->mnemonic.type = 0x01; */
  9062.      SPBptr->mnemonic[0] = 0x01;              /* mnemonic type */
  9063.      if (spb_param == NULL) {
  9064.           spb_param = (char *) malloc(6 * sizeof(char));
  9065.           *spb_param = 0x04;
  9066.           *(spb_param + 1) = '\0';
  9067.           strcat(spb_param, "UNFM");
  9068.      }
  9069.      /*      SPBptr->mnemonic.address = spb_param;  */
  9070.      SPBptr->mnemonic[1] = *((char *) & spb_param + 1);   /* set address */
  9071.      SPBptr->mnemonic[2] = *((char *) & spb_param + 2);
  9072.      SPBptr->mnemonic[3] = *((char *) & spb_param + 3);
  9073. }
  9074.  
  9075.  
  9076. mcs_accept(qname)
  9077. char     *qname;
  9078. {
  9079.      char     msgcnt[7];
  9080.      int     mesg_no;
  9081.      char     status[2];
  9082.  
  9083.      if (deblog)
  9084.           debug(F100, "funct: mcs_accept", "", 0);
  9085.  
  9086.      init_icd(qname);
  9087.  
  9088. #ifndef lint
  9089.      MCS\:ACCEPT(ICDptr);
  9090. #endif
  9091.      if ((ICDptr->statkey[0] != '0') ||  (ICDptr->statkey[1] != '0'))    {
  9092.  
  9093.           status[0] = ICDptr->statkey[0];
  9094.           status[1] = ICDptr->statkey[1];
  9095.           status[2] = '\0';
  9096.           mcserr ('a', status, 'x');
  9097.      }
  9098.      strncpy(msgcnt, ICDptr->msgcnt, 6);
  9099.      msgcnt[6] = '\0';
  9100.      mesg_no = atoi(msgcnt);
  9101.      return mesg_no;
  9102. }
  9103.  
  9104.  
  9105. mcs_recv(qname, mesg, mesglength, source, status)
  9106. char     *qname;
  9107. char     *mesg;
  9108. int     *mesglength;
  9109. char     *source;
  9110. char     status[3];
  9111. {
  9112.      char     len_str[5];
  9113.  
  9114.      if (deblog)
  9115.           debug(F100, "funct:mcs_recv", "", 0);
  9116.  
  9117.      init_icd(qname);
  9118.      init_recv_icd();
  9119.      /*      init_rpb(); */
  9120.  
  9121. #ifndef lint
  9122.      MCS\:RECEIV(ICDptr, mesg, RPBptr);
  9123. #else
  9124.      fgets(mesg, 200, stdin);
  9125.      sprintf(len_str, "%0.4d", strlen(mesg));
  9126.      strncpy(ICDptr->len, len_str, 4);
  9127.      *mesglength = strlen(mesg);
  9128.      strcpy(status, "00");
  9129. #endif
  9130.      strncpy(len_str, ICDptr->len, 4);
  9131.      len_str[4] = '\0';
  9132.      *mesglength = atoi(len_str);
  9133.  
  9134.      if (mesg[*mesglength - 1] == '\r')
  9135.        mesg[*mesglength - 1] = '\n';
  9136.  
  9137.      mesg[*mesglength] = '\0';
  9138.  
  9139. /*
  9140.  *   mesg[*mesglength] = '\n';
  9141.  *    mesg[*mesglength+1] = '\0';
  9142.  */
  9143.      source = ICDptr->source;
  9144.      status[0] = ICDptr->statkey[0];
  9145.      status[1] = ICDptr->statkey[1];
  9146.      status[2] = '\0';
  9147.  
  9148.      if (deblog)
  9149.           debug(V110, "mcs_recv:mesg ", mesg, *mesglength);  /* PEG  042490 */
  9150.      if (deblog)
  9151.           debug(F111, "funct:mcs_recv", "mesglength", *mesglength);
  9152.  
  9153.      if ((status[0] != '0') || (status[1] != '0'))      /* PEG 013090 */
  9154.           mcserr ('r', status, 'x');
  9155.  
  9156. }
  9157.  
  9158.  
  9159. mcs_send(qname, mesg, mesglength, destination, status)
  9160. char     *qname;
  9161. char     *mesg;
  9162. int     mesglength;
  9163. char     *destination;
  9164. char     status[3];
  9165. {
  9166.      char     source[80];
  9167.      int     i, j, mesg_no, count;
  9168.  
  9169.      i = j = 0;
  9170.  
  9171.      while (mesg[i] != '\0') {
  9172.           realmesg[j] = mesg[i];
  9173.           if (realmesg[j] == '\n') {
  9174.                mesglength++;
  9175.                realmesg[++j] = '\r';
  9176.           }
  9177.           i++;
  9178.           j++;
  9179.      }
  9180.  
  9181.      realmesg[j] = '\0';
  9182.  
  9183.      if (deblog)
  9184.           debug(F110, "funct: mcs_send ", realmesg, 0);
  9185.  
  9186.      init_write_ocd(mesglength, destination);
  9187.  
  9188. #ifndef lint
  9189.      MCS\:SEND(OCDptr, realmesg, SPBptr);
  9190. #else
  9191.      for (count = 0; count < mesglength; count++) {
  9192.           if (mesg[count] != '\r')
  9193.                putchar(mesg[count]);
  9194.      }
  9195.      strcpy(status, "00");
  9196. #endif
  9197.  
  9198.      /* This code removed the returned statuses
  9199.         passed back from MCS from the respective
  9200.         queues. At present we check the status
  9201.         from MCS returned from the system call.
  9202.         But we do NOT check any statuses placed on
  9203.         the queues. McDaid threw the statuses away
  9204.         after removing them from the queue. MCS
  9205.         now never places the statuses on the queue.
  9206.         This was done by changing MCSKNDLJ OPRTN
  9207.         parameter from BOTH to NONE. MCS now does
  9208.         the work we use to do. A small performance
  9209.         gain should result.
  9210.  
  9211.         PEG April 19, 1990
  9212.  
  9213.         mesg_no = mcs_accept(qname);
  9214.  
  9215.         for (i=0;i<mesg_no;i++) {
  9216.              mcs_recv(qname,mesg,&mesglength,source,status);
  9217.              mesg[mesglength] = '\0';
  9218.         }
  9219. */
  9220.      status[0] = OCDptr->statkey[0];
  9221.      status[1] = OCDptr->statkey[1];
  9222.      status[2] = '\0';
  9223.  
  9224.      if ((status[0] != '0') || (status[1] != '0'))      /* PEG 013090 */
  9225.           mcserr ('s', status, OCDptr->errkey);
  9226.  
  9227. }
  9228. <<< ckvpro.c >>>
  9229. /* WARNING -- This C source program generated by Wart preprocessor. */
  9230. /* Do not edit this file; edit the Wart-format source file instead, */
  9231. /* and then run it through Wart to produce a new C source file.     */
  9232.  
  9233. /* Wart Version Info: */
  9234. char     *wartv = "Wart Version 1A(006) May 1990";
  9235.  
  9236. #ifndef MCS_FLAG
  9237. char     *protv = "IVS-Kermit Protocol Module 4E(032), 31 May 90";
  9238. #else
  9239. char     *protv = "MCS-Kermit Protocol Module 4E(032), 31 May 90";
  9240. #endif
  9241.                           /* -*-C-*- */
  9242.  
  9243. /* C K V P R O  -- C-Kermit Protocol Module, in Wart preprocessor notation. */
  9244.  
  9245. /**********************************************************************
  9246. *                                                                     *
  9247. * IVS / MCS-Kermit REL 2                                              *
  9248. * source code                                                         *
  9249. *                                                                     *
  9250. * Change History:                                                     *
  9251. *                                                                     *
  9252. *                1. Modify C-Kermit(4E) source code to                *
  9253. *                   produce new module for MCS/IVS-Kermit             *
  9254. *                   ORIGINAL RELEASE                                  *
  9255. *                   June 22, 1990                                     *
  9256. *                                                                     *
  9257. *                                                                     *
  9258. ***********************************************************************/
  9259.  
  9260.  
  9261. /*
  9262.  Authors: Frank da Cruz (SY.FDC@CU20B), Bill Catchings, Jeff Damens;
  9263.  Columbia University Center for Computing Activities, January 1985.
  9264.  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
  9265.  Permission is granted to any individual or institution to use, copy, or
  9266.  redistribute this software so long as it is not sold for profit, provided this
  9267.  copyright notice is retained.
  9268. */
  9269. #include "ckcdeb.h"
  9270. #include "ckcker.h"
  9271. /*
  9272.  Note -- This file may also be preprocessed by the NCR-VRX Lex program, but
  9273.  you must indent the above #include statements before using Lex, and then
  9274.  restore them to the left margin in the resulting C program before compilation.
  9275.  Also, the invocation of the "wart()" function below must be replaced by an
  9276.  invocation  of the "yylex()" function.  It might also be necessary to remove
  9277.  comments in the %%...%% section.
  9278. */
  9279.  
  9280. /* State definitions for Wart (or Lex) */
  9281. #define ipkt 1
  9282. #define rfile 2
  9283. #define rdata 3
  9284. #define ssinit 4
  9285. #define ssfile 5
  9286. #define ssdata 6
  9287. #define sseof 7
  9288. #define sseot 8
  9289. #define serve 9
  9290. #define generic 10
  9291. #define get 11
  9292. #define rgen 12
  9293.  
  9294. /* External C-Kermit variable declarations */
  9295. extern char     sstate, deblog, *versio, *srvtxt, *cmarg, *cmarg2, *rpar();
  9296. extern char     data[], filnam[], srvcmd[], ttname[], *srvptr;
  9297. extern int     pktnum, timint, nfils, hcflg, xflg, speed, flow, mdmtyp;
  9298. extern int     prvpkt, cxseen, czseen, server, local, displa, bctu, bctr,
  9299.                quiet;
  9300. extern int     tsecs, parity, backgrd;
  9301. extern int     putsrv(), puttrm(), putfil(), errpkt();
  9302. extern char     *rdatap;
  9303.  
  9304. /* Local variables */
  9305. static char     vstate = 0;               /* Saved State   */
  9306. static char     vcmd = 0;                 /* Saved Command */
  9307. int     x;                                /* General-purpose integer */
  9308. char     *s;                              /* General-purpose string pointer */
  9309.  
  9310. /* Macros - Note, BEGIN is predefined by Wart (and Lex) */
  9311. #define SERVE  tinit(); BEGIN serve
  9312. #define RESUME if (server) { SERVE; } else { sleep(2); return; }
  9313.  
  9314.  
  9315. #define BEGIN state =
  9316.  
  9317. int     state = 0;
  9318.  
  9319. wart()
  9320. {
  9321.      int     c, actno;
  9322.      extern short     tbl[];
  9323.      while (1) {
  9324.           c = input();
  9325.           if ((actno = tbl[c + state*128]) != -1)
  9326.                switch (actno) {
  9327.                case 1:
  9328.                      {
  9329.                          tinit();                /* Do Send command */
  9330.                          if (sinit())
  9331.                               BEGIN ssinit;
  9332.                          else
  9333.                               RESUME;
  9334.                     }
  9335.                     break;
  9336.                case 2:
  9337.                      {
  9338.                          tinit();
  9339.                          BEGIN get;
  9340.                     }
  9341.                     break;
  9342.                case 3:
  9343.                      {
  9344.                          tinit();
  9345.                          vstate = get;
  9346.                          vcmd = 0;
  9347.                          sipkt('I');
  9348.                          BEGIN ipkt;
  9349.                     }
  9350.                     break;
  9351.                case 4:
  9352.                      {
  9353.                          tinit();
  9354.                          vstate = rgen;
  9355.                          vcmd = 'C';
  9356.                          sipkt('I');
  9357.                          BEGIN ipkt;
  9358.                     }
  9359.                     break;
  9360.                case 5:
  9361.                      {
  9362.                          tinit();
  9363.                          vstate = rgen;
  9364.                          vcmd = 'G';
  9365.                          sipkt('I');
  9366.                          BEGIN ipkt;
  9367.                     }
  9368.                     break;
  9369.                case 6:
  9370.                      {
  9371.                          sleep(1);
  9372.                          SERVE;
  9373.                     }
  9374.                     break;
  9375.                case 7:
  9376.                      {   /* "Abort" -- Tell other side. */
  9377.                          errpkt("User cancelled transaction");
  9378.                          x = quiet;
  9379.                          quiet = 1;               /* Close files silently. */
  9380.                          clsif();
  9381.                          clsof(1);
  9382.                          quiet = x;
  9383.                          return(0);
  9384.                     }
  9385.                     break;
  9386.                case 8:
  9387.                      {
  9388.                          rinit(rdatap);
  9389.                          bctu = bctr; /* Get Send-Init */
  9390.                          resetc();                    /* Reset counters */
  9391.                          rtimer();                    /* Reset timer */
  9392.                          BEGIN rfile;
  9393.                     }
  9394.                     break;
  9395.                case 9:
  9396.                      {
  9397.                          spar(rdatap);             /* Get ack for I-packet */
  9398.                          if (vcmd) {
  9399.                               scmd(vcmd, cmarg);
  9400.                               vcmd = 0;
  9401.                          }
  9402.                          if (vstate == get)
  9403.                               srinit();
  9404.                          BEGIN vstate;
  9405.                     }
  9406.                     break;
  9407.                case 10:
  9408.                      {
  9409.                          if (vcmd)   /* Get E for I-packet (ignore) */
  9410.                               scmd(vcmd, cmarg);
  9411.                          vcmd = 0;
  9412.                          if (vstate == get)
  9413.                               srinit();
  9414.                          BEGIN vstate;
  9415.                     }
  9416.                     break;
  9417.                case 11:
  9418.                      {
  9419.                          srinit();
  9420.                     }
  9421.                     break;
  9422.                case 12:
  9423.                      {
  9424.                          srvptr = srvcmd;
  9425.                          decode(rdatap, putsrv); /* Get Receive-Init */
  9426.                          cmarg = srvcmd;
  9427.                          nfils = -1;
  9428.                          if (sinit())
  9429.                               BEGIN ssinit;
  9430.                          else {
  9431.                               SERVE;
  9432.                          }
  9433.                     }
  9434.                     break;
  9435.                case 13:
  9436.                      {
  9437.                          spar(rdatap);
  9438.                          ack1(rpar());     /* Get Init Parameters */
  9439.                          pktnum = 0;
  9440.                          prvpkt = -1;
  9441.                     }
  9442.                     break;
  9443.                case 14:
  9444.                      {
  9445.                          srvptr = srvcmd;
  9446.                          decode(rdatap, putsrv); /* Get & decode command. */
  9447.                          putsrv('\0');
  9448.                          putsrv('\0');
  9449.                          sstate = srvcmd[0];
  9450.                          BEGIN generic;
  9451.                     }
  9452.                     break;
  9453.                case 15:
  9454.                      {
  9455.                          srvptr = srvcmd;          /* Get command for shell */
  9456.                          decode(rdatap, putsrv);
  9457.                          putsrv('\0');
  9458.                          if (syscmd(srvcmd, ""))
  9459.                               BEGIN ssinit;
  9460.                          else {
  9461.                               errpkt("Can't do system command");
  9462.                               SERVE;
  9463.                          }
  9464.                     }
  9465.                     break;
  9466.                case 16:
  9467.                      {
  9468.                          errpkt("Unimplemented server function");
  9469.                          SERVE;
  9470.                     }
  9471.                     break;
  9472.                case 17:
  9473.                      {
  9474.                          if (!cwd(srvcmd + 1))
  9475.                               errpkt("Can't change directory"); /* CWD */
  9476.                          SERVE;
  9477.                     }
  9478.                     break;
  9479.                case 18:
  9480.                      {
  9481.                          errpkt("Can't list directory");
  9482.                          SERVE;
  9483.                     }
  9484.                     break;
  9485.                case 19:
  9486.                      {
  9487.                          errpkt("Can't remove file");
  9488.                          SERVE;
  9489.                     }
  9490.                     break;
  9491.                case 20:
  9492.                      {
  9493.                          ack();
  9494.                          screen(SCR_TC, 0, 0l, "");
  9495.                          return(0);
  9496.                     }
  9497.                     break;
  9498.                case 21:
  9499.                      {
  9500.                          ack();
  9501.                          ttres();
  9502.                          screen(SCR_TC, 0, 0l, "");
  9503.                          return(zkself());
  9504.                     }
  9505.                     break;
  9506.                case 22:
  9507.                      {
  9508.                          if (sndhlp())
  9509.                               BEGIN ssinit;
  9510.                          else {
  9511.                               errpkt("Can't send help");
  9512.                               SERVE;
  9513.                          }
  9514.                     }
  9515.                     break;
  9516.                case 23:
  9517.                      {
  9518.                          errpkt("Can't type file");
  9519.                          SERVE;
  9520.                     }
  9521.                     break;
  9522.                case 24:
  9523.                      {
  9524.                          errpkt("Can't check space");
  9525.                          SERVE;
  9526.                     }
  9527.                     break;
  9528.                case 25:
  9529.                      {
  9530.                          errpkt("Can't do who command");
  9531.                          SERVE;
  9532.                     }
  9533.                     break;
  9534.                case 26:
  9535.                      {
  9536.                          errpkt("Unimplemented generic server function");
  9537.                          SERVE;
  9538.                     }
  9539.                     break;
  9540.                case 27:
  9541.                      {
  9542.                          decode(rdatap, puttrm);
  9543.                          RESUME;
  9544.                     }
  9545.                     break;
  9546.                case 28:
  9547.                      {
  9548.                          if (rcvfil())                   /* File header */ {
  9549.                               encstr(filnam);
  9550.                               ack1(data);
  9551.                               BEGIN rdata;
  9552.                          } else {
  9553.                               errpkt("Can't open file");
  9554.                               RESUME;
  9555.                          }
  9556.                     }
  9557.                     break;
  9558.                case 29:
  9559.                      {
  9560.                          opent();
  9561.                          ack();
  9562.                          BEGIN rdata;
  9563.                     }
  9564.                     break;
  9565.                case 30:
  9566.                      {
  9567.                          ack();
  9568.                          tsecs = gtimer();
  9569.                          reot();
  9570.                          RESUME;
  9571.                     }
  9572.                     break;
  9573.                case 31:
  9574.                      {
  9575.                          if (cxseen)
  9576.                               ack1("X");    /* Got data. */
  9577.                          else if (czseen)
  9578.                               ack1("Z");
  9579.                          else
  9580.                               ack();
  9581.                          decode(rdatap, putfil);
  9582.                     }
  9583.                     break;
  9584.                case 32:
  9585.                      {
  9586.                          if (reof() < 0) {         /* Got End Of File */
  9587.                               errpkt("Can't close file");
  9588.                               RESUME;
  9589.                          } else {
  9590.                               ack();
  9591.                               BEGIN rfile;
  9592.                          }
  9593.                     }
  9594.                     break;
  9595.                case 33:
  9596.                      {
  9597.                          spar(rdatap);
  9598.                          bctu = bctr;        /* Got ACK to Send-Init */
  9599.                          x = sfile(xflg);    /* Send X or F header packet */
  9600.                          if (x) {
  9601.                               resetc();
  9602.                               rtimer();
  9603.                               BEGIN ssfile;
  9604.                          } else {
  9605.                               s = xflg ? "Can't execute command" :
  9606.                                   "Can't open file";
  9607.                               errpkt(s);
  9608.                               RESUME;
  9609.                          }
  9610.                     }
  9611.                     break;
  9612.                case 34:
  9613.                      {
  9614.                          srvptr = srvcmd;                   /* Got ACK to F */
  9615.                          decode(rdatap, putsrv);
  9616.                          putsrv('\0');
  9617.                          if (*srvcmd)
  9618.                               tlog(F110, " stored as",
  9619.                                    srvcmd, 0);
  9620.                          if (sdata() < 0) {
  9621.                               clsif();
  9622.                               seof("");
  9623.                               BEGIN sseof;
  9624.                          } else
  9625.                               BEGIN ssdata;
  9626.                     }
  9627.                     break;
  9628.                case 35:
  9629.                      {
  9630.                          if (canned(rdatap)) {
  9631.                               clsif();
  9632.                               seof("D");
  9633.                               BEGIN sseof;
  9634.                          } else if (sdata() < 0) {
  9635.                               clsif();
  9636.                               seof("");
  9637.                               BEGIN sseof;
  9638.                          }
  9639.                     }
  9640.                     break;
  9641.                case 36:
  9642.                      {
  9643.                          if (gnfile() > 0) {
  9644.                               /* Got ACK to EOF, get next file */
  9645.                               if (sfile(xflg))
  9646.                                    BEGIN ssdata;
  9647.                               else {
  9648.                                    errpkt("Can't open file") ;
  9649.                                    RESUME;
  9650.                               }
  9651.                          } else {                    /* If no next file, EOT */
  9652.                               tsecs = gtimer();
  9653.                               seot();
  9654.                               BEGIN sseot;
  9655.                          }
  9656.                     }
  9657.                     break;
  9658.                case 37:
  9659.                      {
  9660.                          RESUME;
  9661.                     }
  9662.                     break;
  9663.                case 38:
  9664.                      {   /* Error packet, issue message. *
  9665.                          ermsg(rdatap);         /
  9666.                          x = quiet;
  9667.                          quiet = 1;           /* Close files silently, */
  9668.                          clsif();
  9669.                          clsof(1);            /* discarding any output file. */
  9670.                          tsecs = gtimer();
  9671.                          quiet = x;
  9672.                          if (backgrd && !server)
  9673.                               fatal("Protocol error");
  9674.                          RESUME;
  9675.                     }
  9676.                     break;
  9677.                case 39:
  9678.                      {
  9679.                          errpkt("Unknown packet type-> Please retry");
  9680.                          RESUME;
  9681.                     }
  9682.                     break;
  9683.  
  9684.                }
  9685.      }
  9686. }
  9687.  
  9688.  
  9689. short     tbl[] = {
  9690.      -1, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9691.          39,
  9692.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9693.          39,
  9694.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9695.          39,
  9696.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9697.          39,
  9698.      39, 39, 39, 39, 39, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9699.          39,
  9700.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9701.          39,
  9702.      39,  7, 39,  4, 39, 39, 39,  5, 39, 39, 39, 39, 39, 39, 39,
  9703.          39,
  9704.      39, 39,  3,  1, 39, 39,  2, 39,  6, 39, 39, 39, 39, 39, 39,
  9705.          39,
  9706.      -1, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9707.          39,
  9708.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9709.          39,
  9710.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9711.          39,
  9712.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9713.          39,
  9714.      39, 39, 39, 39, 39, 10, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9715.          39,
  9716.      39, 39, 39, 39, 39, 39, 39, 39, 39,  9, 39, 39, 39, 39, 39,
  9717.          39,
  9718.      39,  7, 39,  4, 39, 39, 39,  5, 39, 39, 39, 39, 39, 39, 39,
  9719.          39,
  9720.      39, 39,  3,  1, 39, 39,  2, 39,  6, 39, 39, 39, 39, 39, 39,
  9721.          39,
  9722.      -1, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9723.          39,
  9724.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9725.          39,
  9726.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9727.          39,
  9728.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9729.          39,
  9730.      39, 39, 30, 39, 39, 38, 28, 39, 39, 39, 39, 39, 39, 39, 39,
  9731.          39,
  9732.      39, 39, 39, 39, 39, 39, 39, 39, 29, 39, 39, 39, 39, 39, 39,
  9733.          39,
  9734.      39,  7, 39,  4, 39, 39, 39,  5, 39, 39, 39, 39, 39, 39, 39,
  9735.          39,
  9736.      39, 39,  3,  1, 39, 39,  2, 39,  6, 39, 39, 39, 39, 39, 39,
  9737.          39,
  9738.      -1, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9739.          39,
  9740.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9741.          39,
  9742.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9743.          39,
  9744.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9745.          39,
  9746.      39, 39, 39, 39, 31, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9747.          39,
  9748.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 32, 39, 39, 39, 39,
  9749.          39,
  9750.      39,  7, 39,  4, 39, 39, 39,  5, 39, 39, 39, 39, 39, 39, 39,
  9751.          39,
  9752.      39, 39,  3,  1, 39, 39,  2, 39,  6, 39, 39, 39, 39, 39, 39,
  9753.          39,
  9754.      -1, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9755.          39,
  9756.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9757.          39,
  9758.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9759.          39,
  9760.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9761.          39,
  9762.      39, 39, 39, 39, 39, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9763.          39,
  9764.      39, 39, 39, 39, 39, 39, 39, 39, 39, 33, 39, 39, 39, 39, 39,
  9765.          39,
  9766.      39,  7, 39,  4, 39, 39, 39,  5, 39, 39, 39, 39, 39, 39, 39,
  9767.          39,
  9768.      39, 39,  3,  1, 39, 39,  2, 39,  6, 39, 39, 39, 39, 39, 39,
  9769.          39,
  9770.      -1, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9771.          39,
  9772.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9773.          39,
  9774.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9775.          39,
  9776.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9777.          39,
  9778.      39, 39, 39, 39, 39, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9779.          39,
  9780.      39, 39, 39, 39, 39, 39, 39, 39, 39, 34, 39, 39, 39, 39, 39,
  9781.          39,
  9782.      39,  7, 39,  4, 39, 39, 39,  5, 39, 39, 39, 39, 39, 39, 39,
  9783.          39,
  9784.      39, 39,  3,  1, 39, 39,  2, 39,  6, 39, 39, 39, 39, 39, 39,
  9785.          39,
  9786.      -1, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9787.          39,
  9788.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9789.          39,
  9790.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9791.          39,
  9792.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9793.          39,
  9794.      39, 39, 39, 39, 39, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9795.          39,
  9796.      39, 39, 39, 39, 39, 39, 39, 39, 39, 35, 39, 39, 39, 39, 39,
  9797.          39,
  9798.      39,  7, 39,  4, 39, 39, 39,  5, 39, 39, 39, 39, 39, 39, 39,
  9799.          39,
  9800.      39, 39,  3,  1, 39, 39,  2, 39,  6, 39, 39, 39, 39, 39, 39,
  9801.          39,
  9802.      -1, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9803.          39,
  9804.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9805.          39,
  9806.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9807.          39,
  9808.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9809.          39,
  9810.      39, 39, 39, 39, 39, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9811.          39,
  9812.      39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 39, 39, 39, 39, 39,
  9813.          39,
  9814.      39,  7, 39,  4, 39, 39, 39,  5, 39, 39, 39, 39, 39, 39, 39,
  9815.          39,
  9816.      39, 39,  3,  1, 39, 39,  2, 39,  6, 39, 39, 39, 39, 39, 39,
  9817.          39,
  9818.      -1, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9819.          39,
  9820.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9821.          39,
  9822.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9823.          39,
  9824.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9825.          39,
  9826.      39, 39, 39, 39, 39, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9827.          39,
  9828.      39, 39, 39, 39, 39, 39, 39, 39, 39, 37, 39, 39, 39, 39, 39,
  9829.          39,
  9830.      39,  7, 39,  4, 39, 39, 39,  5, 39, 39, 39, 39, 39, 39, 39,
  9831.          39,
  9832.      39, 39,  3,  1, 39, 39,  2, 39,  6, 39, 39, 39, 39, 39, 39,
  9833.          39,
  9834.      -1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
  9835.          16,
  9836.      16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
  9837.          16,
  9838.      16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
  9839.          16,
  9840.      16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
  9841.          16,
  9842.      16, 16, 16, 15, 16, 16, 16, 14, 16, 13, 16, 16, 16, 16, 16,
  9843.          16,
  9844.      16, 16, 12,  8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
  9845.          16,
  9846.      16,  7, 16,  4, 16, 16, 16,  5, 16, 16, 16, 16, 16, 16, 16,
  9847.          16,
  9848.      16, 16,  3,  1, 16, 16,  2, 16,  6, 16, 16, 16, 16, 16, 16,
  9849.          16,
  9850.      -1, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
  9851.          26,
  9852.      26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
  9853.          26,
  9854.      26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
  9855.          26,
  9856.      26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
  9857.          26,
  9858.      26, 26, 26, 17, 18, 19, 20, 26, 22, 26, 26, 26, 21, 26, 26,
  9859.          26,
  9860.      26, 26, 26, 26, 23, 24, 26, 25, 26, 26, 26, 26, 26, 26, 26,
  9861.          26,
  9862.      26,  7, 26,  4, 26, 26, 26,  5, 26, 26, 26, 26, 26, 26, 26,
  9863.          26,
  9864.      26, 26,  3,  1, 26, 26,  2, 26,  6, 26, 26, 26, 26, 26, 26,
  9865.          26,
  9866.      -1, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9867.          39,
  9868.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9869.          39,
  9870.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9871.          39,
  9872.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9873.          39,
  9874.      39, 39, 39, 39, 39, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9875.          39,
  9876.      39, 39, 39,  8, 39, 39, 39, 39, 39, 11, 39, 39, 39, 39, 39,
  9877.          39,
  9878.      39,  7, 39,  4, 39, 39, 39,  5, 39, 39, 39, 39, 39, 39, 39,
  9879.          39,
  9880.      39, 39,  3,  1, 39, 39,  2, 39,  6, 39, 39, 39, 39, 39, 39,
  9881.          39,
  9882.      0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9883.           39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9884.           39,
  9885.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9886.          39,
  9887.      39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
  9888.          39,
  9889.      39, 39, 39, 39, 39, 38, 28, 39, 39, 39, 39, 39, 39, 39, 39,
  9890.          39,
  9891.      39, 39, 39,  8, 39, 39, 39, 39, 29, 27, 39, 39, 39, 39, 39,
  9892.          39,
  9893.      39,  7, 39,  4, 39, 39, 39,  5, 39, 39, 39, 39, 39, 39, 39,
  9894.          39,
  9895.      39, 39,  3,  1, 39, 39,  2, 39,  6, 39, 39, 39, 39, 39, 39,
  9896.          39,
  9897. };
  9898.  
  9899.  
  9900. /*  P R O T O  --  Protocol entry function  */
  9901.  
  9902. proto()
  9903. {
  9904.  
  9905.      extern int     sigint();
  9906.      int     x;
  9907.  
  9908.      conint(sigint);                     /* Enable console interrupts */
  9909.  
  9910.      /* Set up the communication line for file transfer. */
  9911.  
  9912.      if (local && (speed < 0)) {
  9913.           screen(SCR_EM, 0, 0l, "Sorry, you must 'set speed' first");
  9914.           return;
  9915.      }
  9916.  
  9917.      x = -1;
  9918.      if (ttopen(ttname, &x, mdmtyp) < 0) {
  9919.           if (deblog)
  9920.                debug(F111, "failed: proto ttopen local", ttname,
  9921.                     local);
  9922.           screen(SCR_EM, 0, 0l, "Can't open line");
  9923.           return;
  9924.      }
  9925.      if (x > -1)
  9926.           local = x;
  9927.      if (deblog)
  9928.           debug(F111, "proto ttopen local", ttname, local);
  9929.  
  9930.      x = (local) ? speed : -1;
  9931.      if (ttpkt(x, flow, parity) < 0) {     /* Put line in packet mode, */
  9932.           screen(SCR_EM, 0, 0l, "Can't condition line");
  9933.           return;
  9934.      }
  9935.      if (sstate == 'x') {                /* If entering server mode, */
  9936.           server = 1;                     /* set flag, */
  9937.           if (!quiet) {
  9938.                if (!local)                 /* and issue appropriate message. */
  9939.                     conol(srvtxt);
  9940.                else {
  9941.                     conol("Entering server mode on ");
  9942.                     conoll(ttname);
  9943.                }
  9944.           }
  9945.      } else
  9946.           server = 0;
  9947.      if (sstate == 'v' && !local && !quiet)
  9948.           conoll("ESC back to local system and give a SEND command...");
  9949.      if (sstate == 's' && !local && !quiet)
  9950.           conoll("ESC back to local system and give a RECEIVE command...");
  9951.      sleep(1);
  9952. /*
  9953.  The 'wart()' function is generated by the wart program.  It gets a
  9954.  character from the input() routine and then based on that character and
  9955.  the current state, selects the appropriate action, according to the state
  9956.  table above, which is transformed by the wart program into a big case
  9957.  statement.  The function is active for one transaction.
  9958. */
  9959.      wart();                             /* Enter the state table switcher. */
  9960.  
  9961.      if (server) {                       /* Back from packet protocol. */
  9962.           server = 0;
  9963.           if (!quiet)                     /* Give appropriate message */
  9964. #ifndef MCS_FLAG
  9965.                conoll("IVS-Kermit server done");
  9966. #else
  9967.                conoll("MCS-Kermit server done");
  9968. #endif
  9969.      }
  9970.      ttres();
  9971.      screen(SCR_TC, 0, 0l, "");             /* Transaction complete */
  9972. }
  9973. <<< ckvscr.c >>>
  9974. char     *loginv = "Script Command, V2.0(007) 11 May 90";
  9975.  
  9976. /*  C K U S C R  --  Login script for logging onto remote system */
  9977.  
  9978. /**********************************************************************
  9979. *                                                                     *
  9980. * IVS / MCS-Kermit REL 2                                              *
  9981. * source code                                                         *
  9982. *                                                                     *
  9983. * Change History:                                                     *
  9984. *                                                                     *
  9985. *                1. Modify C-Kermit(4E) source code to                *
  9986. *                   produce new module for MCS/IVS-Kermit             *
  9987. *                   ORIGINAL RELEASE                                  *
  9988. *                   June 22, 1990                                     *
  9989. *                                                                     *
  9990. *                                                                     *
  9991. ***********************************************************************/
  9992.  
  9993. /*
  9994.  This module should work under all versions of NCR-VRX.  It calls externally
  9995.  defined system-depended functions for i/o.
  9996.  
  9997.  The module expects a login string of the expect send [expect send] ...
  9998.  format.  It is intended to operate similarly to the way the common
  9999.  uucp "L.sys" login entries work.  Conditional responses are supported
  10000.  expect[-send-expect[...]] as with uucp.  The send keyword EOT sends a
  10001.  control-d, and the keyword BREAK sends a break.  Letters prefixed
  10002.  by '~' are '~b' backspace, '~s' space, '~n' linefeed, '~r' return, '~x' xon,
  10003.  '~t' tab, '~q' ? (not allowed on kermit command lines), '~' ~, '~'',
  10004.  '~"', '~c' don't append return, '~o[o[o]]' octal character.  As with
  10005.  some uucp systems, sent strings are followed by ~r (not ~n) unless they
  10006.  end with ~c. Null expect strings (e.g., ~0 or --) cause a short
  10007.  delay, and are useful for sending sequences requiring slight pauses.
  10008.  
  10009.  Author: Herm Fischer (HFISCHER@USC-ECLB)
  10010.  Contributed to Columbia University for inclusion in C-Kermit.
  10011.  Copyright (C) 1985, Herman Fischer, 16400 Ventura Blvd, Encino CA 91436
  10012.  Permission is granted to any individual or institution to use, copy, or
  10013.  redistribute this software so long as it is not sold for profit, provided this
  10014.  copyright notice is retained.
  10015. */
  10016.  
  10017. #include "ckcdeb.h"
  10018. #include <stdio.h>
  10019. #include <ctype.h>
  10020. #include <signal.h>
  10021. #include <setjmp.h>
  10022. #include "ckcker.h"
  10023. #include "kermisc.h"
  10024. #ifdef MCS_FLAG
  10025. #include "mcs.h"
  10026. #endif
  10027.  
  10028. extern int     local, speed, flow, seslog, mdmtyp, quiet, duplex, deblog;
  10029. extern char    ttname[];
  10030. extern CHAR    dopar();
  10031. static char    *chstr();
  10032.  
  10033. static int     EXP_ALRM = 15;           /* Time to wait for expect string */
  10034. #define SND_ALRM        15              /* Time to allow for sending string */
  10035. #define NULL_EXP        2               /* Time to pause on null expect strg*/
  10036. #define DEL_MSEC        300             /* milliseconds to pause on ~d */
  10037.  
  10038. #define SBUFL 512
  10039. static char     seq_buf[SBUFL], *s;         /* Login Sequence buffer */
  10040. static char     fls_buf[SBUFL];             /* Flush buffer */
  10041. static int     got_it, no_cr;
  10042.  
  10043. /*  connect state parent/child communication signal handlers */
  10044.  
  10045. static jmp_buf alrmRng;         /* Envir ptr for connect errors */
  10046.  
  10047. scrtime()
  10048. {                             /* modem read failure handler, */
  10049.      longjmp(alrmRng, 1);         /* notifies parent process to stop */
  10050. }
  10051.  
  10052.  
  10053. /*
  10054.  Sequence interpreter -- pick up next sequence from command string,
  10055.  decode escapes and place into seq_buf
  10056.  
  10057.  If string contains a ~d (delay) then sequenc returns a 1 expecting
  10058.  to be called again after the ~d executes.
  10059. */
  10060. static
  10061. sequenc()
  10062. {
  10063.  
  10064.      int     i;
  10065.      char     c, oct_char;
  10066.  
  10067.      no_cr = 0;                          /* output needs cr appended */
  10068.  
  10069.      for (i = 0; i < SBUFL; ) {
  10070.           if (*s == '\0' || *s == '-' || isspace(*s) ) { /* done */
  10071.                seq_buf[i] = '\0';
  10072.                return(0) ;
  10073.           }
  10074.  
  10075.           if (*s == '~') {                /* escape character */
  10076.                switch (c = *(++s) ) {
  10077.                case 'n':
  10078.                     seq_buf[i++] = '\n';
  10079.                     break;
  10080.                case 'r':
  10081.                     seq_buf[i++] = '\r';
  10082.                     break;
  10083.                case 't':
  10084.                     seq_buf[i++] = '\t';
  10085.                     break;
  10086.                case 'b':
  10087.                     seq_buf[i++] = '\b';
  10088.                     break;
  10089.                case 'q':
  10090.                     seq_buf[i++] = '?';
  10091.                     break;
  10092.                case '~':
  10093.                     seq_buf[i++] = '~';
  10094.                     break;
  10095.                case '\'':
  10096.                     seq_buf[i++] = '\'';
  10097.                     break;
  10098.                case '\"':
  10099.                     seq_buf[i++] = '\"';
  10100.                     break;
  10101.                case 's':
  10102.                     seq_buf[i++] = ' ';
  10103.                     break;
  10104.                case 'x':
  10105.                     seq_buf[i++] = '\021';
  10106.                     break;
  10107.                case 'c':
  10108.                     no_cr = 1;
  10109.                     break;
  10110.                case 'd':
  10111.                      {                     /* send what we have & then */
  10112.                          /* expect to send rest after */
  10113.                          seq_buf[i] = '\0';
  10114.                           /* sender delays a little */
  10115.                          no_cr = 1;
  10116.                          s++;
  10117.                          return(1);
  10118.                     }
  10119.                case 'w':
  10120.                      {                     /* wait count */
  10121.                          EXP_ALRM = 15;              /* default to 15 sec */
  10122.                          if ( isdigit( *(s + 1) ) ) {
  10123.                               EXP_ALRM = (*(++s)) &
  10124.                                   15;
  10125.                               if ( isdigit( *(s +
  10126.                                   1) ) ) {
  10127.                                    EXP_ALRM = EXP_ALRM
  10128.                                        *10 + ( (*(++s)) &
  10129.                                        15 );
  10130.                               }
  10131.                          }
  10132.                          break;
  10133.                     }
  10134.                default:
  10135.                     if ( isdigit(c) ) {         /* octal character */
  10136.                          oct_char = (c & 7);     /* most significant digit */
  10137.                          if (isdigit( *(s + 1) ) ) {
  10138.                               oct_char = (oct_char
  10139.                                   << 3) | ( (*(++s)) &
  10140.                                   7 ) ;
  10141.                               if (isdigit( *(s + 1) ) ) {
  10142.                                    oct_char = (oct_char
  10143.                                        << 3) | ( (*(++s)) &
  10144.                                        7 ) ;
  10145.                               }
  10146.                          }
  10147.                          seq_buf[i++] = oct_char;
  10148.                          break;
  10149.                     }
  10150.                }
  10151.           } else
  10152.                seq_buf[i++] = *s;         /* plain old character */
  10153.           s++;
  10154.      }
  10155.      seq_buf[i] = '\0';
  10156.      return(0);                  /* end of space, return anyway */
  10157. }
  10158.  
  10159.  
  10160. /*
  10161.  Receive sequence -- see if expected response comes return success
  10162.  (or failure) in got_it
  10163. */
  10164. static
  10165. recvSeq()
  10166. {
  10167.  
  10168.      char     *e, got[7], trace[SBUFL];
  10169.      int     i, l;
  10170.  
  10171.      sequenc();
  10172.      l = strlen(e = seq_buf);          /* no more than 7 chars allowed */
  10173.      if (l > 7) {
  10174.           e += l - 7;
  10175.           l = 7;
  10176.      }
  10177.      tlog(F111, "expecting sequence", e, (long) l);
  10178.      if (l == 0) {           /* null sequence, just delay a little */
  10179.           sleep (NULL_EXP);
  10180.           got_it = 1;
  10181.           tlog(F100, "got it (null sequence)", "", 0l);
  10182.           return;
  10183.      }
  10184.      *trace = '\0';
  10185.      for (i = 0; i < 7; i++)
  10186.           got[i] = '\0';
  10187.  
  10188.      SIGNAL(SIGALRM, scrtime);        /* did we get it? */
  10189.      if (!setjmp(alrmRng)) { /* not timed out yet */
  10190.           ALARM(EXP_ALRM);
  10191.           while (!got_it) {
  10192.                for (i = 0; i < (l - 1); i++)
  10193.                     got[i] = got[i+1]; /* shift over one */
  10194.                got[l-1] = ttinc(0) & 0177;             /* next char */
  10195.                if (seslog)             /* Log in session log */
  10196.                     zchout(ZSFILE, got[l-1]);
  10197.                if (strlen(trace) < sizeof(trace) - 2 )
  10198.                     strcat(trace, chstr(got[l-1]));
  10199.                got_it = (!strncmp(seq_buf, got, l) ) ;
  10200.           }
  10201.      } else
  10202.           got_it = 0;              /* timed out here */
  10203.  
  10204.      ALARM(0);
  10205.      SIGNAL(SIGALRM, SIG_IGN);
  10206.      tlog(F110, "received sequence: ", trace, 0l);
  10207.      tlog(F101, "returning with got-it code", "", (long) got_it);
  10208.      return;
  10209. }
  10210.  
  10211.  
  10212. /*
  10213.  Output A Sequence starting at pointer s,
  10214.  return 0 if okay,
  10215.  1 if failed to read (modem hangup or whatever)
  10216. */
  10217. static int
  10218. outSeq()
  10219. {
  10220.      char     *sb;
  10221.      int     l;
  10222.      int     delay;
  10223.      int     retCode = 0;
  10224.  
  10225.      while (1) {
  10226.           delay = sequenc();
  10227.           l = strlen(seq_buf);
  10228.           tlog(F111, "sending sequence ", seq_buf, (long) l);
  10229.           SIGNAL(SIGALRM, scrtime);
  10230.           if (!setjmp(alrmRng)) {
  10231.                ALARM(SND_ALRM);
  10232.                if (!strcmp(seq_buf, "EOT")) {
  10233.                     ttoc(dopar('\004'));
  10234.                     if (seslog && duplex)
  10235.                          zsout(ZSFILE, "{EOT}");
  10236.                } else if (!strcmp(seq_buf, "BREAK")) {
  10237.                     ttsndb();
  10238.                     zsout(ZSFILE, "{BREAK}");
  10239.                } else {
  10240.                     if (l > 0) {
  10241.                          for ( sb = seq_buf; *sb; sb++)
  10242.                               *sb = dopar(*sb);
  10243.                          ttol(seq_buf, l);                /* with parity */
  10244.                          if (seslog && duplex)
  10245.                               zsout(ZSFILE, seq_buf);
  10246.                     }
  10247.                     if (!no_cr) {
  10248.                          ttoc( dopar('\r') );
  10249.                          if (seslog && duplex)
  10250.                               zchout(ZSFILE, dopar('\r'));
  10251.                     }
  10252.                }
  10253.           } else
  10254.                retCode |= -1;             /* else -- alarm rang */
  10255.           ALARM(0);
  10256.           SIGNAL(SIGALRM, SIG_IGN);
  10257.           if (!delay)
  10258.                return ( retCode );
  10259.           msleep(DEL_MSEC);       /* delay, and loop to next stuff to send */
  10260.      }
  10261. }
  10262.  
  10263.  
  10264. /*  L O G I N  --  Login to remote system */
  10265.  
  10266. login(cmdstr)
  10267. char     *cmdstr;
  10268. {
  10269.  
  10270.      SIGTYP (*saveAlm)();    /* save incoming alarm function */
  10271.      char     *e;
  10272.  
  10273.      s = cmdstr;                     /* make global to ckuscr.c */
  10274.  
  10275.      tlog(F100, loginv, "", 0l);
  10276.  
  10277.      if (!local) {
  10278. #ifndef MCS_FLAG
  10279.           printf("Sorry, you must 'set line' first\n");
  10280. #else
  10281.           mcs_printf("Sorry, you must 'set line' first\n");
  10282. #endif
  10283.           return(-2);
  10284.      }
  10285.      if (speed < 0) {
  10286. #ifndef MCS_FLAG
  10287.           printf("Sorry, you must 'set speed' first\n");
  10288. #else
  10289.           mcs_printf("Sorry, you must 'set speed' first\n");
  10290. #endif
  10291.           return(-2);
  10292.      }
  10293.      if (ttopen(ttname, &local, mdmtyp) < 0) {
  10294.           sprintf(seq_buf, "Sorry, can't open %s", ttname);
  10295.           perror(seq_buf);
  10296.           return(-2);
  10297.      }
  10298. #ifndef MCS_FLAG
  10299.      if (!quiet)
  10300.           printf("Executing script thru %s, speed %d.\r\n", ttname,
  10301.                speed);
  10302. #else
  10303.      if (!quiet) {
  10304.           sprintf(print_str,"Executing script thru %s, speed %d.\r\n", ttname,
  10305.                speed);
  10306.           mcs_printf(print_str);
  10307.      }
  10308. #endif
  10309.      *seq_buf = 0;
  10310.      for (e = s; *e; e++)
  10311.           strcat(seq_buf, chstr(*e) );
  10312. #ifndef MCS_FLAG
  10313.      if (!quiet)
  10314.           printf("Script string: %s\r\n", seq_buf);
  10315. #else
  10316.      if (!quiet) {
  10317.        sprintf(print_str,"Script string: %s\r\n", seq_buf);
  10318.        mcs_printf(print_str);
  10319.      }
  10320. #endif
  10321.      tlog(F110, "Script string: ", seq_buf, 0l);
  10322.  
  10323.      /* Condition console terminal and communication line */
  10324.  
  10325.      if (ttvt(speed, flow) < 0) {
  10326. #ifndef MCS_FLAG
  10327.           printf("Sorry, Can't condition communication line\n");
  10328. #else
  10329.           mcs_printf("Sorry, Can't condition communication line\n");
  10330. #endif
  10331.           return(-2);
  10332.      }
  10333.      /* save initial timer interrupt value */
  10334.      saveAlm = SIGNAL(SIGALRM, SIG_IGN);
  10335.  
  10336.      flushi();               /* flush stale input */
  10337.  
  10338.      /* start expect - send sequence */
  10339.  
  10340.      while (*s) {                /* while not done with buffer */
  10341.  
  10342.           while (*s && isspace(*s))
  10343.                s++;  /* skip over separating whitespaces */
  10344.           /* gather up expect sequence */
  10345.           got_it = 0;
  10346.           recvSeq();
  10347.  
  10348.           while (!got_it) {
  10349.                /* no, is there a conditional send */
  10350.                if (*s++ != '-')
  10351.                     goto failRet;      /* no -- return failure */
  10352.  
  10353.                /* start of conditional send */
  10354.                flushi();                           /* flush out input buffer */
  10355.                if (outSeq())
  10356.                     goto failRet;         /* if unable to send! */
  10357.  
  10358.                if (*s++ != '-')
  10359.                     goto failRet;      /* must have condit respon.*/
  10360.                recvSeq();
  10361.           }       /* loop back and check got_it */
  10362.  
  10363.           while (*s && !isspace(*s++) )
  10364.                ; /* Skip over conditionals */
  10365.           while (*s && isspace(*s))
  10366.                s++;  /* Skip over separating whitespaces */
  10367.           flushi();                       /* Flush */
  10368.           if (*s)
  10369.                if (outSeq())
  10370.                     goto failRet; /* If any */
  10371.      }
  10372.      SIGNAL(SIGALRM, saveAlm);
  10373.      if (!quiet)
  10374. #ifndef MCS_FLAG
  10375.           printf("Script successful.\r\n");
  10376. #else
  10377.           mcs_printf("Script successful.\r\n");
  10378. #endif
  10379.      tlog(F100, "Script successful.", "", 0l);
  10380.      return(0);
  10381.  
  10382. failRet:
  10383.      SIGNAL(SIGALRM, saveAlm);
  10384. #ifndef MCS_FLAG
  10385.      printf("Sorry, script failed\r\n");
  10386. #else
  10387.      mcs_printf("Sorry, script failed\r\n");
  10388. #endif
  10389.      tlog(F100, "Script failed", "", 0l);
  10390.      return(-2);
  10391. }
  10392.  
  10393.  
  10394. /*  C H S T R  --  Make printable string from a character */
  10395.  
  10396. static char     *
  10397. chstr(c)
  10398. char     c;
  10399. {
  10400.      static char     sc[4];
  10401.  
  10402.      if (c < SP)
  10403.           sprintf(sc, "^%c", ctl(c) );
  10404.      else
  10405.           sprintf(sc, "%c", c);
  10406.  
  10407.      return(sc);
  10408. }
  10409.  
  10410.  
  10411. /*  F L U S H I  --  Flush, but log, input buffer  */
  10412.  
  10413. flushi()
  10414. {
  10415.      int     n;
  10416.      if (seslog) {                       /* Logging session? */
  10417.           n = ttchk();                    /* Yes, anything in buffer? */
  10418.           if (n > 0) {                    /* If so, */
  10419.                if (n > SBUFL)
  10420.                     n = SBUFL;   /* make sure not too much, */
  10421.                n = ttxin(n, fls_buf);       /* then read it, */
  10422.                zsout(ZSFILE, fls_buf);      /* and log it. */
  10423.           }
  10424.      } else
  10425.           ttflui();                    /* Otherwise just flush. */
  10426. }
  10427. <<< ckvtio.c >>>
  10428. char     *ckxv = "NCR-VRX tty I/O, 4E, 01 June 90";
  10429.  
  10430. /*  C K V T I O  */
  10431.  
  10432. /**********************************************************************
  10433. *                                                                     *
  10434. * IVS / MCS-Kermit REL 2                                              *
  10435. * source code                                                         *
  10436. *                                                                     *
  10437. * Change History:                                                     *
  10438. *                                                                     *
  10439. *                1. Modify C-Kermit(4E) source code to                *
  10440. *                   produce new module for MCS/IVS-Kermit             *
  10441. *                   ORIGINAL RELEASE                                  *
  10442. *                   June 22, 1990                                     *
  10443. *                                                                     *
  10444. *                                                                     *
  10445. ***********************************************************************/
  10446.  
  10447.  
  10448. /* C-Kermit interrupt, terminal control & i/o functions for NCR-VRX systems */
  10449.  
  10450. /*
  10451.  Author: Frank da Cruz (SY.FDC@CU20B),
  10452.  Columbia University Center for Computing Activities, January 1985.
  10453.  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
  10454.  Permission is granted to any individual or institution to use, copy, or
  10455.  redistribute this software so long as it is not sold for profit, provided this
  10456.  copyright notice is retained.
  10457. */
  10458. /* Includes for all NCR-VRXes (conditional includes come later) */
  10459.  
  10460. #include <types.h>   /* Types */
  10461. #include <ctype.h>   /* Character types */
  10462. #include <stdio.h>   /* NCR-VRX Standard i/o */
  10463. #include <signal.h>   /* Interrupts */
  10464. #include <setjmp.h>   /* Longjumps */
  10465. #include "ckcdeb.h"   /* Typedefs, formats for debug() */
  10466. #include <fcntl.h>
  10467. #include "ckuusr.h"
  10468. #include <time.h>   /* Clock info (for break generation) */
  10469. #ifdef MCS_FLAG
  10470. #include "mcs.h"
  10471. #define read mcs_read
  10472. #define write mcs_write
  10473. #endif
  10474.  
  10475. /* DUMMY DEFINES FOR COMPILE */
  10476. #define DIRSIZ 10
  10477. #define B0 1
  10478. #define B110 1
  10479. #define B150 1
  10480. #define B300 1
  10481. #define B600 1
  10482. #define B1200 1
  10483. #define B1800 1
  10484. #define B2400 1
  10485. #define B4800 1
  10486. #define B9600 1
  10487. #define SIGQUIT 1
  10488. #define SIGINT 1
  10489. #define SIGHUP 1
  10490. #define SIGALRM 1
  10491.  
  10492. /* Maximum length for the name of a tty device */
  10493.  
  10494. #ifndef DEVNAMLEN
  10495. #define DEVNAMLEN 25
  10496. #endif
  10497.  
  10498. char     *ckxsys = " NCR VRX/VE";
  10499.  
  10500. /* Features... */
  10501.  
  10502. /* Do own buffering, using unbuffered read() calls... */
  10503.  
  10504.  
  10505. /*
  10506.  Variables available to outside world:
  10507.  
  10508.    dftty  -- Pointer to default tty name string, like "/dev/tty".
  10509.    dfloc  -- 0 if dftty is console, 1 if external line.
  10510.    dfprty -- Default parity
  10511.    dfflow -- Default flow control
  10512.    ckxech -- Flag for who echoes console typein:
  10513.      1 - The program (system echo is turned off)
  10514.      0 - The system (or front end, or terminal).
  10515.    functions that want to do their own echoing should check this flag
  10516.    before doing so.
  10517.  
  10518.    flfnam -- Name of lock file, including its path, e.g.,
  10519.              "/usr/spool/uucp/LCK..cul0" or "/etc/locks/tty77"
  10520.    hasLock -- Flag set if this kermit established a uucp lock.
  10521.    inbufc -- number of tty line rawmode unread characters
  10522.              (system III/V unixes)
  10523.    backgrd -- Flag indicating program executing in background ( & on
  10524.               end of shell command). Used to ignore INT and QUIT signals.
  10525.  
  10526.  Functions for assigned communication line (either external or console tty):
  10527.  
  10528.    sysinit()               -- System dependent program initialization
  10529.    ttopen(ttname,local,mdmtyp) -- Open the named tty for exclusive access.
  10530.    ttclos()                -- Close & reset the tty, releasing any access lock.
  10531.    ttpkt(speed,flow)       -- Put the tty in packet mode and set the speed.
  10532.    ttvt(speed,flow)        -- Put the tty in virtual terminal mode.
  10533.                               or in DIALING or CONNECTED modem control state.
  10534.    ttinl(dest,max,timo)    -- Timed read line from the tty.
  10535.    ttinc(timo)             -- Timed read character from tty.
  10536.    myread()     -- System 3 raw mode bulk buffer read, gives
  10537.                 --   subsequent chars one at a time and simulates
  10538.                 --   FIONREAD!
  10539.    myunrd(c)     -- Places c back in buffer to be read (one only)
  10540.    ttchk()                 -- See how many characters in tty input buffer.
  10541.    ttxin(n,buf)            -- Read n characters from tty (untimed).
  10542.    ttol(string,length)     -- Write a string to the tty.
  10543.    ttoc(c)                 -- Write a character to the tty.
  10544.    ttflui()                -- Flush tty input buffer.
  10545.  
  10546.    ttlock(ttname)    -- Lock against uucp collisions (Sys III)
  10547.    ttunlck()     -- Unlock "       "     "
  10548.    look4lk(ttname)    -- Check if a lock file exists
  10549. */
  10550.  
  10551. /*
  10552. Functions for console terminal:
  10553.  
  10554.    congm()   -- Get console terminal modes.
  10555.    concb(esc) -- Put the console in single-character wakeup mode with no echo.
  10556.    conbin(esc) -- Put the console in binary (raw) mode.
  10557.    conres()  -- Restore the console to mode obtained by congm().
  10558.    conoc(c)  -- Unbuffered output, one character to console.
  10559.    conol(s)  -- Unbuffered output, null-terminated string to the console.
  10560.    conola(s) -- Unbuffered output, array of strings to the console.
  10561.    conxo(n,s) -- Unbuffered output, n characters to the console.
  10562.    conchk()  -- Check if characters available at console (bsd 4.2).
  10563.                 Check if escape char (^\) typed at console (System III/V).
  10564.    coninc(timo)  -- Timed get a character from the console.
  10565.    conint()  -- Enable terminal interrupts on the console if not background.
  10566.    connoi()  -- Disable terminal interrupts on the console if not background.
  10567.  
  10568. Time functions
  10569.  
  10570.    msleep(m) -- Millisecond sleep
  10571.    ztime(&s) -- Return pointer to date/time string
  10572.    rtimer() --  Reset timer
  10573.    gtimer()  -- Get elapsed time since last call to rtimer()
  10574. */
  10575.  
  10576.  
  10577. /* Declarations */
  10578.  
  10579. long     time();    /* All NCR-VRXes should have this... */
  10580. char     *dftty = CTTNAM;  /* Remote by default, use normal */
  10581. int      dfloc = 0;   /* controlling terminal name. */
  10582.  
  10583. extern int     errno;   /* System call error return */
  10584. extern int     deblog;
  10585.  
  10586. /* dftty is the device name of the default device for file transfer */
  10587. /* dfloc is 0 if dftty is the user's console terminal, 1 if an external line */
  10588.  
  10589.  
  10590. int     dfprty = 0;   /* Parity (0 = none) */
  10591. int     dfflow = 1;   /* Xon/Xoff flow control */
  10592. int     backgrd = 0;   /* Assume in foreground (no '&' ) */
  10593.  
  10594. int     ckxech = 0; /* 0 if system normally echoes console characters,
  10595.                          else 1 */
  10596.  
  10597. /* Declarations of variables global within this module */
  10598.  
  10599. static long     tcount;   /* Elapsed time counter */
  10600.  
  10601. static char     *brnuls = "\0\0\0\0\0\0\0"; /* A string of nulls */
  10602.  
  10603. static jmp_buf sjbuf, jjbuf;  /* Longjump buffer */
  10604. static int     lkf = 0,   /* Line lock flag */
  10605. conif = 0,    /* Console interrupts on/off flag */
  10606. cgmf = 0,    /* Flag that console modes saved */
  10607. xlocal = 0,    /* Flag for tty local or remote */
  10608. ttyfd = -1;    /* TTY file descriptor */
  10609. static char     escchr;   /* Escape or attn character */
  10610.  
  10611. /* Special line discipline, 4.2bsd only, and only with kernel mods... */
  10612. static int     kerld = 0;  /* Not selected, no special l.d. */
  10613.  
  10614.  
  10615. /* dummy struct for compilw **** */
  10616. struct sgttyb {
  10617.      int     sg_ispeed;
  10618.      int     sg_ospeed;
  10619. };
  10620.  
  10621. static struct sgttyb /* sgtty info... */
  10622. ttold, ttraw, tttvt, ttbuf,  /* for communication line */
  10623. ccold, ccraw, cccbrk;  /* and for console */
  10624.  
  10625. static char     flfnam[80];   /* uucp lock file path name */
  10626. static int     hasLock = 0;   /* =1 if this kermit locked uucp */
  10627. static int     inbufc = 0;   /* stuff for efficient SIII raw line */
  10628. static int     ungotn = -1;   /* pushback to unread character */
  10629. static int     conesc = 0;   /* set to 1 if esc char (^\) typed */
  10630.  
  10631. static int     ttlock();   /* definition of ttlock subprocedure */
  10632. static int     ttunlck();   /* and unlock subprocedure */
  10633. static char     ttnmsv[DEVNAMLEN];  /* copy of open path for tthang */
  10634.  
  10635. /*  S Y S I N I T  --  System-dependent program initialization.  */
  10636.  
  10637. sysinit()
  10638. {
  10639.  
  10640.      /* for now, nothing... */
  10641.      if (deblog)
  10642.           debug(F100, "funct: sysinit ", "", 0);
  10643.  
  10644. }
  10645.  
  10646.  
  10647. /* T T Y N A M E -- Set default tty name.  */
  10648. char     *
  10649. ttyname(x)
  10650. int     x;
  10651. {
  10652.      char     *xx;
  10653.  
  10654.      if (deblog)
  10655.           debug(F100, "funct: ttyname ", "", 0);
  10656.      xx = "/dev/tty";
  10657.      return(xx);
  10658. }
  10659.  
  10660.  
  10661. /*  T T O P E N  --  Open a tty for exclusive access.  */
  10662.  
  10663. /*  Returns 0 on success, -1 on failure.  */
  10664. /*
  10665.   If called with lcl < 0, sets value of lcl as follows:
  10666.   0: the terminal named by ttname is the job's controlling terminal.
  10667.   1: the terminal named by ttname is not the job's controlling terminal.
  10668.   But watch out: if a line is already open, or if requested line can't
  10669.   be opened, then lcl remains (and is returned as) -1.
  10670. */
  10671. ttopen(ttname, lcl, modem)
  10672. char     *ttname;
  10673. int     *lcl, modem;
  10674. {
  10675.  
  10676.      char     *x;
  10677.      char     cname[DEVNAMLEN];
  10678.  
  10679.      if (deblog)
  10680.           debug(F100, "funct: ttopen  ", "", 0);
  10681.      if (ttyfd > -1)
  10682.           return(0);  /* If already open, ignore this call */
  10683.      xlocal = *lcl;   /* Make this available to other fns */
  10684.  
  10685.      ttyfd = open(ttname, O_TTY);  /* Try to open for read/write */
  10686.  
  10687.      if (ttyfd < 0) {   /* If couldn't open, fail. */
  10688.           return(-1);
  10689.      }
  10690.      strncpy(ttnmsv, ttname, DEVNAMLEN); /* Open, keep copy of name locally. */
  10691.  
  10692.      /* Caller wants us to figure out if line is controlling tty */
  10693.  
  10694.      if (deblog)
  10695.           debug(F111, "ttopen", ttname, *lcl);
  10696.      if (*lcl == -1) {
  10697.           if (strcmp(ttname, CTTNAM) == 0) {   /* "/dev/tty" always remote */
  10698.                if (deblog)
  10699.                     debug(F110, " Same as CTTNAM", ttname,
  10700.                          0);
  10701.                xlocal = 0;
  10702.           } else if (isatty(0)) {  /* Else, if stdin not redirected */
  10703.                x = ttyname(0);  /* then compare its device name */
  10704.  
  10705.                strncpy(cname, x, DEVNAMLEN);
  10706.                                 /* (copy from internal static buf) */
  10707.                if (deblog)
  10708.                     debug(F110, " ttyname(0)", x, 0);
  10709.                x = ttyname(ttyfd);  /* ...with real name of ttname. */
  10710.                xlocal = (strncmp(x, cname, DEVNAMLEN) == 0) ?
  10711.                    0 : 1;
  10712.                if (deblog)
  10713.                     debug(F111, " ttyname", x, xlocal);
  10714.           } else {   /* Else, if stdin redirected... */
  10715.  
  10716.                /* Just assume local, so "set speed"
  10717.                   and similar commands will work */
  10718.                /* If not really local, how could it work anyway?... */
  10719.  
  10720.                xlocal = 1;
  10721.                if (deblog)
  10722.                     debug(F101, " redirected stdin", "",
  10723.                          xlocal);
  10724.  
  10725.           }
  10726.      }
  10727.  
  10728.      /* Now check if line is locked -- if so fail, else lock for ourselves */
  10729.  
  10730.      lkf = 0;    /* Check lock */
  10731.      if (xlocal > 0) {
  10732.           if (ttlock(ttname) < 0) {
  10733.                fprintf(stderr, "Exclusive access to %s denied\n",
  10734.                     ttname);
  10735.                close(ttyfd);
  10736.                ttyfd = -1;
  10737.                if (deblog)
  10738.                     debug(F110, " Access denied by lock",
  10739.                          ttname, 0);
  10740.                return(-1);   /* Not if already locked */
  10741.           } else
  10742.                lkf = 1;
  10743.      }
  10744.  
  10745.      /* Got the line, now set the desired value for local. */
  10746.  
  10747.      if (*lcl < 0)
  10748.           *lcl = xlocal;
  10749.  
  10750.      /* Some special stuff for v7... */
  10751.  
  10752.  
  10753.      /* Request exclusive access on systems that allow it. */
  10754.  
  10755.      /* Get tty device settings */
  10756.  
  10757.      GTTY(ttyfd, &ttold);   /* Get sgtty info */
  10758.      GTTY(ttyfd, &ttraw);   /* And a copy of it for packets*/
  10759.      GTTY(ttyfd, &tttvt);   /* And one for virtual tty service */
  10760.  
  10761.      if (deblog)
  10762.           debug(F101, "ttopen, ttyfd", "", ttyfd);
  10763.      if (deblog)
  10764.           debug(F101, " lcl", "", *lcl);
  10765.      if (deblog)
  10766.           debug(F111, " lock file", flfnam, lkf);
  10767.      return(0);
  10768. }
  10769.  
  10770.  
  10771. /*  T T C L O S  --  Close the TTY, releasing any lock.  */
  10772.  
  10773. ttclos()
  10774. {
  10775.      if (deblog)
  10776.           debug(F100, "funct: ttclos  ", "", 0);
  10777.      if (ttyfd < 0)
  10778.           return(0);  /* Wasn't open. */
  10779.      if (xlocal) {
  10780.           if (tthang())   /* Hang up phone line */
  10781.                fprintf(stderr, "Warning, problem hanging up the phone\n");
  10782.           if (ttunlck())   /* Release uucp-style lock */
  10783.                fprintf(stderr, "Warning, problem releasing lock\n");
  10784.      }
  10785.      ttres();    /* Reset modes. */
  10786.      /* Relinquish exclusive access if we might have had it... */
  10787.      close(ttyfd);   /* Close it. */
  10788.      ttyfd = -1;    /* Mark it as closed. */
  10789.      return(0);
  10790. }
  10791.  
  10792.  
  10793. /*  T T H A N G -- Hangup phone line */
  10794.  
  10795. tthang()
  10796. {
  10797.  
  10798.      if (deblog)
  10799.           debug(F100, "funct: tthang ", "", 0);
  10800.      if (ttyfd < 0)
  10801.           return(0);  /* Not open. */
  10802.      return (0);
  10803. }
  10804.  
  10805.  
  10806. /*  T T R E S  --  Restore terminal to "normal" mode.  */
  10807.  
  10808. ttres()
  10809. {    /* Restore the tty to normal. */
  10810.      if (deblog)
  10811.           debug(F100, "funct: ttres   ", "", 0);
  10812.      if (ttyfd < 0)
  10813.           return(-1);  /* Not open. */
  10814.  
  10815.      sleep(1);    /* Wait for pending i/o to finish. */
  10816.  
  10817.      if (STTY(ttyfd, &ttold) < 0)
  10818.           return(-1); /* Restore sgtty stuff */
  10819.  
  10820.      return(0);
  10821. }
  10822.  
  10823.  
  10824. /* Exclusive uucp file locking control */
  10825. /*
  10826.  by H. Fischer, creative non-Bell coding !
  10827.  copyright rights for lock modules assigned to Columbia University
  10828. */
  10829. static char     *
  10830. xxlast(s, c)
  10831. char     *s;
  10832. char     c;
  10833. {  /* Equivalent to strrchr() */
  10834.      int     i;
  10835.      if (deblog)
  10836.           debug(F100, "funct: xxlast  ", "", 0);
  10837.      for (i = strlen(s); i > 0; i--)
  10838.           if ( s[i-1] == c )
  10839.                return( s + (i - 1) );
  10840.      return(NULL);
  10841. }
  10842.  
  10843.  
  10844. static
  10845. look4lk(ttname)
  10846. char     *ttname;
  10847. {
  10848.      extern char     *strcat(), *strcpy();
  10849.      char     *device, *devname;
  10850.      char     lockfil[DIRSIZ+1];
  10851.      char     *lockdir = "/usr/spool/uucp";
  10852.  
  10853.      device = ( (devname = xxlast(ttname, '/')) != NULL ? devname
  10854.          + 1 : ttname);
  10855.  
  10856.      strcat( strcpy( lockfil, "LCK.." ), device );
  10857.  
  10858.      if (access( lockdir, 04 ) < 0) { /* read access denied on lock dir */
  10859.           fprintf(stderr, "Warning, read access to lock directory denied\n");
  10860.           return( 1 );   /* cannot check or set lock file */
  10861.      }
  10862.  
  10863.      strcat(strcat(strcpy(flfnam, lockdir), "/"), lockfil);
  10864.      if (deblog)
  10865.           debug(F110, "look4lk", flfnam, 0);
  10866.  
  10867.      if ( !access( flfnam, 00 ) ) { /* print out lock file entry */
  10868.           char     lckcmd[40] ;
  10869.           strcat( strcpy(lckcmd, "ls -l ") , flfnam);
  10870.           SYSTEM(lckcmd);
  10871.           if (access(flfnam, 02) == 0)
  10872. #ifndef MCS_FLAG
  10873.                printf("(Use \"DEL %s\" to remove this file)\n",
  10874.                     flfnam);
  10875. #else
  10876.                mcs_printf("(Use \"DEL %s\" to remove this file)\n",
  10877.                     flfnam);
  10878. #endif
  10879.           return( -1 );
  10880.      }
  10881.      if ( access( lockdir, 02 ) < 0 ) { /* lock file cannot be written */
  10882.           fprintf(stderr, "Warning, write access to lock directory denied\n");
  10883.           return( 1 );
  10884.      }
  10885.      return( 0 );   /* okay to go ahead and lock */
  10886. }
  10887.  
  10888.  
  10889. /*  T T L O C K  */
  10890.  
  10891.  
  10892. static
  10893. ttlock(ttyfd)
  10894. char     *ttyfd;
  10895. {  /* lock uucp if possible */
  10896.  
  10897.      int     lck_fil, l4l;
  10898.      int     pid_buf = getpid();  /* pid to save in lock file */
  10899.  
  10900.      hasLock = 0;   /* not locked yet */
  10901.      l4l = look4lk(ttyfd);
  10902.      if (deblog)
  10903.           debug(F100, "funct: ttlock  ", "", 0);
  10904.      if (l4l < 0)
  10905.           return (-1);  /* already locked */
  10906.      if (l4l == 1)
  10907.           return (0);  /* can't read/write lock directory */
  10908.      lck_fil = creat(flfnam, 0444); /* create lock file ... */
  10909.      if (lck_fil < 0)
  10910.           return (-1); /* create of lockfile failed */
  10911.      /* creat leaves file handle open for writing -- hf */
  10912.      write (lck_fil, &pid_buf, sizeof(pid_buf) );
  10913.                                /* uucp expects int in file */
  10914.      close (lck_fil);
  10915.      hasLock = 1;   /* now is locked */
  10916.      return(0);
  10917. }
  10918.  
  10919.  
  10920. /*  T T U N L O C K  */
  10921.  
  10922. static
  10923. ttunlck()
  10924. {    /* kill uucp lock if possible */
  10925.      if (deblog)
  10926.           debug(F100, "funct: ttunlock", "", 0);
  10927.      if (hasLock)
  10928.           return( unlink( flfnam ) );
  10929. }
  10930.  
  10931.  
  10932. /*  T T P K T  --  Condition the communication line for packets. */
  10933. /*  or for modem dialing */
  10934.  
  10935. #define DIALING 4  /* flags (via flow) for modem handling */
  10936. #define CONNECT 5
  10937.  
  10938. /*  If called with speed > -1, also set the speed.  */
  10939.  
  10940. /*  Returns 0 on success, -1 on failure.  */
  10941.  
  10942. ttpkt(speed, flow)
  10943. int     speed, flow;
  10944. {
  10945.      int     s;
  10946.      if (deblog)
  10947.           debug(F100, "funct: ttpkt   ", "", 0);
  10948.      if (ttyfd < 0)
  10949.           return(-1);  /* Not open. */
  10950.  
  10951.      s = ttsspd(speed);   /* Check the speed */
  10952.  
  10953.  
  10954.  
  10955.      ttflui();    /* Flush any pending input */
  10956.      return(0);
  10957. }
  10958.  
  10959.  
  10960. /*  T T V T -- Condition communication line for use as virtual terminal  */
  10961.  
  10962. ttvt(speed, flow)
  10963. int     speed, flow;
  10964. {
  10965.      int     s;
  10966.      if (deblog)
  10967.           debug(F100, "funct: ttvt    ", "", 0);
  10968.      if (ttyfd < 0)
  10969.           return(-1);  /* Not open. */
  10970.  
  10971.      s = ttsspd(speed);   /* Check the speed */
  10972.  
  10973.      if (s > -1)
  10974.           tttvt.sg_ispeed = tttvt.sg_ospeed = s; /* Do the speed */
  10975.      if (STTY(ttyfd, &tttvt) < 0)
  10976.           return(-1);
  10977.  
  10978. }
  10979.  
  10980.  
  10981. /*  T T S S P D  --  Return the internal baud rate code for 'speed'.  */
  10982.  
  10983. ttsspd(speed)
  10984. {
  10985.      int     s, spdok;
  10986.  
  10987.      if (deblog)
  10988.           debug(F100, "funct: ttsspd  ", "", 0);
  10989.      if (speed < 0)
  10990.           return(-1);
  10991.      spdok = 1;   /* Assume arg ok */
  10992.      switch (speed) {
  10993.      case 0:
  10994.           s = B0;
  10995.           break; /* Just the common ones. */
  10996.      case 110:
  10997.           s = B110;
  10998.           break; /* The others from ttydev.h */
  10999.      case 150:
  11000.           s = B150;
  11001.           break; /* could also be included if */
  11002.      case 300:
  11003.           s = B300;
  11004.           break; /* necessary... */
  11005.      case 600:
  11006.           s = B600;
  11007.           break;
  11008.      case 1200:
  11009.           s = B1200;
  11010.           break;
  11011.      case 1800:
  11012.           s = B1800;
  11013.           break;
  11014.      case 2400:
  11015.           s = B2400;
  11016.           break;
  11017.      case 4800:
  11018.           s = B4800;
  11019.           break;
  11020.      case 9600:
  11021.           s = B9600;
  11022.           break;
  11023.      default:
  11024.           spdok = 0;
  11025.           fprintf(stderr, "Unsupported line speed - %d\n", speed);
  11026.           fprintf(stderr, "Current speed not changed\n");
  11027.           break;
  11028.      }
  11029.      if (spdok)
  11030.           return(s);
  11031.      else
  11032.           return(-1);
  11033. }
  11034.  
  11035.  
  11036.  
  11037. /*  T T F L U I  --  Flush tty input buffer */
  11038.  
  11039. ttflui()
  11040. {
  11041.  
  11042.      long     n;
  11043.  
  11044.      if (deblog)
  11045.           debug(F100, "funct: ttflui  ", "", 0);
  11046.      if (ttyfd < 0)
  11047.           return(-1);  /* Not open. */
  11048.  
  11049.      ungotn = -1;   /* Initialize myread() stuff */
  11050.      inbufc = 0;
  11051.  
  11052.      return(0);
  11053. }
  11054.  
  11055.  
  11056. /* Interrupt Functions */
  11057.  
  11058.  
  11059. /* Timeout handler for communication line input functions */
  11060.  
  11061. timerh()
  11062. {
  11063.      longjmp(sjbuf, 1);
  11064. }
  11065.  
  11066.  
  11067. /* Set up terminal interrupts on console terminal */
  11068.  
  11069.  
  11070. /*  C O N I N T  --  Console Interrupt setter  */
  11071.  
  11072. conint(f)
  11073. int     (*f)();
  11074. {   /* Set an interrupt trap. */
  11075.  
  11076.      if (deblog)
  11077.           debug(F100, "funct: conint  ", "", 0);
  11078.      if (backgrd)
  11079.           return;  /* must ignore signals in bkgrd */
  11080.  
  11081.      /*
  11082.  Except for special cases below, ignore keyboard quit signal.
  11083.  ^\ too easily confused with connect escape, and besides, we don't want
  11084.  to leave lock files around.  (Frank Prindle)
  11085. */
  11086.      SIGNAL(SIGQUIT, SIG_IGN);
  11087.  
  11088.  
  11089.      if (conif)
  11090.           return;   /* Nothing to do if already on. */
  11091.  
  11092.      /* check if invoked in background -- if so signals set to be ignored */
  11093.  
  11094.      if (SIGNAL(SIGINT, SIG_IGN) == SIG_IGN) {
  11095.           backgrd = 1;   /*   means running in background */
  11096.           return;
  11097.      }
  11098.      SIGNAL(SIGINT, f);   /* Function to trap to on interrupt. */
  11099.      SIGNAL(SIGHUP, f);   /* Or hangup, so lock file cleared. */
  11100.      conif = 1;    /* Flag console interrupts on. */
  11101. }
  11102.  
  11103.  
  11104. /*  C O N N O I  --  Reset console terminal interrupts */
  11105.  
  11106. connoi()
  11107. {    /* Console-no-interrupts */
  11108.  
  11109.      if (deblog)
  11110.           debug(F100, "funct: connoi  ", "", 0);
  11111.      if (backgrd)
  11112.           return;  /* Ignore signals in background */
  11113.  
  11114.      SIGNAL(SIGINT, SIG_DFL);
  11115.      SIGNAL(SIGHUP, SIG_DFL);
  11116.      SIGNAL(SIGQUIT, SIG_DFL);
  11117.      conif = 0;    /* Flag interrupt trapping off */
  11118. }
  11119.  
  11120.  
  11121. /*  myread() -- For use by systems that can do nonblocking read() calls  */
  11122. /*
  11123.  Returns:
  11124.   -1  if no characters available,
  11125.   -2  upon error (such as disconnect),
  11126.   otherwise value of character (0 or greater)
  11127. */
  11128. myread()
  11129. {
  11130.      static int     inbuf_item;
  11131.      static CHAR inbuf[257];
  11132.      CHAR readit;
  11133.  
  11134.      if (ungotn >= 0) {
  11135.           readit = ungotn;
  11136.      } else {
  11137.           if (inbufc > 0) {
  11138.                readit = inbuf[++inbuf_item];
  11139.           } else {
  11140.                if ((inbufc = read(0, inbuf, 256)) == 0) {  /* end of file */
  11141.                     /* means carrier dropped on modem connection */
  11142.                     errno = 9999;  /* magic number for no carrier */
  11143.                     return(-2);  /* end of file has no errno */
  11144.                }
  11145.                if (inbufc < 0)
  11146.                     return(-2);
  11147.                readit = inbuf[inbuf_item = 0];
  11148.           }
  11149.           inbufc--;
  11150.      }
  11151.      ungotn = -1;
  11152.      return(readit);
  11153. }
  11154.  
  11155.  
  11156. myunrd(ch)
  11157. CHAR ch;
  11158. {   /* push back up to one character */
  11159.      ungotn = ch;
  11160. }
  11161.  
  11162.  
  11163. /*  T T C H K  --  Tell how many characters are waiting in tty input buffer  */
  11164.  
  11165. ttchk()
  11166. {
  11167.      int     x;
  11168.      long     n;
  11169.      if (deblog)
  11170.           debug(F100, "funct: ttchk   ", "", 0);
  11171.  
  11172.      return(0);
  11173. }
  11174.  
  11175.  
  11176. /*  T T X I N  --  Get n characters from tty input buffer  */
  11177.  
  11178. /*  Returns number of characters actually gotten, or -1 on failure  */
  11179.  
  11180. /*  Intended for use only when it is known that n characters are actually */
  11181. /*  Available in the input buffer.  */
  11182.  
  11183. ttxin(n, buf)
  11184. int     n;
  11185. char     *buf;
  11186. {
  11187.      int     x;
  11188.      CHAR c;
  11189.  
  11190.      if (deblog)
  11191.           debug(F100, "funct: ttxin   ", "", 0);
  11192.      if (deblog)
  11193.           debug(F101, "ttxin: n", "", n);
  11194.      x = read(0, buf, n);
  11195.      if (deblog)
  11196.           debug(F101, " x", "", x);
  11197.      if (x > 0)
  11198.           buf[x] = '\0';
  11199.      if (x < 0)
  11200.           x = -1;
  11201.      return(x);
  11202. }
  11203.  
  11204.  
  11205. /*  T T O L  --  Similar to "ttinl", but for writing.  */
  11206.  
  11207. ttol(s, n)
  11208. int     n;
  11209. char     *s;
  11210. {
  11211.      int     x;
  11212.      char     *str;
  11213.      int     nbr;
  11214.      if (deblog)
  11215.           debug(F100, "funct: ttol    ", "", 0);
  11216.      if (ttyfd < 0)
  11217.           return(-1);  /* Not open. */
  11218.      if (deblog)
  11219.           debug(F111, "ttol", "string length", n);
  11220.      x = write(1, s, n);
  11221.      if (deblog)
  11222.           debug(F110, "ttol: packet ", s, 0);
  11223.      if (x < 0 && deblog)
  11224.           debug(F101, "ttol failed", "", x);
  11225.      return(x);
  11226. }
  11227.  
  11228.  
  11229. /*  T T O C  --  Output a character to the communication line  */
  11230.  
  11231. ttoc(c)
  11232. char     c;
  11233. {
  11234.      if (deblog)
  11235.           debug(F100, "funct: ttoc    ", "", 0);
  11236.      if (ttyfd < 0)
  11237.           return(-1);  /* Not open. */
  11238.      return(write(1, &c, 1));
  11239. }
  11240.  
  11241.  
  11242. /*  T T I N L  --  Read a record (up to break character) from comm line.  */
  11243. /*
  11244.   If no break character encountered within "max", return "max" characters,
  11245.   with disposition of any remaining characters undefined.  Otherwise, return
  11246.   the characters that were read, including the break character, in "dest" and
  11247.   the number of characters read as the value of function, or 0 upon end of
  11248.   file, or -1 if an error occurred.  Times out & returns error if not completed
  11249.   within "timo" seconds.
  11250. */
  11251.  
  11252. ttinl(dest, max, timo, eol)
  11253. int     max, timo;
  11254. char     *dest;
  11255. char     eol;
  11256. {
  11257.      int     x, y;
  11258.      CHAR c;
  11259.  
  11260.      if (deblog)
  11261.           debug(F101, "funct: ttinl timo ", "", timo);
  11262.      if (ttyfd < 0)
  11263.           return(-1);  /* Not open. */
  11264.      if (timo <= 0) {   /* Untimed read... */
  11265.           x = read(0, dest, max); /* Try to read. */
  11266.           return(x);   /* Return the count. */
  11267.      }
  11268.  
  11269.      /* Timed read... */
  11270.  
  11271.      SIGNAL(SIGALRM, timerh);  /* Set up timeout action. */
  11272.      ALARM(timo);   /* Set the timer. */
  11273.      if (setjmp(sjbuf))   /* Do this if timer went off. */
  11274.           x = -1;
  11275.      else if (kerld) {   /* Efficient Kermit line discipline */
  11276.           x = read(0, dest, max); /* for 4.2bsd only... */
  11277.      } else {    /* Normal case... */
  11278.           if (deblog)
  11279.                debug(F101, "ttinl, starting for loop, max ",
  11280.                     "", max);
  11281.           if (deblog)
  11282.                debug(F101, "                          eol ",
  11283.                     "", eol);
  11284.           for (x = c = y = 0; (x < max) && (c != eol); x++) {
  11285.                while ((y = read(0, &c, 1)) == 0) /* Else call system */
  11286.                     ;   /* ...for each character. */
  11287.                if (deblog)
  11288.                     debug(F101, "ttinl, read character ",
  11289.                          "", c);
  11290.                if (y < 0) {
  11291.                     ALARM(0);  /* Error, turn off timer, */
  11292.                     SIGNAL(SIGALRM, SIG_DFL); /* and associated interrupt. */
  11293.                     return(y);  /* Return the error indication. */
  11294.                }
  11295.                dest[x] = c;
  11296.           }
  11297.           x++;
  11298.      }
  11299.      dest[x] = '\0';   /* DRE 041890 - null terminate input line */
  11300.      ALARM(0);    /* Success, turn off timer, */
  11301.      SIGNAL(SIGALRM, SIG_DFL);  /* and associated interrupt. */
  11302.      return(x);    /* Return the count. */
  11303. }
  11304.  
  11305.  
  11306. /*  T T I N C --  Read a character from the communication line  */
  11307.  
  11308. ttinc(timo)
  11309. int     timo;
  11310. {
  11311.      int     n = 0;
  11312.      CHAR ch = 0;
  11313.  
  11314.      if (deblog)
  11315.           debug(F100, "funct: tinc    ", "", 0);
  11316.      if (ttyfd < 0)
  11317.           return(-1);  /* Not open. */
  11318.      if (timo <= 0) {   /* Untimed. */
  11319.           while ((n = read(0, &ch, 1)) == 0)
  11320.                ; /* Wait for a character. */
  11321.           if (n == 46) {     /* Break and exit if ':' is typed. */
  11322.                conoll("BREAK");
  11323.                doexit(BAD_EXIT);
  11324.           }
  11325.           return( (n > 0) ? (ch & 0377) : n );
  11326.      }
  11327.  
  11328.      SIGNAL(SIGALRM, timerh);  /* Timed, set up timer. */
  11329.      ALARM(timo);
  11330.      if (setjmp(sjbuf)) {
  11331.           n = -1;
  11332.      } else {
  11333.           n = read(0, &ch, 1);  /* Otherwise call the system. */
  11334.  
  11335.      }
  11336.      ALARM(0);    /* Turn off timer, */
  11337.      SIGNAL(SIGALRM, SIG_DFL);  /* and interrupt. */
  11338.      return( (n > 0) ? (ch & 0377) : n ); /* Return char or -1. */
  11339. }
  11340.  
  11341.  
  11342. /*  T T S N D B  --  Send a BREAK signals */
  11343.  
  11344. ttsndb()
  11345. {
  11346.      int     x;
  11347.      long     n;
  11348.      char     spd;
  11349.  
  11350.      if (deblog)
  11351.           debug(F100, "funct: ttsndb  ", "", 0);
  11352.      if (ttyfd < 0)
  11353.           return(-1);  /* Not open. */
  11354.  
  11355. }
  11356.  
  11357.  
  11358. /*  M S L E E P  --  Millisecond version of sleep().  */
  11359.  
  11360. /*
  11361.  Intended only for small intervals.  For big ones, just use sleep().
  11362. */
  11363.  
  11364. msleep(m)
  11365. int     m;
  11366. {
  11367.  
  11368.      if (deblog)
  11369.           debug(F100, "funct: msleep  ", "", 0);
  11370.  
  11371.  
  11372. }
  11373.  
  11374.  
  11375. /*  R T I M E R --  Reset elapsed time counter  */
  11376.  
  11377. rtimer()
  11378. {
  11379.      if (deblog)
  11380.           debug(F100, "funct: rtimer  ", "", 0);
  11381.      tcount = time( (long *) 0 );
  11382. }
  11383.  
  11384.  
  11385. /*  G T I M E R --  Get current value of elapsed time counter in seconds  */
  11386.  
  11387. gtimer()
  11388. {
  11389.      int     x;
  11390.      if (deblog)
  11391.           debug(F100, "funct: gtimer  ", "", 0);
  11392.      x = (int) (time( (long *) 0 ) - tcount);
  11393.      rtimer();
  11394.      return( (x < 0) ? 0 : x );
  11395. }
  11396.  
  11397.  
  11398. /*  Z T I M E  --  Return date/time string  */
  11399.  
  11400. ztime(s)
  11401. char     **s;
  11402. {
  11403. long clk;
  11404.  
  11405.      clk=time((long *) 0);
  11406.      *s=ctime(&clk);
  11407. }
  11408.  
  11409.  
  11410. /*  C O N G M  --  Get console terminal modes.  */
  11411.  
  11412. /*
  11413.  Saves current console mode, and establishes variables for switching between
  11414.  current (presumably normal) mode and other modes.
  11415. */
  11416.  
  11417. congm()
  11418. {
  11419.      if (deblog)
  11420.           debug(F100, "funct: congm   ", "", 0);
  11421.  
  11422.      GTTY(0, &ccold);   /* Structure for restoring */
  11423.      GTTY(0, &cccbrk);   /* For setting CBREAK mode */
  11424.      GTTY(0, &ccraw);   /* For setting RAW mode */
  11425.      cgmf = 1;    /* Flag that we got them. */
  11426. }
  11427.  
  11428.  
  11429. /*  C O N C B --  Put console in cbreak mode.  */
  11430.  
  11431. /*  Returns 0 if ok, -1 if not  */
  11432.  
  11433. concb(esc)
  11434. char     esc;
  11435. {
  11436.      int     x;
  11437.      if (deblog)
  11438.           debug(F100, "funct: concb   ", "", 0);
  11439.      if (cgmf == 0)
  11440.           congm();  /* Get modes if necessary. */
  11441.      escchr = esc;   /* Make this available to other fns */
  11442.      ckxech = 1;    /* Program can echo characters */
  11443.      if (x > -1)
  11444.           setbuf(stdout, NULL); /* Make console unbuffered. */
  11445.      return(x);
  11446. }
  11447.  
  11448.  
  11449. /*  C O N B I N  --  Put console in binary mode  */
  11450.  
  11451. /*  Returns 0 if ok, -1 if not  */
  11452.  
  11453. conbin(esc)
  11454. char     esc;
  11455. {
  11456.      if (cgmf == 0)
  11457.           congm();  /* Get modes if necessary. */
  11458.      escchr = esc;   /* Make this available to other fns */
  11459.      ckxech = 1;    /* Program can echo characters */
  11460. }
  11461.  
  11462.  
  11463. /*  C O N R E S  --  Restore the console terminal  */
  11464.  
  11465. conres()
  11466. {
  11467.      if (deblog)
  11468.           debug(F100, "funct: conres  ", "", 0);
  11469.      if (cgmf == 0)
  11470.           return(0);  /* Don't do anything if modes */
  11471.  
  11472.      sleep(1);    /*  not known! */
  11473.  
  11474.      ckxech = 0;    /* System should echo chars */
  11475.  
  11476.      return(STTY(0, &ccold));  /* Restore controlling tty */
  11477. }
  11478.  
  11479.  
  11480. /*  C O N O C  --  Output a character to the console terminal  */
  11481.  
  11482. conoc(c)
  11483. char     c;
  11484. {
  11485.      if (deblog)
  11486.           debug(F100, "funct: conoc   ", "", 0);
  11487.      write(1, &c, 1);
  11488. }
  11489.  
  11490.  
  11491. /*  C O N X O  --  Write x characters to the console terminal  */
  11492.  
  11493. conxo(x, s)
  11494. char     *s;
  11495. int     x;
  11496. {
  11497.      if (deblog)
  11498.           debug(F100, "funct: conxo   ", "", 0);
  11499.      write(1, s, x);
  11500. }
  11501.  
  11502.  
  11503. /*  C O N O L  --  Write a line to the console terminal  */
  11504.  
  11505. conol(s)
  11506. char     *s;
  11507. {
  11508.      int     len;
  11509.      len = strlen(s);
  11510.      if (deblog)
  11511.           debug(F100, "funct: conol   ", "", 0);
  11512.      write(1, s, len);
  11513. }
  11514.  
  11515.  
  11516. /*  C O N O L A  --  Write an array of lines to the console terminal */
  11517.  
  11518. conola(s)
  11519. char     *s[];
  11520. {
  11521.      int     i;
  11522.      if (deblog)
  11523.           debug(F100, "funct: conola  ", "", 0);
  11524.      for (i = 0 ; *s[i] ; i++)
  11525.           conol(s[i]);
  11526. }
  11527.  
  11528.  
  11529. /*  C O N O L L  --  Output a string followed by CRLF  */
  11530.  
  11531. conoll(s)
  11532. char     *s;
  11533. {
  11534.      conol(s);
  11535.      if (deblog)
  11536.           debug(F100, "funct: conoll  ", "", 0);
  11537.      write(1, "\r\n", 2);
  11538. }
  11539.  
  11540.  
  11541. /*  C O N C H K  --  Return how many characters available at console  */
  11542.  
  11543. conchk()
  11544. {
  11545.      int     x;
  11546.      long     n;
  11547.  
  11548.      if (deblog)
  11549.           debug(F100, "funct: conchk  ", "", 0);
  11550.      return(0);    /* Others can't do. */
  11551.  
  11552. }
  11553.  
  11554.  
  11555. /*  C O N I N C  --  Get a character from the console  */
  11556.  
  11557. coninc(timo)
  11558. int     timo;
  11559. {
  11560.      int     n = 0;
  11561.      char     ch;
  11562.      if (deblog)
  11563.           debug(F100, "funct: coninc  ", "", 0);
  11564.      if (timo <= 0 ) {   /* untimed */
  11565.           n = read(0, &ch, 1);  /* Read a character. */
  11566.           ch &= 0377;
  11567.           if (n > 0)
  11568.                return(ch);   /* Return the char if read */
  11569.           else
  11570.                     return(-1);    /* Return the char, or -1. */
  11571.      }
  11572.      SIGNAL(SIGALRM, timerh);  /* Timed read, so set up timer */
  11573.      ALARM(timo);
  11574.      if (setjmp(sjbuf))
  11575.           n = -2;
  11576.      else {
  11577.           n = read(0, &ch, 1);
  11578.           ch &= 0377;
  11579.      }
  11580.      ALARM(0);    /* Stop timing, we got our character */
  11581.      SIGNAL(SIGALRM, SIG_DFL);
  11582.      if (n > 0)
  11583.           return(ch);
  11584.      else
  11585.                return(-1);
  11586. }
  11587.  
  11588.  
  11589. /* A L A R M - this is a dummy alarm()     */
  11590.  
  11591. ALARM(sec)
  11592. unsigned     sec;
  11593. {
  11594.      return(1);
  11595. }
  11596.  
  11597.  
  11598. /* C H D I R - this is a dummy chdir()     */
  11599.  
  11600. CHDIR(path)
  11601. char     *path;
  11602. {
  11603.      return(0);
  11604. }
  11605.  
  11606.  
  11607. /* F O R K - this is a dummy fork()        */
  11608.  
  11609. FORK()
  11610. {
  11611.      return(1);
  11612. }
  11613.  
  11614.  
  11615. /* G T T Y - this is a dummy gtty()        */
  11616.  
  11617. GTTY(arg1, arg2)
  11618. int     arg1, arg2;
  11619. {
  11620.      return(0);
  11621. }
  11622.  
  11623.  
  11624. /* I O C T L - this is a dummy ioctl()     */
  11625.  
  11626. IOCTL(fildes, request, arg)
  11627. int     fildes, request, arg;
  11628. {
  11629.      return(1);
  11630. }
  11631.  
  11632.  
  11633. /* K I L L - this is a dummy kill()        */
  11634.  
  11635. KILL(pid, sig)
  11636. int     pid, sig;
  11637. {
  11638.      return(0);
  11639. }
  11640.  
  11641.  
  11642. /* P A U S E - this is a dummy pause()     */
  11643.  
  11644. PAUSE()
  11645. {
  11646.      return(0);
  11647. }
  11648.  
  11649.  
  11650. /* S I G N A L - this is a dummy signal()  */
  11651.  
  11652. SIGNAL(arg1, arg2)
  11653. int     arg1, arg2;
  11654. {
  11655.      return(0);
  11656. }
  11657.  
  11658.  
  11659. /* S T T Y - this is a dummy for stty()    */
  11660.  
  11661. STTY(arg1, arg2)
  11662. int     arg1, arg2;
  11663. {
  11664.      return(1);
  11665. }
  11666.  
  11667.  
  11668. /* S Y S T E M - this is a dummy for system() */
  11669.  
  11670. SYSTEM(cmd)
  11671. char     *cmd;
  11672. {
  11673.      return(1);
  11674. }
  11675.  
  11676.  
  11677. /* W A I T - this is a dummy for wait()       */
  11678.  
  11679. WAIT(stat_loc)
  11680. int     *stat_loc;
  11681. {
  11682.      return(1);
  11683. }
  11684.  
  11685.  
  11686. /*  S Y S C L E A N U P  --  System-dependent program cleanup.  */
  11687.  
  11688. syscleanup()
  11689. {
  11690.  
  11691.      /* for now, nothing... */
  11692.      return(0);
  11693. }
  11694.  
  11695.  
  11696. /* G E T P W U I D - this is a dummy for getpwuid()    */
  11697.  
  11698. struct passwd *GETPWUID (uid)
  11699. int     uid;
  11700. {
  11701.      return ( (struct passwd *) NULL);
  11702.  
  11703. }
  11704.  
  11705.  
  11706. /* G E T U I D  - this is a dummy for getuid()          */
  11707.  
  11708. unsigned short     GETUID()
  11709.  
  11710. {
  11711.      return (1);
  11712. }
  11713.  
  11714.  
  11715. /* E X E C L - dummy for execl()                        */
  11716.  
  11717.  
  11718. int     EXECL (path, arg0, arg1, arg2, arg3, arg4)
  11719.  
  11720. char     *path, *arg0, *arg1, *arg2, *arg3, *arg4;
  11721.  
  11722. {
  11723.      return (1);
  11724. }
  11725. <<< ckvus2.c >>>
  11726. /*  C K U U S 2  --  "User Interface" STRINGS module for NCR-VRX Kermit  */
  11727.  
  11728. /**********************************************************************
  11729. *                                                                     *
  11730. * IVS / MCS-Kermit REL 2                                              *
  11731. * source code                                                         *
  11732. *                                                                     *
  11733. * Change History:                                                     *
  11734. *                                                                     *
  11735. *                1. Modify C-Kermit(4E) source code to                *
  11736. *                   produce new module for MCS/IVS-Kermit             *
  11737. *                   ORIGINAL RELEASE                                  *
  11738. *                   June 22, 1990                                     *
  11739. *                                                                     *
  11740. *                                                                     *
  11741. ***********************************************************************/
  11742.  
  11743.  
  11744. /*
  11745.  Author: Frank da Cruz (SY.FDC@CU20B),
  11746.  Columbia University Center for Computing Activities, January 1985.
  11747.  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
  11748.  Permission is granted to any individual or institution to use, copy, or
  11749.  redistribute this software so long as it is not sold for profit, provided this
  11750.  copyright notice is retained.
  11751. */
  11752.  
  11753. /*  This module separates long strings from the body of the ckuser module. */
  11754.  
  11755. #include "ckcdeb.h"
  11756. #include <stdio.h>
  11757. #include <ctype.h>
  11758. #include "ckcker.h"
  11759. #include "ckucmd.h"
  11760. #include "ckuusr.h"
  11761. #ifdef MCS_FLAG
  11762. #include "mcs.h"
  11763. #endif
  11764.  
  11765. extern CHAR    mystch, stchr, eol, seol, padch, mypadc, ctlq;
  11766. extern CHAR    data[], *rdatap, ttname[];
  11767. extern char    cmdbuf[], line[], debfil[], pktfil[], sesfil[], trafil[];
  11768. extern int     nrmt, nprm, dfloc, deblog, seslog, speed, local, parity,
  11769.                duplex;
  11770. extern int     send_id, recv_id, send_num,  recv_num, send_renum, recv_renum;
  11771. extern int     send_addnum, recv_addnum, rptflg;
  11772. extern int     turn, turnch, pktlog, tralog, mdmtyp, flow, cmask, timef,
  11773.  spsizf;
  11774. extern int     rtimo, timint, npad, mypadn, bctr, delay;
  11775. extern int     maxtry, spsiz, urpsiz, maxsps, maxrps, ebqflg, ebq;
  11776. extern int     rptflg, rptq, fncnv, binary, pktlog, /* warn,*/ quiet, fmask,
  11777.                keep;
  11778. extern int     tsecs, bctu, len, atcapu, lpcapu, swcapu, wsize, sq, rpsiz;
  11779. extern int     capas;
  11780. extern long    filcnt, tfc, tlci, tlco, ffc, flci, flco;
  11781. extern char    *dftty, *versio, *ckxsys;
  11782. extern struct  keytab prmtab[];
  11783. extern struct  keytab remcmd[];
  11784.  
  11785. static
  11786. char     *hlp1[] = {                  /* unless the  kermit CNTLSTR
  11787.                                      is set up properly this
  11788.                                      message will never be output
  11789.                                                                    */
  11790.      "\n",
  11791.      "  Usage: kermit [-x arg [-x arg]...[-yyy]..]]\n",
  11792.      "   x requires an argument, y requires option with no argument:\n",
  11793.           "     actions (* options also require -l and -b) --\n",
  11794.      "       -s file(s)   send\n",
  11795.      "       -r           receive\n",
  11796.      "       -k           receive to stdout\n",
  11797.      "       -a name      alternate name, used with -s, -r, -g\n",
  11798.           "       -x           enter server mode\n",
  11799.      "     * -c           connect before transaction\n",
  11800.      "     * -n           connect after transaction\n",
  11801.      "     settings --\n",
  11802.      "       -l line      communication line device\n",
  11803.      "       -b baud      line speed, e.g. 1200\n",
  11804.      "       -i           binary file or NCR-VRX-to-PC (text by default)\n",
  11805.           "       -p x         parity, x is one of e,o,m,s,n\n",
  11806.      "       -t           line turnaround handshake = xon, half duplex\n",
  11807.           "       -q           be quiet during file transfer\n",
  11808.      "       -d           log debugging info to debuglog\n",
  11809.      "       -e length    (extended) receive packet length\n",
  11810.      " If no action command is included, enter interactive dialog.\n",
  11811.           ""
  11812. };
  11813.  
  11814.  
  11815. /*  U S A G E */
  11816.  
  11817. usage()
  11818. {
  11819.      conola(hlp1);
  11820. }
  11821.  
  11822.  
  11823. /*  Help string definitions  */
  11824.  
  11825. static char     *tophlp[] = {
  11826. "\n",
  11827. "Type ? for a list of commands, type 'help x' for any command x.\n",
  11828. "While typing commands, use the following special characters:\n\n",
  11829. " DEL, RUBOUT, BACKSPACE, CTRL-H: Delete the most recent character typed.\n",
  11830. " ?       (question mark) display help on the current command or field.\n",
  11831. " \\      (backslash) include the following character literally.\n\n",
  11832. "\n",
  11833.      "" };
  11834.  
  11835.  
  11836. static char     *hmxxbye = "V-Kermit does not support this functionality";
  11837.  
  11838. static char     *hmxxclo =
  11839. "Close logs: 'help log' for further info.";
  11840.  
  11841. static char     *hmxxcon = "V-Kermit does not support this functionality";
  11842.  
  11843. static char     *hmxxget = "V-Kermit does not support this functionality";
  11844.  
  11845. static char     *hmxxlg[] = {
  11846. "Record information in a log file:\n\n",
  11847. " debugging             Debugging information, to help track down\n",
  11848. "  (default debuglog)  bugs in the V-Kermit program.\n\n",
  11849. " packets           Kermit packets, to help track down protocol problems.\n",
  11850. "  (packetlog)\n\n",
  11851. " transactions          Names and statistics about files transferred.\n",
  11852. "  (transactlog)\n",
  11853. "" };
  11854.  
  11855.  
  11856. static char     *hmxxlogi[] = {
  11857.      "V-Kermit does not support this functionality\n",
  11858.      "" };
  11859.  
  11860.  
  11861. static char     *hmxxrc[] = {
  11862.      "V-Kermit does not support this functionality",
  11863.      "" };
  11864.  
  11865.  
  11866. static char     *hmxxsen = "V-Kermit does not support this functionality";
  11867.  
  11868. static char     *hmxxser =
  11869. "Enter server mode. Commands are in packet form from other Kermit program.";
  11870.  
  11871. static char     *hmhset[] = {
  11872. "The 'set' command is used to establish various communication or file\n",
  11873. "parameters.  The 'show' command can be used to display the values of\n",
  11874. "'set' parameters.  Help is available for each individual parameter;\n",
  11875. "type 'help set ?' to see what's available.\n",
  11876. "" };
  11877.  
  11878.  
  11879. static char     *hmxychkt[] = {
  11880. "Type of packet block check to be used for error detection, 1, 2, or 3.\n",
  11881. "Type 1 is standard, and catches most errors.  Types 2 and 3 specify more\n",
  11882. "rigorous checking at the cost of higher overhead.  Not all Kermit programs\n",
  11883. "support types 2 and 3.\n",
  11884. "" };
  11885.  
  11886.  
  11887. static char     *hmxyf[] = {
  11888. "set file: names, type, display.\n\n",
  11889. "'names' are normally 'converted', which means file names are converted\n",
  11890. "to 'common form' during transmission; 'literal' means use filenames\n",
  11891. "literally (useful between like systems).\n\n",
  11892. "'type' is normally 'text', in which conversion is done between NCR-VRX\n",
  11893. "newlines and CRLF line delimiters; 'binary' means to do no conversion.\n",
  11894. "Use 'binary' for executable programs or binary data.\n\n",
  11895. "\n'display' is normally 'on', causing file transfer ",
  11896. "progress to be displayed\n",
  11897. "on your screen when in local mode.  'set display off' is useful for\n",
  11898. "allowing file transfers to proceed in the background.\n\n",
  11899. "" };
  11900.  
  11901.  
  11902. static char     *hmhrmt[] = {
  11903.      "V-Kermit does not support this functionality",
  11904.      "" };
  11905.  
  11906.  
  11907. /*  D O H L P  --  Give a help message  */
  11908.  
  11909. dohlp(xx)
  11910. int     xx;
  11911. {
  11912.      int     x, y;
  11913.  
  11914.      if (xx < 0)
  11915.           return(xx);
  11916.      switch (xx) {
  11917.  
  11918.      case XXBYE:
  11919.           return(hmsg(hmxxbye));
  11920.  
  11921.      case XXCLO:
  11922.           return(hmsg(hmxxclo));
  11923.  
  11924. /*
  11925.      case XXCON:
  11926.           return(hmsg(hmxxcon));
  11927. */
  11928.  
  11929. /*
  11930.      case XXCWD:
  11931.           return(hmsg(
  11932.                 "Change Working Directory, equivalent to VRX filen command"));
  11933. */
  11934.  
  11935. /*
  11936.      case XXDEL:
  11937.           return(hmsg("Delete a local file or files"));
  11938. */
  11939.  
  11940. /*
  11941.      case XXDIAL:
  11942.           return(hmsg("Dial a number using modem autodialer"));
  11943. */
  11944.  
  11945. /*
  11946.      case XXDIR:
  11947.           return(hmsg("Display a directory of local files"));
  11948. */
  11949.  
  11950.      case XXECH:
  11951.           return(hmsg("Display the rest of the command on the terminal."));
  11952.  
  11953.      case XXEXI:
  11954.      case XXQUI:
  11955.           return(hmsg("Exit from the Kermit program, closing any open logs."));
  11956.  
  11957. /*
  11958.      case XXFIN:
  11959.           return(hmsg(
  11960.           "Tell the remote Kermit server to shut down without logging out."));
  11961. */
  11962.  
  11963. /*
  11964.      case XXGET:
  11965.           return(hmsg(hmxxget));
  11966. */
  11967.  
  11968. /*
  11969.      case XXHAN:
  11970.           return(hmsg("Hang up the phone."));
  11971. */
  11972.  
  11973.      case XXHLP:
  11974.           return(hmsga(tophlp));
  11975.  
  11976.      case XXLOG:
  11977.           return(hmsga(hmxxlg));
  11978.  
  11979. /*
  11980.      case XXLOGI:
  11981.           return(hmsga(hmxxlogi));
  11982. */
  11983.  
  11984. /*
  11985.      case XXREC:
  11986.           return(hmsga(hmxxrc));
  11987. */
  11988.  
  11989. /*
  11990.      case XXREM:
  11991.           if ((y = cmkey(remcmd,nrmt,"Remote command","")) == -2) return(y);
  11992.           if (y == -1) return(y);
  11993.           if (x = (cmcfm()) < 0) return(x);
  11994.           return(dohrmt(y));
  11995. */
  11996.  
  11997. /*
  11998.       case XXSEN:
  11999.            return(hmsg(hmxxsen));
  12000. */
  12001.  
  12002.      case XXSER:
  12003.           return(hmsg(hmxxser));
  12004.  
  12005.      case XXSET:
  12006.           if ((y = cmkey(prmtab, nprm, "Parameter", "")) == -2)
  12007.                return(y);
  12008.           if (y == -2)
  12009.                return(y);
  12010.           if (x = (cmcfm()) < 0)
  12011.                return(x);
  12012.           return(dohset(y));
  12013.  
  12014. /*
  12015.      case XXSHE:
  12016.           return(hmsg(
  12017.             "Issue a command to the VRX shell (space req.after '!')"));
  12018. */
  12019.  
  12020.      case XXSHO:
  12021.           return(hmsg("Display current values of 'set' parameters."));
  12022.  
  12023. /*
  12024.      case XXSPA:
  12025.           return(hmsg("Display disk usage in current device, directory"));
  12026. */
  12027.  
  12028.      case XXSTA:
  12029.           return(hmsg("Display statistics about most recent file transfer"));
  12030.  
  12031.      case XXTAK:
  12032.           return(hmsg("Take Kermit commands from the named file."));
  12033.  
  12034.      default:
  12035.           if (x = (cmcfm()) < 0)
  12036.                return(x);
  12037. #ifndef MCS_FLAG
  12038.           printf("V-Kermit does not support: %s\n", cmdbuf);
  12039. #else
  12040.           sprintf(print_str,"V-Kermit does not support: %s\n", cmdbuf);
  12041.           mcs_printf(print_str);
  12042. #endif
  12043.           break;
  12044.      }
  12045.      return(0);
  12046. }
  12047.  
  12048.  
  12049. /*  H M S G  --  Get confirmation, then print the given message  */
  12050.  
  12051. hmsg(s)
  12052. char     *s;
  12053. {
  12054.      int     x;
  12055.      if ((x = cmcfm()) < 0)
  12056.           return(x);
  12057.      puts(s);
  12058.      return(0);
  12059. }
  12060.  
  12061.  
  12062. hmsga(s)
  12063. char     *s[];
  12064. {                   /* Same function, but for arrays */
  12065.      int     x, i;
  12066.      if ( x = (cmcfm()) < 0)
  12067.           return(x);
  12068.      for ( i = 0; *s[i] ; i++)
  12069.           fputs(s[i], stdout);
  12070.      fputc( '\n', stdout);
  12071.      return(0);
  12072. }
  12073.  
  12074.  
  12075. /*  D O H S E T  --  Give help for SET command  */
  12076.  
  12077. dohset(xx)
  12078. int     xx;
  12079. {
  12080.  
  12081.      if (xx == -3)
  12082.           return(hmsga(hmhset));
  12083.      if (xx < 0)
  12084.           return(xx);
  12085.      switch (xx) {
  12086.  
  12087.      case XYCHKT:
  12088.           return(hmsga(hmxychkt));
  12089.  
  12090. /*
  12091.      case XYDELA:
  12092.           puts(
  12093.           "\# of secs to wait before SND first packet after 'send' command.");
  12094.           return(0);
  12095. */
  12096.  
  12097.      case XYDUPL:
  12098.           puts("During 'connect': 'full' means remote echoes, ");
  12099.           puts("'half' means this program does its own echoing.");
  12100.           return(0);
  12101.  
  12102. /*
  12103.      case XYESC:
  12104.           printf(
  12105.                "Dec ASCII for ESC char during 'connect',\n(Control-\\)\n");
  12106.           return(0);
  12107. */
  12108.  
  12109.      case XYFILE:
  12110.           return(hmsga(hmxyf));
  12111.  
  12112.      case XYFLOW:
  12113.           puts("Type of flow control used.  Choices 'xon/xoff' and 'none'.");
  12114.           puts("normally xon/xoff.");
  12115.           return(0);
  12116.  
  12117.      case XYHAND:
  12118.           puts("Dec ASCII for char to use for half duplex line turnaround");
  12119.           puts("handshake.  Normally, handshaking is not done.");
  12120.           return(0);
  12121.  
  12122. /*
  12123.      case XYLINE:
  12124.           printf("Device name of communication line to use. Normally %s.\n",
  12125.                  dftty);
  12126.           if (!dfloc) {
  12127.           printf("If you set the line to other than %s, then Kermit\n",dftty);
  12128.           printf("will be in 'local' mode; 'set line' will reset Kermit ");
  12129.           printf("to remote mode.\n");
  12130.            }
  12131.           return(0);
  12132. */
  12133.  
  12134. /*
  12135.           case XYMODM:
  12136.                puts("Type of modem for dialing remote connections. ");
  12137.                puts(" Needed to indicate modem can");
  12138.                puts(" be commanded to dial without 'CD' from modem. ");
  12139.                puts("  Many recently") ;
  12140.                puts("manufactured modems use 'hayes' protocol.  ");
  12141.                puts("Type 'set modem ?' to see what");
  12142.                puts("types of modems are supported by this program.");
  12143.                return(0);
  12144. */
  12145.  
  12146.  
  12147.      case XYPARI:
  12148.           puts("Parity to use during terminal connection and file transfer:");
  12149.           puts("even, odd, mark, space, or none.  Normally none.");
  12150.           return(0);
  12151.  
  12152.      case XYPROM:
  12153. #ifndef MCS_FLAG
  12154.           puts("Prompt string for this program, normally 'IVS-Kermit>'.");
  12155. #else
  12156.           puts("Prompt string for this program, normally 'MCS-Kermit>'.");
  12157. #endif
  12158.           return(0);
  12159.  
  12160.      case XYRETR:
  12161.           puts("How many times to retransmit a packet before giving up");
  12162.           return(0);
  12163.  
  12164.      case XYSPEE:
  12165.           puts("Communication line speed for external tty line ");
  12166.           puts("specified in most recent");
  12167.           puts("'set line' command.  Any of the common baud rates:");
  12168.           puts(" 0, 110, 150, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200.");
  12169.           return(0);
  12170.  
  12171.      case XYRECV:
  12172. /*
  12173. puts("Specify parameters for inbound packets:");
  12174. puts("End-Of-Packet (ASCII value), Id-Fields ('keep' or 'discard'),");
  12175. puts("Line-Numbers ('keep' or 'discard'), Renumber ('on' or 'off'),");
  12176. puts("Packet-Length (1000 or less), Padding (amount, 94 or less),");
  12177. puts("Pad-Character (ASCII value), Start-Of-Packet (ASCII value),");
  12178. puts("and Timeout (94 seconds or less), all specified as decimal numbers");
  12179. puts("except for Id-Fields, Line-Numbers and Renumber.");
  12180. return(0);
  12181. */
  12182.     puts("Specify parameters for inbound packets:");
  12183.     puts("  End-of-Packet (ASCII value), Packet-Length (1000 or less),");
  12184.     puts("  Padding (amount, 94 or less), Pad-Character (ASCII value),");
  12185.     puts("  Start-of-Packet (ASCII value), and Timeout (94 seconds or less),");
  12186.     puts("  all specified as decimal numbers.");
  12187.     return(0);
  12188.  
  12189.      case XYSEND:
  12190. /*
  12191. puts("Specify parameters for outbound packets:");
  12192. puts("End-Of-Packet (ASCII value), Id-Fields ('keep' or 'discard'),");
  12193. puts("Line-Numbers ('keep' or 'discard'), Renumber ('on' or 'off'),");
  12194. puts("Packet-Length (1000 or less), Padding (amount, 94 or less),");
  12195. puts("Pad-Character (ASCII value), Start-Of-Packet (ASCII value),");
  12196. puts("and Timeout (94 seconds or less), all specified as decimal numbers");
  12197. puts("except for Id-Fields, Line-Numbers and Renumber.");
  12198. return(0);
  12199. */
  12200.    puts("Specify parameters for outbound packets:");
  12201.    puts("  End-of-Packet (ASCII value), Packet-Length (1000 or less),");
  12202.    puts("  Padding (amount, 94 or less), Pad-Character (ASCII value),");
  12203.    puts("  Start-of-Packet (ASCII value), and Timeout (94 seconds or less),");
  12204.    puts("  all specified as decimal numbers.");
  12205.    return(0);
  12206.  
  12207.      default:
  12208. #ifndef MCS_FLAG
  12209.           printf("V-Kermit does not support: %s\n", cmdbuf);
  12210. #else
  12211.           sprintf(print_str,"V-Kermit does not support: %s\n", cmdbuf);
  12212.           mcs_printf(print_str);
  12213. #endif
  12214.           return(0);
  12215.      }
  12216. }
  12217.  
  12218.  
  12219. /*  D O H R M T  --  Give help about REMOTE command  */
  12220.  
  12221. dohrmt(xx)
  12222. int     xx;
  12223. {
  12224.      int     x;
  12225.      if (xx == -3)
  12226.           return(hmsga(hmhrmt));
  12227.      if (xx < 0)
  12228.           return(xx);
  12229.      if (x = (cmcfm()) < 0)
  12230.           return(x);
  12231. #ifndef MCS_FLAG
  12232.      printf("V-Kermit does not support this functionality- %s\n",
  12233.           cmdbuf);
  12234. #else
  12235.       sprintf(print_str,"V-Kermit does not support this functionality- %s\n",
  12236.           cmdbuf);
  12237.       mcs_printf(print_str);
  12238. #endif
  12239.      return(-2);
  12240. }
  12241.  
  12242. /*  D O L O G  --  Do the log command  */
  12243.  
  12244. dolog(x)
  12245. int     x;
  12246. {
  12247.      int     y;
  12248.      char     *s;
  12249.  
  12250.      switch (x) {
  12251.  
  12252.      case LOGD:
  12253.           y = cmofi("Name of debugging log file", "debuglog",
  12254.               &s);
  12255.           break;
  12256.  
  12257.      case LOGP:
  12258.           y = cmofi("Name of packet log file", "packetlog", &s);
  12259.           break;
  12260.  
  12261. /*
  12262.      case LOGS:
  12263.           y = cmofi("Name of session log file","sessionlog",&s);
  12264.           break;
  12265. */
  12266.  
  12267.      case LOGT:
  12268.           y = cmofi("Name of transaction log file", "transactlog",
  12269.                &s);
  12270.           break;
  12271.  
  12272.      default:
  12273. #ifndef MCS_FLAG
  12274.           printf("\n?Unexpected log designator - %d\n", x);
  12275. #else
  12276.           sprintf(print_str,"\n?Unexpected log designator - %d\n", x);
  12277.           mcs_printf(print_str);
  12278. #endif
  12279.           return(-2);
  12280.      }
  12281.      if (y < 0)
  12282.           return(y);
  12283.  
  12284.      strcpy(line, s);
  12285.      s = line;
  12286.      if ((y = cmcfm()) < 0)
  12287.           return(y);
  12288.  
  12289.      switch (x) {
  12290.  
  12291.      case LOGD:
  12292.           return(deblog = debopn(s));
  12293.  
  12294.      case LOGP:
  12295.           zclose(ZPFILE);
  12296.           y = zopeno(ZPFILE, s);
  12297.           if (y > 0)
  12298.                strcpy(pktfil, s);
  12299.           else
  12300.                *pktfil = '\0';
  12301.           return(pktlog = y);
  12302.  
  12303. /*
  12304.      case LOGS:
  12305.           zclose(ZSFILE);
  12306.           y = zopeno(ZSFILE,s);
  12307.           if (y > 0) strcpy(sesfil,s); else *sesfil = '\0';
  12308.           return(seslog = y);
  12309. */
  12310.  
  12311.      case LOGT:
  12312.           zclose(ZTFILE);
  12313.           tralog = zopeno(ZTFILE, s);
  12314.           if (tralog > 0) {
  12315.                strcpy(trafil, s);
  12316.                tlog(F110, "Transaction Log:", versio, 0l);
  12317.                tlog(F100, ckxsys, "", 0);
  12318.                ztime(&s);
  12319.                tlog(F100, s, "", 0l);
  12320.           } else
  12321.                *trafil = '\0';
  12322.           return(tralog);
  12323.  
  12324.      default:
  12325.           return(-2);
  12326.      }
  12327. }
  12328.  
  12329.  
  12330. /*  D E B O P N  --  Open a debugging file  */
  12331.  
  12332. debopn(s)
  12333. char     *s;
  12334. {
  12335.      char     *tp;
  12336.      zclose(ZDFILE);
  12337.      deblog = zopeno(ZDFILE, s);
  12338.      if (deblog > 0) {
  12339.           strcpy(debfil, s);
  12340.           if (deblog)
  12341.                debug(F110, "Debug Log ", versio, 0);
  12342.           if (deblog)
  12343.                debug(F100, ckxsys, "", 0);
  12344.           ztime(&tp);
  12345.           if (deblog)
  12346.                debug(F100, tp, "", 0);
  12347.      } else
  12348.           *debfil = '\0';
  12349.      return(deblog);
  12350. }
  12351.  
  12352.  
  12353. /*  S H O P A R  --  Show Parameters  */
  12354.  
  12355. shopar()
  12356. {
  12357.      int     i;
  12358.      extern struct keytab mdmtab[];
  12359.      extern int     nmdm;
  12360.  
  12361. #ifndef MCS_FLAG
  12362.      printf("\n%s, %s\n", versio, ckxsys);
  12363.      printf("Communications Parameters:\n");
  12364. #else
  12365.        sprintf(print_str,"\n%s, %s\n", versio, ckxsys);
  12366.        mcs_printf(print_str);
  12367.        mcs_printf("Communications Parameters:\n");
  12368. #endif
  12369. /*
  12370.     printf(" Line: %s, speed: %d, mode: ",ttname,speed);
  12371.     if (local) printf("local"); else printf("remote");
  12372.     for (i = 0; i < nmdm; i++) {
  12373.         if (mdmtab[i].val == mdmtyp) {
  12374.             printf(", modem-dialer: %s",mdmtab[i].kwd);
  12375.             break;
  12376.         }
  12377.     }
  12378.  */
  12379. #ifndef MCS_FLAG
  12380.      printf("  Bits: %d", (parity) ? 7 : 8);
  12381.      printf(", Parity: ");
  12382. #else
  12383.      sprintf(print_str,"  Bits: %d", (parity) ? 7 : 8);
  12384.      mcs_printf(print_str);
  12385.      mcs_printf(", Parity: ");
  12386. #endif
  12387.      switch (parity) {
  12388.      case 'e':
  12389. #ifndef MCS_FLAG
  12390.           printf("even");
  12391. #else
  12392.           mcs_printf("even");
  12393. #endif
  12394.           break;
  12395.      case 'o':
  12396. #ifndef MCS_FLAG
  12397.           printf("odd");
  12398. #else
  12399.           mcs_printf("odd");
  12400. #endif
  12401.           break;
  12402.      case 'm':
  12403. #ifndef MCS_FLAG
  12404.           printf("mark");
  12405. #else
  12406.           mcs_printf("mark");
  12407. #endif
  12408.           break;
  12409.      case 's':
  12410. #ifndef MCS_FLAG
  12411.           printf("space");
  12412. #else
  12413.           mcs_printf("space");
  12414. #endif
  12415.           break;
  12416.      case 0:
  12417. #ifndef MCS_FLAG
  12418.           printf("none");
  12419. #else
  12420.           mcs_printf("none");
  12421. #endif
  12422.           break;
  12423.      default:
  12424. #ifndef MCS_FLAG
  12425.           printf("invalid - %d", parity);
  12426. #else
  12427.           sprintf(print_str,"invalid - %d", parity);
  12428.           mcs_printf(print_str);
  12429. #endif
  12430.           break;
  12431.      }
  12432. #ifndef MCS_FLAG
  12433.      printf(", Duplex: ");
  12434. #else
  12435.      mcs_printf(", Duplex: ");
  12436. #endif
  12437.      if (duplex)
  12438. #ifndef MCS_FLAG
  12439.           printf("half, ");
  12440. #else
  12441.           mcs_printf("half, ");
  12442. #endif
  12443.      else
  12444. #ifndef MCS_FLAG
  12445.           printf("full, ");
  12446.      printf("Flow: ");
  12447. #else
  12448.           mcs_printf("full, ");
  12449.      mcs_printf("Flow: ");
  12450. #endif
  12451.      if (flow == 1)
  12452. #ifndef MCS_FLAG
  12453.           printf("xon/xoff");
  12454. #else
  12455.           mcs_printf("xon/xoff");
  12456. #endif
  12457.      else if (flow == 0)
  12458. #ifndef MCS_FLAG
  12459.           printf("none");
  12460. #else
  12461.           mcs_printf("none");
  12462. #endif
  12463.      else
  12464. #ifndef MCS_FLAG
  12465.           printf("%d", flow);
  12466. #else
  12467.           sprintf(print_str,"%d",flow);
  12468.           mcs_printf(print_str);
  12469. #endif
  12470. #ifndef MCS_FLAG
  12471.      printf(", Handshake: ");
  12472. #else
  12473.      mcs_printf(", Handshake: ");
  12474. #endif
  12475. #ifndef MCS_FLAG
  12476.      if (turn)
  12477.           printf("%d\n", turnch);
  12478. #else
  12479.      if (turn) {
  12480.           sprintf(print_str,"%d\n", turnch);
  12481.           mcs_printf(print_str);
  12482.      }
  12483. #endif
  12484.      else
  12485. #ifndef MCS_FLAG
  12486.           printf("none\n");
  12487. #else
  12488.           mcs_printf("none\n");
  12489. #endif
  12490. /*
  12491.     printf("  Terminal emulation: %d bits\n", (cmask == 0177) ? 7 : 8);
  12492. */
  12493.  
  12494. #ifndef MCS_FLAG
  12495.      printf("\nProtocol & Transfer Parameters:     Send      Receive");
  12496. #else
  12497.      mcs_printf("\nProtocol & Transfer Parameters:     Send      Receive");
  12498. #endif
  12499.      if (timef || spsizf)
  12500. #ifndef MCS_FLAG
  12501.           printf("    (* = override)");
  12502. #else
  12503.           mcs_printf("    (* = override)");
  12504. #endif
  12505.  
  12506. #ifndef MCS_FLAG
  12507.      printf("\n  Timeout:      %23d%12d", rtimo,  timint);
  12508. #else
  12509.        sprintf(print_str,"\n  Timeout:      %23d%12d",rtimo,timint);
  12510.        mcs_printf(print_str);
  12511. #endif
  12512.      if (timef)
  12513. #ifndef MCS_FLAG
  12514.           printf("*");
  12515. #else
  12516.           mcs_printf("*");
  12517. #endif
  12518.  
  12519. #ifndef MCS_FLAG
  12520.      printf("\n  Padding:      %23d%12d\n", npad,   mypadn);
  12521.      printf(  "  Pad Character:%23d%12d\n", padch,  mypadc);
  12522.      printf(  "  Packet Start: %23d%12d\n", mystch, stchr);
  12523.      printf(  "  Packet End:   %23d%12d\n", seol,   eol);
  12524.      printf(  "  Packet Length:%23d", spsiz);
  12525.      printf( spsizf ? "*" : " " );
  12526. #else
  12527.      sprintf(print_str,"\n  Padding:      %23d%12d\n", npad,   mypadn);
  12528.      mcs_printf(print_str);
  12529.      sprintf(print_str,"  Pad Character:%23d%12d\n", padch,  mypadc);
  12530.      mcs_printf(print_str);
  12531.      sprintf(print_str,"  Packet Start: %23d%12d\n", mystch, stchr);
  12532.      mcs_printf(print_str);
  12533.      sprintf(print_str,"  Packet End:   %23d%12d\n", seol,   eol);
  12534.      mcs_printf(print_str);
  12535.      sprintf(print_str,"  Packet Length:%23d", spsiz);
  12536.      mcs_printf(print_str);
  12537.      sprintf(print_str,(spsizf ? "*" : " "));
  12538.      mcs_printf(print_str);
  12539. #endif
  12540.      /*  printf("%11d\n", rpsiz); */
  12541.  
  12542. #ifndef MCS_FLAG
  12543.      if (urpsiz > 94)
  12544.           printf("%11d (%d)\n", urpsiz, rpsiz);
  12545. #else
  12546.      if (urpsiz > 94) {
  12547.           sprintf(print_str,"%11d (%d)\n", urpsiz, rpsiz);
  12548.           mcs_printf(print_str);
  12549.      }
  12550. #endif
  12551. #ifndef MCS_FLAG
  12552.      else
  12553.           printf("%11d\n", rpsiz);
  12554. #else
  12555.      else {
  12556.           sprintf(print_str,"%11d\n", rpsiz);
  12557.           mcs_printf(print_str);
  12558.      }
  12559. #endif
  12560.  
  12561. /*
  12562.     printf(  "  ID Fields:    ");
  12563.     if (send_id) printf("%23s","keep");
  12564.     else printf("%23s","discard");
  12565.     if (recv_id) printf("%12s\n","keep");
  12566.     else printf("%12s\n","discard");
  12567.  
  12568.     printf(  "  Line Numbers: ");
  12569.     if (send_num) printf("%23s","keep");
  12570.     else printf("%23s","discard");
  12571.     if (recv_num) printf("%12s\n","keep");
  12572.     else printf("%12s\n","discard");
  12573.  
  12574.     printf(  "  Renumbering:  ");
  12575.     if (send_renum) printf("%23s","on");
  12576.     else printf("%23s","off");
  12577.     if (recv_renum) printf("%12s\n","on");
  12578.     else printf("%12s\n","off");
  12579.  
  12580.     printf(  "  Number Adding:");
  12581.     if (send_addnum) printf("%23s","on");
  12582.     else printf("%23s","off");
  12583.     if (recv_addnum) printf("%12s\n","on");
  12584.     else printf("%12s\n","off");
  12585.     printf("  Block Check Type: %d,  Delay: %d\n",bctr,delay);
  12586. */
  12587. #ifndef MCS_FLAG
  12588.      printf("  Block Check Type:     %d\n", bctr);
  12589. #else
  12590.      sprintf(print_str,"  Block Check Type:     %d\n", bctr);
  12591.      mcs_printf(print_str);
  12592. #endif
  12593. #ifndef MCS_FLAG
  12594.      if (ebqflg)
  12595.           printf("  8th-Bit Prefix:      '%c'\n", ebq);
  12596. #else
  12597.      if (ebqflg) {
  12598.           sprintf(print_str,"  8th-Bit Prefix:      '%c'\n", ebq);
  12599.           mcs_printf(print_str);
  12600.      }
  12601. #endif
  12602. #ifndef MCS_FLAG
  12603.      if (rptflg)
  12604.           printf("  Repeat-Count Prefix: '%c'\n", rptq);
  12605. #else
  12606.      if (rptflg) {
  12607.           sprintf(print_str,"  Repeat-Count Prefix: '%c'\n", rptq);
  12608.           mcs_printf(print_str);
  12609.      }
  12610. #endif
  12611.  
  12612. #ifndef MCS_FLAG
  12613.      printf("\nFile Parameters:\n  File Names:     ");
  12614. #else
  12615.      mcs_printf("\nFile Parameters:\n  File Names:     ");
  12616. #endif
  12617. #ifndef MCS_FLAG
  12618.      if (fncnv)
  12619.           printf("%-12s", "converted");
  12620. #else
  12621.      if (fncnv) {
  12622.           sprintf(print_str,"%-12s", "converted");
  12623.           mcs_printf(print_str);
  12624.      }
  12625. #endif
  12626. #ifndef MCS_FLAG
  12627.      else
  12628.           printf("%-12s", "literal");
  12629. #else
  12630.      else {
  12631.           sprintf(print_str,"%-12s", "literal");
  12632.           mcs_printf(print_str);
  12633.      }
  12634. #endif
  12635. #ifndef MCS_FLAG
  12636.      printf("   Debugging Log:    ");
  12637. #else
  12638.      sprintf(print_str,"   Debugging Log:    ");
  12639.      mcs_printf(print_str);
  12640. #endif
  12641. #ifndef MCS_FLAG
  12642.      if (deblog)
  12643.           printf("%s", debfil);
  12644. #else
  12645.      if (deblog) {
  12646.           sprintf(print_str,"%s", debfil);
  12647.           mcs_printf(print_str);
  12648.      }
  12649. #endif
  12650.      else
  12651. #ifndef MCS_FLAG
  12652.           printf("none");
  12653. #else
  12654.           mcs_printf("none");
  12655. #endif
  12656.  
  12657. #ifndef MCS_FLAG
  12658.      printf("\n  File Type:      ");
  12659. #else
  12660.      mcs_printf("\n  File Type:      ");
  12661. #endif
  12662. #ifndef MCS_FLAG
  12663.      if (binary)
  12664.           printf("%-12s", "binary");
  12665. #else
  12666.      if (binary) {
  12667.           sprintf(print_str,"%-12s", "binary");
  12668.           mcs_printf(print_str);
  12669.      }
  12670. #endif
  12671. #ifndef MCS_FLAG
  12672.      else
  12673.           printf("%-12s", "text");
  12674. #else
  12675.      else {
  12676.           sprintf(print_str,"%-12s", "text");
  12677.           mcs_printf(print_str);
  12678.      }
  12679. #endif
  12680. #ifndef MCS_FLAG
  12681.      printf("   Packet Log:       ");
  12682. #else
  12683.      mcs_printf("   Packet Log:       ");
  12684. #endif
  12685.      if (pktlog)
  12686. #ifndef MCS_FLAG
  12687.           printf(pktfil);
  12688. #else
  12689.           mcs_printf(pktfil);
  12690. #endif
  12691.      else
  12692. #ifndef MCS_FLAG
  12693.           printf("none");
  12694. #else
  12695.           mcs_printf("none");
  12696. #endif
  12697.  
  12698. /*  printf("\n  File Warning: ");
  12699.     if (warn) printf("%-12s","on"); else printf("%-12s","off");
  12700.     printf("   Session Log:      ");
  12701.     if (seslog) printf(sesfil); else printf("none");
  12702.     printf("\n  File Display:   ");
  12703.     if (quiet) printf("%-12s","off"); else printf("%-12s","on");
  12704.     printf("   Session Log:      ");
  12705.     if (seslog) printf(sesfil); else printf("none");
  12706. */
  12707. #ifndef MCS_FLAG
  12708.      printf("\n  File Byte Size: %-12d", (fmask == 0177) ? 7 : 8);
  12709.      printf("   Transaction Log:  ");
  12710. #else
  12711.      sprintf(print_str,"\n  File Byte Size: %-12d", (fmask == 0177) ? 7 : 8);
  12712.      mcs_printf(print_str);
  12713.      mcs_printf("   Transaction Log:  ");
  12714. #endif
  12715.      if (tralog)
  12716. #ifndef MCS_FLAG
  12717.           printf(trafil);
  12718. #else
  12719.           mcs_printf(trafil);
  12720. #endif
  12721.      else
  12722. #ifndef MCS_FLAG
  12723.           printf("none");
  12724. #else
  12725.           mcs_printf("none");
  12726. #endif
  12727.  
  12728. /*    printf("\n\nFile Byte Size: %d",(fmask == 0177) ? 7 : 8); */
  12729.  
  12730. #ifndef MCS_FLAG
  12731.      printf("\n  Incomplete File Disposition: ");
  12732. #else
  12733.      mcs_printf("\n  Incomplete File Disposition: ");
  12734. #endif
  12735.      if (keep)
  12736. #ifndef MCS_FLAG
  12737.           printf("keep");
  12738. #else
  12739.           mcs_printf("keep");
  12740. #endif
  12741.      else
  12742. #ifndef MCS_FLAG
  12743.           printf("discard");
  12744.      printf(",  Init file: %s", KERMRC);
  12745. #else
  12746.           mcs_printf("discard");
  12747.      sprintf(print_str,",  Init file: %s", KERMRC);
  12748.      mcs_printf(print_str);
  12749. #endif
  12750.      puts("\n");
  12751. }
  12752.  
  12753.  
  12754. /*  D O S T A T  --  Display file transfer statistics.  */
  12755.  
  12756. dostat()
  12757. {
  12758. #ifndef MCS_FLAG
  12759.      printf("\nMost recent transaction --\n");
  12760.      printf(" files: %ld\n", filcnt);
  12761.      printf(" total file characters  : %ld\n", tfc);
  12762.      printf(" communication line in  : %ld\n", tlci);
  12763.      printf(" communication line out : %ld\n", tlco);
  12764.      printf(" elapsed time           : %d sec\n", tsecs);
  12765. #else
  12766.      sprintf(print_str,"\nMost recent transaction --\n");
  12767.      mcs_printf(print_str);
  12768.      sprintf(print_str," files: %ld\n", filcnt);
  12769.      mcs_printf(print_str);
  12770.      sprintf(print_str," total file characters  : %ld\n", tfc);
  12771.      mcs_printf(print_str);
  12772.      sprintf(print_str," communication line in  : %ld\n", tlci);
  12773.      mcs_printf(print_str);
  12774.      sprintf(print_str," communication line out : %ld\n", tlco);
  12775.      mcs_printf(print_str);
  12776.      sprintf(print_str," elapsed time           : %d sec\n", tsecs);
  12777.      mcs_printf(print_str);
  12778. #endif
  12779.      if (filcnt > 0) {
  12780.           if (tsecs > 0) {
  12781.                long     lx;
  12782.                lx = (tfc * 10l) / tsecs;
  12783. #ifndef MCS_FLAG
  12784.                printf(" effective baud rate    : %ld\n", lx);
  12785. #else
  12786.                sprintf(print_str," effective baud rate    : %ld\n", lx);
  12787.                mcs_printf(print_str);
  12788. #endif
  12789.                if (speed > 0) {
  12790.                     lx = (lx * 100l) / speed;
  12791. #ifndef MCS_FLAG
  12792.                     printf(" efficiency             : %ld %%\n",lx);
  12793. #else
  12794.                     sprintf(print_str," efficiency             : %ld %%\n",
  12795.                             lx);
  12796.                     mcs_printf(print_str);
  12797. #endif
  12798.                }
  12799.           }
  12800. #ifndef MCS_FLAG
  12801.           printf(" packet length          : %d (send), %d (receive)\n",
  12802.                  spsiz, urpsiz);
  12803.           printf(" block check type used  : %d\n", bctu);
  12804.           printf(" compression            : ");
  12805. #else
  12806.           sprintf(print_str,
  12807.                   " packet length          : %d (send), %d (receive)\n",
  12808.                   spsiz, urpsiz);
  12809.           mcs_printf(print_str);
  12810.           sprintf(print_str," block check type used  : %d\n", bctu);
  12811.           mcs_printf(print_str);
  12812.           mcs_printf(" compression            : ");
  12813. #endif
  12814. #ifndef MCS_FLAG
  12815.           if (rptflg)
  12816.                printf("yes [%c]\n", rptq);
  12817. #else
  12818.           if (rptflg) {
  12819.                sprintf(print_str,"yes [%c]\n", rptq);
  12820.                mcs_printf(print_str);
  12821.           }
  12822. #endif
  12823.           else
  12824. #ifndef MCS_FLAG
  12825.                printf("no\n");
  12826.           printf(" 8th bit prefixing      : ");
  12827. #else
  12828.                mcs_printf("no\n");
  12829.           mcs_printf(" 8th bit prefixing      : ");
  12830. #endif
  12831. #ifndef MCS_FLAG
  12832.           if (ebqflg)
  12833.                printf("yes [%c]\n", ebq);
  12834. #else
  12835.           if (ebqflg) {
  12836.                sprintf(print_str,"yes [%c]\n", ebq);
  12837.                mcs_printf(print_str);
  12838.           }
  12839. #endif
  12840.           else
  12841. #ifndef MCS_FLAG
  12842.                printf("no\n\n");
  12843. #else
  12844.                mcs_printf("no\n\n");
  12845. #endif
  12846.      } else
  12847. #ifndef MCS_FLAG
  12848.           printf("\n");
  12849. #else
  12850.           mcs_printf("\n");
  12851. #endif
  12852.      return(0);
  12853. }
  12854.  
  12855.  
  12856. /*  F S T A T S  --  Record file statistics in transaction log  */
  12857.  
  12858. fstats()
  12859. {
  12860.      tlog(F100, " end of file", "", 0l);
  12861.      tlog(F101, "  file characters        ", "", ffc);
  12862.      tlog(F101, "  communication line in  ", "", flci);
  12863.      tlog(F101, "  communication line out ", "", flco);
  12864. }
  12865.  
  12866.  
  12867. /*  T S T A T S  --  Record statistics in transaction log  */
  12868.  
  12869. tstats()
  12870. {
  12871.      char     *tp;
  12872.      int     x;
  12873.  
  12874.      ztime(&tp);                         /* Get time stamp */
  12875.      tlog(F110, "End of transaction", tp, 0l);  /* Record it */
  12876.  
  12877.      if (filcnt < 1)
  12878.           return;             /* If no files, done. */
  12879.  
  12880.      /* If multiple files, record character totals for all files */
  12881.  
  12882.      if (filcnt > 1) {
  12883.           tlog(F101, " files", "", filcnt);
  12884.           tlog(F101, " total file characters   ", "", tfc);
  12885.           tlog(F101, " communication line in   ", "", tlci);
  12886.           tlog(F101, " communication line out  ", "", tlco);
  12887.      }
  12888.  
  12889.      /* Record timing info for one or more files */
  12890.  
  12891.      tlog(F101, " elapsed time (seconds)  ", "", (long) tsecs);
  12892.      if (tsecs > 0) {
  12893.           x = (tfc / tsecs) * 10;
  12894.           tlog(F101, " effective baud rate     ", "", x);
  12895.           if (speed > 0) {
  12896.                x = (x * 100) / speed;
  12897.                tlog(F101, " efficiency (percent)    ", "",
  12898.                    x);
  12899.           }
  12900.      }
  12901.      tlog(F100, "", "", 0);                 /* Leave a blank line */
  12902. }
  12903.  
  12904.  
  12905. /*  S D E B U  -- Record spar results in debugging log  */
  12906.  
  12907. sdebu(len)
  12908. int     len;
  12909. {
  12910.  
  12911.      if (!deblog)
  12912.           return;
  12913.  
  12914.      debug(F111, "spar: data", rdatap, len);
  12915.      debug(F101, " spsiz ", "", spsiz);
  12916.      debug(F101, " timint", "", timint);
  12917.      debug(F101, " npad  ", "",  npad);
  12918.      debug(F101, " padch ", "", padch);
  12919.      debug(F101, " seol  ", "",  seol);
  12920.      debug(F101, " ctlq  ", "",  ctlq);
  12921.      debug(F101, " ebq   ", "",   ebq);
  12922.      debug(F101, " ebqflg", "", ebqflg);
  12923.      debug(F101, " bctr  ", "",  bctr);
  12924.      debug(F101, " rptq  ", "",  rptq);
  12925.      debug(F101, " rptflg", "", rptflg);
  12926.      debug(F101, " atcapu", "", atcapu);
  12927.      debug(F101, " lpcapu", "", lpcapu);
  12928.      debug(F101, " swcapu", "", swcapu);
  12929.      debug(F101, " wsize ", "", wsize);
  12930. }
  12931.  
  12932.  
  12933. /*  R D E B U -- Debugging display of rpar() values  */
  12934.  
  12935. rdebu(len)
  12936. int     len;
  12937. {
  12938.  
  12939.      if (!deblog)
  12940.           return;
  12941.  
  12942.      debug(F111, "spar: data", rdatap, len);
  12943.      debug(F101, " rpsiz ", "", xunchar(data[1]));
  12944.      debug(F101, " rtimo ", "", rtimo);
  12945.      debug(F101, " mypadn", "", mypadn);
  12946.      debug(F101, " mypadc", "", mypadc);
  12947.      debug(F101, " eol   ", "",   eol);
  12948.      debug(F101, " ctlq  ", "",  ctlq);
  12949.      debug(F101, " sq    ", "",    sq);
  12950.      debug(F101, " ebq   ", "",   ebq);
  12951.      debug(F101, " ebqflg", "", ebqflg);
  12952.      debug(F101, " bctr  ", "",  bctr);
  12953.      debug(F101, " rptq  ", "", data[9]);
  12954.      debug(F101, " rptflg", "", rptflg);
  12955.      debug(F101, " capas ", "", capas);
  12956.      debug(F101, " bits  ", "", data[capas]);
  12957.      debug(F101, " atcapu", "", atcapu);
  12958.      debug(F101, " lpcapu", "", lpcapu);
  12959.      debug(F101, " swcapu", "", swcapu);
  12960.      debug(F101, " wsize ", "", wsize);
  12961.      debug(F101, " rpsiz(extended)", "", rpsiz);
  12962. }
  12963. <<< ckvus3.c >>>
  12964. /*  C K V U S 3 --  "User Interface" for NCR-VRX Kermit, part 3  */
  12965.  
  12966. /**********************************************************************
  12967. *                                                                     *
  12968. * IVS / MCS-Kermit REL 2                                              *
  12969. * source code                                                         *
  12970. *                                                                     *
  12971. * Change History:                                                     *
  12972. *                                                                     *
  12973. *                1. Modify C-Kermit(4E) source code to                *
  12974. *                   produce new module for MCS/IVS-Kermit             *
  12975. *                   ORIGINAL RELEASE                                  *
  12976. *                   June 22, 1990                                     *
  12977. *                                                                     *
  12978. *                                                                     *
  12979. ***********************************************************************/
  12980.  
  12981.  
  12982. /*
  12983.  Author: Frank da Cruz (fdc@cunixc.cc.columbia.edu, FDCCU@CUVMA.BITNET),
  12984.  Columbia University Center for Computing Activities.
  12985.  First released January 1985.
  12986.  Copyright (C) 1985, 1989, Trustees of Columbia University in the City of New
  12987.  York.  Permission is granted to any individual or institution to use, copy, or
  12988.  redistribute this software so long as it is not sold for profit, provided this
  12989.  copyright notice is retained.
  12990. */
  12991.  
  12992. /*  SET and REMOTE commands; screen, debug, interrupt, and logging functions */
  12993.  
  12994. /* Includes */
  12995.  
  12996. #include "ckcdeb.h"
  12997. #include <stdio.h>
  12998. #include <ctype.h>
  12999. #include "ckcker.h"
  13000. #include "ckucmd.h"
  13001. #include "ckuusr.h"
  13002. #ifdef MCS_FLAG
  13003. #include "mcs.h"
  13004. #endif
  13005.  
  13006. /* Variables */
  13007.  
  13008. int userpad = SNDPADC;   /* storage for the user specified pad char
  13009.                   used in spack to reset any SI packet
  13010.                   pad char while in server mode          */
  13011.  
  13012. extern int     size, spsiz, rpsiz, urpsiz, npad, timint, rtimo, speed,
  13013.                local, server, lpcapr, fmask, cmask, backgrd,
  13014.                send_id, recv_id, send_num,  recv_num, send_renum,
  13015.                recv_renum, send_addnum, recv_addnum, rptflg,
  13016.                flow, displa, binary, fncnv, delay, parity, deblog,
  13017.                escape, xargc, turn, duplex, cxseen, czseen, nfils,
  13018.                ckxech, pktlog, seslog, tralog,  stdouf, turnch, bctr,
  13019.                bctu, dfloc, mdmtyp, keep, maxtry,
  13020.                rptflg, ebqflg, /* warn,*/ quiet, cnflg, timef,
  13021.                spsizf, mypadn;
  13022.  
  13023. extern long     filcnt, tlci, tlco, ffc, tfc, fsize;
  13024.  
  13025. extern char     *versio, *protv, *ckxv, *ckzv, *fnsv, *connv, *dftty, *cmdv;
  13026. extern char     *cmarg, *cmarg2, **xargv, **cmlist;
  13027. extern CHAR     stchr, mystch, sstate, padch, mypadc, eol, seol, ctlq;
  13028. extern CHAR     filnam[], ttname[];
  13029. char            *strcpy();
  13030.  
  13031. extern void errhdlr();
  13032.  
  13033. /* Declarations from cmd package */
  13034.  
  13035. extern char     cmdbuf[];                   /* Command buffer */
  13036. extern char     atmbuf[];                   /* Atom buffer */
  13037.  
  13038. /* From main ckuser module... */
  13039.  
  13040. extern char     line[100], *lp;        /* Character buffer for anything */
  13041. extern char     debfil[50],            /* Debugging log file name */
  13042. pktfil[50],                            /* Packet log file name */
  13043. sesfil[50],                            /* Session log file name */
  13044. trafil[50];                            /* Transaction log file name */
  13045.  
  13046. extern int     tlevel;                  /* Take Command file level */
  13047. extern FILE *tfile[];                   /* Array of take command fd's */
  13048.  
  13049.  
  13050. /* Keyword tables for SET commands */
  13051.  
  13052. /* Block checks */
  13053.  
  13054. struct keytab blktab[] = {
  13055.      "1", 1, 0,
  13056.      "2", 2, 0,
  13057.      "3", 3, 0
  13058. };
  13059.  
  13060.  
  13061. /* Duplex keyword table */
  13062.  
  13063. struct keytab dpxtab[] = {
  13064.      "full",      0, 0,
  13065.      "half",      1, 0
  13066. };
  13067.  
  13068.  
  13069. struct keytab filtab[] = {
  13070.      "display", XYFILD, CM_INV,
  13071.      "names",   XYFILN, 0,
  13072.      "type",    XYFILT, 0
  13073. };
  13074.  
  13075.  
  13076. int     nfilp = (sizeof(filtab)
  13077.  / sizeof(struct keytab )
  13078. );
  13079.  
  13080. /* Send/Receive Parameters */
  13081.  
  13082. struct keytab srtab[] = {
  13083.      "add-linenum", XYADD, CM_INV,
  13084.      "id-fields", XYID, CM_INV,
  13085.      "line-numbers", XYNUM, CM_INV,
  13086.      "end-of-packet", XYEOL, 0,
  13087.      "packet-length", XYLEN, 0,
  13088.      "pad-character", XYPADC, 0,
  13089.      "padding", XYNPAD, 0,
  13090.      "renumber", XYRNUM, CM_INV,
  13091.      "start-of-packet", XYMARK, 0,
  13092.      "timeout", XYTIMO, 0
  13093. };
  13094.  
  13095.  
  13096. int     nsrtab = (sizeof(srtab)
  13097.  / sizeof(struct keytab )
  13098. );
  13099.  
  13100. /* Flow Control */
  13101.  
  13102. struct keytab flotab[] = {
  13103.      "none",     0, 0,
  13104.      "xon/xoff", 1, 0
  13105. };
  13106.  
  13107.  
  13108. int     nflo = (sizeof(flotab)
  13109.  / sizeof(struct keytab )
  13110. );
  13111.  
  13112. /*  Handshake characters  */
  13113.  
  13114. struct keytab hshtab[] = {
  13115.      "bell", 007, 0,
  13116.      "cr",   015, 0,
  13117.      "esc",  033, 0,
  13118.      "lf",   012, 0,
  13119.      "none", 999, 0,                     /* (can't use negative numbers) */
  13120.      "xoff", 023, 0,
  13121.      "xon",  021, 0
  13122. };
  13123.  
  13124.  
  13125. int     nhsh = (sizeof(hshtab)
  13126.  / sizeof(struct keytab )
  13127. );
  13128.  
  13129. struct keytab fntab[] = {               /* File naming */
  13130.      "converted", 1, 0,
  13131.      "literal",   0, 0
  13132. };
  13133.  
  13134.  
  13135. struct keytab fttab[] = {               /* File types */
  13136.      "binary",    1, 0,
  13137.      "text",      0, 0
  13138. };
  13139.  
  13140.  
  13141. extern struct keytab mdmtab[] ;         /* Modem types (in module ckudia.c) */
  13142. extern int     nmdm;
  13143.  
  13144. /* Parity keyword table */
  13145.  
  13146. struct keytab partab[] = {
  13147.      "even",    'e', 0,
  13148.      "mark",    'm', 0,
  13149.      "none",      0, 0,
  13150.      "odd",     'o', 0,
  13151.      "space",   's', 0
  13152. };
  13153.  
  13154.  
  13155. int     npar = (sizeof(partab)
  13156.  / sizeof(struct keytab )
  13157. );
  13158.  
  13159.  
  13160. /* On/Off table */
  13161.  
  13162. struct keytab onoff[] = {
  13163.      "off",       0, 0,
  13164.      "on",        1, 0
  13165. };
  13166.  
  13167.  
  13168. /* Incomplete File Disposition table */
  13169.  
  13170. struct keytab ifdtab[] = {
  13171.      "discard",   0, 0,
  13172.      "keep",      1, 0
  13173. };
  13174.  
  13175.  
  13176. /* Terminal parameters table */
  13177.  
  13178. struct keytab trmtab[] = {
  13179.      "bytesize",  0, 0
  13180. };
  13181.  
  13182.  
  13183. /*  D O P R M  --  Set a parameter.  */
  13184. /*
  13185.  Returns:
  13186.   -2: illegal input
  13187.   -1: reparse needed
  13188.    0: success
  13189. */
  13190. doprm(xx)
  13191. int     xx;
  13192. {
  13193.      int     x, y, z;
  13194.      char     *s;
  13195.  
  13196.      switch (xx) {
  13197.  
  13198.  
  13199.      case XYEOL:     /* These have all been moved to set send/receive... */
  13200.      case XYLEN:     /* Let the user know what to do. */
  13201.      case XYMARK:
  13202.      case XYNPAD:
  13203.      case XYPADC:
  13204.      case XYTIMO:
  13205.      case XYID:
  13206.      case XYNUM:
  13207.      case XYRNUM:
  13208.      case XYADD:
  13209. #ifndef MCS_FLAG
  13210.           printf("...Use 'set send' or 'set receive' instead.\n");
  13211.           printf("Type 'help set send' / 'help set receive' for info.\n");
  13212. #else
  13213.           mcs_printf("...Use 'set send' or 'set receive' instead.\n");
  13214.           mcs_printf("Type 'help set send' / 'help set receive' for info.\n");
  13215. #endif
  13216.           return(0);
  13217.  
  13218.      case XYIFD:                             /* Incomplete file disposition */
  13219.           if ((y = cmkey(ifdtab, 2, "", "discard")) < 0)
  13220.                return(y);
  13221.           if ((x = cmcfm()) < 0)
  13222.                return(x);
  13223.           keep = y;
  13224.           return(0);
  13225.  
  13226. /*   case XYLINE:
  13227. *         if ((x = cmtxt("Device name", dftty, &s)) < 0)
  13228. *              return(x);
  13229. *         ttclos();                     * close old line, if any was open *
  13230. *
  13231. *         * Maybe let ttopen figure it out... *
  13232. *         x = strcmp(s, dftty) ? -1 : dfloc;
  13233. *         if (ttopen(s, &x, mdmtyp) < 0 ) {     * Can we open the new line? *
  13234. *               errhdlr("doprm: Sorry, can't open line");
  13235. *               return(-2);                     * If not, give bad return *
  13236. *          }
  13237. *          if (x > -1)
  13238. *               local = x;              * Set local/remote status. *
  13239. *          strcpy(ttname, s);           * OK, copy name into real place. *
  13240. *          if (!local)
  13241. *               speed = -1;             * If remote, say speed unknown. *
  13242. *          if (deblog)
  13243. *               debug(F111, "set line ", ttname, local);
  13244. *          return(0);
  13245. */
  13246.      case XYCHKT:
  13247.           if ((y = cmkey(blktab, 3, "", "1")) < 0)
  13248.                return(y);
  13249.           if ((x = cmcfm()) < 0)
  13250.                return(x);
  13251.           bctr = y;
  13252.           return(0);
  13253.  
  13254.      case XYDEBU:
  13255.           return(seton(&deblog));
  13256.  
  13257. /*    case XYDELA:
  13258. *          y = cmnum("Number of seconds before starting to send",
  13259. *               "5", 10, &x);
  13260. *          if (deblog)
  13261. *               debug(F101, "XYDELA: y", "", y);
  13262. *          return(setnum(&delay, x, y, 94));
  13263. */
  13264.      case XYDUPL:
  13265.           if ((y = cmkey(dpxtab, 2, "", "full")) < 0)
  13266.                return(y);
  13267.           if ((x = cmcfm()) < 0)
  13268.                return(x);
  13269.           duplex = y;
  13270.           return(0);
  13271.  
  13272.      case XYESC:
  13273.           y = cmnum("Decimal ASCII code for escape character",
  13274.                "", 10, &x);
  13275.           return(setcc(&escape, x, y));
  13276.  
  13277.      case XYFILE:
  13278.           if ((y = cmkey(filtab, nfilp, "File parameter", "")) <
  13279.               0)
  13280.                return(y);
  13281.           switch (y) {
  13282.                int     z;
  13283. /*        case XYFILD:                     * Display *
  13284. *              y = seton(&z);
  13285. *              if (y < 0)
  13286. *                   return(y);
  13287. *              quiet = !z;
  13288. *              return(0);
  13289. */
  13290.           case XYFILN:                    /* Names */
  13291.                if ((x = cmkey(fntab, 2, "how to handle filenames",
  13292.                     "converted")) < 0)
  13293.                     return(x);
  13294.                if ((z = cmcfm()) < 0)
  13295.                     return(z);
  13296.                fncnv = x;
  13297.                return(0);
  13298.  
  13299.           case XYFILT:                    /* Type */
  13300.                if ((x = cmkey(fttab, 2, "type of file", "text")) <
  13301.                    0)
  13302.                     return(x);
  13303.                if ((y = cmnum("file byte size (7 or 8)", "8",
  13304.                     10, &z)) < 0)
  13305.                     return(y);
  13306.                if (z != 7 && z != 8) {
  13307. #ifndef MCS_FLAG
  13308.                     printf("\n?The choices are 7 and 8\n");
  13309. #else
  13310.                     mcs_printf("\n?The choices are 7 and 8\n");
  13311. #endif
  13312.                     return(-2);
  13313.                }
  13314.                if ((y = cmcfm()) < 0)
  13315.                     return(y);
  13316.                binary = x;
  13317.                if (z == 7)
  13318.                     fmask = 0177;
  13319.                else if (z == 8)
  13320.                     fmask = 0377;
  13321.                return(0);
  13322.  
  13323.                /* case XYFILW:                     *  Warning/Write-Protect *
  13324.             return(seton(&warn));   */
  13325.  
  13326.           default:
  13327. #ifndef MCS_FLAG
  13328.                printf("?unexpected file parameter\n");
  13329. #else
  13330.                mcs_printf("?unexpected file parameter\n");
  13331. #endif
  13332.                return(-2);
  13333.           }
  13334.  
  13335.      case XYFLOW:                            /* Flow control */
  13336.           if ((y = cmkey(flotab, nflo, "", "xon/xoff")) < 0)
  13337.                return(y);
  13338.           if ((x = cmcfm()) < 0)
  13339.                return(x);
  13340.           flow = y;
  13341.           return(0);
  13342.  
  13343.      case XYHAND:                            /* Handshake */
  13344.           if ((y = cmkey(hshtab, nhsh, "", "none")) < 0)
  13345.                return(y);
  13346.           if ((x = cmcfm()) < 0)
  13347.                return(x);
  13348.           turn = (y > 0127) ? 0 : 1 ;
  13349.           turnch = y;
  13350.           return(0);
  13351.  
  13352. /*    case XYMODM:
  13353. *          if ((x = cmkey(mdmtab, nmdm, "type of modem, direct means none",
  13354. *               "direct")) < 0)
  13355. *               return(x);
  13356. *          if ((z = cmcfm()) < 0)
  13357. *               return(z);
  13358. *          mdmtyp = x;
  13359. *          return(0);
  13360. */
  13361.      case XYPARI:                            /* Parity */
  13362.           if ((y = cmkey(partab, npar, "", "none")) < 0)
  13363.                return(y);
  13364.           if ((x = cmcfm()) < 0)
  13365.                return(x);
  13366.  
  13367.           /* If parity not none, then we also want 8th-bit prefixing */
  13368.  
  13369.           if (parity = y)
  13370.                ebqflg = 1;
  13371.           else
  13372.                ebqflg = 0;
  13373.           return(0);
  13374.  
  13375.      case XYPROM:
  13376. #ifndef MCS_FLAG
  13377.           if ((x = cmtxt("Program's command prompt", "IVS-Kermit>",
  13378. #else
  13379.           if ((x = cmtxt("Program's command prompt", "MCS-Kermit>",
  13380. #endif
  13381.                &s)) < 0)
  13382.                return(x);
  13383.  
  13384.           if (*s == '\42') {             /* Quoted string? */
  13385.                x = strlen(s) - 1;        /* Yes, strip quotes. */
  13386.                if (*(s + x) == '\42')    /* This allows leading or trailing */
  13387.                     *(s + x) = '\0';     /* blanks. */
  13388.                s++;
  13389.           }
  13390.           cmsetp(s);
  13391.           return(0);
  13392.  
  13393.      case XYRETR:                            /* Per-packet retry limit */
  13394.           y = cmnum("Maximum retries per packet", "10", 10, &x);
  13395.           return(setnum(&maxtry, x, y, 94));
  13396.  
  13397.      case XYTERM:                            /* Terminal parameters */
  13398.           if ((y = cmkey(trmtab, 1, "", "bytesize")) < 0)
  13399.                return(y);
  13400.           switch (y) {
  13401.           case 0:
  13402.                if ((y = cmnum("bytesize for terminal connection",
  13403.                     "8", 10, &x)) < 0)
  13404.                     return(y);
  13405.                if (x != 7 && x != 8) {
  13406. #ifndef MCS_FLAG
  13407.                     printf("\n?The choices are 7 and 8\n");
  13408. #else
  13409.                     mcs_printf("\n?The choices are 7 and 8\n");
  13410. #endif
  13411.                     return(-2);
  13412.                }
  13413.                if ((y = cmcfm()) < 0)
  13414.                     return(y);
  13415.                if (x == 7)
  13416.                     cmask = 0177;
  13417.                else if (x == 8)
  13418.                     cmask = 0377;
  13419.                return(y);
  13420.           default:       /* Add more cases when we think of more parameters */
  13421.                return(-2);
  13422.           }
  13423.  
  13424.           /* SET SEND/RECEIVE... */
  13425.  
  13426.      case XYRECV:
  13427.      case XYSEND:
  13428.           if (xx == XYRECV)
  13429.                strcpy(line, "Parameter for inbound packets");
  13430.           else
  13431.                strcpy(line, "Parameter for outbound packets");
  13432.  
  13433.           if ((y = cmkey(srtab, nsrtab, line, "")) < 0)
  13434.                return(y);
  13435.           switch (y) {
  13436.  
  13437.           case XYEOL:
  13438.                y = cmnum("Decimal ASCII code for packet terminator",
  13439.                     "13", 10, &x);
  13440.                if ((y = setcc(&z, x, y)) < 0)
  13441.                     return(y);
  13442.                if (xx == XYRECV)
  13443.                     eol = z;
  13444.                else
  13445.                     seol = z;
  13446.                return(y);
  13447.  
  13448.           case XYLEN:
  13449.                y = cmnum("Maximum number of characters in a packet",
  13450.                     "90", 10, &x);
  13451.                if (xx == XYRECV) {                 /* Receive... */
  13452.                     if ((y = setnum(&z, x, y, MAXRP)) < 0)
  13453.                          return(y);
  13454.                     urpsiz = z;
  13455.                     rpsiz =  (z > 94) ? 94 : z;
  13456.                } else {                            /* Send... */
  13457.                     if ((y = setnum(&z, x, y, MAXSP)) < 0)
  13458.                          return(y);
  13459.                     spsiz = z;        /*   Set it and flag that it was set */
  13460.                     spsizf = 1;       /*   to allow overriding Send-Init. */
  13461.                }
  13462.                if (z > 94 && !backgrd)
  13463. #ifndef MCS_FLAG
  13464.                     printf("Extended-length packets requested\n");
  13465. #else
  13466.                     mcs_printf("Extended-length packets requested\n");
  13467. #endif
  13468.                return(y);
  13469.  
  13470.           case XYMARK:
  13471.                y = cmnum("Decimal ASCII code for packet-start character",
  13472.                     "1", 10, &x);
  13473.                if ((y = setcc(&z, x, y)) < 0)
  13474.                     return(y);
  13475.                if (xx == XYRECV)
  13476.                     stchr = z;
  13477.                else
  13478.                     mystch = z;
  13479.                return(y);
  13480.  
  13481.           case XYNPAD:                            /* Padding */
  13482.                y = cmnum("How many padding characters for inbound packets",
  13483.                     "0", 10, &x);
  13484.                if ((y = setnum(&z, x, y, 94)) < 0)
  13485.                     return(y);
  13486.                if (xx == XYRECV)
  13487.                     mypadn = z;
  13488.                else
  13489.                     npad = z;
  13490.                return(y);
  13491.  
  13492.           case XYPADC:                            /* Pad character */
  13493.                y = cmnum("Decimal ASCII code for inbound pad character",
  13494.                     "0", 10, &x);
  13495.                if ((y = setcc(&z, x, y)) < 0)
  13496.                     return(y);
  13497.                if (xx == XYRECV)
  13498.                     mypadc = z;
  13499.                else {                 /* disabling \0 padd char
  13500.                                          to prevent mcs errors
  13501.                                          PEG May 16, 1990         */
  13502.                     if (z == 0) {
  13503. #ifndef MCS_FLAG
  13504.                         printf("\nvalid send pad-char 1 - 31 and 127.\n");
  13505. #else
  13506.                         mcs_printf("\nvalid send pad-char 1 - 31 and 127.\n");
  13507. #endif
  13508.                         return (-2);
  13509.                     }
  13510.                     else padch = userpad = z;
  13511.                }
  13512.                return(y);
  13513.  
  13514.           case XYTIMO:
  13515.                y = cmnum("Interpacket timeout interval", "5",
  13516.                     10, &x);
  13517.                if ((y = setnum(&z, x, y, 94)) < 0)
  13518.                     return(y);
  13519.                if (xx == XYRECV) {
  13520.                     timef = 1;
  13521.                     timint = z;
  13522.                } else
  13523.                     rtimo = z;
  13524.                return(y);
  13525.  
  13526. /*         case XYID:  * Flag for id-fields in SPUR files *
  13527. *               if ((y = cmkey(ifdtab, 2, "", "keep")) < 0)
  13528. *                    return(y);
  13529. *               if ((x = cmcfm()) < 0)
  13530. *                    return(x);
  13531. *               if (xx == XYRECV)
  13532. *                    recv_id = y;
  13533. *               else
  13534. *                    send_id = y;
  13535. *               return(0);
  13536. *          case XYNUM:  * Flag for line number fields in SPUR files *
  13537. *               if ((y = cmkey(ifdtab, 2, "", "keep")) < 0)
  13538. *                    return(y);
  13539. *               if ((x = cmcfm()) < 0)
  13540. *                    return(x);
  13541. *               if (xx == XYRECV)
  13542. *                    recv_num = y;
  13543. *               else
  13544. *                    send_num = y;
  13545. *               return(0);
  13546. *
  13547. *                * Flag for renumbering line number fields in SPUR files *
  13548. *          case XYRNUM:
  13549. *               if ((y = cmkey(onoff, 2, "", "off")) < 0)
  13550. *                    return(y);
  13551. *               if ((x = cmcfm()) < 0)
  13552. *                    return(x);
  13553. *               if (xx == XYRECV)
  13554. *                    recv_renum = y;
  13555. *               else
  13556. *                    send_renum = y;
  13557. *               return(0);
  13558. *          case XYADD:  * Flag for adding line number fields in SPUR files *
  13559. *               if ((y = cmkey(onoff, 2, "", "off")) < 0)
  13560. *                    return(y);
  13561. *               if ((x = cmcfm()) < 0)
  13562. *                    return(x);
  13563. *               if (xx == XYRECV)
  13564. *                    recv_addnum = y;
  13565. *               else
  13566. *                    send_addnum = y;
  13567. *               return(0);
  13568. */
  13569.           }
  13570.  
  13571. /*   case XYSPEE:
  13572. *         if (!local) {
  13573. *            printf("\nSpeed setting can only be done on an external line\n");
  13574. *            printf("You must 'set line' before issuing this command\n");
  13575. *            return(0);
  13576. *         }
  13577. *         lp = line;
  13578. *         sprintf(lp, "Baud rate for %s", ttname);
  13579. *         if ((y = cmnum(line, "", 10, &x)) < 0)
  13580. *              return(y);
  13581. *         if (y = (cmcfm()) < 0)
  13582. *              return(y);
  13583. *         y = chkspd(x);
  13584. *         if (y < 0)
  13585. *              printf("?Unsupported line speed - %d\n", x);
  13586. *         else {
  13587. *              speed = y;
  13588. *              if (!backgrd)
  13589. *                   printf("%s: %d baud\n", ttname, speed);
  13590. *         }
  13591. */        return(0);
  13592.  
  13593.      default:
  13594.           if ((x = cmcfm()) < 0)
  13595.                return(x);
  13596. #ifndef MCS_FLAG
  13597.           printf("V-Kermit does not support: %s\n", cmdbuf);
  13598. #else
  13599.           sprintf(print_str,"V-Kermit does not support: %s\n", cmdbuf);
  13600.           mcs_printf(print_str);
  13601. #endif
  13602.           return(0);
  13603.      }
  13604. }
  13605.  
  13606.  
  13607. /*  C H K S P D  --  Check if argument is a valid baud rate  */
  13608.  
  13609. chkspd(x)
  13610. int     x;
  13611. {
  13612.      switch (x) {
  13613.      case 0:
  13614.      case 110:
  13615.      case 150:
  13616.      case 300:
  13617.      case 600:
  13618.      case 1200:
  13619.      case 1800:
  13620.      case 2400:
  13621.      case 4800:
  13622.      case 9600:
  13623.      case 19200:
  13624.           return(x);
  13625.      default:
  13626.           return(-1);
  13627.      }
  13628. }
  13629.  
  13630.  
  13631. /*  S E T O N  --  Parse on/off (default on), set parameter to result  */
  13632.  
  13633. seton(prm)
  13634. int     *prm;
  13635. {
  13636.      int     x, y;
  13637.      if ((y = cmkey(onoff, 2, "", "on")) < 0)
  13638.           return(y);
  13639.      if ((x = cmcfm()) < 0)
  13640.           return(x);
  13641.      *prm = y;
  13642.      return(0);
  13643. }
  13644.  
  13645.  
  13646. /*  S E T N U M  --  Set parameter to result of cmnum() parse.  */
  13647. /*
  13648.  Call with x - number from cnum parse, y - return code from cmnum
  13649. */
  13650. setnum(prm, x, y, max)
  13651. int     x, y, *prm, max;
  13652. {
  13653.      if (deblog)
  13654.           debug(F101, "setnum", "", y);
  13655.  
  13656.      if (y < 0)
  13657.           return(y);
  13658.  
  13659.      if (x > max) {
  13660. #ifndef MCS_FLAG
  13661.           printf("\n?Sorry, %d is the maximum\n", max);
  13662. #else
  13663.           sprintf(print_str,"\n?Sorry, %d is the maximum\n", max);
  13664.           mcs_printf(print_str);
  13665. #endif
  13666.           return(-2);
  13667.      }
  13668.  
  13669. #ifdef MCS_FLAG
  13670.      if (x == -562)         /* value that indicates invalid number */
  13671.        sprintf(print_str,"\n?not a number - %s\n",atmbuf);
  13672. #endif
  13673.  
  13674.      if ((y = cmcfm()) < 0)
  13675.           return(y);
  13676.  
  13677. #ifdef MCS_FLAG
  13678.      /* If we got to here and if something other then a number
  13679.       * was entered, then no back spaces were entered on the line.
  13680.       * So, reparsing is not necessary. Just put out an error msg. */
  13681.  
  13682.       if (x == -562) {
  13683.         mcs_printf(print_str);
  13684.         return(-2);
  13685.       }
  13686. #endif
  13687.  
  13688.      *prm = x;
  13689.      return(0);
  13690. }
  13691.  
  13692.  
  13693. /*  S E T C C  --  Set parameter to an ASCII control character value.  */
  13694.  
  13695. setcc(prm, x, y)
  13696. int     x, y, *prm;
  13697. {
  13698.      if (y < 0)
  13699.           return(y);
  13700.      if ((x > 037) && (x != 0177)) {
  13701. #ifndef MCS_FLAG
  13702.           printf("\n?Not in ASCII control range - %d\n", x);
  13703. #else
  13704.           sprintf(print_str,"\n?Not in ASCII control range - %d\n", x);
  13705.           mcs_printf(print_str);
  13706. #endif
  13707.           return(-2);
  13708.      }
  13709.      if ((y = cmcfm()) < 0)
  13710.           return(y);
  13711.      *prm = x;
  13712.      return(0);
  13713. }
  13714.  
  13715.  
  13716. /*  D O R M T  --  Do a remote command  */
  13717.  
  13718. dormt(xx)
  13719. int     xx;
  13720. {
  13721.    return(-2);   /* stub for deleted featured this function
  13722.                     should never be called but just in case..
  13723. *
  13724. *    int     x;
  13725. *    char     *s, sbuf[50], *s2;
  13726. *
  13727. *    if (xx < 0)
  13728. *         return(xx);
  13729. *    switch (xx) {
  13730. *
  13731. *     case XZCWD:                              * CWD *
  13732. *          if ((x = cmtxt("Remote directory name", "", &s)) < 0)
  13733. *               return(x);
  13734. *          if (deblog)
  13735. *               debug(F111, "XZCWD: ", s, x);
  13736. *          *sbuf = NUL;
  13737. *          s2 = sbuf;
  13738. *          if (*s != NUL) {                     * If directory name given, *
  13739. *                * get password on separate line. *
  13740. *               if (tlevel > -1) {               * From take file... *
  13741. *
  13742. *                    if (fgets(sbuf, 50, tfile[tlevel]) ==
  13743. *                        NULL)
  13744. *                         fatal("take file ends prematurely in 'remote cwd'");
  13745. *                    if (deblog)
  13746. *                         debug(F110, " pswd from take file",
  13747. *                              s2, 0);
  13748. *                    for (x = strlen(sbuf);  x > 0 && (sbuf[x-1] ==
  13749. *                        '\n' || sbuf[x-1] == '\r');  x--)
  13750. *                         sbuf[x-1] = '\0';
  13751. *
  13752. *               } else {                         * From terminal... *
  13753. *
  13754. *                    printf(" Password: ");               * get a password *
  13755. *                    while (((x = getchar()) != NL) && (x !=
  13756. *                        CR)) {  * with no echo *
  13757. *                         if ((x &= 0177) == '?') {
  13758. *                            printf("Remote directory Password: ");
  13759. *                              s2 = sbuf;
  13760. *                              *sbuf = NUL;
  13761. *
  13762. *                            * Mini command line editor... *
  13763. *                         } else if (x == ESC)
  13764. *                              putchar(BEL);
  13765. *                         else if (x == BS || x == 0177)
  13766. *                              s2--;
  13767. *                         else if (x == 025) {     * Ctrl-U *
  13768. *                              s2 = sbuf;
  13769. *                              *sbuf = NUL;
  13770. *                         } else
  13771. *                              *s2++ = x;
  13772. *                    }
  13773. *                    *s2 = NUL;
  13774. *                    putchar('\n');
  13775. *               }
  13776. *               s2 = sbuf;
  13777. *          } else
  13778. *               s2 = "";
  13779. *          if (deblog)
  13780. *               debug(F110, " password", s2, 0);
  13781. *          sstate = setgen('C', s, s2, "");
  13782. *          return(0);
  13783. *
  13784. *     case XZDEL:                              * Delete *
  13785. *          if ((x = cmtxt("Name of remote file(s) to delete", "",
  13786. *               &s)) < 0)
  13787. *               return(x);
  13788. *          return(sstate = rfilop(s, 'E'));
  13789. *
  13790. *     case XZDIR:                              * Directory *
  13791. *          if ((x = cmtxt("Remote directory or file specification",
  13792. *               "", &s)) < 0)
  13793. *               return(x);
  13794. *          return(sstate = setgen('D', s, "", ""));
  13795. *
  13796. *     case XZHLP:                              * Help *
  13797. *          if (x = (cmcfm()) < 0)
  13798. *               return(x);
  13799. *          sstate = setgen('H', "", "", "");
  13800. *          return(0);
  13801. *
  13802. *     case XZHOS:                              * Host *
  13803. *          if ((x = cmtxt("Command for remote system", "", &cmarg)) <
  13804. *              0)
  13805. *               return(x);
  13806. *          return(sstate = 'c');
  13807. *
  13808. *     case XZPRI:                              * Print *
  13809. *          if ((x = cmtxt("Remote file(s) to print on remote printer",
  13810. *               "", &s)) < 0)
  13811. *               return(x);
  13812. *          return(sstate = rfilop(s, 'S'));
  13813. *
  13814. *     case XZSPA:                              * Space *
  13815. *          if ((x = cmtxt("Confirm, or remote directory name",
  13816. *              "", &s)) < 0)
  13817. *               return(x);
  13818. *          return(sstate = setgen('U', s, "", ""));
  13819. *
  13820. *     case XZTYP:                              * Type *
  13821. *          if ((x = cmtxt("Remote file specification", "", &s)) <
  13822. *              0)
  13823. *               return(x);
  13824. *          return(sstate = rfilop(s, 'T'));
  13825. *
  13826. *     case XZWHO:
  13827. *          if ((x = cmtxt("Remote user name, or carriage return",
  13828. *               "", &s)) < 0)
  13829. *               return(x);
  13830. *          return(sstate = setgen('W', s, "", ""));
  13831. *
  13832. *     default:
  13833. *          if (x = (cmcfm()) < 0)
  13834. *               return(x);
  13835. *         printf("not working yet - %s\n", cmdbuf);
  13836. *         return(-2);
  13837. *    }
  13838. */
  13839.  
  13840. }
  13841.  
  13842. /*  R F I L O P  --  Remote File Operation  */
  13843.  
  13844. rfilop(s, t)
  13845. char     *s, t;
  13846. {
  13847.      if (*s == NUL) {
  13848. #ifndef MCS_FLAG
  13849.           printf("?File specification required\n");
  13850. #else
  13851.           mcs_printf("?File specification required\n");
  13852. #endif
  13853.           return(-2);
  13854.      }
  13855.      if (deblog)
  13856.           debug(F111, "rfilop", s, t);
  13857.      return(setgen(t, s, "", ""));
  13858. }
  13859.  
  13860.  
  13861. /*  S C R E E N  --  Screen display function  */
  13862.  
  13863. /*  screen(f,c,n,s)
  13864.       f - argument descriptor
  13865.       c - a character or small integer
  13866.       n - a long integer
  13867.       s - a string.
  13868.  Fill in this routine with the appropriate display update for the system.
  13869.  This version is for a dumb tty.
  13870. */
  13871. screen(f, c, n, s)
  13872. int     f;
  13873. long     n;
  13874. char     c;
  13875. char     *s;
  13876. {
  13877.      static int     p = 0;                   /* Screen position */
  13878.      int     len;                            /* Length of string */
  13879.      char     buf[80];                       /* Output buffer */
  13880.      len = strlen(s);                    /* Length of string */
  13881.      if (!displa || quiet)
  13882.           return;       /* No update if display flag off */
  13883.  
  13884.      switch (f) {
  13885.  
  13886.      case SCR_FN:                            /* filename */
  13887.           conoll("");
  13888.           conol(s);
  13889.           conoc(SP);
  13890.           p = len + 1;
  13891.           return;
  13892.  
  13893.      case SCR_AN:                            /* as-name */
  13894.           if (p + len > 75) {
  13895.                conoll("");
  13896.                p = 0;
  13897.           }
  13898.           conol("=> ");
  13899.           conol(s);
  13900.           if ((p += (len + 3)) > 78) {
  13901.                conoll("");
  13902.                p = 0;
  13903.           }
  13904.           return;
  13905.  
  13906.      case SCR_FS:                            /* file-size */
  13907.           sprintf(buf, ", Size: %ld", n);
  13908.           conoll(buf);
  13909.           p = 0;
  13910.           return;
  13911.  
  13912.      case SCR_XD:                            /* x-packet data */
  13913.           conoll("");
  13914.           conoll(s);
  13915.           p = 0;
  13916.           return;
  13917.  
  13918.      case SCR_ST:                            /* File status */
  13919.           switch (c) {
  13920.           case ST_OK:                     /*  Transferred OK */
  13921.                if ((p += 5) > 78) {
  13922.                     conoll("");
  13923.                     p = 0;
  13924.                }
  13925.                conoll(" [OK]");
  13926.                p += 5;
  13927.                return;
  13928.  
  13929.           case ST_DISC:                   /*  Discarded */
  13930.                if ((p += 12) > 78) {
  13931.                     conoll("");
  13932.                     p = 0;
  13933.                }
  13934.                conoll(" [discarded]");
  13935.                p += 12;
  13936.                return;
  13937.  
  13938.           case ST_INT:                    /*  Interrupted */
  13939.                if ((p += 14) > 78) {
  13940.                     conoll("");
  13941.                     p = 0;
  13942.                }
  13943.                conoll(" [interrupted]");
  13944.                p += 14;
  13945.                return;
  13946.  
  13947.           case ST_SKIP:                   /*  Skipped */
  13948.                conoll("");
  13949.                conol("Skipping ");
  13950.                conoll(s);
  13951.                p = 0;
  13952.                return;
  13953.  
  13954.           default:
  13955.                conoll("*** screen() called with bad status ***");
  13956.                p = 0;
  13957.                return;
  13958.           }
  13959.  
  13960.      case SCR_PN:                            /* Packet number */
  13961.           sprintf(buf, "%s: %ld", s, n);
  13962.           conol(buf);
  13963.           p += strlen(buf);
  13964.           return;
  13965.  
  13966.      case SCR_PT:                    /* Packet type or pseudotype */
  13967.           if (c == 'Y')
  13968.                return;               /* Don't bother with ACKs */
  13969.           if (c == 'D') {            /* Only show every 4th data packet */
  13970.                if (n % 4)
  13971.                     return;
  13972.                c = '.';
  13973.           }
  13974.           conoc(c);                  /* Display the character. */
  13975.           return;
  13976.  
  13977.      case SCR_TC:                    /* transaction complete */
  13978.           conoc(BEL);
  13979.           return;
  13980.  
  13981.      case SCR_EM:                            /* Error message */
  13982.           conoll("");
  13983.           conoc('?');
  13984.           conoll(s);
  13985.           p = 0;
  13986.           return;           /* +1   */
  13987.  
  13988.      case SCR_WM:                            /* Warning message */
  13989.           conoll("");
  13990.           conoll(s);
  13991.           p = 0;
  13992.           return;
  13993.  
  13994.      case SCR_TU:                            /* Undelimited text */
  13995.           if ((p += len) > 78) {
  13996.                conoll("");
  13997.                p = len;
  13998.           }
  13999.           conol(s);
  14000.           return;
  14001.  
  14002.      case SCR_TN:                            /* Text delimited at beginning */
  14003.           conoll("");
  14004.           conol(s);
  14005.           p = len;
  14006.           return;
  14007.  
  14008.      case SCR_TZ:                            /* Text delimited at end */
  14009.           if ((p += len) > 78) {
  14010.                conoll("");
  14011.                p = len;
  14012.           }
  14013.           conoll(s);
  14014.           return;
  14015.  
  14016.      case SCR_QE:                            /* Quantity equals */
  14017.           sprintf(buf, "%s: %ld", s, n);
  14018.           conoll(buf);
  14019.           p = 0;
  14020.           return;
  14021.  
  14022.      default:
  14023.           conoll("*** screen() called with bad object ***");
  14024.           p = 0;
  14025.           return;
  14026.      }
  14027. }
  14028.  
  14029.  
  14030. /*  I N T M S G  --  Issue message about terminal interrupts  */
  14031.  
  14032. intmsg(n)
  14033. long     n;
  14034. {
  14035.      extern char     *chstr();
  14036.      char     buf[80];
  14037.  
  14038.      if ((!displa) || (quiet))
  14039.           return;
  14040.      if (n == 1) {
  14041.           screen(SCR_TN, 0, 0l,
  14042.                  "CTRL-F to cancel file,  CTRL-R to resend current packet");
  14043.           screen(SCR_TN, 0, 0l,
  14044.                  "CTRL-B to cancel batch, CTRL-A for status report: ");
  14045.      } else
  14046.           screen(SCR_TU, 0, 0l, " ");
  14047. }
  14048.  
  14049.  
  14050. /*  C H K I N T  --  Check for console interrupts  */
  14051.  
  14052. /*** should rework not to destroy typeahead ***/
  14053.  
  14054. chkint()
  14055. {
  14056.      int     ch, cn;
  14057.  
  14058.      if ((!local) || (quiet))
  14059.           return(0); /* Only do this if local & not quiet */
  14060.  
  14061.      cn = conchk();                      /* Any input waiting? */
  14062.  
  14063.      if (deblog)
  14064.           debug(F101, "conchk", "", cn);
  14065.  
  14066.      while (cn > 0) {                    /* Yes, read it. */
  14067.           cn--;
  14068.           /* give read 5 seconds for interrupt character */
  14069.  
  14070.           if ((ch = coninc(5)) < 0)
  14071.                return(0);
  14072.  
  14073.           switch (ch & 0177) {
  14074.           case 0001:                  /* CTRL-A */
  14075.                screen(SCR_TN, 0, 0l, "^A  Status report:");
  14076.                screen(SCR_TN, 0, 0l, " file type: ");
  14077.                if (binary)
  14078.                     screen(SCR_TZ, 0, 0l, "binary");
  14079.                else
  14080.                     screen(SCR_TZ, 0, 0l, "text");
  14081.                screen(SCR_QE, 0, (long)filcnt, " file number");
  14082.                screen(SCR_QE, 0, (long)ffc,   " characters ");
  14083.                screen(SCR_QE, 0, (long)bctu,  " block check");
  14084.                screen(SCR_QE, 0, (long)rptflg, " compression");
  14085.                screen(SCR_QE, 0, (long)ebqflg, " 8th-bit prefixing");
  14086.                continue;
  14087.           case 0002:                  /* CTRL-B */
  14088.                screen(SCR_TN, 0, 0l, "^B - Cancelling Batch ");
  14089.                czseen = 1;
  14090.                continue;
  14091.           case 0006:                  /* CTRL-F */
  14092.                screen(SCR_TN, 0, 0l, "^F - Cancelling File ");
  14093.                cxseen = 1;
  14094.                continue;
  14095.           case 0022:                  /* CTRL-R */
  14096.                screen(SCR_TN, 0, 0l, "^R - Resending ");
  14097.                resend();
  14098.                return(1);
  14099.           default:                    /* Anything else, just ignore */
  14100.                screen(SCR_TU, 0, 0l, " [Ignored] ");
  14101.                continue;
  14102.           }
  14103.      }
  14104.      return(0);
  14105. }
  14106.  
  14107.  
  14108. #define TBUFL 300
  14109. /*  T L O G  --  Log a record in the transaction file  */
  14110. /*
  14111.  Call with a format and 3 arguments: two strings and a number:
  14112.    f  - Format, a bit string in range 0-7, bit x is on, arg #x is printed.
  14113.    s1,s2 - String arguments 1 and 2.
  14114.    n  - Int, argument 3.
  14115. */
  14116. tlog(f, s1, s2, n)
  14117. int     f;
  14118. long     n;
  14119. char     *s1, *s2;
  14120. {
  14121.      static char     s[TBUFL];
  14122.      char     *sp = s;
  14123.      int     x;
  14124.  
  14125.      if (!tralog)
  14126.           return;                /* If no transaction log, don't */
  14127.      switch (f) {
  14128.      case F000:                      /* 0 (special) "s1 n s2"  */
  14129.           if (strlen(s1) + strlen(s2) + 15 > TBUFL)
  14130.                sprintf(sp, "?T-Log string too long\n");
  14131.           else
  14132.                sprintf(sp, "%s %ld %s\n", s1, n, s2);
  14133.           zsout(ZTFILE, s);
  14134.           break;
  14135.      case F001:                      /* 1, " n" */
  14136.           sprintf(sp, " %ld\n", n);
  14137.           zsout(ZTFILE, s);
  14138.           break;
  14139.      case F010:                      /* 2, "[s2]" */
  14140.           x = strlen(s2);
  14141.           if (s2[x] == '\n')
  14142.                s2[x] = '\0';
  14143.           if (x + 6 > TBUFL)
  14144.                sprintf(sp, "?T-Log string too long\n");
  14145.           else
  14146.                sprintf(sp, "[%s]\n", s2);
  14147.           zsout(ZTFILE, "");
  14148.           break;
  14149.      case F011:                      /* 3, "[s2] n" */
  14150.           x = strlen(s2);
  14151.           if (s2[x] == '\n')
  14152.                s2[x] = '\0';
  14153.           if (x + 6 > TBUFL)
  14154.                sprintf(sp, "?T-Log string too long\n");
  14155.           else
  14156.                sprintf(sp, "[%s] %ld\n", s2, n);
  14157.           zsout(ZTFILE, s);
  14158.           break;
  14159.      case F100:                      /* 4, "s1" */
  14160.           zsoutl(ZTFILE, s1);
  14161.           break;
  14162.      case F101:                      /* 5, "s1: n" */
  14163.           if (strlen(s1) + 15 > TBUFL)
  14164.                sprintf(sp, "?T-Log string too long\n");
  14165.           else
  14166.                sprintf(sp, "%s: %ld\n", s1, n);
  14167.           zsout(ZTFILE, s);
  14168.           break;
  14169.      case F110:                      /* 6, "s1 s2" */
  14170.           x = strlen(s2);
  14171.           if (s2[x] == '\n')
  14172.                s2[x] = '\0';
  14173.           if (strlen(s1) + x + 4 > TBUFL)
  14174.                sprintf(sp, "?T-Log string too long\n");
  14175.           else
  14176.                sprintf(sp, "%s %s\n", s1, s2);
  14177.           zsout(ZTFILE, s);
  14178.           break;
  14179.      case F111:                      /* 7, "s1 s2: n" */
  14180.           x = strlen(s2);
  14181.           if (s2[x] == '\n')
  14182.                s2[x] = '\0';
  14183.           if (strlen(s1) + x + 15 > TBUFL)
  14184.                sprintf(sp, "?T-Log string too long\n");
  14185.           else
  14186.                sprintf(sp, "%s %s: %ld\n", s1, s2, n);
  14187.           zsout(ZTFILE, s);
  14188.           break;
  14189.      default:
  14190.           sprintf(sp, "\n?Invalid format for tlog() - %ld\n",
  14191.               n);
  14192.           zsout(ZTFILE, s);
  14193.      }
  14194. }
  14195.  
  14196.  
  14197. /*  D E B U G  --  Enter a record in the debugging log  */
  14198.  
  14199. /*
  14200.  Call with a format, two strings, and a number:
  14201.    f  - Format, a bit string in range 0-7.
  14202.         If bit x is on, then argument number x is printed.
  14203.    s1 - String, argument number 1.  If selected, printed as is.
  14204.    s2 - String, argument number 2.  If selected, printed in brackets.
  14205.    n  - Int, argument 3.  If selected, printed preceded by equals sign.
  14206.  
  14207.    f=0 is special: print s1,s2, and interpret n as a char.
  14208. */
  14209. #define DBUFL 1400
  14210.  
  14211. debug(f,s1,s2,n) int f, n; char *s1, *s2; {
  14212.     static char s[DBUFL];
  14213.     char *sp = s;
  14214.  
  14215.     if (!deblog) return;        /* If no debug log, don't */
  14216.     switch (f) {
  14217.  
  14218.       case F000:            /* 0, print both strings, */
  14219.         if (strlen(s1) + strlen(s2) + 3 > DBUFL)
  14220.           sprintf(sp,"DEBUG string too long\n");
  14221.         else
  14222.           sprintf(sp,"%s%s%c\n",s1,s2,n); /* interpret n as a char */
  14223.         zsout(ZDFILE,s);
  14224.         break;
  14225.  
  14226.         case F001:            /* 1, "=n" */
  14227.         sprintf(sp,"=%d\n",n);
  14228.         zsout(ZDFILE,s);
  14229.         break;
  14230.  
  14231.       case F010:            /* 2, "[s2]" */
  14232.         if (strlen(s2) + 4 > DBUFL)
  14233.           sprintf(sp,"DEBUG string too long\n");
  14234.         else
  14235.           sprintf(sp,"[%s]\n",s2);
  14236.         zsout(ZDFILE,"");
  14237.         break;
  14238.  
  14239.       case F011:            /* 3, "[s2]=n" */
  14240.         if (strlen(s2) + 15 > DBUFL)
  14241.           sprintf(sp,"DEBUG string too long\n");
  14242.         else
  14243.           sprintf(sp,"[%s]=%d\n",s2,n);
  14244.         zsout(ZDFILE,s);
  14245.         break;
  14246.  
  14247.       case F100:            /* 4, "s1" */
  14248.         zsoutl(ZDFILE,s1);
  14249.         break;
  14250.  
  14251.       case F101:            /* 5, "s1=n" */
  14252.         if (strlen(s1) + 15 > DBUFL)
  14253.           sprintf(sp,"DEBUG string too long\n");
  14254.         else
  14255.           sprintf(sp,"%s=%d\n",s1,n);
  14256.         zsout(ZDFILE,s);
  14257.         break;
  14258.  
  14259.       case F110:            /* 6, "s1[s2]" */
  14260.         if (strlen(s1) + strlen(s2) + 4 > DBUFL)
  14261.           sprintf(sp,"DEBUG string too long\n");
  14262.         else
  14263.           sprintf(sp,"%s[%s]\n",s1,s2);
  14264.         zsout(ZDFILE,s);
  14265.         break;
  14266.  
  14267.       case F111:            /* 7, "s1[s2]=n" */
  14268.         if (strlen(s1) + strlen(s2) + 15 > DBUFL)
  14269.           sprintf(sp,"DEBUG string too long\n");
  14270.         else
  14271.           sprintf(sp,"%s[%s]=%d\n",s1,s2,n);
  14272.         zsout(ZDFILE,s);
  14273.         break;
  14274.  
  14275.      /* the interface to call debug() with V110
  14276.          debug(V110,string1,string2,n);
  14277.                string -> char *
  14278.                n      -> strlen(string2) || with binary 0 padding
  14279.                          the length returned by MCS
  14280.                                                                     */
  14281.       case V110:
  14282.            {
  14283.                static char     stmp[DBUFL];
  14284.                char            *cptr;
  14285.                int             i, j;
  14286.                static char     hexchar[]={ '0','1','2','3','4','5','6',
  14287.                                            '7','8','9','A','B','C','D',
  14288.                                            'E','F'};
  14289.  
  14290.                if (n <= 0 || (strlen(s2)+n*2)>DBUFL)
  14291.                      sprintf (stmp, "V110 error (n)length=0");
  14292.                else
  14293.                      for (j = 0,i = 0, cptr=s2;
  14294.                           j <= n, *cptr=='\0'; j++) {
  14295.  
  14296.                          if (*cptr < 0x10)
  14297.                              stmp[i++] = '0';
  14298.                          else
  14299.                              stmp[i++] = hexchar[(int)*cptr++ / 0x10];
  14300.  
  14301.                          if (*cptr == 0x00)
  14302.                              stmp[i++] = '0';
  14303.                          else
  14304.                              stmp[i++]= hexchar[(int)*cptr++ % 0x10];
  14305.                      }
  14306.                stmp[i] = '\0';
  14307.                sprintf(sp, "<%s>%s\n", s1, stmp);
  14308.           }
  14309.           zsout(ZDFILE, s);
  14310.           break;
  14311.  
  14312.     default:
  14313.         sprintf(sp,"\n?Invalid format for debug() - %d\n",n);
  14314.         zsout(ZDFILE,s);
  14315.     }
  14316. }
  14317. <<< ckvusr.c >>>
  14318. char     *userv = "User Interface 4E(060), 06 June 90";
  14319.  
  14320. /*  C K V U S R --  "User Interface" for NCR-VRX Kermit (Part 1)  */
  14321.  
  14322. /**********************************************************************
  14323. *                                                                     *
  14324. * IVS / MCS-Kermit REL 2                                              *
  14325. * source code                                                         *
  14326. *                                                                     *
  14327. * Change History:                                                     *
  14328. *                                                                     *
  14329. *                1. Modify C-Kermit(4E) source code to                *
  14330. *                   produce new module for MCS/IVS-Kermit             *
  14331. *                   ORIGINAL RELEASE                                  *
  14332. *                   June 22, 1990                                     *
  14333. *                                                                     *
  14334. *                                                                     *
  14335. ***********************************************************************/
  14336.  
  14337.  
  14338. /*
  14339.  4E, support for Apollo Aegis, Data General added, July 87.
  14340. */
  14341. /*
  14342.  Author: Frank da Cruz (fdc@cunixc.cc.columbia.edu, FDCCU@CUVMA.BITNET),
  14343.  Columbia University Center for Computing Activities.
  14344.  First released January 1985.
  14345.  Copyright (C) 1985, 1989, Trustees of Columbia University in the City of New
  14346.  York.  Permission is granted to any individual or institution to use, copy, or
  14347.  redistribute this software so long as it is not sold for profit, provided this
  14348.  copyright notice is retained.
  14349. */
  14350.  
  14351. /*
  14352.  The ckuusr module contains the terminal input and output functions for VRX
  14353.  Kermit.  It includes a simple NCR-VRX-style command line parser as well as
  14354.  an interactive prompting keyword command parser.  It depends on the existence
  14355.  of VRX facilities like fopen, fgets, feof, (f)printf, argv/argc, etc.  Other
  14356.  functions that are likely to vary among VRX implementations -- like setting
  14357.  terminal modes or interrupts -- are invoked via calls to functions that are
  14358.  defined in the system-dependent modules, ck?[ft]io.c.
  14359.  
  14360.  The command line parser processes any arguments found on the command line,
  14361.  as passed to main() via argv/argc.  The interactive parser uses the facilities
  14362.  of the cmd package (developed for this program, but usable by any program).
  14363.  
  14364.  Any command parser may be substituted for this one.  The only requirements
  14365.  for the Kermit command parser are these:
  14366.  
  14367.  1. Set parameters via global variables like duplex, speed, ttname, etc.
  14368.     See ckmain.c for the declarations and descriptions of these variables.
  14369.  
  14370.  2. If a command can be executed without the use of Kermit protocol, then
  14371.     execute the command directly and set the variable sstate to 0. Examples
  14372.     include 'set' commands, local directory listings, the 'connect' command.
  14373.  
  14374.  3. If a command requires the Kermit protocol, set the following variables:
  14375.  
  14376.     sstate                             string data
  14377.       'x' (enter server mode)            (none)
  14378.       'r' (send a 'get' command)         cmarg, cmarg2
  14379.       'v' (enter receive mode)           cmarg2
  14380.       'g' (send a generic command)       cmarg
  14381.       's' (send files)                   nfils, cmarg & cmarg2 OR cmlist
  14382.       'c' (send a remote host command)   cmarg
  14383.  
  14384.     cmlist is an array of pointers to strings.
  14385.     cmarg, cmarg2 are pointers to strings.
  14386.     nfils is an integer.
  14387.  
  14388.     cmarg can be a filename string (possibly wild), or
  14389.        a pointer to a prefabricated generic command string, or
  14390.        a pointer to a host command string.
  14391.     cmarg2 is the name to send a single file under, or
  14392.        the name under which to store an incoming file; must not be wild.
  14393.     cmlist is a list of nonwild filenames, such as passed via argv.
  14394.     nfils is an integer, interpreted as follows:
  14395.       -1: argument string is in cmarg, and should be expanded internally.
  14396.        0: stdin.
  14397.       >0: number of files to send, from cmlist.
  14398.  
  14399.  The screen() function is used to update the screen during file transfer.
  14400.  The tlog() function maintains a transaction log.
  14401.  The debug() function maintains a debugging log.
  14402.  The intmsg() and chkint() functions provide the user i/o for interrupting
  14403.    file transfers.
  14404. */
  14405.  
  14406. /* Includes */
  14407.  
  14408. #include "ckcdeb.h"
  14409. #include <stdio.h>
  14410. #include <ctype.h>
  14411. #include <signal.h>
  14412. #include "ckcker.h"
  14413. #include "ckucmd.h"
  14414. #include "ckuusr.h"
  14415. #include "kermisc.h"
  14416.  
  14417. #ifdef MCS_FLAG
  14418. #include "mcs.h"
  14419. #endif
  14420.  
  14421. /* External Kermit Variables, see ckmain.c for description. */
  14422.  
  14423. extern int     EXECL();
  14424.  
  14425. extern void errhdlr();
  14426.  
  14427. #ifdef MCS_FLAG
  14428. extern void \:FINISH();
  14429. #endif
  14430.  
  14431. extern int     size, rpsiz, urpsiz, speed, local,
  14432. server, displa, binary, parity, deblog, escape, xargc, flow,
  14433. turn, duplex, nfils, ckxech, pktlog, seslog, tralog, stdouf,
  14434. turnch, dfloc, keep, maxrps, /*  warn, */ quiet, cnflg, tlevel,
  14435. send_id, recv_id, send_num, recv_num, send_renum, recv_renum,
  14436. send_addnum, recv_addnum;
  14437.  
  14438. extern char     *versio, *protv, *ckxv, *ckzv, *fnsv, *connv, *dftty, *cmdv;
  14439. extern char     *dialv, *loginv;
  14440. extern char     *ckxsys, *ckzsys, *cmarg, *cmarg2, **xargv, **cmlist;
  14441. extern char     cmerrp[];
  14442. extern CHAR sstate, ttname[];
  14443. char     *strcpy(), *GETENV();
  14444.  
  14445. /* Declarations from cmd package */
  14446.  
  14447. extern char     cmdbuf[];                   /* Command buffer */
  14448. extern int      cmflgs;                     /* Command flags */
  14449.  
  14450. /* Declarations from ck?fio.c module */
  14451.  
  14452. extern char     *zhome();           /* Space command, home directory. */
  14453. extern int     backgrd;             /* Kermit executing in background */
  14454.  
  14455. /* The background flag is set by ckutio.c (via conint() ) to note whether */
  14456. /* this kermit is executing in background ('&' on shell command line).    */
  14457.  
  14458.  
  14459. /* Variables and symbols local to this module */
  14460.  
  14461. char     line[CMDBL+10], *lp;               /* Character buffer for anything */
  14462. char     debfil[50];                        /* Debugging log file name */
  14463. char     pktfil[50];                        /* Packet log file name */
  14464. char     sesfil[50];                        /* Session log file name */
  14465. char     trafil[50];                        /* Transaction log file name */
  14466.  
  14467. int     n,                                  /* General purpose int */
  14468. cflg,                               /* Command-line connect cmd given */
  14469. action,                             /* Action selected on command line*/
  14470. repars,                             /* Reparse needed */
  14471. cwdf = 0;                           /* CWD has been done */
  14472.  
  14473. #define MAXTAKE 20                  /* Maximum nesting of TAKE files */
  14474. FILE *tfile[MAXTAKE];               /* File pointers for TAKE command */
  14475.  
  14476. char     *homdir;                   /* Pointer to home directory string */
  14477. char     cmdstr[100];               /* Place to build generic command */
  14478.  
  14479. /*  C M D L I N  --  Get arguments from command line  */
  14480. /*
  14481.  Simple NCR-VRX-style command line parser, conforming with 'A Proposed Command
  14482.  Syntax Standard for NCR-VRX Systems', Hemenway & Armitage, Unix/World, Vol.1,
  14483.  No.3, 1984.
  14484. */
  14485. cmdlin()
  14486. {
  14487.      char     x;                             /* Local general-purpose int */
  14488.      cmarg = "";                         /* Initialize globals */
  14489.      cmarg2 = "";
  14490.      action = cflg = 0;
  14491.  
  14492.      while (--xargc > 0) {               /* Go through command line words */
  14493.           xargv++;
  14494.           if (deblog)
  14495.                debug(F111, "xargv", *xargv, xargc);
  14496.           if (**xargv == '-') {       /* Got an option (begins with dash) */
  14497.                x = *(*xargv + 1);     /* Get the option letter */
  14498.                x = doarg(x);          /* Go handle the option */
  14499.                if (x < 0)
  14500.                     doexit(BAD_EXIT);
  14501.           } else {                        /* No dash where expected */
  14502.                usage();
  14503.                doexit(BAD_EXIT);
  14504.           }
  14505.      }
  14506.      if (deblog)
  14507.           debug(F101, "action", "", action);
  14508.      if (!local) {
  14509.           if ((action == 'g') || (action == 'r') ||  (action ==
  14510.               'c') || (cflg != 0))
  14511.                fatal("-l and -b required");
  14512.      }
  14513.      if (*cmarg2 != 0) {
  14514.           if ((action != 's') && (action != 'r') &&  (action !=
  14515.               'v'))
  14516.                fatal("-a without -s, -r, or -g");
  14517.      }
  14518.      if ((action == 'v') && (stdouf) && (!local)) {
  14519.           if (isatty(1))
  14520.                fatal("unredirected -k can only be used in local mode");
  14521.      }
  14522.      if ((action == 's') || (action == 'v') ||  (action == 'r') ||
  14523.          (action == 'x')) {
  14524.           if (local)
  14525.                displa = 1;
  14526.           if (stdouf) {
  14527.                displa = 0;
  14528.                quiet = 1;
  14529.           }
  14530.      }
  14531.  
  14532.      if (quiet)
  14533.           displa = 0;              /* No display if quiet requested */
  14534.  
  14535.      if (cflg) {
  14536.           conect();                       /* Connect if requested */
  14537.           if (action == 0) {
  14538.                if (cnflg)
  14539.                     conect();        /* And again if requested */
  14540.                doexit(GOOD_EXIT);          /* Then exit indicating success */
  14541.           }
  14542.      }
  14543.      if (displa)
  14544.           concb(escape);          /* (for console "interrupts") */
  14545.      return(action);                     /* Then do any requested protocol */
  14546. }
  14547.  
  14548.  
  14549. /*  D O A R G  --  Do a command-line argument.  */
  14550.  
  14551. doarg(x)
  14552. char     x;
  14553. {
  14554.      int     z;
  14555.      char     *xp;
  14556.  
  14557.      if (deblog) debug(F101,"funct: doarg> x:","",x);
  14558.  
  14559.      xp = *xargv + 1;                      /* Pointer for bundled args */
  14560.      while (x) {
  14561.           switch (x) {
  14562.  
  14563.           case 'x':                               /* server */
  14564.                if (action)
  14565.                     fatal("conflicting actions");
  14566.                action = 'x';
  14567.                break;
  14568.  
  14569.           case 'f':
  14570.                if (action)
  14571.                     fatal("conflicting actions");
  14572.                action = setgen('F', "", "", "");
  14573.                break;
  14574. /*
  14575. *         case 'r':                               * receive *
  14576. *              if (action)
  14577. *                   fatal("conflicting actions");
  14578. *              action = 'v';
  14579. *              break;
  14580. *
  14581. *         case 'k':                               * receive to stdout *
  14582. *              if (action)
  14583. *                   fatal("conflicting actions");
  14584. *              stdouf = 1;
  14585. *              action = 'v';
  14586. *              break;
  14587. *
  14588. *         case 's':                                * send *
  14589. *              if (action)
  14590. *                   fatal("conflicting actions");
  14591. *              if (*(xp + 1))
  14592. *                   fatal("invalid argument bundling after -s");
  14593. *               * Initialize file counter, flag *
  14594. *               z = nfils = 0;
  14595. *               * Remember this pointer *
  14596. *               cmlist = xargv + 1;
  14597. *               while (--xargc > 0) {                * Traverse the list *
  14598. *                    *xargv++;
  14599. *                    if (**xargv == '-') {       * Check for sending stdin *
  14600. *                         if (strcmp(*xargv, "-") != 0)
  14601. *                              break;
  14602. *                         z++;
  14603. *                    }
  14604. *                    nfils++;                         * Bump file counter *
  14605. *               }
  14606. *               xargc++, *xargv--;                   * Adjust argv/argc *
  14607. *               if (nfils < 1)
  14608. *                    fatal("missing filename for -s");
  14609. *               if (z > 1)
  14610. *                    fatal("-s: too many -'s");
  14611. *               if (z == 1) {
  14612. *                    if (nfils == 1)
  14613. *                         nfils = 0;
  14614. *                    else
  14615. *                         fatal("invalid mixture of filenames and '-' in -s");
  14616. *               }
  14617. *               if (nfils == 0) {
  14618. *                    if (isatty(0))
  14619. *                         fatal("sending from terminal not allowed");
  14620. *               }
  14621. *               if (deblog)
  14622. *                    debug(F101, *xargv, "", nfils);
  14623. *               action = 's';
  14624. *               break;
  14625. *
  14626. *          case 'g':                                * get *
  14627. *               if (action)
  14628. *                    fatal("conflicting actions");
  14629. *               if (*(xp + 1))
  14630. *                    fatal("invalid argument bundling after -g");
  14631. *               *xargv++, xargc--;
  14632. *               if ((xargc == 0) || (**xargv == '-'))
  14633. *                    fatal("missing filename for -g");
  14634. *               cmarg = *xargv;
  14635. *               action = 'r';
  14636. *               break;
  14637. *
  14638. *          case 'c':                                * connect before *
  14639. *               cflg = 1;
  14640. *               break;
  14641. *
  14642. *          case 'n':                                * connect after *
  14643. *               cnflg = 1;
  14644. *               break;
  14645. */
  14646.           case 'h':                               /* help */
  14647.                usage();
  14648.                return(-1);
  14649.  
  14650. /*         case 'a':                                * "as" *
  14651. *               if (*(xp + 1))
  14652. *                    fatal("invalid argument bundling after -a");
  14653. *               *xargv++, xargc--;
  14654. *               if ((xargc < 1) || (**xargv == '-'))
  14655. *                    fatal("missing name in -a");
  14656. *               cmarg2 = *xargv;
  14657. *               break;
  14658. *
  14659. *          case 'l':                                * set line *
  14660. *               if (*(xp + 1))
  14661. *                    fatal("invalid argument bundling after -l");
  14662. *               *xargv++, xargc--;
  14663. *               if ((xargc < 1) || (**xargv == '-'))
  14664. *                    fatal("communication line device name missing");
  14665. *               strcpy(ttname, *xargv);
  14666. *
  14667. *                *  if (strcmp(ttname,dftty) == 0) local = dfloc;
  14668. *                   else local = 1;  *
  14669. *
  14670. *                * (better than old way) *
  14671. *               local = (strcmp(ttname, CTTNAM) != 0);
  14672. *               if (deblog)
  14673. *                    debug(F101, "local", "", local);
  14674. *               ttopen(ttname, &local, 0);
  14675. *               break;
  14676. *
  14677. *          case 'b':                                * set baud *
  14678. *               if (*(xp + 1))
  14679. *                    fatal("invalid argument bundling");
  14680. *               *xargv++, xargc--;
  14681. *               if ((xargc < 1) || (**xargv == '-'))
  14682. *                    fatal("missing baud");
  14683. *               z = atoi(*xargv);                    * Convert to number *
  14684. *               if (chkspd(z) > -1)
  14685. *                    speed = z;       * Check it *
  14686. *               else
  14687. *                    fatal("unsupported baud rate");
  14688. *              break;
  14689. */
  14690.           case 'e':                               /* Extended packet length */
  14691.                if (*(xp + 1))
  14692.                     fatal("invalid argument bundling");
  14693.                *xargv++, xargc--;
  14694.                if ((xargc < 1) || (**xargv == '-'))
  14695.                     fatal("missing length");
  14696.                z = atoi(*xargv);                   /* Convert to number */
  14697.                if (z > 10 && z < maxrps) {
  14698.                     rpsiz = urpsiz = z;
  14699.                     if (z > 94)
  14700.                          rpsiz = 94;      /* Fallback if other Kermit can't */
  14701.                } else
  14702.                     fatal("Unsupported packet length");
  14703.                break;
  14704.  
  14705.           case 'i':                               /* Treat files as binary */
  14706.                binary = 1;
  14707.                break;
  14708.  
  14709.  
  14710.        /* case 'w':                                * File warning *
  14711.         *      warn = 1;
  14712.         *      break;
  14713.         */
  14714.  
  14715.           case 'q':                               /* Quiet */
  14716.                quiet = 1;
  14717.                break;
  14718.  
  14719.           case 'd':                               /* debug */
  14720.                debopn("debuglog");
  14721.                break;
  14722.  
  14723.           case 'p':                               /* set parity */
  14724.                if (*(xp + 1))
  14725.                     fatal("invalid argument bundling");
  14726.                *xargv++, xargc--;
  14727.                if ((xargc < 1) || (**xargv == '-'))
  14728.                     fatal("missing parity");
  14729.                switch (x = **xargv) {
  14730.                case 'e':
  14731.                case 'o':
  14732.                case 'm':
  14733.                case 's':
  14734.                     parity = x;
  14735.                     break;
  14736.                case 'n':
  14737.                     parity = 0;
  14738.                     break;
  14739.                default:
  14740.                     fatal("invalid parity");
  14741.                }
  14742.                break;
  14743.  
  14744.           case 't':
  14745.                turn = 1;            /* Line turnaround handshake */
  14746.                turnch = XON;        /* XON is turnaround character */
  14747.                duplex = 1;          /* Half duplex */
  14748.                flow = 0;            /* No flow control */
  14749.                break;
  14750.  
  14751.           default:
  14752.                fatal("invalid argument, type 'kermit -h' for help");
  14753.           }
  14754.  
  14755.           x = *++xp;                          /* See if options are bundled */
  14756.      }
  14757.      return(0);
  14758. }
  14759.  
  14760.  
  14761. fatal(msg)
  14762. char     *msg;
  14763. {                 /* Fatal error message */
  14764.      fprintf(stderr, "\r\nFatal: %s\n", msg);
  14765.      tlog(F110, "Fatal:", msg, 0l);
  14766.      doexit(BAD_EXIT);                   /* Exit indicating failure */
  14767. }
  14768.  
  14769.  
  14770. ermsg(msg)
  14771. char     *msg;
  14772. {                 /* Print error message */
  14773.      if (!quiet)
  14774.           fprintf(stderr, "\r\n%s - %s\n", cmerrp, msg);
  14775.      tlog(F110, "Error -", msg, 0l);
  14776. }
  14777.  
  14778.  
  14779. /* Interactive command parser */
  14780.  
  14781.  
  14782. /* Top-Level Keyword Table */
  14783.  
  14784. struct keytab cmdtab[] = {
  14785.      "!",           XXSHE, CM_INV,
  14786.      "%",           XXCOM, CM_INV,
  14787.      "bye",         XXBYE, CM_INV,
  14788.      "c",           XXCON, CM_INV,
  14789.      "cd",          XXCWD, CM_INV,
  14790.      "close",       XXCLO, 0,
  14791.      "connect",     XXCON, CM_INV,
  14792.      "cwd",         XXCWD, CM_INV,
  14793.      "dial",        XXDIAL, CM_INV,
  14794.      "directory",   XXDIR, CM_INV,
  14795.      "echo",        XXECH, 0,
  14796.      "exit",        XXEXI, 0,
  14797.      "finish",      XXFIN, CM_INV,
  14798.      "get",         XXGET, CM_INV,
  14799.      "hangup",      XXHAN, CM_INV,
  14800.      "help",        XXHLP, 0,
  14801.      "log",         XXLOG, 0,
  14802.      "quit",        XXQUI, 0,
  14803.      "r",           XXREC, CM_INV,
  14804.      "receive",     XXREC, CM_INV,
  14805.      "remote",      XXREM, CM_INV,
  14806.      "s",           XXSEN, CM_INV,
  14807.      "script",      XXLOGI, CM_INV,
  14808.      "send",        XXSEN, CM_INV,
  14809.      "server",      XXSER, 0,
  14810.      "set",         XXSET, 0,
  14811.      "show",        XXSHO, 0,
  14812.      "space",       XXSPA, CM_INV,
  14813.      "statistics",  XXSTA, 0,
  14814.      "take",        XXTAK, 0
  14815. };
  14816.  
  14817.  
  14818. int     ncmd = (sizeof(cmdtab)
  14819.  / sizeof(struct keytab )
  14820. );
  14821.  
  14822. /* Parameter keyword table */
  14823.  
  14824. struct keytab prmtab[] = {
  14825.      "baud",             XYSPEE,  CM_INV,
  14826.      "add-linenum",      XYADD,   CM_INV,    /* moved to send/receive */
  14827.      "block-check",      XYCHKT,  0,
  14828.      "delay",            XYDELA,  CM_INV,
  14829.      "duplex",           XYDUPL,  0,
  14830.      "end-of-packet",    XYEOL,   CM_INV,    /* moved to send/receive */
  14831.      "escape-character", XYESC,   CM_INV,
  14832.      "file",             XYFILE,  0,
  14833.      "flow-control",     XYFLOW,  0,
  14834.      "handshake",        XYHAND,  0,
  14835.      "id-fields",        XYID,    CM_INV,    /* moved to send/receive */
  14836.      "incomplete",       XYIFD,   0,
  14837.      "line",             XYLINE,  CM_INV,
  14838.      "line-numbers",     XYNUM,   CM_INV,    /* moved to send/receive */
  14839.      "modem-dialer",     XYMODM,  CM_INV,
  14840.      "packet-length",    XYLEN,   CM_INV,    /* moved to send/receive */
  14841.      "pad-character",    XYPADC,  CM_INV,    /* moved to send/receive */
  14842.      "padding",          XYNPAD,  CM_INV,    /* moved to send/receive */
  14843.      "parity",           XYPARI,  0,
  14844.      "prompt",           XYPROM,  0,
  14845.      "receive",          XYRECV,  0,
  14846.      "retry",            XYRETR,  0,
  14847.      "renumber",         XYRNUM,  CM_INV, /* moved to send/receive */
  14848.      "send",             XYSEND,  0,
  14849.      "speed",            XYSPEE,  CM_INV,
  14850.      "start-of-packet",  XYMARK,  CM_INV,    /* moved to send/receive */
  14851.      "terminal",         XYTERM,  CM_INV,
  14852.      "timeout",          XYTIMO,  CM_INV     /* moved to send/receive */
  14853. };
  14854.  
  14855.  
  14856. int     nprm = (sizeof(prmtab)
  14857.  / sizeof(struct keytab )
  14858. ); /* How many parameters */
  14859.  
  14860.  
  14861. /* Remote Command Table */
  14862.  
  14863. struct keytab remcmd[] = {
  14864.      "cd",        XZCWD, CM_INV,
  14865.      "cwd",       XZCWD, 0,
  14866.      "delete",    XZDEL, 0,
  14867.      "directory", XZDIR, 0,
  14868.      "help",      XZHLP, 0,
  14869.      "host",      XZHOS, 0,
  14870.      "space",     XZSPA, 0,
  14871.      "type",      XZTYP, 0,
  14872.      "who",       XZWHO, 0
  14873. };
  14874.  
  14875.  
  14876. int     nrmt = (sizeof(remcmd)
  14877.  / sizeof(struct keytab )
  14878. );
  14879.  
  14880. struct keytab logtab[] = {
  14881.      "debugging",    LOGD, 0,
  14882.      "packets",      LOGP, 0,
  14883.      "session",      LOGS, CM_INV,
  14884.      "transactions", LOGT, 0
  14885. };
  14886.  
  14887.  
  14888. int     nlog = (sizeof(logtab)
  14889.  / sizeof(struct keytab )
  14890. );
  14891.  
  14892. /* Show command arguments */
  14893.  
  14894. #define SHPAR 0                         /* Parameters */
  14895. #define SHVER 1                         /* Versions */
  14896.  
  14897. struct keytab shotab[] = {
  14898.      "parameters", SHPAR, 0,
  14899.      "versions",   SHVER, 0
  14900. };
  14901.  
  14902.  
  14903. /*  C M D I N I  --  Initialize the interactive command parser  */
  14904.  
  14905. cmdini()
  14906. {
  14907.  
  14908.      tlevel = -1;                        /* Take file level */
  14909. #ifndef MCS_FLAG
  14910.      cmsetp("IVS-Kermit>");                /* Set default prompt */
  14911. #else
  14912.      cmsetp("MCS-Kermit>");                /* Set default prompt */
  14913. #endif
  14914.  
  14915.      /* Look for init file in home or current directory. */
  14916.  
  14917.      homdir = zhome();         /* home dir not used */
  14918.      lp = line;
  14919.      lp[0] = '\0';
  14920.  
  14921. /*
  14922.  *   if (homdir) {
  14923.  *        strcpy(lp, homdir);
  14924.  *         if (lp[0] == '/')
  14925.  *             strcat(lp, "/");
  14926.  *   }
  14927.  *   strcat(lp, KERMRC);
  14928.  *   if ((tfile[0] = fopen(line, "r")) != NULL) {
  14929.  *        tlevel = 0;
  14930.  *        if (deblog)
  14931.  *             debug(F110, "init file", line, 0);
  14932.  *   }
  14933.  *   if (homdir && (tlevel < 0)) {
  14934.  *        strcpy(lp, KERMRC);
  14935.  *        if ((tfile[0] = fopen(line, "r")) != NULL) {
  14936.  *             tlevel = 0;
  14937.  *             if (deblog)
  14938.  *                  debug(F110, "init file", line, 0);
  14939.  *        } else {
  14940.  *             if (deblog)
  14941.  *                  debug(F100, "no init file", "", 0);
  14942.  *        }
  14943.  *   }
  14944.  */
  14945.  
  14946.      /* Look for the init file.  In the V environment, the file
  14947.         location is controlled by the filelocation parameter.
  14948.         If CAT or CAT/NOCAT is specified, we'll look in the
  14949.         current subcatalog node.  If NOCAT is specified, we'll
  14950.         look on disk.  If there is no volume assigned, then we
  14951.         could get a resource not available message.  */
  14952.  
  14953.      strcpy(lp, KERMRC);
  14954.      if ((tfile[0] = fopen(line, "r")) != NULL) {
  14955.        tlevel = 0;
  14956.        if (deblog) debug(F110, "init file", line, 0);
  14957.      } else {
  14958.          if (deblog) debug(F100, "no init file", "", 0);
  14959.      }
  14960.  
  14961.      congm();                            /* Get console tty modes */
  14962. }
  14963.  
  14964.  
  14965. /* Display version herald and initial prompt */
  14966.  
  14967. herald()
  14968. {
  14969.      if (!backgrd)
  14970. #ifndef MCS_FLAG
  14971.           printf("%s\nType ? for help\n", versio);
  14972. #else
  14973.           sprintf("%s\nType ? for help\n", versio);
  14974.           mcs_printf(print_str);
  14975. #endif
  14976. }
  14977.  
  14978.  
  14979. /*  T R A P  --  Terminal interrupt handler */
  14980.  
  14981. trap()
  14982. {
  14983.      if (deblog)
  14984.           debug(F100, "terminal interrupt...", "", 0);
  14985.      doexit(GOOD_EXIT);                  /* Exit indicating success */
  14986. }
  14987.  
  14988.  
  14989. /*  S T P T R A P -- Handle SIGTSTP signals */
  14990.  
  14991. stptrap()
  14992. {
  14993.      conres();                           /* Reset the console */
  14994.      doexit(GOOD_EXIT);                  /* Probably won't happen otherwise */
  14995.      concb();                            /* Put console back in Kermit mode */
  14996. }
  14997.  
  14998.  
  14999. /*  P A R S E R  --  Top-level interactive command parser.  */
  15000.  
  15001. char     parser()
  15002. {
  15003.      int     xx, cbn;
  15004.      char     *cbp;
  15005.  
  15006.      concb(escape);              /* Put console in cbreak mode. */
  15007.      conint(trap);               /* Turn on console terminal interrupts. */
  15008.      /*
  15009.  sstate becomes nonzero when a command has been parsed that requires some
  15010.  action from the protocol module.  Any non-protocol actions, such as local
  15011.  directory listing or terminal emulation, are invoked directly from below.
  15012. */
  15013.      if (local && !backgrd)
  15014. #ifndef MCS_FLAG
  15015.           printf("\n"); /*** Temporary kludge ***/
  15016. #else
  15017.           mcs_printf("\n"); /*** Temporary kludge ***/
  15018. #endif
  15019.      sstate = 0;                         /* Start with no start state. */
  15020.      while (sstate == 0) {   /* Parse cmds until action requested */
  15021.           while ((tlevel > -1) && feof(tfile[tlevel])) { /* If end of take */
  15022.                fclose(tfile[tlevel--]); /* file, close it. */
  15023.                cmini(ckxech);          /* and clear the cmd buffer. */
  15024.                if (tlevel < 0) {       /* Just popped out of cmd files? */
  15025.                     conint(trap);       /* Check background stuff again. */
  15026.                     return(0);          /* End of init file or whatever. */
  15027.                }
  15028.           }
  15029.           if (deblog)
  15030.                debug(F101, "tlevel", "", tlevel);
  15031.           if (tlevel > -1) {              /* If in take file */
  15032.                cbp = cmdbuf;               /* Get the next line. */
  15033.                cbn = CMDBL;
  15034.  
  15035.          /* Loop to get next command line and
  15036.             all continuation lines from take file. */
  15037.  
  15038. again:
  15039.                if (fgets(line, cbn, tfile[tlevel]) == NULL)
  15040.                     continue;
  15041.                lp = line;                  /* Got one, copy it. */
  15042.                while (*cbp++ = *lp++)
  15043.                     if (--cbn < 1)
  15044.                          fatal("Command too long for internal buffer");
  15045.                if (*(cbp - 3) == '\\') {   /* Continued on next line? */
  15046.                     cbp -= 3;               /* If so, back up pointer, */
  15047.                     goto again;             /* go back, get next line. */
  15048.                }
  15049.                /* Strip any quotes from cmd buffer. */
  15050.                stripq(cmdbuf);
  15051.  
  15052.           } else {                        /* No take file, get typein. */
  15053.  
  15054.                if (!backgrd)
  15055.                     prompt();     /* Issue interactive prompt. */
  15056.                cmini(ckxech);
  15057.           }
  15058.           repars = 1;
  15059.           displa = 0;
  15060.           while (repars) {
  15061.                cmres();                    /* Reset buffer pointers. */
  15062.                xx = cmkey(cmdtab, ncmd, "Command", "");
  15063.                if (deblog)
  15064.                     debug(F101, "top-level cmkey", "", xx);
  15065.                switch (docmd(xx)) {
  15066.                case -4:                /* EOF */
  15067.                     doexit(GOOD_EXIT);  /* ...exit successfully */
  15068.                case -1:                /* Reparse needed */
  15069.                     repars = 1;
  15070.                     continue;
  15071.                case -2:                /* Invalid command given */
  15072.                     if (backgrd)        /* if in background, terminate */
  15073.                          fatal("Kermit command error in background execution");
  15074.                     if (tlevel > -1) {  /* If in take file, quit */
  15075.                          ermsg("Kermit command error: take file terminated.");
  15076.                          fclose(tfile[tlevel]);
  15077.                          tlevel--;
  15078.                     }
  15079.                     cmini(ckxech);     /* fall thru */
  15080.                case -3:                /* Empty command OK at top level */
  15081.                default:                /* Anything else (fall thru) */
  15082.                     repars = 0;        /* No reparse, get new command. */
  15083.                     *cmdbuf = NUL;     /* Clear out the command buffer */
  15084.                     continue;
  15085.                }
  15086.           }
  15087.      }
  15088.      /* Got an action command; disable terminal
  15089.         interrupts and return start state */
  15090.  
  15091.      if (!local)
  15092.           connoi();               /* Interrupts off only if remote */
  15093.      return(sstate);
  15094. }
  15095.  
  15096.  
  15097. /*  D O E X I T  --  Exit from the program.  */
  15098.  
  15099. doexit(exitstat)
  15100. int     exitstat;
  15101. {
  15102.  
  15103.      ttclos();                           /* Close external line, if any */
  15104.      if (local) {
  15105.           strcpy(ttname, dftty);         /* Restore default tty */
  15106.           local = dfloc;                 /* And default remote/local status */
  15107.      }
  15108.      if (!quiet)
  15109.           conres();               /* Restore console terminal. */
  15110.      if (!quiet)
  15111.           connoi();               /* Turn off console interrupt traps. */
  15112.  
  15113.      if (deblog) {                       /* Close any open logs. */
  15114.           if (deblog)
  15115.                debug(F100, "Debug Log Closed", "", 0);
  15116.           *debfil = '\0';
  15117.           deblog = 0;
  15118.           zclose(ZDFILE);
  15119.      }
  15120.      if (pktlog) {
  15121.           *pktfil = '\0';
  15122.           pktlog = 0;
  15123.           zclose(ZPFILE);
  15124.      }
  15125. /*   if (seslog) {            packet log disabled from opening
  15126.           *sesfil = '\0';
  15127.           seslog = 0;
  15128.           zclose(ZSFILE);
  15129.      }                                                            */
  15130.      if (tralog) {
  15131.           tlog(F100, "Transaction Log Closed", "", 0l);
  15132.           *trafil = '\0';
  15133.           tralog = 0;
  15134.           zclose(ZTFILE);
  15135.      }
  15136.      syscleanup();
  15137.  
  15138. #ifndef MCS_FLAG
  15139.     exit(exitstat);                 /* Exit from the program. */
  15140. #else
  15141.     \:FINISH(exitstat);
  15142. #endif
  15143. }
  15144.  
  15145.  
  15146. /*  B L D L E N  --  Make length-encoded copy of string  */
  15147.  
  15148. char     *
  15149. bldlen(str, dest)
  15150. char     *str, *dest;
  15151. {
  15152.      int     len;
  15153.      len = strlen(str);
  15154.      *dest = tochar(len);
  15155.      strcpy(dest + 1, str);
  15156.      return(dest + len + 1);
  15157. }
  15158.  
  15159.  
  15160. /*  S E T G E N  --  Construct a generic command  */
  15161.  
  15162. setgen(type, arg1, arg2, arg3)
  15163. char     type, *arg1, *arg2, *arg3;
  15164. {
  15165.      char     *upstr, *cp;
  15166.  
  15167.      cp = cmdstr;
  15168.      *cp++ = type;
  15169.      *cp = NUL;
  15170.      if (*arg1 != NUL) {
  15171.           upstr = bldlen(arg1, cp);
  15172.           if (*arg2 != NUL) {
  15173.                upstr = bldlen(arg2, upstr);
  15174.                if (*arg3 != NUL)
  15175.                     bldlen(arg3, upstr);
  15176.           }
  15177.      }
  15178.      cmarg = cmdstr;
  15179.      if (deblog)
  15180.           debug(F110, "setgen", cmarg, 0);
  15181.  
  15182.      return('g');
  15183. }
  15184.  
  15185.  
  15186. /* C M D N O T I -- Command not implemented message */
  15187.  
  15188. cmdnoti() {
  15189.   int  c;
  15190.  
  15191. #ifndef MCS_FLAG
  15192.     printf("\nV-Kermit does not support: %s.\n",cmdbuf);
  15193. #else
  15194.     sprintf(print_str,"\nV-Kermit does not support: %s.\n",cmdbuf);
  15195.     mcs_printf(print_str);
  15196. #endif
  15197.  
  15198.   if (cmflgs != 1) {
  15199.     /* The command was not terminated with a carriage return. So there
  15200.     must be something following it on the input line.  Since the command
  15201.     was not implemented, we'll flush the rest of the input line. */
  15202.  
  15203.     while ((c = getchar()) != NL && c != CR)  ;
  15204.   }
  15205.   return(0);
  15206. }
  15207.  
  15208.  
  15209. /*  D O C M D  --  Do a command  */
  15210.  
  15211. /*
  15212.  Returns:
  15213.    -2: user typed an illegal command
  15214.    -1: reparse needed
  15215.     0: parse was successful (even tho command may have failed).
  15216. */
  15217.  
  15218. docmd(cx)
  15219. int     cx;
  15220. {
  15221.      int     x, y;
  15222.      char     *s;
  15223.      char     temp[400];
  15224.  
  15225.      switch (cx) {
  15226.      case -4:                                /* EOF */
  15227.           if (!quiet && !backgrd)
  15228. #ifndef MCS_FLAG
  15229.                printf("\r\n");
  15230. #else
  15231.                mcs_printf("\r\n");
  15232. #endif
  15233.           doexit(GOOD_EXIT);
  15234.      case -3:                                /* Null command */
  15235.           return(0);
  15236.      case -2:                                /* Error */
  15237.      case -1:                                /* Reparse needed */
  15238.           return(cx);
  15239.  
  15240.      case XXBYE:                             /* bye */
  15241.           return(cmdnoti());
  15242. /*        if ((x = cmcfm()) < 0)
  15243. *              return(x);
  15244. *         if (!local) {
  15245. *              printf("You have to 'set line' first\n");
  15246. *              return(0);
  15247. *          }
  15248. *         sstate = setgen('L', "", "", "");
  15249. *         return(0);
  15250. */
  15251.      case XXCOM:                             /* comment */
  15252.  
  15253.           if ((x = cmtxt("Text of comment line", "", &s)) < 0)
  15254.                return(x);
  15255.           return(0);
  15256.  
  15257.      case XXCON:                             /* connect */
  15258.           return(cmdnoti());    /* command not implemented */
  15259. /*
  15260.  *        if ((x = cmcfm()) < 0)
  15261.  *             return(x);
  15262.  *        return(doconect());
  15263.  */
  15264.      case XXCWD:                            /* change directory */
  15265.           return(cmdnoti());    /* command not implemented */
  15266. /*
  15267.  *        if (cmtxt("Name of local directory, or carriage return",
  15268.  *             homdir, &s) < 0)
  15269.  *             return(-1);
  15270.  *        if (CHDIR(s)) {
  15271.  *             sprintf(temp, "docmd: %s", s);
  15272.  *             errhdlr(s);
  15273.  *        }
  15274.  *        cwdf = 1;
  15275.  *        return(0);
  15276.  */
  15277.      case XXCLO:
  15278.           x = cmkey(logtab, nlog, "Which log to close", "");
  15279.           if (x == -3) {
  15280. #ifndef MCS_FLAG
  15281.                printf("?You must tell which log\n");
  15282. #else
  15283.                mcs_printf("?You must tell which log\n");
  15284. #endif
  15285.                return(-2);
  15286.           }
  15287.           if (x < 0)
  15288.                return(x);
  15289.           if ((y = cmcfm()) < 0)
  15290.                return(y);
  15291.  
  15292.           switch (x) {
  15293.           case LOGD:
  15294.                if (deblog == 0) {
  15295. #ifndef MCS_FLAG
  15296.                     printf("?Debugging log wasn't open\n");
  15297. #else
  15298.                     mcs_printf("?Debugging log wasn't open\n");
  15299. #endif
  15300.                     return(0);
  15301.                }
  15302.                *debfil = '\0';
  15303.                deblog = 0;
  15304.                return(zclose(ZDFILE));
  15305.  
  15306.           case LOGP:
  15307.                if (pktlog == 0) {
  15308. #ifndef MCS_FLAG
  15309.                     printf("?Packet log wasn't open\n");
  15310. #else
  15311.                     mcs_printf("?Packet log wasn't open\n");
  15312. #endif
  15313.                     return(0);
  15314.                }
  15315.                *pktfil = '\0';
  15316.                pktlog = 0;
  15317.                return(zclose(ZPFILE));
  15318. /*
  15319.  *        case LOGS:
  15320.  *             if (seslog == 0) {
  15321.  *                  printf("?Session log wasn't open\n");
  15322.  *                  return(0);
  15323.  *             }
  15324.  *             *sesfil = '\0';
  15325.  *             seslog = 0;
  15326.  *             return(zclose(ZSFILE));
  15327.  */
  15328.           case LOGT:
  15329.                if (tralog == 0) {
  15330. #ifndef MCS_FLAG
  15331.                     printf("?Transaction log wasn't open\n");
  15332. #else
  15333.                     mcs_printf("?Transaction log wasn't open\n");
  15334. #endif
  15335.                     return(0);
  15336.                }
  15337.                *trafil = '\0';
  15338.                tralog = 0;
  15339.                return(zclose(ZTFILE));
  15340.  
  15341.           default:
  15342. #ifndef MCS_FLAG
  15343.                printf("\n?Unexpected log designator - %ld\n", x);
  15344. #else
  15345.                sprintf(print_str,"\n?Unexpected log designator - %ld\n", x);
  15346.                mcs_printf(print_str);
  15347. #endif
  15348.                return(0);
  15349.           }
  15350.  
  15351.      case XXDIAL:                            /* dial number */
  15352.           return(cmdnoti());      /* command not implemented */
  15353. /*
  15354.  *        if ((x = cmtxt("Number to be dialed", "", &s)) < 0)
  15355.  *             return(x);
  15356.  *        return(ckdial(s));
  15357.  */
  15358.      case XXDIR:                             /* list directory */
  15359.           return(cmdnoti());      /* command not implemented */
  15360. /*
  15361.  *        if ((x = cmtxt("Directory/file specification", ".",
  15362.  *            &s)) < 0)
  15363.  *             return(x);
  15364.  *        lp = line;
  15365.  *        SYSTEM(line);
  15366.  *        return(0);
  15367.  */
  15368.      case XXECH:                             /* echo */
  15369.           if ((x = cmtxt("Material to be echoed", "", &s)) < 0)
  15370.                return(x);
  15371.           for ( ; *s; s++) {
  15372.                if ((x = *s) == 0134) {         /* Convert octal escapes */
  15373.                     s++;                        /* up to 3 digits */
  15374.                     for (x = y = 0; *s >= '0' && *s <= '7' &&
  15375.                         y < 3; s++, y++) {
  15376.                          x = x * 8 + (int) *s - 48;
  15377.                     }
  15378.                     s--;
  15379.                }
  15380.                putchar(x);
  15381.           }
  15382. #ifndef MCS_FLAG
  15383.           printf("\n");
  15384. #else
  15385.           mcs_printf("\n");
  15386. #endif
  15387.           return(0);
  15388.  
  15389.      case XXQUI:                             /* quit, exit */
  15390.      case XXEXI:
  15391.           if ((x = cmcfm()) > -1)
  15392.                doexit(GOOD_EXIT);
  15393.           else
  15394.                return(x);
  15395.  
  15396.      case XXFIN:                             /* finish */
  15397.           return(cmdnoti());    /* command not implemented */
  15398. /*          if ((x = cmcfm()) < 0)
  15399. *               return(x);
  15400. *          if (!local) {
  15401. *               printf("You have to 'set line' first\n");
  15402. *               return(0);
  15403. *          }
  15404. *          sstate = setgen('F', "", "", "");
  15405. */
  15406.  
  15407.      case XXGET:                             /* get */
  15408.           return(cmdnoti());    /* command not implemented */
  15409. /*        if (!local) {
  15410. *              printf("\nYou have to 'set line' first\n");
  15411. *              return(0);
  15412. *         }
  15413. *         x = cmtxt("Name of remote file(s), or carriage return",
  15414. *              "", &cmarg);
  15415. *         if ((x == -2) || (x == -1))
  15416. *              return(x);
  15417. *
  15418. *          * If foreign file name omitted, get
  15419. *            foreign and local names separately *
  15420. *
  15421. *         x = 0;                               * For some reason cmtxt
  15422. *                                                returns 1 *
  15423. *         if (*cmarg == NUL) {
  15424. *
  15425. *              if (tlevel > -1) {               * Input is from take file *
  15426. *
  15427. *                   if (fgets(line, 100, tfile[tlevel]) ==
  15428. *                       NULL)
  15429. *                        fatal("take file ends prematurely in 'get'");
  15430. *                   if (deblog)
  15431. *                        debug(F110, "take-get 2nd line",
  15432. *                             line, 0);
  15433. *                   stripq(line);
  15434. *                   for (x = strlen(line);  x > 0 && (line[x-1] ==
  15435. *                       '\n' || line[x-1] == '\r');  x--)
  15436. *                        line[x-1] = '\0';
  15437. *                   cmarg = line;
  15438. *                   if (fgets(cmdbuf, CMDBL, tfile[tlevel]) ==
  15439. *                       NULL)
  15440. *                        fatal("take file ends prematurely in 'get'");
  15441. *                   stripq(cmdbuf);
  15442. *                   for (x = strlen(cmdbuf);  x > 0 && (cmdbuf[x-1] ==
  15443. *                       '\n' || cmdbuf[x-1] == '\r');  x--)
  15444. *                        cmdbuf[x-1] = '\0';
  15445. *                   if (*cmdbuf == NUL)
  15446. *                        cmarg2 = line;
  15447. *                   else
  15448. *                        cmarg2 = cmdbuf;
  15449. *                   x = 0;                       * Return code *
  15450. *
  15451. *              } else {                         * Input is from terminal *
  15452. *
  15453. *                   char     psave[40];              * Save old prompt *
  15454. *                   cmsavp(psave, 40);
  15455. *                   cmsetp(" Remote file specification: "); * Make new one *
  15456. *                   cmini(ckxech);
  15457. *                   x = -1;
  15458. *                   if (!backgrd)
  15459. *                        prompt();
  15460. *                   while (x == -1) {       * Prompt till they answer *
  15461. *                        x = cmtxt("Name of remote file(s)",
  15462. *                             "", &cmarg);
  15463. *                        if (deblog)
  15464. *                             debug(F111, " cmtxt",
  15465. *                                  cmarg, x);
  15466. *                   }
  15467. *                   if (x < 0) {
  15468. *                        cmsetp(psave);
  15469. *                        return(x);
  15470. *                   }
  15471. *                   if (*cmarg == NUL) {         * If user types a bare CR, *
  15472. *                        printf("(cancelled)\n");  * Forget about this. *
  15473. *                        cmsetp(psave);           * Restore old prompt, *
  15474. *                        return(0);               * and return. *
  15475. *                   }
  15476. *                   strcpy(line, cmarg);          * Make a safe copy *
  15477. *                   cmarg = line;
  15478. *                    * New prompt *
  15479. *                   cmsetp(" Local name to store it under: ");
  15480. *                   cmini(ckxech);
  15481. *                   x = -1;
  15482. *                   if (!backgrd)  prompt();
  15483. *                   while (x == -1) {       * Again, parse till answered *
  15484. *                        x = cmofi("Local file name", "", &cmarg2);
  15485. *                   }
  15486. *                   if (x == -3) {                   * If bare CR, *
  15487. *                        printf("(cancelled)\n");    * escape from this *
  15488. *                        cmsetp(psave);              * Restore old prompt, *
  15489. *                        return(0);                 * and return. *
  15490. *                   } else if (x < 0)
  15491. *                        return(x);         * Handle parse errors. *
  15492. *
  15493. *                   x = -1;                      * Get confirmation. *
  15494. *                   while (x == -1)
  15495. *                        x = cmcfm();
  15496. *                   cmsetp(psave);              * Restore old prompt. *
  15497. *              }
  15498. *         }
  15499. *         if (x == 0) {                       * Good return from cmtxt or
  15500. *                                                cmcfm,                    *
  15501. *              sstate = 'r';                   * set start state. *
  15502. *              if (local)
  15503. *                   displa = 1;
  15504. *         }
  15505. *         return(x);
  15506. */
  15507.      case XXHLP:                             /* Help */
  15508. #ifndef MCS_FLAG
  15509.           x = cmkey(cmdtab, ncmd, "IVS-Kermit command", "help");
  15510. #else
  15511.           x = cmkey(cmdtab, ncmd, "MCS-Kermit command", "help");
  15512. #endif
  15513.           return(dohlp(x));
  15514.  
  15515.      case XXHAN:                             /* Hangup */
  15516.           return(cmdnoti());       /* command not implemented */
  15517. /*
  15518.  *        if ((x = cmcfm()) > -1)
  15519.  *             return(tthang());
  15520.  */
  15521.      case XXLOG:                             /* Log */
  15522.           x = cmkey(logtab, nlog, "What to log", "");
  15523.           if (x == -3) {
  15524. #ifndef MCS_FLAG
  15525.                printf("?You must specify what is to be logged\n");
  15526. #else
  15527.                mcs_printf("?You must specify what is to be logged\n");
  15528. #endif
  15529.                return(-2);
  15530.           }
  15531.           if (x < 0)
  15532.                return(x);
  15533.           return(dolog(x));
  15534.  
  15535.      case XXLOGI:                            /* Send script remote system */
  15536.           return(cmdnoti());       /* command not implemented */
  15537. /*
  15538.  *        if ((x = cmtxt("Text of login script", "", &s)) < 0)
  15539.  *             return(x);
  15540.  *        return( login(s) );                 * Return 0=completed,
  15541.  *                                               -2=failed *
  15542.  */
  15543.  
  15544.      case XXREC:                             /* Receive */
  15545.           return(cmdnoti());    /* command not implemented */
  15546. /*         cmarg2 = "";
  15547. *          x = cmofi("Name under which to store the file, or CR",
  15548. *               "", &cmarg2);
  15549. *          if ((x == -1) || (x == -2))
  15550. *               return(x);
  15551. *          if (deblog)
  15552. *               debug(F111, "cmofi cmarg2", cmarg2, x);
  15553. *          if ((x = cmcfm()) < 0)
  15554. *               return(x);
  15555. *          sstate = 'v';
  15556. *          if (local)
  15557. *               displa = 1;
  15558. *          return(0);
  15559. */
  15560.      case XXREM:                             /* Remote */
  15561.           return(cmdnoti());      /* command not implemented */
  15562. /*
  15563.  *        if (!local) {
  15564.  *             printf("\nYou have to 'set line' first\n");
  15565.  *             return(-2);
  15566.  *        }
  15567.  *        x = cmkey(remcmd, nrmt, "Remote Kermit server command", "");
  15568.  *        if (x == -3) {
  15569.  *             printf("?You must specify a command for the remote server\n");
  15570.  *             return(-2);
  15571.  *        }
  15572.  *        return(dormt(x));
  15573.  */
  15574.      case XXSEN:                             /* Send */
  15575.           return(cmdnoti());    /* command not implemented */
  15576. /*        cmarg = cmarg2 = "";
  15577. *          if ((x = cmifi("File(s) to send", "", &s, &y)) < 0) {
  15578. *               if (x == -3) {
  15579. *                    printf("?A file specification is required\n");
  15580. *                    return(-2);
  15581. *               }
  15582. *               return(x);
  15583. *          }
  15584. *          nfils = -1;                   * Files come from internal list. *
  15585. *          strcpy(line, s);              * Save copy of string just parsed. *
  15586. *          if (deblog)
  15587. *               debug(F101, "Send: wild", "", y);
  15588. *          *cmarg2 = '\0';                     * Initialize send-as name *
  15589. *          if (y == 0) {
  15590. *               if ((x = cmtxt("Name to send it with", "", &cmarg2)) <
  15591. *                   0)
  15592. *                    return(x);
  15593. *          } else {
  15594. *               if ((x = cmcfm()) < 0)
  15595. *                    return(x);
  15596. *          }
  15597. *          cmarg = line;                       * File to send *
  15598. *          if (deblog)
  15599. *               debug(F110, "Sending:", cmarg, 0);
  15600. *          if (*cmarg2 != '\0' && deblog)
  15601. *               debug(F110, " as:", cmarg2, 0);
  15602. *          sstate = 's';                       * Set start state *
  15603. *          if (local)
  15604. *               displa = 1;
  15605. *          return(0);
  15606. */
  15607.      case XXSER:                             /* Server */
  15608.           if ((x = cmcfm()) < 0)
  15609.                return(x);
  15610.           sstate = 'x';
  15611.           if (local)
  15612.                displa = 1;
  15613.           return(0);
  15614.  
  15615.      case XXSET:                             /* Set */
  15616.           x = cmkey(prmtab, nprm, "Parameter", "");
  15617.           if (x == -3) {
  15618. #ifndef MCS_FLAG
  15619.                printf("?You must specify a parameter to set\n");
  15620. #else
  15621.                mcs_printf("?You must specify a parameter to set\n");
  15622. #endif
  15623.                return(-2);
  15624.           }
  15625.           if (x < 0)
  15626.                return(x);
  15627.           return(doprm(x));
  15628.  
  15629.  /* XXSHE code by H. Fischer; copyright rights assigned to Columbia Univ */
  15630.  /*
  15631.  Adapted to use getpwuid to find login shell because many systems do not
  15632.  have SHELL in environment, and to use direct calling of shell rather
  15633.  than intermediate system() call. -- H. Fischer
  15634.  */
  15635.      case XXSHE:                             /* Local shell command */
  15636.            return(cmdnoti());       /* command not implemented */
  15637. /*
  15638.  *         {
  15639.  *             int     pid;
  15640.  *             if (cmtxt("NCR-VRX shell command to execute",
  15641.  *                  "", &s) < 0)
  15642.  *                  return(-1);
  15643.  *             conres();                           * Make console normal  *
  15644.  *
  15645.  *             SYSTEM("x :cli prefix Kermit_Baby:");
  15646.  *
  15647.  *             if ((pid = FORK()) == 0) {          * Make child *
  15648.  *                  char     *shpath, *shname, *shptr;
  15649.  *                                        * For finding desired shell *
  15650.  *                  struct passwd *p;
  15651.  *                  extern struct passwd *GETPWUID();
  15652.  *                  extern int     GETUID();
  15653.  *                  char     *defShel = "/bin/sh";      * Default *
  15654.  *
  15655.  *                  p = GETPWUID( GETUID() );       * Get login data *
  15656.  *                  if ( p == (struct passwd *) NULL ||
  15657.  *                      !*(p->pw_shell) )
  15658.  *                       shpath = defShel;
  15659.  *                  else
  15660.  *                       shpath = p->pw_shell;
  15661.  *                  shptr = shname = shpath;
  15662.  *                  while (*shptr != '\0')
  15663.  *                       if (*shptr++ == '/')
  15664.  *                            shname = shptr;
  15665.  *
  15666.  *                  * Remove following uid calls if they cause trouble *
  15667.  *
  15668.  *                  if (*s == NUL)          * Interactive shell requested? *
  15669.  *                       EXECL(shpath, shname, "-i",
  15670.  *                           NULL);    * Yes, do that *
  15671.  *                  else * Otherwise, *
  15672.  *                       EXECL(shpath, shname, "-c",
  15673.  *                           s, NULL); * exec the given command *
  15674.  *                  exit(BAD_EXIT);
  15675.  *             }               * Just punt if it didn't work *
  15676.  *                 else {                             * Parent *
  15677.  *
  15678.  *                  int     wstat;          * Kermit must wait for child *
  15679.  *                  SIGTYP (*istat)(), (*qstat)();
  15680.  *
  15681.  *                  istat = SIGNAL(SIGINT, SIG_IGN); * Let the fork handle
  15682.  *                                                      keyboard          *
  15683.  *                  qstat = SIGNAL(SIGQUIT, SIG_IGN); * interrupts itself *
  15684.  *
  15685.  *                  while (((wstat = WAIT((int *)0)) !=
  15686.  *                      pid) && (wstat != -1))
  15687.  *                       ;
  15688.  *                  * Wait for fork *
  15689.  *                  SIGNAL(SIGINT, istat);           * Restore interrupts *
  15690.  *                  SIGNAL(SIGQUIT, qstat);
  15691.  *             }
  15692.  *             concb(escape);                      * Console back in cbreak
  15693.  *                                                    mode                *
  15694.  *             return(0);
  15695.  *        }
  15696.  */
  15697.      case XXSHO:                             /* Show */
  15698.           x = cmkey(shotab, 2, "", "parameters");
  15699.           if (x < 0)
  15700.                return(x);
  15701.           if ((y = cmcfm()) < 0)
  15702.                return(y);
  15703.           switch (x) {
  15704.  
  15705.           case SHPAR:
  15706.                shopar();
  15707.                break;
  15708.  
  15709.           case SHVER:
  15710. #ifndef MCS_FLAG
  15711.                printf("\nVersions:\n %s\n %s\n", versio, protv);
  15712.                printf(" %s\n", fnsv);
  15713.                printf(" %s\n %s\n", cmdv, userv);
  15714.                printf(" %s for%s\n", ckxv, ckxsys);
  15715.                printf(" %s for%s\n", ckzv, ckzsys);
  15716. #else
  15717.                sprintf(print_str,"\nVersions:\n %s\n %s\n", versio, protv);
  15718.                mcs_printf(print_str);
  15719.                sprintf(print_str," %s\n", fnsv);
  15720.                mcs_printf(print_str);
  15721.                sprintf(print_str," %s\n %s\n", cmdv, userv);
  15722.                mcs_printf(print_str);
  15723.                sprintf(print_str," %s for%s\n", ckxv, ckxsys);
  15724.                mcs_printf(print_str);
  15725.                sprintf(print_str," %s for%s\n", ckzv, ckzsys);
  15726.                mcs_printf(print_str);
  15727. #endif
  15728.                break;
  15729.  
  15730.           default:
  15731.                printf("\nNothing to show...\n");
  15732.                break;
  15733.           }
  15734.           return(0);
  15735.  
  15736.      case XXSPA:                             /* space */
  15737.           return(cmdnoti());       /* command not implemented */
  15738. /*
  15739.  *        if ((x = cmcfm()) < 0)
  15740.  *             return(x);
  15741.  *        return(0);
  15742.  */
  15743.      case XXSTA:                             /* statistics */
  15744.           if ((x = cmcfm()) < 0)
  15745.                return(x);
  15746.           return(dostat());
  15747.  
  15748.      case XXTAK:                             /* take */
  15749.           if (tlevel > MAXTAKE - 1) {
  15750. #ifndef MCS_FLAG
  15751.                printf("?Take files nested too deeply\n");
  15752. #else
  15753.                mcs_printf("?Take files nested too deeply\n");
  15754. #endif
  15755.                return(-2);
  15756.           }
  15757. #ifndef MCS_FLAG
  15758.           if ((y = cmifi("IVS-Kermit command file", "", &s, &x)) <
  15759. #else
  15760.           if ((y = cmifi("MCS-Kermit command file", "", &s, &x)) <
  15761. #endif
  15762.               0) {
  15763.                if (y == -3) {
  15764. #ifndef MCS_FLAG
  15765.                     printf("?A file specification is required\n");
  15766. #else
  15767.                     mcs_printf("?A file specification is required\n");
  15768. #endif
  15769.                     return(-2);
  15770.                } else
  15771.                     return(y);
  15772.           }
  15773.           if (x != 0) {
  15774. #ifndef MCS_FLAG
  15775.                printf("?Wildcards not allowed in command file name\n");
  15776. #else
  15777.                mcs_printf("?Wildcards not allowed in command file name\n");
  15778. #endif
  15779.                return(-2);
  15780.           }
  15781.           strcpy(line, s);        /* Make a safe copy of the string */
  15782.           if ((y = cmcfm()) < 0)
  15783.                return(y);
  15784.           if ((tfile[++tlevel] = fopen(line, "r")) == NULL) {
  15785.                sprintf(temp, "docmd: %s", line);
  15786.                errhdlr(temp);
  15787.                if (deblog)
  15788.                     debug(F110, "Failure to open", line, 0);
  15789.                tlevel--;
  15790.           }
  15791.           return(0);
  15792.  
  15793.      default:
  15794. #ifndef MCS_FLAG
  15795.           printf("V-Kermit does not support: %s\n", cmdbuf);
  15796. #else
  15797.           sprintf(print_str,"V-Kermit does not support: %s.\n",cmdbuf);
  15798.           mcs_printf(print_str);
  15799. #endif
  15800.           return(-2);
  15801.      }
  15802. }
  15803.  
  15804.  
  15805. /*  D O C O N E C T  --  Do the connect command  */
  15806.  
  15807. /*  Note, we don't call this directly from dial, because we need to give */
  15808. /*  the user a chance to change parameters (e.g. parity) after the */
  15809. /*  connection is made. */
  15810.  
  15811. doconect()
  15812. {
  15813.      int     x;
  15814.      conres();                           /* Put console back to normal */
  15815.      x = conect();                       /* Connect */
  15816.      concb(escape);                      /* Put console into cbreak mode, */
  15817.      return(x);                          /* for more command parsing. */
  15818. }
  15819. <<< compile.ins >>>
  15820. IVS-Kermit cOmpilation instructions:
  15821.  
  15822. From an IVS session or SCL procedure file:
  15823.  
  15824. REC (L=2500,V=1500,STAC=250,PROT=600);
  15825.  
  15826. CC(FN=FILENAME_C,LNK=NO,OPTM=TRUE,GLBOPT='-R -o FILENAME_O',
  15827.    POPT='-bo -X1',COPT='-b -Xv');!"
  15828.  
  15829. ***NOTE***
  15830.     IVS-Kermit object modules end in _O. MCS-Kermit modules
  15831.         end in _M. This is done to separate MCS-Kermit object
  15832.         from IVS-Kermit object. There are several common object
  15833.         modules between MCS / IVS-Kermit, they do not require the
  15834.         _M convention. Any naming convention is exceptable,
  15835.         as long as the modules are separated.
  15836.         The common object modules are listed below.
  15837.  
  15838.         Common object modules:
  15839.  
  15840.           BIND=CKVFN2_O
  15841.           BIND=CKVFNS_O
  15842.           BIND=CKVFI2_O
  15843.           BIND=CKVFIO_O
  15844.           BIND=VKNCRLIO  NCRL source module
  15845.           BIND=CKVMCS_O  *** COMPILE USING IVS INSTRUCTIONS
  15846.           BIND=CKVBUF_O  *** COMPILE USING IVS INSTRUCTIONS
  15847.  
  15848. MCS-Kermit compilation instructions:
  15849.  
  15850. From an IVS session or SCL procedure file:
  15851.  
  15852. REC (L=2500,V=1500,STAC=250,PROT=600);
  15853.  
  15854. CC(FN=FILENAME_C,LNK=NO,OPTM=TRUE,GLBOPT='-R -o FILENAME_M',
  15855.    POPT='-bo -X1 -D MCS_FLAG',COPT='-b -Xv');!"
  15856. <<< ivskpm.pro >>>
  15857. PROCEDURE IVSKPM(COMMAND : STRING := '  ');
  15858. %
  15859. % ************************
  15860. % *  COPYRIGHT NCR CORP. *
  15861. % *    DAYTON, OHIO      *
  15862. % *    1990              *
  15863. % ************************
  15864. %
  15865. % *************************************************
  15866. % *
  15867. % * THIS SCL PROCEDURE FILE INITIALIZES IVS-KERMIT
  15868. % *   FOR TRANSFERRING
  15869. % *   FILES TO THE CATALOG OR SUD=D02
  15870. % *
  15871. % * CREATED BY THE V-KERMIT PROJECT TEAM ON 8-18-89
  15872. % *
  15873. % *
  15874. % *************************************************
  15875. %
  15876. DISPLAY : '  BEGINNING IVSKPM FOR IVS-KERMIT FILE TRANSFERS.';
  15877. DISPLAY : '    FOR GENERIC FILE USE.';
  15878. DISPLAY : '    UPDATED ON 6-20-90.';
  15879. DISPLAY : ' ';
  15880. DISPLAY : '  IVS-KERMIT 2.01 NOW HANDLES:';
  15881. DISPLAY : '    1000 BYTE PACKETS.';
  15882. DISPLAY : ' ';
  15883. DISPLAY : '  MOVE kermrc TO YOUR';
  15884. DISPLAY : '    SOURCE/DESTINATION CATALOG NODE';
  15885. DISPLAY : '    AND SUD=D02';
  15886. DISPLAY : '    BEFORE CONTINUING.';
  15887. DISPLAY : ' ';
  15888. DISPLAY : '  REFER TO THE V-KERMIT FS FOR MS-DOS FILE NAME EXTENSIONS';
  15889. DISPLAY : '    USED FOR VRX FILES.';
  15890. DISPLAY : ' ';
  15891. DISPLAY : '    EXAMPLES ARE: FN.N3(JOB),FN.PRO(SCL PROC),FN.C(C),';
  15892. DISPLAY : '      FN.CO(COBOL),FN.NCR(NCRL),FN.NC(NEAT/C),';
  15893. DISPLAY : '      FN.BIN(BINARY DATA FILE).';
  15894. DISPLAY : '    OBJECT FILES(USE FN.OBJ).';
  15895. DISPLAY : ' ';
  15896. DISPLAY : '  WARNINGS:';
  15897. DISPLAY : '    IF YOUR IVS SESSION USES A DSP COMM PORT,';
  15898. DISPLAY : '    MAX PACKET SIZE IS 222.';
  15899. DISPLAY : ' ';
  15900. %
  15901. % *************************************************
  15902. % * VARIABLE DEFINITIONS
  15903. % *************************************************
  15904. %
  15905. LOCAL
  15906.   MSG       : STRING,
  15907.   ENV       : STRING,
  15908.   VSN       : STRING,
  15909.   DTYPE     : STRING,
  15910.   VOL_INT   : INTEGER,
  15911.   NODE      : STRING,
  15912.   NODENAME  : NAME,
  15913.   ACTION    : STRING,
  15914.   P1        : PROCESS,
  15915.   VMEM_IVSK : INTEGER,
  15916.   LDSA_IVSK : INTEGER,
  15917.   PDSA_IVSK : INTEGER,
  15918.   FILESIZ   : STRING,
  15919.   RSTRT_FLAG: BOOLEAN,
  15920.   DEFAULTS  : STRING,
  15921.   ORG_CHOICE : STRING,
  15922.   REC_TYPE  : STRING;
  15923. %
  15924. % *************************************************
  15925. %
  15926. RSTRT_FLAG := FALSE;
  15927. FILESIZ := '500';
  15928. % FILEL CAT/NOCAT;
  15929. % FILEC CAT;
  15930. %
  15931. DISPLAY : '  PLEASE WAIT.';
  15932. BEGIN
  15933. %
  15934. IF (MYJOB(VMAXMEM) < 800);
  15935. THEN
  15936.  MYJOB(VMAXMEM) := 800;
  15937.  DISPLAY : '  TOO LITTLE VMAXMEM,';
  15938.  DISPLAY : '    VMAXMEM HAS BEEN SET TO 800.';
  15939.  RSTRT_FLAG := TRUE;
  15940.  VMEM_IVSK := 800;
  15941. ELSE
  15942. VMEM_IVSK := MYJOB(VMAXMEM);
  15943. IFEND;
  15944. %
  15945. IF (MYJOB(LOCALDSA) < 1000);
  15946. THEN
  15947.  MYJOB(LOCALDSA) := 1000;
  15948.  DISPLAY : '  TOO LITTLE LOCALDSA,';
  15949.  DISPLAY : '    LOCALDSA HAS BEEN SET TO 1000.';
  15950.  RSTRT_FLAG := TRUE;
  15951.  LDSA_IVSK := 1000;
  15952. ELSE
  15953. LDSA_IVSK := MYJOB(LOCALDSA);
  15954. IFEND;
  15955. %
  15956. IF (MYJOB(PROTECTDSA) < 800);
  15957. THEN
  15958.  MYJOB(PROTECTDSA) := 800;
  15959.  DISPLAY : '  TOO LITTLE PROTECTDSA,';
  15960.  DISPLAY : '    PROTECTDSA HAS BEEN SET TO 800.';
  15961.  RSTRT_FLAG := TRUE;
  15962.  PDSA_IVSK := 800;
  15963. ELSE
  15964. PDSA_IVSK := MYJOB(PROTECTDSA);
  15965. IFEND;
  15966. %
  15967. IF (RSTRT_FLAG = TRUE);
  15968. THEN
  15969.  RSTRT_FLAG := FALSE;
  15970.  DISPLAY : '  RE-EXECUTE IVSKP.';
  15971. REC(V=#VMEM_IVSK,LOCALDSA=#LDSA_IVSK,PROTECTDSA=#PDSA_IVSK);
  15972. RETURN : '  END OF IVSKP.';
  15973. IFEND;
  15974. %
  15975. END;
  15976. %
  15977. % *********************************************
  15978. % * SOLICITATION OF SETUP OPTIONS FOR MICKEY
  15979. % *   USER ACCEPTS DEFAULTS(DEFAULTS IN PARENS)?
  15980. % *     -FILE SOURCE/DEST(CAT)
  15981. % *       -NODE(USER CURRENT)
  15982. % *       -VOLUME/TYPE(CURRENT D02)
  15983. % *     -FILE SPECIFICATIONS FOR REF=DATAFILE
  15984. % *       -PRINTER FONT/FORM UPLOADS(NO)
  15985. % *       -FILESIZE FOR D02 AND FONT/FORMS(500 BLOCKS)
  15986. % *       -FIXED LENGTH DATAFILE RECORDS(NO)
  15987. % *
  15988. % *******************************************************
  15989. %
  15990. %
  15991. DISPLAY : '  PLEASE WAIT.';
  15992. BEGIN
  15993. %
  15994. %  ******************************************************
  15995. %  * ASKING USER FOR ACCEPTANCE OF DEFAULTS
  15996. %  *
  15997. %  ******************************************************
  15998. %
  15999.    DISPLAY : ' ';
  16000.    DISPLAY : ' ';
  16001.    DISPLAY : '  PLEASE SELECT THE IVS-KERMIT ENVIRONMENT.';
  16002.    DISPLAY : ' ';
  16003.    DISPLAY : '    THE IVS-KERMIT ENVIRONMENT DEFAULTS ARE:';
  16004.    DISPLAY : ' ';
  16005.    DISPLAY : '      DATA FILES WITH:';
  16006.    DISPLAY : '      - SEQUENTIAL ORGANIZATION.';
  16007.    DISPLAY : '        (THERE IS A CHOICE FOR RELATIVE(FONT/FORM) ';
  16008.    DISPLAY : '         FILE STRUCTURE.)';
  16009.    DISPLAY : '      - FILESIZE OF 500/BLOCKS  ';
  16010.    DISPLAY : '      - VARIABLE LENGTH RECORDS ';
  16011.    DISPLAY : '  ';
  16012.    DISPLAY : '      FILE SOURCE/DESTINATION OF:';
  16013.    DISPLAY : '      - USER CURRENT NODE IN CATALOG.';
  16014.    DISPLAY : ' ';
  16015.    DISPLAY : '    DO YOU WANT TO ACCEPT THESE DEFAULTS? [Y,N]';
  16016.    DISPLAY : '      DEFAULT IS YES.';
  16017.    ACCEPT DEFAULTS;
  16018. %
  16019.    IF (SUBSTRING(DEFAULTS,0,1) /= 'N')
  16020.      THEN
  16021.      DEFAULTS := 'YES';
  16022.      ENV := 'CAT';
  16023.      REC_TYPE := 'VAR';
  16024.      ORG_CHOICE := 'NO';
  16025.      FILESIZ := '500';
  16026.      GOTO TAG5;
  16027.    IFEND;
  16028. %
  16029. %
  16030. %
  16031. %  *******************************************************
  16032. %  * DEFAULTS NOT ACCEPTED
  16033. %  *******************************************************
  16034.    DISPLAY : '  WILL YOU UPLOAD PRINTER FONT/FORM FILES? [Y,N]';
  16035.    DISPLAY : '    IF YES, ALL DATA FILES WILL HAVE';
  16036.    DISPLAY : '      THE RELATIVE ORGANIZATION.';
  16037.    DISPLAY : '    DEFAULT IS NO.';
  16038.    ACCEPT ORG_CHOICE;
  16039. %
  16040.    IF (SUBSTRING(ORG_CHOICE,0,1) = 'Y')
  16041.      THEN
  16042.      ORG_CHOICE := 'YES';
  16043.      REC_TYPE := 'VAR';
  16044.    ELSE
  16045.    ORG_CHOICE := 'NO';
  16046. %
  16047. %  ****************************************************
  16048. %  * ASKING FOR FIXED/VARIABLE RECORD TYPE.
  16049. %  ****************************************************
  16050.    DISPLAY : '  DO YOU WANT DATAFILES TO HAVE FIXED OR';
  16051.    DISPLAY : '    VARIABLE LENGTH RECORDS? [F,V]';
  16052.    DISPLAY : '    DEFAULT IS VARIABLE.';
  16053.    ACCEPT REC_TYPE;
  16054. %
  16055.    IF (SUBSTRING(REC_TYPE,0,1) /= 'F')
  16056.      THEN
  16057.      REC_TYPE := 'VAR';
  16058.    ELSE
  16059.    REC_TYPE := 'FIX';
  16060.    IFEND;
  16061. %
  16062.    IFEND;
  16063. %
  16064. %  ******************************************************
  16065. %  * ASKING FOR FILE SOURCE/DESTINATION.
  16066. %  ******************************************************
  16067. %
  16068. $TAG2
  16069.    DISPLAY : '  SELECT IVS-KERMIT SOURCE/DESTINATION ENVIRONMENT. ' ;
  16070.    MSG := '    DEFAULT ENVIRONMENT IS CATALOG. [CAT,DISK]';
  16071.    DISPLAY : MSG;
  16072.    ACCEPT ENV;
  16073. %
  16074.    IF ((SUBSTRING(ENV,0,1) /= 'C') AND (SUBSTRING(ENV,0,1) /= 'D') AND
  16075.        (SUBSTRING(ENV,0,1) /= '')) THEN
  16076.      GOTO TAG2;
  16077.    IFEND;
  16078. %
  16079.    IF ((SUBSTRING(ENV,0,1) = 'C') OR (SUBSTRING(ENV,0,1) = '')) THEN
  16080. %  ******************************************************
  16081. %  * CATALOG SELECTED;ASKING FOR NODE.
  16082. %  ******************************************************
  16083. $TAG3
  16084.      DISPLAY : '  PLEASE ENTER SUBCATALOG NODE NAME.  ' ;
  16085.      DISPLAY : '  USE SINGLE QUOTES. EX: ''$.NODE.NODE''.';
  16086.      MSG := '    DEFAULT IS THE USER CURRENT NODE.';
  16087.      DISPLAY : MSG;
  16088.      ACCEPT NODE;
  16089. %
  16090.      IF (NODE = '') THEN
  16091.        GOTO TAG5;
  16092.      ELSE
  16093.        NODENAME := #NODE;
  16094.        FILENODE #NODENAME [P1];
  16095.      IFEND;
  16096. %
  16097.      IF (P1(STATUS) /= COMPLETED) THEN
  16098.        DISPLAY : '  CANT POSITION TO ' & #NODE & '.';
  16099.        MSG := '    DO YOU WANT TO TRY ANOTHER SUBCATALOG? [Y,N].';
  16100.        DISPLAY : MSG;
  16101.        ACCEPT ACTION;
  16102. %
  16103.        IF (SUBSTRING(ACTION,0,1) = 'N') THEN
  16104.          RETURN : '  END OF IVSKPM';
  16105.        ELSE
  16106.          GOTO TAG3;
  16107.        IFEND;
  16108. %
  16109.      IFEND;
  16110. %
  16111. $TAG5
  16112.      DISPLAY : ' ';
  16113.      DISPLAY :'  IVS-KERMIT USING CATALOG ENVIRONMENT.' ;
  16114. %    * FILEC OF CAT IS TO KNOW WHERE STDERR WILL BE.
  16115.      FILEC CAT;
  16116.      FILEN;
  16117. %
  16118.      IF (SUBSTRING(ORG_CHOICE,0,1) = 'Y')
  16119.        THEN
  16120. %
  16121. %      *********************************************
  16122. %      * FILE 'REFERENCE' OF 'DATAFILE' IS USED FOR
  16123. %      *   FONT/FORM FILES
  16124. %      *
  16125. %      * FILESIZE MUST BE FOR THE LARGEST
  16126. %      *   FILE ANTICIPATED BECAUSE RELATIVE FILES ARE NOT RMS.
  16127. %      *
  16128. %      ************************************************
  16129. %
  16130. %
  16131.        IF (DEFAULTS /= 'YES')
  16132.          THEN
  16133. %        *********************************************
  16134. %        * ASKING ABOUT FILE SIZE
  16135. %        * IN THE CATALOG,VARIABLE,FONT/FORM CASE.
  16136. %        *
  16137. %        *   FONT/FORM FILES
  16138. %        *
  16139. %        * FILESIZE MUST BE FOR THE LARGEST
  16140. %        *   FILE ANTICIPATED BECAUSE RELATIVE FILES
  16141. %        *   ARE NOT RMS.
  16142. %        *
  16143. %        ************************************************
  16144. %
  16145. %
  16146.          DISPLAY : ' ';
  16147.          DISPLAY : '  SPECIFY FILESIZE VALUE FOR DATAFILE REFERENCE';
  16148.          DISPLAY : '    THAT IS BIG ENOUGH TO HOLD THE LARGEST ';
  16149.          DISPLAY : '    FONT/FORM FILE TO BE UPLOADED.';
  16150.          DISPLAY : '    DEFAULT FILESIZE IS 500/BLOCKS.';
  16151.          ACCEPT FILESIZ;
  16152. %
  16153.          IF ((SUBSTRING(FILESIZ,0,1) = '') OR (SUBSTRING(FILESIZ,0,1) = 'A'))
  16154.            THEN
  16155.            FILESIZ := '500';
  16156.          IFEND;
  16157. %
  16158.        IFEND;
  16159. %
  16160. %      ************************************************
  16161. %      * ASSIGNING REF=DATAFILE
  16162. %      * IN THE FONT/FORM CASE USING CATALOG.
  16163. %      ************************************************
  16164.        ASSIGN FILE DATAFILE(REF=DATAFILE,
  16165. %                ************************************
  16166. %                *  THE FOLLOWING 5 PARAMETERS ARE
  16167. %                *    FOR FONT/FORM UPLOADS
  16168. %                ************************************
  16169.                  ORGANIZATION=RELATIVE,
  16170.                  BLOCKSIZE=1/RECORDS,
  16171.                  CAMHEADER,
  16172.                  RECORDSIZE=1/485,
  16173.                  FILESIZE=#FILESIZ/BLOCKS,
  16174.                  DATESCHEME=GEN,FILETYPE=DATA,FREEUP,CATALOG);
  16175.      ELSE
  16176. %
  16177.      IF (SUBSTRING(REC_TYPE,0,1) = 'F')
  16178.        THEN
  16179. %
  16180. %      ************************************************
  16181. %      * ASSIGNING REF=DATAFILE
  16182. %      * IN THE FIXED LENGTH RECORDS, NON FONT/FORM
  16183. %      * CASE USING CATALOG.
  16184. %      ************************************************
  16185.        ASSIGN FILE DATAFILE(REF=DATAFILE,RMS=YES,
  16186. %                ************************************
  16187. %                *  THE FOLLOWING PARAMETERS ARE
  16188. %                *    FOR FIXED LENGTH RECORDS
  16189. %                ************************************
  16190.                  RECORDSIZE=80,
  16191.                  DATESCHEME=GEN,FILETYPE=DATA,FREEUP,CATALOG);
  16192.      ELSE
  16193. %
  16194. %    *******************************************
  16195. %    * FILE 'REFERENCE' OF 'DATAFILE' IS USED FOR
  16196. %    *   BINARY AND TEXT 'DATA' FILES
  16197. %    *
  16198. %    *
  16199. %    *******************************************
  16200. %
  16201. %
  16202. %    ************************************************
  16203. %    * ASSIGNING REF=DATAFILE
  16204. %    * IN THE VARIABLE LENGTH RECORDS, NON FONT/FORM
  16205. %    * CASE USING CATALOG.
  16206. %    *
  16207. %    * THIS IS CONSIDERED TO BE THE OVERALL
  16208. %    * DEFAULT CASE.
  16209. %    *
  16210. %    ************************************************
  16211.      ASSIGN FILE DATAFILE(REF=DATAFILE,RMS=YES,
  16212.                  RECORDSIZE=1/485,
  16213.                  DATESCHEME=GEN,FILETYPE=DATA,FREEUP,CATALOG);
  16214.      IFEND;
  16215. %
  16216.      IFEND;
  16217. %    ****************************************************
  16218. %    * ASSIGNING THE OTHER FILE REFERENCES IN THE
  16219. %    * CATALOG CASE.
  16220. %    ****************************************************
  16221.      ASSIGN FILE SRCFILE(REF=SRCFILE,RMS=YES,FILESIZE='NO LIMIT',
  16222.                  RECORDSIZE=1/83,
  16223.                  DATESCHEME=GEN,FILETYPE=SOURCE,FREEUP,CATALOG),
  16224.             FILE OBJFILE(REF=OBJFILE,RMS=YES,FILESIZE='NO LIMIT',
  16225.                  RECORDSIZE=1/490,
  16226.                  DATESCHEME=GEN,FILETYPE=OBJECT,FREEUP,CATALOG),
  16227.             FILE CSFILE(REF=CSFILE,RMS=YES,FILESIZE='NO LIMIT',
  16228.                  FREEUP,DATESCHEME=GEN,
  16229.                  RECORDSIZE=1/82,
  16230.                  FILETYPE='CONTROL STRING',CATALOG);
  16231. %    ****************************************************
  16232. %    * END OF THE CATALOG CASE.
  16233. %    ****************************************************
  16234.    ELSE
  16235. %  ******************************************************
  16236. %  * BEGINNING OF THE SUD=D02 CASE.
  16237. %  ******************************************************
  16238.      DISPLAY : ' ';
  16239.      DISPLAY :'  IVS-KERMIT USING NON-CATALOG ENVIRONMENT.' ;
  16240. $TAG4
  16241. %  ******************************************************
  16242. %  * ASKING ABOUT SUD=D02.
  16243. %  ******************************************************
  16244.      DI PER;
  16245.      DISPLAY : '  PLEASE ENTER(IN QUOTES) VOLUME NUMBER AND DEVICE TYPE.' ;
  16246.      DISPLAY : '    FOR EXAMPLE (''525252/BA'')';
  16247.      DISPLAY : '    OR [CONTINUE] TO USE CURRENT D02.';
  16248.      ACCEPT VSN;
  16249. %
  16250.      IF (SUBSTRING(VSN,0,1) = 'C')
  16251.        THEN
  16252.        DISPLAY : '  IVS-KERMIT USING CURRENT D02.';
  16253.      ELSE
  16254.      VOL_INT := INT(SUBSTRING(VSN,0,6));
  16255.      DTYPE := SUBSTRING(VSN,7,2);
  16256.      ASSIGN UNIT D02(SUD=D02,VOL=#VOL_INT,TYPE=#DTYPE) [P1];
  16257. %
  16258.      IF (P1(STATUS) /= COMPLETED) THEN
  16259.        DISPLAY : '  CANT ASSIGN VOLUME ' & SUBSTRING(VSN,0,6) &
  16260.               ' WITH DEVICE TYPE ' & DTYPE & '.    ' ;
  16261.        MSG := '    DO YOU WANT TO TRY ANOTHER VOLUME?  ';
  16262.        DISPLAY : MSG;
  16263.        DISPLAY : '    OR CONTINUE WITH CURRENT D02?  [Y,N,CONTINUE]';
  16264.        ACCEPT ACTION;
  16265. %
  16266.        IF (SUBSTRING(ACTION,0,1) = 'N') THEN
  16267.          RETURN : '  END OF IVSKPM';
  16268.        ELSE
  16269. %
  16270.        IF (SUBSTRING(ACTION,0,1) /= 'C')
  16271.          THEN
  16272.          GOTO TAG4;
  16273.        ELSE
  16274.        VSN := '';
  16275.        DISPLAY : ' ';
  16276.        DISPLAY : '  IVS-KERMIT USING CURRENT D02.';
  16277.        IFEND;
  16278. %
  16279.        IFEND;
  16280. %
  16281.      ELSE
  16282. %
  16283.      IF(VSN /= '')
  16284.        THEN
  16285.        DISPLAY : ' ';
  16286.        DISPLAY : '  IVS-KERMIT USING VOLUME ' & #VSN & '.';
  16287.      IFEND;
  16288. %
  16289.      IFEND;
  16290. %
  16291.      IFEND;
  16292. %    *******************************************
  16293. %    * ASKING ABOUT FILE SIZE
  16294. %    * IN THE D02 CASE.
  16295. %    *
  16296. %    *
  16297. %    *
  16298. %    *
  16299. %    *******************************************
  16300. %
  16301. %
  16302. %    *********************************************
  16303. %    * FILE 'REFERENCE' OF 'DATAFILE' IS USED FOR
  16304. %    *   BINARY AND TEXT 'DATA' FILES
  16305. %    *
  16306. %    * FILESIZE MUST BE FOR THE LARGEST
  16307. %    *   FILE ANTICIPATED
  16308. %    *
  16309. %    ************************************************
  16310. %
  16311. %
  16312.      DISPLAY : ' ';
  16313.      DISPLAY : '  ENSURE THAT ENOUGH SPACE EXISTS ON D02';
  16314.      DISPLAY : '    FOR THE LARGEST UPLOADED FILE.';
  16315.      DISPLAY : '  ENSURE THAT THE D02 DATAFILE FILESIZE PARAMETER';
  16316.      DISPLAY : '    IS BIG ENOUGH TO HOLD THE LARGEST FILE.';
  16317.      DISPLAY : ' ';
  16318.      DISPLAY : '  SPECIFY FILESIZE VALUE FOR D02 DATAFILE REFERENCE';
  16319.      DISPLAY : '    USED BY DATA FILES.';
  16320.      DISPLAY : '    DEFAULT FILESIZE IS 500/BLOCKS.';
  16321.      ACCEPT FILESIZ;
  16322. %
  16323.      IF ((SUBSTRING(FILESIZ,0,1) = '') OR (SUBSTRING(FILESIZ,0,1) = 'A'))
  16324.        THEN
  16325.        FILESIZ := '500';
  16326.      IFEND;
  16327. %
  16328.      IF (SUBSTRING(ORG_CHOICE,0,1) = 'Y')
  16329.        THEN
  16330. %
  16331. %
  16332. %      ************************************************
  16333. %      * ASSIGNING REF=DATAFILE
  16334. %      * IN THE FONT/FORM CASE USING D02.
  16335. %      ************************************************
  16336.        ASSIGN FILE DATAFILE(REF=DATAFILE,RMS=NO,SUD=D02,FREEUP,
  16337.                  DATESCHEME=GEN,NOCAT,
  16338.                  FILESIZE=#FILESIZ/BLOCKS,
  16339. %                ************************************
  16340. %                *  THE FOLLOWING 4 PARAMETERS ARE
  16341. %                *    FOR FONT/FORM UPLOADS
  16342. %                ************************************
  16343.                  ORGANIZATION=RELATIVE,
  16344.                  BLOCKSIZE=1/RECORDS,
  16345.                  CAMHEADER,
  16346.                  RECORDSIZE=1/485,
  16347.                  FILETYPE=DATA);
  16348.      ELSE
  16349. %
  16350.      IF (SUBSTRING(REC_TYPE,0,1) = 'F')
  16351.        THEN
  16352. %
  16353. %
  16354. %      ************************************************
  16355. %      * ASSIGNING REF=DATAFILE
  16356. %      * IN THE FIXED LENGTH RECORD, NON FONT/FORM CASE
  16357. %      * USING D02.
  16358. %      *
  16359. %      * THIS IS CONSIDERED TO BE THE
  16360. %      * 'FIXED ACQUISITION' CASE.
  16361. %      ************************************************
  16362.  
  16363.        ASSIGN FILE DATAFILE(REF=DATAFILE,RMS=NO,SUD=D02,FREEUP,
  16364.                    DATESCHEME=GEN,NOCAT,
  16365.                    FILESIZE=#FILESIZ/BLOCKS,
  16366. %                  ************************************
  16367. %                  *  THE FOLLOWING PARAMETERS ARE
  16368. %                  *    FOR FIXED LENGTH RECORDS
  16369. %                  ************************************
  16370.                    RECORDSIZE=80,
  16371.                    FILETYPE=DATA);
  16372.      ELSE
  16373. %
  16374. %
  16375. %    ************************************************
  16376. %    * ASSIGNING REF=DATAFILE
  16377. %    * IN THE VARIABLE LENGTH RECORD, NON FONT/FORM
  16378. %    * CASE USING D02.
  16379. %    ************************************************
  16380. %
  16381. %    *******************************************
  16382. %    * FILE 'REFERENCE' OF 'DATAFILE' IS USED FOR
  16383. %    *   BINARY AND TEXT 'DATA' FILES
  16384. %    *
  16385. %    *
  16386. %    *******************************************
  16387. %
  16388.      ASSIGN FILE DATAFILE(REF=DATAFILE,RMS=NO,SUD=D02,FREEUP,
  16389.                  DATESCHEME=GEN,NOCAT,
  16390.                  FILESIZE=#FILESIZ/BLOCKS,
  16391.                  RECORDSIZE=1/485,
  16392.                  FILETYPE=DATA);
  16393.      IFEND;
  16394. %
  16395.      IFEND;
  16396. %
  16397. %
  16398. %
  16399. %    ****************************************************
  16400. %    * ASSIGNING THE OTHER FILE REFERENCES IN THE
  16401. %    * D02 CASE.
  16402. %    ****************************************************
  16403. %
  16404.      ASSIGN FILE SRCFILE(REF=SRCFILE,RMS=NO,SUD=D02,FREEUP,
  16405.                  RECORDSIZE=1/82,
  16406.                  FILESIZE=200/BLOCKS,DATESCHEME=GEN,NOCAT,
  16407.                  FILETYPE=SOURCE),
  16408.             FILE OBJFILE(REF=OBJFILE,RMS=NO,SUD=D02,FREEUP,
  16409.                  FILESIZE=1000/BLOCKS,RECORDSIZE=1/490,
  16410.                  DATESCHEME=GEN,FILETYPE=OBJECT,NOCAT),
  16411.             FILE CSFILE(REF=CSFILE,RMS=NO,SUD=D02,FREEUP,
  16412.                  FILESIZE=200/BLOCKS,RECORDSIZE=1/82,NOCAT,
  16413.                  DATESCHEME=GEN,FILETYPE='CONTROL STRING');
  16414. %
  16415. %
  16416. %  FILEL NOCAT;
  16417. %  * FILEC IS TO KNOW WHERE STDERR WILL BE.
  16418.    FILEC NOCAT;
  16419. %  ******************************************************
  16420. %  * END OF THE SUD=D02 CASE.
  16421. %  ******************************************************
  16422.    IFEND;
  16423. %
  16424. END;
  16425. %
  16426. % *********************************************
  16427. TERMCHNG('796401');
  16428. DEPOT(UNSOLICITED=DROP);
  16429. DEPOT(WIDTH=2048);
  16430. DEPOT(LENGTH=999);
  16431. DEPOT(WAIT=FALSE);
  16432. %
  16433. % ************************************************
  16434. %
  16435. ARGS := #COMMAND & ' 2> STDERR ';
  16436. DISPLAY : ' ';
  16437. DISPLAY : '  EXECUTING LOAD MODULE WERMIT.';
  16438. %
  16439. % MUST SPECIFY LOCATION OF LOAD MODULE
  16440. IVSKERM(ARGS);
  16441. DISPLAY : '  IVS-KERMIT TERMINATED.';
  16442. %
  16443. BEGIN
  16444. DISPLAY : '  PRINTING IVS-KERMIT TRANSFER HISTORY LOG(STDERR).';
  16445. DISPLAY : '  PLEASE WAIT.';
  16446. PUSH;
  16447. FREE DEFAULT_PRINTER;
  16448. ASSIGN PRINTER DEFAULT_PRINTER(SUD=P01);
  16449. %
  16450. IF (VSN /= '') THEN
  16451.   EXECUTE PRINT,SPEC='(NAME=STDERR,AGE=NEW,SUD=D02,NOCAT' &
  16452.     ') FORMAT=RECORDS,ASCII ONLY;';
  16453. ELSE
  16454. EXECUTE PRINT,SPEC='(NAME=STDERR,AGE=NEW) FORMAT=RECORDS,ASCII ONLY;';
  16455. IFEND;
  16456. %
  16457. QUEUE DEFAULT_PRINTER;
  16458. FREE DEFAULT_PRINTER;
  16459. ASSIGN PRINTER DEFAULT_PRINTER(SUD=P01,TYPE=TERMINAL);
  16460. POP;
  16461. DISPLAY : '  END OF PRINTING STDERR.';
  16462. END;
  16463. %
  16464. IF (VSN /= '') THEN
  16465.   FREE D02;
  16466. IFEND;
  16467. %
  16468. FREE DATAFILE;
  16469. FREE SRCFILE;
  16470. FREE OBJFILE;
  16471. FREE CSFILE;
  16472. % FILEL CAT/NOCAT;
  16473. % FILEC CAT;
  16474. %
  16475. IF ( NODE = '')
  16476. THEN
  16477.  FILEN;
  16478. ELSE
  16479. FILEN USER;
  16480. FILEN;
  16481. IFEND;
  16482. %
  16483. DEPOT(UNSOLICITED=NOTIFY);
  16484. DEPOT(WIDTH=80);
  16485. DEPOT(LENGTH=23);
  16486. DEPOT(WAIT=TRUE);
  16487. DISPLAY : '  END OF IVSKP.';
  16488. PROCEND IVSKPM;
  16489. <<< kermisc.h >>>
  16490. /**********************************************************************
  16491. *                                                                     *
  16492. * IVS / MCS-Kermit REL 2                                              *
  16493. * source code                                                         *
  16494. *                                                                     *
  16495. * Change History:                                                     *
  16496. *                                                                     *
  16497. *                1. Modify C-Kermit(4E) source code to                *
  16498. *                   produce new module for MCS/IVS-Kermit             *
  16499. *                   ORIGINAL RELEASE                                  *
  16500. *                   June 22, 1990                                     *
  16501. *                                                                     *
  16502. *                                                                     *
  16503. ***********************************************************************/
  16504.  
  16505.  
  16506.  
  16507. #define SIG_DFL (int (*)())0
  16508. #define SIG_IGN (int (*)())1
  16509.  
  16510. extern int (*ssignal())();
  16511.  
  16512.  
  16513. #define SIGINT  2       /* interrupt (rubout) */
  16514. #define SIGQUIT 3       /* quit (ASCII FS) */
  16515. #define SIGILL  4       /* illegal instruction (not reset when caught)*/
  16516. #define SIGTRAP 5       /* trace trap (not reset when caught) */
  16517. #define SIGIOT  6       /* IOT instruction */
  16518. #define SIGEMT  7       /* EMT instruction */
  16519. #define SIGFPE  8       /* floating point exception */
  16520. #define SIGKILL 9       /* kill (cannot be caught or ignored) */
  16521. #define SIGBUS  10      /* bus error */
  16522. #define SIGSEGV 11      /* segmentation violation */
  16523. #define SIGSYS  12      /* bad argument to system call */
  16524. #define SIGPIPE 13      /* write on a pipe with no one to read it */
  16525. #define SIGALRM 14      /* alarm clock */
  16526. #define SIGTERM 15      /* software termination signal from kill */
  16527. #define SIGUSR1 16      /* user defined signal 1 */
  16528. #define SIGUSR2 17      /* user defined signal 2 */
  16529. #define SIGCLD  18      /* death of a child */
  16530. #define SIGPWR  19      /* power-fail restart */
  16531. #define NSIG    20
  16532. <<< linkmcs.pro >>>
  16533. 000010PROCEDURE LINKMCS;
  16534. 000020LINKEDIT,EDIT(
  16535. 000030   NAME=MCSKERM,
  16536. 000035   BIND=MCSKNDL,
  16537. 000040   BIND=CRT0/D90/CLIB,
  16538. 000050   BIND=CKVMAI_M,
  16539. 000060   BIND=CKVFN2_O,
  16540. 000070   BIND=CKVTIO_M,
  16541. 000080   BIND=CKVFNS_O,
  16542. 000090   BIND=CKVPRO_M,
  16543. 000100   BIND=CKVUSR_M,
  16544. 000110   BIND=CKVCMD_M,
  16545. 000120   BIND=CKVCON_M,
  16546. 000130   BIND=CKVDIA_M,
  16547. 000140   BIND=CKVFI2_O,
  16548. 000150   BIND=CKVSCR_M,
  16549. 000160   BIND=CKVUS2_M,
  16550. 000170   BIND=CKVUS3_M,
  16551. 000180   BIND=VKNCRLIO,
  16552. 000190   BIND=CKVFIO_O,
  16553. 000200   BIND=CKVMCS_O,
  16554. 000210   BIND=CKVBUF_O,
  16555. 000215   AUTOLIB=D90/CLIB,
  16556. 000220   ATTRSORT,SHARE);
  16557. 000230PROCEND LINKMCS;
  16558. <<< lnk1ksrc.n3 >>>
  16559. 000000CLNKIVS    NEAT/3
  16560. 000010CLNKIVS    CATJOB
  16561. 000020CLNKIVS    JOB   VMAXMEM=1650,LOCALDSA=3000,PROTECTDSA=256
  16562. 000030                 STACKSIZE=250,SHARE,ACCESS=YES
  16563. 000040                 USERID=XXX,ACCT = XXXXX
  16564.                        CPTY=10,JPTY=8
  16565.                        NAME=YOUR_NAME,PASSWORD=XXXXXXXX
  16566. 000050C          UNIT  SUD=D01/D02/D03,VOL=525252,TYPE=BA/3A/3B
  16567. 000090           SPCEND
  16568. 000100           SCLBGN
  16569.        FILEL CAT/NOCAT;FILEC CAT;FILEN $.XXX.XXXXXX;
  16570.        ASS FLAGS MYFLAGS(MF02=4);
  16571.        MCLBEGIN;
  16572. 000130           NEXTDOLINKEDIT
  16573. 000140           FILE  REFERENCE=OUTPUTFILE
  16574. 000150                 BLOCK SIZE=  8/RECORDS
  16575. 000160           EDIT  NAME    = IVSKERM
  16576.                        BIND = CRT0/D90/CLIB
  16577.                        BIND = CKVMAI_O
  16578.                        BIND = CKVFN2_O
  16579.                        BIND = CKVTIO_O
  16580.                        BIND = CKVFNS_O
  16581.                        BIND = CKVPRO_O
  16582.                        BIND = CKVUSR_O
  16583.                        BIND = CKVCMD_O
  16584.                        BIND = CKVCON_O
  16585.                        BIND = CKVDIA_O
  16586.                        BIND = CKVFI2_O
  16587.                        BIND = VKNCRLIO
  16588.                        BIND = CKVFIO_O
  16589.                        BIND = CKVSCR_O
  16590.                        BIND = CKVUS2_O
  16591.                        BIND = CKVUS3_O
  16592. 000230                 AUTOLIB = D90/CLIB
  16593.                        ATTRSORT,SHARE
  16594. 000240           STOPRD
  16595. 000250           JOB   END
  16596. <<< mcs.h >>>
  16597.  
  16598. #define puts            mcs_puts
  16599. #define fputs           mcs_fputs
  16600. #define gets            mcs_gets
  16601. #define fputc           mcs_fputc
  16602. #define fputchar        mcs_fputchar
  16603. #define putchar         mcs_putchar
  16604. #define getchar         mcs_getchar
  16605. #define fgetc           mcs_fgetc
  16606. #define putc            mcs_fputc
  16607. #define getc            mcs_fgetc
  16608. #define fgets           mcs_fgets
  16609.  
  16610.  
  16611. static char print_str[200];
  16612. <<< mcs_defs.h >>>
  16613. /*           mcs_defs_h                   */
  16614.  
  16615.  
  16616. #include <stdio.h>
  16617. #include <ctype.h>
  16618.  
  16619. #define COMPVER 0x01        /* Compiler version 1. */
  16620. #define MESGS 40            /* Number of messages in outmesg array. */
  16621. #define BUF 50
  16622. #define MSGBUF 80           /* Maximum length of the message buffers */
  16623.                             /* DRE 013190 - changed from 110 TO 80 */
  16624. #define PWDLEN 10           /* Password buffer length. */
  16625. #define RESP_EOT 0x1e       /* Response message End-Of-Text character. */
  16626. #define PASSWD "PASSWORD"   /* Password for enabling and disabling. */
  16627. #define PRT_FILE "SPOOLFILE"
  16628. #define IN_TERM   "INPUT"
  16629. #define OUT_TERM  "OUTPUT"
  16630. #define QUEUENAME "THE_QUEUE"
  16631. #define iowriter if (iowrite) prt_iowriter
  16632. #define printriow if (iowrite) printreciow
  16633. #define OFF 0
  16634. #define ON 1
  16635. #define YES 'Y'
  16636. #define NO 'N'
  16637. #define MESG 0              /* Boolean for testing messages. */
  16638. #define VARESP 1            /* Boolean for testing variable responses. */
  16639. #define RESP 2              /* Boolean for testing responses. */
  16640. #define S 0                 /* Regular send. */
  16641. #define SX25 1              /* Send SX25. */
  16642.  
  16643. /* Defines for ParBlock structures. */
  16644. #define IPPHASE 0x49        /* Input phase. */
  16645. #define OPPHASE 0x4f        /* Output phase. */
  16646. #define TERMPHASE 0x54      /* Input terminal phase. */
  16647. #define NODATA(x) x |= 0x01 /* No data was available - return (bit 1 set) */
  16648. #define EXITFG(x) x |= 0x02 /* Suspend if data is not available (bit 2 set) */
  16649. #define NOENDKEY 0          /* Partial segment, user specified. */
  16650. #define INTEGESI 0x01       /* End of segment, user specified. */
  16651. #define INTEGEMI 0x02       /* End of message, user specified. */
  16652. #define INTEGEGI 0x03       /* End of group, user specified. */
  16653. #define ESI 0x53            /* End of segment, compiler generated. */
  16654. #define EMI 0x4d            /* End of message, compiler generated. */
  16655. #define EGI 0x47            /* End of group, compiler generated. * */
  16656. #define AFTER 0x41          /* Advance after message display. */
  16657. #define BEFORE 0x42         /* Advance before message display. * */
  16658. #define LINE 0x4c           /* Line advancing. */
  16659. #define PAGE 0x50           /* Page advancing. * */
  16660. #define HEXMNEM 0           /* Mnemonic is a string of hex. */
  16661. #define ASCIIMNEM 1         /* Mnemonic is a string of ascii. * */
  16662.  
  16663. #ifndef lint
  16664. extern void MSGBUILD();
  16665. extern void \:FINISH();
  16666. extern void MCS\:ENABLE();
  16667. extern void MCS\:DSABLE();
  16668. extern void MCS\:SEND();
  16669. extern void MCS\:RECEIV();
  16670. extern void MCS\:ACCEPT();
  16671. extern void SESS\:MGT();
  16672. #endif /*NOT LINT*/
  16673.  
  16674. FILE *fp;                   /* File pointer for the spool file. */
  16675.  
  16676. int iowrite;                /* Iowriter. */
  16677. int nosends;                /* Number of sends in a session. */
  16678.  
  16679. char outmesg[MESGS][MSGBUF];/* Array of output messages. */
  16680. char outterm[BUF];          /* Output terminal name. */
  16681. char interm[BUF];           /* Input terminal name. */
  16682. char iobuff[MSGBUF];        /* Buffer for send messages to iowriter. */
  16683.  
  16684. char *mcs_fgets();
  16685.  
  16686. struct SendSMTD{
  16687.   char ijn[BUF];
  16688.   char ihc[BUF];
  16689. } SendSMTD;
  16690.  
  16691. struct OutputCD {           /* Output communication descriptor. */
  16692.   char destcnt[4];          /* Destination count. */
  16693.   char textlen[4];          /* Text length. */
  16694.   char statkey[2];          /* Status key. */
  16695.   char errkey;              /* Error key. */
  16696.   char symdest[12];         /* Symbolic destination. */
  16697.   struct ExOutCD {          /* Extended output CD. */
  16698.     char xoformat;          /* Extended output format. */
  16699.     char tcfunction[3];     /* TC function. */
  16700.     char tcqualifier[3];    /* TC qualifier. */
  16701.     char tcoutput_reset;    /* TC output_reset */
  16702.     char xofiller[33];      /* Extended output filler. */
  16703.   } ExOutCD;
  16704. } OutCD;
  16705.  
  16706. struct InputCD {            /* Input communication descriptor. */
  16707.   char q[12];               /* Input CD queue. */
  16708.   char symq1[12];           /* Symbolic Sub-queue 1. */
  16709.   char symq2[12];           /* Symbolic Sub-queue 2. */
  16710.   char symq3[12];           /* Symbolic Sub-queue 3. */
  16711.   char mdate[6];            /* Message date. */
  16712.   char mtime[8];            /* Message time. */
  16713.   char source[12];          /* Symbolic source. */
  16714.   char len[4];              /* Text length. */
  16715.   char endkey;              /* End key. */
  16716.   char statkey[2];          /* Status key. */
  16717.   char msgcnt[6];           /* Message count */
  16718.   struct ExInCD {           /* Extended input CD. */
  16719.        char xiformat;          /* Extended input format. */
  16720.        char xistatus[2];       /* TC status. */
  16721.        char xipassthru[10];    /* TC pass through. */
  16722.        char xifiller[27];      /* Extended input filler. */
  16723.   } ExInCD;
  16724. } InCD;
  16725.  
  16726.  
  16727. struct mnemonik {           /* Mnemonic structure in each parameter block. */
  16728.    char type;               /* Mnemonic type field. */
  16729.    char *address;           /* Address of mnemonic. */
  16730.                             /* DRE 013190 - change to char ptr */
  16731.                             /* CHANGE PEG 012990        */
  16732.                             /* CAUSED AN ALIGNMENT PROBLEM DUE TO
  16733.                                RANDOMNESS OF BYTE PLACEMENT       */
  16734.                             /* for all purposes a four byte array */
  16735.  
  16736. };
  16737.  
  16738. struct SParBlck {           /*   parameter block for sending. */
  16739.   short length;             /* User message area length. */
  16740.   char complver;            /* Compiler version. */
  16741.   char linenum;             /* Number of lines to advance. */
  16742.   char indicator;           /* Send or receive end key. */
  16743.   char advancing;           /* Type of advancing. */
  16744.   char position;            /* Mode of advancing. */
  16745.   char sendcount;           /* Send destination count. */
  16746. /* struct mnemonik mnemonic; */ /* Mnemonic structure field. */
  16747.   char mnemonic[4];                                      /* DRE 020990 */
  16748. } SParBlock;
  16749.  
  16750. struct RParBlck {           /*   parameter block for receiving. */
  16751.   short length;             /* User message area length. */
  16752.   char complver;            /* Compiler version. */
  16753.   char avail;               /* Bit flags - receive data availability. */
  16754.   char indicator;           /* Send or receive end key. */
  16755.   char filler[7];           /* PEG 012990
  16756.                                SIMILAR TO MCDAID'S DELETED SEVEN
  16757.                                UNUSED BYTES FOR PROPER DEFINE         */
  16758.  
  16759. } RParBlock;
  16760.  
  16761. struct ParBlck {           /*   parameter block for enable/disable. */
  16762.   char denabltyp;           /* Enable or disable type. */
  16763.   char passwdlen;           /* Password length. */
  16764.   char complver;            /* Compiler version. */
  16765.   char destcount;           /* Enable/disable/purge destination count. */
  16766.   char filler [8];
  16767. } ParBlock;
  16768.  
  16769. struct SMParBlck {          /* Session Management Parameter Block. */
  16770.   char format;
  16771.   char action[3];           /* EST, DIS, ABT, 1, 2, or 3. */
  16772.   char pbstatus[4];         /* Parameter block status. */
  16773.   char symdest[12];         /* Symbolic destination. */
  16774.   char input;               /* Allow input. */
  16775.   char output;              /* Allow output. */
  16776.   char status[2];           /* Return status. */
  16777.   char exstatus[4];         /* Return extended status. */
  16778. } SMParBlock;
  16779. <<< mcskj.n3 >>>
  16780.        MCSKJ     CATJOB
  16781.        MCSKJ     JOB   NAME=(MCS-KERMIT)
  16782.                         ****************************
  16783.                         * COPYRIGHT NCR CORP.      *
  16784.                         *   DAYTON, OHIO           *
  16785.                         *   1990                   *
  16786.                         ****************************
  16787.                        USERID=PUBLIC
  16788.                        ACCT=PUBLICACCTNUMBER
  16789.                         *PASSWORD=PUBLIC
  16790.                         *USERID=XXX,ACCT=NNNN,PASSWORD=XXX
  16791.                        CPTY=7,JPTY=1,CNTLSTKLEN=808
  16792.                        MAXT=INFINITE,IOCT=9999999
  16793.                        VMAXMEM=1000,LOCALDSA=2500
  16794.                        PROTECTDSA=1000,SIZE=124,STACKSIZE=124
  16795.                        JOBCONTROL=SCL
  16796.                  SPCEND
  16797. %
  16798. % *************************************************
  16799. % *
  16800. % * THIS JOB INITIALIZES MCS-KERMIT
  16801. % *   FOR TRANSFERRING
  16802. % *   FILES TO/FROM THE CATALOG OR SUD=D02
  16803. % *
  16804. % *
  16805. % *
  16806. % * UPDATED ON 6-1-90
  16807. % * UPDATED ON 6-8-90
  16808. % * UPDATED ON 6-15-90
  16809. % *
  16810. % *************************************************
  16811. %
  16812. %
  16813. % *************************************************
  16814. % * VARIABLE DEFINITIONS
  16815. % *************************************************
  16816. %
  16817. %
  16818.    LOCAL
  16819.     MSG       : STRING,
  16820.     LPN       : STRING,
  16821.     ENV       : STRING,
  16822.     VSN       : STRING,
  16823.     DTYPE     : STRING,
  16824.     VOL_INT   : INTEGER,
  16825.     NODE      : STRING,
  16826.     NODENAME  : NAME,
  16827.     ACTION    : STRING,
  16828.     FILESIZ   : STRING,
  16829.     RSTRT_FLAG: BOOLEAN,
  16830.     DEFAULTS  : STRING,
  16831.     FONT_FORM : STRING,
  16832.     REC_TYPE  : STRING,
  16833.     P1        : PROCESS;
  16834. %
  16835. % *******************************************************
  16836. % * ASSIGNING THE DEFAULT VALUES
  16837. % *******************************************************
  16838. %
  16839.   LOCAL
  16840.     LPN_DFLT       : STRING,
  16841.     ENV_DFLT       : STRING,
  16842.     NODE_DFLT      : STRING,
  16843.     REC_TYP_DFLT   : STRING,
  16844.     FONT_FORM_DFLT : STRING,
  16845.     FILESIZ_DFLT   : STRING;
  16846. %
  16847. % *******************************************************
  16848. % * WARNING:
  16849. % *  DEFAULT STRING LENGTHS CANNOT BE SO LONG AS TO
  16850. % *  CAUSE ANY OF THE 'MSG' STRINGS TO BE > 105 CHARS.
  16851. % *******************************************************
  16852. %
  16853.   LPN_DFLT         := '0104';
  16854.   ENV_DFLT         := 'CAT';
  16855.   NODE_DFLT        := '$';
  16856.   REC_TYP_DFLT     := 'VARIABLE';
  16857.   FONT_FORM_DFLT   := 'SEQUENTIAL';
  16858.   FILESIZ_DFLT     := '500';
  16859. %
  16860.    FILECREATION CAT;
  16861. %
  16862. % *********************************************
  16863. % * SOLICITATION OF SETUP OPTIONS
  16864. % *
  16865. % *     -LPN?
  16866. % *
  16867. % *     -FILE SOURCE AND DEST?
  16868. % *       -IF CAT, WHICH NODE?
  16869. % *       -IF DISK, WHIC VOLUME AND TYPE?
  16870. % *
  16871. % *     -FILE SPECIFICATIONS FOR REF=DATAFILE?
  16872. % *       -REGULAR FILE STRUCTURE OR 6437/38 LASER
  16873. % *        PRINTER FONT/FORMS?
  16874. % *       -FILESIZE FOR D02 AND FONT/FORMS?
  16875. % *
  16876. % *******************************************************
  16877. %
  16878. %
  16879. %
  16880. % ******************************************************
  16881. % * ASKING USER FOR ACCEPTANCE OF DEFAULTS
  16882. % *
  16883. % *   USER ACCEPTS DEFAULTS(DEFAULTS IN PARENS)?
  16884. % *
  16885. % *     -LPN ( 0150 )
  16886. % *
  16887. % *     -FILE SOURCE/DEST ( CAT )
  16888. % *         -NODE ( $ )
  16889. % *
  16890. % *
  16891. % *     -FILE SPECIFICATIONS FOR REF=DATAFILE
  16892. % *       -FIXED LENGTH DATAFILE RECORDS ( NO )
  16893. % *       -FONT/FORMS ORGANIZATION ( NO )
  16894. % *       -FILESIZE FOR D02 AND FONT/FORMS ( 500 BLOCKS )
  16895. % *
  16896. % *
  16897. % ******************************************************
  16898. %
  16899. % * NOTE: ASKOP WILL ONLY DISPLAY A 105 CHARACTER STRING.
  16900. % *       AND IT LOSES THE 1ST 2 CHARACTERS.
  16901. %
  16902. BEGIN
  16903.    MSG := '  ACCEPT DEFAULTS OF LPN=' &
  16904.           #LPN_DFLT &
  16905.           ',SOURCE/DEST=' &
  16906.           #ENV_DFLT &
  16907.           ',' &
  16908.           'NODE=' &
  16909.           #NODE_DFLT &
  16910.           ',' &
  16911.           SUBSTRING(REC_TYP_DFLT,0,3) &
  16912.           ' RECS,' &
  16913.           SUBSTRING(FONT_FORM_DFLT,0,3) &
  16914.           ' ORG,SIZE=' &
  16915.           #FILESIZ_DFLT &
  16916.           '/BLOCKS' &
  16917.           '?[Y,N]';
  16918.    ASKPROC (#MSG,/DEFAULTS/);
  16919. %
  16920.    IF (SUBSTRING(DEFAULTS,0,1) /= 'N')
  16921.      THEN
  16922. %    * SET UP DEFAULT VALUES
  16923.      LPN       := LPN_DFLT;
  16924.      ENV       := ENV_DFLT;
  16925.      NODE      := NODE_DFLT;
  16926.      VSN       := '';
  16927.      REC_TYPE  := REC_TYP_DFLT;
  16928.      FONT_FORM := FONT_FORM_DFLT;
  16929.      FILESIZ   := FILESIZ_DFLT;
  16930.      DEFAULTS  := 'YES';
  16931.      NODENAME  := #NODE;
  16932.      FILENODE #NODENAME;
  16933.    ELSE
  16934.    DEFAULTS := 'NO';
  16935.    IFEND;
  16936. %
  16937. %
  16938. %  *******************************************************
  16939. %  * DEFAULTS NOT ACCEPTED
  16940. %  *
  16941. %  * THE 'X' RESPONSE STOPS THE QUESTIONS
  16942. %  *
  16943. %  *******************************************************
  16944.    IF (DEFAULTS = 'NO' )
  16945.      THEN
  16946. $TAG1
  16947. %    *****************************************************
  16948. %    * ASKING FOR LPN OF SUD=A02.
  16949. %    *****************************************************
  16950.      MSG := '  SPECIFY LPN FOR MCS-KERMIT COMMUNICATION LINK.' &
  16951.             ' DEFAULT LPN IS ' &
  16952.             #LPN_DFLT &
  16953.             '.' &
  16954.             ' ''X'' TO STOP ASKING.[NNNN,X]';
  16955.      ASKPROC (#MSG,/LPN/);
  16956. %
  16957.      IF (LPN = '')
  16958.        THEN
  16959.        LPN := LPN_DFLT;
  16960.      IFEND;
  16961. %
  16962.      IF (LPN = 'X')
  16963.        THEN
  16964.        DEFAULTS := 'YES';
  16965. %      * SET UP DEFAULT VALUES
  16966.        LPN       := LPN_DFLT;
  16967.        ENV       := ENV_DFLT;
  16968.        NODE      := NODE_DFLT;
  16969.        VSN       := '';
  16970.        REC_TYPE  := REC_TYP_DFLT;
  16971.        FONT_FORM := FONT_FORM_DFLT;
  16972.        FILESIZ   := FILESIZ_DFLT;
  16973.        DEFAULTS  := 'YES';
  16974.        NODE      := NODE_DFLT;
  16975.        NODENAME  := #NODE;
  16976.        FILENODE #NODENAME;
  16977.      IFEND;
  16978. %
  16979.    IFEND;
  16980. %
  16981. %  ******************************************************
  16982. %  * ASSIGN A02 IN BOTH 'DEFAULT' AND 'SOLICITED' CASES.
  16983. %  ******************************************************
  16984.    ASSIGN UNIT A02(SUD=A02,TYPE=C1,LPN=#LPN) [P1];
  16985. %
  16986.    IF (P1(STATUS) /= COMPLETED)
  16987.      THEN
  16988.      MSG := '  LPN ' & #LPN & ' WAS INVALID OR IN USE.  DO YOU WANT ' &
  16989.             'TO TRY ANOTHER LPN? [Y,N]';
  16990.      ASKPROC (#MSG,/ACTION/);
  16991. %
  16992.      IF (SUBSTRING(ACTION,0,1) = 'N') THEN
  16993.        BYE;
  16994.      ELSE
  16995.      GOTO TAG1;
  16996.      IFEND;
  16997. %
  16998.    IFEND;
  16999. %
  17000. $TAG2
  17001. %
  17002.    IF (DEFAULTS = 'YES' )
  17003.      THEN
  17004.      GOTO TAG5;
  17005.    IFEND;
  17006. %
  17007. %  ******************************************************
  17008. %  * ASKING FOR FILE SOURCE/DESTINATION.
  17009. %  ******************************************************
  17010.    MSG := '  SELECT MCS-KERMIT SOURCE/DESTINATION ENVIRONMENT.' &
  17011.           ' DEFAULT ENVIRONMENT IS ' &
  17012.           #ENV_DFLT &
  17013.           '.' &
  17014.           '[CAT,DISK,X]';
  17015.    ASKPROC (#MSG,/ENV/);
  17016. %
  17017.    IF ((SUBSTRING(ENV,0,1) /= 'C') AND (SUBSTRING(ENV,0,1) /= 'D') AND
  17018.        (SUBSTRING(ENV,0,1) /= 'X') AND
  17019.        (SUBSTRING(ENV,0,1) /= '')) THEN
  17020.      GOTO TAG2;
  17021.    IFEND;
  17022. %
  17023.    IF (SUBSTRING(ENV,0,1) = 'X')
  17024.      THEN
  17025.      DEFAULTS := 'YES';
  17026. %    * SET UP DEFAULT VALUES
  17027.      ENV       := ENV_DFLT;
  17028.      NODE      := NODE_DFLT;
  17029.      VSN       := '';
  17030.      REC_TYPE  := REC_TYP_DFLT;
  17031.      FONT_FORM := FONT_FORM_DFLT;
  17032.      FILESIZ   := FILESIZ_DFLT;
  17033.      DEFAULTS  := 'YES';
  17034.      NODE      := NODE_DFLT;
  17035.      NODENAME  := #NODE;
  17036.      FILENODE #NODENAME;
  17037.      GOTO TAG5;
  17038.    IFEND;
  17039. %
  17040.    IF ((SUBSTRING(ENV,0,1) = 'C') OR (SUBSTRING(ENV,0,1) = '')) THEN
  17041. $TAG3
  17042. %  ******************************************************
  17043. %  * CATALOG SELECTED;ASKING FOR NODE.
  17044. %  ******************************************************
  17045.      MSG := '  PLEASE ENTER SUBCATALOG NODE NAME. DEFAULT IS' &
  17046.             ' THE ' &
  17047.             #NODE_DFLT &
  17048.             ' NODE.' &
  17049.             '[NODE NAME,X]';
  17050.      ASKPROC (#MSG,/NODE/);
  17051. %
  17052.      IF (NODE = '') THEN
  17053.        NODE      := NODE_DFLT;
  17054.      IFEND;
  17055. %
  17056.      IF (NODE = 'X')
  17057.        THEN
  17058.        DEFAULTS := 'YES';
  17059. %      * SET UP DEFAULT VALUES
  17060.        VSN       := '';
  17061.        REC_TYPE  := REC_TYP_DFLT;
  17062.        FONT_FORM := FONT_FORM_DFLT;
  17063.        FILESIZ   := FILESIZ_DFLT;
  17064.        DEFAULTS  := 'YES';
  17065.        NODE      := NODE_DFLT;
  17066.        NODENAME  := #NODE;
  17067.        FILENODE #NODENAME;
  17068.        GOTO TAG5;
  17069.      ELSE
  17070.      NODENAME := #NODE;
  17071.      IFEND;
  17072. %
  17073.      FILENODE #NODENAME [P1];
  17074. %
  17075.      IF (P1(STATUS) /= COMPLETED) THEN
  17076.        MSG := '  CANT POSITION TO ' & #NODE & '  DO YOU WANT' &
  17077.               ' TO TRY ANOTHER SUBCATALOG?[Y,N]';
  17078.        ASKPROC (#MSG,/ACTION/);
  17079. %
  17080.        IF (SUBSTRING(ACTION,0,1) = 'N') THEN
  17081.          BYE;
  17082.        ELSE
  17083.        GOTO TAG3;
  17084.        IFEND;
  17085. %
  17086.      IFEND;
  17087. %
  17088. %    ****************************************************
  17089. %    * ASKING FOR FIXED/VARIABLE RECORD TYPE.
  17090. %    * IN THE CATALOG CASE.
  17091. %    ****************************************************
  17092.      MSG := '  DO YOU WANT DATAFILES TO HAVE FIXED OR' &
  17093.             ' VARIABLE LENGTH RECORDS?' &
  17094.             ' DEFAULT IS ' &
  17095.             #REC_TYP_DFLT &
  17096.             '.' &
  17097.             '[F,V,X]';
  17098.      ASKPROC (#MSG,/REC_TYPE/);
  17099. %
  17100.      IF (SUBSTRING(REC_TYPE,0,1) = 'X')
  17101.        THEN
  17102.        DEFAULTS := 'YES';
  17103. %      * SET UP DEFAULT VALUES
  17104.        VSN       := '';
  17105.        REC_TYPE  := REC_TYP_DFLT;
  17106.        FONT_FORM := FONT_FORM_DFLT;
  17107.        FILESIZ   := FILESIZ_DFLT;
  17108.        DEFAULTS  := 'YES';
  17109.        GOTO TAG5;
  17110.      IFEND;
  17111. %
  17112.      IF (SUBSTRING(REC_TYPE,0,1) /= 'F')
  17113.        THEN
  17114.        REC_TYPE := 'VAR';
  17115. %      **************************************************
  17116. %      * ASKING ABOUT THE TRANSFER OF FONT/FORM FILES
  17117. %      * IN THE CATALOG CASE.
  17118. %      **************************************************
  17119.        MSG := '  WILL YOU UPLOAD FONT/FORM FILES?' &
  17120.              ' IF YES,ALL DATA FILES HAVE' &
  17121.              ' ''REL'' ORGANIZATION;' &
  17122.              'DEFAULT IS ' &
  17123.              SUBSTRING(FONT_FORM_DFLT,0,3) &
  17124.              '.[Y,N]';
  17125.        ASKPROC (#MSG,/FONT_FORM/);
  17126. %
  17127.        IF (SUBSTRING(FONT_FORM,0,1) /= 'Y')
  17128.          THEN
  17129. %        *******************************************
  17130. %        * FILE 'REFERENCE' OF 'DATAFILE' IS USED FOR
  17131. %        *   BINARY AND TEXT 'DATA' FILES
  17132. %        *
  17133. %        *
  17134. %        *******************************************
  17135. %
  17136. $TAG5
  17137. %
  17138. %        ************************************************
  17139. %        * ASSIGNING REF=DATAFILE
  17140. %        * IN THE VARIABLE LENGTH RECORDS, NON FONT/FORM
  17141. %        * CASE USING CATALOG.
  17142. %        *
  17143. %        * THIS IS CONSIDERED TO BE THE OVERALL
  17144. %        * DEFAULT CASE.
  17145. %        *
  17146. %        ************************************************
  17147.          ASSIGN FILE DATAFILE(REF=DATAFILE,RMS=YES,
  17148.                  FILESIZE='NO LIMIT',
  17149.                  RECORDSIZE=1/485,
  17150.                  DATESCHEME=GEN,FILETYPE=DATA,FREEUP,CATALOG);
  17151.        ELSE
  17152. %      *********************************************
  17153. %      * ASKING ABOUT FILE SIZE
  17154. %      * IN THE CATALOG,VARIABLE,FONT/FORM CASE.
  17155. %      *
  17156. %      *   FONT/FORM FILES
  17157. %      *
  17158. %      * FILESIZE MUST BE FOR THE LARGEST
  17159. %      *   FILE ANTICIPATED BECAUSE RELATIVE FILES
  17160. %      *   ARE NOT RMS.
  17161. %      *
  17162. %      ************************************************
  17163. %
  17164. %
  17165.        MSG := '  SPECIFY FILESIZE' &
  17166.               ' BIG ENOUGH FOR THE LARGEST' &
  17167.               ' FONT/FORM FILE UPLOADED.' &
  17168.               ' DEFAULT SIZE IS ' &
  17169.               #FILESIZ_DFLT &
  17170.               '/BLOCKS.[NNNN]';
  17171.        ASKPROC (#MSG,/FILESIZ/);
  17172. %
  17173.        IF ((SUBSTRING(FILESIZ,0,1) = '') OR (SUBSTRING(FILESIZ,0,1) = 'A'))
  17174.          THEN
  17175.          FILESIZ := FILESIZ_DFLT;
  17176.        IFEND;
  17177. %
  17178. %      ************************************************
  17179. %      * ASSIGNING REF=DATAFILE
  17180. %      * IN THE FONT/FORM CASE USING CATALOG.
  17181. %      ************************************************
  17182.        ASSIGN FILE DATAFILE(REF=DATAFILE,RMS=YES,
  17183. %                ************************************
  17184. %                *  THE FOLLOWING 5 PARAMETERS ARE
  17185. %                *    FOR FONT/FORM UPLOADS
  17186. %                ************************************
  17187.                  ORGANIZATION=RELATIVE,
  17188.                  BLOCKSIZE=1/RECORDS,
  17189.                  CAMHEADER,
  17190.                  RECORDSIZE=1/485,
  17191.                  FILESIZE=#FILESIZ/BLOCKS,
  17192.                  DATESCHEME=GEN,FILETYPE=DATA,FREEUP,CATALOG);
  17193.        IFEND;
  17194. %
  17195.      ELSE
  17196. %
  17197. %    ************************************************
  17198. %    * ASSIGNING REF=DATAFILE
  17199. %    * IN THE FIXED LENGTH RECORDS, NON FONT/FORM
  17200. %    * CASE USING CATALOG.
  17201. %    ************************************************
  17202.      ASSIGN FILE DATAFILE(REF=DATAFILE,RMS=YES,
  17203. %                ************************************
  17204. %                *  THE FOLLOWING PARAMETERS ARE
  17205. %                *    FOR FIXED LENGTH RECORDS
  17206. %                ************************************
  17207.                  RECORDSIZE=80,
  17208.                  FILESIZE='NO LIMIT',
  17209.                  DATESCHEME=GEN,FILETYPE=DATA,FREEUP,CATALOG);
  17210.      IFEND;
  17211. %
  17212.      FILEN;
  17213. %    ****************************************************
  17214. %    * ASSIGNING THE OTHER FILE REFERENCES IN THE
  17215. %    * CATALOG CASE.
  17216. %    ****************************************************
  17217.      ASSIGN FILE SRCFILE(REF=SRCFILE,RMS=YES,FILESIZE='NO LIMIT',
  17218.                  RECORDSIZE=1/83,
  17219.                  DATESCHEME=GEN,FILETYPE=SOURCE,FREEUP,CATALOG),
  17220.             FILE OBJFILE(REF=OBJFILE,RMS=YES,FILESIZE='NO LIMIT',
  17221.                  RECORDSIZE=1/490,
  17222.                  DATESCHEME=GEN,FILETYPE=OBJECT,FREEUP,CATALOG),
  17223.             FILE CSFILE(REF=CSFILE,RMS=YES,FILESIZE='NO LIMIT',
  17224.                  FREEUP,DATESCHEME=GEN,
  17225.                  RECORDSIZE=1/82,
  17226.                  FILETYPE='CONTROL STRING',CATALOG);
  17227.      FILEL CAT/NOCAT;
  17228. %    ****************************************************
  17229. %    * END OF THE CATALOG CASE.
  17230. %    ****************************************************
  17231.    ELSE
  17232. %  ******************************************************
  17233. %  * BEGINNING OF THE SUD=D02 CASE.
  17234. %  ******************************************************
  17235.    DISPLAY :'MCS-KERMIT USING NON-CATALOG ENVIRONMENT' TO JD;
  17236. $TAG4
  17237. %  ******************************************************
  17238. %  * ASKING ABOUT SUD=D02.
  17239. %  ******************************************************
  17240.    MSG := '  PLEASE ENTER VOLUME NUMBER AND DEVICE TYPE.' &
  17241.           '[NNNNNN/XX]';
  17242.    ASKPROC (#MSG,/VSN/);
  17243.    VOL_INT := INT(SUBSTRING(VSN,0,6));
  17244.    DTYPE := SUBSTRING(VSN,7,2);
  17245.    ASSIGN UNIT D02(SUD=D02,VOL=#VOL_INT,TYPE=#DTYPE) [P1];
  17246. %
  17247.    IF (P1(STATUS) /= COMPLETED) THEN
  17248.      MSG := '  CANT ASSIGN VOLUME ' & SUBSTRING(VSN,0,6) &
  17249.             ' WITH DEVICE TYPE ' & DTYPE & '. DO YOU WANT' &
  17250.             ' TO TRY ANOTHER VOLUME?[Y,N]';
  17251.      ASKPROC (#MSG,/ACTION/);
  17252. %
  17253.      IF (SUBSTRING(ACTION,0,1) = 'N') THEN
  17254.        BYE;
  17255.      ELSE
  17256.      GOTO TAG4;
  17257.      IFEND;
  17258. %
  17259.    IFEND;
  17260. %
  17261. %
  17262. %  ****************************************************
  17263. %  * ASKING FOR FIXED/VARIABLE RECORD TYPE.
  17264. %  * IN THE D02 CASE.
  17265. %  ****************************************************
  17266. %
  17267.    MSG := '  DO YOU WANT DATAFILES TO HAVE FIXED OR' &
  17268.           ' VARIABLE LENGTH RECORDS?' &
  17269.           ' DEFAULT IS ' &
  17270.           #REC_TYP_DFLT &
  17271.           '.' &
  17272.           '[F,V,X]';
  17273.    ASKPROC (#MSG,/REC_TYPE/);
  17274. %
  17275. %
  17276.    IF (SUBSTRING(REC_TYPE,0,1) = 'X')
  17277.      THEN
  17278.      DEFAULTS := 'YES';
  17279. %    * SET UP DEFAULT VALUES
  17280.      REC_TYPE  := REC_TYP_DFLT;
  17281.      FONT_FORM := FONT_FORM_DFLT;
  17282.      FILESIZ   := FILESIZ_DFLT;
  17283.      GOTO TAG6;
  17284.    IFEND;
  17285. %
  17286.    IF (SUBSTRING(REC_TYPE,0,1) /= 'F')
  17287.      THEN
  17288.      REC_TYPE := 'VAR';
  17289. %    **************************************************
  17290. %    * ASKING ABOUT THE TRANSFER OF FONT/FORM FILES
  17291. %    * IN THE D02 CASE.
  17292. %    **************************************************
  17293.      MSG := '  WILL YOU UPLOAD FONT/FORM FILES?' &
  17294.             ' IF YES,ALL DATA FILES HAVE' &
  17295.             ' ''REL'' ORGANIZATION;' &
  17296.             'DEFAULT IS ' &
  17297.             SUBSTRING(FONT_FORM_DFLT,0,3) &
  17298.             '.' &
  17299.             '[Y,N,X]';
  17300.      ASKPROC (#MSG,/FONT_FORM/);
  17301. %
  17302.      %
  17303.      IF (SUBSTRING(FONT_FORM,0,1) = 'X')
  17304.        THEN
  17305.        DEFAULTS := 'YES';
  17306. %      * SET UP DEFAULT VALUES
  17307.        FONT_FORM := FONT_FORM_DFLT;
  17308.        FILESIZ   := FILESIZ_DFLT;
  17309.        GOTO TAG6;
  17310.      IFEND;
  17311. %
  17312.      IF (SUBSTRING(FONT_FORM,0,1) /= 'Y')
  17313.        THEN
  17314. %      *******************************************
  17315. %      * ASKING ABOUT FILE SIZE
  17316. %      * IN THE D02, VARIABLE, NON FONT/FORM CASE.
  17317. %      *
  17318. %      * THIS IS CONSIDERED TO BE THE 'NORMAL' AND
  17319. %      * DEFAULT CASE
  17320. %      * WHEN USING D02.
  17321. %      *
  17322. %      *
  17323. %      *
  17324. %      *******************************************
  17325. %
  17326.        MSG := '  SPECIFY FILESIZE' &
  17327.               ' BIG ENOUGH FOR THE LARGEST' &
  17328.               ' DATA FILE UPLOADED.' &
  17329.               ' DEFAULT SIZE IS ' &
  17330.               #FILESIZ_DFLT &
  17331.               '/BLOCKS.' &
  17332.               '[NNNN]';
  17333.        ASKPROC (#MSG,/FILESIZ/);
  17334. %
  17335.        IF ((SUBSTRING(FILESIZ,0,1) = '') OR (SUBSTRING(FILESIZ,0,1) = 'A'))
  17336.          THEN
  17337.          FILESIZ := FILESIZ_DFLT;
  17338.        IFEND;
  17339. $TAG6
  17340. %
  17341. %
  17342. %      ************************************************
  17343. %      * ASSIGNING REF=DATAFILE
  17344. %      * IN THE VARIABLE LENGTH RECORD, NON FONT/FORM
  17345. %      * CASE USING D02.
  17346. %      *
  17347. %      * THIS IS CONSIDERED TO BE THE 'NORMAL' AND
  17348. %      * DEFAULT CASE
  17349. %      * WHEN USING D02.
  17350. %      *
  17351. %      ************************************************
  17352.        ASSIGN FILE DATAFILE(REF=DATAFILE,RMS=NO,SUD=D02,FREEUP,
  17353.                  RECORDSIZE=1/485,
  17354.                  DATESCHEME=GEN,
  17355.                  FILESIZE=#FILESIZ/BLOCKS,
  17356.                  NOCAT,
  17357.                  FILETYPE=DATA);
  17358.      ELSE
  17359. %    *********************************************
  17360. %    * ASKING ABOUT FILE SIZE
  17361. %    * IN THE D02, VARIABLE, FONT/FORM CASE.
  17362. %    *
  17363. %    *   FONT/FORM FILES
  17364. %    *
  17365. %    * FILESIZE MUST BE FOR THE LARGEST
  17366. %    *   FONT/FORM FILE ANTICIPATED.
  17367. %    *
  17368. %    ************************************************
  17369. %
  17370. %
  17371.      MSG := '  SPECIFY FILESIZE' &
  17372.             ' BIG ENOUGH FOR THE LARGEST' &
  17373.             ' FONT/FORM FILE UPLOADED.' &
  17374.             ' DEFAULT SIZE IS ' &
  17375.             #FILESIZ_DFLT &
  17376.             '/BLOCKS.' &
  17377.             '[NNNN]';
  17378.      ASKPROC (#MSG,/FILESIZ/);
  17379. %
  17380.      IF ((SUBSTRING(FILESIZ,0,1) = '') OR (SUBSTRING(FILESIZ,0,1) = 'A'))
  17381.        THEN
  17382.        FILESIZ := FILESIZ_DFLT;
  17383.      IFEND;
  17384. %
  17385. %
  17386. %    ************************************************
  17387. %    * ASSIGNING REF=DATAFILE
  17388. %    * IN THE FONT/FORM CASE USING D02.
  17389. %    ************************************************
  17390.      ASSIGN FILE DATAFILE(REF=DATAFILE,RMS=NO,SUD=D02,FREEUP,
  17391. %                ************************************
  17392. %                *  THE FOLLOWING 5 PARAMETERS ARE
  17393. %                *    FOR FONT/FORM UPLOADS
  17394. %                ************************************
  17395.                  ORGANIZATION=RELATIVE,
  17396.                  BLOCKSIZE=1/RECORDS,
  17397.                  CAMHEADER,
  17398.                  RECORDSIZE=1/485,
  17399.                  FILESIZE=#FILESIZ/BLOCKS,
  17400.                  NOCAT,
  17401.                  FILETYPE=DATA);
  17402.      IFEND;
  17403. %
  17404.    ELSE
  17405. %
  17406. %  *********************************************
  17407. %  * ASKING ABOUT FILE SIZE
  17408. %  * IN THE D02, FIXED LENGTH RECORDS, NON
  17409. %  * FONT/FORM CASE.
  17410. %  *
  17411. %  * FIXED LENGTH RECORDS.
  17412. %  *
  17413. %  * CUSTOMIZED FOR FIX ACQUISITION USE.
  17414. %  *
  17415. %  * FILE 'REFERENCE' OF 'DATAFILE' IS USED FOR
  17416. %  *   DATA FILES
  17417. %  *
  17418. %  * FILESIZE MUST BE FOR THE LARGEST
  17419. %  *   FILE ANTICIPATED.
  17420. %  *
  17421. %  ************************************************
  17422. %
  17423. %
  17424.    MSG := '  SPECIFY FILESIZE' &
  17425.           ' BIG ENOUGH FOR THE LARGEST' &
  17426.           ' DATA FILE UPLOADED.' &
  17427.           ' DEFAULT SIZE IS ' &
  17428.           #FILESIZ_DFLT &
  17429.           '/BLOCKS.' &
  17430.           '[NNNN]';
  17431.    ASKPROC (#MSG,/FILESIZ/);
  17432. %
  17433.    IF ((SUBSTRING(FILESIZ,0,1) = '') OR (SUBSTRING(FILESIZ,0,1) = 'A'))
  17434.      THEN
  17435.      FILESIZ := FILESIZ_DFLT;
  17436.    IFEND;
  17437. %
  17438. %
  17439. %  ************************************************
  17440. %  * ASSIGNING REF=DATAFILE
  17441. %  * IN THE FIXED LENGTH RECORD, NON FONT/FORM CASE
  17442. %  * USING D02.
  17443. %  *
  17444. %  * THIS IS CONSIDERED TO BE THE
  17445. %  * 'FIXED ACQUISITION' CASE.
  17446. %  ************************************************
  17447.    ASSIGN FILE DATAFILE(REF=DATAFILE,RMS=NO,SUD=D02,FREEUP,
  17448.                  DATESCHEME=GEN,NOCAT,
  17449. %                ************************************
  17450. %                *  THE FOLLOWING PARAMETERS ARE
  17451. %                *    FOR FIXED LENGTH RECORDS
  17452. %                ************************************
  17453.                  RECORDSIZE=80,
  17454. %                ************************************
  17455. %                * THE FOLLOWING PARAMS ARE FOR
  17456. %                * FIX ACQUISITION
  17457. %                ************************************
  17458. %
  17459.                  NOCAMHEADER,
  17460.                  BLOCKSIZE=6/RECORDS,
  17461.                  FILESIZE=#FILESIZ/BLOCKS,
  17462.                  NOCAT,
  17463.                  FILETYPE=DATA);
  17464.    IFEND;
  17465. %
  17466. %
  17467. %  ****************************************************
  17468. %  * ASSIGNING THE OTHER FILE REFERENCES IN THE
  17469. %  * D02 CASE.
  17470. %  ****************************************************
  17471.    ASSIGN FILE SRCFILE(REF=SRCFILE,RMS=NO,SUD=D02,FREEUP,
  17472.                RECORDSIZE=1/82,
  17473.                FILESIZE=300/BLOCKS,DATESCHEME=GEN,NOCAT,
  17474.                FILETYPE=SOURCE),
  17475.           FILE OBJFILE(REF=OBJFILE,RMS=NO,SUD=D02,FREEUP,
  17476.                FILESIZE=1000/BLOCKS,RECORDSIZE=1/490,
  17477.                DATESCHEME=GEN,FILETYPE=OBJECT,NOCAT),
  17478.           FILE CSFILE(REF=CSFILE,RMS=NO,SUD=D02,FREEUP,
  17479.                FILESIZE=100/BLOCKS,RECORDSIZE=1/82,NOCAT,
  17480.                DATESCHEME=GEN,FILETYPE='CONTROL STRING');
  17481.    FILEL NOCAT/CAT;
  17482. %  ******************************************************
  17483. %  * END OF THE SUD=D02 CASE.
  17484. %  ******************************************************
  17485.    IFEND;
  17486. %
  17487. END;
  17488. ASSIGN PRINTER P09(SUD=P09);
  17489. MCLBEGIN;
  17490.                  MEMORYREALTIME=YES
  17491.                        SWAP OUT TIME=NEVER
  17492.                  SCLBGN
  17493. % MUST SPECIFY LOCATION OF LOAD MODULE
  17494. EXECUTE MCSKERM;
  17495.    QUEUE P09;
  17496.    FREE P09;
  17497. %
  17498.    IF (VSN /= '') THEN
  17499.      FREE D02;
  17500.    IFEND;
  17501. %
  17502.                  JOB   END
  17503. <<< mcskndlj.n3 >>>
  17504.        MCSKNDLJ  CATJOB
  17505.        MCSKNDLJ  JOB   NAME=XXXXXX,ACCT=XXXX,SIZE=512
  17506.                        JPTY=4,RMINMEM=42,VMAXMEM=128
  17507.                        USERID=XXX,PASSWORD=XXXXXX
  17508.                        LOCALDSA=600,STACKSIZE=250
  17509.                        JOBCONTROL = SCL
  17510.                  UNIT  SUD=D02,VOL=525252
  17511.                  SPCEND
  17512.  % This job builds the MCSKNDL object module.  This module
  17513.  % should be linked into the MCS-KERMIT load object module
  17514.  % MCSKLOBJ.  It defines the primary MCS queue and the
  17515.  % communication links that MCS-KERMIT will use.  The module
  17516.  % is created using the Network Description Langauge (NDL).
  17517.  FILEL CAT/NOCAT;
  17518.  FILEC CAT;
  17519.  FILEN $.XXXXXXXXX;
  17520.  MCLBEGIN;
  17521.                  NEXTDONDLP
  17522.                  STOPRD
  17523.        MCSKNDL   MCS   ENTRY = C_START, QUEUE = 'THE_QUEUE   '
  17524.                        OPRTN = NONE, PASSWD = PASSWORD
  17525.                        UNSOLIP = 'THE_QUEUE   '
  17526.                  LINK  SUD=A002, BUFF = 2400
  17527.                        INPUT=5
  17528.                  TERM  SPEED = 9600,TIMES=0, NETWORK = P/LB
  17529.                        CODE = ASCII/N, RETRY = 0/0/3
  17530.                        NAMES='THE_QUEUE   '/'INPUT       '/'OUTPUT      '
  17531.                        TYPE = 7961
  17532. END$
  17533.        MCSKNDLJ  JOB   END
  17534. <<< packing.lst >>>
  17535. /**********************************************************************
  17536. *                                                   *
  17537. * Packing List                                                        *
  17538. *                                                                     *
  17539. * This floppy contains IVS-Kermit & MCS-Kermit source code,           *
  17540. * compilation instructions, linkedit jobfiles, and user               *
  17541. * documentation.                                                      *
  17542. *                                                                     *
  17543. * IVS-Kermit & MCS-Kermit file names use the Unix file naming         *
  17544. * convention as used in C-Kermit. Both products are based on          *
  17545. * C-Kermit(4E) with features added or deleted depending on            *
  17546. * VRX system capabilities, and NCR selected product content.          *
  17547. * Module names reflect the same usage as in C-Kermit(4E).             *
  17548. * New modules have a short explanation.                               *
  17549. *                                                                     *
  17550. * IVS-Kermit and MCS-Kermit share common source code. MCS-Kermit      *
  17551. * has two additional files to interface to the MCS telecommunications *
  17552. * facility. MCS modules are labeled MCS ONLY.                         *
  17553. *                                                                     *
  17554. * June 22, 1990                                                       *
  17555. *                                                                     *
  17556. ***********************************************************************/
  17557.  
  17558.  
  17559.         CKCDEB   H    IVS / MCS-Kermit header file
  17560.         CKVFN2   C    IVS / MCS-Kermit C source module
  17561.         CKVFNS   C    IVS / MCS-Kermit C source module
  17562.         CKCKER   H    IVS / MCS-Kermit header file
  17563.         CKVMAI   C    IVS / MCS-Kermit C source module
  17564.         CKVPRO   C    IVS / MCS-Kermit C source module
  17565.         CKUSYM   H    IVS / MCS-Kermit header file
  17566.         CKVCMD   C    IVS / MCS-Kermit C source module
  17567.         CKUCMD   H    IVS / MCS-Kermit header file
  17568.         CKVCON   C    IVS / MCS-Kermit C source module
  17569.         CKVDIA   C    IVS / MCS-Kermit C source module
  17570.         CKVFI2   C    IVS / MCS-Kermit C source module
  17571.         CKVSCR   C    IVS / MCS-Kermit C source module
  17572.         CKVTIO   C    IVS / MCS-Kermit C source module
  17573.         CKVUS2   C    IVS / MCS-Kermit C source module
  17574.         CKVUS3   C    IVS / MCS-Kermit C source module
  17575.         CKVUSR   C    IVS / MCS-Kermit C source module
  17576.         CKUUSR   H    IVS / MCS-Kermit header file
  17577.         CKVFIO   C    IVS / MCS-Kermit C source module
  17578.         CKVMCS   C    MCS-Kermit C source module  MCSONLY
  17579.                       MCS system I/F routines
  17580.         CKVBUF   C    MCS-Kermit C source module
  17581.                       Buffering routines for MCS I/F
  17582.         COMPILE  INS  Compilation instructions
  17583.         KERMISC  H    IVS / MCS-Kermit header file
  17584.         IVSKPM   PRO  SCL routine to execute IVS-Kermit
  17585.         MCS      H    MCS-Kermit header file: used to
  17586.                       redefine fgets, fputs, etc.
  17587.         MCS_DEFS H    MCS control structures
  17588.         MCSKJ    N3   SCL jobfile to execute MCS-Kermit
  17589.         PWD      H    IVS / MCS-Kermit header file*
  17590.         SGTTY    H    IVS / MCS-Kermit header file*
  17591.         SIGNAL   H    IVS / MCS-Kermit header file*
  17592.         TYPES    H    IVS / MCS-Kermit header file*
  17593.         VKNCRLIO NCR  IVS / MCS-Kermit C source module
  17594.         VRX      H    IVS / MCS-Kermit header file
  17595.         MCSKNDLJ N3   NDL compilation jobfile to specify
  17596.                       terminal / queue characterisitics,
  17597.                       and produce NDL object.
  17598.         LINKMCS  PRO  LinkEdit SCL procedure file used
  17599.                       to link MCS-Kermit
  17600.         LNK1KSRC N3   LinkEdit jobfile used to link
  17601.                       IVS-Kermit
  17602.         PACKING  LST  This list
  17603.  
  17604.         VKERMIT  DOC  VKermit documentation
  17605.  
  17606.  
  17607. * These files do not exist on a VRX/VE system, they are
  17608.   placed in either the compilation catalog node or disk.
  17609. <<< pwd.h >>>
  17610. struct passwd {
  17611.     char    *pw_name;
  17612.     char    *pw_passwd;
  17613.     int        pw_uid;
  17614.     int      pw_gid;
  17615.     char    *pw_age;
  17616.     char    *pw_comment;
  17617.     char    *pw_gecos;
  17618.     char    *pw_dir;
  17619.     char    *pw_shell;
  17620. };
  17621.  
  17622. struct comment {
  17623.     char    *c_dept;
  17624.     char    *c_name;
  17625.     char    *c_acct;
  17626.     char    *c_bin;
  17627. };
  17628. <<< sgtty.h >>>
  17629. struct sgttyb {
  17630.     char    sg_ispeed;        /* input speed */
  17631.     char    sg_ospeed;        /* output speed */
  17632.     char    sg_erase;        /* erase character */
  17633.     char    sg_kill;        /* kill character */
  17634.     int    sg_flags;        /* mode flags */
  17635. };
  17636.  
  17637. /*
  17638.  * Modes
  17639.  */
  17640. #define    HUPCL    01
  17641. #define    XTABS    02
  17642. #define    LCASE    04
  17643. #define    ECHO    010
  17644. #define    CRMOD    020
  17645. #define    RAW    040
  17646. #define    ODDP    0100
  17647. #define    EVENP    0200
  17648. #define ANYP    0300
  17649. #define    NLDELAY    001400
  17650. #define    TBDELAY    002000
  17651. #define    CRDELAY    030000
  17652. #define    VTDELAY    040000
  17653. #define BSDELAY 0100000
  17654. #define ALLDELAY 0177400
  17655.  
  17656. /*
  17657.  * Delay algorithms
  17658.  */
  17659. #define    CR0    0
  17660. #define    CR1    010000
  17661. #define    CR2    020000
  17662. #define    CR3    030000
  17663. #define    NL0    0
  17664. #define    NL1    000400
  17665. #define    NL2    001000
  17666. #define    NL3    001400
  17667. #define    TAB0    0
  17668. #define    TAB1    002000
  17669. #define    NOAL    004000
  17670. #define    FF0    0
  17671. #define    FF1    040000
  17672. #define    BS0    0
  17673. #define    BS1    0100000
  17674.  
  17675. /*
  17676.  * Speeds
  17677.  */
  17678. #define B0    0
  17679. #define B50    1
  17680. #define B75    2
  17681. #define B110    3
  17682. #define B134    4
  17683. #define B150    5
  17684. #define B200    6
  17685. #define B300    7
  17686. #define B600    8
  17687. #define B1200    9
  17688. #define    B1800    10
  17689. #define B2400    11
  17690. #define B4800    12
  17691. #define B9600    13
  17692. #define EXTA    14
  17693. #define EXTB    15
  17694.  
  17695. /*
  17696.  *    ioctl arguments
  17697.  */
  17698. #define FIOCLEX        (('f'<<8)|1)
  17699. #define FIONCLEX    (('f'<<8)|2)
  17700. #define    TIOCHPCL    (('t'<<8)|2)
  17701. #define    TIOCGETP    (('t'<<8)|8)
  17702. #define    TIOCSETP    (('t'<<8)|9)
  17703. #define    TIOCEXCL    (('t'<<8)|13)
  17704. #define    TIOCNXCL    (('t'<<8)|14)
  17705. <<< signal.h >>>
  17706. #define SIG_DFL (int (*)())0
  17707. #define SIG_IGN (int (*)())1
  17708.  
  17709. extern int (*ssignal())();
  17710.  
  17711. #ident "@(#)signal.h    5.4"
  17712. #define    SIGINT    2    /* interrupt (rubout) */
  17713. #define    SIGQUIT    3    /* quit (ASCII FS) */
  17714. #define    SIGILL    4    /* illegal instruction (not reset when caught)*/
  17715. #define    SIGTRAP    5    /* trace trap (not reset when caught) */
  17716. #define    SIGIOT    6    /* IOT instruction */
  17717. #define    SIGEMT    7    /* EMT instruction */
  17718. #define    SIGFPE    8    /* floating point exception */
  17719. #define    SIGKILL    9    /* kill (cannot be caught or ignored) */
  17720. #define    SIGBUS    10    /* bus error */
  17721. #define    SIGSEGV    11    /* segmentation violation */
  17722. #define    SIGSYS    12    /* bad argument to system call */
  17723. #define    SIGPIPE    13    /* write on a pipe with no one to read it */
  17724. #define    SIGALRM    14    /* alarm clock */
  17725. #define    SIGTERM    15    /* software termination signal from kill */
  17726. #define    SIGUSR1    16    /* user defined signal 1 */
  17727. #define    SIGUSR2    17    /* user defined signal 2 */
  17728. #define    SIGCLD    18    /* death of a child */
  17729. #define    SIGPWR    19    /* power-fail restart */
  17730. #define    NSIG    20
  17731. <<< types.h >>>
  17732. typedef    struct { int r[1]; } *    physadr;
  17733. typedef    long        daddr_t;
  17734. typedef    char *        caddr_t;
  17735. typedef    unsigned int    uint;
  17736. typedef    unsigned short    ushort;
  17737. typedef    ushort        ino_t;
  17738. typedef short        cnt_t;
  17739. typedef    long        time_t;
  17740. typedef    int        label_t[13];
  17741. typedef    short        dev_t;
  17742. typedef    long        off_t;
  17743. typedef    long        paddr_t;
  17744. typedef    long        key_t;
  17745. <<< vkncrlio.ncr >>>
  17746. 000010?? TITLE := 'VKNCRLIO - NCRL I/O FOR OBJECT FILES' ??
  17747. 000020module vkncrlio;
  17748. 000030 "
  17749.        /**********************************************************************
  17750.         *                                                                     *
  17751.         * IVS / MCS-Kermit REL 2                                              *
  17752.         * source code                                                         *
  17753.         *                                                                     *
  17754.         * Change History:                                                     *
  17755.         *                                                                     *
  17756.         *                1. Modify C-Kermit(4E) source code to                *
  17757.         *                   produce new module for MCS/IVS-Kermit             *
  17758.         *                   ORIGINAL RELEASE                                  *
  17759.         *                   June 22, 1990                                     *
  17760.         *                                                                     *
  17761.         *                                                                     *
  17762.         ***********************************************************************/
  17763.  
  17764. 000040  This module provides NCRL runtime interfaces to perform
  17765. 000050  I/O on VRX object files.
  17766. 000060 "
  17767. 000070
  17768. 000080*CALL FOR0307.COMPILATION_CONTROL_DEFINITION,SUD=D04
  17769. 000090*CALL SYS0015.SYSTEM_DEFINITIONS,SUD=D04
  17770. 000100*CALL VRXMAIN.VRXNCRL,SUD=D04
  17771. 000110*CALL SYSPROCS.SET_FILE_REFERENCE,SUD=D04
  17772. 000120*CALL SYSPROCS.SETOUTCOME,SUD=D04
  17773. 000130*CALL SYSPROCS.VRXOUTCOME,SUD=D04
  17774. 000140
  17775. 000150
  17776. 000160?? OLDTITLE ??
  17777. 000170?? NEWTITLE := 'GLOBAL TYPES AND VARIABLES' ??
  17778. 000180?? EJECT ??
  17779. 000190
  17780. 000200 type
  17781. 000210    legible_type = (leginfile, legoutfile),
  17782. 000220    nio_result = (nio_ok, nio_bad, nio_eof);
  17783. 000230
  17784. 000240  "Dummy types for clean compiles"
  17785. 000250 type
  17786. 000260   task_descriptor_block = cell;
  17787. 000270
  17788. 000280 var
  17789. 000290   errcell : [xref] integer;  " we pass back bad outcomes to
  17790. 000300                                a global int for output to
  17791. 000310                                screen and stderr "
  17792. 000320
  17793. 000330?? OLDTITLE ??
  17794. 000340?? NEWTITLE := 'OBJOPENI' ??
  17795. 000350?? EJECT ??
  17796. 000360  proc [XDCL] objopeni (
  17797. 000370    ref
  17798. 000380      fname: string (*) of char,
  17799. 000390      fref: string (*) of char,
  17800. 000400      myfile: legible,
  17801. 000410      result: nio_result);
  17802. 000420
  17803. 000430  var
  17804. 000440    infile : legible := [#OLD, #IN, fname],
  17805. 000450    refset : boolean,
  17806. 000460    transfer_ptr1 : ^string( * ) of char,
  17807. 000470    transfer_ptr2 : ^string( * ) of char;
  17808. 000480
  17809. 000490    result := nio_ok;
  17810. 000500
  17811. 000510   " Determine the file operation and set myfile parameter.
  17812. 000520     This must be done indirectly with bind statements since
  17813. 000530     NCRL does not allow the direct assignments of legible files.
  17814. 000540    "
  17815. 000550      bind transfer_ptr1 : [#size(legible)] to #loc(infile);
  17816. 000560
  17817. 000570    bind transfer_ptr2 : [#size(legible)] to #loc(myfile);
  17818. 000580    transfer_ptr2^ (1, *) := transfer_ptr1^ (1, *);
  17819. 000590
  17820. 000600    "
  17821. 000610     Set the file reference so FCL can be used on the file.
  17822. 000620     The filetype and recordsize must be set to be appropriate
  17823. 000630     for object files in FCL as there is no way to do it with
  17824. 000640     NCRL I/O.
  17825. 000650    "
  17826. 000660    set_file_reference($SYSPROCS#FILEREC[LEGF, ^myfile], fref,
  17827. 000670      refset);
  17828. 000680    if (not refset) then
  17829. 000690      result := nio_bad;
  17830. 000700      return;
  17831. 000710    ifend;
  17832. 000720
  17833. 000730    " all #open, #put, #get, #close
  17834. 000740    we check the outcome from :CAM with
  17835. 000750    the vrxoutcome function call. we
  17836. 000760    do not have to setoutcome to ok or 0
  17837. 000770    this is done just in case. At least
  17838. 000780    this way nothing bites us later
  17839. 000790    PEG March 6, 1990 "
  17840. 000800
  17841. 000810    setoutcome(ok);
  17842. 000820
  17843. 000830    #open(myfile);
  17844. 000840
  17845. 000850    if (vrxoutcome() /= ok ) then
  17846. 000860       result := nio_bad;
  17847. 000870       errcell := vrxoutcome();
  17848. 000880       return;
  17849. 000890    ifend;
  17850. 000900
  17851. 000910  procend objopeni;
  17852. 000920?? OLDTITLE ??
  17853. 000930?? NEWTITLE := 'OBJOPENO' ??
  17854. 000940?? EJECT ??
  17855. 000950  proc [XDCL] objopeno (
  17856. 000960    ref
  17857. 000970      fname: string (*) of char,
  17858. 000980      fref: string (*) of char,
  17859. 000990      myfile: legible,
  17860. 001000      result: nio_result);
  17861. 001010
  17862. 001020  var
  17863. 001030    outfile : legible := [#NEW, #OUT, fname],
  17864. 001040    refset : boolean,
  17865. 001050    transfer_ptr1 : ^string( * ) of char,
  17866. 001060    transfer_ptr2 : ^string( * ) of char;
  17867. 001070
  17868. 001080    result := nio_ok;
  17869. 001090
  17870. 001100   " Determine the file operation and set myfile parameter.
  17871. 001110     This must be done indirectly with bind statements since
  17872. 001120     NCRL does not allow the direct assignments of legible files.
  17873. 001130    "
  17874. 001140      bind transfer_ptr1 : [#size(legible)] to #loc(outfile);
  17875. 001150
  17876. 001160    bind transfer_ptr2 : [#size(legible)] to #loc(myfile);
  17877. 001170    transfer_ptr2^ (1, *) := transfer_ptr1^ (1, *);
  17878. 001180
  17879. 001190    "
  17880. 001200     Set the file reference so FCL can be used on the file.
  17881. 001210     The filetype and recordsize must be set to be appropriate
  17882. 001220     for object files in FCL as there is no way to do it with
  17883. 001230     NCRL I/O.
  17884. 001240    "
  17885. 001250    set_file_reference($SYSPROCS#FILEREC[LEGF, ^myfile], fref,
  17886. 001260      refset);
  17887. 001270    if (not refset) then
  17888. 001280      result := nio_bad;
  17889. 001290      return;
  17890. 001300    ifend;
  17891. 001310
  17892. 001320    setoutcome(ok);
  17893. 001330    #open(myfile);
  17894. 001340
  17895. 001350    if (vrxoutcome() /= ok ) then
  17896. 001360       result := nio_bad;
  17897. 001370       errcell := vrxoutcome();
  17898. 001380       return;
  17899. 001390    ifend;
  17900. 001400
  17901. 001410  procend objopeno;
  17902. 001420?? OLDTITLE ??
  17903. 001430?? NEWTITLE := 'OBJCLOSE' ??
  17904. 001440?? EJECT ??
  17905. 001450  proc [XDCL] objclose (
  17906. 001460    ref
  17907. 001470      closefile: legible,
  17908. 001480      result   : nio_result);
  17909. 001490
  17910. 001500    setoutcome(ok);
  17911. 001510    #close(closefile);
  17912. 001520    if (vrxoutcome() /= ok ) then
  17913. 001530       result := nio_bad;
  17914. 001540       errcell := vrxoutcome();
  17915. 001550       return;
  17916. 001560    ifend;
  17917. 001570
  17918. 001580  procend objclose;
  17919. 001590?? OLDTITLE ??
  17920. 001600?? NEWTITLE := 'OBJRECIN' ??
  17921. 001610?? EJECT ??
  17922. 001620  proc [XDCL] objrecin (
  17923. 001630    ref
  17924. 001640      infile: legible,
  17925. 001650      buf: string (*) of char,
  17926. 001660      charsread : integer,
  17927. 001670      result: nio_result);
  17928. 001680
  17929. 001690    "
  17930. 001700     This routine reads the next record into a buffer. The VLI
  17931. 001710     is reconstructed and placed at the beginning of the buffer.
  17932. 001720     The buffer (including room for the VLI) must be allocated by
  17933. 001730     caller. The file must have been opened by objopen.
  17934. 001740    "
  17935. 001750
  17936. 001760    "Repeat until a good read, skipping over empty records.
  17937. 001770     Note that one place this may happen is just before EOF
  17938. 001780     is detected."
  17939. 001790
  17940. 001800    repeat
  17941. 001810      if #EOF(infile) then
  17942. 001820        result := nio_eof;
  17943. 001830        return;
  17944. 001840      else
  17945. 001850        result := nio_ok;
  17946. 001860      ifend;
  17947. 001870
  17948. 001880      setoutcome(ok);
  17949. 001890      #GET(infile, charsread, buf(3, *));
  17950. 001900      if (vrxoutcome() /= ok ) then
  17951. 001910          result := nio_bad;
  17952. 001920          errcell := vrxoutcome();
  17953. 001930          return;
  17954. 001940      ifend;
  17955. 001950
  17956. 001960      if (charsread > 0) then
  17957. 001970        " Add the VLI to the beginning "
  17958. 001980        buf (2) := $char (charsread mod 256);
  17959. 001990        buf (1) := $char ((charsread / 256) mod 256);
  17960. 002000      ifend;
  17961. 002010    until ((charsread > 0) or (result = nio_eof));
  17962. 002020
  17963. 002030  procend objrecin;
  17964. 002040?? OLDTITLE ??
  17965. 002050?? NEWTITLE := 'OBJRECOUT' ??
  17966. 002060?? EJECT ??
  17967. 002070  proc [XDCL] objrecout (
  17968. 002080    ref
  17969. 002090      outfile: legible,
  17970. 002100      buf: string (*) of char,
  17971. 002110      result: nio_result);
  17972. 002120
  17973. 002130  var
  17974. 002140    charstowrite: integer;
  17975. 002150
  17976. 002160    result := nio_ok;
  17977. 002170    charstowrite := ($integer(buf(1)) * 256) + $integer(buf(2));
  17978. 002180
  17979. 002190    setoutcome(ok);
  17980. 002200
  17981. 002210    #PUT(outfile, buf (3, charstowrite) );
  17982. 002220
  17983. 002230    if (vrxoutcome() /= ok ) then
  17984. 002240       result := nio_bad;
  17985. 002250       errcell := vrxoutcome();
  17986. 002260       return;
  17987. 002270    ifend;
  17988. 002280
  17989. 002290  procend objrecout;
  17990. 002300modend vkncrlio;
  17991. <<< vrx.h >>>
  17992. #define BASIC        1111577344
  17993. #define OBJECT       1329744384
  17994. #define BINARY       1112100352
  17995. #define CS           1129512960
  17996. #define DATA         1145132032
  17997. #define NCRL         1313034752
  17998. #define FORTB        1178730496
  17999. #define FORTI        1179189248
  18000. #define FORTF        1178992640
  18001. #define FORTV        1180041216
  18002. #define NEAT3        1311965184
  18003. #define NEATVS       1314280192
  18004. #define NEATC        1313013760
  18005. #define COBOL        1129250816
  18006. #define COBOL6       1129264640
  18007. #define COBOL7       1129264896
  18008. #define COBOL8       1129265152
  18009. #define COBOL1       1129263360
  18010. #define COBOL16      1127298560
  18011. #define COBOL17      1127298816
  18012. #define COBOL18      1127299072
  18013. #define COBOL4       1129264128
  18014. #define PROC         1347571456
  18015. #define PROCN        1347571200
  18016. #define L_BASIC      1650553600
  18017. #define L_OBJECT     1868720640
  18018. #define L_BINARY     1651076608
  18019. #define L_CS         1668481024
  18020. #define L_DATA       1684108288
  18021. #define L_NCRL       1852011008
  18022. #define L_FORTB      1717698560
  18023. #define L_FORTI      1718157312
  18024. #define L_FORTF      1717960704
  18025. #define L_FORTV      1719009280
  18026. #define L_NEAT3      1848836096
  18027. #define L_NEATVS     1853256448
  18028. #define L_NEATC      1851981824
  18029. #define L_COBOL      1668218880
  18030. #define L_COBOL6     1668232704
  18031. #define L_COBOL7     1668232960
  18032. #define L_COBOL8     1668233216
  18033. #define L_COBOL1     1668231424
  18034. #define L_COBOL16    1664169472
  18035. #define L_COBOL17    1664169728
  18036. #define L_COBOL18    1664169984
  18037. #define L_COBOL4     1668232192
  18038. #define L_PROC       1886547712
  18039. #define L_PROCN      1886547456
  18040.  
  18041. #define ID_START          0
  18042. #define ID_LEN            1
  18043. #define REC_LEN           2
  18044. #define NUM_FIELD_LEN     3
  18045. #define MAX_SPURTYPE     21
  18046. #define MAX_FIELD         8
  18047. #define DATA_LEN         90
  18048. #define NUM_LEN           6
  18049. #define LINE_LEN        140
  18050. #define TAIL_LEN        100
  18051. #define HEAD_END          6
  18052. #define INCREMENT        10
  18053.  
  18054. int spur_info[MAX_SPURTYPE * 4] = {
  18055.         6, 0, 0, 0, 0, 6, 6, 6, 8, 0, 8, 7, 6, 0, 0, 0, 0, 8, 7, 6, 6,
  18056.         8, 0, 0, 0, 0, 2, 7, 7, 6, 0, 6, 7, 8, 0, 0, 0, 0, 6, 7, 8, 8,
  18057.        72,80,80,80,80,78,73,73,74,80,74,73,72,80,80,80,80,74,73,72,72,
  18058.         6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
  18059. };
  18060.  
  18061.