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