home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / old / ckermit60 / ckuusy.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  24KB  |  972 lines

  1. #include "ckcsym.h"
  2. #define XFATAL fatal
  3.  
  4. #ifndef NOCMDL
  5.  
  6. /*  C K U U S Y --  "User Interface" for Unix Kermit, part Y  */
  7.  
  8. /*  Command-Line Argument Parser */
  9.  
  10. /*
  11.   Author: Frank da Cruz (fdc@columbia.edu),
  12.   Columbia University, New York City.
  13.  
  14.   Copyright (C) 1985, 1996, Trustees of Columbia University in the City of
  15.   New York.  All rights reserved.
  16. */
  17.  
  18. #ifdef COMMENT
  19.   Census of command-line options ( "grep ^case ckuusy.c | sort" :-)
  20.   Update this if you add a new one:
  21.  
  22. case '8':                /* 8-bit clean */
  23. case 'B':                /* Batch (no controlling terminal) */
  24. case 'C':                /* Commands for parser */
  25. case 'D':                /* Delay */
  26. case 'E':                /* Exit on close */
  27. case 'F':                /* Socket file descriptor */
  28. case 'J':                /* Like j but exits on disconnect */
  29. case 'M':                /* Username for Telnet, Rlogin, etc */
  30. case 'N':                       /* NetBios Adapter Number follows */
  31. case 'P':                /* Pipe */
  32. case 'Q':                /* Use quick settings */
  33. case 'R':                /* Remote-Only */
  34. case 'S':                /* "Stay" - enter interactive */
  35. case 'T':                /* Text file transfer mode */
  36. case 'U':                               /* X.25 call user data */
  37. case 'W':                /* Win32 Window Handle */
  38. case 'X':                /* SET HOST to X.25 address */
  39. case 'Y':                /* No initialization file */
  40. case 'Z':                /* SET HOST to X.25 file descriptor */
  41. case 'a':                /* "as" */
  42. case 'b':                       /* set bits-per-second for serial */
  43. case 'c':                /* connect before */
  44. case 'd':                /* DEBUG */
  45. case 'e':                /* Extended packet length */
  46. case 'f':                /* finish */
  47. case 'g':                /* get */
  48. case 'h':                /* help */
  49. case 'i':                /* Treat files as binary */
  50. case 'j':                /* SET HOST (TCP/IP socket) */
  51. case 'k':                /* receive to stdout */
  52. case 'l':                /* SET LINE */
  53. case 'm':                /* Modem type */
  54. case 'n':                /* connect after */
  55. case 'o':                               /* X.25 closed user group */
  56. case 'p':                /* SET PARITY */
  57. case 'q':                /* Quiet */
  58. case 'r':                /* receive */
  59. case 's':                 /* send */
  60. case 't':                /* Line turnaround handshake */
  61. case 'u':                               /* X.25 reverse charge call */
  62. case 'v':                /* Vindow size */
  63. case 'w':                /* Writeover */
  64. case 'x':                /* server */
  65. case 'y':                /* Alternate init-file name */
  66. case 'z':                /* Not background */
  67. #endif /* COMMENT */
  68.  
  69. #include "ckcdeb.h"
  70. #include "ckcasc.h"
  71. #include "ckcker.h"
  72. #include "ckucmd.h"
  73. #include "ckcnet.h"
  74. #include "ckuusr.h"
  75.  
  76. #ifdef OS2
  77. #include <io.h>
  78. #endif /* OS2 */
  79.  
  80. #ifdef NETCONN
  81. #ifdef ANYX25
  82. extern int revcall, closgr, cudata;
  83. extern char udata[];
  84. extern int x25fd;
  85. #endif /* ANYX25 */
  86. #ifndef VMS
  87. #ifndef OS2
  88. #ifndef OSK
  89. extern
  90. #endif /* OSK */
  91. #endif /* OS2 */
  92. #endif /* VMS */
  93.  
  94. int telnetfd;
  95. extern struct keytab netcmd[];
  96. extern int tn_exit;
  97. #ifndef NOICP
  98. #ifndef NODIAL
  99. extern int nnets, nnetdir;        /* Network services directory */
  100. extern char *netdir[];
  101. extern char *nh_p[];            /* Network directory entry pointers */
  102. extern char *nh_p2[];            /* Network directory entry nettype */
  103. #endif /* NODIAL */
  104. extern int nhcount;
  105. extern char * n_name;            /* Network name pointer */
  106. #endif /* NOICP */
  107. #endif /* NETCONN */
  108.  
  109. #ifndef NOSPL
  110. extern char uidbuf[];
  111. #endif /* NOSPL */
  112.  
  113. extern char *ckxsys, *ckzsys, *cmarg, *cmarg2, **xargv, **cmlist, *clcmds;
  114. extern int action, cflg, xargc, stdouf, stdinf, displa, cnflg, nfils,
  115.   local, quiet, escape, network, mdmtyp, maxrps, rpsiz, bgset, backgrd, xargs,
  116.   urpsiz, wslotr, swcapr, binary, warn, parity, turn, turnch, duplex, flow,
  117.   fncact, clfils, noinit, stayflg, nettype, cfilef, delay, noherald,
  118.   cmask, cmdmsk, backgrd, exitonclose;
  119. extern long speed;
  120. extern char ttname[];
  121. extern char * pipedata;
  122.  
  123. #ifdef OS2
  124. extern struct keytab os2devtab[];
  125. extern int nos2dev;
  126. extern int ttslip;
  127. #ifdef OS2PM
  128. extern int os2pm;
  129. #endif /* OS2PM */
  130. #endif /* OS2 */
  131.  
  132. #ifdef CK_NETBIOS
  133. extern unsigned char NetBiosAdapter;
  134. #endif /* CK_NETBIOS */
  135.  
  136. #ifdef XFATAL
  137. #undef XFATAL
  138. #endif /* XFATAL */
  139.  
  140. #ifndef NOICP
  141. #ifndef NODIAL
  142. extern int nmdm, telephony;
  143. extern struct keytab mdmtab[];
  144. extern int usermdm, dialudt;
  145. #endif /* NODIAL */
  146. extern int what;
  147. _PROTOTYP(static int pmsg, (char *) );
  148. _PROTOTYP(static int fmsg, (char *) );
  149. static int pmsg(s) char *s; { printf("%s\n", s); return(0); }
  150. static int fmsg(s) char *s; { fatal(s); return(0); }
  151. #define XFATAL(s) return(what==W_COMMAND?pmsg(s):fmsg(s))
  152. #else
  153. #define XFATAL fatal
  154. #endif /* NOICP */
  155.  
  156. VOID
  157. fatal2(msg1,msg2) char *msg1, *msg2; {
  158.     char buf[256];
  159.     if (!msg1) msg1 = "";
  160.     if (!msg2) msg2 = "";
  161.     sprintf(buf,"\"%s\" - %s",msg1,msg2);
  162. #ifndef NOICP
  163.     if (what == W_COMMAND)
  164.       printf("%s\n",buf);
  165.     else
  166. #endif /* NOICP */
  167.       fatal((char *)buf);
  168. }
  169.  
  170. /*  C M D L I N  --  Get arguments from command line  */
  171. /*
  172.  Simple Unix-style command line parser, conforming with 'A Proposed Command
  173.  Syntax Standard for Unix Systems', Hemenway & Armitage, Unix/World, Vol.1,
  174.  No.3, 1984.
  175. */
  176. int
  177. cmdlin() {
  178.     char x;                /* Local general-purpose char */
  179.  
  180.     cmarg = "";                /* Initialize globals */
  181.     cmarg2 = "";
  182.     action = 0;
  183.     cflg = 0;
  184.  
  185.     debug(F111,"cmdlin",*xargv,xargc);
  186.  
  187. /* If we were started directly from a Kermit application file, its name is */
  188. /* in argv[1], so skip past it. */
  189.  
  190.     debug(F101,"cmdlin cfilef","",cfilef);
  191.     if (xargc > 1) {
  192.     if (*xargv[1] != '-') {
  193.         if (cfilef) {        /* Command file found in prescan() */
  194.         xargc -= 1;        /* Skip past it */
  195.         xargv += 1;
  196.         cfilef = 0;
  197.         }
  198.     }
  199.     }
  200.     while (--xargc > 0) {        /* Go through command line words */
  201.     xargv++;
  202.     debug(F111,"xargv",*xargv,xargc);
  203.     if (**xargv == '=') return(0);
  204. #ifdef VMS
  205.     else if (**xargv == '/') continue;
  206. #endif /* VMS */
  207.         else if (**xargv == '-') {    /* Got an option (begins with dash) */
  208.         x = *(*xargv+1);        /* Get the option letter */
  209.         if (doarg(x) < 0) {
  210. #ifndef NOICP
  211.         if (what == W_COMMAND)
  212.           return(0);
  213.         else
  214. #endif /* NOICP */
  215.           {
  216. #ifdef OS2
  217.               sleep(1);        /* Give it a chance... */
  218. #endif /* OS2 */
  219.               doexit(BAD_EXIT,1); /* Go handle option */
  220.           }
  221.         }
  222.         } else {            /* No dash where expected */
  223.         fatal2(*xargv,
  224. #ifdef NT
  225.            "invalid command-line option, type \"k95 -h\" for help"
  226. #else
  227. #ifdef OS2
  228.            "invalid command-line option, type \"ckermit -h\" for help"
  229. #else
  230.            "invalid command-line option, type \"kermit -h\" for help"
  231. #endif /* OS2 */
  232. #endif /* NT */
  233.            );
  234.     }
  235.     }
  236.     debug(F101,"action","",action);
  237. #ifndef NOLOCAL
  238.     if (!local) {
  239.     if ((action == 'c') || (cflg != 0)) {
  240.         XFATAL("-l or -j or -X required");
  241.     }
  242.     }
  243. #endif /* NOLOCAL */
  244.     if (*cmarg2 != 0) {
  245.     if ((action != 's') && (action != 'r') && (action != 'v')) {
  246.         XFATAL("-a without -s, -r, or -g");
  247.     }
  248.     if (action == 'r' || action == 'v') {
  249. #ifdef CK_TMPDIR
  250.         if (isdir(cmarg2)) {    /* -a is a directory */
  251.         if (!zchdir(cmarg2)) {    /* try to change to it */
  252.             XFATAL("can't change to '-a' directory");
  253.         } else cmarg2 = "";
  254.         } else
  255. #endif /* CK_TMPDIR */
  256.           if (zchko(cmarg2) < 0) {
  257.           XFATAL("write access to -a file denied");
  258.           }
  259.     }
  260.     }
  261.     if ((action == 'v') && (stdouf) && (!local)) {
  262.     if (is_a_tty(1)) {
  263.         XFATAL("unredirected -k can only be used in local mode");
  264.     }
  265.     }
  266.     if ((action == 's') || (action == 'v') ||
  267.     (action == 'r') || (action == 'x')) {
  268.     if (local)
  269.       displa = 1;
  270.     if (stdouf) {
  271.         displa = 0;
  272.         quiet = 1;
  273.     }
  274.     }
  275.     if (quiet) displa = 0;        /* No display if quiet requested */
  276.     return(action);            /* Then do any requested protocol */
  277. }
  278.  
  279. /*  D O A R G  --  Do a command-line argument.  */
  280.  
  281. int
  282. #ifdef CK_ANSIC
  283. doarg(char x)
  284. #else
  285. doarg(x) char x; 
  286. #endif /* CK_ANSIC */
  287. /* doarg */ {
  288.     int i, n, y, z, xx; long zz; char *xp;
  289.  
  290. #ifdef NETCONN
  291. #define YYBUFLEN 256
  292.     char tmpbuf[YYBUFLEN+1];        /* Local storage for network things */
  293.     char line[YYBUFLEN+1];
  294. #endif /* NETCONN */
  295.  
  296.     xp = *xargv+1;            /* Pointer for bundled args */
  297.     debug(F111,"doarg entry",xp,xargc);
  298.     while (x) {
  299.     debug(F000,"doarg arg","",x);
  300.     switch (x) {
  301.  
  302. #ifndef NOSPL
  303. case 'C':                /* Commands for parser */
  304.     xargv++, xargc--;
  305.     if ((xargc < 1) || (**xargv == '-')) {
  306.     XFATAL("No commands given for -C");
  307.     }
  308.     clcmds = *xargv;            /* Get the argument (must be quoted) */
  309.     break;
  310. #endif /* NOSPL */
  311.  
  312. case 'D':                /* Delay */
  313.     if (*(xp+1)) {
  314.     XFATAL("invalid argument bundling");
  315.     }
  316.     xargv++, xargc--;
  317.     if ((xargc < 1) || (**xargv == '-')) {
  318.     XFATAL("missing delay value");
  319.     }
  320.     z = atoi(*xargv);            /* Convert to number */
  321.     if (z > -1)                /* If in range */
  322.       delay = z;            /* set it */
  323.     else {
  324.     XFATAL("bad delay value");
  325.     }
  326.     break;
  327.  
  328. case 'E':                /* Exit on close */
  329. #ifdef NETCONN
  330.     tn_exit = 1;
  331. #endif /* NETCONN */
  332.     exitonclose = 1;
  333.     break;
  334.  
  335. #ifndef NOICP
  336. case 'S':                /* "Stay" - enter interactive */
  337.     stayflg = 1;            /* command parser after executing */
  338.     break;                /* command-line actions. */
  339. #endif /* NOICP */
  340.  
  341. case 'T':                /* File transfer mode = text */
  342.     binary = XYFT_T;
  343.     break;
  344.  
  345. case 'Q':                /* Quick (i.e. FAST) */
  346.     wslotr = 20;            /* 20 window slots */
  347.     rpsiz = 94;                /* 4K packets */
  348.     urpsiz = 4096;
  349.     if (urpsiz > MAXSP)
  350.       urpsiz = MAXSP;
  351. #ifdef CK_SPEED
  352.     setprefix(PX_CAU);            /* Cautious unprefixing */
  353. #endif /* CK_SPEED */
  354.     break;
  355.  
  356. case 'R':                /* Remote-Only */
  357.     break;                /* This is handled in prescan(). */
  358.  
  359. #ifndef NOSERVER
  360. case 'x':                /* server */
  361.     if (action) {
  362.     XFATAL("conflicting actions");
  363.     }
  364.     action = 'x';
  365.     break;
  366. #endif /* NOSERVER */
  367.  
  368. case 'f':                /* finish */
  369.     if (action) {
  370.     XFATAL("conflicting actions");
  371.     }
  372.     action = setgen('F',"","","");
  373.     break;
  374.  
  375. case 'r': {                /* receive */
  376.     if (action) {
  377.     XFATAL("conflicting actions");
  378.     }
  379.     action = 'v';
  380.     break;
  381.   } 
  382. case 'k':                /* receive to stdout */
  383.     if (action) {
  384.     XFATAL("conflicting actions");
  385.     }
  386.     stdouf = 1;
  387.     action = 'v';
  388.     break;
  389.  
  390. case 's':                 /* send */
  391.     if (action) {
  392.     XFATAL("conflicting actions");
  393.     }
  394.     if (*(xp+1)) {
  395.     XFATAL("invalid argument bundling after -s");
  396.     }
  397.     nfils = 0;                /* Initialize file counter */
  398.     z = 0;                /* Flag for stdin */
  399.     cmlist = xargv + 1;            /* Remember this pointer */
  400.     while (--xargc > 0) {        /* Traverse the list */    
  401.     xargv++;
  402.     if (**xargv == '-') {        /* Check for sending stdin */
  403.         if (strcmp(*xargv,"-") != 0) /* Watch out for next option. */
  404.           break;
  405.         z++;            /* "-" alone means send from stdin. */
  406.         } else if (zchki(*xargv) > -1) { /* Check if file exists */
  407.         nfils++;            /* Bump file counter */
  408.     } else if (iswild(*xargv) && zxpand(*xargv) > 0) {
  409.         /* or contains wildcard characters matching real files */
  410.         nfils++;
  411.     }
  412.     }
  413.     xargc++, xargv--;            /* Adjust argv/argc */
  414.     if (nfils < 1 && z == 0) {
  415. #ifdef VMS
  416.     XFATAL("%CKERMIT-E-SEARCHFAIL, no files for -s");
  417. #else
  418.     XFATAL("No files for -s");
  419. #endif /* VMS */
  420.     }
  421.     if (z > 1) {
  422.     XFATAL("-s: too many -'s");
  423.     }
  424.     if (z == 1 && nfils > 0) {
  425.     XFATAL("invalid mixture of filenames and '-' in -s");
  426.     }
  427.     debug(F101,"doarg s nfils","",nfils);
  428.     debug(F101,"doarg s z","",z);
  429.     if (nfils == 0) {
  430.     if (is_a_tty(0)) {        /* (used to be is_a_tty(1) - why?) */
  431.         XFATAL("sending from terminal not allowed");
  432.     } else stdinf = 1;
  433.     }
  434.     debug(F101,"doarg s stdinf","",stdinf);
  435.     debug(F101,*xargv,"",nfils);
  436.     action = 's';
  437.     break;
  438.  
  439. case 'g':                /* get */
  440.     if (action) {
  441.     XFATAL("conflicting actions");
  442.     }
  443.     if (*(xp+1)) {
  444.     XFATAL("invalid argument bundling after -g");
  445.     }
  446.     xargv++, xargc--;
  447.     if ((xargc == 0) || (**xargv == '-')) {
  448.         XFATAL("missing filename for -g");
  449.     }
  450.     cmarg = *xargv;
  451.     action = 'r';
  452.     break;
  453.  
  454. #ifndef NOLOCAL
  455. case 'c':                /* connect before */
  456.     cflg = 1;
  457.     break;
  458.  
  459. case 'n':                /* connect after */
  460.     cnflg = 1;
  461.     break;
  462. #endif /* NOLOCAL */
  463.  
  464. case 'h':                /* help */
  465.     usage();
  466. #ifndef NOICP
  467.     if (stayflg || what == W_COMMAND)
  468.       break;
  469.     else
  470. #endif /* NOICP */
  471.       doexit(GOOD_EXIT,-1);
  472.  
  473. case 'a':                /* "as" */
  474.     if (*(xp+1)) {
  475.     XFATAL("invalid argument bundling after -a");
  476.     }
  477.     xargv++, xargc--;
  478.     if ((xargc < 1) || (**xargv == '-')) {
  479.         XFATAL("missing name in -a");
  480.     }
  481.     cmarg2 = *xargv;
  482.     break;
  483.  
  484. #ifndef NOICP
  485. case 'Y':                /* No initialization file */
  486.     noinit = 1;
  487.     break;
  488.  
  489. case 'y':                /* Alternate init-file name */
  490.     if (*(xp+1)) {
  491.     XFATAL("invalid argument bundling after -y");
  492.     }
  493.     xargv++, xargc--;
  494.     if (xargc < 1) {
  495.     XFATAL("missing filename in -y");
  496.     }
  497.     /* strcpy(kermrc,*xargv); ...this was already done in prescan()... */
  498.     break;
  499. #endif /* NOICP */
  500.  
  501. #ifndef NOLOCAL
  502. case 'l':                /* SET LINE */
  503. #ifdef NETCONN
  504. #ifdef ANYX25
  505. case 'X':                /* SET HOST to X.25 address */
  506. #ifdef SUNX25
  507. case 'Z':                /* SET HOST to X.25 file descriptor */
  508. #endif /* SUNX25 */
  509. #endif /* ANYX25 */
  510. #ifdef TCPSOCKET
  511. case 'J':
  512. case 'j':                /* SET HOST (TCP/IP socket) */
  513. #endif /* TCPSOCKET */
  514. #endif /* NETCONN */
  515.     network = 0;
  516.     if (*(xp+1)) {
  517.     XFATAL("invalid argument bundling after -l or -j");
  518.     }
  519.     xargv++, xargc--;
  520.     if ((xargc < 1) || (**xargv == '-')) {
  521.     XFATAL("communication line device name missing");
  522.     }
  523. #ifdef NETCONN
  524.     if (x == 'J') {
  525.     cflg    = 1;            /* Connect */
  526.     stayflg = 1;            /* Stay */
  527.     tn_exit = 1;            /* Telnet-like exit condition */
  528.     }
  529. #endif /* NETCONN */
  530.     strcpy(ttname,*xargv);
  531.     local = (strcmp(ttname,CTTNAM) != 0);
  532. /*
  533.   NOTE: We really do not need to call ttopen here, since it should be called
  534.   again later, automatically, when we first try to condition the device via
  535.   ttpkt or ttvt.  Calling ttopen here has the bad side effect of making the
  536.   order of the -b and -l options significant, but order of command-line options
  537.   should not matter.  However, the network cases immediately below complicate
  538.   matters a bit, so we'll settle this in a future edit.
  539. */
  540.     if (x == 'l') {
  541.     if (ttopen(ttname,&local,mdmtyp,0) < 0) {
  542.         XFATAL("can't open device");
  543.     }
  544.     debug(F101,"cmdlin speed","",speed);
  545.     speed = ttgspd();        /* get it. */
  546. #ifdef NETCONN
  547.     } else {
  548.     if (x == 'j' || x == 'J') {    /* IP network host name */
  549.         char * s = line;
  550.         char * service = tmpbuf;
  551.         if (xargc > 0) {        /* Check if it's followed by */
  552.         /* A service name or number */
  553.         if (*(xargv+1) && *(*(xargv+1)) != '-') {
  554.             xargv++, xargc--;            
  555.             strcat(ttname,":");
  556.             strcat(ttname,*xargv);
  557.         }
  558.         }
  559.         nettype = NET_TCPB;
  560.         mdmtyp = -nettype;          /* Perhaps already set in init file */
  561.         telnetfd = 1;        /* Or maybe an open file descriptor */
  562.         
  563.         strncpy(line, ttname, YYBUFLEN); /* Working copy of the name */
  564.         for (s = line; *s != '\0' && *s != ':'; s++); /* and service */
  565.         if (*s) {
  566.         *s++ = '\0';
  567.         strncpy(service, s, YYBUFLEN);
  568.         } else *service = '\0';
  569.         s = line;
  570. #ifndef NODIAL
  571. #ifndef NOICP
  572.         /* Look up in network directory */
  573.         x = 0;
  574.         if (*s == '=') {        /* If number starts with = sign */
  575.         s++;            /* strip it */
  576.         while (*s == SP)    /* and also any leading spaces */
  577.           s++;
  578.         strncpy(line,s,YYBUFLEN); /* Do this again. */
  579.         nhcount = 0;
  580.         } else if (!isdigit(line[0])) {
  581. /*
  582.   nnetdir will be greater than 0 if the init file has been processed and it
  583.   contained a SET NETWORK DIRECTORY command.
  584. */
  585.         xx = 0;            /* Initialize this */
  586.         if (nnetdir > 0)    /* If there is a directory... */
  587.           xx = lunet(line);    /* Look up the name */
  588.         else            /* If no directory */
  589.           nhcount = 0;        /* we didn't find anything there */
  590.         if (xx < 0) {        /* Lookup error: */
  591.             sprintf(tmpbuf,
  592.                 "?Fatal network directory lookup error - %s\n",
  593.                 line
  594.                 );
  595.             XFATAL(tmpbuf);
  596.         }
  597.         }
  598. #endif /* NOICP */
  599. #endif /* NODIAL */
  600.         /* Add service to line specification for ttopen() */
  601.         if (*service) {        /* There is a service specified */
  602.         strcat(line, ":");
  603.         strcat(line, service);
  604.         } else {
  605.         strcat(line, ":telnet");
  606.         }       
  607.  
  608. #ifndef NOICP
  609. #ifndef NODIAL
  610.         if ((nhcount > 1) && !quiet && !backgrd) {
  611.         printf("%d entr%s found for \"%s\"%s\n",
  612.                        nhcount,
  613.                        (nhcount == 1) ? "y" : "ies",
  614.                        s,
  615.                        (nhcount > 0) ? ":" : "."
  616.                        );
  617.         for (i = 0; i < nhcount; i++)
  618.           printf("%3d. %s %-12s => %s\n",
  619.              i+1, n_name, nh_p2[i], nh_p[i]
  620.              );
  621.         }
  622.         if (nhcount == 0)
  623.           n = 1;
  624.         else
  625.           n = nhcount;
  626. #else
  627.         n = 1;
  628.         nhcount = 0;
  629. #endif /* NODIAL */
  630.         for (i = 0; i < n; i++) {
  631. #ifndef NODIAL
  632.         if (nhcount >= 1) {
  633.             strcpy(line,nh_p[i]); /* Copy the current entry to line */
  634.             /* Check to see if the network entry contains a service */
  635.             for ( s = line ; (*s != '\0') && (*s != ':'); s++)
  636.               ;
  637.             /* If directory does not have a service ... */
  638.             if (!*s && *service) { /* and the user specified one */
  639.             strcat(line, ":");
  640.             strcat(line, service);
  641.             }
  642.             if (lookup(netcmd,nh_p2[i],nnets,&z) > -1) {
  643.             mdmtyp = 0 - netcmd[z].kwval;
  644.             } else {
  645.             printf("Error - network type \"%s\" not supported\n",
  646.                                nh_p2[i]
  647.                    );
  648.             continue;
  649.             }            
  650.         }
  651. #endif /* NODIAL */
  652.         }
  653. #endif /* NOICP */
  654.         strcpy(ttname, line);
  655. #ifdef SUNX25
  656.     } else if (x == 'X') {        /* X.25 address */
  657.         nettype = NET_SX25;
  658.         mdmtyp = -nettype;
  659.     } else if (x == 'Z') {        /* Open X.25 file descriptor */
  660.         nettype = NET_SX25;
  661.         mdmtyp = -nettype;
  662.         x25fd = 1;
  663. #endif /* SUNX25 */
  664. #ifdef STRATUSX25
  665.     } else if (x == 'X') {        /* X.25 address */
  666.         nettype = NET_VX25;
  667.         mdmtyp = -nettype;
  668. #endif /* STRATUSX25 */
  669.     }
  670.     if (ttopen(ttname,&local,mdmtyp,0) < 0) {
  671.         XFATAL("can't open host connection");
  672.     }
  673.     network = 1;
  674. #endif /* NETCONN */
  675.     }
  676.     /* add more here later - decnet, etc... */
  677.     break;
  678.  
  679. #ifdef ANYX25
  680. case 'U':                               /* X.25 call user data */
  681.     if (*(xp+1)) {
  682.     XFATAL("invalid argument bundling");
  683.     }
  684.     xargv++, xargc--;
  685.     if ((xargc < 1) || (**xargv == '-')) {
  686.         XFATAL("missing call user data string");
  687.     }
  688.     strcpy(udata,*xargv);
  689.     if ((int)strlen(udata) <= MAXCUDATA) {
  690.     cudata = 1;
  691.     } else {
  692.     XFATAL("Invalid call user data");
  693.     }
  694.     break;
  695.  
  696. case 'o':                               /* X.25 closed user group */
  697.     if (*(xp+1)) {
  698.     XFATAL("invalid argument bundling");
  699.     }
  700.     xargv++, xargc--;
  701.     if ((xargc < 1) || (**xargv == '-')) {
  702.         XFATAL("missing closed user group index");
  703.     }
  704.     z = atoi(*xargv);            /* Convert to number */
  705.     if (z >= 0 && z <= 99) {
  706.     closgr = z;
  707.     } else {
  708.     XFATAL("Invalid closed user group index");
  709.     }
  710.     break;
  711.  
  712. case 'u':                               /* X.25 reverse charge call */
  713.     revcall = 1;
  714.     break;
  715. #endif /* ANYX25 */
  716. #endif /* NOLOCAL */
  717.  
  718. case 'b':                /* Bits-per-second for serial device */
  719.     if (*(xp+1)) {
  720.     XFATAL("invalid argument bundling"); 
  721.     }
  722.     xargv++, xargc--;
  723.     if ((xargc < 1) || (**xargv == '-')) {
  724.         XFATAL("missing bps");
  725.     }
  726.     zz = atol(*xargv);            /* Convert to long int */
  727.     i = zz / 10L;
  728. #ifndef NOLOCAL
  729.     if (ttsspd(i) > -1)            /* Check and set it */
  730. #endif /* NOLOCAL */
  731.       speed = ttgspd();            /* and read it back. */
  732. #ifndef NOLOCAL
  733.     else {
  734.     XFATAL("unsupported transmission rate");
  735.     }
  736. #endif /* NOLOCAL */
  737.     break;
  738.  
  739. #ifndef NODIAL
  740. #ifndef NOICP
  741. case 'm':                /* Modem type */
  742.     if (*(xp+1)) {
  743.     XFATAL("invalid argument bundling after -m");    
  744.     }
  745.     xargv++, xargc--;
  746.     if ((xargc < 1) || (**xargv == '-')) {
  747.         XFATAL("modem type missing");
  748.     }
  749.     y = lookup(mdmtab,*xargv,nmdm,&z);
  750.     if (y < 0) {
  751.     XFATAL("unknown modem type");
  752.     }
  753.     usermdm = 0;
  754.     usermdm = (y == dialudt) ? x : 0;
  755.     initmdm(y);
  756.     break;
  757. #endif /* NOICP */
  758. #endif /* NODIAL */
  759.  
  760. case 'e':                /* Extended packet length */
  761.     if (*(xp+1)) {
  762.     XFATAL("invalid argument bundling after -e");
  763.     }
  764.     xargv++, xargc--;
  765.     if ((xargc < 1) || (**xargv == '-')) {
  766.         XFATAL("missing length");
  767.     }
  768.     z = atoi(*xargv);            /* Convert to number */
  769.     if (z > 10 && z <= maxrps) {
  770.         rpsiz = urpsiz = z;
  771.     if (z > 94) rpsiz = 94;        /* Fallback if other Kermit can't */
  772.     } else {
  773.     XFATAL("Unsupported packet length");
  774.     }
  775.     break;
  776.  
  777. case 'v':                /* Vindow size */
  778.     if (*(xp+1)) {
  779.     XFATAL("invalid argument bundling");
  780.     }
  781.     xargv++, xargc--;
  782.     if ((xargc < 1) || (**xargv == '-')) {
  783.         XFATAL("missing or bad window size");
  784.     }
  785.     z = atoi(*xargv);            /* Convert to number */
  786.     if (z < 32) {            /* If in range */
  787.     wslotr = z;            /* set it */
  788.     if (z > 1) swcapr = 1;        /* Set capas bit if windowing */
  789.     } else {
  790.     XFATAL("Unsupported packet length");
  791.     }
  792.     break;
  793.  
  794. case 'i':                /* Treat files as binary */
  795.     binary = XYFT_B;
  796.     break;
  797.  
  798. case 'w':                /* Writeover */
  799.     warn = 0;
  800.     fncact = XYFX_X;
  801.     break;
  802.  
  803. case 'q':                /* Quiet */
  804.     quiet = 1;
  805.     break;
  806.  
  807. #ifdef DEBUG
  808. case 'd':                /* DEBUG */
  809.     break;                /* Handled in prescan() */
  810. #endif /* DEBUG */ 
  811.  
  812. case '8':                /* 8-bit clean */
  813.     parity = 0;
  814.     cmdmsk = 0xff;
  815.     cmask = 0xff;
  816.     break;
  817.  
  818. case 'p':                /* SET PARITY */
  819.     if (*(xp+1)) {
  820.     XFATAL("invalid argument bundling");
  821.     }
  822.     xargv++, xargc--;
  823.     if ((xargc < 1) || (**xargv == '-')) {
  824.         XFATAL("missing parity");
  825.     }
  826.     switch(x = **xargv) {
  827.     case 'e':
  828.     case 'o':
  829.     case 'm':
  830.     case 's': parity = x; break;
  831.     case 'n': parity = 0; break;
  832.     default:  { XFATAL("invalid parity"); }
  833.         }
  834.     break;
  835.  
  836. case 't':                /* Line turnaround handshake */
  837.     turn = 1;                
  838.     turnch = XON;            /* XON is turnaround character */
  839.     duplex = 1;                /* Half duplex */
  840.     flow = 0;                /* No flow control */
  841.     break;
  842.  
  843. case 'B':
  844.     bgset = 1;                /* Force background (batch) */
  845.     backgrd = 1;
  846.     break;
  847.  
  848. case 'z':                /* Force foreground */
  849.     bgset = 0;
  850.     backgrd = 0;
  851.     break;
  852.  
  853. #ifndef NOSPL
  854. case 'M':                /* My User Name */
  855.     /* Already done in prescan() */
  856.     if (*(xp+1)) {
  857.     XFATAL("invalid argument bundling");
  858.     }
  859.     xargv++, xargc--;
  860.     if ((xargc < 1) || (**xargv == '-')) {
  861.         XFATAL("missing username");
  862.     }
  863. #ifdef COMMENT
  864.     if ((int)strlen(*xargv) > 63) {
  865.         XFATAL("username too long");
  866.     }
  867.     strcpy(uidbuf,*xargv);
  868. #endif /* COMMENT */
  869.     break;
  870. #endif /* NOSPL */
  871.  
  872. #ifdef CK_NETBIOS
  873. case 'N':                       /* NetBios Adapter Number follows */
  874.     if (*(xp+1)) {
  875.     XFATAL("invalid argument bundling after -N");
  876.     }
  877.     xargv++, xargc--;
  878.     if ((xargc < 1) || (**xargv == '-')) {
  879.     XFATAL("missing NetBios Adapter number");
  880.     }
  881.     if ((strlen(*xargv) != 1) ||
  882.     (*xargv)[0] != 'X' ||
  883.     ((atoi(*xargv) < 0) ||
  884.      (atoi(*xargv) > 9)) ) {
  885.     XFATAL("Invalid NetBios Adapter - Adapters 0 to 9 are valid");
  886.     }
  887.     break;
  888. #endif /* CK_NETBIOS */
  889.  
  890. #ifdef NETCONN
  891. case 'F':
  892.     network = 1;
  893.     if (*(xp+1)) {
  894.     XFATAL("invalid argument bundling after -F");
  895.     }
  896.     xargv++, xargc--;
  897.     if ((xargc < 1) || (**xargv == '-')) {
  898.     XFATAL("network file descriptor missing");
  899.     }
  900.     strcpy(ttname,*xargv);
  901.     nettype = NET_TCPB;
  902.     mdmtyp = -nettype;
  903.     telnetfd = 1;
  904.     local = 1;
  905.     break;
  906. #endif /* NETCONN */
  907.  
  908. #ifdef OS2PM
  909. case 'P':                /* OS/2 Presentation Manager */
  910.     if (*(xp+1)) {
  911.     XFATAL("invalid argument bundling after -P"); 
  912.     }
  913.     xargv++, xargc--;
  914.     if ((xargc < 1) || (**xargv == '-')) {
  915.         XFATAL("pipe data missing");
  916.     }
  917.     pipedata = *xargv;
  918.     break;
  919. #endif /* OS2PM */
  920.  
  921. #ifndef NOICP
  922. case 'H':
  923.     noherald = 1;
  924.     break;
  925. #endif /* NOICP */
  926.  
  927. #ifdef OS2
  928. case 'W':
  929.     if (*(xp+1)) {
  930.     XFATAL("invalid argument bundling after -W"); 
  931.     }
  932.     xargv++, xargc--;
  933.     if ((xargc < 1)) { /* could be negative */
  934.     XFATAL("Window handle missing");
  935.     }
  936.     xargv++, xargc--;
  937.     if ((xargc < 1) || (**xargv == '-')) {
  938.     XFATAL("Kermit Instance missing");
  939.     }
  940.     /* Action done in prescan */
  941.     break;
  942. #endif /* OS2 */
  943.  
  944. default:
  945.     fatal2(*xargv,
  946. #ifdef NT
  947.            "invalid command-line option, type \"k95 -h\" for help"
  948. #else
  949. #ifdef OS2
  950.            "invalid command-line option, type \"ckermit -h\" for help"
  951. #else
  952.            "invalid command-line option, type \"kermit -h\" for help"
  953. #endif /* OS2 */
  954. #endif /* NT */
  955.        );
  956.         }
  957.  
  958.     x = *++xp;                /* See if options are bundled */
  959.     }
  960.     return(0);
  961. }
  962. #else /* No command-line interface... */
  963.  
  964. extern int xargc;
  965. int
  966. cmdlin() {
  967.     if (xargc > 1) {
  968.     XFATAL("Sorry, command-line options disabled.");
  969.     }
  970. }
  971. #endif /* NOCMDL */
  972.