home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / ncr9800 / ckvmcs.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  22KB  |  662 lines

  1. /* CKVMCS_C MCS I/F routines June 14, 1990  */
  2.  
  3. /**********************************************************************
  4. *                                                                     *
  5. * MCS-Kermit REL 2                                                    *
  6. * source code                                                         *
  7. *                                                                     *
  8. * Change History:                                                     *
  9. *                                                                     *
  10. *                1. Modify C-Kermit(4E) source code to                *
  11. *                   produce new module for MCS/IVS-Kermit             *
  12. *                   ORIGINAL RELEASE                                  *
  13. *                   June 22, 1990                                     *
  14. *                                                                     *
  15. *                                                                     *
  16. ***********************************************************************/
  17.  
  18. #include <stdio.h>
  19. #include <ctype.h>
  20. #include <string.h>
  21. #include <errno.h>
  22. #include <fcntl.h>
  23. #include <time.h>
  24. #include "mcs_defs_h"
  25. #include "ckcdeb.h"     /* DRE 020190 */
  26. #include "ckcker.h"     /* DRE 060690 */
  27.  
  28. #define SCR_EM 9        /* PEG 013090 */
  29. #define MCSLIMIT 200
  30.  
  31. extern int     server;     /* PEG 013090 */
  32. extern char     *free();
  33. extern char     *malloc();
  34. extern int     deblog;       /* DRE 021690 */
  35. extern int     doexit();
  36.  
  37. static struct OutputCD *OCDptr = &OutCD;
  38. static struct InputCD *ICDptr = &InCD;
  39. static struct SParBlck *SPBptr = &SParBlock;
  40. static struct RParBlck *RPBptr = &RParBlock;
  41. static struct ParBlck *PBptr  = &ParBlock;
  42. static char     mcs_tmpstr[MCSLIMIT];
  43. static char     *blanks = "                                   ";
  44. static char     *spb_param = NULL;                  /* DRE 020190 */
  45.  
  46. static char     realmesg[MAXSP];                    /* DRE 060690 */
  47.  
  48.  
  49. /*******************************************************************
  50. *                                                                  *
  51. *                   str_convert                                    *
  52. *                                                                  *
  53. *    converts non-printable MCS structures to a hex format         *
  54. *                                                                  *
  55. *    PEG  June 4, 1990                                             *
  56. *                                                                  *
  57. ********************************************************************/
  58.  
  59. void str_convert(mcs_ptr, lgth)
  60. char     *mcs_ptr;
  61. int     lgth;
  62. {
  63.      char     *cptr;
  64.      int     i, j, flag = 0;
  65.      static char     hexchar[] = {
  66.           '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
  67.                                       'B', 'C', 'D', 'E', 'F'          };
  68.  
  69.      if ((lgth * 2) > MCSLIMIT) {
  70.           fprintf(stderr, "\nstr_convert lgth over MCSLIMIT...\n\n");
  71.           mcs_tmpstr[0] = '\0';
  72.           return;
  73.      }
  74.  
  75.      for (j = 0, cptr = mcs_ptr; j < lgth; j++, cptr++)
  76.           if (!isprint(*cptr))
  77.                flag = 1;
  78.  
  79.      if (!flag) {
  80.           strncpy(mcs_tmpstr, mcs_ptr, lgth);
  81.           *(mcs_ptr + lgth + 1) = '\0';
  82.           return;
  83.      } else {
  84.           for (j = 0, i = 0; j < lgth; j++) {
  85.  
  86.                if (*cptr < 0x10)             /* high order bits */
  87.                     mcs_tmpstr[i++] = '0';
  88.                else
  89.                     mcs_tmpstr[i++] = hexchar[*cptr++ / 0x10];
  90.  
  91.                if (*cptr == 0x00)           /* low order bits */
  92.                     mcs_tmpstr[i++] = '0';
  93.                else
  94.                     mcs_tmpstr[i++] = hexchar[*cptr++ % 0x10];
  95.           }
  96.           mcs_tmpstr[i] = '\0';
  97.  
  98.           if (i + 25 > MCSLIMIT)
  99.                fprintf(stderr, "Next line converted to HEX...\n");
  100.           else
  101.                strcat(mcs_tmpstr, " *** converted to hex *** ");
  102.      }
  103. }
  104.  
  105.  
  106. /*******************************************************************
  107. *                                                                  *
  108. *                   dump routines                                  *
  109. *                                                                  *
  110. *    dumps MCS control structures for mcs_send                      *
  111. *                                     mcs_recv                      *
  112. *                                                                  *
  113. *    PEG  June 4, 1990                                             *
  114. *                                                                  *
  115. ********************************************************************/
  116.  
  117. void dump_OCD()
  118. {
  119.      fprintf(stderr, "\nDumping OCDptr...\n");
  120.      str_convert(OCDptr->destcnt, 4);
  121.      fprintf(stderr, "OCDptr->destcnt: %s\n", mcs_tmpstr);
  122.      str_convert(OCDptr->textlen, 4);
  123.      fprintf(stderr, "OCDptr->textlen: %s\n", mcs_tmpstr);
  124.      str_convert(OCDptr->statkey, 2);
  125.      fprintf(stderr, "OCDptr->statkey: %s\n", mcs_tmpstr);
  126.      fprintf(stderr, "OCDptr->errkey: %#X\n", OCDptr->errkey);
  127.      str_convert(OCDptr->symdest, 12);
  128.      fprintf(stderr, "OCDptr->symdest: %s\n", mcs_tmpstr);
  129.      fprintf(stderr, "OCDptr->ExOutCD.xoformat: %#X\n",
  130.                       OCDptr->ExOutCD.xoformat);
  131.      str_convert(OCDptr->ExOutCD.tcfunction, 3);
  132.      fprintf(stderr, "OCDptr->ExOutCD.tcfunction: %s\n", mcs_tmpstr);
  133.      str_convert(OCDptr->ExOutCD.tcqualifier, 3);
  134.      fprintf(stderr, "OCDptr->ExOutCD.tcqualifier: %s\n", mcs_tmpstr);
  135.      fprintf(stderr, "OCDptr->ExOutCD.tcoutput_reset: %#X\n",
  136.                       OCDptr->ExOutCD.tcoutput_reset);
  137. }
  138.  
  139.  
  140. void dump_ICD()
  141. {
  142.      fprintf(stderr, "\nDumping ICDptr...\n");
  143.      str_convert(ICDptr->q, 12);
  144.      fprintf(stderr, "ICDptr->q: %s\n", mcs_tmpstr);
  145.      str_convert(ICDptr->symq1, 12);
  146.      fprintf(stderr, "ICDptr->symq1: %s\n", mcs_tmpstr);
  147.      str_convert(ICDptr->symq2, 12);
  148.      fprintf(stderr, "ICDptr->symq2: %s\n", mcs_tmpstr);
  149.      str_convert(ICDptr->symq3, 12);
  150.      fprintf(stderr, "ICDptr->symq3: %s\n", mcs_tmpstr);
  151.      str_convert(ICDptr->mdate, 6);
  152.      fprintf(stderr, "ICDptr->mdate: %s\n", mcs_tmpstr);
  153.      str_convert(ICDptr->mtime, 8);
  154.      fprintf(stderr, "ICDptr->mtime: %s\n", mcs_tmpstr);
  155.      str_convert(ICDptr->source, 12);
  156.      fprintf(stderr, "ICDptr->source: %s\n", mcs_tmpstr);
  157.      str_convert(ICDptr->len, 4);
  158.      fprintf(stderr, "ICDptr->len: %s\n", mcs_tmpstr);
  159.      fprintf(stderr, "ICDptr->endkey: %#X\n", ICDptr->endkey);
  160.      str_convert(ICDptr->statkey, 2);
  161.      fprintf(stderr, "ICDptr->statkey: %s\n", mcs_tmpstr);
  162.      str_convert(ICDptr->msgcnt, 6);
  163.      fprintf(stderr, "ICDptr->msgcnt: %s\n", mcs_tmpstr);
  164.      fprintf(stderr, "ICDptr->ExInCD.xiformat: %#X\n",
  165.                       ICDptr->ExInCD.xiformat);
  166.      str_convert(ICDptr->ExInCD.xistatus, 2);
  167.      fprintf(stderr, "ICDptr->ExInCD.xistatus: %s\n", mcs_tmpstr);
  168.      str_convert(ICDptr->ExInCD.xipassthru, 10);
  169.      fprintf(stderr, "ICDptr->ExInCD.xipassthru: %s\n", mcs_tmpstr);
  170. }
  171.  
  172.  
  173. void dump_SPB()
  174. {
  175.      fprintf(stderr, "\nDumping SDBptr...\n");
  176.      fprintf(stderr, "SPBptr->length: %d\n", SPBptr->length);
  177.      fprintf(stderr, "SPBptr->complver: % #X\n", SPBptr->complver);
  178.      fprintf(stderr, "SPBptr->linenum: %#X\n", SPBptr->linenum);
  179.      fprintf(stderr, "SPBptr->indicator: %#X\n", SPBptr->indicator);
  180.      fprintf(stderr, "SPBptr->advancing: %#X\n", SPBptr->advancing);
  181.      fprintf(stderr, "SPBptr->position: %#X\n", SPBptr->position);
  182.      fprintf(stderr, "SPBptr->sendcount: %#X\n", SPBptr->sendcount);
  183.      str_convert(SPBptr->mnemonic, 4);
  184.      fprintf(stderr, "SPBptr->mnemonic: %s\n", mcs_tmpstr);
  185. }
  186.  
  187.  
  188. void dump_RPB()
  189. {
  190.      fprintf(stderr, "\nDumping RPBptr...\n");
  191.      fprintf(stderr, "RPBptr->length: %d\n", RPBptr->length);
  192.      fprintf(stderr, "RPBptr->complver: %#X\n", RPBptr->complver);
  193.      fprintf(stderr, "RPBptr->avail: %#X\n", RPBptr->avail);
  194.      fprintf(stderr, "RPBptr->indicator: %#X\n", RPBptr->indicator);
  195. }
  196.  
  197.  
  198. /********************************************************************
  199. *                                                                   *
  200. *                  Function mcserr                                  *
  201. *                  called when status returned by MCS               *
  202. *                  routines return anything other than 00           *
  203. *                  outputs an error message                         *
  204. *                                                                   *
  205. *                  Paul E. Gladden                                  *
  206. *                  May 3, 1990                                      *
  207. *                  June 14, 1990 update dump ICD / OCD struct       *
  208. *                                                                   *
  209. *                  assumes status bytes are ascii                   *
  210. *                  chars                                            *
  211. *                                                                   *
  212. *********************************************************************/
  213.  
  214. void mcserr(cin, status, errsend)
  215. char     cin;
  216. char     status[2];
  217. char     errsend;
  218. {
  219.  
  220.      char     str1[100];
  221.      long     errclk;
  222.      char     *cptr;
  223.  
  224.      str1[0] = '\0';
  225.  
  226.      errclk = time((long *) 0);               /* time stamping mcs errors */
  227.      sprintf(str1, "\n%s", ctime(&errclk));
  228.      cptr = strrchr(str1, '\n');
  229.      if (cptr != NULL) {
  230.           *cptr++ = ' ';         /* removing \n put in by ctime */
  231.           *cptr = '\0';
  232.      }
  233.  
  234.      switch (cin)  {
  235.      case 'd' :
  236.           strcat(str1, "MCS Error Status: Disable ");
  237.           break;
  238.      case 'e' :
  239.           strcat(str1, "MCS Error Status: Enable ");
  240.           break;
  241.      case 'a' :
  242.           strcat(str1, "MCS Error Status: Accept ");
  243.           break;
  244.      case 's' :
  245.           strcat(str1, "MCS Error Status: Send ");
  246.           break;
  247.      case 'r' :
  248.           strcat(str1, "MCS Error Status: Receive ");
  249.           break;
  250.      default :
  251.           strcat(str1, "MCS Error Status: Unknown ");
  252.           break;
  253.      }
  254.  
  255.      strncat (str1, status, 2);
  256.  
  257.      if ( cin == 's' )  {      /* moves errorkey char into error output */
  258.           char     valtmp[3];  /* with an error condition occurs with a */
  259.                                /* mcs_send   PEG 020590                 */
  260.           valtmp[0] = ' ';
  261.           valtmp[1] = errsend;
  262.           valtmp[2] = '\0';
  263.  
  264.           strncat(str1, valtmp, 2);
  265.      }
  266.  
  267.      strncat(str1, "\n", 1);                             /* DRE 021690 */
  268.      write(2, str1, (unsigned)(strlen(str1)));
  269.      if (deblog)
  270.           debug(F110, "funct: mcserr> ", str1, 0);
  271.  
  272.      if (cin == 'e' && !(strncmp(status, "00", 2))) {       /* enable failed
  273.                                                                exiting...     */
  274.           if (!(strncmp(status, "12", 2)))
  275.                return;
  276.  
  277.           sprintf(str1, "MCSENABLE failed...program exiting...\n");
  278.           write(2, str1, (unsigned)(strlen(str1)));
  279.           doexit(BAD_EXIT);
  280.      }
  281.      if (deblog) {
  282.           if ( cin == 's' ) {
  283.                dump_OCD();
  284.                dump_SPB();
  285.           }
  286.  
  287.           if ( cin == 'r' ) {
  288.                dump_ICD();
  289.                dump_RPB();
  290.           }
  291.      }
  292.  
  293. }
  294.  
  295.  
  296. mcs_disable(io, qname, status)
  297. char     *io;
  298. char     *qname;
  299. char     status[3];
  300. {
  301.      char     passwd[PWDLEN];
  302.  
  303.      init_pwd(passwd);
  304.  
  305.      if (deblog)
  306.           debug(F100, "funct: mcs_disable", "", 0);
  307.  
  308.      if ((*io == 'r') || (*io == 'R')) {
  309.           /* disable the input queue */
  310.           init_ipb();
  311.           init_icd(qname);
  312.           MCS\:DSABLE(ICDptr, passwd, PBptr);     /* DRE 013190 */
  313.           status[0] = ICDptr->statkey[0];       /* DRE 013190 */
  314.           status[1] = ICDptr->statkey[1];       /* DRE 013190 */
  315.           status[2] = '\0';                     /* DRE 013190 */
  316.      } else {
  317.           /* disable the output */
  318.           init_opb();                           /* DRE 012990 */
  319.           init_ocd();                           /* DRE 012990 */
  320.           MCS\:DSABLE(OCDptr, passwd, PBptr);     /* DRE 013190 */
  321.           status[0] = OCDptr->statkey[0];       /* DRE 013190 */
  322.           status[1] = OCDptr->statkey[1];       /* DRE 013190 */
  323.           status[2] = '\0';                     /* DRE 013190 */
  324.      }
  325.  
  326.      if ((status[0] != '0') || (status[1] != '0'))  /* PEG 013090 */
  327.           mcserr ('d', status, 'x');
  328.  
  329. }
  330.  
  331.  
  332. mcs_enable(io, qname, status)
  333. char     *io;
  334. char     *qname;
  335. char     status[3];
  336. {
  337.      char     passwd[PWDLEN];
  338.  
  339.      init_pwd(passwd);
  340.  
  341.      if (deblog)
  342.           debug(F100, "funct: mcs_enable", "", 0);
  343.  
  344.      if ((*io == 'r') || (*io == 'R')) {
  345.           /* enable the input */
  346.           init_ipb();
  347.           init_icd(qname);
  348.           init_rpb();     /* DRE 021690 - Done here for performance */
  349.           MCS\:ENABLE(ICDptr, passwd, PBptr);     /* DRE 013190 */
  350.           status[0] = ICDptr->statkey[0];       /* DRE 013190 */
  351.           status[1] = ICDptr->statkey[1];       /* DRE 013190 */
  352.           status[2] = '\0';                     /* DRE 013190 */
  353.      } else {
  354.           /* enable the output */
  355.           init_opb();                           /* DRE 012990 */
  356.           init_ocd();                           /* DRE 012990 */
  357.           init_spb();   /* DRE 021690 - Done here for performance */
  358.           MCS\:ENABLE(OCDptr, passwd, PBptr);     /* DRE 013190 */
  359.           status[0] = OCDptr->statkey[0];       /* DRE 013190 */
  360.           status[1] = OCDptr->statkey[1];       /* DRE 013190 */
  361.           status[2] = '\0';                     /* DRE 013190 */
  362.      }
  363.  
  364.      if ((status[0] != '0') || (status[1] != '0'))   /* PEG 013090 */
  365.           mcserr ('e', status, 'x');
  366.  
  367. }
  368.  
  369.  
  370. init_pwd(passwd)
  371. char     *passwd;
  372. {
  373.  
  374.      strncpy(passwd, blanks, PWDLEN);
  375.      strncpy(passwd, PASSWD, strlen(PASSWD));
  376. }
  377.  
  378.  
  379. init_icd(qname)
  380. char     *qname;
  381. {
  382.      strncpy(ICDptr->q, blanks, 12);
  383.      strncpy(ICDptr->q, qname, strlen(qname));
  384.      strncpy(ICDptr->symq1, blanks, 12);
  385.      strncpy(ICDptr->symq2, blanks, 12);
  386.      strncpy(ICDptr->symq3, blanks, 12);
  387.      strncpy(ICDptr->mdate, blanks, 6);
  388.      strncpy(ICDptr->mtime, blanks, 8);
  389.      strncpy(ICDptr->source, blanks, 12);
  390.      strncpy(ICDptr->source, IN_TERM, strlen(IN_TERM));
  391.      strncpy(ICDptr->len, blanks, 4);
  392.      strncpy(ICDptr->statkey, blanks, 2);
  393.      strncpy(ICDptr->msgcnt, blanks, 6);             /* DRE 020290 */
  394.  
  395.      /* DRE 012990 - removed reference to filler and
  396.         msgcnt3 parameters */
  397.  
  398.      strncpy(ICDptr->ExInCD.xistatus, blanks, 2);
  399.      strncpy(ICDptr->ExInCD.xipassthru, blanks, 3);
  400.      ICDptr->endkey = 0x20;
  401.      ICDptr->ExInCD.xiformat = 0x20;
  402.      strncpy(ICDptr->ExInCD.xifiller, blanks, 27);   /* DRE 012990 */
  403. }
  404.  
  405.  
  406. init_recv_icd()
  407. {
  408.      ICDptr->endkey = 0x32;
  409.      strncpy(ICDptr->statkey, "00", 2);
  410.      ICDptr->ExInCD.xiformat = 0x30;
  411.      strncpy(ICDptr->ExInCD.xistatus, blanks, 2);
  412.      strncpy(ICDptr->ExInCD.xipassthru, blanks, 10);
  413. }
  414.  
  415.  
  416. init_ocd()
  417. {
  418.      strncpy(OCDptr->destcnt, "0001", 4);
  419.      strncpy(OCDptr->textlen, blanks, 4);
  420.      strncpy(OCDptr->statkey, blanks, 2);
  421.      OCDptr->errkey = 0x20;
  422.      strncpy(OCDptr->symdest, blanks, 12);           /* DRE 012990 */
  423.      strncpy(OCDptr->symdest, OUT_TERM, strlen(OUT_TERM));
  424.      OCDptr->ExOutCD.xoformat = 0x30;
  425.      strncpy(OCDptr->ExOutCD.tcfunction, blanks, 3);
  426.      strncpy(OCDptr->ExOutCD.tcqualifier, blanks, 3);
  427.      strncpy(OCDptr->ExOutCD.xofiller, blanks, 33);  /* DRE 012990 */
  428.      OCDptr->ExOutCD.tcoutput_reset = 0x20;        /* DRE 012990 */
  429. }
  430.  
  431.  
  432. init_write_ocd(mesglength, destination)
  433. int     mesglength;
  434. char     *destination;
  435. {
  436.      char     len[5];
  437.  
  438.      sprintf(len, "%0.4d", mesglength);
  439.      strncpy(OCDptr->textlen, len, 4);
  440.      SPBptr->length = (short)mesglength;
  441.      strncpy(OCDptr->statkey, "00", 2);
  442.      OCDptr->errkey = 0x30;
  443.      strncpy(OCDptr->symdest, blanks, 12);
  444.      strncpy(OCDptr->symdest, destination, strlen(destination));
  445. }
  446.  
  447.  
  448. init_ipb()
  449. {
  450.      PBptr->denabltyp = IPPHASE;
  451.      PBptr->passwdlen = PWDLEN;
  452.      PBptr->complver = COMPVER;
  453.      PBptr->destcount = 0x00;
  454.      strncpy(PBptr->filler, blanks, 8);              /* DRE 012990 */
  455.      /* DRE 012990 - remove references to indicator,
  456.         advancing, position, sendcount, and mnemonic fields */
  457. }
  458.  
  459.  
  460. init_opb()
  461. {
  462.      PBptr->denabltyp = OPPHASE;
  463.      PBptr->passwdlen = PWDLEN;
  464.      PBptr->complver = COMPVER;
  465.      PBptr->destcount = 0x00;
  466.      strncpy(PBptr->filler, blanks, 8);              /* DRE 012990 */
  467.      /* DRE 012990 - remove references to indicator,
  468.         advancing, position, sendcount, and mnemonic fields */
  469. }
  470.  
  471.  
  472. init_rpb()
  473. {
  474.      RPBptr->length = 0x0050;
  475.      RPBptr->complver = COMPVER;
  476.      RPBptr->avail = 0x02;          /* suspend if input Q empty */
  477.      RPBptr->indicator = EMI;
  478.      strncpy(RPBptr->filler, blanks, 7);             /* DRE 012990 */
  479.      /* DRE 012990 - remove references to advancing and
  480.         position fields */
  481. }
  482.  
  483.  
  484. init_spb()
  485. {
  486.      /* length field set by init_write_ocd */
  487.      SPBptr->complver = COMPVER;
  488.      SPBptr->linenum = 0x00;
  489.      SPBptr->indicator = EMI;
  490.      /*      SPBptr->advancing = AFTER;  */
  491.      SPBptr->advancing = 0x00;                     /* DRE 020990 */
  492.      SPBptr->position = 0x00;                      /* DRE 020990 */
  493.      /*      SPBptr->position = LINE;  */
  494.      SPBptr->sendcount = 0x01;                     /* DRE 012990 */
  495.      /*      SPBptr->mnemonic.type = 0x01; */
  496.      SPBptr->mnemonic[0] = 0x01;              /* mnemonic type */
  497.      if (spb_param == NULL) {
  498.           spb_param = (char *) malloc(6 * sizeof(char));
  499.           *spb_param = 0x04;
  500.           *(spb_param + 1) = '\0';
  501.           strcat(spb_param, "UNFM");
  502.      }
  503.      /*      SPBptr->mnemonic.address = spb_param;  */
  504.      SPBptr->mnemonic[1] = *((char *) & spb_param + 1);   /* set address */
  505.      SPBptr->mnemonic[2] = *((char *) & spb_param + 2);
  506.      SPBptr->mnemonic[3] = *((char *) & spb_param + 3);
  507. }
  508.  
  509.  
  510. mcs_accept(qname)
  511. char     *qname;
  512. {
  513.      char     msgcnt[7];
  514.      int     mesg_no;
  515.      char     status[2];
  516.  
  517.      if (deblog)
  518.           debug(F100, "funct: mcs_accept", "", 0);
  519.  
  520.      init_icd(qname);
  521.  
  522. #ifndef lint
  523.      MCS\:ACCEPT(ICDptr);
  524. #endif
  525.      if ((ICDptr->statkey[0] != '0') ||  (ICDptr->statkey[1] != '0'))    {
  526.  
  527.           status[0] = ICDptr->statkey[0];
  528.           status[1] = ICDptr->statkey[1];
  529.           status[2] = '\0';
  530.           mcserr ('a', status, 'x');
  531.      }
  532.      strncpy(msgcnt, ICDptr->msgcnt, 6);
  533.      msgcnt[6] = '\0';
  534.      mesg_no = atoi(msgcnt);
  535.      return mesg_no;
  536. }
  537.  
  538.  
  539. mcs_recv(qname, mesg, mesglength, source, status)
  540. char     *qname;
  541. char     *mesg;
  542. int     *mesglength;
  543. char     *source;
  544. char     status[3];
  545. {
  546.      char     len_str[5];
  547.  
  548.      if (deblog)
  549.           debug(F100, "funct:mcs_recv", "", 0);
  550.  
  551.      init_icd(qname);
  552.      init_recv_icd();
  553.      /*      init_rpb(); */
  554.  
  555. #ifndef lint
  556.      MCS\:RECEIV(ICDptr, mesg, RPBptr);
  557. #else
  558.      fgets(mesg, 200, stdin);
  559.      sprintf(len_str, "%0.4d", strlen(mesg));
  560.      strncpy(ICDptr->len, len_str, 4);
  561.      *mesglength = strlen(mesg);
  562.      strcpy(status, "00");
  563. #endif
  564.      strncpy(len_str, ICDptr->len, 4);
  565.      len_str[4] = '\0';
  566.      *mesglength = atoi(len_str);
  567.  
  568.      if (mesg[*mesglength - 1] == '\r')
  569.        mesg[*mesglength - 1] = '\n';
  570.  
  571.      mesg[*mesglength] = '\0';
  572.  
  573. /*
  574.  *   mesg[*mesglength] = '\n';
  575.  *    mesg[*mesglength+1] = '\0';
  576.  */
  577.      source = ICDptr->source;
  578.      status[0] = ICDptr->statkey[0];
  579.      status[1] = ICDptr->statkey[1];
  580.      status[2] = '\0';
  581.  
  582.      if (deblog)
  583.           debug(V110, "mcs_recv:mesg ", mesg, *mesglength);  /* PEG  042490 */
  584.      if (deblog)
  585.           debug(F111, "funct:mcs_recv", "mesglength", *mesglength);
  586.  
  587.      if ((status[0] != '0') || (status[1] != '0'))      /* PEG 013090 */
  588.           mcserr ('r', status, 'x');
  589.  
  590. }
  591.  
  592.  
  593. mcs_send(qname, mesg, mesglength, destination, status)
  594. char     *qname;
  595. char     *mesg;
  596. int     mesglength;
  597. char     *destination;
  598. char     status[3];
  599. {
  600.      char     source[80];
  601.      int     i, j, mesg_no, count;
  602.  
  603.      i = j = 0;
  604.  
  605.      while (mesg[i] != '\0') {
  606.           realmesg[j] = mesg[i];
  607.           if (realmesg[j] == '\n') {
  608.                mesglength++;
  609.                realmesg[++j] = '\r';
  610.           }
  611.           i++;
  612.           j++;
  613.      }
  614.  
  615.      realmesg[j] = '\0';
  616.  
  617.      if (deblog)
  618.           debug(F110, "funct: mcs_send ", realmesg, 0);
  619.  
  620.      init_write_ocd(mesglength, destination);
  621.  
  622. #ifndef lint
  623.      MCS\:SEND(OCDptr, realmesg, SPBptr);
  624. #else
  625.      for (count = 0; count < mesglength; count++) {
  626.           if (mesg[count] != '\r')
  627.                putchar(mesg[count]);
  628.      }
  629.      strcpy(status, "00");
  630. #endif
  631.  
  632.      /* This code removed the returned statuses
  633.         passed back from MCS from the respective
  634.         queues. At present we check the status
  635.         from MCS returned from the system call.
  636.         But we do NOT check any statuses placed on
  637.         the queues. McDaid threw the statuses away
  638.         after removing them from the queue. MCS
  639.         now never places the statuses on the queue.
  640.         This was done by changing MCSKNDLJ OPRTN
  641.         parameter from BOTH to NONE. MCS now does
  642.         the work we use to do. A small performance
  643.         gain should result.
  644.  
  645.         PEG April 19, 1990
  646.  
  647.         mesg_no = mcs_accept(qname);
  648.  
  649.         for (i=0;i<mesg_no;i++) {
  650.              mcs_recv(qname,mesg,&mesglength,source,status);
  651.              mesg[mesglength] = '\0';
  652.         }
  653. */
  654.      status[0] = OCDptr->statkey[0];
  655.      status[1] = OCDptr->statkey[1];
  656.      status[2] = '\0';
  657.  
  658.      if ((status[0] != '0') || (status[1] != '0'))      /* PEG 013090 */
  659.           mcserr ('s', status, OCDptr->errkey);
  660.  
  661. }
  662.