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