|
|
1.1 root 1: #ifndef NOCMDL
2: /* C K U U S Y -- "User Interface" for Unix Kermit, part Y */
3:
4: /* Command-Line Argument Parser */
5:
6: /*
7: Author: Frank da Cruz ([email protected], [email protected]),
8: Columbia University Center for Computing Activities.
9: First released January 1985.
10: Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
11: York. Permission is granted to any individual or institution to use this
12: software as long as it is not sold for profit. This copyright notice must be
13: retained. This software may not be included in commercial products without
14: written permission of Columbia University.
15: */
16:
17: #include "ckcdeb.h"
18: #include "ckcasc.h"
19: #include "ckcker.h"
20: #include "ckucmd.h"
21: #include "ckcnet.h"
22:
23: #ifdef NETCONN
24: #ifdef SUNX25
25: #include "ckcnet.h"
26: extern int revcall, closgr, cudata;
27: extern char udata[MAXCUDATA];
28: extern int x25fd;
29: #endif /* SUNX25 */
30: extern int telnetfd;
31: #endif /* NETCONN */
32:
33: extern char *ckxsys, *ckzsys, *cmarg, *cmarg2, **xargv, **cmlist, *clcmds;
34: extern int action, cflg, xargc, stdouf, stdinf, displa, cnflg, nfils,
35: local, quiet, escape, network, mdmtyp, maxrps, rpsiz, bgset, xargs,
36: urpsiz, wslotr, swcapr, binary, warn, parity, turn, turnch, duplex, flow,
37: fncact, clfils, noinit, stayflg, nettype;
38: extern long speed, ttgspd(), zchki();
39: extern char ttname[];
40:
41: #ifndef NODIAL
42: extern int nmdm;
43: extern struct keytab mdmtab[];
44: #endif /* NODIAL */
45:
46: /* C M D L I N -- Get arguments from command line */
47: /*
48: Simple Unix-style command line parser, conforming with 'A Proposed Command
49: Syntax Standard for Unix Systems', Hemenway & Armitage, Unix/World, Vol.1,
50: No.3, 1984.
51: */
52: int
53: cmdlin() {
54: char x; /* Local general-purpose int */
55: cmarg = ""; /* Initialize globals */
56: cmarg2 = "";
57: action = cflg = 0;
58:
59: /* If we were started directly from a Kermit application file, its name is */
60: /* in argv[1], so skip past it. */
61:
62: if (xargc > 1) {
63: if (*xargv[0] != '-' && *xargv[1] != '-') {
64: if (
65: /* some shells don't put full pathname... */
66: /* zchki(xargv[0]) > 0 && */ /* ...so skip this test */
67: zchki(xargv[1]) > 0) { /* if it's an existing file */
68: xargc -= 1; /* skip past it */
69: xargv += 1; /* ... */
70: }
71: }
72: }
73:
74: while (--xargc > 0) { /* Go through command line words */
75: xargv++;
76: debug(F111,"xargv",*xargv,xargc);
77: if (**xargv == '=') return(0);
78: #ifdef VMS
79: else if (**xargv == '/') continue;
80: #endif /* VMS */
81: else if (**xargv == '-') { /* Got an option (begins with dash) */
82: x = *(*xargv+1); /* Get the option letter */
83: if (doarg(x) < 0) doexit(BAD_EXIT,1); /* Go handle option */
84: } else { /* No dash where expected */
85: usage();
86: doexit(BAD_EXIT,1);
87: }
88: }
89: debug(F101,"action","",action);
90: if (!local) {
91: if ((action == 'c') || (cflg != 0))
92: fatal("-l and -b required");
93: }
94: if (*cmarg2 != 0) {
95: if ((action != 's') && (action != 'r') &&
96: (action != 'v'))
97: fatal("-a without -s, -r, or -g");
98: }
99: if ((action == 'v') && (stdouf) && (!local)) {
100: if (isatty(1))
101: fatal("unredirected -k can only be used in local mode");
102: }
103: if ((action == 's') || (action == 'v') ||
104: (action == 'r') || (action == 'x')) {
105: if (local) displa = 1;
106: if (stdouf) { displa = 0; quiet = 1; }
107: }
108:
109: if (quiet) displa = 0; /* No display if quiet requested */
110: return(action); /* Then do any requested protocol */
111: }
112:
113: /* D O A R G -- Do a command-line argument. */
114:
115: int
116: #ifdef CK_ANSIC
117: doarg(char x)
118: #else
119: doarg(x) char x;
120: #endif /* CK_ANSIC */
121: /* doarg */ {
122: int i, y, z; long zz; char *xp;
123:
124: xp = *xargv+1; /* Pointer for bundled args */
125: while (x) {
126: switch (x) {
127:
128: #ifndef NOSPL
129: case 'C': /* Commands for parser */
130: xargv++, xargc--;
131: if ((xargc < 1) || (**xargv == '-'))
132: fatal("No commands given for -C");
133: clcmds = *xargv; /* Get the argument (must be quoted) */
134: break;
135: #endif /* NOSPL */
136:
137: #ifndef NOICP
138: case 'S': /* "Stay" - enter interactive */
139: stayflg = 1; /* command parser after executing */
140: break; /* command-line actions. */
141: #endif /* NOICP */
142:
143: #ifndef NOSERVER
144: case 'x': /* server */
145: if (action) fatal("conflicting actions");
146: action = 'x';
147: break;
148: #endif /* NOSERVER */
149:
150: case 'f': /* finish */
151: if (action) fatal("conflicting actions");
152: action = setgen('F',"","","");
153: break;
154:
155: case 'r': /* receive */
156: if (action) fatal("conflicting actions");
157: action = 'v';
158: break;
159:
160: case 'k': /* receive to stdout */
161: if (action) fatal("conflicting actions");
162: stdouf = 1;
163: action = 'v';
164: break;
165:
166: case 's': /* send */
167: if (action) fatal("conflicting actions");
168: if (*(xp+1)) fatal("invalid argument bundling after -s");
169: nfils = z = 0; /* Initialize file counter, flag */
170: cmlist = xargv+1; /* Remember this pointer */
171: while (--xargc > 0) { /* Traverse the list */
172: xargv++;
173: if (**xargv == '-') { /* Check for sending stdin */
174: if (strcmp(*xargv,"-") != 0) /* Watch out for next option. */
175: break;
176: z++; /* "-" alone means send from stdin. */
177: } else if (zchki(*xargv) > -1 /* Check if file exists */
178: #ifndef UNIX
179: /* or contains wildcard characters matching real files */
180: || (iswild(*xargv) && zxpand(*xargv) > 0)
181: #endif /* UNIX */
182: ) {
183: nfils++; /* Bump file counter */
184: }
185: }
186: xargc++, xargv--; /* Adjust argv/argc */
187: if (nfils < 1 && z == 0)
188: #ifdef VMS
189: fatal("%CKERMIT-E-SEARCHFAIL, no files for -s");
190: #else
191: fatal("No files for -s");
192: #endif /* VMS */
193: if (z > 1) fatal("-s: too many -'s");
194: if (z == 1 && nfils > 0)
195: fatal("invalid mixture of filenames and '-' in -s");
196: if (nfils == 0) {
197: if (isatty(0)) fatal("sending from terminal not allowed");
198: else stdinf = 1;
199: }
200:
201: #ifdef COMMENT
202: /* If only one filespec was given, indicate "internal list" rather than */
203: /* "expanded list", so in case it includes wildcards, C-Kermit can */
204: /* expand them itself. */
205: if (nfils == 1) {
206: cmarg = *cmlist;
207: nfils = -1;
208: }
209: #endif /* COMMENT */
210:
211: debug(F101,*xargv,"",nfils);
212: action = 's';
213: #ifdef UNIX
214: /* When set, this flag tells Kermit not to expand wildcard characters. */
215: /* In UNIX, the shell has already expanded them. In VMS, OS/2, etc, */
216: /* Kermit must expand them. Kermit must not expand them in UNIX because */
217: /* a filename might itself contain metacharacters. Imagine, for example, */
218: /* what would happen if a directory contained a file named "*". */
219: clfils = 1; /* Flag for command-line files */
220: #endif /* UNIX */
221: break;
222:
223: case 'g': /* get */
224: if (action) fatal("conflicting actions");
225: if (*(xp+1)) fatal("invalid argument bundling after -g");
226: xargv++, xargc--;
227: if ((xargc == 0) || (**xargv == '-'))
228: fatal("missing filename for -g");
229: cmarg = *xargv;
230: action = 'r';
231: break;
232:
233: case 'c': /* connect before */
234: cflg = 1;
235: break;
236:
237: case 'n': /* connect after */
238: cnflg = 1;
239: break;
240:
241: case 'h': /* help */
242: usage();
243: #ifndef NOICP
244: if (stayflg)
245: break;
246: else
247: #endif /* NOICP */
248: doexit(GOOD_EXIT,-1);
249:
250: case 'a': /* "as" */
251: if (*(xp+1)) fatal("invalid argument bundling after -a");
252: xargv++, xargc--;
253: if ((xargc < 1) || (**xargv == '-'))
254: fatal("missing name in -a");
255: cmarg2 = *xargv;
256: break;
257:
258: #ifndef NOICP
259: case 'Y': /* No initialization file */
260: noinit = 1;
261: break;
262:
263: case 'y': /* Alternate init-file name */
264: if (*(xp+1)) fatal("invalid argument bundling after -y");
265: xargv++, xargc--;
266: if (xargc < 1) fatal("missing name in -y");
267: /* strcpy(kermrc,*xargv); ...this was already done in prescan()... */
268: break;
269: #endif /* NOICP */
270:
271: case 'l': /* set line */
272: #ifdef NETCONN
273: case 'X': /* set host to X.25 address */
274: case 'Z': /* set host to X.25 file descriptor */
275: case 'j': /* set host (TCP/IP socket) */
276: #endif /* NETCONN */
277: network = 0;
278: if (*(xp+1)) fatal("invalid argument bundling after -l or -j");
279: xargv++, xargc--;
280: if ((xargc < 1) || (**xargv == '-'))
281: fatal("communication line device name missing");
282: strcpy(ttname,*xargv);
283: local = (strcmp(ttname,CTTNAM) != 0);
284: if (x == 'l') {
285: if (ttopen(ttname,&local,mdmtyp,0) < 0)
286: fatal("can't open device");
287: debug(F101,"cmdlin speed","",speed);
288: #ifdef COMMENT
289: /* What can it hurt? */
290: if (speed < 0L) /* If speed hasn't been set yet, */
291: #endif /* COMMENT */
292: speed = ttgspd(); /* get it. */
293: #ifdef NETCONN
294: } else {
295: if (x == 'j') { /* IP network host name */
296: mdmtyp = -nettype; /* perhaps alread set in init file */
297: telnetfd = 1; /* Or maybe an open file descriptor */
298: #ifdef SUNX25
299: } else if (x == 'X') { /* X.25 address */
300: mdmtyp = 0 - NET_SX25;
301: } else if (x == 'Z') { /* Open X.25 file descriptor */
302: mdmtyp = 0 - NET_SX25;
303: x25fd = 1;
304: #endif /* SUNX25 */
305: }
306: if (ttopen(ttname,&local,mdmtyp,0) < 0)
307: fatal("can't open host connection");
308: network = 1;
309: #endif /* NETCONN */
310: }
311: /* add more here later - decnet, etc... */
312: break;
313:
314: #ifdef SUNX25
315: case 'U': /* X.25 call user data */
316: if (*(xp+1)) fatal("invalid argument bundling");
317: xargv++, xargc--;
318: if ((xargc < 1) || (**xargv == '-'))
319: fatal("missing call user data string");
320: strcpy(udata,*xargv);
321: if ((int)strlen(udata) <= MAXCUDATA) cudata = 1;
322: else fatal("Invalid call user data");
323: break;
324:
325: case 'o': /* X.25 closed user group */
326: if (*(xp+1)) fatal("invalid argument bundling");
327: xargv++, xargc--;
328: if ((xargc < 1) || (**xargv == '-'))
329: fatal("missing closed user group index");
330: z = atoi(*xargv); /* Convert to number */
331: if (z >= 0 && z <= 99) closgr = z;
332: else fatal("Invalid closed user group index");
333: break;
334:
335: case 'u': /* X.25 reverse charge call */
336: revcall = 1;
337: break;
338: #endif /* SUNX25 */
339:
340: case 'b': /* set bits-per-second for serial */
341: if (*(xp+1)) fatal("invalid argument bundling"); /* communication device */
342: xargv++, xargc--;
343: if ((xargc < 1) || (**xargv == '-'))
344: fatal("missing baud");
345: zz = atol(*xargv); /* Convert to long int */
346: i = zz / 10L;
347: if (ttsspd(i) > -1) /* Check and set it */
348: speed = zz;
349: else
350: fatal("unsupported transmission rate");
351: break;
352:
353: #ifndef NODIAL
354: case 'm': /* Modem type */
355: if (*(xp+1)) fatal("invalid argument bundling after -m");
356: xargv++, xargc--;
357: if ((xargc < 1) || (**xargv == '-'))
358: fatal("modem type missing");
359: y = lookup(mdmtab,*xargv,nmdm,&z);
360: if (y < 0)
361: fatal("unknown modem type");
362: mdmtyp = y;
363: break;
364: #endif
365:
366: case 'e': /* Extended packet length */
367: if (*(xp+1)) fatal("invalid argument bundling after -e");
368: xargv++, xargc--;
369: if ((xargc < 1) || (**xargv == '-'))
370: fatal("missing length");
371: z = atoi(*xargv); /* Convert to number */
372: if (z > 10 && z <= maxrps) {
373: rpsiz = urpsiz = z;
374: if (z > 94) rpsiz = 94; /* Fallback if other Kermit can't */
375: } else fatal("Unsupported packet length");
376: break;
377:
378: case 'v': /* Vindow size */
379: if (*(xp+1)) fatal("invalid argument bundling");
380: xargv++, xargc--;
381: if ((xargc < 1) || (**xargv == '-'))
382: fatal("missing or bad window size");
383: z = atoi(*xargv); /* Convert to number */
384: if (z < 32) { /* If in range */
385: wslotr = z; /* set it */
386: if (z > 1) swcapr = 1; /* Set capas bit if windowing */
387: } else fatal("Unsupported packet length");
388: break;
389:
390: case 'i': /* Treat files as binary */
391: binary = 1;
392: break;
393:
394: case 'w': /* Writeover */
395: warn = 0;
396: fncact = XYFX_X;
397: break;
398:
399: case 'q': /* Quiet */
400: quiet = 1;
401: break;
402:
403: #ifdef DEBUG
404: case 'd': /* debug */
405: /** debopn("debug.log"); *** already did this in prescan() **/
406: break;
407: #endif /* DEBUG */
408:
409: case 'p': /* set parity */
410: if (*(xp+1)) fatal("invalid argument bundling");
411: xargv++, xargc--;
412: if ((xargc < 1) || (**xargv == '-'))
413: fatal("missing parity");
414: switch(x = **xargv) {
415: case 'e':
416: case 'o':
417: case 'm':
418: case 's': parity = x; break;
419: case 'n': parity = 0; break;
420: default: fatal("invalid parity");
421: }
422: break;
423:
424: case 't':
425: turn = 1; /* Line turnaround handshake */
426: turnch = XON; /* XON is turnaround character */
427: duplex = 1; /* Half duplex */
428: flow = 0; /* No flow control */
429: break;
430:
431: case 'z': /* Not background */
432: bgset = 0;
433: break;
434:
435: default:
436: fatal("invalid argument, type 'kermit -h' for help");
437: }
438:
439: x = *++xp; /* See if options are bundled */
440: }
441: return(0);
442: }
443: #else /* No command-line interface... */
444:
445: extern int xargc;
446: int
447: cmdlin() {
448: if (xargc > 1) printf("Sorry, command-line options disabled.\n");
449: return(0);
450: }
451: #endif /* NOCMDL */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.