|
|
1.1 ! root 1: char *connv = "Connect Command for Unix, V4E(017) 14 Sep 87"; ! 2: ! 3: /* C K U C O N -- Dumb terminal connection to remote system, for Unix */ ! 4: /* ! 5: This module should work under all versions of Unix. It calls externally ! 6: defined system-dependent functions for i/o, but depends upon the existence ! 7: of the fork() function. ! 8: ! 9: Author: Frank da Cruz (SY.FDC@CU20B), ! 10: Columbia University Center for Computing Activities, January 1985. ! 11: Copyright (C) 1985, Trustees of Columbia University in the City of New York. ! 12: Permission is granted to any individual or institution to use, copy, or ! 13: redistribute this software so long as it is not sold for profit, provided this ! 14: copyright notice is retained. ! 15: ! 16: Enhanced by H. Fischer to detect when child process (modem reader) ! 17: reports that the communications line has been broken and hang up. ! 18: Also enhanced to allow escaping from connect state to command ! 19: interpreter, to allow sending/receiving without breaking connection. ! 20: */ ! 21: ! 22: #include <stdio.h> ! 23: #include <ctype.h> /* Character types */ ! 24: #include "ckcdeb.h" ! 25: #include "ckcker.h" ! 26: #include <signal.h> ! 27: ! 28: #ifndef ZILOG ! 29: #include <setjmp.h> /* Longjumps */ ! 30: #else ! 31: #include <setret.h> ! 32: #endif ! 33: ! 34: #ifndef SIGUSR1 ! 35: #define SIGUSR1 16 ! 36: #endif ! 37: ! 38: extern int local, speed, escape, duplex, parity, flow, seslog, mdmtyp; ! 39: extern int errno, cmask, fmask; ! 40: extern char ttname[], sesfil[]; ! 41: extern CHAR dopar(); ! 42: ! 43: int i, active; /* Variables global to this module */ ! 44: char *chstr(); ! 45: char temp[50]; ! 46: ! 47: #define LBUFL 200 /* Line buffer */ ! 48: char lbuf[LBUFL]; ! 49: ! 50: /* Connect state parent/child communication signal handlers */ ! 51: ! 52: static jmp_buf env_con; /* Envir ptr for connect errors */ ! 53: ! 54: static ! 55: conn_int() { /* Modem read failure handler, */ ! 56: longjmp(env_con,1); /* notifies parent process to stop */ ! 57: } ! 58: ! 59: /* C O N E C T -- Perform terminal connection */ ! 60: ! 61: conect() { ! 62: int pid, /* process id of child (modem reader) */ ! 63: parent_id, /* process id of parent (keyboard reader) */ ! 64: n; ! 65: int c; /* c is a character, but must be signed ! 66: integer to pass thru -1, which is the ! 67: modem disconnection signal, and is ! 68: different from the character 0377 */ ! 69: char errmsg[50], *erp; ! 70: ! 71: if (!local) { ! 72: printf("Sorry, you must 'set line' first\n"); ! 73: return(-2); ! 74: } ! 75: if (speed < 0) { ! 76: printf("Sorry, you must 'set speed' first\n"); ! 77: return(-2); ! 78: } ! 79: if ((escape < 0) || (escape > 0177)) { ! 80: printf("Your escape character is not ASCII - %d\n",escape); ! 81: return(-2); ! 82: } ! 83: if (ttopen(ttname,&local,mdmtyp) < 0) { ! 84: erp = errmsg; ! 85: sprintf(erp,"Sorry, can't open %s",ttname); ! 86: perror(errmsg); ! 87: return(-2); ! 88: } ! 89: printf("Connecting thru %s, speed %d.\r\n",ttname,speed); ! 90: printf("The escape character is %s (%d).\r\n",chstr(escape),escape); ! 91: printf("Type the escape character followed by C to get back,\r\n"); ! 92: printf("or followed by ? to see other options.\r\n"); ! 93: if (seslog) printf("(Session logged to %s.)\r\n",sesfil); ! 94: ! 95: /* Condition console terminal and communication line */ ! 96: ! 97: if (conbin(escape) < 0) { ! 98: printf("Sorry, can't condition console terminal\n"); ! 99: return(-2); ! 100: } ! 101: if (ttvt(speed,flow) < 0) { ! 102: conres(); ! 103: printf("Sorry, Can't condition communication line\n"); ! 104: return(-2); ! 105: } ! 106: ! 107: /* cont'd... */ ! 108: ! 109: /* ...connect, cont'd */ ! 110: ! 111: ! 112: parent_id = getpid(); /* Get parent id for signalling */ ! 113: signal(SIGUSR1,SIG_IGN); /* Don't kill parent */ ! 114: pid = fork(); /* All ok, make a fork */ ! 115: if (pid == -1) { ! 116: conres(); /* Reset the console. */ ! 117: perror("Can't create keyboard fork"); ! 118: printf("[Back at Local System]\n"); ! 119: return(0); ! 120: } ! 121: if (pid) { ! 122: active = 1; /* This fork reads, sends keystrokes */ ! 123: if (!setjmp(env_con)) { /* comm error in child process */ ! 124: signal(SIGUSR1,conn_int); /* routine for child process exit */ ! 125: while (active) { ! 126: c = coninc(0) & cmask; /* Get character from keyboard */ ! 127: if ((c & 0177) == escape) { /* Look for escape char */ ! 128: c = coninc(0) & 0177; /* Got esc, get its arg */ ! 129: doesc(c); /* And process it */ ! 130: } else { /* Ordinary character */ ! 131: if (ttoc(dopar(c)) > -1) { ! 132: if (duplex) { /* Half duplex? */ ! 133: conoc(c); /* Yes, also echo it. */ ! 134: if (seslog) /* And maybe log it. */ ! 135: if (zchout(ZSFILE,c) < 0) seslog = 0; ! 136: } ! 137: } else { ! 138: perror("\r\nCan't send character"); ! 139: active = 0; ! 140: } ! 141: } ! 142: } ! 143: } /* Come here on death of child */ ! 144: kill(pid,9); /* Done, kill inferior fork. */ ! 145: wait((int *)0); /* Wait till gone. */ ! 146: conres(); /* Reset the console. */ ! 147: printf("[Back at Local System]\n"); ! 148: return(0); ! 149: ! 150: } else { /* Inferior reads, prints port input */ ! 151: ! 152: sleep(1); /* Wait for parent's handler setup */ ! 153: while (1) { /* Fresh read, wait for a character */ ! 154: if ((c = ttinc(0)) < 0) { /* Comm line hangup detected */ ! 155: if (errno == 9999) /* this value set by ckutio.c myread */ ! 156: printf("\r\nCommunications disconnect "); ! 157: else perror("\r\nCan't get character"); ! 158: kill(parent_id,SIGUSR1); /* notify parent. */ ! 159: pause(); /* Wait to be killed by parent. */ ! 160: } ! 161: c &= cmask; /* Got a char, strip parity, etc */ ! 162: conoc(c); /* Put it on the screen. */ ! 163: if (seslog) zchout(ZSFILE,c); /* If logging, log it. */ ! 164: while ((n = ttchk()) > 0) { /* Any more left in buffer? */ ! 165: if (n > LBUFL) n = LBUFL; /* Get them all at once. */ ! 166: if ((n = ttxin(n,lbuf)) > 0) { ! 167: for (i = 0; i < n; i++) lbuf[i] &= cmask; /* Strip */ ! 168: conxo(n,lbuf); /* Output */ ! 169: if (seslog) zsoutx(ZSFILE,lbuf,n); /* Log */ ! 170: } ! 171: } ! 172: } ! 173: } ! 174: } ! 175: ! 176: /* H C O N N E -- Give help message for connect. */ ! 177: ! 178: hconne() { ! 179: int c; ! 180: static char *hlpmsg[] = {"\ ! 181: \r\nC to close the connection, or:", ! 182: "\r\n 0 (zero) to send a null", ! 183: "\r\n B to send a BREAK", ! 184: "\r\n H to hangup and close connection", ! 185: "\r\n S for status", ! 186: "\r\n ? for help", ! 187: "\r\n escape character twice to send the escape character.\r\n\r\n", ! 188: "" }; ! 189: ! 190: conola(hlpmsg); /* Print the help message. */ ! 191: conol("Command>"); /* Prompt for command. */ ! 192: c = coninc(0) & 0177; /* Get character, strip any parity. */ ! 193: conoc(c); /* Echo it. */ ! 194: conoll(""); ! 195: return(c); /* Return it. */ ! 196: } ! 197: ! 198: ! 199: /* C H S T R -- Make a printable string out of a character */ ! 200: ! 201: char * ! 202: chstr(c) int c; { ! 203: static char s[8]; ! 204: char *cp = s; ! 205: ! 206: if (c < SP) { ! 207: sprintf(cp,"CTRL-%c",ctl(c)); ! 208: } else sprintf(cp,"'%c'\n",c); ! 209: cp = s; ! 210: return(cp); ! 211: } ! 212: ! 213: /* D O E S C -- Process an escape character argument */ ! 214: ! 215: doesc(c) char c; { ! 216: CHAR d; ! 217: ! 218: while (1) { ! 219: if (c == escape) { /* Send escape character */ ! 220: d = dopar(c); ttoc(d); return; ! 221: } else /* Or else look it up below. */ ! 222: if (isupper(c)) c = tolower(c); ! 223: ! 224: switch (c) { ! 225: ! 226: case 'c': /* Close connection */ ! 227: case '\03': ! 228: active = 0; conol("\r\n"); return; ! 229: ! 230: case 'b': /* Send a BREAK signal */ ! 231: case '\02': ! 232: ttsndb(); return; ! 233: ! 234: case 'h': /* Hangup */ ! 235: case '\010': ! 236: tthang(); active = 0; conol("\r\n"); return; ! 237: ! 238: case 's': /* Status */ ! 239: conol("\r\nConnected thru "); ! 240: conol(ttname); ! 241: if (speed >= 0) { ! 242: sprintf(temp,", speed %d",speed); conol(temp); ! 243: } ! 244: sprintf(temp,", %d bits",(cmask == 0177) ? 7 : 8); ! 245: if (parity) { ! 246: conol(", "); ! 247: switch (parity) { ! 248: case 'e': conol("even"); break; ! 249: case 'o': conol("odd"); break; ! 250: case 's': conol("space"); break; ! 251: case 'm': conol("mark"); break; ! 252: } ! 253: conol(" parity"); ! 254: } ! 255: if (seslog) { ! 256: conol(", logging to "); conol(sesfil); ! 257: } ! 258: conoll(""); return; ! 259: ! 260: case '?': /* Help */ ! 261: c = hconne(); continue; ! 262: ! 263: case '0': /* Send a null */ ! 264: c = '\0'; d = dopar(c); ttoc(d); return; ! 265: ! 266: case SP: /* Space, ignore */ ! 267: return; ! 268: ! 269: default: /* Other */ ! 270: conoc(BEL); return; /* Invalid esc arg, beep */ ! 271: } ! 272: } ! 273: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.