home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / pub / sinclairqla / qlkus2.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  16KB  |  527 lines

  1. /*
  2.     US2_C - QL-Kermit SET command
  3.  
  4.     Based on ckuus[123].c, (C) Columbia University
  5. */
  6.  
  7.  
  8. /* Include files */
  9.  
  10. #include "flp1_ctype_h"                          /* Character type functions */
  11. #include "flp1_fcntl_h"                          /* File opening modes */
  12.  
  13. #include "ram1_ker_h"                            /* Kermit definitions */
  14. #include "ram1_cmd_h"                            /* Command interpreter definitions */
  15. #include "ram1_usr_h"                            /* User command definitions */
  16.  
  17.  
  18. /* External variables */
  19.  
  20. extern int slen;                                 /* Send packet size */
  21. extern int rlen;                                 /* Receive packet size */
  22. extern int rtmo;                                 /* Timeout we use */
  23. extern int stmo;                                 /* Timeout remote uses */
  24. extern int ttychid;                              /* QDOS channel ID for serial line */
  25. extern int debug;                                /* Debugging level */
  26. extern int trans;                                /* File name translation */
  27. extern int speed;                                /* Line speed (baud rate) */
  28. extern int xfertyp;                              /* File transfer type */
  29. extern int ttyfd;                                /* FD for communication line */
  30. extern int retry;                                /* Retry limit */
  31. extern int delay;                                /* Delay before SEND starts */
  32. extern int serno;                                /* Serial port in use */
  33. extern int parity;                               /* Parity setting */
  34. extern int npad;                                 /* How much padding remote needs */
  35.  
  36. extern bool timer;                               /* Timer enabled flag */
  37. extern bool echo;                                /* Local echo flag */
  38. extern bool local;                               /* Local/remote flag */
  39. extern bool keep;                                /* Incomplete file disposition */
  40. extern bool tkecho;                              /* Show TAKE commands flag */
  41. extern bool tkabort;                             /* Error abort flag */
  42.  
  43. extern char ssop;                                /* Packet start remote needs */
  44. extern char rsop;                                /* Packet start I need */
  45. extern char reol;                                /* EOL I need */
  46. extern char seol;                                /* EOL remote needs */
  47. extern char quote;                               /* Control prefix */
  48. extern char pebq;                                /* Eight-bit prefix */
  49. extern char enter[];                             /* What ENTER sends */
  50.  
  51. extern unsigned char padch;                      /* Pad character remote needs */
  52.  
  53. extern char ttyname[];                           /* Communication device name */
  54. extern char *dftty;                              /* Default ditto */
  55.  
  56. extern char *sourdev;                            /* Default source device */
  57. extern char *destdev;                            /* Default destination device */
  58. extern char *takedev;                            /* Default TAKE file device */
  59. extern char *suffix;                             /* Sending file suffix */
  60.  
  61. extern int _oserr;                               /* QDOS error code */
  62. extern int oserr;                                /* Copy of above */
  63.  
  64.  
  65. /* External functions */
  66.  
  67. extern bool chkquote();                          /* Check for valid quote character */
  68.  
  69.  
  70. /* Keyword tables */
  71.  
  72. struct keytab srtab[] =                          /* SEND/RECEIVE parameters */
  73. {
  74.     0,        "end-of-line",      XYEOL,
  75.     0,        "packet-length",    XYLEN,
  76.     CM_INV,   "start-of-packet",  XYMARK,
  77.     0,        "marker",           XYMARK,
  78.     0,        "timeout",          XYTIMO
  79. };
  80.  
  81. int nsrtab = (sizeof(srtab) / sizeof(struct keytab));
  82.  
  83.  
  84. struct keytab filetab[] =                        /* FILE parameters */
  85. {
  86.     0,        "type",             XZTYPE,
  87.     0,        "incomplete",       XZIFD,
  88.     0,        "name",             XZNAME,
  89.     0,        "suffix",           XZSUFF
  90. };
  91.  
  92. int nfiletab = (sizeof(filetab) / sizeof(struct keytab));
  93.  
  94.  
  95. struct keytab devtab[] =                         /* DEVICE parameters */
  96. {
  97.     0,        "source",           XZSOUR,
  98.     0,        "destination",      XZDEST,
  99.     0,        "take-file",        XZTAKE
  100. };
  101.  
  102. int ndevtab = (sizeof(devtab) / sizeof(struct keytab));
  103.  
  104.  
  105. struct keytab fntab[4] =                         /* File name translation */
  106. {
  107.     0,        "normal",           FNNORM,
  108.     CM_INV,   "translated",       FNNORM,
  109.     0,        "untranslated",     FNUNTR,
  110.     CM_INV,   "literal",          FNUNTR
  111. };
  112.  
  113.  
  114. struct keytab onoff[2] =                         /* On/off */
  115. {
  116.     0,        "off",              0,
  117.     0,        "on",               1
  118. };
  119.  
  120.  
  121. struct keytab deblvl[] =                         /* Debugging level */
  122. {
  123.     0,        "off",              DBOFF,
  124.     0,        "on",               DBON,
  125.     0,        "full",             DBFULL
  126. };
  127.  
  128. int ndeblvl = (sizeof(deblvl) / sizeof(struct keytab));
  129.  
  130.  
  131. struct keytab ifdtab[3] =                        /* Incomplete file disposition */
  132. {
  133.     0,        "delete",           0,
  134.     CM_INV,   "discard",          0,
  135.     0,        "keep",             1
  136. };
  137.  
  138.  
  139. struct keytab fttab[3] =                         /* File transfer type */
  140. {
  141.     0,        "ascii",            FTASC,
  142.     CM_INV,   "text",             FTASC,
  143.     0,        "binary",           FTBIN
  144. };
  145.  
  146.  
  147. struct keytab ptytab[] =                         /* PARITY setting */
  148. {
  149.     0,        "none",             PYNONE,
  150.     CM_INV,   "off",              PYNONE,
  151.     0,        "even",             PYEVEN,
  152.     0,        "odd",              PYODD,
  153.     0,        "mark",             PYMARK,
  154.     0,        "space",            PYSPC
  155. };
  156.  
  157. int nptytab = (sizeof(ptytab) / sizeof(struct keytab));
  158.  
  159.  
  160. struct keytab linetab[2] =                       /* LINE setting */
  161. {
  162.     0,        "1",                1,
  163.     0,        "2",                2
  164. };
  165.  
  166.  
  167. struct keytab spdtab[] =                         /* Baud rate */
  168. {
  169.     0,        "75",               75,
  170.     0,        "300",              300,
  171.     0,        "600",              600,
  172.     0,        "1200",             1200,
  173.     0,        "2400",             2400,
  174.     0,        "4800",             4800,
  175.     0,        "9600",             9600
  176. };
  177.  
  178. int nspdtab = (sizeof(spdtab) / sizeof(struct keytab));
  179.  
  180.  
  181. struct keytab enttab[] =                         /* ENTER action */
  182. {
  183.     0,        "cr",               256*CR,
  184.     0,        "lf",               256*LF,
  185.     0,        "crlf",             256*CR+LF,
  186.     0,        "lfcr",             256*LF+CR
  187. };
  188.  
  189. int nenttab = (sizeof(enttab) / sizeof(struct keytab));
  190.  
  191.  
  192. /* DOPRM - Handle the SET command
  193.  
  194.     Returns:
  195.        -2: illegal input
  196.        -1: reparse needed
  197.         0: success
  198. */
  199.  
  200. int doprm(xx)
  201. int xx;
  202. {
  203.     int x,y,z;
  204.     char *s;
  205.  
  206.     switch (xx)
  207.     {
  208.  
  209. case XYEOL:                                      /* These have all been moved */
  210. case XYLEN:                                      /* to SET SEND/RECEIVE, so */
  211. case XYMARK:                                     /* let the user know what to do */
  212. case XYTIMO:
  213.          x = cmcfm();
  214.          error("Use SET SEND or SET RECEIVE");
  215.          return(-2);
  216.  
  217. case XYENT:                                      /* ENTER action */
  218.          if ((y = cmkey(enttab,nenttab,"cr","What ENTER sends"))<0) return(y);
  219.          if ((x = cmcfm())<0) return(x);
  220.          enter[0] = (y&0177400)>>8;
  221.          enter[1] = y&0377;
  222.          return(0);
  223.  
  224. case XYTKAB:                                     /* TAKE file abort */
  225.          return(seton(&tkabort));
  226.  
  227. case XYTIME:                                     /* Timer status */
  228.          return(seton(&timer));
  229.  
  230. case XYTKEC:                                     /* TAKE command echo */
  231.          return(seton(&tkecho));
  232.  
  233. case XYDEB:                                      /* Debugging display level */
  234.          if ((y = cmkey(deblvl,ndeblvl,"off","Debug level"))<0) return(y);
  235.          if ((x = cmcfm())<0) return(x);
  236.          debug = y;
  237.          return(0);
  238.  
  239. case XYECHO:                                     /* Local echo */
  240.          return(seton(&echo));
  241.  
  242. case XYLINE:                                     /* Communication line */
  243.          x = cmkey(linetab,2,"","Serial port");
  244.          if (x==-1 || x==-2) return(x);
  245.          if ((y = cmcfm())<0) return(y);
  246.  
  247.          if (x==-3) x = -1;                      /* Nothing given, unset line */
  248.          serno = x;                              /* Set new port number */
  249.          return(newtty());                       /* and reopen it */
  250.  
  251. case XYPARI:                                     /* Parity */
  252.          x = cmkey(ptytab,nptytab,"","Parity setting");
  253.          if (x==-3)
  254.          {
  255.               error("Parity setting not specified");
  256.               x = -2;
  257.          }
  258.          if (x<0) return(x);
  259.          if ((y = cmcfm())<0) return(y);
  260.  
  261.          parity = x;                             /* Set new parity type */
  262.          if (serno>0) return(newtty());          /* and re-open line if set */
  263.          else return(0);                         /* otherwise leave it */
  264.  
  265. case XYRETR:                                     /* Retry limit */
  266.          y = cmnum("5",&x,"Number of retries");
  267.          return(setnum(&retry,x,y));
  268.  
  269. case XYDEL:                                      /* SEND delay */
  270.          y = cmnum("5",&x,"Delay before SEND");
  271.          return(setnum(&delay,x,y));
  272.  
  273. case XYPAD:                                      /* Padding */
  274.          y = cmnum("0",&x,"Amount of padding");  /* Get how much to use */
  275.          if (y<0) return(y);
  276.          y = cmnum("0",&z,"Character to pad with (decimal)");
  277.          if (y<0) return(y);                     /* Get character to use */
  278.          if ((y = cmcfm())<0) return(y);
  279.  
  280.          npad = x;                               /* Store results */
  281.          padch = (unsigned char) z;
  282.          return(0);
  283.  
  284. case XYRECV:                                     /* SET SEND */
  285. case XYSEND:                                     /* SET RECEIVE */
  286.           y = cmkey(srtab,nsrtab,"","What to set");
  287.           if (y==-3)
  288.           {
  289.               error("SEND or RECEIVE parameter not specified");
  290.               y = -2;
  291.           }
  292.           if (y<0) return(y);
  293.  
  294.           switch (y)
  295.           {
  296.  
  297. case XYEOL:   y = cmnum("0",&x,"Packet end character");
  298.               if ((y = setcc(&z,x,y))<0) return(y);
  299.               if (xx==XYRECV) reol = z; else seol = z;
  300.               return(0);
  301.  
  302. case XYLEN:   y = cmnum("90",&x,"Maximum packet length");
  303.               if ((y = setnum(&z,x,y))<0) return(y);
  304.               if (xx==XYRECV) rlen = z; else slen = z;
  305.               return(0);
  306.  
  307. case XYMARK:  y = cmnum("1",&x,"Packet start character");
  308.               if ((y = setcc(&z,x,y))<0) return(y);
  309.               if (xx==XYRECV) rsop = z; else ssop = z;
  310.               return(0);
  311.  
  312. case XYTIMO:  if ((y = cmnum("5",&x,"Timeout in seconds"))<0) return(y);
  313.               if ((x<1) || (x>94))
  314.               {
  315.                    error("Timeout must be in range 1 to 94");
  316.                    return(-2);
  317.               }
  318.               if ((y = cmcfm())<0) return(y);
  319.  
  320.               if (xx==XYRECV) rtmo = x; else stmo = x;
  321.               return(0);
  322.  
  323. default:      error("Unknown SET SEND/RECEIVE option");
  324.               return(-2);
  325.          }
  326.  
  327. case XYFILE:                                     /* SET FILE */
  328.          y = cmkey(filetab,nfiletab,"","File option");
  329.          if (y==-3)
  330.          {
  331.              error("FILE parameter not specified");
  332.              y = -2;
  333.          }
  334.          if (y<0) return(y);
  335.  
  336.          switch (y)
  337.          {
  338.  
  339. case XZTYPE:  if ((y = cmkey(fttab,3,"ascii","Transfer type"))<0) return(y);
  340.               if ((x = cmcfm())<0) return(x);
  341.               xfertyp = y;
  342.               return(0);
  343.  
  344. case XZIFD:   if ((y = cmkey(ifdtab,3,"discard","Incomplete file action"))<0) return(y);
  345.               if ((x = cmcfm())<0) return(x);
  346.               keep = (y==1);
  347.               return(0);
  348.  
  349. case XZNAME:  if ((y = cmkey(fntab,4,"normal","File name action"))<0) return(y);
  350.               if ((x = cmcfm())<0) return(x);
  351.               trans = y;
  352.               return(0);
  353.  
  354. case XZSUFF:  y = cmfld("",&s,"Outgoing file suffix");
  355.               if (y==-1 || y==-2) return(y);
  356.               if ((x = cmcfm())<0) return(x);
  357.               strcpy(suffix,s);
  358.               return(0);
  359.  
  360. default:      error("Unknown SET FILE option");
  361.               return(-2);
  362.          }
  363.  
  364. case XYDEV:                                      /* SET DEVICE */
  365.          y = cmkey(devtab,ndevtab,"","Device to set");
  366.          if (y==-3)
  367.          {
  368.               error("DEVICE parameter not specified");
  369.               y = -2;
  370.          }
  371.          if (y<0) return(y);
  372.  
  373.          switch(y)
  374.          {
  375.  
  376. case XZSOUR:  return(setdev("Transfer source device",sourdev));
  377.  
  378. case XZDEST:  return(setdev("Transfer destination device",destdev));
  379.  
  380. case XZTAKE:  return(setdev("Command file device",takedev));
  381.  
  382. default:      error("Unknown SET DEVICE option");
  383.               return(-2);
  384.          }
  385.  
  386. case XYSPEE:                                     /* Speed (baud rate) */
  387.          if (!local)
  388.          {
  389.               error("Communication line not set");
  390.               return(-2);
  391.          }
  392.  
  393.          if ((y = cmkey(spdtab,nspdtab,DFSPEED,"Baud rate"))<0) return(y);
  394.          if (x = (cmcfm())<0) return(x);
  395.          if ((x = setbaud(y))<0)
  396.          {
  397.               error("Can't set speed to %d",y);
  398.               return(-2);
  399.          }
  400.          speed = y;
  401.          if (debon) printf("%s set to %d baud\n",ttyname,speed);
  402.          return(0);
  403.  
  404. case XYQCTL:                                     /* Control quote */
  405.          return(setq("e,pebq,"#","Control quote character"));
  406.  
  407. case XYEBQ:                                      /* 8-bit quote */
  408.          return(setq(&pebq,quote,"&","8-bit quote character"));
  409.  
  410. default: if ((x = cmcfm())<0) return(x);
  411.          error("Unknown SET option");
  412.          return(-2);
  413.     }
  414. }
  415.  
  416.  
  417. /* SETQ - Parse and set a quote character */
  418.  
  419. int setq(c,other,xdef,xhlp)
  420. char *c;
  421. char other;
  422. char *xdef,*xhlp;
  423. {
  424.     int x,y;
  425.     char *s;
  426.  
  427.     if ((y = cmfld(xdef,&s,xhlp))<0) return(y);  /* Read parameter */
  428.     if ((y = cmcfm())<0) return(y);              /* Confirm end */
  429.  
  430.     if (strlen(s)!=1)                            /* Check length */
  431.     {
  432.          error("Not a single character - %s",s);
  433.          return(-2);
  434.     }
  435.  
  436.     x = *s;
  437.     if (!chkquote(x))                            /* Check for valid quote character */
  438.     {
  439.          error("Not a valid quote character - %c",x);
  440.          return(-2);
  441.     }
  442.  
  443.     if (x==other)                                /* Check for duplication */
  444.     {
  445.          error("Quote characters identical");
  446.          return(-2);
  447.     }
  448.  
  449.     *c = x;                                      /* Valid, set new value */
  450.     return(0);
  451. }
  452.  
  453.  
  454. /* SETON - Parse ON/OFF (default ON), set parameter to result */
  455.  
  456. int seton(prm)
  457. int *prm;
  458. {
  459.     int x, y;
  460.  
  461.     if ((y = cmkey(onoff,2,"on","Option"))<0) return(y);
  462.     if ((x = cmcfm())<0) return(x);
  463.     *prm = (y==1);
  464.     return(0);
  465. }
  466.  
  467.  
  468. /* SETNUM - Set parameter to result of cmnum() parse
  469.  
  470.     Call with:
  471.        x = number from cnum parse
  472.        y = return code from cmnum
  473. */
  474.  
  475. int setnum(prm,x,y)
  476. int *prm,x,y;
  477. {
  478.     if (y<0) return(y);                          /* cmnum error */
  479.     if (x>94 || x<0)                             /* Check range */
  480.     {
  481.          error("Number not in range 0..94 - %d",x);
  482.          return(-2);
  483.     }
  484.     if ((y = cmcfm())<0) return(y);
  485.     *prm = x;
  486.     return(0);
  487. }
  488.  
  489.  
  490. /* SETCC - Set parameter to an ASCII control character value */
  491.  
  492. int setcc(prm,x,y)
  493. int *prm,x,y;
  494. {
  495.     if (y<0) return(y);                          /* cmnum error */
  496.     if ((x>037) && (x!=0177))                    /* Check range */
  497.     {
  498.          error("Number not in ASCII control range - %d",x);
  499.          return(-2);
  500.     }
  501.     if ((y = cmcfm())<0) return(y);
  502.     *prm = x;
  503.     return(0);
  504. }
  505.  
  506.  
  507. /* SETDEV - Read and set a device name */
  508.  
  509. int setdev(xhlp,str)
  510. char *xhlp,*str;
  511. {
  512.      char *s;
  513.      int x;
  514.  
  515.      x = cmfld("",&s,xhlp);                      /* Read device name */
  516.      if (x==-3)
  517.      {
  518.           error("Device not specified");         /* Must be given */
  519.           x = -2;
  520.      }
  521.      if (x<0) return(x);
  522.      if ((x = cmcfm())<0) return(x);             /* Check end of line */
  523.  
  524.      strcpy(str,s);                              /* Copy name to resting place */
  525.      return(0);
  526. }
  527.