1 | #include "ckcsym.h" |
---|
2 | #define XFATAL fatal |
---|
3 | |
---|
4 | #ifndef NOCMDL |
---|
5 | |
---|
6 | /* C K U U S Y -- "User Interface" for Unix Kermit, part Y */ |
---|
7 | |
---|
8 | /* Command-Line Argument Parser */ |
---|
9 | |
---|
10 | /* |
---|
11 | Author: Frank da Cruz (fdc@columbia.edu), |
---|
12 | Columbia University, New York City. |
---|
13 | |
---|
14 | Copyright (C) 1985, 1996, Trustees of Columbia University in the City of |
---|
15 | New York. All rights reserved. |
---|
16 | */ |
---|
17 | |
---|
18 | #ifdef COMMENT |
---|
19 | Census of command-line options ( "grep ^case ckuusy.c | sort" :-) |
---|
20 | Update this if you add a new one: |
---|
21 | |
---|
22 | case '8': /* 8-bit clean */ |
---|
23 | case 'B': /* Batch (no controlling terminal) */ |
---|
24 | case 'C': /* Commands for parser */ |
---|
25 | case 'D': /* Delay */ |
---|
26 | case 'E': /* Exit on close */ |
---|
27 | case 'F': /* Socket file descriptor */ |
---|
28 | case 'J': /* Like j but exits on disconnect */ |
---|
29 | case 'M': /* Username for Telnet, Rlogin, etc */ |
---|
30 | case 'N': /* NetBios Adapter Number follows */ |
---|
31 | case 'P': /* Pipe */ |
---|
32 | case 'Q': /* Use quick settings */ |
---|
33 | case 'R': /* Remote-Only */ |
---|
34 | case 'S': /* "Stay" - enter interactive */ |
---|
35 | case 'T': /* Text file transfer mode */ |
---|
36 | case 'U': /* X.25 call user data */ |
---|
37 | case 'W': /* Win32 Window Handle */ |
---|
38 | case 'X': /* SET HOST to X.25 address */ |
---|
39 | case 'Y': /* No initialization file */ |
---|
40 | case 'Z': /* SET HOST to X.25 file descriptor */ |
---|
41 | case 'a': /* "as" */ |
---|
42 | case 'b': /* set bits-per-second for serial */ |
---|
43 | case 'c': /* connect before */ |
---|
44 | case 'd': /* DEBUG */ |
---|
45 | case 'e': /* Extended packet length */ |
---|
46 | case 'f': /* finish */ |
---|
47 | case 'g': /* get */ |
---|
48 | case 'h': /* help */ |
---|
49 | case 'i': /* Treat files as binary */ |
---|
50 | case 'j': /* SET HOST (TCP/IP socket) */ |
---|
51 | case 'k': /* receive to stdout */ |
---|
52 | case 'l': /* SET LINE */ |
---|
53 | case 'm': /* Modem type */ |
---|
54 | case 'n': /* connect after */ |
---|
55 | case 'o': /* X.25 closed user group */ |
---|
56 | case 'p': /* SET PARITY */ |
---|
57 | case 'q': /* Quiet */ |
---|
58 | case 'r': /* receive */ |
---|
59 | case 's': /* send */ |
---|
60 | case 't': /* Line turnaround handshake */ |
---|
61 | case 'u': /* X.25 reverse charge call */ |
---|
62 | case 'v': /* Vindow size */ |
---|
63 | case 'w': /* Writeover */ |
---|
64 | case 'x': /* server */ |
---|
65 | case 'y': /* Alternate init-file name */ |
---|
66 | case 'z': /* Not background */ |
---|
67 | #endif /* COMMENT */ |
---|
68 | |
---|
69 | #include "ckcdeb.h" |
---|
70 | #include "ckcasc.h" |
---|
71 | #include "ckcker.h" |
---|
72 | #include "ckucmd.h" |
---|
73 | #include "ckcnet.h" |
---|
74 | #include "ckuusr.h" |
---|
75 | |
---|
76 | #ifdef OS2 |
---|
77 | #include <io.h> |
---|
78 | #endif /* OS2 */ |
---|
79 | |
---|
80 | #ifdef NETCONN |
---|
81 | #ifdef ANYX25 |
---|
82 | extern int revcall, closgr, cudata; |
---|
83 | extern char udata[]; |
---|
84 | extern int x25fd; |
---|
85 | #endif /* ANYX25 */ |
---|
86 | #ifndef VMS |
---|
87 | #ifndef OS2 |
---|
88 | #ifndef OSK |
---|
89 | extern |
---|
90 | #endif /* OSK */ |
---|
91 | #endif /* OS2 */ |
---|
92 | #endif /* VMS */ |
---|
93 | |
---|
94 | int telnetfd; |
---|
95 | extern struct keytab netcmd[]; |
---|
96 | extern int tn_exit; |
---|
97 | #ifndef NOICP |
---|
98 | #ifndef NODIAL |
---|
99 | extern int nnets, nnetdir; /* Network services directory */ |
---|
100 | extern char *netdir[]; |
---|
101 | extern char *nh_p[]; /* Network directory entry pointers */ |
---|
102 | extern char *nh_p2[]; /* Network directory entry nettype */ |
---|
103 | #endif /* NODIAL */ |
---|
104 | extern int nhcount; |
---|
105 | extern char * n_name; /* Network name pointer */ |
---|
106 | #endif /* NOICP */ |
---|
107 | #endif /* NETCONN */ |
---|
108 | |
---|
109 | #ifndef NOSPL |
---|
110 | extern char uidbuf[]; |
---|
111 | #endif /* NOSPL */ |
---|
112 | |
---|
113 | extern char *ckxsys, *ckzsys, *cmarg, *cmarg2, **xargv, **cmlist, *clcmds; |
---|
114 | extern int action, cflg, xargc, stdouf, stdinf, displa, cnflg, nfils, |
---|
115 | local, quiet, escape, network, mdmtyp, maxrps, rpsiz, bgset, backgrd, xargs, |
---|
116 | urpsiz, wslotr, swcapr, binary, warn, parity, turn, turnch, duplex, flow, |
---|
117 | fncact, clfils, noinit, stayflg, nettype, cfilef, delay, noherald, |
---|
118 | cmask, cmdmsk, backgrd, exitonclose; |
---|
119 | extern long speed; |
---|
120 | extern char ttname[]; |
---|
121 | extern char * pipedata; |
---|
122 | |
---|
123 | #ifdef OS2 |
---|
124 | extern struct keytab os2devtab[]; |
---|
125 | extern int nos2dev; |
---|
126 | extern int ttslip; |
---|
127 | #ifdef OS2PM |
---|
128 | extern int os2pm; |
---|
129 | #endif /* OS2PM */ |
---|
130 | #endif /* OS2 */ |
---|
131 | |
---|
132 | #ifdef CK_NETBIOS |
---|
133 | extern unsigned char NetBiosAdapter; |
---|
134 | #endif /* CK_NETBIOS */ |
---|
135 | |
---|
136 | #ifdef XFATAL |
---|
137 | #undef XFATAL |
---|
138 | #endif /* XFATAL */ |
---|
139 | |
---|
140 | #ifndef NOICP |
---|
141 | #ifndef NODIAL |
---|
142 | extern int nmdm, telephony; |
---|
143 | extern struct keytab mdmtab[]; |
---|
144 | extern int usermdm, dialudt; |
---|
145 | #endif /* NODIAL */ |
---|
146 | extern int what; |
---|
147 | _PROTOTYP(static int pmsg, (char *) ); |
---|
148 | _PROTOTYP(static int fmsg, (char *) ); |
---|
149 | static int pmsg(s) char *s; { printf("%s\n", s); return(0); } |
---|
150 | static int fmsg(s) char *s; { fatal(s); return(0); } |
---|
151 | #define XFATAL(s) return(what==W_COMMAND?pmsg(s):fmsg(s)) |
---|
152 | #else |
---|
153 | #define XFATAL fatal |
---|
154 | #endif /* NOICP */ |
---|
155 | |
---|
156 | VOID |
---|
157 | fatal2(msg1,msg2) char *msg1, *msg2; { |
---|
158 | char buf[256]; |
---|
159 | if (!msg1) msg1 = ""; |
---|
160 | if (!msg2) msg2 = ""; |
---|
161 | sprintf(buf,"\"%s\" - %s",msg1,msg2); |
---|
162 | #ifndef NOICP |
---|
163 | if (what == W_COMMAND) |
---|
164 | printf("%s\n",buf); |
---|
165 | else |
---|
166 | #endif /* NOICP */ |
---|
167 | fatal((char *)buf); |
---|
168 | } |
---|
169 | |
---|
170 | /* C M D L I N -- Get arguments from command line */ |
---|
171 | /* |
---|
172 | Simple Unix-style command line parser, conforming with 'A Proposed Command |
---|
173 | Syntax Standard for Unix Systems', Hemenway & Armitage, Unix/World, Vol.1, |
---|
174 | No.3, 1984. |
---|
175 | */ |
---|
176 | int |
---|
177 | cmdlin() { |
---|
178 | char x; /* Local general-purpose char */ |
---|
179 | |
---|
180 | cmarg = ""; /* Initialize globals */ |
---|
181 | cmarg2 = ""; |
---|
182 | action = 0; |
---|
183 | cflg = 0; |
---|
184 | |
---|
185 | debug(F111,"cmdlin",*xargv,xargc); |
---|
186 | |
---|
187 | /* If we were started directly from a Kermit application file, its name is */ |
---|
188 | /* in argv[1], so skip past it. */ |
---|
189 | |
---|
190 | debug(F101,"cmdlin cfilef","",cfilef); |
---|
191 | if (xargc > 1) { |
---|
192 | if (*xargv[1] != '-') { |
---|
193 | if (cfilef) { /* Command file found in prescan() */ |
---|
194 | xargc -= 1; /* Skip past it */ |
---|
195 | xargv += 1; |
---|
196 | cfilef = 0; |
---|
197 | } |
---|
198 | } |
---|
199 | } |
---|
200 | while (--xargc > 0) { /* Go through command line words */ |
---|
201 | xargv++; |
---|
202 | debug(F111,"xargv",*xargv,xargc); |
---|
203 | if (**xargv == '=') return(0); |
---|
204 | #ifdef VMS |
---|
205 | else if (**xargv == '/') continue; |
---|
206 | #endif /* VMS */ |
---|
207 | else if (**xargv == '-') { /* Got an option (begins with dash) */ |
---|
208 | x = *(*xargv+1); /* Get the option letter */ |
---|
209 | if (doarg(x) < 0) { |
---|
210 | #ifndef NOICP |
---|
211 | if (what == W_COMMAND) |
---|
212 | return(0); |
---|
213 | else |
---|
214 | #endif /* NOICP */ |
---|
215 | { |
---|
216 | #ifdef OS2 |
---|
217 | sleep(1); /* Give it a chance... */ |
---|
218 | #endif /* OS2 */ |
---|
219 | doexit(BAD_EXIT,1); /* Go handle option */ |
---|
220 | } |
---|
221 | } |
---|
222 | } else { /* No dash where expected */ |
---|
223 | fatal2(*xargv, |
---|
224 | #ifdef NT |
---|
225 | "invalid command-line option, type \"k95 -h\" for help" |
---|
226 | #else |
---|
227 | #ifdef OS2 |
---|
228 | "invalid command-line option, type \"ckermit -h\" for help" |
---|
229 | #else |
---|
230 | "invalid command-line option, type \"kermit -h\" for help" |
---|
231 | #endif /* OS2 */ |
---|
232 | #endif /* NT */ |
---|
233 | ); |
---|
234 | } |
---|
235 | } |
---|
236 | debug(F101,"action","",action); |
---|
237 | #ifndef NOLOCAL |
---|
238 | if (!local) { |
---|
239 | if ((action == 'c') || (cflg != 0)) { |
---|
240 | XFATAL("-l or -j or -X required"); |
---|
241 | } |
---|
242 | } |
---|
243 | #endif /* NOLOCAL */ |
---|
244 | if (*cmarg2 != 0) { |
---|
245 | if ((action != 's') && (action != 'r') && (action != 'v')) { |
---|
246 | XFATAL("-a without -s, -r, or -g"); |
---|
247 | } |
---|
248 | if (action == 'r' || action == 'v') { |
---|
249 | #ifdef CK_TMPDIR |
---|
250 | if (isdir(cmarg2)) { /* -a is a directory */ |
---|
251 | if (!zchdir(cmarg2)) { /* try to change to it */ |
---|
252 | XFATAL("can't change to '-a' directory"); |
---|
253 | } else cmarg2 = ""; |
---|
254 | } else |
---|
255 | #endif /* CK_TMPDIR */ |
---|
256 | if (zchko(cmarg2) < 0) { |
---|
257 | XFATAL("write access to -a file denied"); |
---|
258 | } |
---|
259 | } |
---|
260 | } |
---|
261 | if ((action == 'v') && (stdouf) && (!local)) { |
---|
262 | if (is_a_tty(1)) { |
---|
263 | XFATAL("unredirected -k can only be used in local mode"); |
---|
264 | } |
---|
265 | } |
---|
266 | if ((action == 's') || (action == 'v') || |
---|
267 | (action == 'r') || (action == 'x')) { |
---|
268 | if (local) |
---|
269 | displa = 1; |
---|
270 | if (stdouf) { |
---|
271 | displa = 0; |
---|
272 | quiet = 1; |
---|
273 | } |
---|
274 | } |
---|
275 | if (quiet) displa = 0; /* No display if quiet requested */ |
---|
276 | return(action); /* Then do any requested protocol */ |
---|
277 | } |
---|
278 | |
---|
279 | /* D O A R G -- Do a command-line argument. */ |
---|
280 | |
---|
281 | int |
---|
282 | #ifdef CK_ANSIC |
---|
283 | doarg(char x) |
---|
284 | #else |
---|
285 | doarg(x) char x; |
---|
286 | #endif /* CK_ANSIC */ |
---|
287 | /* doarg */ { |
---|
288 | int i, n, y, z, xx; long zz; char *xp; |
---|
289 | |
---|
290 | #ifdef NETCONN |
---|
291 | #define YYBUFLEN 256 |
---|
292 | char tmpbuf[YYBUFLEN+1]; /* Local storage for network things */ |
---|
293 | char line[YYBUFLEN+1]; |
---|
294 | #endif /* NETCONN */ |
---|
295 | |
---|
296 | xp = *xargv+1; /* Pointer for bundled args */ |
---|
297 | debug(F111,"doarg entry",xp,xargc); |
---|
298 | while (x) { |
---|
299 | debug(F000,"doarg arg","",x); |
---|
300 | switch (x) { |
---|
301 | |
---|
302 | #ifndef NOSPL |
---|
303 | case 'C': /* Commands for parser */ |
---|
304 | xargv++, xargc--; |
---|
305 | if ((xargc < 1) || (**xargv == '-')) { |
---|
306 | XFATAL("No commands given for -C"); |
---|
307 | } |
---|
308 | clcmds = *xargv; /* Get the argument (must be quoted) */ |
---|
309 | break; |
---|
310 | #endif /* NOSPL */ |
---|
311 | |
---|
312 | case 'D': /* Delay */ |
---|
313 | if (*(xp+1)) { |
---|
314 | XFATAL("invalid argument bundling"); |
---|
315 | } |
---|
316 | xargv++, xargc--; |
---|
317 | if ((xargc < 1) || (**xargv == '-')) { |
---|
318 | XFATAL("missing delay value"); |
---|
319 | } |
---|
320 | z = atoi(*xargv); /* Convert to number */ |
---|
321 | if (z > -1) /* If in range */ |
---|
322 | delay = z; /* set it */ |
---|
323 | else { |
---|
324 | XFATAL("bad delay value"); |
---|
325 | } |
---|
326 | break; |
---|
327 | |
---|
328 | case 'E': /* Exit on close */ |
---|
329 | #ifdef NETCONN |
---|
330 | tn_exit = 1; |
---|
331 | #endif /* NETCONN */ |
---|
332 | exitonclose = 1; |
---|
333 | break; |
---|
334 | |
---|
335 | #ifndef NOICP |
---|
336 | case 'S': /* "Stay" - enter interactive */ |
---|
337 | stayflg = 1; /* command parser after executing */ |
---|
338 | break; /* command-line actions. */ |
---|
339 | #endif /* NOICP */ |
---|
340 | |
---|
341 | case 'T': /* File transfer mode = text */ |
---|
342 | binary = XYFT_T; |
---|
343 | break; |
---|
344 | |
---|
345 | case 'Q': /* Quick (i.e. FAST) */ |
---|
346 | wslotr = 20; /* 20 window slots */ |
---|
347 | rpsiz = 94; /* 4K packets */ |
---|
348 | urpsiz = 4096; |
---|
349 | if (urpsiz > MAXSP) |
---|
350 | urpsiz = MAXSP; |
---|
351 | #ifdef CK_SPEED |
---|
352 | setprefix(PX_CAU); /* Cautious unprefixing */ |
---|
353 | #endif /* CK_SPEED */ |
---|
354 | break; |
---|
355 | |
---|
356 | case 'R': /* Remote-Only */ |
---|
357 | break; /* This is handled in prescan(). */ |
---|
358 | |
---|
359 | #ifndef NOSERVER |
---|
360 | case 'x': /* server */ |
---|
361 | if (action) { |
---|
362 | XFATAL("conflicting actions"); |
---|
363 | } |
---|
364 | action = 'x'; |
---|
365 | break; |
---|
366 | #endif /* NOSERVER */ |
---|
367 | |
---|
368 | case 'f': /* finish */ |
---|
369 | if (action) { |
---|
370 | XFATAL("conflicting actions"); |
---|
371 | } |
---|
372 | action = setgen('F',"","",""); |
---|
373 | break; |
---|
374 | |
---|
375 | case 'r': { /* receive */ |
---|
376 | if (action) { |
---|
377 | XFATAL("conflicting actions"); |
---|
378 | } |
---|
379 | action = 'v'; |
---|
380 | break; |
---|
381 | } |
---|
382 | case 'k': /* receive to stdout */ |
---|
383 | if (action) { |
---|
384 | XFATAL("conflicting actions"); |
---|
385 | } |
---|
386 | stdouf = 1; |
---|
387 | action = 'v'; |
---|
388 | break; |
---|
389 | |
---|
390 | case 's': /* send */ |
---|
391 | if (action) { |
---|
392 | XFATAL("conflicting actions"); |
---|
393 | } |
---|
394 | if (*(xp+1)) { |
---|
395 | XFATAL("invalid argument bundling after -s"); |
---|
396 | } |
---|
397 | nfils = 0; /* Initialize file counter */ |
---|
398 | z = 0; /* Flag for stdin */ |
---|
399 | cmlist = xargv + 1; /* Remember this pointer */ |
---|
400 | while (--xargc > 0) { /* Traverse the list */ |
---|
401 | xargv++; |
---|
402 | if (**xargv == '-') { /* Check for sending stdin */ |
---|
403 | if (strcmp(*xargv,"-") != 0) /* Watch out for next option. */ |
---|
404 | break; |
---|
405 | z++; /* "-" alone means send from stdin. */ |
---|
406 | } else if (zchki(*xargv) > -1) { /* Check if file exists */ |
---|
407 | nfils++; /* Bump file counter */ |
---|
408 | } else if (iswild(*xargv) && zxpand(*xargv) > 0) { |
---|
409 | /* or contains wildcard characters matching real files */ |
---|
410 | nfils++; |
---|
411 | } |
---|
412 | } |
---|
413 | xargc++, xargv--; /* Adjust argv/argc */ |
---|
414 | if (nfils < 1 && z == 0) { |
---|
415 | #ifdef VMS |
---|
416 | XFATAL("%CKERMIT-E-SEARCHFAIL, no files for -s"); |
---|
417 | #else |
---|
418 | XFATAL("No files for -s"); |
---|
419 | #endif /* VMS */ |
---|
420 | } |
---|
421 | if (z > 1) { |
---|
422 | XFATAL("-s: too many -'s"); |
---|
423 | } |
---|
424 | if (z == 1 && nfils > 0) { |
---|
425 | XFATAL("invalid mixture of filenames and '-' in -s"); |
---|
426 | } |
---|
427 | debug(F101,"doarg s nfils","",nfils); |
---|
428 | debug(F101,"doarg s z","",z); |
---|
429 | if (nfils == 0) { |
---|
430 | if (is_a_tty(0)) { /* (used to be is_a_tty(1) - why?) */ |
---|
431 | XFATAL("sending from terminal not allowed"); |
---|
432 | } else stdinf = 1; |
---|
433 | } |
---|
434 | debug(F101,"doarg s stdinf","",stdinf); |
---|
435 | debug(F101,*xargv,"",nfils); |
---|
436 | action = 's'; |
---|
437 | break; |
---|
438 | |
---|
439 | case 'g': /* get */ |
---|
440 | if (action) { |
---|
441 | XFATAL("conflicting actions"); |
---|
442 | } |
---|
443 | if (*(xp+1)) { |
---|
444 | XFATAL("invalid argument bundling after -g"); |
---|
445 | } |
---|
446 | xargv++, xargc--; |
---|
447 | if ((xargc == 0) || (**xargv == '-')) { |
---|
448 | XFATAL("missing filename for -g"); |
---|
449 | } |
---|
450 | cmarg = *xargv; |
---|
451 | action = 'r'; |
---|
452 | break; |
---|
453 | |
---|
454 | #ifndef NOLOCAL |
---|
455 | case 'c': /* connect before */ |
---|
456 | cflg = 1; |
---|
457 | break; |
---|
458 | |
---|
459 | case 'n': /* connect after */ |
---|
460 | cnflg = 1; |
---|
461 | break; |
---|
462 | #endif /* NOLOCAL */ |
---|
463 | |
---|
464 | case 'h': /* help */ |
---|
465 | usage(); |
---|
466 | #ifndef NOICP |
---|
467 | if (stayflg || what == W_COMMAND) |
---|
468 | break; |
---|
469 | else |
---|
470 | #endif /* NOICP */ |
---|
471 | doexit(GOOD_EXIT,-1); |
---|
472 | |
---|
473 | case 'a': /* "as" */ |
---|
474 | if (*(xp+1)) { |
---|
475 | XFATAL("invalid argument bundling after -a"); |
---|
476 | } |
---|
477 | xargv++, xargc--; |
---|
478 | if ((xargc < 1) || (**xargv == '-')) { |
---|
479 | XFATAL("missing name in -a"); |
---|
480 | } |
---|
481 | cmarg2 = *xargv; |
---|
482 | break; |
---|
483 | |
---|
484 | #ifndef NOICP |
---|
485 | case 'Y': /* No initialization file */ |
---|
486 | noinit = 1; |
---|
487 | break; |
---|
488 | |
---|
489 | case 'y': /* Alternate init-file name */ |
---|
490 | if (*(xp+1)) { |
---|
491 | XFATAL("invalid argument bundling after -y"); |
---|
492 | } |
---|
493 | xargv++, xargc--; |
---|
494 | if (xargc < 1) { |
---|
495 | XFATAL("missing filename in -y"); |
---|
496 | } |
---|
497 | /* strcpy(kermrc,*xargv); ...this was already done in prescan()... */ |
---|
498 | break; |
---|
499 | #endif /* NOICP */ |
---|
500 | |
---|
501 | #ifndef NOLOCAL |
---|
502 | case 'l': /* SET LINE */ |
---|
503 | #ifdef NETCONN |
---|
504 | #ifdef ANYX25 |
---|
505 | case 'X': /* SET HOST to X.25 address */ |
---|
506 | #ifdef SUNX25 |
---|
507 | case 'Z': /* SET HOST to X.25 file descriptor */ |
---|
508 | #endif /* SUNX25 */ |
---|
509 | #endif /* ANYX25 */ |
---|
510 | #ifdef TCPSOCKET |
---|
511 | case 'J': |
---|
512 | case 'j': /* SET HOST (TCP/IP socket) */ |
---|
513 | #endif /* TCPSOCKET */ |
---|
514 | #endif /* NETCONN */ |
---|
515 | network = 0; |
---|
516 | if (*(xp+1)) { |
---|
517 | XFATAL("invalid argument bundling after -l or -j"); |
---|
518 | } |
---|
519 | xargv++, xargc--; |
---|
520 | if ((xargc < 1) || (**xargv == '-')) { |
---|
521 | XFATAL("communication line device name missing"); |
---|
522 | } |
---|
523 | #ifdef NETCONN |
---|
524 | if (x == 'J') { |
---|
525 | cflg = 1; /* Connect */ |
---|
526 | stayflg = 1; /* Stay */ |
---|
527 | tn_exit = 1; /* Telnet-like exit condition */ |
---|
528 | } |
---|
529 | #endif /* NETCONN */ |
---|
530 | strcpy(ttname,*xargv); |
---|
531 | local = (strcmp(ttname,CTTNAM) != 0); |
---|
532 | /* |
---|
533 | NOTE: We really do not need to call ttopen here, since it should be called |
---|
534 | again later, automatically, when we first try to condition the device via |
---|
535 | ttpkt or ttvt. Calling ttopen here has the bad side effect of making the |
---|
536 | order of the -b and -l options significant, but order of command-line options |
---|
537 | should not matter. However, the network cases immediately below complicate |
---|
538 | matters a bit, so we'll settle this in a future edit. |
---|
539 | */ |
---|
540 | if (x == 'l') { |
---|
541 | if (ttopen(ttname,&local,mdmtyp,0) < 0) { |
---|
542 | XFATAL("can't open device"); |
---|
543 | } |
---|
544 | debug(F101,"cmdlin speed","",speed); |
---|
545 | speed = ttgspd(); /* get it. */ |
---|
546 | #ifdef NETCONN |
---|
547 | } else { |
---|
548 | if (x == 'j' || x == 'J') { /* IP network host name */ |
---|
549 | char * s = line; |
---|
550 | char * service = tmpbuf; |
---|
551 | if (xargc > 0) { /* Check if it's followed by */ |
---|
552 | /* A service name or number */ |
---|
553 | if (*(xargv+1) && *(*(xargv+1)) != '-') { |
---|
554 | xargv++, xargc--; |
---|
555 | strcat(ttname,":"); |
---|
556 | strcat(ttname,*xargv); |
---|
557 | } |
---|
558 | } |
---|
559 | nettype = NET_TCPB; |
---|
560 | mdmtyp = -nettype; /* Perhaps already set in init file */ |
---|
561 | telnetfd = 1; /* Or maybe an open file descriptor */ |
---|
562 | |
---|
563 | strncpy(line, ttname, YYBUFLEN); /* Working copy of the name */ |
---|
564 | for (s = line; *s != '\0' && *s != ':'; s++); /* and service */ |
---|
565 | if (*s) { |
---|
566 | *s++ = '\0'; |
---|
567 | strncpy(service, s, YYBUFLEN); |
---|
568 | } else *service = '\0'; |
---|
569 | s = line; |
---|
570 | #ifndef NODIAL |
---|
571 | #ifndef NOICP |
---|
572 | /* Look up in network directory */ |
---|
573 | x = 0; |
---|
574 | if (*s == '=') { /* If number starts with = sign */ |
---|
575 | s++; /* strip it */ |
---|
576 | while (*s == SP) /* and also any leading spaces */ |
---|
577 | s++; |
---|
578 | strncpy(line,s,YYBUFLEN); /* Do this again. */ |
---|
579 | nhcount = 0; |
---|
580 | } else if (!isdigit(line[0])) { |
---|
581 | /* |
---|
582 | nnetdir will be greater than 0 if the init file has been processed and it |
---|
583 | contained a SET NETWORK DIRECTORY command. |
---|
584 | */ |
---|
585 | xx = 0; /* Initialize this */ |
---|
586 | if (nnetdir > 0) /* If there is a directory... */ |
---|
587 | xx = lunet(line); /* Look up the name */ |
---|
588 | else /* If no directory */ |
---|
589 | nhcount = 0; /* we didn't find anything there */ |
---|
590 | if (xx < 0) { /* Lookup error: */ |
---|
591 | sprintf(tmpbuf, |
---|
592 | "?Fatal network directory lookup error - %s\n", |
---|
593 | line |
---|
594 | ); |
---|
595 | XFATAL(tmpbuf); |
---|
596 | } |
---|
597 | } |
---|
598 | #endif /* NOICP */ |
---|
599 | #endif /* NODIAL */ |
---|
600 | /* Add service to line specification for ttopen() */ |
---|
601 | if (*service) { /* There is a service specified */ |
---|
602 | strcat(line, ":"); |
---|
603 | strcat(line, service); |
---|
604 | } else { |
---|
605 | strcat(line, ":telnet"); |
---|
606 | } |
---|
607 | |
---|
608 | #ifndef NOICP |
---|
609 | #ifndef NODIAL |
---|
610 | if ((nhcount > 1) && !quiet && !backgrd) { |
---|
611 | printf("%d entr%s found for \"%s\"%s\n", |
---|
612 | nhcount, |
---|
613 | (nhcount == 1) ? "y" : "ies", |
---|
614 | s, |
---|
615 | (nhcount > 0) ? ":" : "." |
---|
616 | ); |
---|
617 | for (i = 0; i < nhcount; i++) |
---|
618 | printf("%3d. %s %-12s => %s\n", |
---|
619 | i+1, n_name, nh_p2[i], nh_p[i] |
---|
620 | ); |
---|
621 | } |
---|
622 | if (nhcount == 0) |
---|
623 | n = 1; |
---|
624 | else |
---|
625 | n = nhcount; |
---|
626 | #else |
---|
627 | n = 1; |
---|
628 | nhcount = 0; |
---|
629 | #endif /* NODIAL */ |
---|
630 | for (i = 0; i < n; i++) { |
---|
631 | #ifndef NODIAL |
---|
632 | if (nhcount >= 1) { |
---|
633 | strcpy(line,nh_p[i]); /* Copy the current entry to line */ |
---|
634 | /* Check to see if the network entry contains a service */ |
---|
635 | for ( s = line ; (*s != '\0') && (*s != ':'); s++) |
---|
636 | ; |
---|
637 | /* If directory does not have a service ... */ |
---|
638 | if (!*s && *service) { /* and the user specified one */ |
---|
639 | strcat(line, ":"); |
---|
640 | strcat(line, service); |
---|
641 | } |
---|
642 | if (lookup(netcmd,nh_p2[i],nnets,&z) > -1) { |
---|
643 | mdmtyp = 0 - netcmd[z].kwval; |
---|
644 | } else { |
---|
645 | printf("Error - network type \"%s\" not supported\n", |
---|
646 | nh_p2[i] |
---|
647 | ); |
---|
648 | continue; |
---|
649 | } |
---|
650 | } |
---|
651 | #endif /* NODIAL */ |
---|
652 | } |
---|
653 | #endif /* NOICP */ |
---|
654 | strcpy(ttname, line); |
---|
655 | #ifdef SUNX25 |
---|
656 | } else if (x == 'X') { /* X.25 address */ |
---|
657 | nettype = NET_SX25; |
---|
658 | mdmtyp = -nettype; |
---|
659 | } else if (x == 'Z') { /* Open X.25 file descriptor */ |
---|
660 | nettype = NET_SX25; |
---|
661 | mdmtyp = -nettype; |
---|
662 | x25fd = 1; |
---|
663 | #endif /* SUNX25 */ |
---|
664 | #ifdef STRATUSX25 |
---|
665 | } else if (x == 'X') { /* X.25 address */ |
---|
666 | nettype = NET_VX25; |
---|
667 | mdmtyp = -nettype; |
---|
668 | #endif /* STRATUSX25 */ |
---|
669 | } |
---|
670 | if (ttopen(ttname,&local,mdmtyp,0) < 0) { |
---|
671 | XFATAL("can't open host connection"); |
---|
672 | } |
---|
673 | network = 1; |
---|
674 | #endif /* NETCONN */ |
---|
675 | } |
---|
676 | /* add more here later - decnet, etc... */ |
---|
677 | break; |
---|
678 | |
---|
679 | #ifdef ANYX25 |
---|
680 | case 'U': /* X.25 call user data */ |
---|
681 | if (*(xp+1)) { |
---|
682 | XFATAL("invalid argument bundling"); |
---|
683 | } |
---|
684 | xargv++, xargc--; |
---|
685 | if ((xargc < 1) || (**xargv == '-')) { |
---|
686 | XFATAL("missing call user data string"); |
---|
687 | } |
---|
688 | strcpy(udata,*xargv); |
---|
689 | if ((int)strlen(udata) <= MAXCUDATA) { |
---|
690 | cudata = 1; |
---|
691 | } else { |
---|
692 | XFATAL("Invalid call user data"); |
---|
693 | } |
---|
694 | break; |
---|
695 | |
---|
696 | case 'o': /* X.25 closed user group */ |
---|
697 | if (*(xp+1)) { |
---|
698 | XFATAL("invalid argument bundling"); |
---|
699 | } |
---|
700 | xargv++, xargc--; |
---|
701 | if ((xargc < 1) || (**xargv == '-')) { |
---|
702 | XFATAL("missing closed user group index"); |
---|
703 | } |
---|
704 | z = atoi(*xargv); /* Convert to number */ |
---|
705 | if (z >= 0 && z <= 99) { |
---|
706 | closgr = z; |
---|
707 | } else { |
---|
708 | XFATAL("Invalid closed user group index"); |
---|
709 | } |
---|
710 | break; |
---|
711 | |
---|
712 | case 'u': /* X.25 reverse charge call */ |
---|
713 | revcall = 1; |
---|
714 | break; |
---|
715 | #endif /* ANYX25 */ |
---|
716 | #endif /* NOLOCAL */ |
---|
717 | |
---|
718 | case 'b': /* Bits-per-second for serial device */ |
---|
719 | if (*(xp+1)) { |
---|
720 | XFATAL("invalid argument bundling"); |
---|
721 | } |
---|
722 | xargv++, xargc--; |
---|
723 | if ((xargc < 1) || (**xargv == '-')) { |
---|
724 | XFATAL("missing bps"); |
---|
725 | } |
---|
726 | zz = atol(*xargv); /* Convert to long int */ |
---|
727 | i = zz / 10L; |
---|
728 | #ifndef NOLOCAL |
---|
729 | if (ttsspd(i) > -1) /* Check and set it */ |
---|
730 | #endif /* NOLOCAL */ |
---|
731 | speed = ttgspd(); /* and read it back. */ |
---|
732 | #ifndef NOLOCAL |
---|
733 | else { |
---|
734 | XFATAL("unsupported transmission rate"); |
---|
735 | } |
---|
736 | #endif /* NOLOCAL */ |
---|
737 | break; |
---|
738 | |
---|
739 | #ifndef NODIAL |
---|
740 | #ifndef NOICP |
---|
741 | case 'm': /* Modem type */ |
---|
742 | if (*(xp+1)) { |
---|
743 | XFATAL("invalid argument bundling after -m"); |
---|
744 | } |
---|
745 | xargv++, xargc--; |
---|
746 | if ((xargc < 1) || (**xargv == '-')) { |
---|
747 | XFATAL("modem type missing"); |
---|
748 | } |
---|
749 | y = lookup(mdmtab,*xargv,nmdm,&z); |
---|
750 | if (y < 0) { |
---|
751 | XFATAL("unknown modem type"); |
---|
752 | } |
---|
753 | usermdm = 0; |
---|
754 | usermdm = (y == dialudt) ? x : 0; |
---|
755 | initmdm(y); |
---|
756 | break; |
---|
757 | #endif /* NOICP */ |
---|
758 | #endif /* NODIAL */ |
---|
759 | |
---|
760 | case 'e': /* Extended packet length */ |
---|
761 | if (*(xp+1)) { |
---|
762 | XFATAL("invalid argument bundling after -e"); |
---|
763 | } |
---|
764 | xargv++, xargc--; |
---|
765 | if ((xargc < 1) || (**xargv == '-')) { |
---|
766 | XFATAL("missing length"); |
---|
767 | } |
---|
768 | z = atoi(*xargv); /* Convert to number */ |
---|
769 | if (z > 10 && z <= maxrps) { |
---|
770 | rpsiz = urpsiz = z; |
---|
771 | if (z > 94) rpsiz = 94; /* Fallback if other Kermit can't */ |
---|
772 | } else { |
---|
773 | XFATAL("Unsupported packet length"); |
---|
774 | } |
---|
775 | break; |
---|
776 | |
---|
777 | case 'v': /* Vindow size */ |
---|
778 | if (*(xp+1)) { |
---|
779 | XFATAL("invalid argument bundling"); |
---|
780 | } |
---|
781 | xargv++, xargc--; |
---|
782 | if ((xargc < 1) || (**xargv == '-')) { |
---|
783 | XFATAL("missing or bad window size"); |
---|
784 | } |
---|
785 | z = atoi(*xargv); /* Convert to number */ |
---|
786 | if (z < 32) { /* If in range */ |
---|
787 | wslotr = z; /* set it */ |
---|
788 | if (z > 1) swcapr = 1; /* Set capas bit if windowing */ |
---|
789 | } else { |
---|
790 | XFATAL("Unsupported packet length"); |
---|
791 | } |
---|
792 | break; |
---|
793 | |
---|
794 | case 'i': /* Treat files as binary */ |
---|
795 | binary = XYFT_B; |
---|
796 | break; |
---|
797 | |
---|
798 | case 'w': /* Writeover */ |
---|
799 | warn = 0; |
---|
800 | fncact = XYFX_X; |
---|
801 | break; |
---|
802 | |
---|
803 | case 'q': /* Quiet */ |
---|
804 | quiet = 1; |
---|
805 | break; |
---|
806 | |
---|
807 | #ifdef DEBUG |
---|
808 | case 'd': /* DEBUG */ |
---|
809 | break; /* Handled in prescan() */ |
---|
810 | #endif /* DEBUG */ |
---|
811 | |
---|
812 | case '8': /* 8-bit clean */ |
---|
813 | parity = 0; |
---|
814 | cmdmsk = 0xff; |
---|
815 | cmask = 0xff; |
---|
816 | break; |
---|
817 | |
---|
818 | case 'p': /* SET PARITY */ |
---|
819 | if (*(xp+1)) { |
---|
820 | XFATAL("invalid argument bundling"); |
---|
821 | } |
---|
822 | xargv++, xargc--; |
---|
823 | if ((xargc < 1) || (**xargv == '-')) { |
---|
824 | XFATAL("missing parity"); |
---|
825 | } |
---|
826 | switch(x = **xargv) { |
---|
827 | case 'e': |
---|
828 | case 'o': |
---|
829 | case 'm': |
---|
830 | case 's': parity = x; break; |
---|
831 | case 'n': parity = 0; break; |
---|
832 | default: { XFATAL("invalid parity"); } |
---|
833 | } |
---|
834 | break; |
---|
835 | |
---|
836 | case 't': /* Line turnaround handshake */ |
---|
837 | turn = 1; |
---|
838 | turnch = XON; /* XON is turnaround character */ |
---|
839 | duplex = 1; /* Half duplex */ |
---|
840 | flow = 0; /* No flow control */ |
---|
841 | break; |
---|
842 | |
---|
843 | case 'B': |
---|
844 | bgset = 1; /* Force background (batch) */ |
---|
845 | backgrd = 1; |
---|
846 | break; |
---|
847 | |
---|
848 | case 'z': /* Force foreground */ |
---|
849 | bgset = 0; |
---|
850 | backgrd = 0; |
---|
851 | break; |
---|
852 | |
---|
853 | #ifndef NOSPL |
---|
854 | case 'M': /* My User Name */ |
---|
855 | /* Already done in prescan() */ |
---|
856 | if (*(xp+1)) { |
---|
857 | XFATAL("invalid argument bundling"); |
---|
858 | } |
---|
859 | xargv++, xargc--; |
---|
860 | if ((xargc < 1) || (**xargv == '-')) { |
---|
861 | XFATAL("missing username"); |
---|
862 | } |
---|
863 | #ifdef COMMENT |
---|
864 | if ((int)strlen(*xargv) > 63) { |
---|
865 | XFATAL("username too long"); |
---|
866 | } |
---|
867 | strcpy(uidbuf,*xargv); |
---|
868 | #endif /* COMMENT */ |
---|
869 | break; |
---|
870 | #endif /* NOSPL */ |
---|
871 | |
---|
872 | #ifdef CK_NETBIOS |
---|
873 | case 'N': /* NetBios Adapter Number follows */ |
---|
874 | if (*(xp+1)) { |
---|
875 | XFATAL("invalid argument bundling after -N"); |
---|
876 | } |
---|
877 | xargv++, xargc--; |
---|
878 | if ((xargc < 1) || (**xargv == '-')) { |
---|
879 | XFATAL("missing NetBios Adapter number"); |
---|
880 | } |
---|
881 | if ((strlen(*xargv) != 1) || |
---|
882 | (*xargv)[0] != 'X' || |
---|
883 | ((atoi(*xargv) < 0) || |
---|
884 | (atoi(*xargv) > 9)) ) { |
---|
885 | XFATAL("Invalid NetBios Adapter - Adapters 0 to 9 are valid"); |
---|
886 | } |
---|
887 | break; |
---|
888 | #endif /* CK_NETBIOS */ |
---|
889 | |
---|
890 | #ifdef NETCONN |
---|
891 | case 'F': |
---|
892 | network = 1; |
---|
893 | if (*(xp+1)) { |
---|
894 | XFATAL("invalid argument bundling after -F"); |
---|
895 | } |
---|
896 | xargv++, xargc--; |
---|
897 | if ((xargc < 1) || (**xargv == '-')) { |
---|
898 | XFATAL("network file descriptor missing"); |
---|
899 | } |
---|
900 | strcpy(ttname,*xargv); |
---|
901 | nettype = NET_TCPB; |
---|
902 | mdmtyp = -nettype; |
---|
903 | telnetfd = 1; |
---|
904 | local = 1; |
---|
905 | break; |
---|
906 | #endif /* NETCONN */ |
---|
907 | |
---|
908 | #ifdef OS2PM |
---|
909 | case 'P': /* OS/2 Presentation Manager */ |
---|
910 | if (*(xp+1)) { |
---|
911 | XFATAL("invalid argument bundling after -P"); |
---|
912 | } |
---|
913 | xargv++, xargc--; |
---|
914 | if ((xargc < 1) || (**xargv == '-')) { |
---|
915 | XFATAL("pipe data missing"); |
---|
916 | } |
---|
917 | pipedata = *xargv; |
---|
918 | break; |
---|
919 | #endif /* OS2PM */ |
---|
920 | |
---|
921 | #ifndef NOICP |
---|
922 | case 'H': |
---|
923 | noherald = 1; |
---|
924 | break; |
---|
925 | #endif /* NOICP */ |
---|
926 | |
---|
927 | #ifdef OS2 |
---|
928 | case 'W': |
---|
929 | if (*(xp+1)) { |
---|
930 | XFATAL("invalid argument bundling after -W"); |
---|
931 | } |
---|
932 | xargv++, xargc--; |
---|
933 | if ((xargc < 1)) { /* could be negative */ |
---|
934 | XFATAL("Window handle missing"); |
---|
935 | } |
---|
936 | xargv++, xargc--; |
---|
937 | if ((xargc < 1) || (**xargv == '-')) { |
---|
938 | XFATAL("Kermit Instance missing"); |
---|
939 | } |
---|
940 | /* Action done in prescan */ |
---|
941 | break; |
---|
942 | #endif /* OS2 */ |
---|
943 | |
---|
944 | default: |
---|
945 | fatal2(*xargv, |
---|
946 | #ifdef NT |
---|
947 | "invalid command-line option, type \"k95 -h\" for help" |
---|
948 | #else |
---|
949 | #ifdef OS2 |
---|
950 | "invalid command-line option, type \"ckermit -h\" for help" |
---|
951 | #else |
---|
952 | "invalid command-line option, type \"kermit -h\" for help" |
---|
953 | #endif /* OS2 */ |
---|
954 | #endif /* NT */ |
---|
955 | ); |
---|
956 | } |
---|
957 | |
---|
958 | x = *++xp; /* See if options are bundled */ |
---|
959 | } |
---|
960 | return(0); |
---|
961 | } |
---|
962 | #else /* No command-line interface... */ |
---|
963 | |
---|
964 | extern int xargc; |
---|
965 | int |
---|
966 | cmdlin() { |
---|
967 | if (xargc > 1) { |
---|
968 | XFATAL("Sorry, command-line options disabled."); |
---|
969 | } |
---|
970 | } |
---|
971 | #endif /* NOCMDL */ |
---|