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