home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / old / ckermit5a188 / ckuusy.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  13KB  |  455 lines

  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 (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
  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. #ifndef VMS
  31. extern
  32. #endif /* VMS */
  33.  int telnetfd;
  34. #endif /* NETCONN */
  35.  
  36. extern char *ckxsys, *ckzsys, *cmarg, *cmarg2, **xargv, **cmlist, *clcmds;
  37. extern int action, cflg, xargc, stdouf, stdinf, displa, cnflg, nfils,
  38.   local, quiet, escape, network, mdmtyp, maxrps, rpsiz, bgset, xargs,
  39.   urpsiz, wslotr, swcapr, binary, warn, parity, turn, turnch, duplex, flow,
  40.   fncact, clfils, noinit, stayflg, nettype;
  41. extern long speed, ttgspd(), zchki();
  42. extern char ttname[];
  43.  
  44. #ifndef NODIAL
  45. extern int nmdm;
  46. extern struct keytab mdmtab[];
  47. #endif /* NODIAL */
  48.  
  49. /*  C M D L I N  --  Get arguments from command line  */
  50. /*
  51.  Simple Unix-style command line parser, conforming with 'A Proposed Command
  52.  Syntax Standard for Unix Systems', Hemenway & Armitage, Unix/World, Vol.1,
  53.  No.3, 1984.
  54. */
  55. int
  56. cmdlin() {
  57.     char x;                /* Local general-purpose int */
  58.     cmarg = "";                /* Initialize globals */
  59.     cmarg2 = "";
  60.     action = cflg = 0;
  61.  
  62. /* If we were started directly from a Kermit application file, its name is */
  63. /* in argv[1], so skip past it. */
  64.  
  65.     if (xargc > 1) {
  66.     if (*xargv[0] != '-' && *xargv[1] != '-') {
  67.         if (
  68.         /* some shells don't put full pathname... */
  69.         /* zchki(xargv[0]) > 0 && */ /* ...so skip this test */
  70.         zchki(xargv[1]) > 0) {    /* if it's an existing file */
  71.         xargc -= 1;        /* skip past it */
  72.         xargv += 1;        /* ... */
  73.         }
  74.     }
  75.     }
  76.  
  77.     while (--xargc > 0) {        /* Go through command line words */
  78.     xargv++;
  79.     debug(F111,"xargv",*xargv,xargc);
  80.     if (**xargv == '=') return(0);
  81. #ifdef VMS
  82.     else if (**xargv == '/') continue;
  83. #endif /* VMS */
  84.         else if (**xargv == '-') {    /* Got an option (begins with dash) */
  85.         x = *(*xargv+1);        /* Get the option letter */
  86.         if (doarg(x) < 0) doexit(BAD_EXIT,1); /* Go handle option */
  87.         } else {            /* No dash where expected */
  88.         usage();
  89.         doexit(BAD_EXIT,1);
  90.     }
  91.     }
  92.     debug(F101,"action","",action);
  93.     if (!local) {
  94.     if ((action == 'c') || (cflg != 0))
  95.         fatal("-l and -b required");
  96.     }
  97.     if (*cmarg2 != 0) {
  98.     if ((action != 's') && (action != 'r') &&
  99.         (action != 'v'))
  100.         fatal("-a without -s, -r, or -g");
  101.     }
  102.     if ((action == 'v') && (stdouf) && (!local)) {
  103.         if (isatty(1))
  104.         fatal("unredirected -k can only be used in local mode");
  105.     }
  106.     if ((action == 's') || (action == 'v') ||
  107.         (action == 'r') || (action == 'x')) {
  108.     if (local) displa = 1;
  109.     if (stdouf) { displa = 0; quiet = 1; }
  110.     }
  111.  
  112.     if (quiet) displa = 0;        /* No display if quiet requested */
  113.     return(action);            /* Then do any requested protocol */
  114. }
  115.  
  116. /*  D O A R G  --  Do a command-line argument.  */
  117.  
  118. int
  119. #ifdef CK_ANSIC
  120. doarg(char x)
  121. #else
  122. doarg(x) char x; 
  123. #endif /* CK_ANSIC */
  124. /* doarg */ {
  125.     int i, y, z; long zz; char *xp;
  126.  
  127.     xp = *xargv+1;            /* Pointer for bundled args */
  128.     while (x) {
  129.     switch (x) {
  130.  
  131. #ifndef NOSPL
  132. case 'C':                /* Commands for parser */
  133.     xargv++, xargc--;
  134.     if ((xargc < 1) || (**xargv == '-'))
  135.       fatal("No commands given for -C");
  136.     clcmds = *xargv;            /* Get the argument (must be quoted) */
  137.     break;
  138. #endif /* NOSPL */
  139.  
  140. #ifndef NOICP
  141. case 'S':                /* "Stay" - enter interactive */
  142.     stayflg = 1;            /* command parser after executing */
  143.     break;                /* command-line actions. */
  144. #endif /* NOICP */
  145.  
  146. #ifndef NOSERVER
  147. case 'x':                /* server */
  148.     if (action) fatal("conflicting actions");
  149.     action = 'x';
  150.     break;
  151. #endif /* NOSERVER */
  152.  
  153. case 'f':                /* finish */
  154.     if (action) fatal("conflicting actions");
  155.     action = setgen('F',"","","");
  156.     break;
  157.  
  158. case 'r':                /* receive */
  159.     if (action) fatal("conflicting actions");
  160.     action = 'v';
  161.     break;
  162.  
  163. case 'k':                /* receive to stdout */
  164.     if (action) fatal("conflicting actions");
  165.     stdouf = 1;
  166.     action = 'v';
  167.     break;
  168.  
  169. case 's':                 /* send */
  170.     if (action) fatal("conflicting actions");
  171.     if (*(xp+1)) fatal("invalid argument bundling after -s");
  172.     nfils = z = 0;            /* Initialize file counter, flag */
  173.     cmlist = xargv+1;            /* Remember this pointer */
  174.     while (--xargc > 0) {        /* Traverse the list */    
  175.     xargv++;
  176.     if (**xargv == '-') {        /* Check for sending stdin */
  177.         if (strcmp(*xargv,"-") != 0) /* Watch out for next option. */
  178.           break;
  179.         z++;            /* "-" alone means send from stdin. */
  180.         } else if (zchki(*xargv) > -1    /* Check if file exists */
  181. #ifndef UNIX
  182.            /* or contains wildcard characters matching real files */
  183.            || (iswild(*xargv) && zxpand(*xargv) > 0)
  184. #endif /* UNIX */
  185.            ) {
  186.         nfils++;            /* Bump file counter */
  187.     }
  188.     }
  189.     xargc++, xargv--;            /* Adjust argv/argc */
  190.     if (nfils < 1 && z == 0)
  191. #ifdef VMS
  192.       fatal("%CKERMIT-E-SEARCHFAIL, no files for -s");
  193. #else
  194.       fatal("No files for -s");
  195. #endif /* VMS */
  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 = -nettype;          /* perhaps already set in init file */
  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. case 'z':                /* Not background */
  435.     bgset = 0;
  436.     break;
  437.  
  438. default:
  439.     fatal("invalid argument, type 'kermit -h' for help");
  440.         }
  441.  
  442.     x = *++xp;                /* See if options are bundled */
  443.     }
  444.     return(0);
  445. }
  446. #else /* No command-line interface... */
  447.  
  448. extern int xargc;
  449. int
  450. cmdlin() {
  451.     if (xargc > 1) printf("Sorry, command-line options disabled.\n");
  452.     return(0);
  453. }
  454. #endif /* NOCMDL */
  455.