home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ckv200.zip / ckuusy.c < prev    next >
C/C++ Source or Header  |  2001-12-08  |  108KB  |  3,706 lines

  1. #include "ckcsym.h"
  2. #define XFATAL fatal
  3.  
  4. /*  C K U U S Y --  "User Interface" for Unix Kermit, part Y  */
  5.  
  6. /*  Command-Line Argument Parser */
  7.  
  8. /*
  9.   Author: Frank da Cruz <fdc@columbia.edu>
  10.   Columbia University, New York City.
  11.  
  12.   Copyright (C) 1985, 2001,
  13.     Trustees of Columbia University in the City of New York.
  14.     All rights reserved.  See the C-Kermit COPYING.TXT file or the
  15.     copyright text in the ckcmai.c module for disclaimer and permissions.
  16. */
  17. #include "ckcdeb.h"
  18.  
  19. char * bannerfile = NULL;
  20. char * helpfile = NULL;
  21. extern int xferlog, filepeek, nolinks;
  22. extern char * xferfile;
  23.  
  24. #include "ckcasc.h"
  25. #include "ckcker.h"
  26. #include "ckucmd.h"
  27. #include "ckcnet.h"
  28. #include "ckuusr.h"
  29. #ifdef CK_SSL
  30. #include "ck_ssl.h"
  31. #endif /* CK_SSL */
  32. #include <signal.h>
  33.  
  34. #ifdef OS2
  35. #include <io.h>
  36. #endif /* OS2 */
  37.  
  38. extern int inserver, fncnv, f_save, xfermode;
  39. #ifdef PATTERNS
  40. extern int patterns;
  41. #endif /* PATTERNS */
  42.  
  43. #ifndef NOICP
  44. extern int cmdint;
  45. #endif /* NOICP */
  46. extern int suspend;
  47.  
  48. #ifdef NETCONN
  49. #ifdef ANYX25
  50. extern int revcall, closgr, cudata;
  51. extern char udata[];
  52. extern int x25fd;
  53. #endif /* ANYX25 */
  54. #ifndef VMS
  55. #ifndef OS2
  56. #ifndef OSK
  57. extern
  58. #endif /* OSK */
  59. #endif /* OS2 */
  60. #endif /* VMS */
  61.  
  62. int telnetfd;
  63. extern struct keytab netcmd[];
  64. extern int tn_exit;
  65. #ifndef NOICP
  66. #ifndef NODIAL
  67. extern int nnets, nnetdir;              /* Network services directory */
  68. extern char *netdir[];
  69. extern char *nh_p[];                    /* Network directory entry pointers */
  70. extern char *nh_p2[];                   /* Network directory entry nettype */
  71. extern char *nh_px[4][MAXDNUMS + 1];
  72. #endif /* NODIAL */
  73. extern int nhcount;
  74. extern char * n_name;                   /* Network name pointer */
  75. #endif /* NOICP */
  76. #endif /* NETCONN */
  77.  
  78. #ifndef NOSPL
  79. extern int nmac;
  80. extern struct mtab *mactab;
  81. #endif /* NOSPL */
  82. extern char uidbuf[];
  83.  
  84. #ifdef CK_LOGIN
  85. extern int logintimo;
  86. #endif /* CK_LOGIN */
  87.  
  88. extern char * myname, * dftty;
  89. extern int howcalled;
  90.  
  91. extern char *ckxsys, *ckzsys, **xargv, *xarg0, **cmlist, *clcmds;
  92.  
  93. extern int action, cflg, xargc, cnflg, local, quiet, escape, network, mdmtyp,
  94.   bgset, backgrd, xargs, binary, parity, turn, turnch, duplex, flow, clfils,
  95.   noinit, stayflg, nettype, cfilef, noherald, cmask, cmdmsk, exitonclose,
  96.   haveline, justone, cxtype, xfinish, ttnproto;
  97.  
  98. extern long speed;
  99. extern char ttname[];
  100. extern char * pipedata, * cmdfil;
  101.  
  102. #ifndef NOXFER
  103. extern char *cmarg, *cmarg2;
  104.  
  105. extern int nfils, stdouf, stdinf, displa, maxrps, rpsiz, ckwarn, urpsiz,
  106.   wslotr, swcapr, ckdelay, recursive, reliable, xreliable, fnspath, fncact,
  107.   clearrq, setreliable;
  108.  
  109. #ifdef PIPESEND
  110. extern int usepipes, pipesend;
  111. #endif /* PIPESEND */
  112. extern int protocol;
  113. #endif /* NOXFER */
  114.  
  115. #ifdef OS2
  116. extern struct keytab os2devtab[];
  117. extern int nos2dev;
  118. extern int ttslip;
  119. #ifdef OS2PM
  120. extern int os2pm;
  121. #endif /* OS2PM */
  122. #endif /* OS2 */
  123.  
  124. #ifdef CK_NETBIOS
  125. extern unsigned char NetBiosAdapter;
  126. #endif /* CK_NETBIOS */
  127.  
  128. #ifdef XFATAL
  129. #undef XFATAL
  130. #endif /* XFATAL */
  131.  
  132. #ifdef TNCODE
  133. _PROTOTYP(static int dotnarg, (char x) );
  134. #endif /* TNCODE */
  135.  
  136. int haveftpuid = 0;
  137. #ifdef NEWFTP
  138. extern char * ftp_host;
  139. #endif /* NEWFTP */
  140.  
  141. extern int what;
  142.  
  143. #ifndef NOICP
  144. #ifndef NODIAL
  145. extern int nmdm, telephony;
  146. extern struct keytab mdmtab[];
  147. extern int usermdm, dialudt;
  148. #endif /* NODIAL */
  149. _PROTOTYP(static int pmsg, (char *) );
  150. _PROTOTYP(static int fmsg, (char *) );
  151. static int pmsg(s) char *s; { printf("%s\n", s); return(0); }
  152. static int fmsg(s) char *s; { fatal(s); return(0); }
  153. #define XFATAL(s) return(what==W_COMMAND?pmsg(s):fmsg(s))
  154. #else
  155. #define XFATAL fatal
  156. #endif /* NOICP */
  157.  
  158. #ifndef NOHTTP
  159. #define HTTP_GET 1
  160. #define HTTP_PUT 2
  161. #define HTTP_HED 3
  162. #endif /* NOHTTP */
  163.  
  164. #ifdef CK_URL
  165. /* URLs we recognize */
  166.  
  167. #define URL_FTP    1
  168. #define URL_HTTP   2
  169. #define URL_HTTPS  3
  170. #define URL_IKSD   4
  171. #define URL_TELNET 5
  172. #define URL_LOGIN  6
  173.  
  174. struct keytab urltab[] = {
  175. #ifdef NEWFTP
  176.     "ftp",    URL_FTP,    0,
  177. #endif /* NEWFTP */
  178. #ifndef NOHTTP
  179.     "http",   URL_HTTP,   0,
  180.     "https",  URL_HTTPS,  0,
  181. #endif /* NOHTTP */
  182.     "iksd",   URL_IKSD,   0,
  183.     "telnet", URL_TELNET, 0,
  184.     "", 0, 0
  185. };
  186. int nurltab = sizeof(urltab)/sizeof(struct keytab) - 1;
  187.  
  188. #ifndef URLBUFLEN
  189. #define URLBUFLEN 1024
  190. #endif /* URLBUFLEN */
  191. static char urlbuf[URLBUFLEN];
  192. struct urldata g_url = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
  193.  
  194. /* u r l p a r s e  --  Parse a possible URL */
  195.  
  196. /*
  197.   Returns 0 if the candidate does not seem to be a URL.
  198.   Returns 1 if it might be a URL, with the above pointers set to its pieces:
  199.     service : [ // ] [ user [ : password ] @ ] host [ : service ] [ / path ]
  200.  
  201.   Example: ftp://ds.internic.net:21/rfc/rfc1234.txt
  202.     url.svc = [ftp]
  203.     url.usr = [(NULL)]
  204.     url.psw = [(NULL)]
  205.     url.hos = [ds.internic.net]
  206.     url.por = [21]
  207.     url.pth = [rfc/rfc1234.txt]
  208.  
  209.   It might be a URL if it contains a possible service name followed by a
  210.   a colon (:).  Thus "telnet:xyzcorp.com" is a minimal URL, whereas a
  211.   full-blown example would be:
  212.  
  213.     ftp://olga:secret@ftp.xyzcorp.com/public/oofa.txt
  214.  
  215.   The caller must verify the results, i.e. that the service string is a real
  216.   TCP service, etc.  This routine just parses the fields.
  217.  
  218.   struct urldata defined in ckcker.h
  219. */
  220.  
  221. int
  222. urlparse(s,url) char *s; struct urldata * url; {
  223.     char * p = NULL, * urlbuf = NULL;
  224.     int x;
  225.  
  226.     if (!s || !url)
  227.         return(0);
  228.  
  229.     if (!*s)
  230.         return(0);
  231.  
  232.     makestr(&urlbuf,s);
  233.  
  234.     if (url->sav) {            /* In case we were called before... */
  235.         free(url->sav);
  236.         url->sav = NULL;
  237.     }
  238.     if (url->svc) {
  239.         free(url->svc);
  240.         url->svc = NULL;
  241.     }
  242.     if (url->hos) {
  243.         free(url->svc);
  244.         url->hos = NULL;
  245.     }
  246.     if (url->por) {
  247.         free(url->por);
  248.         url->por = NULL;
  249.     }
  250.     if (url->usr) {
  251.         free(url->usr);
  252.         url->usr = NULL;
  253.     }
  254.     if (url->psw) {
  255.         free(url->psw);
  256.         url->psw = NULL;
  257.     }
  258.     if (url->pth) {
  259.         free(url->pth);
  260.         url->pth = NULL;
  261.     }
  262.     p = urlbuf;                /* Was a service requested? */
  263.     while (*p && *p != ':')        /* Look for colon */
  264.       p++;
  265.     if (*p == ':') {                    /* Have a colon */
  266.         *p++ = NUL;            /* Get service name or number */
  267.         if (*p == ':')            /* a second colon */
  268.           *p++ = NUL;            /* get rid of that one too */
  269.         while (*p == '/') *p++ = NUL;    /* and slashes */
  270. #ifdef COMMENT
  271.         /* Trailing slash is part of path - leave it - jaltman */
  272.         x = strlen(p);                  /* Length of remainder */
  273.         if (p[x-1] == '/')              /* If there is a trailing slash */
  274.           p[x-1] = NUL;            /* remove it. */
  275. #endif /* COMMENT */
  276.         if (urlbuf[0]) {        /* Anything left? */
  277.             char *q = p, *r = p, *w = p;
  278.         makestr(&url->svc,urlbuf);
  279.  
  280.             while (*p != NUL && *p != '@') /* look for @ */
  281.           p++;
  282.             if (*p == '@') {        /* Signifies user ID, maybe password */
  283.                 *p++ = NUL;
  284.         url->hos = p;
  285.                 while (*w != NUL && *w != ':')
  286.                   w++;
  287.                 if (*w == ':')
  288.                   *w++ = NUL;
  289.         url->usr = r;        /* Username */
  290.         url->psw = w;        /* Password */
  291.                 q = p;
  292.             } else {            /* No username or password */
  293.                 p = q;
  294.         url->hos = p;
  295.             }
  296.             while (*p != NUL && *p != ':' && *p != '/')    /* Port? */
  297.               p++;
  298.             if (*p == ':') {        /* TCP port */
  299.                 *p++ = NUL;
  300.                 r = p;
  301.         url->por = r;
  302.                 while (*p != NUL && *p != '/')
  303.           p++;
  304.                 /* '/' is part of path, leave it until we can copy */
  305.                 if (*p == '/') {
  306.             makestr(&url->pth,p);  /* Path */
  307.             *p = NUL;
  308.                 }
  309.             } else {            /* No port */
  310.                 /* '/' is part of path, leave it */
  311.                 if (*p == '/') {
  312.             makestr(&url->pth,p);  /* Path */
  313.             *p = NUL;
  314.                 }
  315.             }
  316.         }
  317.     /* Copy non-NULL result strings */
  318.     if (url->svc) if (*url->svc) {
  319.             p = url->svc;
  320.             url->svc = NULL;
  321.             makestr(&url->svc,p);
  322.         }
  323.     if (url->hos) if (*url->hos) {
  324.             p = url->hos;
  325.             url->hos = NULL;
  326.             makestr(&url->hos,p);
  327.         }
  328.     if (url->por) if (*url->por) {
  329.             p = url->por;
  330.             url->por = NULL;
  331.             makestr(&url->por,p);
  332.         }
  333.     if (url->usr) if (*url->usr) {
  334.             p = url->usr;
  335.             url->usr = NULL;
  336.             makestr(&url->usr,p);
  337.         }
  338.     if (url->psw) if (*url->psw) {
  339.             p = url->psw;
  340.             url->psw = NULL;
  341.             makestr(&url->psw,p);
  342.         }
  343.  
  344.         /* Save a copy of the full url if one was found. */
  345.     if (url->svc) 
  346.       makestr(&url->sav,s);
  347.         free(urlbuf);
  348.     return(url->svc ? 1 : 0);
  349.     }
  350.     return(0);
  351. }
  352. #endif /* CK_URL */
  353.  
  354. #ifndef NOCMDL
  355.  
  356. char *hlp1[] = {
  357. #ifndef NOICP
  358. " [filename] [-x arg [-x arg]...[-yyy]..] [ = text ] ]\n",
  359. #else
  360. "[-x arg [-x arg]...[-yyy]..]\n",
  361. #endif /* NOICP */
  362. "\n",
  363. "  -x is an option requiring an argument, -y an option with no argument.\n",
  364. "  If the first command-line argument is the name of a file, interactive-\n",
  365. "  mode commands are executed from the file.  The '=' argument tells Kermit\n",
  366. "  not to parse the remainder of the command line, but to make the words\n",
  367. "  following '=' available as \\%1, \\%2, ... \\%9.  The command file \
  368. (if any)\n",
  369. "  is executed before the command-line options.\n",
  370. "\n",
  371. #ifndef NOICP
  372. "If no action command is included, or -S is, then after the command line is\n",
  373. "executed, Kermit issues its prompt and waits for you to type commands.\n",
  374. #else
  375. "Operation by command-line options only.\n",
  376. #endif /* NOICP */
  377. ""
  378. };
  379.  
  380. static
  381. char *hlp2[] = {
  382. "  [option-list] host[:port] [port]\n",
  383. "  The option-list consists of zero, one, or more of:\n",
  384. "  -8                Negotiate Telnet Binary in both directions\n",
  385. "  -a                Require use of Telnet authentication\n",
  386. "  -d                Turn on debug mode\n",
  387. "  -E                No escape character\n",
  388. "  -K                Refuse use of authentication; do not send username\n",
  389. "  -l user           Set username and request Telnet authentication\n",
  390. "  -L                Negotiate Telnet Binary Output only\n",
  391. "  -x                Require Encryption\n",
  392. "  -D                Disable forward-X\n",
  393. "  -T cert=file      Use certificate in file\n",
  394. "  -T key=file       Use private key in file\n",
  395. "  -T crlfile=file   Use CRL in file\n",
  396. "  -T crldir=dir     Use CRLs in directory\n",
  397. "  -T cipher=string  Use only ciphers in string\n",
  398. "  -f                Forward credentials to host\n",
  399. "  -k realm          Set default Kerberos realm\n",
  400. ""
  401. };
  402.  
  403. /* Command-line option help lines.  Update this when adding new options! */
  404.  
  405. char * opthlp[128];                     /* Option help */
  406. char * arghlp[128];                     /* Argument for option */
  407. int optact[128];                        /* Action-option flag */
  408.  
  409. VOID
  410. fatal2(msg1,msg2) char *msg1, *msg2; {
  411.     char buf[256];
  412.     if (!msg1) msg1 = "";
  413.     if (!msg2) msg2 = "";
  414.     ckmakmsg(buf,256,"\"",msg1,"\" - ",msg2);
  415. #ifndef NOICP
  416.     if (what == W_COMMAND)
  417.       printf("%s\n",buf);
  418.     else
  419. #endif /* NOICP */
  420.       fatal((char *)buf);
  421. }
  422.  
  423. static SIGTYP
  424. #ifdef CK_ANSI
  425. cl_int(int dummy)
  426. #else /* CK_ANSI */
  427. cl_int(dummy) int dummy;
  428. #endif /* CK_ANSI */
  429. {                    /* Command-line interrupt handler */
  430.     doexit(BAD_EXIT,1);
  431.     SIGRETURN;
  432. }
  433.  
  434. #ifdef NEWFTP
  435. extern int ftp_action, ftp_cmdlin;
  436.  
  437. static int
  438. xx_ftp(host, port) char * host, * port; {
  439. #ifdef CK_URL
  440.     extern int haveurl;
  441. #endif /* CK_URL */
  442.     extern char * ftp_logname;
  443.     int use_tls = 0;
  444.     char * p;
  445.  
  446.     if (port) if (!*port) port = NULL;
  447.  
  448.     if (!host)
  449.       return(0);
  450.     if (!*host)
  451.       return(0);
  452.     debug(F111,"ftp xx_ftp host",ftp_host,haveftpuid);
  453.     debug(F111,"ftp xx_ftp uidbuf",uidbuf,haveftpuid);
  454.     ftp_cmdlin = 1;            /* 1 = FTP started from command line */
  455.     if (nfils > 0)
  456.       ftp_cmdlin++;            /* 2 = same plus file transfer */
  457.  
  458.     if (haveftpuid) {
  459.     makestr(&ftp_logname,uidbuf);
  460.     debug(F111,"ftp_logname",ftp_logname,haveftpuid);
  461.     }
  462.     if (!port) {
  463.     if ((p = ckstrchr(ftp_host,':')))
  464.       *p++ = NUL;
  465.     port = p;
  466.     }
  467.     if (!port) {
  468. #ifdef CK_URL
  469.         if (haveurl) {
  470.         if (g_url.por) 
  471.           port = g_url.por;
  472.             else if (g_url.svc)
  473.           port = g_url.svc;
  474.             else 
  475.           port = "ftp";
  476.         } else
  477. #endif /* CK_URL */
  478.       port = "ftp";
  479.     }
  480.  
  481. #ifdef CK_SSL
  482.     if (haveurl && g_url.svc)
  483.       use_tls = !ckstrcmp("ftps",g_url.svc,-1,0);
  484. #endif /* CK_SSL */
  485.  
  486.     if (ftpopen(ftp_host,port,use_tls) < 1)
  487.       return(-1);
  488.     debug(F111,"ftp xx_ftp action",ckctoa((char)ftp_action),nfils);
  489.     if (nfils > 0) {
  490.     switch (ftp_action) {
  491.       case 'g':
  492.         return(cmdlinget(stayflg));
  493.       case 'p':
  494.       case 's':
  495.         return(cmdlinput(stayflg));
  496.     }
  497.     }
  498.     return(1);
  499. }
  500. #endif /* NEWFTP */
  501.  
  502.  
  503. #ifndef NOHTTP
  504. static
  505. char * http_hlp[] = {
  506.     " -h             This message.\n",
  507.     " -d             Debug to debug.log.\n",
  508.     " -S             Stay (issue command prompt when done).\n",
  509.     " -Y             Do not execute Kermit initialization file.\n",
  510.     " -q             Quiet (suppress most messages).\n",
  511.     " -u name        Username.\n",
  512.     " -P password    Password.\n",
  513.     " -g pathname    Get remote pathname.\n",
  514.     " -p pathname    Put remote pathname.\n",
  515.     " -H pathname    Head remote pathname.\n",
  516.     " -l pathname    Local path for -g, -p, and -H.\n",
  517. #ifdef CK_SSL
  518.     " -z opt[=value] Security options...\n",
  519.     "    cert=file   Client certificate file\n",
  520.     "    certsok     Accept all certificates\n",
  521.     "    key=file    Client private key file\n",
  522.     "    secure      Use SSL\n",
  523.     "    verify=n    0 = none, 1 = peer , 2 = certificate required\n",
  524. #endif /* CK_SSL */
  525.     ""
  526. };
  527.  
  528. #define HT_CERTFI 0
  529. #define HT_OKCERT 1
  530. #define HT_KEY    2
  531. #define HT_SECURE 3
  532. #define HT_VERIFY 4
  533.  
  534. static struct keytab httpztab[] = {
  535.     { "cert",    HT_CERTFI, CM_ARG },
  536.     { "certsok", HT_OKCERT, 0 },
  537.     { "key",     HT_KEY,    CM_ARG },
  538.     { "secure",  HT_SECURE, 0 },
  539.     { "verify",  HT_VERIFY, CM_ARG },
  540.     { "", 0, 0 }
  541. };
  542. static int nhttpztab = sizeof(httpztab) / sizeof(struct keytab) - 1;
  543. #endif /* NOHTTP */
  544.  
  545. /*  U S A G E */
  546.  
  547. VOID
  548. usage() {
  549. #ifdef MINIX
  550.     conol("Usage: ");
  551.     conol(xarg0);
  552.     conol(" [-x arg [-x arg]...[-yyy]..] ]\n");
  553. #else
  554.     conol("Usage: ");
  555.     conol(xarg0);
  556.     if (howcalled == I_AM_KERMIT || howcalled == I_AM_IKSD)
  557.       conola(hlp1);
  558.     else if (howcalled == I_AM_TELNET)
  559.       conola(hlp2);
  560.     if (howcalled == I_AM_KERMIT || howcalled == I_AM_IKSD) {
  561.     int c;
  562.     conoll("");
  563.     conoll("Complete listing of command-line options:");
  564.     conoll("");
  565.     for (c = 31; c < 128; c++) {
  566.         if (!opthlp[c])
  567.           continue;
  568.         if (arghlp[c]) {
  569.         printf(" -%c <arg>%s\n",
  570.                (char)c,
  571.                (optact[c] ? " (action option)" : "")
  572.                );
  573.         printf("     %s\n",opthlp[c]);
  574.         printf("     Argument: %s\n\n",arghlp[c]);
  575.         } else {            /* Option without arg */
  576.         printf(" -%c  %s%s\n",
  577.                (char)c, opthlp[c],
  578.                (optact[c]?" (action option)":"")
  579.                );
  580.         printf("     Argument: (none)\n\n");
  581.         }
  582.     }
  583. #ifdef OS2ORUNIX
  584.     printf("To prevent this message from scrolling, use '%s -h | more'.\n",
  585.            xarg0);
  586. #endif /* OS2ORUNIX */
  587.     printf("For a list of extended options use '%s --help'.\n",
  588.            xarg0);
  589.     }
  590. #endif /* MINIX */
  591. }
  592.  
  593.  
  594. /*  C M D L I N  --  Get arguments from command line  */
  595.  
  596. int
  597. cmdlin() {
  598.     char x;                             /* Local general-purpose char */
  599.     extern int haveurl;
  600.  
  601. #ifdef NEWFTP
  602.     char * port = NULL;
  603. #endif /* NEWFTP */
  604.  
  605. #ifndef NOXFER
  606.     cmarg = "";                         /* Initialize globals */
  607.     cmarg2 = "";
  608. #endif /* NOXFER */
  609.     action = 0;
  610.     cflg = 0;
  611.  
  612.     signal(SIGINT,cl_int);
  613.  
  614. /* Here we handle different "Command Line Personalities" */
  615.  
  616. #ifdef TCPSOCKET
  617. #ifndef NOHTTP
  618.     if (howcalled == I_AM_HTTP) {       /* If I was called as HTTP... */
  619.     char rdns[128];
  620. #ifdef OS2
  621.     char * agent = "Kermit 95";
  622. #else   
  623.     char * agent = "C-Kermit";
  624. #endif /* OS2 */
  625.  
  626.         debug(F100,"http personality","",0);
  627. #ifdef CK_URL
  628.         if (haveurl) {
  629.             int type;
  630.             char * lfile;
  631.  
  632.         type = lookup(urltab,g_url.svc,nurltab,NULL);
  633.             if (!(type == URL_HTTP || type == URL_HTTPS)) {
  634.                 printf("?Internal Error: HTTP command line processing\n");
  635.                 debug(F100,"Error: HTTP command line processing","",0);
  636.                 doexit(BAD_EXIT,1);
  637.             }
  638.             rdns[0] = '\0';
  639.             lfile = "";
  640.             x = (http_open(g_url.hos,g_url.por ? g_url.por : g_url.svc, 
  641.                            type == URL_HTTPS, rdns,128) == 0);
  642.             if (x) {
  643.                 if (!quiet) {
  644.                     if (rdns[0])
  645.               printf("Connected to %s [%s]\r\n",g_url.hos,rdns);
  646.                     else
  647.               printf("Connected to %s\r\n",g_url.hos);
  648.                 }
  649.                 if (g_url.pth)
  650.                   zstrip(g_url.pth,&lfile);
  651.                 else
  652.           g_url.pth = "/";
  653.  
  654.                 if (!*lfile)
  655.                   lfile = "index.html";
  656.  
  657.                 x = http_get(agent,
  658.                  NULL,    /* hdrlist */
  659.                  g_url.usr,
  660.                  g_url.psw,
  661.                  0,
  662.                  lfile ,
  663.                  g_url.pth,
  664.                  0        /* stdio */
  665.                  );
  666.                 x = (http_close() == 0);
  667.             } else {
  668.                 if (!quiet)
  669.           printf("?HTTP Connection failed.\r\n");
  670.             }
  671.             doexit(x ? GOOD_EXIT : BAD_EXIT, -1);
  672.         } else 
  673. #endif /* CK_URL */
  674.       {
  675.           extern int debtim;
  676.           int http_action = 0;
  677.           char * host = NULL, * svc = NULL, * lpath = NULL;
  678.           char * user = NULL, * pswd = NULL, * path = NULL;
  679.           char * xp;
  680.  
  681.           while (--xargc > 0) {    /* Go through command line words */
  682.           xargv++;
  683.           debug(F111,"cmdlin http xargv",*xargv,xargc);
  684.           xp = *xargv+1;
  685.           if (**xargv == '-') { /* Got an option */
  686.               int xx;
  687.               x = *(*xargv+1);    /* Get the option letter */
  688.               switch (x) {
  689.             case 'd':    /* Debug */
  690. #ifdef DEBUG
  691.               if (deblog) {
  692.                   debtim = 1;
  693.               } else {
  694.                   deblog = debopn("debug.log",0);
  695.               }
  696. #endif /* DEBUG */
  697.               break;
  698.             case 'S':    /* Stay */
  699.             case 'Y':    /* No initialization file */
  700.               break;    /* (already done in prescan) */
  701.             case 'q':    /* Quiet */
  702.               quiet = 1;
  703.               break;
  704.             case 'u':    /* Options that require arguments */
  705.             case 'P':
  706.             case 'g':
  707.             case 'p':
  708.             case 'H':
  709.             case 'l':
  710.               if (*(xp+1)) {
  711.                   XFATAL("Invalid argument bundling");
  712.               }
  713.               xargv++, xargc--;
  714.               if ((xargc < 1) || (**xargv == '-')) {
  715.                   XFATAL("Missing argument");
  716.               }
  717.               switch (x) {
  718.                 case 'u':
  719.                   user = *xargv;
  720.                   break;
  721.                 case 'P':
  722.                   pswd = *xargv;
  723.                   break;
  724.                 case 'l':
  725.                   if (http_action != HTTP_PUT)
  726.                 lpath = *xargv;
  727.                   break;
  728.                 case 'g':
  729.                   http_action = HTTP_GET;
  730.                   path = *xargv;
  731.                   debug(F111,"cmdlin http GET",path,http_action);
  732.                   break;
  733.                 case 'p':
  734.                   http_action = HTTP_PUT;
  735.                   path = *xargv;
  736.                   break;
  737.                 case 'H':
  738.                   http_action = HTTP_HED;
  739.                   path = *xargv;
  740.               }
  741.               break;
  742.  
  743. #ifdef CK_SSL
  744.                         case 'z': {
  745.                 /* *xargv contains a value of the form tag=value */
  746.                 /* we need to lookup the tag and save the value  */
  747.                 int x,y,z;
  748.                 char * p, * q;
  749.                 makestr(&p,*xargv);
  750.                 y = ckindex("=",p,0,0,1);
  751.                 if (y > 0)
  752.                               p[y-1] = '\0';
  753.                 x = lookup(httpztab,p,nhttpztab,&z);
  754.                 if (x < 0) {
  755.                 printf("?Invalid security option: \"%s\"\n",p);
  756.                 } else {
  757.                 printf("Security option: \"%s",p);
  758.                 if (httpztab[z].flgs & CM_ARG) {
  759.                     q = &p[y];
  760.                     if (!*q)
  761.                                       fatal("?Missing required value");
  762.                 }
  763.                 /* -z options w/args */
  764.                 switch (httpztab[z].kwval) {
  765.                   case HT_CERTFI:
  766.                     makestr(&ssl_rsa_cert_file,q);
  767.                     break;
  768.                   case HT_OKCERT:
  769.                     ssl_certsok_flag = 1;
  770.                     break;
  771.                   case HT_KEY:
  772.                     makestr(&ssl_rsa_key_file,q);
  773.                     break;
  774.                   case HT_SECURE:
  775.                     svc="https";
  776.                     break;
  777.                   case HT_VERIFY:
  778.                     if (!rdigits(q))
  779.                                       printf("?Bad number: %s\n",q);
  780.                     ssl_verify_flag = atoi(q);
  781.                     break;
  782.                 }
  783.                 }
  784.                 free(p);
  785.                 break;
  786.                         }
  787. #endif /* CK_SSL */
  788.  
  789.             case 'h':    /* Help */
  790.             default:
  791.               printf("Usage: %s host [ options... ]\n",xarg0);
  792.               conola(http_hlp);
  793.               doexit(GOOD_EXIT,-1);
  794.               }
  795.           } else {        /* No dash - must be hostname */
  796.               host = *xargv;
  797.               if (xargc > 1) {
  798.               svc = *(xargv+1);
  799.               if (svc) if (*svc == '-' || !*svc)
  800.                 svc = NULL;
  801.               if (svc) {
  802.                   xargv++;
  803.                   xargc--;
  804.               }
  805.               }
  806.           }
  807.           }
  808.           if (!svc) svc = "";
  809.           if (!*svc) svc = "http";
  810.           if (!host) XFATAL("No http host given");
  811.  
  812.           /* Check action args before opening the connection */
  813.           if (http_action) {
  814.           if (http_action == HTTP_PUT) {
  815.               if (!lpath)
  816.             XFATAL("No local path for http PUT");
  817.           }
  818.           if (!path)
  819.             XFATAL("No remote path for http action");
  820.           }
  821.           /* Now it's OK to open the connection */
  822.           rdns[0] = NUL;
  823.           x = (http_open(host,
  824.                  svc,!ckstrcmp("https",svc,-1,0),rdns,128
  825.                  ) == 0);
  826.           if (!x) {
  827.           if (!quiet)
  828.             printf("?HTTP Connection failed.\r\n");
  829.           doexit(BAD_EXIT,-1);
  830.           }
  831.           if (!quiet) {
  832.           if (rdns[0])
  833.             printf("Connected to %s [%s]\r\n",host,rdns);
  834.           else
  835.             printf("Connected to %s\r\n",host);
  836.           }
  837.           if (http_action) {
  838.                   int pcpy = 0;
  839.           if (http_action != HTTP_PUT) { /* Supply default */
  840.               if (!lpath) {         /* local path... */
  841.               zstrip(path,&lpath);
  842.               if (!lpath)
  843.                 lpath = "";
  844.               if (!*lpath)
  845.                 lpath = "index.html";
  846.               }
  847.           }
  848.                   if (*path != '/') {
  849.                       char * p = (char *) malloc(strlen(path)+2);
  850.                       if (!p) fatal("?Memory allocation error\n");
  851.                       *p = '/';
  852.                       strcpy(&p[1],path);      /* safe */
  853.                       path = p;
  854.                       pcpy = 1;
  855.                   }
  856.           switch (http_action) {
  857.             case HTTP_GET:
  858.               x = http_get(agent,NULL,user,pswd,0,lpath,path,0);
  859.               break;
  860.               
  861.             case HTTP_PUT:
  862.               x = http_put(agent,NULL,"text/HTML",
  863.                    user,pswd,0,lpath,path,NULL,0);
  864.               break;
  865.  
  866.             case HTTP_HED:
  867.               x = http_head(agent,NULL,user,pswd,0,lpath,path,0);
  868.               break;
  869.           }
  870.           debug(F101,"cmdline http result","",x);
  871.                   x = (http_close() == 0);
  872.                   if (pcpy) free(path);
  873.                   doexit(x ? GOOD_EXIT : BAD_EXIT, -1);
  874.           }
  875.           return(0);
  876.       }
  877.     } else
  878. #endif /* NOHTTP */
  879. #ifdef NEWFTP
  880.       if (howcalled == I_AM_FTP) {    /* If I was called as FTP... */
  881.       debug(F100,"ftp personality","",0);
  882. #ifdef CK_URL
  883.       if (haveurl)
  884.             doftparg('U');
  885.       else 
  886. #endif /* CK_URL */
  887.         {
  888.         while (--xargc > 0) {    /* Go through command line words */
  889.             xargv++;
  890.             debug(F111,"cmdlin ftp xargv",*xargv,xargc);
  891.             if (**xargv == '-') { /* Got an option */
  892.             int xx;
  893.             x = *(*xargv+1); /* Get the option letter */
  894.             xx = doftparg(x);
  895.             if (xx < 0) {
  896.                 if (what == W_COMMAND)
  897.                   return(0);
  898.                 else
  899.                   doexit(BAD_EXIT,1);
  900.             }
  901.             } else {        /* No dash - must be hostname */
  902.             makestr(&ftp_host,*xargv);
  903.             if (xargc > 1) {
  904.                 port = *(xargv+1);
  905.                 if (port) if (*port == '-' || !*port)
  906.                   port = NULL;
  907.                 if (port) {
  908.                 xargv++;
  909.                 xargc--;
  910.                 }
  911.             }
  912.             debug(F110,"cmdlin ftp host",ftp_host,0);
  913.             debug(F110,"cmdlin ftp port",port,0);
  914.             }
  915.         } /* while */
  916.         } /* if (haveurl) */
  917.  
  918.       if (ftp_host) {
  919.           int xx;
  920. #ifdef NODIAL
  921.           xx = xx_ftp(ftp_host,port);
  922.           if (xx < 0 && (haveurl || ftp_cmdlin > 1)) doexit(BAD_EXIT,-1);
  923. #else
  924. #ifdef NOICP
  925.           xx = xx_ftp(ftp_host,port);
  926.           if (xx < 0 && (haveurl || ftp_cmdlin > 1)) doexit(BAD_EXIT,-1);
  927. #else
  928.           if (*ftp_host == '=') {    /* Skip directory lookup */
  929.           xx = xx_ftp(&ftp_host[1],port);
  930.           if (xx < 0 && (haveurl || ftp_cmdlin > 1))
  931.             doexit(BAD_EXIT,-1);
  932.           } else {            /* Want lookup */
  933.           int i;
  934.           nhcount = 0;        /* Check network directory */
  935.           debug(F101,"cmdlin nnetdir","",nnetdir);
  936.           if (nnetdir > 0)    /* If there is a directory... */
  937.             lunet(ftp_host);    /* Look up the name */
  938.           else            /* If no directory */
  939.             nhcount = 0;    /* we didn't find anything there */
  940. #ifdef DEBUG
  941.           if (deblog) {
  942.               debug(F101,"cmdlin lunet nhcount","",nhcount);
  943.               if (nhcount > 0) {
  944.               debug(F110,"cmdlin lunet nh_p[0]",nh_p[0],0);
  945.               debug(F110,"cmdlin lunet nh_p2[0]",nh_p2[0],0);
  946.               debug(F110,"cmdlin lunet nh_px[0][0]",
  947.                 nh_px[0][0],0);
  948.               }
  949.           }
  950. #endif /* DEBUG */
  951.           if (nhcount == 0) {
  952.               xx = xx_ftp(ftp_host,port);
  953.               if (xx < 0 && (haveurl || ftp_cmdlin > 1))
  954.             doexit(BAD_EXIT,-1);
  955.           } else {
  956.               for (i = 0; i < nhcount; i++) {
  957.               if (ckstrcmp(nh_p2[i],"tcp/ip",6,0))
  958.                 continue;
  959.               makestr(&ftp_host,nh_p[i]);
  960.               debug(F110,"cmdlin calling xx_ftp",ftp_host,0);
  961.               if (!quiet)
  962.                 printf("Trying %s...\n",ftp_host);
  963.               if (xx_ftp(ftp_host,port) > -1)
  964.                 break;
  965.               }
  966.           }
  967.           }
  968. #endif /* NODIAL */
  969. #endif /* NOICP */
  970.           if (!ftpisconnected())
  971.         doexit(BAD_EXIT,-1);
  972.       }
  973.       return(0);
  974.       }
  975. #endif /* NEWFTP */
  976.  
  977. #ifdef TNCODE
  978.     if (howcalled == I_AM_TELNET) {     /* If I was called as Telnet... */
  979.  
  980.         while (--xargc > 0) {        /* Go through command line words */
  981.             xargv++;
  982.             debug(F111,"cmdlin xargv",*xargv,xargc);
  983.             if (**xargv == '=')
  984.           return(0);
  985.             if (!strcmp(*xargv,"--"))    /* getopt() conformance */
  986.           return(0);
  987. #ifdef VMS
  988.             else if (**xargv == '/')
  989.           continue;
  990. #endif /* VMS */
  991.             else if (**xargv == '-') {    /* Got an option (begins with dash) */
  992.                 int xx;
  993.                 x = *(*xargv+1);    /* Get the option letter */
  994.                 debug(F111,"cmdlin args 1",*xargv,xargc);
  995.                 xx = dotnarg(x);
  996.                 debug(F101,"cmdlin doarg","",xx);
  997.                 debug(F111,"cmdlin args 2",*xargv,xargc);
  998.                 if (xx < 0) {
  999. #ifndef NOICP
  1000.                     if (what == W_COMMAND)
  1001.               return(0);
  1002.                     else
  1003. #endif /* NOICP */
  1004.               {
  1005. #ifdef OS2
  1006.               sleep(1);    /* Give it a chance... */
  1007. #endif /* OS2 */
  1008.               doexit(BAD_EXIT,1); /* Go handle option */
  1009.               }
  1010.                 }
  1011.             } else {            /* No dash must be hostname */
  1012.                 ckstrncpy(ttname,*xargv,TTNAMLEN+1);
  1013.                 debug(F110,"cmdlin telnet host",ttname,0);
  1014.  
  1015. #ifndef NOICP
  1016. #ifndef NODIAL
  1017.                 nhcount = 0;        /* Check network directory */
  1018.                 debug(F101,"cmdlin nnetdir","",nnetdir);
  1019.                 if (nnetdir > 0)    /* If there is a directory... */
  1020.           lunet(*xargv);    /* Look up the name */
  1021.                 else            /* If no directory */
  1022.           nhcount = 0;        /* we didn't find anything there */
  1023. #ifdef DEBUG
  1024.                 if (deblog) {
  1025.                     debug(F101,"cmdlin lunet nhcount","",nhcount);
  1026.                     if (nhcount > 0) {
  1027.                         debug(F110,"cmdlin lunet nh_p[0]",nh_p[0],0);
  1028.                         debug(F110,"cmdlin lunet nh_p2[0]",nh_p2[0],0);
  1029.                         debug(F110,"cmdlin lunet nh_px[0][0]",nh_px[0][0],0);
  1030.                     }
  1031.                 }
  1032. #endif /* DEBUG */
  1033.                 if (nhcount > 0 && nh_p2[0]) /* If network type specified */
  1034.           if (ckstrcmp(nh_p2[0],"tcp/ip",6,0)) /* it must be TCP/IP */
  1035.             nhcount = 0;
  1036.                 if (nhcount == 1) {    /* Still OK, so make substitution */
  1037.                     ckstrncpy(ttname,nh_p[0],TTNAMLEN+1);
  1038.                     debug(F110,"cmdlin lunet substitution",ttname,0);
  1039.                 }
  1040. #endif /* NODIAL */
  1041. #endif /* NOICP */
  1042.  
  1043.                 if (--xargc > 0 && !haveurl) { /* Service from command line? */
  1044.                     xargv++;
  1045.                     ckstrncat(ttname,":",TTNAMLEN+1);
  1046.                     ckstrncat(ttname,*xargv,TTNAMLEN+1);
  1047.                     debug(F110,"cmdlin telnet host2",ttname,0);
  1048.                 }
  1049. #ifndef NOICP
  1050. #ifndef NODIAL
  1051.                 else if (nhcount) {    /* No - how about in net directory? */
  1052.                     if (nh_px[0][0]) {
  1053.                         ckstrncat(ttname,":",TTNAMLEN+1);
  1054.                         ckstrncat(ttname,nh_px[0][0],TTNAMLEN+1);
  1055.                     }
  1056.                 }
  1057. #endif /* NODIAL */
  1058. #endif /* NOICP */
  1059.                 local = 1;        /* Try to open the connection */
  1060.                 nettype = NET_TCPB;
  1061.                 mdmtyp = -nettype;
  1062.                 if (ttopen(ttname,&local,mdmtyp,0) < 0) {
  1063.                     XFATAL("can't open host connection");
  1064.                 }
  1065.                 network = 1;        /* It's open */
  1066. #ifdef CKLOGDIAL
  1067.                 dolognet();
  1068. #endif /* CKLOGDIAL */
  1069. #ifndef NOXFER
  1070.                 reliable = 1;        /* It's reliable */
  1071.                 xreliable = 1;        /* ... */
  1072.                 setreliable = 1;
  1073. #endif /* NOXFER */
  1074.                 cflg = 1;        /* Connect */
  1075.                 stayflg = 1;        /* Stay */
  1076.                 tn_exit = 1;        /* Telnet-like exit condition */
  1077.                 quiet = 1;
  1078.                 exitonclose = 1;    /* Exit when connection closes */
  1079. #ifndef NOSPL
  1080.                 if (local) {
  1081.                     if (nmac) {        /* Any macros defined? */
  1082.                         int k;        /* Yes */
  1083.                         k = mlook(mactab,"on_open",nmac); /* Look this up */
  1084.                         if (k >= 0) {                     /* If found, */
  1085.                             if (dodo(k,ttname,0) > -1)    /* set it up, */
  1086.                                 parser(1);                /* and execute it */
  1087.                         }
  1088.                     }
  1089.                 }
  1090. #endif /* NOSPL */
  1091.                 break;
  1092.             }
  1093.         }
  1094.         return(0);
  1095.     }
  1096. #endif /* TNCODE */
  1097. #ifdef COMMENT
  1098. #ifdef RLOGCODE
  1099.     else if (howcalled == I_AM_RLOGIN) { /* If I was called as Rlogin... */
  1100.         /* Add rlogin command-line parsing here... */
  1101.         return(0);
  1102.     }
  1103. #endif /* RLOGCODE */
  1104. #endif /* COMMENT */
  1105. #endif /* TCPSOCKET */
  1106.  
  1107. /*
  1108.   From here down: We were called as "kermit" or "iksd".
  1109.  
  1110.   If we were started directly from a Kermit application file, its name is
  1111.   in argv[1], so skip past it.
  1112. */
  1113.     if (xargc > 1) {
  1114.         int n = 1;
  1115.         if (*xargv[1] != '-') {
  1116.  
  1117. #ifdef KERBANG
  1118.             /* If we were started with a Kerbang script, the script */
  1119.             /* arguments were already picked up in prescan / cmdini() */
  1120.             /* and there is nothing here for us anyway. */
  1121.             if (!strcmp(xargv[1],"+"))
  1122.               return(0);
  1123. #endif /* KERBANG */
  1124.  
  1125.             if (cfilef) {               /* Command file found in prescan() */
  1126.                 xargc -= n;             /* Skip past it */
  1127.                 xargv += n;
  1128.                 cfilef = 0;
  1129.                 debug(F101,"cmdlin cfilef set to 0","",cfilef);
  1130.             }
  1131.         }
  1132.     }
  1133. /*
  1134.   Regular Unix-style command line parser, mostly conforming with 'A Proposed
  1135.   Command Syntax Standard for Unix Systems', Hemenway & Armitage, Unix/World,
  1136.   Vol.1, No.3, 1984.
  1137. */
  1138.     while (--xargc > 0) {               /* Go through command line words */
  1139.         xargv++;
  1140.         debug(F111,"cmdlin xargv",*xargv,xargc);
  1141.         if (**xargv == '=')
  1142.           return(0);
  1143.         if (!strcmp(*xargv,"--"))       /* getopt() conformance */
  1144.           return(0);
  1145. #ifdef VMS
  1146.         else if (**xargv == '/')
  1147.           continue;
  1148. #endif /* VMS */
  1149.         else if (**xargv == '-') {      /* Got an option (begins with dash) */
  1150.             int xx;
  1151.             x = *(*xargv+1);            /* Get the option letter */
  1152.             debug(F111,"cmdlin args 1",*xargv,xargc);
  1153.             xx = doarg(x);
  1154.             debug(F101,"cmdlin doarg","",xx);
  1155.             debug(F111,"cmdlin args 2",*xargv,xargc);
  1156.             if (xx < 0) {
  1157. #ifndef NOICP
  1158.                 if (what == W_COMMAND)
  1159.                   return(0);
  1160.                 else
  1161. #endif /* NOICP */
  1162.                   {
  1163. #ifdef OS2
  1164.                       sleep(1);         /* Give it a chance... */
  1165. #endif /* OS2 */
  1166.                       doexit(BAD_EXIT,1); /* Go handle option */
  1167.                   }
  1168.             }
  1169.         } else if (!haveurl) {        /* No dash where expected */
  1170.         char xbuf[32];
  1171.             char buf[128];
  1172.         int k;
  1173.         k = ckstrncpy(xbuf,*xargv,40);
  1174.         if (k > 30) {
  1175.         xbuf[30] = '.';
  1176.         xbuf[29] = '.';
  1177.         xbuf[28] = '.';
  1178.         }
  1179.         xbuf[31] = NUL;
  1180.             ckmakmsg(buf,
  1181.              128,
  1182.              "invalid command-line option, type \"",
  1183.              myname,
  1184.              " -h\" for help",
  1185.              NULL
  1186.              );
  1187.         fatal2(xbuf,buf);
  1188.         }
  1189.     }
  1190. #ifdef DEBUG
  1191.     if (deblog) {
  1192. #ifndef NOICP
  1193.         debug(F101,"cmdlin what","",what);
  1194. #endif /* NOICP */
  1195.         debug(F101,"cmdlin action","",action);
  1196. #ifndef NOXFER
  1197.         debug(F101,"cmdlin stdouf","",stdouf);
  1198. #endif /* NOXFER */
  1199.     }
  1200. #endif /* DEBUG */
  1201.  
  1202. #ifdef NOICP
  1203.     if (!action && !cflg && !cnflg) {
  1204.         debug(F100,"cmdlin NOICP fatal no action","",0);
  1205.         XFATAL("?No actions specified on command line");
  1206.     }
  1207. #else
  1208.     if (inserver && what == 0) {        /* Internet Kermit server checks */
  1209.         if (local || (action != 0 && action != 'x')) {
  1210.             if (local)
  1211.               printf("local\r\n");
  1212.             if (action)
  1213.               printf("action=%c\r\n",action);
  1214.             debug(F100,"cmdlin fatal 1","",0);
  1215.             XFATAL("No actions or connections allowed with -A");
  1216.         }
  1217.     }
  1218. #endif /* NOICP */
  1219.  
  1220. #ifndef NOLOCAL
  1221.     if (!local) {
  1222.         if ((action == 'c') || (cflg != 0)) {
  1223.             debug(F100,"cmdlin fatal 2","",0);
  1224.             XFATAL("-l or -j or -X required");
  1225.         }
  1226.     }
  1227. #endif /* NOLOCAL */
  1228. #ifndef NOXFER
  1229.     if (*cmarg2 != 0) {
  1230.         if ((action != 's') && (action != 'r') && (action != 'v')) {
  1231.             debug(F100,"cmdlin fatal 3","",0);
  1232.             XFATAL("-a without -s, -r, or -g");
  1233.         }
  1234.         if (action == 'r' || action == 'v') {
  1235. #ifdef CK_TMPDIR
  1236.             if (isdir(cmarg2)) {        /* -a is a directory */
  1237.                 if (!zchdir(cmarg2)) {  /* try to change to it */
  1238.                     debug(F100,"cmdlin fatal 4","",0);
  1239.                     XFATAL("can't change to '-a' directory");
  1240.                 } else cmarg2 = "";
  1241.             } else
  1242. #endif /* CK_TMPDIR */
  1243.               if (zchko(cmarg2) < 0) {
  1244.                   debug(F100,"cmdlin fatal 5","",0);
  1245.                   XFATAL("write access to -a file denied");
  1246.               }
  1247.         }
  1248.     }
  1249.     if ((action == 'v') && (stdouf) && (!local)) {
  1250.         if (is_a_tty(1)) {
  1251.             debug(F100,"cmdlin fatal 6","",0);
  1252.             XFATAL("unredirected -k can only be used in local mode");
  1253.         }
  1254.     }
  1255.     if ((action == 's') || (action == 'v') ||
  1256.         (action == 'r') || (action == 'x')) {
  1257.         if (local)
  1258.           displa = 1;
  1259.         if (stdouf) {
  1260.             displa = 0;
  1261.             quiet = 1;
  1262.         }
  1263.     }
  1264.     if (quiet) displa = 0;              /* No display if quiet requested */
  1265. #endif /* NOXFER */
  1266. #ifdef DEBUG
  1267.     if (action)
  1268.       debug(F000,"cmdlin returns action","",action);
  1269.     else
  1270.       debug(F101,"cmdlin returns action","",action);
  1271. #endif /* DEBUG */
  1272.  
  1273.     return(action);                     /* Then do any requested protocol */
  1274. }
  1275.  
  1276. /* Extended argument parsing: --keyword[:value] (or =value) */
  1277.  
  1278. /*
  1279.   XA_xxxx symbols are defined in ckuusr.h.
  1280.   If you add a new one, also remember to update doshow(),
  1281.   SHXOPT section, in ckuus5.c.
  1282. */
  1283. struct keytab xargtab[] = {
  1284. #ifdef CK_LOGIN
  1285.     { "anonymous",   XA_ANON, CM_ARG|CM_PRE },
  1286. #endif /* CK_LOGIN */
  1287.     { "bannerfile",  XA_BAFI, CM_ARG },
  1288.     { "cdfile",      XA_CDFI, CM_ARG },
  1289.     { "cdmessage",   XA_CDMS, CM_ARG },
  1290.     { "cdmsg",       XA_CDMS, CM_ARG|CM_INV },
  1291. #ifdef IKSDB
  1292.     { "database",    XA_DBAS, CM_ARG|CM_PRE },
  1293.     { "dbfile",      XA_DBFI, CM_ARG|CM_PRE },
  1294. #endif /* IKSDB */
  1295.     { "help",        XA_HELP, 0 },
  1296. #ifndef NOHELP
  1297.     { "helpfile",    XA_HEFI, CM_ARG },
  1298. #endif /* NOHELP */
  1299. #ifdef CK_LOGIN
  1300.     { "initfile",    XA_ANFI, CM_ARG|CM_PRE },
  1301. #endif /* CK_LOGIN */
  1302.     { "nointerrupts",XA_NOIN, CM_PRE },
  1303.     { "noperms",     XA_NPRM, 0 },
  1304. #ifdef CK_LOGIN
  1305. #ifndef NOXFER
  1306. #ifdef CK_PERM
  1307.     { "permissions", XA_PERM, CM_ARG|CM_PRE },
  1308.     { "perms",       XA_PERM, CM_ARG|CM_PRE|CM_INV },
  1309. #endif /* CK_PERM */
  1310. #endif /* NOXFER */
  1311. #ifdef UNIX
  1312.     { "privid",      XA_PRIV, CM_ARG|CM_PRE },
  1313.     { "root",        XA_ROOT, CM_ARG|CM_PRE },
  1314. #else /* UNIX */
  1315. #ifdef CKROOT
  1316.     { "root",        XA_ROOT, CM_ARG|CM_PRE },
  1317. #endif /* CKROOT */
  1318. #endif /* UNIX */
  1319. #ifdef CKSYSLOG
  1320.     { "syslog",      XA_SYSL, CM_ARG|CM_PRE },
  1321. #endif /* CKSYSLOG */
  1322.     { "timeout",     XA_TIMO, CM_ARG|CM_PRE },
  1323.     { "userfile",    XA_USFI, CM_ARG|CM_PRE },
  1324.     { "version",     XA_VERS, 0 },
  1325. #ifdef CKWTMP
  1326.     { "wtmpfile",    XA_WTFI, CM_ARG|CM_PRE },
  1327.     { "wtmplog",     XA_WTMP, CM_ARG|CM_PRE },
  1328. #endif /* CKWTMP */
  1329. #endif /* CK_LOGIN */
  1330.     { "xferfile",    XA_IKFI, CM_ARG|CM_PRE },
  1331.     { "xferlog",     XA_IKLG, CM_ARG|CM_PRE },
  1332.     {"", 0, 0 }
  1333. };
  1334. int nxargs = sizeof(xargtab)/sizeof(struct keytab) - 1;
  1335.  
  1336. static struct keytab oktab[] = {
  1337.     { "0",     0, 0 },
  1338.     { "1",     1, 0 },
  1339.     { "2",     2, 0 },
  1340.     { "3",     3, 0 },
  1341.     { "4",     4, 0 },
  1342.     { "5",     5, 0 },
  1343.     { "6",     6, 0 },
  1344.     { "7",     7, 0 },
  1345.     { "8",     8, 0 },
  1346.     { "9",     9, 0 },
  1347.     { "false", 0, 0 },
  1348.     { "no",    0, 0 },
  1349.     { "off",   0, 0 },
  1350.     { "ok",    1, 0 },
  1351.     { "on",    1, 0 },
  1352.     { "true",  1, 0 },
  1353.     { "yes",   1, 0 }
  1354. };
  1355. static int noktab = sizeof(oktab)/sizeof(struct keytab);
  1356.  
  1357. #define XARGBUFL 32
  1358.  
  1359. char * xopthlp[XA_MAX+1];               /* Extended option help */
  1360. char * xarghlp[XA_MAX+1];               /* Extended argument for option */
  1361.  
  1362. static VOID
  1363. inixopthlp() {
  1364.     int i, j;
  1365.     for (i = 0; i <= XA_MAX; i++) {     /* Initialize all to null */
  1366.         xopthlp[i] = NULL;
  1367.         xarghlp[i] = NULL;
  1368.     }
  1369.     for (i = 0; i < nxargs; i++) {      /* Then for each defined keyword */
  1370.         j = xargtab[i].kwval;           /* index by associated value */
  1371.         if (j < 0 || j > XA_MAX)
  1372.           continue;
  1373.         switch (j) {
  1374. #ifdef CK_LOGIN
  1375.           case XA_ANON:                 /* "--anonymous" */
  1376.             xopthlp[j] = "--anonymous:{on,off} [IKSD only]";
  1377.             xarghlp[j] = "Whether to allow anonymous IKSD logins";
  1378.             break;
  1379. #ifdef UNIX
  1380.       case XA_PRIV:
  1381.             xopthlp[j] = "--privid:{on,off} [IKSD only]";
  1382.             xarghlp[j] = "Whether to allow privileged IDs to login to IKSD";
  1383.             break;
  1384. #endif /* UNIX */
  1385. #endif /* CK_LOGIN */
  1386.           case XA_BAFI:                 /* "--bannerfile" */
  1387.             xopthlp[j] = "--bannerfile:<filename>";
  1388.             xarghlp[j] = "File to display upon startup or IKSD login";
  1389.             break;
  1390.           case XA_CDFI:                 /* "--cdfile" */
  1391.             xopthlp[j] = "--cdfile:<filename>";
  1392.             xarghlp[j] = "File to display when server changes directory";
  1393.             break;
  1394.           case XA_CDMS:                 /* "--cdmessage" */
  1395.             xopthlp[j] = "--cdmessage:{on,off}";
  1396.             xarghlp[j] = "Whether to display CD message file";
  1397.             break;
  1398.           case XA_HELP:                 /* "--help" */
  1399.             xopthlp[j] = "--help";
  1400.             xarghlp[j] = "Print this help text about extended options";
  1401.             break;
  1402.           case XA_HEFI:                 /* "--help" */
  1403.             xopthlp[j] = "--helpfile:<filename>";
  1404.             xarghlp[j] = "File containing custom info for HELP command";
  1405.             break;
  1406.           case XA_IKFI:                 /* "--xferfile" */
  1407.             xopthlp[j] = "--xferfile:<filename> [IKSD only]";
  1408.             xarghlp[j] = "Name of ftpd-like logfile.";
  1409.             break;
  1410.           case XA_IKLG:                 /* "--xferlog" */
  1411.             xopthlp[j] = "--xferlog:{on,off} [IKSD only]";
  1412.             xarghlp[j] = "Whether to keep an ftpd-like logfile.";
  1413.             break;
  1414. #ifdef CK_LOGIN
  1415.           case XA_ANFI:                 /* "--initfile" */
  1416.             xopthlp[j] = "--initfile:<filename> [IKSD only]";
  1417.             xarghlp[j] = "Initialization file for anonymous users.";
  1418.             break;
  1419. #ifdef CK_PERM
  1420.           case XA_PERM:                 /* "--permissions" */
  1421.             xopthlp[j] = "--permissions:<octalnum> [IKSD only]";
  1422.             xarghlp[j] = "Permissions for files uploaded by anonymous users.";
  1423.             break;
  1424. #endif /* CK_PERM */
  1425. #ifdef UNIX
  1426.           case XA_ROOT:                 /* "--root" */
  1427.             xopthlp[j] = "--root:<directory> [IKSD only]";
  1428.             xarghlp[j] = "File-system root for anonymous users.";
  1429.             break;
  1430. #else /* UNIX */
  1431. #ifdef CKROOT
  1432.           case XA_ROOT:                 /* "--root" */
  1433.             xopthlp[j] = "--root:<directory> [IKSD only]";
  1434.             xarghlp[j] = "File-system root for anonymous users.";
  1435.             break;
  1436. #endif /* CKROOT */
  1437. #endif /* UNIX */
  1438. #endif /* CK_LOGIN */
  1439. #ifdef CKSYSLOG
  1440.           case XA_SYSL:                 /* "--syslog" */
  1441.             xopthlp[j] = "--syslog:<digit> [IKSD only]";
  1442.             xarghlp[j] = "Syslog recording level, 0-6.";
  1443.             break;
  1444. #endif /* CKSYSLOG */
  1445.           case XA_USFI:                 /* "--userfile" */
  1446.             xopthlp[j] = "--userfile:<filename> [IKSD only]";
  1447.             xarghlp[j] = "Forbidden user file.";
  1448.             break;
  1449. #ifdef CKWTMP
  1450.           case XA_WTFI:                 /* "--wtmpfile" */
  1451.             xopthlp[j] = "--wtmpfile:<filename> [IKSD only]";
  1452.             xarghlp[j] = "Name of wtmp logfile.";
  1453.             break;
  1454.           case XA_WTMP:                 /* "--wtmplog" */
  1455.             xopthlp[j] = "--wtmplog:{on,off} [IKSD only]";
  1456.             xarghlp[j] = "Whether to keep a wtmp logfile.";
  1457.             break;
  1458. #endif /* CKWTMP */
  1459. #ifdef CK_LOGIN
  1460.           case XA_TIMO:                 /* "--timeout" */
  1461.             xopthlp[j] = "--timeout:<seconds> [IKSD only]";
  1462.             xarghlp[j] =
  1463.  "How long to wait for login before closing the connection.";
  1464.             break;
  1465. #endif /* CK_LOGIN */
  1466.           case XA_NOIN:
  1467.             xopthlp[j] = "--nointerrupts";
  1468.             xarghlp[j] = "Disable keyboard interrupts.";
  1469.             break;
  1470. #ifdef IKSDB
  1471.           case XA_DBAS:
  1472.             xopthlp[j] = "--database:{on,off}";
  1473.             xarghlp[j] = "Enable/Disable IKSD database (IKSD only)";
  1474.             break;
  1475.           case XA_DBFI:
  1476.             xopthlp[j] = "--dbfile:<filename>";
  1477.             xarghlp[j] = "Specify IKSD database file (IKSD only)";
  1478.             break;
  1479. #endif /* IKSDB */
  1480. #ifdef CK_PERMS
  1481.       case XA_NPRM:
  1482.             xopthlp[j] = "--noperms";
  1483.             xarghlp[j] = "Disable file-transfer Permissions attribute.";
  1484.             break;
  1485. #endif /* CK_PERMS */
  1486.         }
  1487.     }
  1488. }
  1489.  
  1490. VOID
  1491. iniopthlp() {
  1492.     int i;
  1493.     for (i = 0; i < 128; i++) {
  1494.         optact[i] = 0;
  1495.         switch(i) {
  1496. #ifdef OS2
  1497.           case '#':                     /* K95 Startup Flags */
  1498.             opthlp[i] = "Kermit 95 Startup Flags";
  1499.             arghlp[i] = "\n"\
  1500.               "   1 - turn off Win95 special fixes\n"\
  1501.               "   2 - do not load optional network dlls\n"\
  1502.               "   4 - do not load optional tapi dlls\n"\
  1503.               "   8 - do not load optional kerberos dlls\n"\
  1504.               "  16 - do not load optional zmodem dlls\n"\
  1505.               "  32 - use stdin for input instead of the console\n"\
  1506.               "  64 - use stdout for output instead of the console\n"\
  1507.               " 128 - do not terminate process in response to Session Logoff";
  1508.             break;
  1509. #endif /* OS2 */
  1510.           case '0':                     /* In the middle */
  1511.             opthlp[i] =
  1512.               "100% transparent CONNECT mode for \"in-the-middle\" operation";
  1513.             arghlp[i] = NULL;
  1514.             break;
  1515.  
  1516.           case '8':
  1517.             opthlp[i] = "Connection is 8-bit clean";
  1518.             arghlp[i] = NULL;
  1519.             break;
  1520.  
  1521. #ifdef NEWFTP
  1522.           case '9':
  1523.             opthlp[i] = "Make a connection to an FTP server";
  1524.             arghlp[i] = "IP-address-or-hostname[:optional-TCP-port]";
  1525.             break;
  1526. #endif /* NEWFTP */
  1527.  
  1528. #ifdef IKSD
  1529.           case 'A':
  1530.             opthlp[i] = "Kermit is to be started as an Internet service";
  1531. #ifdef NT
  1532.             arghlp[i] = "  socket handle of incoming connection";
  1533. #else /* NT */
  1534.             arghlp[i] = NULL;
  1535. #endif /* NT */
  1536.             break;
  1537. #endif /* IKSD */
  1538.           case 'B': opthlp[i] =
  1539.       "Kermit is running in Batch or Background (no controlling terminal)";
  1540.             break;
  1541. #ifndef NOSPL
  1542.           case 'C':
  1543.             opthlp[i] = "Interactive-mode Commands to be executed";
  1544.             arghlp[i] = "Commands separated by commas, list in doublequotes";
  1545.             break;
  1546. #endif /* NOSPL */
  1547.           case 'D':
  1548.             opthlp[i] = "Delay before starting to send";
  1549.             arghlp[i] = "Number of seconds";
  1550.             break;
  1551.           case 'E':
  1552.             opthlp[i] = "Exit automatically when connection closes";
  1553.             arghlp[i] = NULL;
  1554.             break;
  1555. #ifdef TCPSOCKET
  1556.           case 'F':
  1557.             opthlp[i] = "Make a TCP connection";
  1558.             arghlp[i] = "Numeric file descriptor of open TCP connection";
  1559.             break;
  1560. #endif /* TCPSOCKET */
  1561.           case 'G':
  1562.             opthlp[i] = "GET from server, send to standard output";
  1563.             arghlp[i] = "Remote file specification";
  1564.             optact[i] = 1;
  1565.             break;
  1566.           case 'H':
  1567.             opthlp[i] = "Suppress program startup Herald and greeting";
  1568.             arghlp[i] = NULL;
  1569.             break;
  1570.           case 'I':
  1571.             opthlp[i] = "Connection is reliable, streaming is allowed";
  1572.             arghlp[i] = NULL;
  1573.             break;
  1574. #ifdef TCPSOCKET
  1575.           case 'J':
  1576.             opthlp[i] = "'Be like Telnet'";
  1577.             arghlp[i] = "IP hostname/address optionally followed by service";
  1578.             break;
  1579. #endif /* TCPSOCKET */
  1580.           case 'L':
  1581.             opthlp[i] = "Recursive directory descent for files in -s option";
  1582.             arghlp[i] = NULL;
  1583.             break;
  1584.           case 'M':
  1585.             opthlp[i] = "My user name (for use with Telnet, Rlogin, etc)";
  1586.             arghlp[i] = "Username string";
  1587.             break;
  1588. #ifdef NETBIOS
  1589.           case 'N':
  1590.             opthlp[i] = "NETBIOS adapter number";
  1591.             arghlp[i] = "Number";
  1592.             break;
  1593. #endif /* NETBIOS */
  1594.           case 'O':                     /* Be a server for One command only */
  1595.             opthlp[i] = "Be a server for One command only";
  1596.             arghlp[i] = NULL;
  1597.             optact[i] = 1;
  1598.             break;
  1599.           case 'P':
  1600.             opthlp[i] = "Don't convert file (Path) names";
  1601.             arghlp[i] = NULL;
  1602.             break;
  1603.           case 'Q':
  1604.             opthlp[i] = "Quick (FAST) Kermit protocol settings";
  1605.             arghlp[i] = NULL;
  1606.             break;
  1607.           case 'R':                     /* Remote-Only */
  1608.             opthlp[i] = "Remote-only (makes IF REMOTE true)";
  1609.             arghlp[i] = NULL;
  1610.             break;
  1611.           case 'S':                     /* "Stay" - enter interactive */
  1612.             opthlp[i] = "Stay (enter command parser after action options)";
  1613.             arghlp[i] = NULL;
  1614.             break;
  1615.           case 'T':                     /* Text file transfer mode */
  1616.             opthlp[i] = "Transfer files in Text mode";
  1617.             arghlp[i] = NULL;
  1618.             break;
  1619. #ifdef ANYX25
  1620.           case 'U':                     /* X.25 call user data */
  1621.             opthlp[i] = "X.25 call User data";
  1622.             arghlp[i] = "Call-user-data string";
  1623.             break;
  1624. #endif /* ANYX25 */
  1625.           case 'V':                     /* No automatic filetype switching */
  1626.             opthlp[i] = "Disable automatic per-file text/binary switching";
  1627.             arghlp[i] = NULL;
  1628.             break;
  1629. #ifdef COMMENT
  1630. #ifdef OS2
  1631.           case 'W':                     /* Win32 Window Handle */
  1632.             opthlp[i] = "";
  1633.             arghlp[i] = NULL;
  1634.             break;
  1635. #endif /* OS2 */
  1636. #endif /* COMMENT */
  1637. #ifdef ANYX25
  1638.           case 'X':                     /* SET HOST to X.25 address */
  1639.             opthlp[i] = "Make an X.25 connection";
  1640.             arghlp[i] = "X.25 or X.121 address";
  1641.             break;
  1642. #endif /* ANYX25 */
  1643.           case 'Y':                     /* No initialization file */
  1644.             opthlp[i] = "Skip initialization file";
  1645.             arghlp[i] = NULL;
  1646.             break;
  1647. #ifdef ANYX25
  1648.           case 'Z':                     /* SET HOST to X.25 file descriptor */
  1649.             opthlp[i] = "Make an X.25 connection";
  1650.             arghlp[i] = "Numeric file descriptor of open X.25 connection";
  1651.             break;
  1652. #endif /* ANYX25 */
  1653.           case 'a':                     /* as-name */
  1654.             opthlp[i] = "As-name for file(s) in -s, -r, or -g";
  1655.             arghlp[i] = "As-name string (alternative filename)";
  1656.             break;
  1657.           case 'b':                     /* Set bits-per-second for serial */
  1658.             opthlp[i] = "Speed for serial device";
  1659.             arghlp[i] = "Numeric Bits per second";
  1660.             break;
  1661.           case 'c':                     /* Connect before */
  1662.             optact[i] = 1;
  1663.             opthlp[i] = "CONNECT before transferring files";
  1664.             arghlp[i] = NULL;
  1665.             break;
  1666.           case 'd':                     /* DEBUG */
  1667.             opthlp[i] = "Create debug.log file (a second -d adds timestamps)";
  1668.             arghlp[i] = NULL;
  1669.             break;
  1670.           case 'e':                     /* Extended packet length */
  1671.             opthlp[i] = "Maximum length for incoming file-transfer packets";
  1672.             arghlp[i] = "Length in bytes";
  1673.             break;
  1674.           case 'f':                     /* finish */
  1675.             optact[i] = 1;
  1676.             opthlp[i] = "Send Finish command to a Kermit server";
  1677.             arghlp[i] = NULL;
  1678.             break;
  1679.           case 'g':                     /* get */
  1680.             optact[i] = 1;
  1681.             opthlp[i] = "GET file(s) from a Kermit server";
  1682.             arghlp[i] = "Remote file specification";
  1683.             break;
  1684.           case 'h':                     /* help */
  1685.             optact[i] = 1;
  1686. #ifdef OS2ORUNIX
  1687.             opthlp[i] =
  1688.           "Print this message (pipe thru 'more' to prevent scrolling)";
  1689. #else
  1690.           "Print this message";
  1691. #endif /* OS2ORUNIX */
  1692.             arghlp[i] = NULL;
  1693.             break;
  1694.           case 'i':                     /* Treat files as binary */
  1695.             opthlp[i] ="Transfer files in binary mode";
  1696.             arghlp[i] = NULL;
  1697.             break;
  1698. #ifdef TCPSOCKET
  1699.           case 'j':                     /* SET HOST (TCP/IP socket) */
  1700.             opthlp[i] = "Make a TCP connection";
  1701.             arghlp[i] =
  1702.           "TCP host name/address and optional service name or number";
  1703.             break;
  1704. #endif /* TCPSOCKET */
  1705.           case 'k':                     /* receive to stdout */
  1706.             optact[i] = 1;
  1707.             opthlp[i] = "RECEIVE file(s) to standard output";
  1708.             arghlp[i] = NULL;
  1709.             break;
  1710.           case 'l':                     /* SET LINE */
  1711.             opthlp[i] = "Make connection on serial communications device";
  1712.             arghlp[i] = "Serial device name";
  1713.             break;
  1714.           case 'm':                     /* Modem type */
  1715.             opthlp[i] = "Modem type for use with -l device";
  1716.             arghlp[i] = "Modem name as in SET MODEM TYPE command";
  1717.             break;
  1718.           case 'n':                     /* connect after */
  1719.             optact[i] = 1;
  1720.             opthlp[i] = "CONNECT after transferring files";
  1721.             arghlp[i] = NULL;
  1722.             break;
  1723. #ifdef ANYX25
  1724.           case 'o':                     /* X.25 closed user group */
  1725.             opthlp[i] = "X.25 closed user group";
  1726.             arghlp[i] = "User group string";
  1727.             break;
  1728. #endif /* ANYX25 */
  1729.           case 'p':                     /* SET PARITY */
  1730.             opthlp[i] = "Parity";
  1731.             arghlp[i] = "One of the following: even, odd, mark, none, space";
  1732.             break;
  1733.           case 'q':                     /* Quiet */
  1734.             opthlp[i] = "Quiet (suppress most messages)";
  1735.             arghlp[i] = NULL;
  1736.             break;
  1737.           case 'r':                     /* receive */
  1738.             optact[i] = 1;
  1739.             opthlp[i] = "RECEIVE file(s)";
  1740.             arghlp[i] = NULL;
  1741.             break;
  1742.           case 's':                     /* send */
  1743.             optact[i] = 1;
  1744.             opthlp[i] = "SEND file(s)";
  1745.             arghlp[i] = "One or more file specifications";
  1746.             break;
  1747.           case 't':                     /* Line turnaround handshake */
  1748.             opthlp[i] = "XON Turnaround character for half-duplex connections";
  1749.             arghlp[i] = NULL;
  1750.             break;
  1751. #ifdef ANYX25
  1752.           case 'u':                     /* X.25 reverse charge call */
  1753.             opthlp[i] = "X.25 reverse charge call";
  1754.             arghlp[i] = NULL;
  1755.             break;
  1756. #endif /* ANYX25 */
  1757.           case 'v':                     /* Vindow size */
  1758.             opthlp[i] = "Window size";
  1759.             arghlp[i] = "Number, 1 to 32";
  1760.             break;
  1761.           case 'w':                     /* Writeover */
  1762.             opthlp[i] = "Incoming files Write over existing files";
  1763.             arghlp[i] = NULL;
  1764.             break;
  1765.           case 'x':                     /* Server */
  1766.             optact[i] = 1;
  1767.             opthlp[i] = "Be a Kermit SERVER";
  1768.             arghlp[i] = NULL;
  1769.             break;
  1770.           case 'y':                     /* Alternate init-file name */
  1771.             opthlp[i] = "Alternative initialization file";
  1772.             arghlp[i] = "File specification";
  1773.             break;
  1774.           case 'z':                     /* Not background */
  1775.             opthlp[i] = "Force foreground behavior";
  1776.             arghlp[i] = NULL;
  1777.             break;
  1778.           default:
  1779.             opthlp[i] = NULL;
  1780.             arghlp[i] = NULL;
  1781.         }
  1782.     }
  1783.     inixopthlp();
  1784. }
  1785.  
  1786. int
  1787. doxarg(s,pre) char ** s; int pre; {
  1788. #ifdef IKSD
  1789. #ifdef CK_LOGIN
  1790.     extern int ckxsyslog, ckxwtmp, ckxanon;
  1791. #ifdef UNIX
  1792.     extern int ckxpriv;
  1793. #endif /* UNIX */
  1794. #ifdef CK_PERMS
  1795.     extern int ckxperms;
  1796. #endif /* CK_PERMS */
  1797.     extern char * anonfile, * userfile, * anonroot;
  1798. #endif /* CK_LOGIN */
  1799. #ifdef CKWTMP
  1800.     extern char * wtmpfile;
  1801. #endif /* CKWTMP */
  1802. #endif /* IKSD */
  1803.     extern int srvcdmsg;
  1804.     extern char * cdmsgfile[], * cdmsgstr;
  1805.     char tmpbuf[CKMAXPATH+1];
  1806.  
  1807.     int i, x, y, z, havearg = 0;
  1808.     char buf[XARGBUFL], c, * p;
  1809.  
  1810.     if (nxargs < 1)
  1811.       return(-1);
  1812.  
  1813.     c = *(*s + 1);                      /* Hyphen or Plus sign */
  1814.  
  1815.     p = *s + 2;
  1816.     for (i = 0; *p && i < XARGBUFL; i++) {
  1817.         buf[i] = *p++;
  1818.         if (buf[i] == '=' || buf[i] == ':') {
  1819.             havearg = 1;
  1820.             buf[i] = NUL;
  1821.             break;
  1822.         } else if (buf[i] < ' ') {
  1823.             buf[i] = NUL;
  1824.             break;
  1825.         }
  1826.     }
  1827.     if (i > XARGBUFL - 1)
  1828.       return(-1);
  1829.     buf[i] = NUL;
  1830.  
  1831.     x = lookup(xargtab,buf,nxargs,&z);  /* Lookup the option keyword */
  1832.  
  1833.     if (x < 0)                          /* On any kind of error */
  1834.       return(-1);                       /* fail. */
  1835.  
  1836.     /* Handle prescan versus post-initialization file */
  1837.  
  1838.     if (((xargtab[z].flgs & CM_PRE) || (c == '+')) && !pre)
  1839.       return(0);
  1840.     else if (pre && !(xargtab[z].flgs & CM_PRE) && (c != '+'))
  1841.       return(0);
  1842.  
  1843.     /* Ensure that argument is given if and only if required */
  1844.  
  1845.     p = havearg ? *s + i + 3 : NULL;
  1846.  
  1847.     if ((xargtab[z].flgs & CM_ARG) && !havearg)
  1848.       return(-1);
  1849.     else if ((!(xargtab[z].flgs & CM_ARG)) && havearg)
  1850.       return(-1);
  1851.  
  1852.     switch (x) {                        /* OK to process this option... */
  1853. #ifdef CKSYSLOG
  1854.       case XA_SYSL:                     /* IKS: Syslog level */
  1855.         y = 0;
  1856.         if (isdigit(*p)) {
  1857.             while (*p) {
  1858.                 if (*p < '0' || *p > '9')
  1859.                   return(-1);
  1860.                 y = y * 10 + (*p++ - '0');
  1861.             }
  1862.         } else {
  1863.             y = lookup(oktab,p,noktab,&z);
  1864.             if (y > 0) y = SYSLG_DF;    /* Yes = default logging level */
  1865.         }
  1866. #ifndef SYSLOGLEVEL
  1867.         /* If specified on cc command line, user can't change it. */
  1868.         if (!inserver)                  /* Don't allow voluminous syslogging */
  1869.           if (y > SYSLG_FA)             /* by ordinary users. */
  1870.             y = SYSLG_FA;
  1871. #endif /* SYSLOGLEVEL */
  1872.         if (y < 0) return(-1);
  1873. #ifdef DEBUG
  1874.         if (y >= SYSLG_DB)
  1875.           if (!deblog)
  1876.             deblog = debopn("debug.log",0);
  1877. #endif /* DEBUG */
  1878. #ifdef SYSLOGLEVEL
  1879.         /* If specified on cc command line, user can't change it. */
  1880.         y = SYSLOGLEVEL;
  1881. #endif /* SYSLOGLEVEL */
  1882.         ckxsyslog = y;
  1883.         /* printf("ckxsyslog=%d\n",ckxsyslog); */
  1884.         break;
  1885. #endif /* CKSYSLOG */
  1886.  
  1887. #ifdef CK_LOGIN
  1888. #ifdef CKWTMP
  1889.       case XA_WTMP:                     /* IKS: wtmp log */
  1890.         y = lookup(oktab,p,noktab,&z);
  1891.         if (y < 0) return(-1);
  1892.         ckxwtmp = y;
  1893.         /* printf("ckxwtmp=%d\n",ckxwtmp); */
  1894.         break;
  1895.  
  1896.       case XA_WTFI:                     /* IKS: wtmp logfile */
  1897.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1898.           p = tmpbuf;
  1899.         makestr(&wtmpfile,p);
  1900.         /* printf("wtmpfile=%s\n",wtmpfile); */
  1901.         break;
  1902. #endif /* CKWTMP */
  1903.  
  1904.       case XA_ANON:                     /* IKS: Anonymous login allowed */
  1905.         y = lookup(oktab,p,noktab,&z);
  1906.         if (y < 0) return(-1);
  1907.         ckxanon = y;
  1908.         /* printf("ckxanon=%d\n",ckxanon); */
  1909.         break;
  1910.  
  1911. #ifdef UNIX
  1912.       case XA_PRIV:                     /* IKS: Priv'd login allowed */
  1913.         y = lookup(oktab,p,noktab,&z);
  1914.         if (y < 0) return(-1);
  1915.         ckxpriv = y;
  1916.         /* printf("ckxpriv=%d\n",ckxpriv); */
  1917.         break;
  1918. #endif /* UNIX */
  1919.  
  1920. #ifdef CK_PERMS
  1921.       case XA_PERM:                     /* IKS: Anonymous Upload Permissions */
  1922.         y = 0;
  1923.         while (*p) {
  1924.             if (*p < '0' || *p > '7')
  1925.               return(-1);
  1926.             y = y * 8 + (*p++ - '0');
  1927.         }
  1928.         ckxperms = y;
  1929.         /* printf("ckxperms=%04o\n",ckxperms); */
  1930.         break;
  1931. #endif /* CK_PERMS */
  1932.  
  1933.       case XA_ANFI:                     /* Anonymous init file */
  1934.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1935.           p = tmpbuf;
  1936.         makestr(&anonfile,p);
  1937.         /* printf("anonfile=%s\n",anonfile); */
  1938.         break;
  1939.  
  1940.       case XA_USFI:                     /* IKS: Forbidden user file */
  1941.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1942.           p = tmpbuf;
  1943.         makestr(&userfile,p);
  1944.         /* printf("userfile=%s\n",userfile); */
  1945.         break;
  1946.  
  1947.       case XA_ROOT:                     /* IKS: Anonymous root */
  1948.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1949.           p = tmpbuf;
  1950.         makestr(&anonroot,p);
  1951.         /* printf("anonroot=%s\n",anonroot); */
  1952.         break;
  1953. #endif /* CK_LOGIN */
  1954.  
  1955.       case XA_CDFI:                     /* CD filename */
  1956. #ifdef COMMENT
  1957.         /* Do NOT expand this one! */
  1958.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1959.           p = tmpbuf;
  1960. #endif /* COMMENT */
  1961.         makelist(p,cdmsgfile,16);
  1962.         makestr(&cdmsgstr,p);
  1963.         /* printf("cdmsgstr=%s\n",cdmsgstr); */
  1964.         break;
  1965.  
  1966.       case XA_CDMS:                     /* CD messages */
  1967.         y = lookup(oktab,p,noktab,&z);
  1968.         if (y < 0) return(-1);
  1969.         srvcdmsg = y;
  1970.         /* printf("srvcdmsg=%d\n",srvcdmsg); */
  1971.         break;
  1972.  
  1973. #ifndef NOXFER
  1974.       case XA_IKLG:                     /* Transfer log on/off */
  1975.         y = lookup(oktab,p,noktab,&z);
  1976.         if (y < 0) return(-1);
  1977.         xferlog = y;
  1978.         /* printf("xferlog=%d\n",xferlog); */
  1979.         break;
  1980.  
  1981.       case XA_IKFI:                     /* Transfer log file */
  1982.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1983.           p = tmpbuf;
  1984.         makestr(&xferfile,p);
  1985.         xferlog = 1;
  1986.         /* printf("xferfile=%s\n",xferfile); */
  1987.         break;
  1988.  
  1989.       case XA_BAFI:                     /* IKS: banner (greeting) file */
  1990.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  1991.           p = tmpbuf;
  1992.         makestr(&bannerfile,p);
  1993.         /* printf("bannerfile=%s\n",bannerfile); */
  1994.         break;
  1995. #endif /* NOXFER */
  1996.  
  1997. #ifndef NOHELP
  1998.       case XA_HELP:                     /* Help */
  1999.         /* printf("help\n"); */
  2000.         for (i = 0; i <= XA_MAX; i++)
  2001.           if (xopthlp[i])
  2002.             printf("%s\n   %s\n\n",xopthlp[i],xarghlp[i]);
  2003.         if (stayflg || what == W_COMMAND)
  2004.           break;
  2005.         else
  2006.           doexit(GOOD_EXIT,-1);
  2007. #endif /* NOHELP */
  2008.  
  2009. #ifndef NOHELP
  2010.       case XA_HEFI:                     /* IKS: custom help file */
  2011.         if (zfnqfp(p,CKMAXPATH,tmpbuf))
  2012.           p = tmpbuf;
  2013.         makestr(&helpfile,p);
  2014.         /* printf("helpfile=%s\n",helpfile); */
  2015.         break;
  2016. #endif /* NOHELP */
  2017.  
  2018. #ifdef CK_LOGIN
  2019.       case XA_TIMO:
  2020.         if (!rdigits(p))
  2021.           return(-1);
  2022.         logintimo = atoi(p);
  2023.         /* printf("logintimo=%d\n",p); */
  2024.         break;
  2025. #endif /* CK_LOGIN */
  2026.  
  2027.       case XA_NOIN:                     /* No interrupts */
  2028. #ifndef NOICP
  2029.         cmdint = 0;
  2030. #endif /* NOICP */
  2031.     suspend = 0;
  2032.         break;
  2033.  
  2034. #ifdef IKSDB
  2035.       case XA_DBFI: {
  2036.           extern char * dbdir, * dbfile;
  2037.           extern int dbenabled;
  2038.           struct zfnfp * zz;
  2039.           if ((zz = zfnqfp(p,CKMAXPATH,tmpbuf))) {
  2040.               makestr(&dbdir,zz->fpath);
  2041.               makestr(&dbfile,(char *)tmpbuf);
  2042.               dbenabled = 1;
  2043.           }
  2044.           break;
  2045.       }
  2046.       case XA_DBAS: {
  2047.           extern int dbenabled;
  2048.           y = lookup(oktab,p,noktab,&z);
  2049.           if (y < 0) return(-1);
  2050.           dbenabled = y;
  2051.           break;
  2052.       }
  2053. #endif /* IKSDB */
  2054.  
  2055.       case XA_VERS: {
  2056.       extern char * ck_s_ver, * ck_s_xver;
  2057.       printf("%s",ck_s_ver);
  2058.       if (*ck_s_xver)
  2059.         printf(" [%s]\n",ck_s_xver);
  2060.       printf("\n");
  2061.       if (stayflg || what == W_COMMAND)
  2062.         break;
  2063.       else
  2064.         doexit(GOOD_EXIT,-1);
  2065.       }
  2066. #ifndef NOXFER
  2067. #ifdef CK_PERMS
  2068.       case XA_NPRM: {
  2069.       extern int atlpri, atlpro, atgpri, atgpro;
  2070.       atlpri = 0;
  2071.       atlpro = 0;
  2072.       atgpri = 0;
  2073.       atgpro = 0;
  2074.       break;
  2075.       }
  2076. #endif /* CK_PERMS */
  2077. #endif /* NOXFER */
  2078.  
  2079.       default:
  2080.         return(-1);
  2081.     }
  2082.     return(0);
  2083. }
  2084.  
  2085. #ifdef IKSD
  2086. #ifdef IKSDCONF
  2087. #define IKS_ANON 0
  2088. #define IKS_BAFI 1
  2089. #define IKS_CDFI 2
  2090. #define IKS_CDMS 3
  2091. #define IKS_HEFI 4
  2092. #define IKS_ANFI 5
  2093. #define IKS_USFI 6
  2094. #define IKS_IKLG 7
  2095. #define IKS_IKFI 8
  2096. #define IKS_DBAS 9
  2097. #define IKS_DBFI 10
  2098. #define IKS_PERM 11
  2099. #define IKS_PRIV 12
  2100. #define IKS_ROOT 13
  2101. #define IKS_TIMO 14
  2102. #define IKS_WTFI 15
  2103. #define IKS_WTMP 16
  2104. #define IKS_SRVR 17
  2105. #define IKS_NOIN 18
  2106. #define IKS_INIT 19
  2107. #define IKS_ANLG 20
  2108. #define IKS_ACCT 21
  2109. #define IKS_NTDOM 22
  2110. #define IKS_SYSL 23
  2111.  
  2112. #ifdef CK_LOGIN
  2113. static struct keytab iksantab[] = {
  2114. #ifdef OS2
  2115.     { "account",     IKS_ACCT, 0 },
  2116. #endif /* OS2 */
  2117.     { "initfile",    IKS_ANFI, 0 },
  2118.     { "login",       IKS_ANLG, 0 },
  2119. #ifdef UNIX
  2120.     { "root",        IKS_ROOT, 0 },
  2121. #else
  2122. #ifdef CKROOT
  2123.     { "root",        IKS_ROOT, 0 },
  2124. #endif /* CKROOT */
  2125. #endif /* UNIX */
  2126.     { "", 0, 0 }
  2127. };
  2128. static int niksantab = sizeof(iksantab) / sizeof(struct keytab) - 1;
  2129. #endif /* CK_LOGIN */
  2130.  
  2131. static struct keytab ikstab[] = {
  2132. #ifdef CK_LOGIN
  2133.     { "anonymous",   IKS_ANON, 0 },
  2134. #endif /* CK_LOGIN */
  2135.     { "bannerfile",  IKS_BAFI, 0 },
  2136.     { "cdfile",      IKS_CDFI, 0 },
  2137.     { "cdmessage",   IKS_CDMS, 0 },
  2138.     { "cdmsg",       IKS_CDMS, CM_INV },
  2139. #ifdef IKSDB
  2140.     { "database",    IKS_DBAS, 0 },
  2141.     { "dbfile",      IKS_DBFI, 0 },
  2142. #endif /* IKSDB */
  2143. #ifdef CK_LOGIN
  2144. #ifdef NT
  2145.     { "default-domain", IKS_NTDOM, 0 },
  2146. #endif /* NT */
  2147. #endif /* CK_LOGIN */
  2148. #ifndef NOHELP
  2149.     { "helpfile",    IKS_HEFI, 0 },
  2150. #endif /* NOHELP */
  2151.     { "initfile",    IKS_INIT, 0 },
  2152.     { "no-initfile", IKS_NOIN, 0 },
  2153. #ifdef CK_LOGIN
  2154. #ifdef CK_PERM
  2155.     { "permissions", IKS_PERM, 0 },
  2156.     { "perms",       IKS_PERM, CM_INV },
  2157. #endif /* CK_PERM */
  2158. #ifdef UNIX
  2159.     { "privid",      IKS_PRIV, 0 },
  2160. #endif /* UNIX */
  2161.     { "server-only", IKS_SRVR, 0 },
  2162. #ifdef CKSYSLOG
  2163.     { "syslog",      IKS_SYSL, 0 },
  2164. #endif /* CKSYSLOG */
  2165.     { "timeout",     IKS_TIMO, 0 },
  2166.     { "userfile",    IKS_USFI, 0 },
  2167. #ifdef CKWTMP
  2168.     { "wtmpfile",    IKS_WTFI, 0 },
  2169.     { "wtmplog",     IKS_WTMP, 0 },
  2170. #endif /* CKWTMP */
  2171. #endif /* CK_LOGIN */
  2172.     { "xferfile",    IKS_IKFI, 0 },
  2173.     { "xferlog",     IKS_IKLG, 0 }
  2174. };
  2175. static int nikstab = sizeof(ikstab) / sizeof(struct keytab);
  2176. #endif /* IKSDCONF */
  2177.  
  2178. #ifndef NOICP
  2179. int
  2180. setiks() {                /* SET IKS */
  2181. #ifdef IKSDCONF
  2182. #ifdef CK_LOGIN
  2183.     extern int ckxsyslog, ckxwtmp, ckxanon;
  2184. #ifdef UNIX
  2185.     extern int ckxpriv;
  2186. #endif /* UNIX */
  2187. #ifdef CK_PERMS
  2188.     extern int ckxperms;
  2189. #endif /* CK_PERMS */
  2190.     extern char * anonfile, * userfile, * anonroot;
  2191. #ifdef OS2
  2192.     extern char * anonacct;
  2193. #endif /* OS2 */
  2194. #ifdef NT
  2195.     extern char * iks_domain;
  2196. #endif /* NT */
  2197. #endif /* CK_LOGIN */
  2198. #ifdef CKWTMP
  2199.     extern char * wtmpfile;
  2200. #endif /* CKWTMP */
  2201.     extern int srvcdmsg, success, iksdcf, rcflag, noinit, arg_x;
  2202.     extern char * cdmsgfile[], * cdmsgstr, *kermrc;
  2203.     extern xx_strp xxstring;
  2204.     int x, y, z;
  2205.     char *s;
  2206.     char tmpbuf[CKMAXPATH+1];
  2207.  
  2208.     if ((y = cmkey(ikstab,nikstab,"","",xxstring)) < 0)
  2209.       return(y);
  2210.  
  2211. #ifdef CK_LOGIN
  2212.     if (y == IKS_ANON) {
  2213.         if ((y = cmkey(iksantab,niksantab,"","",xxstring)) < 0)
  2214.       return(y);
  2215.     }
  2216. #endif /* CK_LOGIN */
  2217.  
  2218.     switch (y) {
  2219. #ifdef CKSYSLOG
  2220.       case IKS_SYSL:                     /* IKS: Syslog level */
  2221.         if ((z = cmkey(oktab,noktab,"","",xxstring)) < 0)
  2222.       return(z);
  2223.         if ((x = cmcfm()) < 0) return(x);
  2224.         if (iksdcf) return(success = 0);
  2225. #ifndef SYSLOGLEVEL
  2226.         /* If specified on cc command line, user can't change it. */
  2227.         if (!inserver)                  /* Don't allow voluminous syslogging */
  2228.           if (y > SYSLG_FA)             /* by ordinary users. */
  2229.             y = SYSLG_FA;
  2230. #endif /* SYSLOGLEVEL */
  2231.         if (y < 0) return(-1);
  2232. #ifdef DEBUG
  2233.         if (y >= SYSLG_DB)
  2234.           if (!deblog)
  2235.             deblog = debopn("debug.log",0);
  2236. #endif /* DEBUG */
  2237. #ifdef SYSLOGLEVEL
  2238.         /* If specified on cc command line, user can't change it. */
  2239.         y = SYSLOGLEVEL;
  2240. #endif /* SYSLOGLEVEL */
  2241.         ckxsyslog = y;
  2242.         /* printf("ckxsyslog=%d\n",ckxsyslog); */
  2243.         break;
  2244. #endif /* CKSYSLOG */
  2245.  
  2246. #ifdef CK_LOGIN
  2247. #ifdef NT
  2248.       case IKS_NTDOM:
  2249.         if ((z = cmtxt(
  2250.  "DOMAIN to be used for user authentication when none is specified",
  2251.                        "", &s,xxstring)) < 0)
  2252.       return(z);
  2253.         if (iksdcf) return(success = 0);
  2254.         if (!*s) s= NULL;
  2255.           makestr(&iks_domain,s);
  2256.         break;
  2257. #endif /* NT */
  2258. #ifdef OS2
  2259.       case IKS_ACCT:
  2260.         if ((z = cmtxt("Name of local account to use for anonymous logins",
  2261.             "GUEST", &s,xxstring)) < 0)
  2262.       return(z);
  2263.         if (iksdcf) return(success = 0);
  2264.         if (*s) {
  2265.             makestr(&anonacct,s);
  2266.         } else if ( anonacct ) {
  2267.         free(anonacct);
  2268.         anonacct = NULL;
  2269.     }
  2270.         break;
  2271. #endif /* OS2 */
  2272.       case IKS_ANLG:
  2273.         if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
  2274.       return(z);
  2275.         if ((x = cmcfm()) < 0) return(x);
  2276.         if (iksdcf) return(success = 0);
  2277.         ckxanon = z;
  2278. #ifdef OS2
  2279.     if (ckxanon && !anonacct)
  2280.       makestr(&anonacct,"GUEST");
  2281. #endif /* OS2 */
  2282.         break;
  2283. #endif /* CK_LOGIN */
  2284.       case IKS_BAFI:
  2285.         if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
  2286.       return(z);
  2287.         if (x) {
  2288.             printf("?Wildcards not allowed\n");
  2289.             return(-9);
  2290.         }
  2291.         debug(F110,"bannerfile before zfnqfp()",s,0);
  2292.         if (zfnqfp(s,CKMAXPATH,tmpbuf)) {
  2293.             debug(F110,"bannerfile after zfnqfp()",tmpbuf,0);
  2294.             s = tmpbuf;
  2295.         }
  2296.         if ((x = cmcfm()) < 0) return(x);
  2297.         if (iksdcf) return(success = 0);
  2298.         if (*s)
  2299.       makestr(&bannerfile,s);
  2300.         break;
  2301.       case IKS_CDFI:
  2302.         if ((z = cmtxt("list of cd message file names","READ.ME",
  2303.                &s,xxstring)) < 0)
  2304.       return(z);
  2305.         if (iksdcf) return(success = 0);
  2306.         if (*s) {
  2307.             makelist(s,cdmsgfile,16);
  2308.             makestr(&cdmsgstr,s);
  2309.         }
  2310.         break;
  2311.       case IKS_CDMS:
  2312.         if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
  2313.       return(z);
  2314.         if ((x = cmcfm()) < 0) return(x);
  2315.         if (iksdcf) return(success = 0);
  2316.         srvcdmsg = z;
  2317.         break;
  2318.       case IKS_HEFI:
  2319.         if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
  2320.       return(z);
  2321.         if (x) {
  2322.             printf("?Wildcards not allowed\n");
  2323.             return(-9);
  2324.         }
  2325.         if (zfnqfp(s,CKMAXPATH,tmpbuf))
  2326.           s = tmpbuf;
  2327.         if ((x = cmcfm()) < 0) return(x);
  2328.         if (iksdcf) return(success = 0);
  2329.         if (*s)
  2330.       makestr(&helpfile,s);
  2331.         break;
  2332.       case IKS_ANFI:
  2333.         if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
  2334.       return(z);
  2335.         if (x) {
  2336.             printf("?Wildcards not allowed\n");
  2337.             return(-9);
  2338.         }
  2339.         if (zfnqfp(s,CKMAXPATH,tmpbuf))
  2340.           s = tmpbuf;
  2341.         if ((x = cmcfm()) < 0) return(x);
  2342.         if (iksdcf) return(success = 0);
  2343.         if (*s)
  2344.       makestr(&anonfile,s);
  2345.         break;
  2346.       case IKS_USFI:
  2347.         if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
  2348.       return(z);
  2349.         if (x) {
  2350.             printf("?Wildcards not allowed\n");
  2351.             return(-9);
  2352.         }
  2353.         if (zfnqfp(s,CKMAXPATH,tmpbuf))
  2354.           s = tmpbuf;
  2355.         if ((x = cmcfm()) < 0) return(x);
  2356.         if (iksdcf) return(success = 0);
  2357.         if (*s)
  2358.       makestr(&userfile,s);
  2359.         break;
  2360.       case IKS_IKFI:
  2361.         if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
  2362.       return(z);
  2363.         if (x) {
  2364.             printf("?Wildcards not allowed\n");
  2365.             return(-9);
  2366.         }
  2367.         if (zfnqfp(s,CKMAXPATH,tmpbuf))
  2368.           s = tmpbuf;
  2369.         if ((x = cmcfm()) < 0) return(x);
  2370.         if (iksdcf) return(success = 0);
  2371.         if (*s) {
  2372.             makestr(&xferfile,s);
  2373.             xferlog = 1;
  2374.         }
  2375.         break;
  2376.       case IKS_IKLG:
  2377.         if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
  2378.       return(z);
  2379.         if ((x = cmcfm()) < 0) return(x);
  2380.         if (iksdcf) return(success = 0);
  2381.         xferlog = z;
  2382.         break;
  2383.  
  2384. #ifdef CK_LOGIN
  2385. #ifdef CK_PERM
  2386.       case IKS_PERM:
  2387.         if ((z = cmtxt("Octal file permssion code","000",
  2388.                &s,xxstring)) < 0)
  2389.       return(z);
  2390.     if (z < 0) return(z);
  2391.         if (iksdcf) return(success = 0);
  2392.         y = 0;
  2393.         while (*s) {
  2394.             if (*s < '0' || *s > '7')
  2395.               return(-9);
  2396.             y = y * 8 + (*s++ - '0');
  2397.         }
  2398.         ckxperms = y;
  2399.         break;
  2400. #endif /* CK_PERM */
  2401. #ifdef UNIX
  2402.       case IKS_PRIV:                     /* IKS: Priv'd login allowed */
  2403.         if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
  2404.       return(z);
  2405.         if ((x = cmcfm()) < 0) return(x);
  2406.         if (iksdcf) return(success = 0);
  2407.         ckxpriv = z;
  2408.         break;
  2409. #endif /* UNIX */
  2410.  
  2411.       case IKS_ROOT:                     /* IKS: Anonymous root */
  2412.     if ((z = cmdir("Name of disk and/or directory","",&s,
  2413.                xxstring)) < 0 ) {
  2414.         if (z != -3)
  2415.           return(z);
  2416.     }
  2417.         if (*s) {
  2418.         if (zfnqfp(s,CKMAXPATH,tmpbuf))
  2419.           s = tmpbuf;
  2420.         } else
  2421.       s = "";
  2422.         if ((x = cmcfm()) < 0) return(x);
  2423.         if (iksdcf) return(success = 0);
  2424.         if (*s)
  2425.       makestr(&anonroot,s);
  2426.         /* printf("anonroot=%s\n",anonroot); */
  2427.         break;
  2428.  
  2429.       case IKS_TIMO:
  2430.     z = cmnum("login timeout, seconds","0",10,&x,xxstring);
  2431.     if (z < 0) return(z);
  2432.         if (x < 0 || x > 7200) {
  2433.             printf("?Value must be between 0 and 7200\r\n");
  2434.             return(-9);
  2435.         }
  2436.         if ((z = cmcfm()) < 0) return(z);
  2437.         if (iksdcf) return(success = 0);
  2438.         logintimo = x;
  2439.         break;
  2440.  
  2441. #ifdef CKWTMP
  2442.       case IKS_WTMP:                     /* IKS: wtmp log */
  2443.         if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
  2444.       return(z);
  2445.         if ((x = cmcfm()) < 0) return(x);
  2446.         if (iksdcf) return(success = 0);
  2447.         ckxwtmp = z;
  2448.         break;
  2449.  
  2450.       case IKS_WTFI:                     /* IKS: wtmp logfile */
  2451.         if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
  2452.       return(z);
  2453.         if (x) {
  2454.             printf("?Wildcards not allowed\n");
  2455.             return(-9);
  2456.         }
  2457.         if (zfnqfp(s,CKMAXPATH,tmpbuf))
  2458.           s = tmpbuf;
  2459.         if ((x = cmcfm()) < 0) return(x);
  2460.         if (iksdcf) return(success = 0);
  2461.         if (*s)
  2462.       makestr(&wtmpfile,s);
  2463.         break;
  2464. #endif /* CKWTMP */
  2465. #endif /* CK_LOGIN */
  2466. #ifdef IKSDB
  2467.       case IKS_DBFI: {
  2468.           extern char * dbdir, * dbfile;
  2469.           extern int dbenabled;
  2470.           struct zfnfp * zz;
  2471.           if ((z = cmifi("Filename","",&s,&x,xxstring)) < 0)
  2472.         return(z);
  2473.           if (x) {
  2474.               printf("?Wildcards not allowed\n");
  2475.               return(-9);
  2476.           }
  2477.           zz = zfnqfp(s,CKMAXPATH,tmpbuf);
  2478.           if ((x = cmcfm()) < 0) return(x);
  2479.           if (iksdcf) return(success = 0);
  2480.           if (zz) {
  2481.               makestr(&dbdir,zz->fpath);
  2482.               makestr(&dbfile,(char *)tmpbuf);
  2483.               dbenabled = 1;
  2484.           } else
  2485.         return(success = 0);
  2486.           break;
  2487.       }
  2488.       case IKS_DBAS: {
  2489.           extern int dbenabled;
  2490.           if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
  2491.         return(z);
  2492.           if ((x = cmcfm()) < 0) return(x);
  2493.           if (iksdcf) return(success = 0);
  2494.           dbenabled = z;
  2495.           break;
  2496.       }
  2497. #endif /* IKSDB */
  2498.  
  2499.       case IKS_INIT:
  2500.         if ((z = cmtxt("Alternate init file specification","",
  2501.                &s,xxstring)) < 0)
  2502.       return(z);
  2503.         if (z < 0) return(z);
  2504.         if (iksdcf) return(success = 0);
  2505.         ckstrncpy(kermrc,s,KERMRCL);
  2506.         rcflag = 1;            /* Flag that this has been done */
  2507.         break;
  2508.  
  2509.       case IKS_NOIN:
  2510.         if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
  2511.       return(z);
  2512.         if ((x = cmcfm()) < 0) return(x);
  2513.         if (iksdcf) return(success = 0);
  2514.         noinit = z;
  2515.         break;
  2516.  
  2517.       case IKS_SRVR:
  2518.         if ((z = cmkey(oktab,noktab,"","no",xxstring)) < 0)
  2519.       return(z);
  2520.         if ((x = cmcfm()) < 0) return(x);
  2521.         if (iksdcf) return(success = 0);
  2522.         arg_x = z;
  2523.         break;
  2524.  
  2525.       default:
  2526.         return(-9);
  2527.     }
  2528.     return(success = (inserver ? 1 : 0));
  2529. #else /* IKSDCONF */
  2530.     if ((x = cmcfm()) < 0)
  2531.       return(x);
  2532.     return(success = 0);
  2533. #endif /* IKSDCONF */
  2534. }
  2535. #endif /* NOICP */
  2536. #endif /* IKSD */
  2537.  
  2538. /*  D O A R G  --  Do a command-line argument.  */
  2539.  
  2540. int
  2541. #ifdef CK_ANSIC
  2542. doarg(char x)
  2543. #else
  2544. doarg(x) char x;
  2545. #endif /* CK_ANSIC */
  2546. /* doarg */ {
  2547.     int i, n, y, z, xx; long zz; char *xp;
  2548.  
  2549. #ifdef NETCONN
  2550. #define YYBUFLEN 256
  2551.     char tmpbuf[YYBUFLEN+1];            /* Local storage for network things */
  2552.     char line[YYBUFLEN+1];
  2553. #endif /* NETCONN */
  2554.  
  2555. #ifdef IKSD
  2556.     /* Internet Kermit Server set some way besides -A... */
  2557.     if (inserver)
  2558.       dofast();
  2559. #endif /* IKSD */
  2560.  
  2561.     xp = *xargv+1;                      /* Pointer for bundled args */
  2562.     debug(F111,"doarg entry",xp,xargc);
  2563.     while (x) {
  2564.         debug(F000,"doarg arg","",x);
  2565.         switch (x) {                    /* Big switch on arg */
  2566.  
  2567. #ifndef COMMENT
  2568.       case '-':            /* Extended commands... */
  2569.         if (doxarg(xargv,0) < 0) {
  2570.         XFATAL("Extended option error");
  2571.         } /* Full thru... */
  2572.       case '+':            /* Extended command for prescan() */
  2573.         return(0);
  2574. #else  /* NOICP */
  2575.       case '-':
  2576.       case '+':
  2577.         XFATAL("Extended options not configured");
  2578. #endif /* NOICP */
  2579.  
  2580. #ifndef NOSPL
  2581.       case 'C': {            /* Commands for parser */
  2582.           char * s;
  2583.           xargv++, xargc--;
  2584.           if ((xargc < 1) || (**xargv == '-')) {
  2585.           XFATAL("No commands given for -C");
  2586.           }
  2587.           s = *xargv;        /* Get the argument (must be quoted) */
  2588.           if (!*s)            /* If empty quotes */
  2589.         s = NULL;        /* ignore this option */
  2590.           if (s) {
  2591.           makestr(&clcmds,s);    /* Make pokeable copy */
  2592.           s = clcmds;        /* Change tabs to spaces */
  2593.           while (*s) {
  2594.               if (*s == '\t') *s = ' ';
  2595.               s++;
  2596.           }
  2597.           }
  2598.           break;
  2599.       }
  2600. #endif /* NOSPL */
  2601.  
  2602. #ifndef NOXFER
  2603.       case 'D':            /* Delay */
  2604.         if (*(xp+1)) {
  2605.         XFATAL("invalid argument bundling");
  2606.         }
  2607.         xargv++, xargc--;
  2608.         if ((xargc < 1) || (**xargv == '-')) {
  2609.         XFATAL("missing delay value");
  2610.         }
  2611.         z = atoi(*xargv);        /* Convert to number */
  2612.         if (z > -1)            /* If in range */
  2613.           ckdelay = z;        /* set it */
  2614.         else {
  2615.         XFATAL("bad delay value");
  2616.         }
  2617.         break;
  2618. #endif /* NOXFER */
  2619.  
  2620.       case 'E':            /* Exit on close */
  2621. #ifdef NETCONN
  2622.         tn_exit = 1;
  2623. #endif /* NETCONN */
  2624.         exitonclose = 1;
  2625.         break;
  2626.  
  2627. #ifndef NOICP
  2628.       case 'S':            /* "Stay" - enter interactive */
  2629.         stayflg = 1;        /* command parser after executing */
  2630.         xfinish = 0;        /* command-line actions. */
  2631.         break;
  2632. #endif /* NOICP */
  2633.  
  2634.       case 'T':            /* File transfer mode = text */
  2635.         binary = XYFT_T;
  2636.         xfermode = XMODE_M;        /* Transfer mode manual */
  2637.         filepeek = 0;
  2638. #ifdef PATTERNS
  2639.         patterns = 0;
  2640. #endif /* PATTERNS */
  2641.         break;
  2642.  
  2643.       case '7':
  2644.         break;
  2645.  
  2646. #ifdef IKSD
  2647.       case 'A': {            /* Internet server */
  2648.           /* Already done in prescan() */
  2649.           /* but implies 'x' &&  'Q'   */
  2650. #ifdef OS2
  2651.           char * p;
  2652.           if (*(xp+1)) {
  2653.           XFATAL("invalid argument bundling");
  2654.           }
  2655. #ifdef NT
  2656.           /* Support for Pragma Systems Telnet/Terminal Servers */
  2657.           p = getenv("PRAGMASYS_INETD_SOCK");
  2658.           if (!(p && atoi(p) != 0)) {
  2659.           xargv++, xargc--;
  2660.           if (xargc < 1 || **xargv == '-') {
  2661.               XFATAL("missing socket handle");
  2662.           }
  2663.           }
  2664. #else /* NT */
  2665.           xargv++, xargc--;
  2666.           if (xargc < 1 || **xargv == '-') {
  2667.           XFATAL("missing socket handle");
  2668.           }
  2669. #endif /* NT */
  2670. #endif /* OS2 */
  2671. #ifdef NOICP                            /* If no Interactive Command Parser */
  2672.           action = 'x';        /* -A implies -x. */
  2673. #endif /* NOICP */
  2674. #ifndef NOXFER
  2675.           dofast();
  2676. #endif /* NOXFER */
  2677.           break;
  2678.       }
  2679. #endif /* IKSD */
  2680.  
  2681. #ifndef NOXFER
  2682.       case 'Q':            /* Quick (i.e. FAST) */
  2683.         dofast();
  2684.         break;
  2685. #endif /* NOXFER */
  2686.  
  2687.       case 'R':            /* Remote-Only */
  2688.         break;            /* This is handled in prescan(). */
  2689.  
  2690. #ifndef NOSERVER
  2691.       case 'x':            /* server */
  2692.       case 'O':            /* (for One command only) */
  2693.         if (action) {
  2694.         XFATAL("conflicting actions");
  2695.         }
  2696.         if (x == 'O') justone = 1;
  2697.         xfinish = 1;
  2698.         action = 'x';
  2699.         break;
  2700. #endif /* NOSERVER */
  2701.  
  2702. #ifndef NOXFER
  2703.       case 'f':            /* finish */
  2704.         if (action) {
  2705.         XFATAL("conflicting actions");
  2706.         }
  2707.         action = setgen('F',"","","");
  2708.         break;
  2709. #endif /* NOXFER */
  2710.  
  2711.       case 'r': {            /* receive */
  2712.           if (action) {
  2713.           XFATAL("conflicting actions");
  2714.           }
  2715.           action = 'v';
  2716.           break;
  2717.       }
  2718.  
  2719. #ifndef NOXFER
  2720.       case 'k':            /* receive to stdout */
  2721.         if (action) {
  2722.         XFATAL("conflicting actions");
  2723.         }
  2724.         stdouf = 1;
  2725.         action = 'v';
  2726.         break;
  2727.  
  2728.       case 's': {            /* send */
  2729.           int fil2snd, rc;
  2730.           if (!recursive)
  2731.           nolinks = 0;        /* Follow links by default */
  2732.  
  2733.           if (action) {
  2734.           XFATAL("conflicting actions");
  2735.           }
  2736.           if (*(xp+1)) {
  2737.           XFATAL("invalid argument bundling after -s");
  2738.           }
  2739.           nfils = 0;        /* Initialize file counter */
  2740.           fil2snd = 0;        /* Assume nothing to send  */
  2741.           z = 0;            /* Flag for stdin */
  2742.           cmlist = xargv + 1;    /* Remember this pointer */
  2743.           while (++xargv, --xargc > 0) { /* Traverse the list */
  2744. #ifdef PIPESEND
  2745.           if (usepipes && protocol == PROTO_K && **xargv == '!') {
  2746.               cmarg = *xargv;
  2747.               cmarg++;
  2748.               debug(F110,"doarg pipesend",cmarg,0);
  2749.               nfils = -1;
  2750.               z = 1;
  2751.               pipesend = 1;
  2752.           } else
  2753. #endif /* PIPESEND */
  2754.             if (**xargv == '-') { /* Check for sending stdin */
  2755.             if (strcmp(*xargv,"-") != 0) /* next option? */
  2756.               break;
  2757.             z++;        /* "-" alone means send from stdin. */
  2758. #ifdef RECURSIVE
  2759.             } else if (!strcmp(*xargv,".")) {
  2760.             fil2snd = 1;
  2761.             nfils++;
  2762.             recursive = 1;
  2763.             nolinks = 2;
  2764. #endif /* RECURSIVE */
  2765.             } else /* Check if file exists */
  2766.               if ((rc = zchki(*xargv)) > -1 || (rc == -2)) {
  2767.               if  (rc != -2)
  2768.                 fil2snd = 1;
  2769.               nfils++;    /* Bump file counter */
  2770.               } else if (iswild(*xargv) && nzxpand(*xargv,0) > 0) {
  2771.               /* or contains wildcard characters matching real files */
  2772.               fil2snd = 1;
  2773.               nfils++;
  2774.               }
  2775.           }
  2776.           xargc++, xargv--;        /* Adjust argv/argc */
  2777.           if (!fil2snd && z == 0) {
  2778. #ifdef VMS
  2779.           XFATAL("%CKERMIT-E-SEARCHFAIL, no files for -s");
  2780. #else
  2781.           XFATAL("No files for -s");
  2782. #endif /* VMS */
  2783.           }
  2784.           if (z > 1) {
  2785.           XFATAL("-s: too many -'s");
  2786.           }
  2787.           if (z == 1 && fil2snd) {
  2788.           XFATAL("invalid mixture of filenames and '-' in -s");
  2789.           }
  2790.           debug(F101,"doarg s nfils","",nfils);
  2791.           debug(F101,"doarg s z","",z);
  2792.           if (nfils == 0) {        /* no file parameters were specified */
  2793.           if (is_a_tty(0)) {    /* (used to be is_a_tty(1) - why?) */
  2794.               XFATAL("sending from terminal not allowed");
  2795.           } else stdinf = 1;
  2796.           }
  2797.           debug(F101,"doarg s stdinf","",stdinf);
  2798.           debug(F111,"doarg",*xargv,nfils);
  2799.           action = 's';
  2800.           break;
  2801.       }
  2802.  
  2803.       case 'g':            /* get */
  2804.       case 'G':            /* get to stdout */
  2805.         if (action) {
  2806.         XFATAL("conflicting actions");
  2807.         }
  2808.         if (*(xp+1)) {
  2809.         XFATAL("invalid argument bundling after -g");
  2810.         }
  2811.         xargv++, xargc--;
  2812.         if ((xargc == 0) || (**xargv == '-')) {
  2813.         XFATAL("missing filename for -g");
  2814.         }
  2815.         if (x == 'G') stdouf = 1;
  2816.         cmarg = *xargv;
  2817.         action = 'r';
  2818.         break;
  2819. #endif /* NOXFER */
  2820.  
  2821. #ifndef NOLOCAL
  2822.       case 'c':            /* connect before */
  2823.         cflg = 1;
  2824.         break;
  2825.  
  2826.       case 'n':            /* connect after */
  2827.         cnflg = 1;
  2828.         break;
  2829. #endif /* NOLOCAL */
  2830.  
  2831.       case 'h':            /* help */
  2832.         usage();
  2833. #ifndef NOICP
  2834.         if (stayflg || what == W_COMMAND)
  2835.           break;
  2836.         else
  2837. #endif /* NOICP */
  2838.           doexit(GOOD_EXIT,-1);
  2839.  
  2840. #ifndef NOXFER
  2841.       case 'a':            /* "as" */
  2842.         if (*(xp+1)) {
  2843.         XFATAL("invalid argument bundling after -a");
  2844.         }
  2845.         xargv++, xargc--;
  2846.         if ((xargc < 1) || (**xargv == '-')) {
  2847.         XFATAL("missing name in -a");
  2848.         }
  2849.         cmarg2 = *xargv;
  2850.         debug(F111,"doarg a",cmarg2,xargc);
  2851.         break;
  2852. #endif /* NOXFER */
  2853.  
  2854. #ifndef NOICP
  2855.       case 'Y':            /* No initialization file */
  2856.         noinit = 1;
  2857.         break;
  2858.  
  2859.       case 'y':            /* Alternate init-file name */
  2860.         noinit = 0;
  2861.         if (*(xp+1)) {
  2862.         XFATAL("invalid argument bundling after -y");
  2863.         }
  2864.         xargv++, xargc--;
  2865.         if (xargc < 1) {
  2866.         XFATAL("missing filename in -y");
  2867.         }
  2868.         /* strcpy(kermrc,*xargv); ... already done in prescan()... */
  2869.         break;
  2870. #endif /* NOICP */
  2871.  
  2872. #ifndef NOXFER
  2873.       case 'I':            /* Assume we have an "Internet" */
  2874.         reliable = 1;        /* or other reliable connection */
  2875.         xreliable = 1;
  2876.         setreliable = 1;
  2877.  
  2878.         /* I'm not so sure about this -- what about VMS? (next comment) */
  2879.         clearrq = 1;        /* therefore the channel is clear */
  2880.  
  2881. #ifndef VMS
  2882. /*
  2883.   Since this can trigger full control-character unprefixing, we need to
  2884.   ensure that our terminal or pty driver is not doing Xon/Xoff; otherwise
  2885.   we can become deadlocked the first time we receive a file that contains
  2886.   Xoff.
  2887. */
  2888.         flow = FLO_NONE;
  2889. #endif /* VMS */
  2890.         break;
  2891. #endif /* NOXFER */
  2892.  
  2893. #ifndef NOLOCAL
  2894.       case 'l':            /* SET LINE */
  2895. #ifdef NETCONN
  2896. #ifdef ANYX25
  2897.       case 'X':            /* SET HOST to X.25 address */
  2898. #ifdef SUNX25
  2899.       case 'Z':            /* SET HOST to X.25 file descriptor */
  2900. #endif /* SUNX25 */
  2901. #endif /* ANYX25 */
  2902. #ifdef TCPSOCKET
  2903.       case 'J':
  2904.       case 'j':            /* SET HOST (TCP/IP socket) */
  2905. #endif /* TCPSOCKET */
  2906. #endif /* NETCONN */
  2907. #ifndef NOXFER
  2908.         if (x == 'j' || x == 'J' || x == 'X' || x == 'Z') {
  2909.         reliable = 1;        /* or other reliable connection */
  2910.         xreliable = 1;
  2911.         setreliable = 1;
  2912.         }
  2913. #endif /* NOXFER */
  2914.         network = 0;
  2915.         if (*(xp+1)) {
  2916.         XFATAL("invalid argument bundling after -l or -j");
  2917.         }
  2918.         xargv++, xargc--;
  2919.         if ((xargc < 1) || (**xargv == '-')) {
  2920.         XFATAL("communication line device name missing");
  2921.         }
  2922.  
  2923. #ifdef NETCONN
  2924.         if (x == 'J') {
  2925.         cflg    = 1;        /* Connect */
  2926.         stayflg = 1;        /* Stay */
  2927.         tn_exit = 1;        /* Telnet-like exit condition */
  2928.         exitonclose = 1;
  2929.         }
  2930. #endif /* NETCONN */
  2931.         ckstrncpy(ttname,*xargv,TTNAMLEN+1);
  2932.         local = (strcmp(ttname,CTTNAM) != 0);
  2933.         if (local && strcmp(ttname,"0") == 0)
  2934.           local = 0;
  2935. /*
  2936.   NOTE: We really do not need to call ttopen here, since it should be called
  2937.   again later, automatically, when we first try to condition the device via
  2938.   ttpkt or ttvt.  Calling ttopen here has the bad side effect of making the
  2939.   order of the -b and -l options significant, but order of command-line options
  2940.   should not matter.  However, the network cases immediately below complicate
  2941.   matters a bit, so we'll settle this in a future edit.
  2942. */
  2943.         if (x == 'l') {
  2944.         if (ttopen(ttname,&local,mdmtyp,0) < 0) {
  2945.             XFATAL("can't open device");
  2946.         }
  2947. #ifdef CKLOGDIAL
  2948.         dologline();
  2949. #endif /* CKLOGDIAL */
  2950.         debug(F101,"doarg speed","",speed);
  2951.         cxtype = (mdmtyp > 0) ? CXT_MODEM : CXT_DIRECT;
  2952.         speed = ttgspd();    /* Get the speed. */
  2953.         setflow();        /* Do something about flow control. */
  2954. #ifndef NOSPL
  2955.         if (local) {
  2956.             if (nmac) {        /* Any macros defined? */
  2957.             int k;        /* Yes */
  2958.             k = mlook(mactab,"on_open",nmac); /* Look this up */
  2959.             if (k >= 0) {    /* If found, */
  2960.                 if (dodo(k,ttname,0) > -1) /* set it up, */
  2961.                   parser(1); /* and execute it */
  2962.             }
  2963.             }
  2964.         }
  2965. #endif /* NOSPL */
  2966.  
  2967. #ifdef NETCONN
  2968.         } else {
  2969.         if (x == 'j' || x == 'J') { /* IP network host name */
  2970.             char * s = line;
  2971.             char * service = tmpbuf;
  2972.             if (xargc > 0) {    /* Check if it's followed by */
  2973.             /* A service name or number */
  2974.             if (*(xargv+1) && *(*(xargv+1)) != '-') {
  2975.                 xargv++, xargc--;
  2976.                 ckstrncat(ttname,":",TTNAMLEN+1);
  2977.                 ckstrncat(ttname,*xargv,TTNAMLEN+1);
  2978.             }
  2979.             }
  2980.             nettype = NET_TCPB;
  2981.             mdmtyp = -nettype;    /* Perhaps already set in init file */
  2982.             telnetfd = 1;    /* Or maybe an open file descriptor */
  2983.             ckstrncpy(line, ttname, YYBUFLEN); /* Working copy */
  2984.             for (s = line; *s != NUL && *s != ':'; s++);
  2985.             if (*s) {
  2986.             *s++ = NUL;
  2987.             ckstrncpy(service, s, YYBUFLEN);
  2988.             } else *service = NUL;
  2989.             s = line;
  2990. #ifndef NODIAL
  2991. #ifndef NOICP
  2992.             /* Look up in network directory */
  2993.             x = 0;
  2994.             if (*s == '=') {    /* If number starts with = sign */
  2995.             s++;        /* strip it */
  2996.             while (*s == SP) /* and also any leading spaces */
  2997.               s++;
  2998.             ckstrncpy(line,s,YYBUFLEN); /* Do this again. */
  2999.             nhcount = 0;
  3000.             } else if (!isdigit(line[0])) {
  3001. /*
  3002.   nnetdir will be greater than 0 if the init file has been processed and it
  3003.   contained a SET NETWORK DIRECTORY command.
  3004. */
  3005.             xx = 0;        /* Initialize this */
  3006.             if (nnetdir > 0) /* If there is a directory... */
  3007.               xx = lunet(line); /* Look up the name */
  3008.             else        /* If no directory */
  3009.               nhcount = 0;    /* we didn't find anything there */
  3010.             if (xx < 0) {    /* Lookup error: */
  3011.                 ckmakmsg(tmpbuf,
  3012.                      YYBUFLEN,
  3013.                     "?Fatal network directory lookup error - ",
  3014.                      line,
  3015.                      "\n",
  3016.                      NULL
  3017.                      );
  3018.                 XFATAL(tmpbuf);
  3019.             }
  3020.             }
  3021. #endif /* NOICP */
  3022. #endif /* NODIAL */
  3023.             /* Add service to line specification for ttopen() */
  3024.             if (*service) {    /* There is a service specified */
  3025.             ckstrncat(line, ":",LINBUFSIZ);
  3026.             ckstrncat(line, service,LINBUFSIZ);
  3027.             ttnproto = NP_DEFAULT;
  3028.             } else {
  3029.             ckstrncat(line, ":telnet",LINBUFSIZ);
  3030.             ttnproto = NP_TELNET;
  3031.             }
  3032.  
  3033. #ifndef NOICP
  3034. #ifndef NODIAL
  3035.             if ((nhcount > 1) && !quiet && !backgrd) {
  3036.             printf("%d entr%s found for \"%s\"%s\n",
  3037.                    nhcount,
  3038.                    (nhcount == 1) ? "y" : "ies",
  3039.                    s,
  3040.                    (nhcount > 0) ? ":" : "."
  3041.                    );
  3042.             for (i = 0; i < nhcount; i++)
  3043.               printf("%3d. %s %-12s => %s\n",
  3044.                  i+1, n_name, nh_p2[i], nh_p[i]
  3045.                  );
  3046.             }
  3047.             if (nhcount == 0)
  3048.               n = 1;
  3049.             else
  3050.               n = nhcount;
  3051. #else
  3052.             n = 1;
  3053.             nhcount = 0;
  3054. #endif /* NODIAL */
  3055.             for (i = 0; i < n; i++) {
  3056. #ifndef NODIAL
  3057.             if (nhcount >= 1) {
  3058.                 /* Copy the current entry to line */
  3059.                 ckstrncpy(line,nh_p[i],LINBUFSIZ);
  3060.                     /* Check to see if the network entry contains a service */
  3061.                 for (s = line ; (*s != NUL) && (*s != ':'); s++)
  3062.                   ;
  3063.                 /* If directory does not have a service ... */
  3064.                 /* and the user specified one */
  3065.                 if (!*s && *service) {
  3066.                 ckstrncat(line, ":",LINBUFSIZ);
  3067.                 ckstrncat(line, service,LINBUFSIZ);
  3068.                 }
  3069.                 if (lookup(netcmd,nh_p2[i],nnets,&z) > -1) {
  3070.                 mdmtyp = 0 - netcmd[z].kwval;
  3071.                 } else {
  3072.                 printf(
  3073.                  "Error - network type \"%s\" not supported\n",
  3074.                        nh_p2[i]
  3075.                        );
  3076.                 continue;
  3077.                 }
  3078.             }
  3079. #endif /* NODIAL */
  3080.             }
  3081. #endif /* NOICP */
  3082.             ckstrncpy(ttname, line,TTNAMLEN+1);
  3083.             cxtype = CXT_TCPIP;    /* Set connection type */
  3084.             setflow();        /* Set appropriate flow control. */
  3085. #ifdef SUNX25
  3086.         } else if (x == 'X') {    /* X.25 address */
  3087.             nettype = NET_SX25;
  3088.             mdmtyp = -nettype;
  3089.         } else if (x == 'Z') {    /* Open X.25 file descriptor */
  3090.             nettype = NET_SX25;
  3091.             mdmtyp = -nettype;
  3092.             x25fd = 1;
  3093. #endif /* SUNX25 */
  3094. #ifdef STRATUSX25
  3095.         } else if (x == 'X') {    /* X.25 address */
  3096.             nettype = NET_VX25;
  3097.             mdmtyp = -nettype;
  3098. #endif /* STRATUSX25 */
  3099. #ifdef IBMX25
  3100.         } else if (x == 'X') {    /* X.25 address */
  3101.             nettype = NET_IX25;
  3102.             mdmtyp = -nettype;
  3103. #endif /* IBMX25 */
  3104. #ifdef HPX25
  3105.         } else if (x == 'X') {    /* X.25 address */
  3106.             nettype = NET_HX25;
  3107.             mdmtyp = -nettype;
  3108. #endif /* HPX25 */
  3109.         }
  3110.         if (ttopen(ttname,&local,mdmtyp,0) < 0) {
  3111.             XFATAL("can't open host connection");
  3112.         }
  3113.         network = 1;
  3114. #ifdef CKLOGDIAL
  3115.         dolognet();
  3116. #endif /* CKLOGDIAL */
  3117.         cxtype = CXT_X25;    /* Set connection type */
  3118.         setflow();        /* Set appropriate flow control. */
  3119. #ifndef NOSPL
  3120.         if (local) {
  3121.             if (nmac) {        /* Any macros defined? */
  3122.             int k;        /* Yes */
  3123.             k = mlook(mactab,"on_open",nmac); /* Look this up */
  3124.             if (k >= 0) {    /* If found, */
  3125.                 if (dodo(k,ttname,0) > -1) /* set it up, */
  3126.                   parser(1);        /* and execute it */
  3127.             }
  3128.             }
  3129.         }
  3130. #endif /* NOSPL */
  3131. #endif /* NETCONN */
  3132.         }
  3133.         /* add more here -- decnet, etc... */
  3134.         haveline = 1;
  3135.         break;
  3136.  
  3137. #ifdef ANYX25
  3138.       case 'U':            /* X.25 call user data */
  3139.         if (*(xp+1)) {
  3140.         XFATAL("invalid argument bundling");
  3141.         }
  3142.         xargv++, xargc--;
  3143.         if ((xargc < 1) || (**xargv == '-')) {
  3144.         XFATAL("missing call user data string");
  3145.         }
  3146.         ckstrncpy(udata,*xargv,MAXCUDATA);
  3147.         if ((int)strlen(udata) <= MAXCUDATA) {
  3148.         cudata = 1;
  3149.         } else {
  3150.         XFATAL("Invalid call user data");
  3151.         }
  3152.         break;
  3153.  
  3154.       case 'o':            /* X.25 closed user group */
  3155.         if (*(xp+1)) {
  3156.         XFATAL("invalid argument bundling");
  3157.         }
  3158.         xargv++, xargc--;
  3159.         if ((xargc < 1) || (**xargv == '-')) {
  3160.         XFATAL("missing closed user group index");
  3161.         }
  3162.         z = atoi(*xargv);        /* Convert to number */
  3163.         if (z >= 0 && z <= 99) {
  3164.         closgr = z;
  3165.         } else {
  3166.         XFATAL("Invalid closed user group index");
  3167.         }
  3168.         break;
  3169.  
  3170.       case 'u':            /* X.25 reverse charge call */
  3171.         revcall = 1;
  3172.         break;
  3173. #endif /* ANYX25 */
  3174. #endif /* NOLOCAL */
  3175.  
  3176.       case 'b':            /* Bits-per-second for serial device */
  3177.         if (*(xp+1)) {
  3178.         XFATAL("invalid argument bundling");
  3179.         }
  3180.         xargv++, xargc--;
  3181.         if ((xargc < 1) || (**xargv == '-')) {
  3182.         XFATAL("missing bps");
  3183.         }
  3184.         zz = atol(*xargv);        /* Convert to long int */
  3185.         i = zz / 10L;
  3186. #ifndef NOLOCAL
  3187.         if (ttsspd(i) > -1)        /* Check and set it */
  3188. #endif /* NOLOCAL */
  3189.           speed = ttgspd();        /* and read it back. */
  3190. #ifndef NOLOCAL
  3191.         else {
  3192.         XFATAL("unsupported transmission rate");
  3193.         }
  3194. #endif /* NOLOCAL */
  3195.         break;
  3196.  
  3197. #ifndef NODIAL
  3198. #ifndef NOICP
  3199.       case 'm':            /* Modem type */
  3200.         if (*(xp+1)) {
  3201.         XFATAL("invalid argument bundling after -m");
  3202.         }
  3203.         xargv++, xargc--;
  3204.         if ((xargc < 1) || (**xargv == '-')) {
  3205.         XFATAL("modem type missing");
  3206.         }
  3207.         y = lookup(mdmtab,*xargv,nmdm,&z);
  3208.         if (y < 0) {
  3209.         XFATAL("unknown modem type");
  3210.         }
  3211.         usermdm = 0;
  3212.         usermdm = (y == dialudt) ? x : 0;
  3213.         initmdm(y);
  3214.         break;
  3215. #endif /* NOICP */
  3216. #endif /* NODIAL */
  3217.  
  3218. #ifndef NOXFER
  3219.       case 'e':            /* Extended packet length */
  3220.         if (*(xp+1)) {
  3221.         XFATAL("invalid argument bundling after -e");
  3222.         }
  3223.         xargv++, xargc--;
  3224.         if ((xargc < 1) || (**xargv == '-')) {
  3225.         XFATAL("missing length");
  3226.         }
  3227.         z = atoi(*xargv);        /* Convert to number */
  3228.         if (z > 10 && z <= maxrps) {
  3229.         rpsiz = urpsiz = z;
  3230.         if (z > 94) rpsiz = 94;    /* Fallback if other Kermit can't */
  3231.         } else {
  3232.         XFATAL("Unsupported packet length");
  3233.         }
  3234.         break;
  3235.  
  3236.       case 'v':            /* Vindow size */
  3237.         if (*(xp+1)) {
  3238.         XFATAL("invalid argument bundling");
  3239.         }
  3240.         xargv++, xargc--;
  3241.         if ((xargc < 1) || (**xargv == '-')) {
  3242.         XFATAL("missing or bad window size");
  3243.         }
  3244.         z = atoi(*xargv);        /* Convert to number */
  3245.         if (z < 32) {        /* If in range */
  3246.         wslotr = z;        /* set it */
  3247.         if (z > 1) swcapr = 1;    /* Set capas bit if windowing */
  3248.         } else {
  3249.         XFATAL("Unsupported packet length");
  3250.         }
  3251.         break;
  3252. #endif /* NOXFER */
  3253.  
  3254.       case 'i':            /* Treat files as binary */
  3255.         binary = XYFT_B;
  3256.         xfermode = XMODE_M;        /* Transfer mode manual */
  3257.         filepeek = 0;
  3258. #ifdef PATTERNS
  3259.         patterns = 0;
  3260. #endif /* PATTERNS */
  3261.         break;
  3262.  
  3263. #ifndef NOXFER
  3264.       case 'w':            /* Writeover */
  3265.         ckwarn = 0;
  3266.         fncact = XYFX_X;
  3267.         break;
  3268. #endif /* NOXFER */
  3269.  
  3270.       case 'q':            /* Quiet */
  3271.         quiet = 1;
  3272.         break;
  3273.  
  3274. #ifdef DEBUG
  3275.       case 'd':            /* DEBUG */
  3276.         break;            /* Handled in prescan() */
  3277. #endif /* DEBUG */
  3278.  
  3279.       case '0': {            /* In the middle */
  3280.           extern int tt_escape, lscapr;
  3281.           tt_escape = 0;        /* No escape character */
  3282.           flow = 0;            /* No Xon/Xoff (what about hwfc?) */
  3283. #ifndef NOXFER
  3284.           lscapr = 0;        /* No locking shifts */
  3285. #endif /* NOXFER */
  3286. #ifdef CK_APC
  3287.           {
  3288.           extern int apcstatus;    /* No APCs */
  3289.           apcstatus = APC_OFF;
  3290.           }
  3291. #endif /* CK_APC */
  3292. #ifdef CK_AUTODL
  3293.           {                /* No autodownload */
  3294.           extern int autodl;
  3295.           autodl = 0;
  3296.           }
  3297. #endif /* CK_AUTODL */
  3298. #ifndef NOCSETS
  3299.           {
  3300.           extern int tcsr, tcsl; /* No character-set translation */
  3301.           tcsr = 0;
  3302.           tcsl = tcsr;        /* Make these equal */
  3303.           }
  3304. #endif /* NOCSETS */
  3305. #ifdef TNCODE
  3306.           TELOPT_DEF_C_U_MODE(TELOPT_KERMIT) = TN_NG_RF;
  3307.           TELOPT_DEF_C_ME_MODE(TELOPT_KERMIT) = TN_NG_RF;
  3308.           TELOPT_DEF_S_U_MODE(TELOPT_KERMIT) = TN_NG_RF;
  3309.           TELOPT_DEF_S_ME_MODE(TELOPT_KERMIT) = TN_NG_RF;
  3310. #endif /* TNCODE */
  3311.       }
  3312. /* Fall thru... */
  3313.  
  3314.       case '8':            /* 8-bit clean */
  3315.         parity = 0;
  3316.         cmdmsk = 0xff;
  3317.         cmask = 0xff;
  3318.         break;
  3319.  
  3320.       case 'V': {
  3321.           extern int xfermode;
  3322. #ifdef PATTERNS
  3323.           extern int patterns;
  3324.           patterns = 0;        /* No patterns */
  3325. #endif /* PATTERNS */
  3326.           xfermode = XMODE_M;    /* Manual transfer mode */
  3327.           filepeek = 0;
  3328.           break;
  3329.       }
  3330.  
  3331.       case 'p':            /* SET PARITY */
  3332.         if (*(xp+1)) {
  3333.         XFATAL("invalid argument bundling");
  3334.         }
  3335.         xargv++, xargc--;
  3336.         if ((xargc < 1) || (**xargv == '-')) {
  3337.         XFATAL("missing parity");
  3338.         }
  3339.         switch(x = **xargv) {
  3340.           case 'e':
  3341.           case 'o':
  3342.           case 'm':
  3343.           case 's': parity = x; break;
  3344.           case 'n': parity = 0; break;
  3345.           default:  { XFATAL("invalid parity"); }
  3346.         }
  3347.         break;
  3348.  
  3349.       case 't':            /* Line turnaround handshake */
  3350.         turn = 1;
  3351.         turnch = XON;        /* XON is turnaround character */
  3352.         duplex = 1;            /* Half duplex */
  3353.         flow = 0;            /* No flow control */
  3354.         break;
  3355.  
  3356.       case 'B':
  3357.         bgset = 1;            /* Force background (batch) */
  3358.         backgrd = 1;
  3359.         break;
  3360.  
  3361.       case 'z':            /* Force foreground */
  3362.         bgset = 0;
  3363.         backgrd = 0;
  3364.         break;
  3365.  
  3366. #ifndef NOXFER
  3367. #ifdef RECURSIVE
  3368.       case 'L':
  3369.         recursive = 2;
  3370.         nolinks = 2;
  3371.         fnspath = PATH_REL;
  3372.         break;
  3373. #endif /* RECURSIVE */
  3374. #endif /* NOXFER */
  3375.  
  3376. #ifndef NOSPL
  3377.       case 'M':            /* My User Name */
  3378.         if (*(xp+1)) {
  3379.         XFATAL("invalid argument bundling");
  3380.         }
  3381.         xargv++, xargc--;
  3382.         if ((xargc < 1) || (**xargv == '-')) {
  3383.         XFATAL("missing username");
  3384.         }
  3385.         if ((int)strlen(*xargv) > 63) {
  3386.         XFATAL("username too long");
  3387.         }
  3388. #ifdef IKSD
  3389.         if (!inserver)
  3390. #endif /* IKSD */
  3391.           {
  3392.           ckstrncpy(uidbuf,*xargv,UIDBUFLEN);
  3393.           haveftpuid = 1;
  3394.           }
  3395.         break;
  3396. #endif /* NOSPL */
  3397.  
  3398. #ifdef CK_NETBIOS
  3399.       case 'N':            /* NetBios Adapter Number follows */
  3400.         if (*(xp+1)) {
  3401.         XFATAL("invalid argument bundling after -N");
  3402.         }
  3403.         xargv++, xargc--;
  3404.         if ((xargc < 1) || (**xargv == '-')) {
  3405.         XFATAL("missing NetBios Adapter number");
  3406.         }
  3407.         if ((strlen(*xargv) != 1) ||
  3408.         (*xargv)[0] != 'X' &&
  3409.         (atoi(*xargv) < 0) &&
  3410.         (atoi(*xargv) > 9)) {
  3411.         XFATAL("Invalid NetBios Adapter - Adapters 0 to 9 are valid");
  3412.         }
  3413.         break;
  3414. #endif /* CK_NETBIOS */
  3415.  
  3416. #ifdef NETCONN
  3417.       case 'F':
  3418.         network = 1;
  3419.         if (*(xp+1)) {
  3420.         XFATAL("invalid argument bundling after -F");
  3421.         }
  3422.         xargv++, xargc--;
  3423.         if ((xargc < 1) || (**xargv == '-')) {
  3424.         XFATAL("network file descriptor missing");
  3425.         }
  3426.         ckstrncpy(ttname,*xargv,TTNAMLEN+1);
  3427.         nettype = NET_TCPB;
  3428.         mdmtyp = -nettype;
  3429.         telnetfd = 1;
  3430.         local = 1;
  3431.         break;
  3432. #endif /* NETCONN */
  3433.  
  3434. #ifdef COMMENT
  3435. #ifdef OS2PM
  3436.       case 'P':            /* OS/2 Presentation Manager */
  3437.         if (*(xp+1)) {
  3438.         XFATAL("invalid argument bundling after -P");
  3439.         }
  3440.         xargv++, xargc--;
  3441.         if ((xargc < 1) || (**xargv == '-')) {
  3442.         XFATAL("pipe data missing");
  3443.         }
  3444.         pipedata = *xargv;
  3445.         break;
  3446. #endif /* OS2PM */
  3447. #else
  3448.       case 'P':            /* Filenames literal */
  3449.         fncnv  = XYFN_L;
  3450.         f_save = XYFN_L;
  3451.         break;
  3452. #endif /* COMMENT */
  3453.  
  3454. #ifndef NOICP
  3455.       case 'H':
  3456.         noherald = 1;
  3457.         break;
  3458. #endif /* NOICP */
  3459.  
  3460. #ifdef OS2
  3461.       case 'W':
  3462.         if (*(xp+1)) {
  3463.         XFATAL("invalid argument bundling after -W");
  3464.         }
  3465.         xargv++, xargc--;
  3466.         if ((xargc < 1)) { /* could be negative */
  3467.         XFATAL("Window handle missing");
  3468.         }
  3469.         xargv++, xargc--;
  3470.         if ((xargc < 1) || (**xargv == '-')) {
  3471.         XFATAL("Kermit Instance missing");
  3472.         }
  3473.         /* Action done in prescan */
  3474.         break;
  3475.  
  3476.       case '#':            /* K95 stdio threads */
  3477.         xargv++, xargc--;        /* Skip past argument */
  3478.         break;            /* Action done in prescan */
  3479. #endif /* OS2 */
  3480.  
  3481. #ifdef NEWFTP
  3482.       case '9':            /* FTP */
  3483.         if (*(xp+1)) {
  3484.         XFATAL("invalid argument bundling after -9");
  3485.         }
  3486.         xargv++, xargc--;
  3487.         if ((xargc < 1) || (**xargv == '-')) {
  3488.         XFATAL("FTP server address missing");
  3489.         }
  3490.         makestr(&ftp_host,*xargv);
  3491.         break;
  3492. #endif /* NEWFTP */
  3493.  
  3494.       default:
  3495.         fatal2(*xargv,
  3496. #ifdef NT
  3497.                    "invalid command-line option, type \"k95 -h\" for help"
  3498. #else
  3499. #ifdef OS2
  3500.                    "invalid command-line option, type \"k2 -h\" for help"
  3501. #else
  3502.                    "invalid command-line option, type \"kermit -h\" for help"
  3503. #endif /* OS2 */
  3504. #endif /* NT */
  3505.            );
  3506.         }
  3507.     if (!xp) break;
  3508.     x = *++xp;            /* See if options are bundled */
  3509.     }
  3510.     return(0);
  3511. }
  3512.  
  3513. #ifdef TNCODE
  3514. /*  D O T N A R G  --  Do a telnet command-line argument.  */
  3515.  
  3516. static int
  3517. #ifdef CK_ANSIC
  3518. dotnarg(char x)
  3519. #else
  3520. dotnarg(x) char x;
  3521. #endif /* CK_ANSIC */
  3522. /* dotnarg */ {
  3523.     char *xp;
  3524.  
  3525.     xp = *xargv+1;                      /* Pointer for bundled args */
  3526.     debug(F111,"doarg entry",xp,xargc);
  3527.     while (x) {
  3528.         debug(F000,"doarg arg","",x);
  3529.         switch (x) {                    /* Big switch on arg */
  3530.  
  3531.       case '-':
  3532.       case '+':
  3533.         XFATAL("Extended options not configured");
  3534.  
  3535. /*
  3536.  * -8                Negotiate Telnet Binary in both directions
  3537.  * -a                Require use of Telnet authentication
  3538.  * -c                Do not read the .telnetrc file
  3539.  * -d                Turn on debug mode
  3540.  * -E                No escape character
  3541.  * -K                Refuse use of authentication; do not send username
  3542.  * -l user           Set username and request Telnet authentication
  3543.  * -L                Negotiate Telnet Binary Output only
  3544.  * -S tos            Use the IP type-of-service tos
  3545.  * -x                Require Encryption
  3546.  * -D                Disable forward-X
  3547.  * -T cert=file      Use certificate in file
  3548.  * -T key=file       Use private key in file
  3549.  * -T crlfile=file   Use CRL in file
  3550.  * -T crldir=dir     Use CRLs in directory
  3551.  * -T cipher=string  Use only ciphers in string
  3552.  * -X atype          Disable use of atype authentication
  3553.  * -f                Forward credentials to host
  3554.  * -k realm          Set default realm
  3555.  *
  3556.  */
  3557.       case 'h':            /* help */
  3558.         usage();
  3559.         doexit(GOOD_EXIT,-1);
  3560.         break;
  3561.  
  3562.       case '8':            /* Telnet Binary in both directions */
  3563.         TELOPT_DEF_C_U_MODE(TELOPT_BINARY) = TN_NG_MU;
  3564.         TELOPT_DEF_C_ME_MODE(TELOPT_BINARY) = TN_NG_MU;
  3565.         parity = 0;
  3566.         cmdmsk = 0xff;
  3567.         cmask = 0xff;
  3568.         break;
  3569.  
  3570.       case 'a':            /* Require Telnet Auth */
  3571.         TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
  3572.         break;
  3573.  
  3574.       case 'd':
  3575. #ifdef DEBUG
  3576.         if (!deblog) {
  3577.         /* extern int debtim; */
  3578.         deblog = debopn("debug.log",0);
  3579.         /* debtim = 1; */
  3580.         }
  3581. #endif /* DEBUG */
  3582.         break;
  3583.  
  3584.       case 'E': {            /* No Escape character */
  3585.           extern int tt_escape;
  3586.           tt_escape = 0;
  3587.       }
  3588.         break;
  3589.  
  3590.       case 'K':
  3591.         TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
  3592.         uidbuf[0] = NUL;
  3593.         break;
  3594.  
  3595.       case 'l': /* Set username and request telnet authentication */
  3596.         if (*(xp+1)) {
  3597.         XFATAL("invalid argument bundling");
  3598.         }
  3599.         xargv++, xargc--;
  3600.         if ((xargc < 1) || (**xargv == '-')) {
  3601.         XFATAL("missing username");
  3602.         }
  3603.         if ((int)strlen(*xargv) > 63) {
  3604.         XFATAL("username too long");
  3605.         }
  3606.         ckstrncpy(uidbuf,*xargv,UIDBUFLEN);
  3607.         TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
  3608.         break;
  3609.  
  3610.       case 'L':            /* Require BINARY mode outbound only */
  3611.         TELOPT_DEF_C_ME_MODE(TELOPT_BINARY) = TN_NG_MU;
  3612.         break;
  3613.  
  3614.       case 'x':            /* Require Encryption */
  3615.         TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  3616.         TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  3617.         break;
  3618.  
  3619.       case 'D':            /* Disable use of Forward X */
  3620.         TELOPT_DEF_C_U_MODE(TELOPT_FORWARD_X) = TN_NG_RF;
  3621.         break;
  3622.  
  3623.       case 'f':            /* Forward credentials to host */
  3624.         {
  3625. #ifdef CK_AUTHENTICATION
  3626.         extern int forward_flag;
  3627.         forward_flag = 1;
  3628. #endif
  3629.         break;
  3630.         }
  3631.  
  3632.       case 'k': {
  3633. #ifdef CK_KERBEROS
  3634.           extern char * krb5_d_realm, * krb4_d_realm;
  3635. #endif /* CK_KERBEROS */
  3636.           if (*(xp+1)) {
  3637.           XFATAL("invalid argument bundling");
  3638.           }
  3639.           xargv++, xargc--;
  3640.           if ((xargc < 1) || (**xargv == '-')) {
  3641.           XFATAL("missing realm");
  3642.           }
  3643. #ifdef CK_KERBEROS
  3644.           if ((int)strlen(*xargv) > 63) {
  3645.           XFATAL("realm too long");
  3646.           }
  3647.           makestr(&krb5_d_realm,*xargv);
  3648.           makestr(&krb4_d_realm,*xargv);
  3649. #endif /* CK_KERBEROS */
  3650.           break;
  3651.       }
  3652.  
  3653.       case 'T': {
  3654.           if (*(xp+1)) {
  3655.           XFATAL("invalid argument bundling");
  3656.           }
  3657.           xargv++, xargc--;
  3658.           if ((xargc < 1) || (**xargv == '-')) {
  3659.           XFATAL("missing cert=, key=, crlfile=, crldir=, or cipher=");
  3660.           }
  3661. #ifdef CK_SSL
  3662.           if (!strncmp(*xargv,"cert=",5)) {
  3663.           extern char * ssl_rsa_cert_file;
  3664.           makestr(&ssl_rsa_cert_file,&(*xargv[5]));
  3665.           } else if ( !strncmp(*xargv,"key=",4) ) {
  3666.           extern char * ssl_rsa_key_file;
  3667.           makestr(&ssl_rsa_key_file,&(*xargv[4]));
  3668.           } else if ( !strncmp(*xargv,"crlfile=",8) ) {
  3669.           extern char * ssl_crl_file;
  3670.           makestr(&ssl_crl_file,&(*xargv[8]));
  3671.           } else if ( !strncmp(*xargv,"crldir=",7) ) {
  3672.           extern char * ssl_crl_dir;
  3673.           makestr(&ssl_crl_dir,&(*xargv[7]));
  3674.           } else if ( !strncmp(*xargv,"cipher=",7) ) {
  3675.           extern char * ssl_cipher_list;
  3676.           makestr(&ssl_cipher_list,&(*xargv[7]));
  3677.           } else {
  3678.           XFATAL("invalid parameter");
  3679.           }
  3680. #endif /* CK_SSL */
  3681.           break;
  3682.       }
  3683.  
  3684.       default:
  3685.         fatal2(*xargv,
  3686.            "invalid command-line option, type \"telnet -h\" for help"
  3687.            );
  3688.         }
  3689.  
  3690.     if (!xp) break;
  3691.     x = *++xp;            /* See if options are bundled */
  3692.     }
  3693.     return(0);
  3694. }
  3695. #endif /* TNCODE */
  3696. #else /* No command-line interface... */
  3697.  
  3698. extern int xargc;
  3699. int
  3700. cmdlin() {
  3701.     if (xargc > 1) {
  3702.         XFATAL("Sorry, command-line options disabled.");
  3703.     }
  3704. }
  3705. #endif /* NOCMDL */
  3706.