|
|
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.