home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / old / ckermit70 / ckuusy.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  69KB  |  2,229 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, 2000,
  15.     Trustees of Columbia University in the City of New York.
  16.     All rights reserved.  See the C-Kermit COPYING.TXT file or the
  17.     copyright text in the ckcmai.c module for disclaimer and permissions.
  18. */
  19. #include "ckcdeb.h"
  20. #include "ckcasc.h"
  21. #include "ckcker.h"
  22. #include "ckucmd.h"
  23. #include "ckcnet.h"
  24. #include "ckuusr.h"
  25. #include <signal.h>
  26.  
  27. #ifdef OS2
  28. #include <io.h>
  29. #endif /* OS2 */
  30.  
  31. extern int inserver, fncnv, f_save, xfermode;
  32. #ifdef PATTERNS
  33. extern int patterns;
  34. #endif /* PATTERNS */
  35.  
  36. #ifndef NOICP
  37. extern int cmdint;
  38. #endif /* NOICP */
  39. extern int suspend;
  40.  
  41. #ifdef NETCONN
  42. #ifdef ANYX25
  43. extern int revcall, closgr, cudata;
  44. extern char udata[];
  45. extern int x25fd;
  46. #endif /* ANYX25 */
  47. #ifndef VMS
  48. #ifndef OS2
  49. #ifndef OSK
  50. extern
  51. #endif /* OSK */
  52. #endif /* OS2 */
  53. #endif /* VMS */
  54.  
  55. int telnetfd;
  56. extern struct keytab netcmd[];
  57. extern int tn_exit;
  58. #ifndef NOICP
  59. #ifndef NODIAL
  60. extern int nnets, nnetdir;              /* Network services directory */
  61. extern char *netdir[];
  62. extern char *nh_p[];                    /* Network directory entry pointers */
  63. extern char *nh_p2[];                   /* Network directory entry nettype */
  64. extern char *nh_px[4][MAXDNUMS + 1];
  65. #endif /* NODIAL */
  66. extern int nhcount;
  67. extern char * n_name;                   /* Network name pointer */
  68. #endif /* NOICP */
  69. #endif /* NETCONN */
  70.  
  71. #ifndef NOSPL
  72. extern int nmac;
  73. extern struct mtab *mactab;
  74. extern char uidbuf[];
  75. #endif /* NOSPL */
  76.  
  77. #ifdef CK_LOGIN
  78. extern int logintimo;
  79. #endif /* CK_LOGIN */
  80.  
  81. extern char * myname, * dftty;
  82. extern int howcalled;
  83.  
  84. extern char *ckxsys, *ckzsys, **xargv, **cmlist, *clcmds;
  85.  
  86. extern int action, cflg, xargc, cnflg, local, quiet, escape, network, mdmtyp,
  87.   bgset, backgrd, xargs, binary, parity, turn, turnch, duplex, flow, clfils,
  88.   noinit, stayflg, nettype, cfilef, noherald, cmask, cmdmsk, exitonclose,
  89.   haveline, justone, cxtype, xfinish, ttnproto;
  90.  
  91. extern long speed;
  92. extern char ttname[];
  93. extern char * pipedata, * cmdfil;
  94.  
  95. char * xargv0 = "";
  96.  
  97. #ifndef NOXFER
  98. extern char *cmarg, *cmarg2;
  99.  
  100. extern int nfils, stdouf, stdinf, displa, maxrps, rpsiz, ckwarn, urpsiz,
  101.   wslotr, swcapr, ckdelay, recursive, reliable, xreliable, fnspath, fncact,
  102.   clearrq, setreliable;
  103.  
  104. #ifdef PIPESEND
  105. extern int usepipes, pipesend;
  106. #endif /* PIPESEND */
  107. extern int protocol;
  108. #endif /* NOXFER */
  109.  
  110. #ifdef OS2
  111. extern struct keytab os2devtab[];
  112. extern int nos2dev;
  113. extern int ttslip;
  114. #ifdef OS2PM
  115. extern int os2pm;
  116. #endif /* OS2PM */
  117. #endif /* OS2 */
  118.  
  119. #ifdef CK_NETBIOS
  120. extern unsigned char NetBiosAdapter;
  121. #endif /* CK_NETBIOS */
  122.  
  123. #ifdef XFATAL
  124. #undef XFATAL
  125. #endif /* XFATAL */
  126.  
  127. #ifndef NOICP
  128. #ifndef NODIAL
  129. extern int nmdm, telephony;
  130. extern struct keytab mdmtab[];
  131. extern int usermdm, dialudt;
  132. #endif /* NODIAL */
  133. extern int what;
  134. _PROTOTYP(static int pmsg, (char *) );
  135. _PROTOTYP(static int fmsg, (char *) );
  136. static int pmsg(s) char *s; { printf("%s\n", s); return(0); }
  137. static int fmsg(s) char *s; { fatal(s); return(0); }
  138. #define XFATAL(s) return(what==W_COMMAND?pmsg(s):fmsg(s))
  139. #else
  140. #define XFATAL fatal
  141. #endif /* NOICP */
  142.  
  143. #ifndef NOCMDL
  144. /* Command-Line usage message (must fit in 24x80) */
  145. static
  146. char *hlp1[] = {
  147. #ifndef NOICP
  148. " [cmdfile] [-x arg [-x arg]...[-yyy]..] [ = text ] ]\n",
  149. #else
  150. "[-x arg [-x arg]...[-yyy]..]\n",
  151. #endif /* NOICP */
  152. "  -x is an option requiring an argument, -y an option with no argument.\n",
  153. "actions:\n",
  154. "  -s files  send files                  -r  receive files\n",
  155. "  -s -      send from stdin             -k  receive files to stdout\n",
  156. #ifndef NOSERVER
  157. "  -x        enter server mode           -f  finish remote server\n",
  158. #else
  159. "  -f        finish remote server\n",
  160. #endif /* NOSERVER */
  161. "  -g files  get remote files from server (quote wildcards)\n",
  162. "  -a name   alternate file name, used with -s, -r, -g\n",
  163. #ifndef NOLOCAL
  164. "  -c        connect (before file transfer), used with -l and -b\n",
  165. "  -n        connect (after file transfer), used with -l and -b\n",
  166. #endif /* NOLOCAL */
  167. "settings:\n",
  168. #ifndef NOLOCAL
  169. "  -l dev    communication line device   -q  quiet during file transfer\n",
  170. #ifdef NETCONN
  171. "  -j host   network host name[:port]    -i  binary transfer (-T = text)\n",
  172. #else
  173. "  -i        binary file transfer\n",
  174. #endif /* NETCONN */
  175. "  -b bps    line speed, e.g. 19200      -t  half duplex, xon handshake\n",
  176. #else
  177. "  -i        binary file transfer\n",
  178. #endif /* NOLOCAL */
  179. #ifdef DEBUG
  180. "  -p x      parity, x = e,o,m,s, or n   -d  log debug info to debug.log\n",
  181. #else
  182. "  -p x      parity, x = e,o,m,s, or n\n",
  183. #endif /* DEBUG */
  184. #ifndef NOICP
  185. "  -y name   alternate init file name    -Y  no init file\n",
  186. #else
  187. #endif /* NOICP */
  188. "  -e n      receive packet length       -w  write over files\n",
  189. #ifdef UNIX
  190. "  -v n      sliding window slots        -z  force foreground\n",
  191. #else
  192. "  -v n      sliding window slots\n",
  193. #endif /* UNIX */
  194. #ifndef NODIAL
  195. "  -m name   modem type                  -R  remote-only advisory\n",
  196. #endif /* NODIAL */
  197. /*
  198.   If all this stuff is defined, we run off the screen...
  199. */
  200. #ifdef CK_NETBIOS
  201. "  -N n      NetBIOS adapter number\n",
  202. #endif /* CK_NETBIOS */
  203. #ifdef ANYX25
  204. " -o index   X.25 closed user group call -X  X.25 address\n",
  205. " -U string  X.25 call user data         -u  X.25 reverse charge call\n",
  206. " -Z n       X.25 connection open file descriptor\n",
  207. #endif /* ANYX25 */
  208. #ifndef NOICP
  209. "If no action command is included, or -S is, enter interactive dialog.\n",
  210. "Type HELP OPTIONS at the prompt for further info.\n",
  211. #else
  212. "Operation by command-line options only.\n",
  213. "See the manual \"Using C-Kermit\" for complete information.\n",
  214. #endif /* NOICP */
  215. ""
  216. };
  217.  
  218. #ifndef NOHELP
  219.  
  220. /* Command-line option help lines.  Update this when adding new options! */
  221.  
  222. char * opthlp[128];                     /* Option help */
  223. char * arghlp[128];                     /* Argument for option */
  224. int optact[128];                        /* Action-option flag */
  225. #endif /* NOHELP */
  226.  
  227. VOID
  228. fatal2(msg1,msg2) char *msg1, *msg2; {
  229.     char buf[256];
  230.     if (!msg1) msg1 = "";
  231.     if (!msg2) msg2 = "";
  232.     sprintf(buf,"\"%s\" - %s",msg1,msg2);
  233. #ifndef NOICP
  234.     if (what == W_COMMAND)
  235.       printf("%s\n",buf);
  236.     else
  237. #endif /* NOICP */
  238.       fatal((char *)buf);
  239. }
  240.  
  241. static SIGTYP
  242. #ifdef CK_ANSI
  243. cl_int(int dummy)
  244. #else /* CK_ANSI */
  245. cl_int(dummy) int dummy;
  246. #endif /* CK_ANSI */
  247. {                    /* Command-line interrupt handler */
  248.     doexit(BAD_EXIT,1);
  249.     SIGRETURN;
  250. }
  251.  
  252. /*  U S A G E */
  253.  
  254. VOID
  255. usage() {
  256. #ifndef MINIX
  257.     conol("Usage: ");
  258.     conol(xargv0);
  259.     conola(hlp1);
  260. #else
  261.     conol("Usage: ");
  262.     conol(xargv0);
  263.     conol(" [-x arg [-x arg]...[-yyy]..] ]\n");
  264. #endif /* MINIX */
  265. }
  266. #endif /* NOCMDL */
  267.  
  268. /*  C M D L I N  --  Get arguments from command line  */
  269.  
  270. int
  271. cmdlin() {
  272.     char x;                             /* Local general-purpose char */
  273.  
  274. #ifndef NOXFER
  275.     cmarg = "";                         /* Initialize globals */
  276.     cmarg2 = "";
  277. #endif /* NOXFER */
  278.     action = 0;
  279.     cflg = 0;
  280.  
  281.     xargv0 = xargv[0];
  282.     debug(F111,"cmdlin myname",myname,howcalled);
  283.     signal(SIGINT,cl_int);
  284.  
  285. /* Here we handle different "Command Line Personalities" */
  286.  
  287. #ifdef TCPSOCKET
  288.     if (howcalled == I_AM_TELNET) {     /* If I was called as Telnet... */
  289.         if (--xargc > 0) {              /* And I have a hostname... */
  290.             xargv++;
  291.             ckstrncpy(ttname,*xargv,TTNAMLEN+1);
  292.             debug(F110,"cmdlin telnet host",ttname,0);
  293.  
  294. #ifndef NOICP
  295. #ifndef NODIAL
  296.             nhcount = 0;                /* Check network directory */
  297.             debug(F101,"cmdlin nnetdir","",nnetdir);
  298.             if (nnetdir > 0)            /* If there is a directory... */
  299.               lunet(*xargv);            /* Look up the name */
  300.             else                        /* If no directory */
  301.               nhcount = 0;              /* we didn't find anything there */
  302. #ifdef DEBUG
  303.             if (deblog) {
  304.                 debug(F101,"cmdlin lunet nhcount","",nhcount);
  305.                 if (nhcount > 0) {
  306.                     debug(F110,"cmdlin lunet nh_p[0]",nh_p[0],0);
  307.                     debug(F110,"cmdlin lunet nh_p2[0]",nh_p2[0],0);
  308.                     debug(F110,"cmdlin lunet nh_px[0][0]",nh_px[0][0],0);
  309.                 }
  310.             }
  311. #endif /* DEBUG */
  312.             if (nhcount > 0 && nh_p2[0]) /* If network type specified */
  313.               if (ckstrcmp(nh_p2[0],"tcp/ip",6,0)) /* it must be TCP/IP */
  314.                 nhcount = 0;
  315.             if (nhcount == 1) {         /* Still OK, so make substitution */
  316.                 ckstrncpy(ttname,nh_p[0],TTNAMLEN+1);
  317.                 debug(F110,"cmdlin lunet substitution",ttname,0);
  318.             }
  319. #endif /* NODIAL */
  320. #endif /* NOICP */
  321.  
  322.             if (--xargc > 0) {          /* Service specified on cmd line? */
  323.                 xargv++;
  324.                 strcat(ttname,":");
  325.                 strcat(ttname,*xargv);
  326.                 debug(F110,"cmdlin telnet host2",ttname,0);
  327.             }
  328. #ifndef NOICP
  329. #ifndef NODIAL
  330.             else if (nhcount) {         /* No - how about in net directory? */
  331.                 if (nh_px[0][0]) {
  332.                     strcat(ttname,":");
  333.                     strcat(ttname,nh_px[0][0]);
  334.                 }
  335.             }
  336. #endif /* NODIAL */
  337. #endif /* NOICP */
  338.             local = 1;                  /* Try to open the connection */
  339.             nettype = NET_TCPB;
  340.             mdmtyp = -nettype;
  341.             if (ttopen(ttname,&local,mdmtyp,0) < 0) {
  342.                 XFATAL("can't open host connection");
  343.             }
  344.             network = 1;                /* It's open */
  345. #ifdef CKLOGDIAL
  346.             dolognet();
  347. #endif /* CKLOGDIAL */
  348. #ifndef NOXFER
  349.             reliable = 1;               /* It's reliable */
  350.             xreliable = 1;              /* ... */
  351.             setreliable = 1;
  352. #endif /* NOXFER */
  353.             cflg = 1;                   /* Connect */
  354.             stayflg = 1;                /* Stay */
  355.             tn_exit = 1;                /* Telnet-like exit condition */
  356.             quiet = 1;
  357.             exitonclose = 1;            /* Exit when connection closes */
  358. #ifndef NOSPL
  359.             if (local) {
  360.                 if (nmac) {                     /* Any macros defined? */
  361.                     int k;                      /* Yes */
  362.                     k = mlook(mactab,"on_open",nmac);   /* Look this up */
  363.                     if (k >= 0) {                       /* If found, */
  364.                         if (dodo(k,ttname,0) > -1)      /* set it up, */
  365.                           parser(1);                    /* and execute it */
  366.                     }
  367.                 }
  368.             }
  369. #endif /* NOSPL */
  370.         }
  371.         return(0);
  372.     }
  373. #ifdef COMMENT
  374. #ifdef RLOGCODE
  375.     else if (howcalled == I_AM_RLOGIN) { /* If I was called as Rlogin... */
  376.         /* Add rlogin command-line parsing here... */
  377.         return(0);
  378.     }
  379. #endif /* RLOGCODE */
  380. #endif /* COMMENT */
  381. #endif /* TCPSOCKET */
  382.  
  383. /*
  384.   From here down: We were called as "kermit" or "iksd".
  385.  
  386.   If we were started directly from a Kermit application file, its name is
  387.   in argv[1], so skip past it.
  388. */
  389.     if (xargc > 1) {
  390.         int n = 1;
  391.         if (*xargv[1] != '-') {
  392. #ifdef KERBANG
  393.             /* If we were started with a Kerbang script, the script */
  394.             /* arguments were already picked up in prescan / cmdini() */
  395.             /* and there is nothing here for us anyway. */
  396.             if (!strcmp(xargv[1],"+"))
  397.               return(0);
  398. #endif /* KERBANG */
  399.  
  400.             if (cfilef) {               /* Command file found in prescan() */
  401.                 xargc -= n;             /* Skip past it */
  402.                 xargv += n;
  403.                 cfilef = 0;
  404.                 debug(F101,"cmdlin cfilef set to 0","",cfilef);
  405.             }
  406.         }
  407.     }
  408. /*
  409.  Regular Unix-style command line parser, conforming with 'A Proposed Command
  410.  Syntax Standard for Unix Systems', Hemenway & Armitage, Unix/World, Vol.1,
  411.  No.3, 1984.
  412. */
  413.     while (--xargc > 0) {               /* Go through command line words */
  414.         xargv++;
  415.         debug(F111,"cmdlin xargv",*xargv,xargc);
  416.         if (**xargv == '=')
  417.           return(0);
  418.         if (!strcmp(*xargv,"--"))       /* getopt() conformance */
  419.           return(0);
  420. #ifdef VMS
  421.         else if (**xargv == '/')
  422.           continue;
  423. #endif /* VMS */
  424.         else if (**xargv == '-') {      /* Got an option (begins with dash) */
  425.             int xx;
  426.             x = *(*xargv+1);            /* Get the option letter */
  427.             debug(F111,"cmdlin args 1",*xargv,xargc);
  428.             xx = doarg(x);
  429.             debug(F101,"cmdlin doarg","",xx);
  430.             debug(F111,"cmdlin args 2",*xargv,xargc);
  431.             if (xx < 0) {
  432. #ifndef NOICP
  433.                 if (what == W_COMMAND)
  434.                   return(0);
  435.                 else
  436. #endif /* NOICP */
  437.                   {
  438. #ifdef OS2
  439.                       sleep(1);         /* Give it a chance... */
  440. #endif /* OS2 */
  441.                       doexit(BAD_EXIT,1); /* Go handle option */
  442.                   }
  443.             }
  444.         } else {                        /* No dash where expected */
  445.             char buf[128];
  446.             sprintf(buf,
  447.                     "invalid command-line option, type \"%s -h\" for help",
  448.                     myname
  449.                     );
  450.             fatal2(*xargv,buf);
  451.         }
  452.     }
  453. #ifdef DEBUG
  454.     if (deblog) {
  455. #ifndef NOICP
  456.         debug(F101,"cmdlin what","",what);
  457. #endif /* NOICP */
  458.         debug(F101,"cmdlin action","",action);
  459. #ifndef NOXFER
  460.         debug(F101,"cmdlin stdouf","",stdouf);
  461. #endif /* NOXFER */
  462.     }
  463. #endif /* DEBUG */
  464.  
  465. #ifdef NOICP
  466.     if (!action && !cflg && !cnflg) {
  467.         debug(F100,"cmdlin NOICP fatal no action","",0);
  468.         XFATAL("?No actions specified on command line");
  469.     }
  470. #else
  471.     if (inserver && what == 0) {        /* Internet Kermit server checks */
  472.         if (local || (action != 0 && action != 'x')) {
  473.             if (local)
  474.               printf("local\r\n");
  475.             if (action)
  476.               printf("action=%c\r\n",action);
  477.             debug(F100,"cmdlin fatal 1","",0);
  478.             XFATAL("No actions or connections allowed with -A");
  479.         }
  480.     }
  481. #endif /* NOICP */
  482.  
  483. #ifndef NOLOCAL
  484.     if (!local) {
  485.         if ((action == 'c') || (cflg != 0)) {
  486.             debug(F100,"cmdlin fatal 2","",0);
  487.             XFATAL("-l or -j or -X required");
  488.         }
  489.     }
  490. #endif /* NOLOCAL */
  491. #ifndef NOXFER
  492.     if (*cmarg2 != 0) {
  493.         if ((action != 's') && (action != 'r') && (action != 'v')) {
  494.             debug(F100,"cmdlin fatal 3","",0);
  495.             XFATAL("-a without -s, -r, or -g");
  496.         }
  497.         if (action == 'r' || action == 'v') {
  498. #ifdef CK_TMPDIR
  499.             if (isdir(cmarg2)) {        /* -a is a directory */
  500.                 if (!zchdir(cmarg2)) {  /* try to change to it */
  501.                     debug(F100,"cmdlin fatal 4","",0);
  502.                     XFATAL("can't change to '-a' directory");
  503.                 } else cmarg2 = "";
  504.             } else
  505. #endif /* CK_TMPDIR */
  506.               if (zchko(cmarg2) < 0) {
  507.                   debug(F100,"cmdlin fatal 5","",0);
  508.                   XFATAL("write access to -a file denied");
  509.               }
  510.         }
  511.     }
  512.     if ((action == 'v') && (stdouf) && (!local)) {
  513.         if (is_a_tty(1)) {
  514.             debug(F100,"cmdlin fatal 6","",0);
  515.             XFATAL("unredirected -k can only be used in local mode");
  516.         }
  517.     }
  518.     if ((action == 's') || (action == 'v') ||
  519.         (action == 'r') || (action == 'x')) {
  520.         if (local)
  521.           displa = 1;
  522.         if (stdouf) {
  523.             displa = 0;
  524.             quiet = 1;
  525.         }
  526.     }
  527.     if (quiet) displa = 0;              /* No display if quiet requested */
  528. #endif /* NOXFER */
  529. #ifdef DEBUG
  530.     if (action)
  531.       debug(F000,"cmdlin returns action","",action);
  532.     else
  533.       debug(F101,"cmdlin returns action","",action);
  534. #endif /* DEBUG */
  535.     return(action);                     /* Then do any requested protocol */
  536. }
  537.  
  538. /* Extended argument parsing: --keyword[:value] (or =value) */
  539.  
  540. /*
  541.   XA_xxxx symbols are defined in ckuusr.h.
  542.   If you add a new one, also remember to update doshow(),
  543.   SHXOPT section, in ckuus5.c.
  544. */
  545. #ifndef NOICP
  546. struct keytab xargtab[] = {
  547. #ifdef CK_LOGIN
  548.     "anonymous",   XA_ANON, CM_ARG|CM_PRE,
  549. #endif /* CK_LOGIN */
  550.     "bannerfile",  XA_BAFI, CM_ARG,
  551.     "cdfile",      XA_CDFI, CM_ARG,
  552.     "cdmessage",   XA_CDMS, CM_ARG,
  553.     "cdmsg",       XA_CDMS, CM_ARG|CM_INV,
  554. #ifdef IKSDB
  555.     "database",    XA_DBAS, CM_ARG|CM_PRE,
  556.     "dbfile",      XA_DBFI, CM_ARG|CM_PRE,
  557. #endif /* IKSDB */
  558.     "help",        XA_HELP, 0,
  559. #ifndef NOHELP
  560.     "helpfile",    XA_HEFI, CM_ARG,
  561. #endif /* NOHELP */
  562. #ifdef CK_LOGIN
  563.     "initfile",    XA_ANFI, CM_ARG|CM_PRE,
  564. #endif /* CK_LOGIN */
  565.     "nointerrupts",XA_NOIN, CM_PRE,
  566. #ifdef CK_LOGIN
  567. #ifdef CK_PERM
  568.     "permissions", XA_PERM, CM_ARG|CM_PRE,
  569.     "perms",       XA_PERM, CM_ARG|CM_PRE|CM_INV,
  570. #endif /* CK_PERM */
  571. #ifdef CK_LOGIN
  572.     "privid",      XA_PRIV, CM_ARG|CM_PRE,
  573. #endif /* CK_LOGIN */
  574. #ifdef UNIX
  575.     "root",        XA_ROOT, CM_ARG|CM_PRE,
  576. #endif /* UNIX */
  577. #ifdef CKSYSLOG
  578.     "syslog",      XA_SYSL, CM_ARG|CM_PRE,
  579.     "timeout",     XA_TIMO, CM_ARG|CM_PRE,
  580. #endif /* CKSYSLOG */
  581.     "userfile",    XA_USFI, CM_ARG|CM_PRE,
  582. #ifdef CKWTMP
  583.     "wtmpfile",    XA_WTFI, CM_ARG|CM_PRE,
  584.     "wtmplog",     XA_WTMP, CM_ARG|CM_PRE,
  585. #endif /* CKWTMP */
  586. #endif /* CK_LOGIN */
  587.     "xferfile",    XA_IKFI, CM_ARG|CM_PRE,
  588.     "xferlog",     XA_IKLG, CM_ARG|CM_PRE,
  589.     "",            0,       0
  590. };
  591. int nxargs = sizeof(xargtab)/sizeof(struct keytab) - 1;
  592.  
  593. static struct keytab oktab[] = {
  594.     "0",     0, 0,
  595.     "1",     1, 0,
  596.     "2",     2, 0,
  597.     "3",     3, 0,
  598.     "4",     4, 0,
  599.     "5",     5, 0,
  600.     "6",     6, 0,
  601.     "7",     7, 0,
  602.     "8",     8, 0,
  603.     "9",     9, 0,
  604.     "false", 0, 0,
  605.     "no",    0, 0,
  606.     "off",   0, 0,
  607.     "ok",    1, 0,
  608.     "on",    1, 0,
  609.     "true",  1, 0,
  610.     "yes",   1, 0
  611. };
  612. static int noktab = sizeof(oktab)/sizeof(struct keytab);
  613.  
  614. #define XARGBUFL 32
  615.  
  616. char * bannerfile = NULL;
  617. char * helpfile = NULL;
  618. extern int xferlog;
  619. extern char * xferfile;
  620.  
  621. #ifndef NOHELP
  622. char * xopthlp[XA_MAX+1];               /* Extended option help */
  623. char * xarghlp[XA_MAX+1];               /* Extended argument for option */
  624.  
  625. static VOID
  626. inixopthlp() {
  627.     int i, j, n;
  628.     for (i = 0; i <= XA_MAX; i++) {     /* Initialize all to null */
  629.         xopthlp[i] = NULL;
  630.         xarghlp[i] = NULL;
  631.     }
  632.     for (i = 0; i < nxargs; i++) {      /* Then for each defined keyword */
  633.         j = xargtab[i].kwval;           /* index by associated value */
  634.         if (j < 0 || j > XA_MAX)
  635.           continue;
  636.         switch (j) {
  637. #ifdef CK_LOGIN
  638.           case XA_ANON:                 /* "--anonymous" */
  639.             xopthlp[j] = "--anonymous:{on,off} [IKSD only]";
  640.             xarghlp[j] = "Whether to allow anonymous IKSD logins";
  641.             break;
  642.       case XA_PRIV:
  643.             xopthlp[j] = "--privid:{on,off} [IKSD only]";
  644.             xarghlp[j] = "Whether to allow privileged IDs to login to IKSD";
  645.             break;
  646. #endif /* CK_LOGIN */
  647.           case XA_BAFI:                 /* "--bannerfile" */
  648.             xopthlp[j] = "--bannerfile:<filename>";
  649.             xarghlp[j] = "File to display upon startup or IKSD login";
  650.             break;
  651.           case XA_CDFI:                 /* "--cdfile" */
  652.             xopthlp[j] = "--cdfile:<filename>";
  653.             xarghlp[j] = "File to display when server changes directory";
  654.             break;
  655.           case XA_CDMS:                 /* "--cdmessage" */
  656.             xopthlp[j] = "--cdmessage:{on,off}";
  657.             xarghlp[j] = "Whether to display CD message file";
  658.             break;
  659.           case XA_HELP:                 /* "--help" */
  660.             xopthlp[j] = "--help";
  661.             xarghlp[j] = "Print this help text about extended options";
  662.             break;
  663.           case XA_HEFI:                 /* "--help" */
  664.             xopthlp[j] = "--helpfile:<filename>";
  665.             xarghlp[j] = "File containing custom info for HELP command";
  666.             break;
  667.           case XA_IKFI:                 /* "--xferfile" */
  668.             xopthlp[j] = "--xferfile:<filename> [IKSD only]";
  669.             xarghlp[j] = "Name of ftpd-like logfile.";
  670.             break;
  671.           case XA_IKLG:                 /* "--xferlog" */
  672.             xopthlp[j] = "--xferlog:{on,off} [IKSD only]";
  673.             xarghlp[j] = "Whether to keep an ftpd-like logfile.";
  674.             break;
  675. #ifdef CK_LOGIN
  676.           case XA_ANFI:                 /* "--initfile" */
  677.             xopthlp[j] = "--initfile:<filename> [IKSD only]";
  678.             xarghlp[j] = "Initialization file for anonymous users.";
  679.             break;
  680. #ifdef CK_PERM
  681.           case XA_PERM:                 /* "--permissions" */
  682.             xopthlp[j] = "--permissions:<octalnum> [IKSD only]";
  683.             xarghlp[j] = "Permissions for files uploaded by anonymous users.";
  684.             break;
  685. #endif /* CK_PERM */
  686. #ifdef UNIX
  687.           case XA_ROOT:                 /* "--root" */
  688.             xopthlp[j] = "--root:<directory> [IKSD only]";
  689.             xarghlp[j] = "File-system root for anonymous users.";
  690.             break;
  691. #endif /* UNIX */
  692. #endif /* CK_LOGIN */
  693. #ifdef CKSYSLOG
  694.           case XA_SYSL:                 /* "--syslog" */
  695.             xopthlp[j] = "--syslog:<digit> [IKSD only]";
  696.             xarghlp[j] = "Syslog recording level, 0-6.";
  697.             break;
  698. #endif /* CKSYSLOG */
  699.           case XA_USFI:                 /* "--userfile" */
  700.             xopthlp[j] = "--userfile:<filename> [IKSD only]";
  701.             xarghlp[j] = "Forbidden user file.";
  702.             break;
  703. #ifdef CKWTMP
  704.           case XA_WTFI:                 /* "--wtmpfile" */
  705.             xopthlp[j] = "--wtmpfile:<filename> [IKSD only]";
  706.             xarghlp[j] = "Name of wtmp logfile.";
  707.             break;
  708.           case XA_WTMP:                 /* "--wtmplog" */
  709.             xopthlp[j] = "--wtmplog:{on,off} [IKSD only]";
  710.             xarghlp[j] = "Whether to keep a wtmp logfile.";
  711.             break;
  712. #endif /* CKWTMP */
  713. #ifdef CK_LOGIN
  714.           case XA_TIMO:                 /* "--timeout" */
  715.             xopthlp[j] = "--timeout:<seconds> [IKSD only]";
  716.             xarghlp[j] =
  717.  "How long to wait for login before closing the connection.";
  718.             break;
  719. #endif /* CK_LOGIN */
  720.           case XA_NOIN:
  721.             xopthlp[j] = "--nointerrupts";
  722.             xarghlp[j] = "Disable keyboard interrupts.";
  723.             break;
  724. #ifdef IKSDB
  725.           case XA_DBAS:
  726.             xopthlp[j] = "--database:{on,off}";
  727.             xarghlp[j] = "Enable/Disable IKSD database (IKSD only)";
  728.             break;
  729.           case XA_DBFI:
  730.             xopthlp[j] = "--dbfile:<filename>";
  731.             xarghlp[j] = "Specify IKSD database file (IKSD only)";
  732.             break;
  733. #endif /* IKSDB */
  734.         }
  735.     }
  736. }
  737.  
  738. VOID
  739. iniopthlp() {
  740.     int i;
  741.     for (i = 0; i < 128; i++) {
  742.         optact[i] = 0;
  743.         switch(i) {
  744. #ifdef OS2
  745.           case '#':                     /* K95 Startup Flags */
  746.             opthlp[i] = "Kermit 95 Startup Flags";
  747.             arghlp[i] =
  748.               "   1 - turn off Win95 special fixes\n"\
  749.               "   2 - do not load optional network dlls\n"\
  750.               "   4 - do not load optional tapi dlls\n"\
  751.               "   8 - do not load optional kerberos dlls\n"\
  752.               "  16 - do not load optional zmodem dlls\n"\
  753.               "  32 - use stdin for input instead of the console\n"\
  754.               "  64 - use stdout for output instead of the console\n"\
  755.               " 128 - do not terminate process in response to Session Logoff";
  756.             break;
  757. #endif /* OS2 */
  758.           case '0':                     /* In the middle */
  759.             opthlp[i] =
  760.               "100% transparent CONNECT mode for \"in-the-middle\" operation";
  761.             arghlp[i] = NULL;
  762.             break;
  763.  
  764.           case '8':
  765.             opthlp[i] = "Connection is 8-bit clean";
  766.             arghlp[i] = NULL;
  767.             break;
  768.           case 'A':
  769.             opthlp[i] = "C-Kermit is to be started as an Internet service";
  770. #ifdef NT
  771.             arghlp[i] = "  socket handle of incoming connection";
  772. #else /* NT */
  773.             arghlp[i] = NULL;
  774. #endif /* NT */
  775.             break;
  776.           case 'B': opthlp[i] =
  777.             "C-Kermit is running in Batch (no controlling terminal)";
  778.             break;
  779. #ifndef NOSPL
  780.           case 'C':
  781.             opthlp[i] = "Interactive-mode Commands to be executed";
  782.             arghlp[i] = "Commands separated by commas, list in doublequotes";
  783.             break;
  784. #endif /* NOSPL */
  785.           case 'D':
  786.             opthlp[i] = "Delay before starting to send";
  787.             arghlp[i] = "Number of seconds";
  788.             break;
  789.           case 'E':
  790.             opthlp[i] = "Exit automatically when connection closes";
  791.             arghlp[i] = NULL;
  792.             break;
  793. #ifdef TCPSOCKET
  794.           case 'F':
  795.             opthlp[i] = "Make a TCP connection";
  796.             arghlp[i] = "Numeric file descriptor of open TCP connection";
  797.             break;
  798. #endif /* TCPSOCKET */
  799.           case 'G':
  800.             opthlp[i] = "GET from server, send to standard output";
  801.             arghlp[i] = "Remote file specification";
  802.             optact[i] = 1;
  803.             break;
  804.           case 'H':
  805.             opthlp[i] = "Suppress program startup Herald and greeting";
  806.             arghlp[i] = NULL;
  807.             break;
  808.           case 'I':
  809.             opthlp[i] = "Connection is relIable, streaming is allowed";
  810.             arghlp[i] = NULL;
  811.             break;
  812. #ifdef TCPSOCKET
  813.           case 'J':
  814.             opthlp[i] = "'Be like Telnet'";
  815.             arghlp[i] = "IP hostname/address optionally followed by socket";
  816.             break;
  817. #endif /* TCPSOCKET */
  818.           case 'L':
  819.             opthlp[i] = "Recursive directory descent for files in -s option";
  820.             arghlp[i] = NULL;
  821.             break;
  822.           case 'M':
  823.             opthlp[i] = "My user name (for use with Telnet, Rlogin, etc)";
  824.             arghlp[i] = "Username string";
  825.             break;
  826. #ifdef NETBIOS
  827.           case 'N':
  828.             opthlp[i] = "NETBIOS adapter number";
  829.             arghlp[i] = "Number";
  830.             break;
  831. #endif /* NETBIOS */
  832.           case 'O':                     /* Be a server for One command only */
  833.             opthlp[i] = "Be a server for One command only";
  834.             arghlp[i] = NULL;
  835.             optact[i] = 1;
  836.             break;
  837.           case 'P':
  838.             opthlp[i] = "Literal file (Path) names";
  839.             arghlp[i] = NULL;
  840.             break;
  841.           case 'Q':
  842.             opthlp[i] = "Quick (FAST) Kermit protocol settings";
  843.             arghlp[i] = NULL;
  844.             break;
  845.           case 'R':                     /* Remote-Only */
  846.             opthlp[i] = "Remote-only (makes IF REMOTE true)";
  847.             arghlp[i] = NULL;
  848.             break;
  849.           case 'S':                     /* "Stay" - enter interactive */
  850.             opthlp[i] = "Stay (enter command parser after action options)";
  851.             arghlp[i] = NULL;
  852.             break;
  853.           case 'T':                     /* Text file transfer mode */
  854.             opthlp[i] = "Transfer files in Text mode";
  855.             arghlp[i] = NULL;
  856.             break;
  857. #ifdef ANYX25
  858.           case 'U':                     /* X.25 call user data */
  859.             opthlp[i] = "X.25 call User data";
  860.             arghlp[i] = "Call-user-data string";
  861.             break;
  862. #endif /* ANYX25 */
  863.           case 'V':                     /* No automatic filetype switching */
  864.             opthlp[i] = "Disable automatic filetype switching";
  865.             arghlp[i] = NULL;
  866.             break;
  867. #ifdef COMMENT
  868. #ifdef OS2
  869.           case 'W':                     /* Win32 Window Handle */
  870.             opthlp[i] = "";
  871.             arghlp[i] = NULL;
  872.             break;
  873. #endif /* OS2 */
  874. #endif /* COMMENT */
  875. #ifdef ANYX25
  876.           case 'X':                     /* SET HOST to X.25 address */
  877.             opthlp[i] = "Make an X.25 connection";
  878.             arghlp[i] = "X.25 or X.121 address";
  879.             break;
  880. #endif /* ANYX25 */
  881.           case 'Y':                     /* No initialization file */
  882.             opthlp[i] = "Skip initialization file";
  883.             arghlp[i] = NULL;
  884.             break;
  885. #ifdef ANYX25
  886.           case 'Z':                     /* SET HOST to X.25 file descriptor */
  887.             opthlp[i] = "Make an X.25 connection";
  888.             arghlp[i] = "Numeric file descriptor of open X.25 connection";
  889.             break;
  890. #endif /* ANYX25 */
  891.           case 'a':                     /* as-name */
  892.             opthlp[i] = "As-name for file(s) in -s, -r, or -g";
  893.             arghlp[i] = "As-name string";
  894.             break;
  895.           case 'b':                     /* Set bits-per-second for serial */
  896.             opthlp[i] = "Speed for serial device";
  897.             arghlp[i] = "Numeric Bits per second";
  898.             break;
  899.           case 'c':                     /* Connect before */
  900.             optact[i] = 1;
  901.             opthlp[i] = "CONNECT before transferring files";
  902.             arghlp[i] = NULL;
  903.             break;
  904.           case 'd':                     /* DEBUG */
  905.             opthlp[i] = "Create debug.log file";
  906.             arghlp[i] = NULL;
  907.             break;
  908.           case 'e':                     /* Extended packet length */
  909.             opthlp[i] = "Receive packet length";
  910.             arghlp[i] = "Length in bytes";
  911.             break;
  912.           case 'f':                     /* finish */
  913.             optact[i] = 1;
  914.             opthlp[i] = "Send Finish command to server";
  915.             arghlp[i] = NULL;
  916.             break;
  917.           case 'g':                     /* get */
  918.             optact[i] = 1;
  919.             opthlp[i] = "GET file(s)";
  920.             arghlp[i] = "Remote file specification";
  921.             break;
  922.           case 'h':                     /* help */
  923.             optact[i] = 1;
  924.             opthlp[i] = "Print brief Help (usage) text";
  925.             arghlp[i] = NULL;
  926.             break;
  927.           case 'i':                     /* Treat files as binary */
  928.             opthlp[i] ="Transfer files in bInary mode";
  929.             arghlp[i] = NULL;
  930.             break;
  931. #ifdef TCPSOCKET
  932.           case 'j':                     /* SET HOST (TCP/IP socket) */
  933.             opthlp[i] = "Make a TCP connection";
  934.             arghlp[i] = "TCP host name/address and optional socket number";
  935.             break;
  936. #endif /* TCPSOCKET */
  937.           case 'k':                     /* receive to stdout */
  938.             optact[i] = 1;
  939.             opthlp[i] = "RECEIVE file(s) to standard output";
  940.             arghlp[i] = NULL;
  941.             break;
  942.           case 'l':                     /* SET LINE */
  943.             opthlp[i] = "Make connection on serial communications device";
  944.             arghlp[i] = "Device name string";
  945.             break;
  946.           case 'm':                     /* Modem type */
  947.             opthlp[i] = "Modem type for use with -l device";
  948.             arghlp[i] = "Modem type string as in SET MODEM TYPE command";
  949.             break;
  950.           case 'n':                     /* connect after */
  951.             optact[i] = 1;
  952.             opthlp[i] = "CONNECT after transferring files";
  953.             arghlp[i] = NULL;
  954.             break;
  955. #ifdef ANYX25
  956.           case 'o':                     /* X.25 closed user group */
  957.             opthlp[i] = "X.25 closed user group";
  958.             arghlp[i] = "User group string";
  959.             break;
  960. #endif /* ANYX25 */
  961.           case 'p':                     /* SET PARITY */
  962.             opthlp[i] = "Parity";
  963.             arghlp[i] = "One of the following: even, odd, mark, none, space";
  964.             break;
  965.           case 'q':                     /* Quiet */
  966.             opthlp[i] = "Quiet (suppress most messages)";
  967.             arghlp[i] = NULL;
  968.             break;
  969.           case 'r':                     /* receive */
  970.             optact[i] = 1;
  971.             opthlp[i] = "RECEIVE file(s)";
  972.             arghlp[i] = NULL;
  973.             break;
  974.           case 's':                     /* send */
  975.             optact[i] = 1;
  976.             opthlp[i] = "SEND file(s)";
  977.             arghlp[i] = "One or more file specifications";
  978.             break;
  979.           case 't':                     /* Line turnaround handshake */
  980.             opthlp[i] = "XON Turnaround character for half-duplex connections";
  981.             arghlp[i] = NULL;
  982.             break;
  983. #ifdef ANYX25
  984.           case 'u':                     /* X.25 reverse charge call */
  985.             opthlp[i] = "X.25 reverse charge call";
  986.             arghlp[i] = NULL;
  987.             break;
  988. #endif /* ANYX25 */
  989.           case 'v':                     /* Vindow size */
  990.             opthlp[i] = "Window size";
  991.             arghlp[i] = "Number, 1 to 32";
  992.             break;
  993.           case 'w':                     /* Writeover */
  994.             opthlp[i] = "Incoming files Write over existing files";
  995.             arghlp[i] = NULL;
  996.             break;
  997.           case 'x':                     /* Server */
  998.             optact[i] = 1;
  999.             opthlp[i] = "Be a Kermit SERVER";
  1000.             arghlp[i] = NULL;
  1001.             break;
  1002.           case 'y':                     /* Alternate init-file name */
  1003.             opthlp[i] = "Alternative initialization file";
  1004.             arghlp[i] = "File specification";
  1005.             break;
  1006.           case 'z':                     /* Not background */
  1007.             opthlp[i] = "Force foreground behavior";
  1008.             arghlp[i] = NULL;
  1009.             break;
  1010.           default:
  1011.             opthlp[i] = NULL;
  1012.             arghlp[i] = NULL;
  1013.         }
  1014.     }
  1015.     inixopthlp();
  1016. }
  1017. #endif /* NOHELP */
  1018.  
  1019. int
  1020. doxarg(s,pre) char ** s; int pre; {
  1021. #ifdef CK_LOGIN
  1022.     extern int ckxsyslog, ckxwtmp, ckxanon, ckxpriv, ckxperms;
  1023.     extern char * anonfile, * userfile, * anonroot;
  1024. #ifdef CKWTMP
  1025.     extern char * wtmpfile;
  1026. #endif /* CKWTMP */
  1027. #endif /* CK_LOGIN */
  1028.     extern int srvcdmsg;
  1029.     extern char * cdmsgfile[], * cdmsgstr;
  1030.     char tmpbuf[CKMAXPATH+1];
  1031.  
  1032.     int i, x, y, z, havearg = 0;
  1033.     char buf[XARGBUFL], c, * p;
  1034.  
  1035.     if (nxargs < 1)
  1036.       return(-1);
  1037.  
  1038.     c = *(*s + 1);                      /* Hyphen or Plus sign */
  1039.  
  1040.     p = *s + 2;
  1041.     for (i = 0; *p && i < XARGBUFL; i++) {
  1042.         buf[i] = *p++;
  1043.         if (buf[i] == '=' || buf[i] == ':') {
  1044.             havearg = 1;
  1045.             buf[i] = NUL;
  1046.             break;
  1047.         } else if (buf[i] < ' ') {
  1048.             buf[i] = NUL;
  1049.             break;
  1050.         }
  1051.     }
  1052.     if (i > XARGBUFL - 1)
  1053.       return(-1);
  1054.     buf[i] = NUL;
  1055.  
  1056.     x = lookup(xargtab,buf,nxargs,&z);  /* Lookup the option keyword */
  1057.  
  1058.     if (x < 0)                          /* On any kind of error */
  1059.       return(-1);                       /* fail. */
  1060.  
  1061.     /* Handle prescan versus post-initialization file */
  1062.  
  1063.     if (((xargtab[z].flgs & CM_PRE) || (c == '+')) && !pre)
  1064.       return(0);
  1065.     else if (pre && !(xargtab[z].flgs & CM_PRE) && (c != '+'))
  1066.       return(0);
  1067.  
  1068.     /* Ensure that argument is given if and only if required */
  1069.  
  1070.     p = havearg ? *s + i + 3 : NULL;
  1071.  
  1072.     if ((xargtab[z].flgs & CM_ARG) && !havearg)
  1073.       return(-1);
  1074.     else if ((!(xargtab[z].flgs & CM_ARG)) && havearg)
  1075.       return(-1);
  1076.  
  1077.     switch (x) {                        /* OK to process this option... */
  1078. #ifdef CKSYSLOG
  1079.       case XA_SYSL:                     /* IKS: Syslog level */
  1080.         y = 0;
  1081.         if (isdigit(*p)) {
  1082.             while (*p) {
  1083.                 if (*p < '0' || *p > '9')
  1084.                   return(-1);
  1085.                 y = y * 10 + (*p++ - '0');
  1086.             }
  1087.         } else {
  1088.             y = lookup(oktab,p,noktab,&z);
  1089.             if (y > 0) y = SYSLG_DF;    /* Yes = default logging level */
  1090.         }
  1091. #ifndef SYSLOGLEVEL
  1092.         /* If specified on cc command line, user can't change it. */
  1093.         if (!inserver)                  /* Don't allow voluminous syslogging */
  1094.           if (y > SYSLG_FA)             /* by ordinary users. */
  1095.             y = SYSLG_FA;
  1096. #endif /* SYSLOGLEVEL */
  1097.         if (y < 0) return(-1);
  1098. #ifdef DEBUG
  1099.         if (y >= SYSLG_DB)
  1100.           if (!deblog)
  1101.             deblog = debopn("debug.log",0);
  1102. #endif /* DEBUG */
  1103. #ifdef SYSLOGLEVEL
  1104.         /* If specified on cc command line, user can't change it. */
  1105.         y = SYSLOGLEVEL;
  1106. #endif /* SYSLOGLEVEL */
  1107.         ckxsyslog = y;
  1108.         /* printf("ckxsyslog=%d\n",ckxsyslog); */
  1109.         break;
  1110. #endif /* CKSYSLOG */
  1111.  
  1112. #ifdef CK_LOGIN
  1113. #ifdef CKWTMP
  1114.       case XA_WTMP:                     /* IKS: wtmp log */
  1115.         y = lookup(oktab,p,noktab,&z);
  1116.         if (y < 0) return(-1);
  1117.         ckxwtmp = y;
  1118.         /* printf("ckxwtmp=%d\n",ckxwtmp); */
  1119.         break;
  1120.  
  1121.       case XA_WTFI:                     /* IKS: wtmp logfile */
  1122.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1123.           p = tmpbuf;
  1124.         makestr(&wtmpfile,p);
  1125.         /* printf("wtmpfile=%s\n",wtmpfile); */
  1126.         break;
  1127. #endif /* CKWTMP */
  1128.  
  1129.       case XA_ANON:                     /* IKS: Anonymous login allowed */
  1130.         y = lookup(oktab,p,noktab,&z);
  1131.         if (y < 0) return(-1);
  1132.         ckxanon = y;
  1133.         /* printf("ckxanon=%d\n",ckxanon); */
  1134.         break;
  1135.  
  1136.       case XA_PRIV:                     /* IKS: Priv'd login allowed */
  1137.         y = lookup(oktab,p,noktab,&z);
  1138.         if (y < 0) return(-1);
  1139.         ckxpriv = y;
  1140.         /* printf("ckxpriv=%d\n",ckxpriv); */
  1141.         break;
  1142.  
  1143.       case XA_PERM:                     /* IKS: Anonymous Upload Permissions */
  1144.         y = 0;
  1145.         while (*p) {
  1146.             if (*p < '0' || *p > '7')
  1147.               return(-1);
  1148.             y = y * 8 + (*p++ - '0');
  1149.         }
  1150.         ckxperms = y;
  1151.         /* printf("ckxperms=%04o\n",ckxperms); */
  1152.         break;
  1153.  
  1154.       case XA_ANFI:                     /* Anonymous init file */
  1155.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1156.           p = tmpbuf;
  1157.         makestr(&anonfile,p);
  1158.         /* printf("anonfile=%s\n",anonfile); */
  1159.         break;
  1160.  
  1161.       case XA_USFI:                     /* IKS: Forbidden user file */
  1162.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1163.           p = tmpbuf;
  1164.         makestr(&userfile,p);
  1165.         /* printf("userfile=%s\n",userfile); */
  1166.         break;
  1167.  
  1168.       case XA_ROOT:                     /* IKS: Anonymous root */
  1169.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1170.           p = tmpbuf;
  1171.         makestr(&anonroot,p);
  1172.         /* printf("anonroot=%s\n",anonroot); */
  1173.         break;
  1174. #endif /* CK_LOGIN */
  1175.  
  1176. #ifndef NOICP
  1177.       case XA_CDFI:                     /* CD filename */
  1178. #ifdef COMMENT
  1179.         /* Do NOT expand this one! */
  1180.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1181.           p = tmpbuf;
  1182. #endif /* COMMENT */
  1183.         makelist(p,cdmsgfile,16);
  1184.         makestr(&cdmsgstr,p);
  1185.         /* printf("cdmsgstr=%s\n",cdmsgstr); */
  1186.         break;
  1187. #endif /* NOICP */
  1188.  
  1189.       case XA_CDMS:                     /* CD messages */
  1190.         y = lookup(oktab,p,noktab,&z);
  1191.         if (y < 0) return(-1);
  1192.         srvcdmsg = y;
  1193.         /* printf("srvcdmsg=%d\n",srvcdmsg); */
  1194.         break;
  1195.  
  1196. #ifndef NOXFER
  1197.       case XA_IKLG:                     /* Transfer log on/off */
  1198.         y = lookup(oktab,p,noktab,&z);
  1199.         if (y < 0) return(-1);
  1200.         xferlog = y;
  1201.         /* printf("xferlog=%d\n",xferlog); */
  1202.         break;
  1203.  
  1204.       case XA_IKFI:                     /* Transfer log file */
  1205.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1206.           p = tmpbuf;
  1207.         makestr(&xferfile,p);
  1208.         xferlog = 1;
  1209.         /* printf("xferfile=%s\n",xferfile); */
  1210.         break;
  1211.  
  1212.       case XA_BAFI:                     /* IKS: banner (greeting) file */
  1213.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1214.           p = tmpbuf;
  1215.         makestr(&bannerfile,p);
  1216.         /* printf("bannerfile=%s\n",bannerfile); */
  1217.         break;
  1218. #endif /* NOXFER */
  1219.  
  1220. #ifndef NOHELP
  1221.       case XA_HELP:                     /* Help */
  1222.         /* printf("help\n"); */
  1223.         for (i = 0; i <= XA_MAX; i++)
  1224.           if (xopthlp[i])
  1225.             printf("%s\n   %s\n\n",xopthlp[i],xarghlp[i]);
  1226. #ifndef NOICP
  1227.         if (stayflg || what == W_COMMAND)
  1228.           break;
  1229.         else
  1230. #endif /* NOICP */
  1231.           doexit(GOOD_EXIT,-1);
  1232. #endif /* NOHELP */
  1233.  
  1234. #ifndef NOHELP
  1235.       case XA_HEFI:                     /* IKS: custom help file */
  1236.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1237.           p = tmpbuf;
  1238.         makestr(&helpfile,p);
  1239.         /* printf("helpfile=%s\n",helpfile); */
  1240.         break;
  1241. #endif /* NOHELP */
  1242.  
  1243. #ifdef CK_LOGIN
  1244.       case XA_TIMO:
  1245.         if (!rdigits(p))
  1246.           return(-1);
  1247.         logintimo = atoi(p);
  1248.         /* printf("logintimo=%d\n",p); */
  1249.         break;
  1250. #endif /* CK_LOGIN */
  1251.  
  1252.       case XA_NOIN:                     /* No interrupts */
  1253. #ifndef NOICP
  1254.         cmdint = 0;
  1255. #endif /* NOICP */
  1256.         suspend = 0;
  1257.         break;
  1258.  
  1259. #ifdef IKSDB
  1260.       case XA_DBFI: {
  1261.           extern char * dbdir, * dbfile;
  1262.           extern int dbenabled;
  1263.           struct zfnfp * zz;
  1264.           if ((zz = zfnqfp(p,CKMAXPATH,tmpbuf))) {
  1265.               makestr(&dbdir,zz->fpath);
  1266.               makestr(&dbfile,(char *)tmpbuf);
  1267.           }
  1268.           dbenabled = 1;
  1269.           break;
  1270.       }
  1271.       case XA_DBAS: {
  1272.           extern int dbenabled;
  1273.           y = lookup(oktab,p,noktab,&z);
  1274.           if (y < 0) return(-1);
  1275.           dbenabled = y;
  1276.           break;
  1277.       }
  1278. #endif /* IKSDB */
  1279.  
  1280.       default:
  1281.         return(-1);
  1282.     }
  1283.     return(0);
  1284. }
  1285. #endif /* NOICP */
  1286.  
  1287. /*  D O A R G  --  Do a command-line argument.  */
  1288.  
  1289. int
  1290. #ifdef CK_ANSIC
  1291. doarg(char x)
  1292. #else
  1293. doarg(x) char x;
  1294. #endif /* CK_ANSIC */
  1295. /* doarg */ {
  1296.     int i, n, y, z, xx; long zz; char *xp;
  1297.  
  1298. #ifdef NETCONN
  1299. #define YYBUFLEN 256
  1300.     char tmpbuf[YYBUFLEN+1];            /* Local storage for network things */
  1301.     char line[YYBUFLEN+1];
  1302. #endif /* NETCONN */
  1303.  
  1304. #ifdef IKSD
  1305.     /* Internet Kermit Server set some way besides -A... */
  1306.     if (inserver)
  1307.       dofast();
  1308. #endif /* IKSD */
  1309.  
  1310.     xp = *xargv+1;                      /* Pointer for bundled args */
  1311.     debug(F111,"doarg entry",xp,xargc);
  1312.     while (x) {
  1313.         debug(F000,"doarg arg","",x);
  1314.         switch (x) {                    /* Big switch on arg */
  1315.  
  1316. #ifndef NOICP
  1317. case '-':                               /* Extended commands... */
  1318.     if (doxarg(xargv,0) < 0) {
  1319.         XFATAL("Extended option error");
  1320.     }                                   /* Full thru... */
  1321. case '+':                               /* Extended command for prescan() */
  1322.     return(0);
  1323. #else  /* NOICP */
  1324. case '-':
  1325. case '+':
  1326.     XFATAL("Extended options not configured");
  1327. #endif /* NOICP */
  1328.  
  1329. #ifndef NOSPL
  1330. case 'C': {                             /* Commands for parser */
  1331.     char * s;
  1332.     xargv++, xargc--;
  1333.     if ((xargc < 1) || (**xargv == '-')) {
  1334.         XFATAL("No commands given for -C");
  1335.     }
  1336.     s = *xargv;                         /* Get the argument (must be quoted) */
  1337.     if (!*s)                            /* If empty quotes */
  1338.       s = NULL;                         /* ignore this option */
  1339.     if (s) {
  1340.         makestr(&clcmds,s);             /* Make pokeable copy */
  1341.         s = clcmds;                     /* Change tabs to spaces */
  1342.         while (*s) {
  1343.             if (*s == '\t') *s = ' ';
  1344.             s++;
  1345.         }
  1346.     }
  1347.     break;
  1348.   }
  1349. #endif /* NOSPL */
  1350.  
  1351. #ifndef NOXFER
  1352. case 'D':                               /* Delay */
  1353.     if (*(xp+1)) {
  1354.         XFATAL("invalid argument bundling");
  1355.     }
  1356.     xargv++, xargc--;
  1357.     if ((xargc < 1) || (**xargv == '-')) {
  1358.         XFATAL("missing delay value");
  1359.     }
  1360.     z = atoi(*xargv);                   /* Convert to number */
  1361.     if (z > -1)                         /* If in range */
  1362.       ckdelay = z;                      /* set it */
  1363.     else {
  1364.         XFATAL("bad delay value");
  1365.     }
  1366.     break;
  1367. #endif /* NOXFER */
  1368.  
  1369. case 'E':                               /* Exit on close */
  1370. #ifdef NETCONN
  1371.     tn_exit = 1;
  1372. #endif /* NETCONN */
  1373.     exitonclose = 1;
  1374.     break;
  1375.  
  1376. #ifndef NOICP
  1377. case 'S':                               /* "Stay" - enter interactive */
  1378.     stayflg = 1;                        /* command parser after executing */
  1379.     xfinish = 0;
  1380.     break;                              /* command-line actions. */
  1381. #endif /* NOICP */
  1382.  
  1383. case 'T':                               /* File transfer mode = text */
  1384.     binary = XYFT_T;
  1385.     xfermode = XMODE_M;            /* Transfer mode manual */
  1386. #ifdef PATTERNS
  1387.     patterns = 0;
  1388. #endif /* PATTERNS */
  1389.     break;
  1390.  
  1391. case '7':
  1392.     break;
  1393.  
  1394. case 'A': {                /* Internet server */
  1395.     /* Already done in prescan() */
  1396.     /* but implies 'x' &&  'Q'   */
  1397. #ifdef NT
  1398.     char * p;
  1399.     if (*(xp+1)) {
  1400.         XFATAL("invalid argument bundling");
  1401.     }
  1402.     /* Support for Pragma Systems Telnet/Terminal Servers */
  1403.     p = getenv("PRAGMASYS_INETD_SOCK");
  1404.     if (!(p && atoi(p) != 0)) {
  1405.         xargv++, xargc--;
  1406.         if (xargc < 1 || **xargv == '-') {
  1407.             XFATAL("missing socket handle");
  1408.     }
  1409.     }
  1410. #endif /* NT */
  1411. #ifdef NOICP                            /* If no Interactive Command Parser */
  1412.     action = 'x';                       /* -A implies -x. */
  1413. #endif /* NOICP */
  1414. #ifndef NOXFER
  1415.     dofast();
  1416. #endif /* NOXFER */
  1417.     break;
  1418. }
  1419.  
  1420. #ifndef NOXFER
  1421. case 'Q':                               /* Quick (i.e. FAST) */
  1422.     dofast();
  1423.     break;
  1424. #endif /* NOXFER */
  1425.  
  1426. case 'R':                               /* Remote-Only */
  1427.     break;                              /* This is handled in prescan(). */
  1428.  
  1429. #ifndef NOSERVER
  1430. case 'x':                               /* server */
  1431. case 'O':                               /* (for One command only) */
  1432.     if (action) {
  1433.         XFATAL("conflicting actions");
  1434.     }
  1435.     if (x == 'O') justone = 1;
  1436.     xfinish = 1;
  1437.     action = 'x';
  1438.     break;
  1439. #endif /* NOSERVER */
  1440.  
  1441. #ifndef NOXFER
  1442. case 'f':                               /* finish */
  1443.     if (action) {
  1444.         XFATAL("conflicting actions");
  1445.     }
  1446.     action = setgen('F',"","","");
  1447.     break;
  1448. #endif /* NOXFER */
  1449.  
  1450. case 'r': {                             /* receive */
  1451.     if (action) {
  1452.         XFATAL("conflicting actions");
  1453.     }
  1454.     action = 'v';
  1455.     break;
  1456.   }
  1457.  
  1458. #ifndef NOXFER
  1459. case 'k':                               /* receive to stdout */
  1460.     if (action) {
  1461.         XFATAL("conflicting actions");
  1462.     }
  1463.     stdouf = 1;
  1464.     action = 'v';
  1465.     break;
  1466.  
  1467. case 's':                               /* send */
  1468.     if (action) {
  1469.         XFATAL("conflicting actions");
  1470.     }
  1471.     if (*(xp+1)) {
  1472.         XFATAL("invalid argument bundling after -s");
  1473.     }
  1474.     nfils = 0;                          /* Initialize file counter */
  1475.     z = 0;                              /* Flag for stdin */
  1476.     cmlist = xargv + 1;                 /* Remember this pointer */
  1477.     while (--xargc > 0) {               /* Traverse the list */
  1478.         xargv++;
  1479. #ifdef PIPESEND
  1480.         if (usepipes && protocol == PROTO_K && **xargv == '!') {
  1481.             cmarg = *xargv;
  1482.             cmarg++;
  1483.             debug(F110,"doarg pipesend",cmarg,0);
  1484.             nfils = -1;
  1485.             z = 1;
  1486.             pipesend = 1;
  1487.         } else
  1488. #endif /* PIPESEND */
  1489.         if (**xargv == '-') {           /* Check for sending stdin */
  1490.             if (strcmp(*xargv,"-") != 0) /* Watch out for next option. */
  1491.               break;
  1492.             z++;                        /* "-" alone means send from stdin. */
  1493. #ifdef RECURSIVE
  1494.         } else if (!strcmp(*xargv,".")) {
  1495.             nfils++;
  1496.             recursive = 1;
  1497. #endif /* RECURSIVE */
  1498.         } else if (zchki(*xargv) > -1) { /* Check if file exists */
  1499.             nfils++;                    /* Bump file counter */
  1500.         } else if (iswild(*xargv) && nzxpand(*xargv,0) > 0) {
  1501.             /* or contains wildcard characters matching real files */
  1502.             nfils++;
  1503.         }
  1504.     }
  1505.     xargc++, xargv--;                   /* Adjust argv/argc */
  1506.     if (nfils < 1 && z == 0) {
  1507. #ifdef VMS
  1508.         XFATAL("%CKERMIT-E-SEARCHFAIL, no files for -s");
  1509. #else
  1510.         XFATAL("No files for -s");
  1511. #endif /* VMS */
  1512.     }
  1513.     if (z > 1) {
  1514.         XFATAL("-s: too many -'s");
  1515.     }
  1516.     if (z == 1 && nfils > 0) {
  1517.         XFATAL("invalid mixture of filenames and '-' in -s");
  1518.     }
  1519.     debug(F101,"doarg s nfils","",nfils);
  1520.     debug(F101,"doarg s z","",z);
  1521.     if (nfils == 0) {
  1522.         if (is_a_tty(0)) {              /* (used to be is_a_tty(1) - why?) */
  1523.             XFATAL("sending from terminal not allowed");
  1524.         } else stdinf = 1;
  1525.     }
  1526.     debug(F101,"doarg s stdinf","",stdinf);
  1527.     debug(F111,"doarg",*xargv,nfils);
  1528.     action = 's';
  1529.     break;
  1530.  
  1531. case 'g':                               /* get */
  1532. case 'G':                               /* get to stdout */
  1533.     if (action) {
  1534.         XFATAL("conflicting actions");
  1535.     }
  1536.     if (*(xp+1)) {
  1537.         XFATAL("invalid argument bundling after -g");
  1538.     }
  1539.     xargv++, xargc--;
  1540.     if ((xargc == 0) || (**xargv == '-')) {
  1541.         XFATAL("missing filename for -g");
  1542.     }
  1543.     if (x == 'G') stdouf = 1;
  1544.     cmarg = *xargv;
  1545.     action = 'r';
  1546.     break;
  1547. #endif /* NOXFER */
  1548.  
  1549. #ifndef NOLOCAL
  1550. case 'c':                               /* connect before */
  1551.     cflg = 1;
  1552.     break;
  1553.  
  1554. case 'n':                               /* connect after */
  1555.     cnflg = 1;
  1556.     break;
  1557. #endif /* NOLOCAL */
  1558.  
  1559. case 'h':                               /* help */
  1560.     usage();
  1561. #ifndef NOICP
  1562.     if (stayflg || what == W_COMMAND)
  1563.       break;
  1564.     else
  1565. #endif /* NOICP */
  1566.       doexit(GOOD_EXIT,-1);
  1567.  
  1568. #ifndef NOXFER
  1569. case 'a':                               /* "as" */
  1570.     if (*(xp+1)) {
  1571.         XFATAL("invalid argument bundling after -a");
  1572.     }
  1573.     xargv++, xargc--;
  1574.     if ((xargc < 1) || (**xargv == '-')) {
  1575.         XFATAL("missing name in -a");
  1576.     }
  1577.     cmarg2 = *xargv;
  1578.     debug(F111,"doarg a",cmarg2,xargc);
  1579.     break;
  1580. #endif /* NOXFER */
  1581.  
  1582. #ifndef NOICP
  1583. case 'Y':                               /* No initialization file */
  1584.     noinit = 1;
  1585.     break;
  1586.  
  1587. case 'y':                               /* Alternate init-file name */
  1588.     if (*(xp+1)) {
  1589.         XFATAL("invalid argument bundling after -y");
  1590.     }
  1591.     xargv++, xargc--;
  1592.     if (xargc < 1) {
  1593.         XFATAL("missing filename in -y");
  1594.     }
  1595.     /* strcpy(kermrc,*xargv); ...this was already done in prescan()... */
  1596.     break;
  1597. #endif /* NOICP */
  1598.  
  1599. #ifndef NOXFER
  1600. case 'I':                               /* Assume we have an "Internet" */
  1601.     reliable = 1;                       /* or other reliable connection */
  1602.     xreliable = 1;
  1603.     setreliable = 1;
  1604.  
  1605.     /* I'm not so sure about this -- what about VMS? (next comment) */
  1606.     clearrq = 1;                        /* therefore the channel is clear */
  1607.  
  1608. #ifndef VMS
  1609. /*
  1610.   Since this can trigger full control-character unprefixing, we need to
  1611.   ensure that our terminal or pty driver is not doing Xon/Xoff; otherwise
  1612.   we can become deadlocked the first time we receive a file that contains
  1613.   Xoff.
  1614. */
  1615.     flow = FLO_NONE;
  1616. #endif /* VMS */
  1617.     break;
  1618. #endif /* NOXFER */
  1619.  
  1620. #ifndef NOLOCAL
  1621. case 'l':                               /* SET LINE */
  1622. #ifdef NETCONN
  1623. #ifdef ANYX25
  1624. case 'X':                               /* SET HOST to X.25 address */
  1625. #ifdef SUNX25
  1626. case 'Z':                               /* SET HOST to X.25 file descriptor */
  1627. #endif /* SUNX25 */
  1628. #endif /* ANYX25 */
  1629. #ifdef TCPSOCKET
  1630. case 'J':
  1631. case 'j':                               /* SET HOST (TCP/IP socket) */
  1632. #endif /* TCPSOCKET */
  1633. #endif /* NETCONN */
  1634. #ifndef NOXFER
  1635.     if (x == 'j' || x == 'J' || x == 'X' || x == 'Z') {
  1636.         reliable = 1;                   /* or other reliable connection */
  1637.         xreliable = 1;
  1638.         setreliable = 1;
  1639.     }
  1640. #endif /* NOXFER */
  1641.     network = 0;
  1642.     if (*(xp+1)) {
  1643.         XFATAL("invalid argument bundling after -l or -j");
  1644.     }
  1645.     xargv++, xargc--;
  1646.     if ((xargc < 1) || (**xargv == '-')) {
  1647.         XFATAL("communication line device name missing");
  1648.     }
  1649.  
  1650. #ifdef NETCONN
  1651.     if (x == 'J') {
  1652.         cflg    = 1;                    /* Connect */
  1653.         stayflg = 1;                    /* Stay */
  1654.         tn_exit = 1;                    /* Telnet-like exit condition */
  1655.         exitonclose = 1;
  1656.     }
  1657. #endif /* NETCONN */
  1658.     ckstrncpy(ttname,*xargv,TTNAMLEN+1);
  1659.     local = (strcmp(ttname,CTTNAM) != 0);
  1660.     if (local && strcmp(ttname,"0") == 0)
  1661.       local = 0;
  1662. /*
  1663.   NOTE: We really do not need to call ttopen here, since it should be called
  1664.   again later, automatically, when we first try to condition the device via
  1665.   ttpkt or ttvt.  Calling ttopen here has the bad side effect of making the
  1666.   order of the -b and -l options significant, but order of command-line options
  1667.   should not matter.  However, the network cases immediately below complicate
  1668.   matters a bit, so we'll settle this in a future edit.
  1669. */
  1670.     if (x == 'l') {
  1671.         if (ttopen(ttname,&local,mdmtyp,0) < 0) {
  1672.             XFATAL("can't open device");
  1673.         }
  1674. #ifdef CKLOGDIAL
  1675.         dologline();
  1676. #endif /* CKLOGDIAL */
  1677.         debug(F101,"doarg speed","",speed);
  1678.         cxtype = (mdmtyp > 0) ? CXT_MODEM : CXT_DIRECT;
  1679.         speed = ttgspd();               /* Get the speed. */
  1680.         setflow();                      /* Do something about flow control. */
  1681. #ifndef NOSPL
  1682.         if (local) {
  1683.             if (nmac) {                 /* Any macros defined? */
  1684.                 int k;                  /* Yes */
  1685.                 k = mlook(mactab,"on_open",nmac);       /* Look this up */
  1686.                 if (k >= 0) {                   /* If found, */
  1687.                     if (dodo(k,ttname,0) > -1)  /* set it up, */
  1688.                       parser(1);                        /* and execute it */
  1689.                 }
  1690.             }
  1691.         }
  1692. #endif /* NOSPL */
  1693.  
  1694. #ifdef NETCONN
  1695.     } else {
  1696.         if (x == 'j' || x == 'J') {     /* IP network host name */
  1697.             char * s = line;
  1698.             char * service = tmpbuf;
  1699.             if (xargc > 0) {            /* Check if it's followed by */
  1700.                 /* A service name or number */
  1701.                 if (*(xargv+1) && *(*(xargv+1)) != '-') {
  1702.                     xargv++, xargc--;
  1703.                     strcat(ttname,":");
  1704.                     strcat(ttname,*xargv);
  1705.                 }
  1706.             }
  1707.             nettype = NET_TCPB;
  1708.             mdmtyp = -nettype;          /* Perhaps already set in init file */
  1709.             telnetfd = 1;               /* Or maybe an open file descriptor */
  1710.  
  1711.             ckstrncpy(line, ttname, YYBUFLEN); /* Working copy of the name */
  1712.             for (s = line; *s != '\0' && *s != ':'; s++); /* and service */
  1713.             if (*s) {
  1714.                 *s++ = '\0';
  1715.                 ckstrncpy(service, s, YYBUFLEN);
  1716.             } else *service = '\0';
  1717.             s = line;
  1718. #ifndef NODIAL
  1719. #ifndef NOICP
  1720.             /* Look up in network directory */
  1721.             x = 0;
  1722.             if (*s == '=') {            /* If number starts with = sign */
  1723.                 s++;                    /* strip it */
  1724.                 while (*s == SP)        /* and also any leading spaces */
  1725.                   s++;
  1726.                 ckstrncpy(line,s,YYBUFLEN); /* Do this again. */
  1727.                 nhcount = 0;
  1728.             } else if (!isdigit(line[0])) {
  1729. /*
  1730.   nnetdir will be greater than 0 if the init file has been processed and it
  1731.   contained a SET NETWORK DIRECTORY command.
  1732. */
  1733.                 xx = 0;                 /* Initialize this */
  1734.                 if (nnetdir > 0)        /* If there is a directory... */
  1735.                   xx = lunet(line);     /* Look up the name */
  1736.                 else                    /* If no directory */
  1737.                   nhcount = 0;          /* we didn't find anything there */
  1738.                 if (xx < 0) {           /* Lookup error: */
  1739.                     sprintf(tmpbuf,
  1740.                             "?Fatal network directory lookup error - %s\n",
  1741.                             line
  1742.                             );
  1743.                     XFATAL(tmpbuf);
  1744.                 }
  1745.             }
  1746. #endif /* NOICP */
  1747. #endif /* NODIAL */
  1748.             /* Add service to line specification for ttopen() */
  1749.             if (*service) {             /* There is a service specified */
  1750.                 strcat(line, ":");
  1751.                 strcat(line, service);
  1752.                 ttnproto = NP_DEFAULT;
  1753.             } else {
  1754.                 strcat(line, ":telnet");
  1755.                 ttnproto = NP_TELNET;
  1756.             }
  1757.  
  1758. #ifndef NOICP
  1759. #ifndef NODIAL
  1760.             if ((nhcount > 1) && !quiet && !backgrd) {
  1761.                 printf("%d entr%s found for \"%s\"%s\n",
  1762.                        nhcount,
  1763.                        (nhcount == 1) ? "y" : "ies",
  1764.                        s,
  1765.                        (nhcount > 0) ? ":" : "."
  1766.                        );
  1767.                 for (i = 0; i < nhcount; i++)
  1768.                   printf("%3d. %s %-12s => %s\n",
  1769.                          i+1, n_name, nh_p2[i], nh_p[i]
  1770.                          );
  1771.             }
  1772.             if (nhcount == 0)
  1773.               n = 1;
  1774.             else
  1775.               n = nhcount;
  1776. #else
  1777.             n = 1;
  1778.             nhcount = 0;
  1779. #endif /* NODIAL */
  1780.             for (i = 0; i < n; i++) {
  1781. #ifndef NODIAL
  1782.                 if (nhcount >= 1) {
  1783.                     /* Copy the current entry to line */
  1784.                     ckstrncpy(line,nh_p[i],LINBUFSIZ);
  1785.                     /* Check to see if the network entry contains a service */
  1786.                     for (s = line ; (*s != '\0') && (*s != ':'); s++)
  1787.                       ;
  1788.                     /* If directory does not have a service ... */
  1789.                     if (!*s && *service) { /* and the user specified one */
  1790.                         strcat(line, ":");
  1791.                         strcat(line, service);
  1792.                     }
  1793.                     if (lookup(netcmd,nh_p2[i],nnets,&z) > -1) {
  1794.                         mdmtyp = 0 - netcmd[z].kwval;
  1795.                     } else {
  1796.                         printf("Error - network type \"%s\" not supported\n",
  1797.                                nh_p2[i]
  1798.                                );
  1799.                         continue;
  1800.                     }
  1801.                 }
  1802. #endif /* NODIAL */
  1803.             }
  1804. #endif /* NOICP */
  1805.             ckstrncpy(ttname, line,TTNAMLEN+1);
  1806.             cxtype = CXT_TCPIP;         /* Set connection type */
  1807.             setflow();                  /* Set appropriate flow control. */
  1808. #ifdef SUNX25
  1809.         } else if (x == 'X') {          /* X.25 address */
  1810.             nettype = NET_SX25;
  1811.             mdmtyp = -nettype;
  1812.         } else if (x == 'Z') {          /* Open X.25 file descriptor */
  1813.             nettype = NET_SX25;
  1814.             mdmtyp = -nettype;
  1815.             x25fd = 1;
  1816. #endif /* SUNX25 */
  1817. #ifdef STRATUSX25
  1818.         } else if (x == 'X') {          /* X.25 address */
  1819.             nettype = NET_VX25;
  1820.             mdmtyp = -nettype;
  1821. #endif /* STRATUSX25 */
  1822. #ifdef IBMX25
  1823.         } else if (x == 'X') {          /* X.25 address */
  1824.             nettype = NET_IX25;
  1825.             mdmtyp = -nettype;
  1826. #endif /* IBMX25 */
  1827. #ifdef HPX25
  1828.         } else if (x == 'X') {          /* X.25 address */
  1829.             nettype = NET_HX25;
  1830.             mdmtyp = -nettype;
  1831. #endif /* HPX25 */
  1832.         }
  1833.         if (ttopen(ttname,&local,mdmtyp,0) < 0) {
  1834.             XFATAL("can't open host connection");
  1835.         }
  1836.         network = 1;
  1837. #ifdef CKLOGDIAL
  1838.         dolognet();
  1839. #endif /* CKLOGDIAL */
  1840.         cxtype = CXT_X25;               /* Set connection type */
  1841.         setflow();                      /* Set appropriate flow control. */
  1842. #ifndef NOSPL
  1843.         if (local) {
  1844.             if (nmac) {                 /* Any macros defined? */
  1845.                 int k;                  /* Yes */
  1846.                 k = mlook(mactab,"on_open",nmac); /* Look this up */
  1847.                 if (k >= 0) {           /* If found, */
  1848.                     if (dodo(k,ttname,0) > -1) /* set it up, */
  1849.                       parser(1);        /* and execute it */
  1850.                 }
  1851.             }
  1852.         }
  1853. #endif /* NOSPL */
  1854. #endif /* NETCONN */
  1855.     }
  1856.     /* add more here -- decnet, etc... */
  1857.     haveline = 1;
  1858.     break;
  1859.  
  1860. #ifdef ANYX25
  1861. case 'U':                               /* X.25 call user data */
  1862.     if (*(xp+1)) {
  1863.         XFATAL("invalid argument bundling");
  1864.     }
  1865.     xargv++, xargc--;
  1866.     if ((xargc < 1) || (**xargv == '-')) {
  1867.         XFATAL("missing call user data string");
  1868.     }
  1869.     ckstrncpy(udata,*xargv,MAXCUDATA);
  1870.     if ((int)strlen(udata) <= MAXCUDATA) {
  1871.         cudata = 1;
  1872.     } else {
  1873.         XFATAL("Invalid call user data");
  1874.     }
  1875.     break;
  1876.  
  1877. case 'o':                               /* X.25 closed user group */
  1878.     if (*(xp+1)) {
  1879.         XFATAL("invalid argument bundling");
  1880.     }
  1881.     xargv++, xargc--;
  1882.     if ((xargc < 1) || (**xargv == '-')) {
  1883.         XFATAL("missing closed user group index");
  1884.     }
  1885.     z = atoi(*xargv);                   /* Convert to number */
  1886.     if (z >= 0 && z <= 99) {
  1887.         closgr = z;
  1888.     } else {
  1889.         XFATAL("Invalid closed user group index");
  1890.     }
  1891.     break;
  1892.  
  1893. case 'u':                               /* X.25 reverse charge call */
  1894.     revcall = 1;
  1895.     break;
  1896. #endif /* ANYX25 */
  1897. #endif /* NOLOCAL */
  1898.  
  1899. case 'b':                               /* Bits-per-second for serial device */
  1900.     if (*(xp+1)) {
  1901.         XFATAL("invalid argument bundling");
  1902.     }
  1903.     xargv++, xargc--;
  1904.     if ((xargc < 1) || (**xargv == '-')) {
  1905.         XFATAL("missing bps");
  1906.     }
  1907.     zz = atol(*xargv);                  /* Convert to long int */
  1908.     i = zz / 10L;
  1909. #ifndef NOLOCAL
  1910.     if (ttsspd(i) > -1)                 /* Check and set it */
  1911. #endif /* NOLOCAL */
  1912.       speed = ttgspd();                 /* and read it back. */
  1913. #ifndef NOLOCAL
  1914.     else {
  1915.         XFATAL("unsupported transmission rate");
  1916.     }
  1917. #endif /* NOLOCAL */
  1918.     break;
  1919.  
  1920. #ifndef NODIAL
  1921. #ifndef NOICP
  1922. case 'm':                               /* Modem type */
  1923.     if (*(xp+1)) {
  1924.         XFATAL("invalid argument bundling after -m");
  1925.     }
  1926.     xargv++, xargc--;
  1927.     if ((xargc < 1) || (**xargv == '-')) {
  1928.         XFATAL("modem type missing");
  1929.     }
  1930.     y = lookup(mdmtab,*xargv,nmdm,&z);
  1931.     if (y < 0) {
  1932.         XFATAL("unknown modem type");
  1933.     }
  1934.     usermdm = 0;
  1935.     usermdm = (y == dialudt) ? x : 0;
  1936.     initmdm(y);
  1937.     break;
  1938. #endif /* NOICP */
  1939. #endif /* NODIAL */
  1940.  
  1941. #ifndef NOXFER
  1942. case 'e':                               /* Extended packet length */
  1943.     if (*(xp+1)) {
  1944.         XFATAL("invalid argument bundling after -e");
  1945.     }
  1946.     xargv++, xargc--;
  1947.     if ((xargc < 1) || (**xargv == '-')) {
  1948.         XFATAL("missing length");
  1949.     }
  1950.     z = atoi(*xargv);                   /* Convert to number */
  1951.     if (z > 10 && z <= maxrps) {
  1952.         rpsiz = urpsiz = z;
  1953.         if (z > 94) rpsiz = 94;         /* Fallback if other Kermit can't */
  1954.     } else {
  1955.         XFATAL("Unsupported packet length");
  1956.     }
  1957.     break;
  1958.  
  1959. case 'v':                               /* Vindow size */
  1960.     if (*(xp+1)) {
  1961.         XFATAL("invalid argument bundling");
  1962.     }
  1963.     xargv++, xargc--;
  1964.     if ((xargc < 1) || (**xargv == '-')) {
  1965.         XFATAL("missing or bad window size");
  1966.     }
  1967.     z = atoi(*xargv);                   /* Convert to number */
  1968.     if (z < 32) {                       /* If in range */
  1969.         wslotr = z;                     /* set it */
  1970.         if (z > 1) swcapr = 1;          /* Set capas bit if windowing */
  1971.     } else {
  1972.         XFATAL("Unsupported packet length");
  1973.     }
  1974.     break;
  1975. #endif /* NOXFER */
  1976.  
  1977. case 'i':                               /* Treat files as binary */
  1978.     binary = XYFT_B;
  1979.     xfermode = XMODE_M;            /* Transfer mode manual */
  1980. #ifdef PATTERNS
  1981.     patterns = 0;
  1982. #endif /* PATTERNS */
  1983.     break;
  1984.  
  1985. #ifndef NOXFER
  1986. case 'w':                               /* Writeover */
  1987.     ckwarn = 0;
  1988.     fncact = XYFX_X;
  1989.     break;
  1990. #endif /* NOXFER */
  1991.  
  1992. case 'q':                               /* Quiet */
  1993.     quiet = 1;
  1994.     break;
  1995.  
  1996. #ifdef DEBUG
  1997. case 'd':                               /* DEBUG */
  1998.     break;                              /* Handled in prescan() */
  1999. #endif /* DEBUG */
  2000.  
  2001. case '0': {                             /* In the middle */
  2002.     extern int tt_escape, lscapr;
  2003.     tt_escape = 0;                      /* No escape character */
  2004.     flow = 0;                           /* No Xon/Xoff (what about hwfc?) */
  2005. #ifndef NOXFER
  2006.     lscapr = 0;                         /* No locking shifts */
  2007. #endif /* NOXFER */
  2008. #ifdef CK_APC
  2009.     {
  2010.         extern int apcstatus;           /* No APCs */
  2011.         apcstatus = APC_OFF;
  2012.     }
  2013. #endif /* CK_APC */
  2014. #ifdef CK_AUTODL
  2015.     {                                   /* No autodownload */
  2016.         extern int autodl;
  2017.         autodl = 0;
  2018.     }
  2019. #endif /* CK_AUTODL */
  2020. #ifndef NOCSETS
  2021.     {
  2022.         extern int tcsr, tcsl;          /* No character-set translation */
  2023.         tcsr = 0;
  2024.         tcsl = tcsr;                    /* Make these equal */
  2025.     }
  2026. #endif /* NOCSETS */
  2027. #ifdef TNCODE
  2028.     TELOPT_DEF_C_U_MODE(TELOPT_KERMIT) = TN_NG_RF;
  2029.     TELOPT_DEF_C_ME_MODE(TELOPT_KERMIT) = TN_NG_RF;
  2030.     TELOPT_DEF_S_U_MODE(TELOPT_KERMIT) = TN_NG_RF;
  2031.     TELOPT_DEF_S_ME_MODE(TELOPT_KERMIT) = TN_NG_RF;
  2032. #endif /* TNCODE */
  2033. }
  2034. /* Fall thru... */
  2035.  
  2036. case '8':                               /* 8-bit clean */
  2037.     parity = 0;
  2038.     cmdmsk = 0xff;
  2039.     cmask = 0xff;
  2040.     break;
  2041.  
  2042. case 'V': {
  2043.     extern int xfermode;
  2044. #ifdef PATTERNS
  2045.     extern int patterns;
  2046.     patterns = 0;                       /* No patterns */
  2047. #endif /* PATTERNS */
  2048.     xfermode = XMODE_M;                 /* Manual transfer mode */
  2049.     break;
  2050. }
  2051.  
  2052. case 'p':                               /* SET PARITY */
  2053.     if (*(xp+1)) {
  2054.         XFATAL("invalid argument bundling");
  2055.     }
  2056.     xargv++, xargc--;
  2057.     if ((xargc < 1) || (**xargv == '-')) {
  2058.         XFATAL("missing parity");
  2059.     }
  2060.     switch(x = **xargv) {
  2061.         case 'e':
  2062.         case 'o':
  2063.         case 'm':
  2064.         case 's': parity = x; break;
  2065.         case 'n': parity = 0; break;
  2066.         default:  { XFATAL("invalid parity"); }
  2067.         }
  2068.     break;
  2069.  
  2070. case 't':                               /* Line turnaround handshake */
  2071.     turn = 1;
  2072.     turnch = XON;                       /* XON is turnaround character */
  2073.     duplex = 1;                         /* Half duplex */
  2074.     flow = 0;                           /* No flow control */
  2075.     break;
  2076.  
  2077. case 'B':
  2078.     bgset = 1;                          /* Force background (batch) */
  2079.     backgrd = 1;
  2080.     break;
  2081.  
  2082. case 'z':                               /* Force foreground */
  2083.     bgset = 0;
  2084.     backgrd = 0;
  2085.     break;
  2086.  
  2087. #ifndef NOXFER
  2088. #ifdef RECURSIVE
  2089. case 'L':
  2090.     recursive = 2;
  2091.     fnspath = PATH_REL;
  2092.     break;
  2093. #endif /* RECURSIVE */
  2094. #endif /* NOXFER */
  2095.  
  2096. #ifndef NOSPL
  2097. case 'M':                               /* My User Name */
  2098.     /* Already done in prescan() */
  2099.     if (*(xp+1)) {
  2100.         XFATAL("invalid argument bundling");
  2101.     }
  2102.     xargv++, xargc--;
  2103.     if ((xargc < 1) || (**xargv == '-')) {
  2104.         XFATAL("missing username");
  2105.     }
  2106. #ifdef COMMENT
  2107.     if ((int)strlen(*xargv) > 63) {
  2108.         XFATAL("username too long");
  2109.     }
  2110. #ifdef IKSD
  2111.     if (!inserver)
  2112. #endif /* IKSD */
  2113.       ckstrncpy(uidbuf,tmpusrid,UIDBUFLEN);
  2114. #endif /* COMMENT */
  2115.     break;
  2116. #endif /* NOSPL */
  2117.  
  2118. #ifdef CK_NETBIOS
  2119. case 'N':                              /* NetBios Adapter Number follows */
  2120.     if (*(xp+1)) {
  2121.         XFATAL("invalid argument bundling after -N");
  2122.     }
  2123.     xargv++, xargc--;
  2124.     if ((xargc < 1) || (**xargv == '-')) {
  2125.         XFATAL("missing NetBios Adapter number");
  2126.     }
  2127.     if ((strlen(*xargv) != 1) ||
  2128.         (*xargv)[0] != 'X' &&
  2129.         (atoi(*xargv) < 0) &&
  2130.          (atoi(*xargv) > 9)) {
  2131.         XFATAL("Invalid NetBios Adapter - Adapters 0 to 9 are valid");
  2132.     }
  2133.     break;
  2134. #endif /* CK_NETBIOS */
  2135.  
  2136. #ifdef NETCONN
  2137. case 'F':
  2138.     network = 1;
  2139.     if (*(xp+1)) {
  2140.         XFATAL("invalid argument bundling after -F");
  2141.     }
  2142.     xargv++, xargc--;
  2143.     if ((xargc < 1) || (**xargv == '-')) {
  2144.         XFATAL("network file descriptor missing");
  2145.     }
  2146.     ckstrncpy(ttname,*xargv,TTNAMLEN+1);
  2147.     nettype = NET_TCPB;
  2148.     mdmtyp = -nettype;
  2149.     telnetfd = 1;
  2150.     local = 1;
  2151.     break;
  2152. #endif /* NETCONN */
  2153.  
  2154. #ifdef COMMENT
  2155. #ifdef OS2PM
  2156. case 'P':                               /* OS/2 Presentation Manager */
  2157.     if (*(xp+1)) {
  2158.         XFATAL("invalid argument bundling after -P");
  2159.     }
  2160.     xargv++, xargc--;
  2161.     if ((xargc < 1) || (**xargv == '-')) {
  2162.         XFATAL("pipe data missing");
  2163.     }
  2164.     pipedata = *xargv;
  2165.     break;
  2166. #endif /* OS2PM */
  2167. #else
  2168. case 'P':                /* Filenames literal */
  2169.     fncnv  = XYFN_L;
  2170.     f_save = XYFN_L;
  2171.     break;
  2172. #endif /* COMMENT */
  2173.  
  2174. #ifndef NOICP
  2175. case 'H':
  2176.     noherald = 1;
  2177.     break;
  2178. #endif /* NOICP */
  2179.  
  2180. #ifdef OS2
  2181. case 'W':
  2182.     if (*(xp+1)) {
  2183.         XFATAL("invalid argument bundling after -W");
  2184.     }
  2185.     xargv++, xargc--;
  2186.     if ((xargc < 1)) { /* could be negative */
  2187.         XFATAL("Window handle missing");
  2188.     }
  2189.     xargv++, xargc--;
  2190.     if ((xargc < 1) || (**xargv == '-')) {
  2191.         XFATAL("Kermit Instance missing");
  2192.     }
  2193.     /* Action done in prescan */
  2194.     break;
  2195.  
  2196. case '#':                               /* K95 stdio threads */
  2197.     xargv++, xargc--;                   /* Skip past argument */
  2198.     break;                              /* Action done in prescan */
  2199. #endif /* OS2 */
  2200.  
  2201. default:
  2202.     fatal2(*xargv,
  2203. #ifdef NT
  2204.                    "invalid command-line option, type \"k95 -h\" for help"
  2205. #else
  2206. #ifdef OS2
  2207.                    "invalid command-line option, type \"k2 -h\" for help"
  2208. #else
  2209.                    "invalid command-line option, type \"kermit -h\" for help"
  2210. #endif /* OS2 */
  2211. #endif /* NT */
  2212.            );
  2213.         }
  2214.     if (!xp) break;
  2215.     x = *++xp;                          /* See if options are bundled */
  2216.     }
  2217.     return(0);
  2218. }
  2219. #else /* No command-line interface... */
  2220.  
  2221. extern int xargc;
  2222. int
  2223. cmdlin() {
  2224.     if (xargc > 1) {
  2225.         XFATAL("Sorry, command-line options disabled.");
  2226.     }
  2227. }
  2228. #endif /* NOCMDL */
  2229.