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