home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / old / ckermit5a / ckuusy.c < prev    next >
C/C++ Source or Header  |  1994-09-30  |  16KB  |  554 lines

  1. #include "ckcsym.h"
  2. #ifndef NOCMDL
  3.  
  4. /*  C K U U S Y --  "User Interface" for Unix Kermit, part Y  */
  5.  
  6. /*  Command-Line Argument Parser */
  7.  
  8. /*
  9.   Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
  10.   Columbia University Academic Information Systems, New York City.
  11.  
  12.   Copyright (C) 1985, 1994, Trustees of Columbia University in the City of New
  13.   York.  The C-Kermit software may not be, in whole or in part, licensed or
  14.   sold for profit as a software product itself, nor may it be included in or
  15.   distributed with commercial products or otherwise distributed by commercial
  16.   concerns to their clients or customers without written permission of the
  17.   Office of Kermit Development and Distribution, Columbia University.  This
  18.   copyright notice must not be removed, altered, or obscured.
  19. */
  20.  
  21. #include "ckcdeb.h"
  22. #include "ckcasc.h"
  23. #include "ckcker.h"
  24. #include "ckucmd.h"
  25. #include "ckcnet.h"
  26.  
  27. #ifdef NETCONN
  28. #ifdef ANYX25
  29. extern int revcall, closgr, cudata;
  30. extern char udata[MAXCUDATA];
  31. extern int x25fd;
  32. #endif /* ANYX25 */
  33. #ifndef VMS
  34. #ifndef OS2
  35. extern
  36. #endif /* OS2 */
  37. #endif /* VMS */
  38.  int telnetfd;
  39. #endif /* NETCONN */
  40.  
  41. extern char *ckxsys, *ckzsys, *cmarg, *cmarg2, **xargv, **cmlist, *clcmds;
  42. extern int action, cflg, xargc, stdouf, stdinf, displa, cnflg, nfils,
  43.   local, quiet, escape, network, mdmtyp, maxrps, rpsiz, bgset, xargs,
  44.   urpsiz, wslotr, swcapr, binary, warn, parity, turn, turnch, duplex, flow,
  45.   fncact, clfils, noinit, stayflg, nettype, cfilef, delay, noherald;
  46. extern long speed, ttgspd(), zchki();
  47. extern char ttname[];
  48. #ifdef OS2PM
  49. extern int os2pm;
  50. #endif /* OS2PM */
  51.  
  52. #ifdef CK_NETBIOS
  53. extern unsigned char NetBiosAdapter ;
  54. #endif /* CK_NETBIOS */
  55.  
  56. #ifndef NODIAL
  57. extern int nmdm;
  58. extern struct keytab mdmtab[];
  59. #endif /* NODIAL */
  60.  
  61. /*  C M D L I N  --  Get arguments from command line  */
  62. /*
  63.  Simple Unix-style command line parser, conforming with 'A Proposed Command
  64.  Syntax Standard for Unix Systems', Hemenway & Armitage, Unix/World, Vol.1,
  65.  No.3, 1984.
  66. */
  67. int
  68. cmdlin() {
  69.     char x;                /* Local general-purpose int */
  70.     cmarg = "";                /* Initialize globals */
  71.     cmarg2 = "";
  72.     action = cflg = 0;
  73.  
  74.     debug(F111,"cmdlin",*xargv,xargc);
  75.  
  76. /* If we were started directly from a Kermit application file, its name is */
  77. /* in argv[1], so skip past it. */
  78.  
  79.     if (xargc > 1) {
  80.     if (*xargv[0] != '-' && *xargv[1] != '-') {
  81.         if (
  82.         /* some shells don't put full pathname... */
  83.         /* zchki(xargv[0]) > 0 && */ /* ...so skip this test */
  84.         cfilef ||        /* If it's our command file */
  85.         zchki(xargv[1]) > 0    /* or if it's an existing file */
  86.         ) {            
  87.         xargc -= 1;        /* skip past it */
  88.         xargv += 1;        /* ... */
  89.         }
  90.     }
  91.     }
  92.  
  93.     while (--xargc > 0) {        /* Go through command line words */
  94.     xargv++;
  95.     debug(F111,"xargv",*xargv,xargc);
  96.     if (**xargv == '=') return(0);
  97. #ifdef VMS
  98.     else if (**xargv == '/') continue;
  99. #endif /* VMS */
  100.         else if (**xargv == '-') {    /* Got an option (begins with dash) */
  101.         x = *(*xargv+1);        /* Get the option letter */
  102.         if (doarg(x) < 0) doexit(BAD_EXIT,1); /* Go handle option */
  103.         } else {            /* No dash where expected */
  104.         fatal2(*xargv,
  105.            "invalid command-line option, type \"kermit -h\" for help");
  106.     }
  107.     }
  108.     debug(F101,"action","",action);
  109. #ifndef NOLOCAL
  110.     if (!local) {
  111.     if ((action == 'c') || (cflg != 0))
  112.         fatal("-l or -j or -X required");
  113.     }
  114. #endif /* NOLOCAL */
  115.     if (*cmarg2 != 0) {
  116.     if ((action != 's') && (action != 'r') &&
  117.         (action != 'v'))
  118.         fatal("-a without -s, -r, or -g");
  119.     if (action == 'r' || action == 'v') {
  120.         if (zchko(cmarg2) < 0)
  121.           fatal("write access to -a file denied");
  122. #ifdef CK_TMPDIR
  123.         if (isdir(cmarg2))        /* -a is a directory */
  124.           if (!zchdir(cmarg2))    /* try to change to it */
  125.         fatal("can't change to -a directory");
  126.           else cmarg2 = "";
  127. #endif /* CK_TMPDIR */
  128.     }
  129.     }
  130.     if ((action == 'v') && (stdouf) && (!local)) {
  131.         if (isatty(1))
  132.         fatal("unredirected -k can only be used in local mode");
  133.     }
  134.     if ((action == 's') || (action == 'v') ||
  135.         (action == 'r') || (action == 'x')) {
  136.     if (local) displa = 1;
  137.     if (stdouf) { displa = 0; quiet = 1; }
  138.     }
  139.     if (quiet) displa = 0;        /* No display if quiet requested */
  140.     return(action);            /* Then do any requested protocol */
  141. }
  142.  
  143. /*  D O A R G  --  Do a command-line argument.  */
  144.  
  145. int
  146. #ifdef CK_ANSIC
  147. doarg(char x)
  148. #else
  149. doarg(x) char x; 
  150. #endif /* CK_ANSIC */
  151. /* doarg */ {
  152.     int i, y, z; long zz; char *xp;
  153.  
  154.     xp = *xargv+1;            /* Pointer for bundled args */
  155.     debug(F111,"doarg entry",xp,xargc);
  156.     while (x) {
  157.     debug(F000,"doarg arg","",x);
  158.     switch (x) {
  159.  
  160. #ifndef NOSPL
  161. case 'C':                /* Commands for parser */
  162.     xargv++, xargc--;
  163.     if ((xargc < 1) || (**xargv == '-'))
  164.       fatal("No commands given for -C");
  165.     clcmds = *xargv;            /* Get the argument (must be quoted) */
  166.     break;
  167. #endif /* NOSPL */
  168.  
  169. case 'D':                /* Delay */
  170.     if (*(xp+1)) fatal("invalid argument bundling");
  171.     xargv++, xargc--;
  172.     if ((xargc < 1) || (**xargv == '-'))
  173.       fatal("missing delay value");
  174.     z = atoi(*xargv);            /* Convert to number */
  175.     if (z > -1)                /* If in range */
  176.       delay = z;            /* set it */
  177.     else
  178.       fatal("bad delay value");
  179.     break;
  180.  
  181.  
  182. #ifndef NOICP
  183. case 'S':                /* "Stay" - enter interactive */
  184.     stayflg = 1;            /* command parser after executing */
  185.     break;                /* command-line actions. */
  186. #endif /* NOICP */
  187.  
  188. case 'R':                /* Remote-Only */
  189.     break;                /* This is handled in prescan(). */
  190.  
  191. #ifndef NOSERVER
  192. case 'x':                /* server */
  193.     if (action) fatal("conflicting actions");
  194.     action = 'x';
  195.     break;
  196. #endif /* NOSERVER */
  197.  
  198. case 'f':                /* finish */
  199.     if (action) fatal("conflicting actions");
  200.     action = setgen('F',"","","");
  201.     break;
  202.  
  203. case 'r':                /* receive */
  204.     if (action) fatal("conflicting actions");
  205.     action = 'v';
  206.     break;
  207.  
  208. case 'k':                /* receive to stdout */
  209.     if (action) fatal("conflicting actions");
  210.     stdouf = 1;
  211.     action = 'v';
  212.     break;
  213.  
  214. case 's':                 /* send */
  215.     if (action) fatal("conflicting actions");
  216.     if (*(xp+1)) fatal("invalid argument bundling after -s");
  217.     nfils = z = 0;            /* Initialize file counter, flag */
  218.     cmlist = xargv+1;            /* Remember this pointer */
  219.     while (--xargc > 0) {        /* Traverse the list */    
  220.     xargv++;
  221.     if (**xargv == '-') {        /* Check for sending stdin */
  222.         if (strcmp(*xargv,"-") != 0) /* Watch out for next option. */
  223.           break;
  224.         z++;            /* "-" alone means send from stdin. */
  225.         } else if (zchki(*xargv) > -1    /* Check if file exists */
  226. #ifndef UNIX
  227.            /* or contains wildcard characters matching real files */
  228.            || (iswild(*xargv) && zxpand(*xargv) > 0)
  229. #endif /* UNIX */
  230.            ) {
  231.         nfils++;            /* Bump file counter */
  232.     }
  233.     }
  234.     xargc++, xargv--;            /* Adjust argv/argc */
  235.     if (nfils < 1 && z == 0)
  236. #ifdef VMS
  237.       fatal("%CKERMIT-E-SEARCHFAIL, no files for -s");
  238. #else
  239.       fatal("No files for -s");
  240. #endif /* VMS */
  241.     if (z > 1) fatal("-s: too many -'s");
  242.     if (z == 1 && nfils > 0)
  243.       fatal("invalid mixture of filenames and '-' in -s");
  244.     if (nfils == 0) {
  245.     if (isatty(0)) fatal("sending from terminal not allowed");
  246.     else stdinf = 1;
  247.     }
  248.  
  249. #ifdef COMMENT
  250.     /* If only one filespec was given, indicate "internal list" rather than */
  251.     /* "expanded list", so in case it includes wildcards, C-Kermit can */
  252.     /* expand them itself. */
  253.     if (nfils == 1) {
  254.     cmarg = *cmlist;
  255.     nfils = -1;
  256.     }
  257. #endif /* COMMENT */
  258.  
  259.     debug(F101,*xargv,"",nfils);
  260.     action = 's';
  261. #ifdef UNIX
  262. /* When set, this flag tells Kermit not to expand wildcard characters. */
  263. /* In UNIX, the shell has already expanded them.  In VMS, OS/2, etc, */
  264. /* Kermit must expand them.  Kermit must not expand them in UNIX because */
  265. /* a filename might itself contain metacharacters.  Imagine, for example, */
  266. /* what would happen if a directory contained a file named "*". */
  267.     clfils = 1;                /* Flag for command-line files */
  268. #endif /* UNIX */
  269.     break;
  270.  
  271. case 'g':                /* get */
  272.     if (action) fatal("conflicting actions");
  273.     if (*(xp+1)) fatal("invalid argument bundling after -g");
  274.     xargv++, xargc--;
  275.     if ((xargc == 0) || (**xargv == '-'))
  276.         fatal("missing filename for -g");
  277.     cmarg = *xargv;
  278.     action = 'r';
  279.     break;
  280.  
  281. #ifndef NOLOCAL
  282. case 'c':                /* connect before */
  283.     cflg = 1;
  284.     break;
  285.  
  286. case 'n':                /* connect after */
  287.     cnflg = 1;
  288.     break;
  289. #endif /* NOLOCAL */
  290.  
  291. case 'h':                /* help */
  292.     usage();
  293. #ifndef NOICP
  294.     if (stayflg)    
  295.       break;
  296.     else
  297. #endif /* NOICP */
  298.       doexit(GOOD_EXIT,-1);
  299.  
  300. case 'a':                /* "as" */
  301.     if (*(xp+1)) fatal("invalid argument bundling after -a");
  302.     xargv++, xargc--;
  303.     if ((xargc < 1) || (**xargv == '-'))
  304.         fatal("missing name in -a");
  305.     cmarg2 = *xargv;
  306.     break;
  307.  
  308. #ifndef NOICP
  309. case 'Y':                /* No initialization file */
  310.     noinit = 1;
  311.     break;
  312.  
  313. case 'y':                /* Alternate init-file name */
  314.     if (*(xp+1)) fatal("invalid argument bundling after -y");
  315.     xargv++, xargc--;
  316.     if (xargc < 1) fatal("missing filename in -y");
  317.     /* strcpy(kermrc,*xargv); ...this was already done in prescan()... */
  318.     break;
  319. #endif /* NOICP */
  320.  
  321. #ifndef NOLOCAL
  322. case 'l':                /* SET LINE */
  323. #ifdef NETCONN
  324. #ifdef ANYX25
  325. case 'X':                /* SET HOST to X.25 address */
  326. #ifdef SUNX25
  327. case 'Z':                /* SET HOST to X.25 file descriptor */
  328. #endif /* SUNX25 */
  329. #endif /* ANYX25 */
  330. #ifdef TCPSOCKET
  331. case 'j':                /* SET HOST (TCP/IP socket) */
  332. #endif /* TCPSOCKET */
  333. #endif /* NETCONN */
  334.     network = 0;
  335.     if (*(xp+1)) fatal("invalid argument bundling after -l or -j");
  336.     xargv++, xargc--;
  337.     if ((xargc < 1) || (**xargv == '-'))
  338.         fatal("communication line device name missing");
  339.     strcpy(ttname,*xargv);
  340.     local = (strcmp(ttname,CTTNAM) != 0);
  341. /*
  342.   NOTE: We really do not need to call ttopen here, since it should be called
  343.   again later, automatically, when we first try to condition the device via
  344.   ttpkt or ttvt.  Calling ttopen here has the bad side effect of making the
  345.   order of the -b and -l options significant, but order of command-line options
  346.   should not matter.  However, the network cases immediately below complicate
  347.   matters a bit, so we'll settle this in a future edit.
  348. */
  349.     if (x == 'l') {
  350.     if (ttopen(ttname,&local,mdmtyp,0) < 0)
  351.       fatal("can't open device");
  352.     debug(F101,"cmdlin speed","",speed);
  353. #ifdef COMMENT
  354. /* What can it hurt? */
  355.     if (speed < 0L)            /* If speed hasn't been set yet, */
  356. #endif /* COMMENT */
  357.       speed = ttgspd();        /* get it. */
  358. #ifdef NETCONN
  359.     } else {
  360.     if (x == 'j') {            /* IP network host name */
  361.         nettype = NET_TCPB;
  362.         mdmtyp = -nettype;          /* perhaps already set in init file */
  363.         telnetfd = 1;        /* Or maybe an open file descriptor */
  364. #ifdef SUNX25
  365.     } else if (x == 'X') {        /* X.25 address */
  366.         nettype = NET_SX25;
  367.         mdmtyp = -nettype;
  368.     } else if (x == 'Z') {        /* Open X.25 file descriptor */
  369.         nettype = NET_SX25;
  370.         mdmtyp = -nettype;
  371.         x25fd = 1;
  372. #endif /* SUNX25 */
  373. #ifdef STRATUSX25
  374.     } else if (x == 'X') {        /* X.25 address */
  375.         nettype = NET_VX25;
  376.         mdmtyp = -nettype;
  377. #endif /* STRATUSX25 */
  378.     }
  379.     if (ttopen(ttname,&local,mdmtyp,0) < 0)
  380.       fatal("can't open host connection");
  381.     network = 1;
  382. #endif /* NETCONN */
  383.     }
  384.     /* add more here later - decnet, etc... */
  385.     break;
  386.  
  387. #ifdef ANYX25
  388. case 'U':                               /* X.25 call user data */
  389.     if (*(xp+1)) fatal("invalid argument bundling");
  390.     xargv++, xargc--;
  391.     if ((xargc < 1) || (**xargv == '-'))
  392.         fatal("missing call user data string");
  393.     strcpy(udata,*xargv);
  394.     if ((int)strlen(udata) <= MAXCUDATA) cudata = 1;
  395.     else fatal("Invalid call user data");
  396.     break;
  397.  
  398. case 'o':                               /* X.25 closed user group */
  399.     if (*(xp+1)) fatal("invalid argument bundling");
  400.     xargv++, xargc--;
  401.     if ((xargc < 1) || (**xargv == '-'))
  402.         fatal("missing closed user group index");
  403.     z = atoi(*xargv);            /* Convert to number */
  404.     if (z >= 0 && z <= 99) closgr = z;
  405.     else fatal("Invalid closed user group index");
  406.     break;
  407.  
  408. case 'u':                               /* X.25 reverse charge call */
  409.     revcall = 1;
  410.     break;
  411. #endif /* ANYX25 */
  412. #endif /* NOLOCAL */
  413.  
  414. case 'b':                       /* set bits-per-second for serial */
  415.     if (*(xp+1)) fatal("invalid argument bundling"); /* communication device */
  416.     xargv++, xargc--;
  417.     if ((xargc < 1) || (**xargv == '-'))
  418.         fatal("missing bps");
  419.     zz = atol(*xargv);            /* Convert to long int */
  420.     i = zz / 10L;
  421. #ifndef NOLOCAL
  422.     if (ttsspd(i) > -1)            /* Check and set it */
  423. #endif /* NOLOCAL */
  424.       speed = ttgspd();            /* and read it back. */
  425. #ifndef NOLOCAL
  426.     else
  427.       fatal("unsupported transmission rate");
  428. #endif /* NOLOCAL */
  429.     break;
  430.  
  431. #ifndef NODIAL
  432. case 'm':                /* Modem type */
  433.     if (*(xp+1)) fatal("invalid argument bundling after -m");    
  434.     xargv++, xargc--;
  435.     if ((xargc < 1) || (**xargv == '-'))
  436.         fatal("modem type missing");
  437.     y = lookup(mdmtab,*xargv,nmdm,&z);
  438.     if (y < 0)
  439.       fatal("unknown modem type");
  440.     mdmtyp = y;
  441.     break;
  442. #endif /* NODIAL */
  443.  
  444. case 'e':                /* Extended packet length */
  445.     if (*(xp+1)) fatal("invalid argument bundling after -e");
  446.     xargv++, xargc--;
  447.     if ((xargc < 1) || (**xargv == '-'))
  448.         fatal("missing length");
  449.     z = atoi(*xargv);            /* Convert to number */
  450.     if (z > 10 && z <= maxrps) {
  451.         rpsiz = urpsiz = z;
  452.     if (z > 94) rpsiz = 94;        /* Fallback if other Kermit can't */
  453.     } else fatal("Unsupported packet length");
  454.     break;
  455.  
  456. case 'v':                /* Vindow size */
  457.     if (*(xp+1)) fatal("invalid argument bundling");
  458.     xargv++, xargc--;
  459.     if ((xargc < 1) || (**xargv == '-'))
  460.         fatal("missing or bad window size");
  461.     z = atoi(*xargv);            /* Convert to number */
  462.     if (z < 32) {            /* If in range */
  463.     wslotr = z;            /* set it */
  464.     if (z > 1) swcapr = 1;        /* Set capas bit if windowing */
  465.     } else fatal("Unsupported packet length");
  466.     break;
  467.  
  468. case 'i':                /* Treat files as binary */
  469.     binary = XYFT_B;
  470.     break;
  471.  
  472. case 'w':                /* Writeover */
  473.     warn = 0;
  474.     fncact = XYFX_X;
  475.     break;
  476.  
  477. case 'q':                /* Quiet */
  478.     quiet = 1;
  479.     break;
  480.  
  481. #ifdef DEBUG
  482. case 'd':                /* DEBUG */
  483.     break;                /* Handled in prescan() */
  484. #endif /* DEBUG */ 
  485.  
  486. case 'p':                /* SET PARITY */
  487.     if (*(xp+1)) fatal("invalid argument bundling");
  488.     xargv++, xargc--;
  489.     if ((xargc < 1) || (**xargv == '-'))
  490.         fatal("missing parity");
  491.     switch(x = **xargv) {
  492.     case 'e':
  493.     case 'o':
  494.     case 'm':
  495.     case 's': parity = x; break;
  496.     case 'n': parity = 0; break;
  497.     default:  fatal("invalid parity");
  498.         }
  499.     break;
  500.  
  501. case 't':
  502.     turn = 1;                /* Line turnaround handshake */
  503.     turnch = XON;            /* XON is turnaround character */
  504.     duplex = 1;                /* Half duplex */
  505.     flow = 0;                /* No flow control */
  506.     break;
  507.  
  508. case 'z':                /* Not background */
  509.     bgset = 0;
  510.     break;
  511.  
  512. #ifdef CK_NETBIOS
  513. case 'N':               /* NetBios Adapter Number follows */
  514.     if (*(xp+1)) fatal("invalid argument bundling after -N");
  515.     xargv++, xargc--;
  516.     if ((xargc < 1) || (**xargv == '-'))
  517.       fatal("missing NetBios Adapter number");
  518.     if ( (strlen(*xargv) != 1) ||
  519.     (atoi(*xargv) < 0) ||
  520.     (atoi(*xargv) > 3) )
  521.       fatal("invalid NetBios Adapter specified\nadapters 0 to 3 are valid");
  522.     break;
  523. #endif /* CK_NETBIOS */
  524.  
  525. #ifdef OS2PM
  526. case 'P':                /* OS/2 Presentation Manager */
  527.     os2pm = 1;
  528.     break;
  529. #endif /* OS2PM */
  530.  
  531. #ifndef NOICP
  532.   case 'H':
  533.     noherald = 1;
  534.     break;
  535. #endif /* NOICP */
  536.  
  537. default:
  538.     fatal2(*xargv,
  539.        "invalid command-line option, type \"kermit -h\" for help");
  540.         }
  541.  
  542.     x = *++xp;                /* See if options are bundled */
  543.     }
  544.     return(0);
  545. }
  546. #else /* No command-line interface... */
  547.  
  548. extern int xargc;
  549. int
  550. cmdlin() {
  551.     if (xargc > 1) fatal("Sorry, command-line options disabled.");
  552. }
  553. #endif /* NOCMDL */
  554.