/* CKVMCS_C MCS I/F routines June 14, 1990 */ /********************************************************************** * * * MCS-Kermit REL 2 * * source code * * * * Change History: * * * * 1. Modify C-Kermit(4E) source code to * * produce new module for MCS/IVS-Kermit * * ORIGINAL RELEASE * * June 22, 1990 * * * * * ***********************************************************************/ #include #include #include #include #include #include #include "mcs_defs_h" #include "ckcdeb.h" /* DRE 020190 */ #include "ckcker.h" /* DRE 060690 */ #define SCR_EM 9 /* PEG 013090 */ #define MCSLIMIT 200 extern int server; /* PEG 013090 */ extern char *free(); extern char *malloc(); extern int deblog; /* DRE 021690 */ extern int doexit(); static struct OutputCD *OCDptr = &OutCD; static struct InputCD *ICDptr = &InCD; static struct SParBlck *SPBptr = &SParBlock; static struct RParBlck *RPBptr = &RParBlock; static struct ParBlck *PBptr = &ParBlock; static char mcs_tmpstr[MCSLIMIT]; static char *blanks = " "; static char *spb_param = NULL; /* DRE 020190 */ static char realmesg[MAXSP]; /* DRE 060690 */ /******************************************************************* * * * str_convert * * * * converts non-printable MCS structures to a hex format * * * * PEG June 4, 1990 * * * ********************************************************************/ void str_convert(mcs_ptr, lgth) char *mcs_ptr; int lgth; { char *cptr; int i, j, flag = 0; static char hexchar[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; if ((lgth * 2) > MCSLIMIT) { fprintf(stderr, "\nstr_convert lgth over MCSLIMIT...\n\n"); mcs_tmpstr[0] = '\0'; return; } for (j = 0, cptr = mcs_ptr; j < lgth; j++, cptr++) if (!isprint(*cptr)) flag = 1; if (!flag) { strncpy(mcs_tmpstr, mcs_ptr, lgth); *(mcs_ptr + lgth + 1) = '\0'; return; } else { for (j = 0, i = 0; j < lgth; j++) { if (*cptr < 0x10) /* high order bits */ mcs_tmpstr[i++] = '0'; else mcs_tmpstr[i++] = hexchar[*cptr++ / 0x10]; if (*cptr == 0x00) /* low order bits */ mcs_tmpstr[i++] = '0'; else mcs_tmpstr[i++] = hexchar[*cptr++ % 0x10]; } mcs_tmpstr[i] = '\0'; if (i + 25 > MCSLIMIT) fprintf(stderr, "Next line converted to HEX...\n"); else strcat(mcs_tmpstr, " *** converted to hex *** "); } } /******************************************************************* * * * dump routines * * * * dumps MCS control structures for mcs_send * * mcs_recv * * * * PEG June 4, 1990 * * * ********************************************************************/ void dump_OCD() { fprintf(stderr, "\nDumping OCDptr...\n"); str_convert(OCDptr->destcnt, 4); fprintf(stderr, "OCDptr->destcnt: %s\n", mcs_tmpstr); str_convert(OCDptr->textlen, 4); fprintf(stderr, "OCDptr->textlen: %s\n", mcs_tmpstr); str_convert(OCDptr->statkey, 2); fprintf(stderr, "OCDptr->statkey: %s\n", mcs_tmpstr); fprintf(stderr, "OCDptr->errkey: %#X\n", OCDptr->errkey); str_convert(OCDptr->symdest, 12); fprintf(stderr, "OCDptr->symdest: %s\n", mcs_tmpstr); fprintf(stderr, "OCDptr->ExOutCD.xoformat: %#X\n", OCDptr->ExOutCD.xoformat); str_convert(OCDptr->ExOutCD.tcfunction, 3); fprintf(stderr, "OCDptr->ExOutCD.tcfunction: %s\n", mcs_tmpstr); str_convert(OCDptr->ExOutCD.tcqualifier, 3); fprintf(stderr, "OCDptr->ExOutCD.tcqualifier: %s\n", mcs_tmpstr); fprintf(stderr, "OCDptr->ExOutCD.tcoutput_reset: %#X\n", OCDptr->ExOutCD.tcoutput_reset); } void dump_ICD() { fprintf(stderr, "\nDumping ICDptr...\n"); str_convert(ICDptr->q, 12); fprintf(stderr, "ICDptr->q: %s\n", mcs_tmpstr); str_convert(ICDptr->symq1, 12); fprintf(stderr, "ICDptr->symq1: %s\n", mcs_tmpstr); str_convert(ICDptr->symq2, 12); fprintf(stderr, "ICDptr->symq2: %s\n", mcs_tmpstr); str_convert(ICDptr->symq3, 12); fprintf(stderr, "ICDptr->symq3: %s\n", mcs_tmpstr); str_convert(ICDptr->mdate, 6); fprintf(stderr, "ICDptr->mdate: %s\n", mcs_tmpstr); str_convert(ICDptr->mtime, 8); fprintf(stderr, "ICDptr->mtime: %s\n", mcs_tmpstr); str_convert(ICDptr->source, 12); fprintf(stderr, "ICDptr->source: %s\n", mcs_tmpstr); str_convert(ICDptr->len, 4); fprintf(stderr, "ICDptr->len: %s\n", mcs_tmpstr); fprintf(stderr, "ICDptr->endkey: %#X\n", ICDptr->endkey); str_convert(ICDptr->statkey, 2); fprintf(stderr, "ICDptr->statkey: %s\n", mcs_tmpstr); str_convert(ICDptr->msgcnt, 6); fprintf(stderr, "ICDptr->msgcnt: %s\n", mcs_tmpstr); fprintf(stderr, "ICDptr->ExInCD.xiformat: %#X\n", ICDptr->ExInCD.xiformat); str_convert(ICDptr->ExInCD.xistatus, 2); fprintf(stderr, "ICDptr->ExInCD.xistatus: %s\n", mcs_tmpstr); str_convert(ICDptr->ExInCD.xipassthru, 10); fprintf(stderr, "ICDptr->ExInCD.xipassthru: %s\n", mcs_tmpstr); } void dump_SPB() { fprintf(stderr, "\nDumping SDBptr...\n"); fprintf(stderr, "SPBptr->length: %d\n", SPBptr->length); fprintf(stderr, "SPBptr->complver: % #X\n", SPBptr->complver); fprintf(stderr, "SPBptr->linenum: %#X\n", SPBptr->linenum); fprintf(stderr, "SPBptr->indicator: %#X\n", SPBptr->indicator); fprintf(stderr, "SPBptr->advancing: %#X\n", SPBptr->advancing); fprintf(stderr, "SPBptr->position: %#X\n", SPBptr->position); fprintf(stderr, "SPBptr->sendcount: %#X\n", SPBptr->sendcount); str_convert(SPBptr->mnemonic, 4); fprintf(stderr, "SPBptr->mnemonic: %s\n", mcs_tmpstr); } void dump_RPB() { fprintf(stderr, "\nDumping RPBptr...\n"); fprintf(stderr, "RPBptr->length: %d\n", RPBptr->length); fprintf(stderr, "RPBptr->complver: %#X\n", RPBptr->complver); fprintf(stderr, "RPBptr->avail: %#X\n", RPBptr->avail); fprintf(stderr, "RPBptr->indicator: %#X\n", RPBptr->indicator); } /******************************************************************** * * * Function mcserr * * called when status returned by MCS * * routines return anything other than 00 * * outputs an error message * * * * Paul E. Gladden * * May 3, 1990 * * June 14, 1990 update dump ICD / OCD struct * * * * assumes status bytes are ascii * * chars * * * *********************************************************************/ void mcserr(cin, status, errsend) char cin; char status[2]; char errsend; { char str1[100]; long errclk; char *cptr; str1[0] = '\0'; errclk = time((long *) 0); /* time stamping mcs errors */ sprintf(str1, "\n%s", ctime(&errclk)); cptr = strrchr(str1, '\n'); if (cptr != NULL) { *cptr++ = ' '; /* removing \n put in by ctime */ *cptr = '\0'; } switch (cin) { case 'd' : strcat(str1, "MCS Error Status: Disable "); break; case 'e' : strcat(str1, "MCS Error Status: Enable "); break; case 'a' : strcat(str1, "MCS Error Status: Accept "); break; case 's' : strcat(str1, "MCS Error Status: Send "); break; case 'r' : strcat(str1, "MCS Error Status: Receive "); break; default : strcat(str1, "MCS Error Status: Unknown "); break; } strncat (str1, status, 2); if ( cin == 's' ) { /* moves errorkey char into error output */ char valtmp[3]; /* with an error condition occurs with a */ /* mcs_send PEG 020590 */ valtmp[0] = ' '; valtmp[1] = errsend; valtmp[2] = '\0'; strncat(str1, valtmp, 2); } strncat(str1, "\n", 1); /* DRE 021690 */ write(2, str1, (unsigned)(strlen(str1))); if (deblog) debug(F110, "funct: mcserr> ", str1, 0); if (cin == 'e' && !(strncmp(status, "00", 2))) { /* enable failed exiting... */ if (!(strncmp(status, "12", 2))) return; sprintf(str1, "MCSENABLE failed...program exiting...\n"); write(2, str1, (unsigned)(strlen(str1))); doexit(BAD_EXIT); } if (deblog) { if ( cin == 's' ) { dump_OCD(); dump_SPB(); } if ( cin == 'r' ) { dump_ICD(); dump_RPB(); } } } mcs_disable(io, qname, status) char *io; char *qname; char status[3]; { char passwd[PWDLEN]; init_pwd(passwd); if (deblog) debug(F100, "funct: mcs_disable", "", 0); if ((*io == 'r') || (*io == 'R')) { /* disable the input queue */ init_ipb(); init_icd(qname); MCS\:DSABLE(ICDptr, passwd, PBptr); /* DRE 013190 */ status[0] = ICDptr->statkey[0]; /* DRE 013190 */ status[1] = ICDptr->statkey[1]; /* DRE 013190 */ status[2] = '\0'; /* DRE 013190 */ } else { /* disable the output */ init_opb(); /* DRE 012990 */ init_ocd(); /* DRE 012990 */ MCS\:DSABLE(OCDptr, passwd, PBptr); /* DRE 013190 */ status[0] = OCDptr->statkey[0]; /* DRE 013190 */ status[1] = OCDptr->statkey[1]; /* DRE 013190 */ status[2] = '\0'; /* DRE 013190 */ } if ((status[0] != '0') || (status[1] != '0')) /* PEG 013090 */ mcserr ('d', status, 'x'); } mcs_enable(io, qname, status) char *io; char *qname; char status[3]; { char passwd[PWDLEN]; init_pwd(passwd); if (deblog) debug(F100, "funct: mcs_enable", "", 0); if ((*io == 'r') || (*io == 'R')) { /* enable the input */ init_ipb(); init_icd(qname); init_rpb(); /* DRE 021690 - Done here for performance */ MCS\:ENABLE(ICDptr, passwd, PBptr); /* DRE 013190 */ status[0] = ICDptr->statkey[0]; /* DRE 013190 */ status[1] = ICDptr->statkey[1]; /* DRE 013190 */ status[2] = '\0'; /* DRE 013190 */ } else { /* enable the output */ init_opb(); /* DRE 012990 */ init_ocd(); /* DRE 012990 */ init_spb(); /* DRE 021690 - Done here for performance */ MCS\:ENABLE(OCDptr, passwd, PBptr); /* DRE 013190 */ status[0] = OCDptr->statkey[0]; /* DRE 013190 */ status[1] = OCDptr->statkey[1]; /* DRE 013190 */ status[2] = '\0'; /* DRE 013190 */ } if ((status[0] != '0') || (status[1] != '0')) /* PEG 013090 */ mcserr ('e', status, 'x'); } init_pwd(passwd) char *passwd; { strncpy(passwd, blanks, PWDLEN); strncpy(passwd, PASSWD, strlen(PASSWD)); } init_icd(qname) char *qname; { strncpy(ICDptr->q, blanks, 12); strncpy(ICDptr->q, qname, strlen(qname)); strncpy(ICDptr->symq1, blanks, 12); strncpy(ICDptr->symq2, blanks, 12); strncpy(ICDptr->symq3, blanks, 12); strncpy(ICDptr->mdate, blanks, 6); strncpy(ICDptr->mtime, blanks, 8); strncpy(ICDptr->source, blanks, 12); strncpy(ICDptr->source, IN_TERM, strlen(IN_TERM)); strncpy(ICDptr->len, blanks, 4); strncpy(ICDptr->statkey, blanks, 2); strncpy(ICDptr->msgcnt, blanks, 6); /* DRE 020290 */ /* DRE 012990 - removed reference to filler and msgcnt3 parameters */ strncpy(ICDptr->ExInCD.xistatus, blanks, 2); strncpy(ICDptr->ExInCD.xipassthru, blanks, 3); ICDptr->endkey = 0x20; ICDptr->ExInCD.xiformat = 0x20; strncpy(ICDptr->ExInCD.xifiller, blanks, 27); /* DRE 012990 */ } init_recv_icd() { ICDptr->endkey = 0x32; strncpy(ICDptr->statkey, "00", 2); ICDptr->ExInCD.xiformat = 0x30; strncpy(ICDptr->ExInCD.xistatus, blanks, 2); strncpy(ICDptr->ExInCD.xipassthru, blanks, 10); } init_ocd() { strncpy(OCDptr->destcnt, "0001", 4); strncpy(OCDptr->textlen, blanks, 4); strncpy(OCDptr->statkey, blanks, 2); OCDptr->errkey = 0x20; strncpy(OCDptr->symdest, blanks, 12); /* DRE 012990 */ strncpy(OCDptr->symdest, OUT_TERM, strlen(OUT_TERM)); OCDptr->ExOutCD.xoformat = 0x30; strncpy(OCDptr->ExOutCD.tcfunction, blanks, 3); strncpy(OCDptr->ExOutCD.tcqualifier, blanks, 3); strncpy(OCDptr->ExOutCD.xofiller, blanks, 33); /* DRE 012990 */ OCDptr->ExOutCD.tcoutput_reset = 0x20; /* DRE 012990 */ } init_write_ocd(mesglength, destination) int mesglength; char *destination; { char len[5]; sprintf(len, "%0.4d", mesglength); strncpy(OCDptr->textlen, len, 4); SPBptr->length = (short)mesglength; strncpy(OCDptr->statkey, "00", 2); OCDptr->errkey = 0x30; strncpy(OCDptr->symdest, blanks, 12); strncpy(OCDptr->symdest, destination, strlen(destination)); } init_ipb() { PBptr->denabltyp = IPPHASE; PBptr->passwdlen = PWDLEN; PBptr->complver = COMPVER; PBptr->destcount = 0x00; strncpy(PBptr->filler, blanks, 8); /* DRE 012990 */ /* DRE 012990 - remove references to indicator, advancing, position, sendcount, and mnemonic fields */ } init_opb() { PBptr->denabltyp = OPPHASE; PBptr->passwdlen = PWDLEN; PBptr->complver = COMPVER; PBptr->destcount = 0x00; strncpy(PBptr->filler, blanks, 8); /* DRE 012990 */ /* DRE 012990 - remove references to indicator, advancing, position, sendcount, and mnemonic fields */ } init_rpb() { RPBptr->length = 0x0050; RPBptr->complver = COMPVER; RPBptr->avail = 0x02; /* suspend if input Q empty */ RPBptr->indicator = EMI; strncpy(RPBptr->filler, blanks, 7); /* DRE 012990 */ /* DRE 012990 - remove references to advancing and position fields */ } init_spb() { /* length field set by init_write_ocd */ SPBptr->complver = COMPVER; SPBptr->linenum = 0x00; SPBptr->indicator = EMI; /* SPBptr->advancing = AFTER; */ SPBptr->advancing = 0x00; /* DRE 020990 */ SPBptr->position = 0x00; /* DRE 020990 */ /* SPBptr->position = LINE; */ SPBptr->sendcount = 0x01; /* DRE 012990 */ /* SPBptr->mnemonic.type = 0x01; */ SPBptr->mnemonic[0] = 0x01; /* mnemonic type */ if (spb_param == NULL) { spb_param = (char *) malloc(6 * sizeof(char)); *spb_param = 0x04; *(spb_param + 1) = '\0'; strcat(spb_param, "UNFM"); } /* SPBptr->mnemonic.address = spb_param; */ SPBptr->mnemonic[1] = *((char *) & spb_param + 1); /* set address */ SPBptr->mnemonic[2] = *((char *) & spb_param + 2); SPBptr->mnemonic[3] = *((char *) & spb_param + 3); } mcs_accept(qname) char *qname; { char msgcnt[7]; int mesg_no; char status[2]; if (deblog) debug(F100, "funct: mcs_accept", "", 0); init_icd(qname); #ifndef lint MCS\:ACCEPT(ICDptr); #endif if ((ICDptr->statkey[0] != '0') || (ICDptr->statkey[1] != '0')) { status[0] = ICDptr->statkey[0]; status[1] = ICDptr->statkey[1]; status[2] = '\0'; mcserr ('a', status, 'x'); } strncpy(msgcnt, ICDptr->msgcnt, 6); msgcnt[6] = '\0'; mesg_no = atoi(msgcnt); return mesg_no; } mcs_recv(qname, mesg, mesglength, source, status) char *qname; char *mesg; int *mesglength; char *source; char status[3]; { char len_str[5]; if (deblog) debug(F100, "funct:mcs_recv", "", 0); init_icd(qname); init_recv_icd(); /* init_rpb(); */ #ifndef lint MCS\:RECEIV(ICDptr, mesg, RPBptr); #else fgets(mesg, 200, stdin); sprintf(len_str, "%0.4d", strlen(mesg)); strncpy(ICDptr->len, len_str, 4); *mesglength = strlen(mesg); strcpy(status, "00"); #endif strncpy(len_str, ICDptr->len, 4); len_str[4] = '\0'; *mesglength = atoi(len_str); if (mesg[*mesglength - 1] == '\r') mesg[*mesglength - 1] = '\n'; mesg[*mesglength] = '\0'; /* * mesg[*mesglength] = '\n'; * mesg[*mesglength+1] = '\0'; */ source = ICDptr->source; status[0] = ICDptr->statkey[0]; status[1] = ICDptr->statkey[1]; status[2] = '\0'; if (deblog) debug(V110, "mcs_recv:mesg ", mesg, *mesglength); /* PEG 042490 */ if (deblog) debug(F111, "funct:mcs_recv", "mesglength", *mesglength); if ((status[0] != '0') || (status[1] != '0')) /* PEG 013090 */ mcserr ('r', status, 'x'); } mcs_send(qname, mesg, mesglength, destination, status) char *qname; char *mesg; int mesglength; char *destination; char status[3]; { char source[80]; int i, j, mesg_no, count; i = j = 0; while (mesg[i] != '\0') { realmesg[j] = mesg[i]; if (realmesg[j] == '\n') { mesglength++; realmesg[++j] = '\r'; } i++; j++; } realmesg[j] = '\0'; if (deblog) debug(F110, "funct: mcs_send ", realmesg, 0); init_write_ocd(mesglength, destination); #ifndef lint MCS\:SEND(OCDptr, realmesg, SPBptr); #else for (count = 0; count < mesglength; count++) { if (mesg[count] != '\r') putchar(mesg[count]); } strcpy(status, "00"); #endif /* This code removed the returned statuses passed back from MCS from the respective queues. At present we check the status from MCS returned from the system call. But we do NOT check any statuses placed on the queues. McDaid threw the statuses away after removing them from the queue. MCS now never places the statuses on the queue. This was done by changing MCSKNDLJ OPRTN parameter from BOTH to NONE. MCS now does the work we use to do. A small performance gain should result. PEG April 19, 1990 mesg_no = mcs_accept(qname); for (i=0;istatkey[0]; status[1] = OCDptr->statkey[1]; status[2] = '\0'; if ((status[0] != '0') || (status[1] != '0')) /* PEG 013090 */ mcserr ('s', status, OCDptr->errkey); }