|
|
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.