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