|
|
1.1 root 1: /*
2: * DCON
3: * Connect terminal to Datakit network
4: * Operation is line-at-a-time with remote echo.
5: */
6: #include <stdio.h>
7: #include <sys/param.h>
8: #include <sys/types.h>
9: #include <sys/ioctl.h>
10: #include <signal.h>
11: #include <dk.h>
12: #include <errno.h>
13:
14: #define CEOT 04
15:
16: struct sgttyb savloc;
17: struct tchars savechars;
18: struct ltchars lsavechars;
19: struct ltchars nlchars = { -1, -1, -1, -1, -1, -1 };
20: char intrchar = 0177;
21: char quitchar = '\\'&037;
22:
23: int rem; /* remote descriptor */
24: extern int dkp_ld, cdkp_ld;
25: #define NOLD (-1) /* no line discipline */
26: int which_ld = NOLD;
27: char serv[32]; /* .login, .dcon, etc. */
28: int autologin;
29: int noflush;
30: #define LINSIZ 128
31: char *space = " \r\t\n";
32: int neofs = 0; /* die when greater than N */
33: int sigint();
34: extern int dkverbose ;
35: extern char *strtok();
36: extern char *strchr();
37: extern char *strcpy();
38: extern char *strcat();
39: extern char *malloc();
40: extern FILE *scriptopen();
41: extern char *strchr();
42: SIG_TYP savint, savquit;
43:
44: intcatch(){ /* catch interrupts, turn them into rubouts */
45: signal(SIGINT, intcatch);
46: ioctl(rem, TIOCFLUSH, 0);
47: write(rem, &intrchar, 1);
48: ioctl(rem, TIOCFLUSH, 0);
49: ioctl(0, TIOCFLUSH, 0);
50: }
51:
52: quitcatch(){ /* catch quits, turn them into FS's */
53: ioctl(0, TIOCFLUSH, 0);
54: signal(SIGQUIT, quitcatch);
55: write(rem, &quitchar, 1);
56: }
57:
58: main(argc,argv)
59: char **argv;
60: {
61: int i, traffic;
62: char dialstr[64] ;
63: int scriptlogin;
64: FILE *script;
65:
66: savetty();
67: which_ld = dkp_ld;
68: strcpy(serv, ".dcon");
69: traffic = 0;
70: autologin = 1;
71: scriptlogin = 0;
72: for(i=1; i<argc && argv[i][0]=='-'; i++) {
73: switch(argv[i][1]) {
74: case 'u':
75: which_ld = NOLD;
76: continue;
77: case 'f':
78: noflush++;
79: continue;
80: case 's':
81: scriptlogin = 1;
82: continue;
83: case 'l':
84: serv[0] = '\0';
85: autologin = 0;
86: continue;
87: case 'd':
88: case 'b':
89: which_ld = dkp_ld;
90: continue;
91: case 'c':
92: which_ld = cdkp_ld;
93: continue;
94: case 'v':
95: dkverbose++ ;
96: continue ;
97: default:
98: goto Usage;
99: }
100: }
101: if (i>=argc){
102: Usage:
103: quit("usage: dcon [-lvs] hostname");
104: }
105: savint = signal(SIGINT, intcatch);
106: savquit = signal(SIGQUIT, quitcatch);
107: /*
108: * request circuit to host.
109: */
110: strcpy(dialstr, argv[i]) ;
111: if(strchr(dialstr, '.'))
112: serv[0] = '\0';
113: if(scriptlogin) {
114: script = scriptopen(dialstr);
115: if(script == NULL)
116: quit("bad script");
117: }
118: strcat(dialstr, serv);
119: rem = tdkdial(dialstr, traffic);
120: if (rem < 0) {
121: char msg[64];
122: extern char *dkerror;
123: sprintf(msg, "%s; call failed", dkerror);
124: quit(msg);
125: }
126: /*
127: * turn on line discipline according to protocol.
128: */
129: if(dkverbose) printf("pushing %d...\n", which_ld);
130: if (which_ld != NOLD
131: && dkproto(rem, which_ld) < 0)
132: quit("can't turn on datakit protocol");
133: if (autologin){
134: if (tdklogin(rem) < 0)
135: quit("can't log in") ;
136: if(dkverbose) printf("logged in\n");
137: }
138: if(scriptlogin) {
139: if (dkscript(rem,script) < 0)
140: quit("can't log in") ;
141: if(dkverbose) fprintf(stderr,"logged in\n");
142: }
143: settty();
144: scan(rem);
145: /*NOTREACHED*/
146: }
147:
148: scan(f)
149: int f;
150: {
151: extern errno;
152: fd_set rd;
153:
154: ioctl(f, DIOCSTREAM, (char *)0);
155: FD_ZERO(rd);
156: for (;;) {
157: FD_SET(f, rd);
158: FD_SET(0, rd);
159: if (select(f+1, &rd, (fd_set *)0, 2000) == -1) {
160: if(errno == EINTR)
161: continue;
162: quit("select failed");
163: }
164: if (FD_ISSET(0, rd))
165: keyboard();
166: if (FD_ISSET(f, rd))
167: remote();
168: }
169: }
170:
171: quit(s)
172: char *s;
173: {
174: printf("dcon: %s\n", s);
175: signal(SIGINT, SIG_DFL);
176: resettty();
177: if (noflush==0)
178: ioctl(rem, TIOCFLUSH, 0);
179: close(rem);
180: exit(strcmp(s, "eof"));
181: }
182:
183: /*
184: * Scan data from keyboard, looking for escape lines.
185: */
186: keyboard()
187: {
188: register c;
189: register cc;
190: register char *bp;
191: register char *be, *obp;
192: char buf[1024];
193: static char line[128];
194: static char *linep = &line[0];
195: static col = 0;
196:
197: cc = read(0, buf, sizeof buf);
198: if (cc == 0)
199: quit("eof");
200: if (cc < 0) {
201: if (errno == EINTR)
202: return;
203: quit("read error on file descriptor 0");
204: }
205: be = buf+cc;
206: bp = obp = buf;
207: while(bp < be) {
208: c = *bp++;
209: if (col==0 && c=='~') {
210: *linep++ = c;
211: col = 1;
212: resettty();
213: write(1, linep-1, 1);
214: continue;
215: }
216: col++;
217: if (c=='\r')
218: c = '\n';
219: if (linep>line) {
220: *linep++ = c;
221: if (c==savloc.sg_kill)
222: write(1, "\n", 1);
223: if (c==savloc.sg_erase)
224: linep -= 2;
225: if (c==savloc.sg_kill || linep<=line) {
226: linep = line;
227: settty();
228: col = 0;
229: obp = bp;
230: }
231: }
232: if (c=='\n') {
233: col = 0;
234: if (linep > line) {
235: *linep = '\0';
236: if (escape(line+1))
237: write(rem, line+1, linep-line-1);
238: obp = bp;
239: linep = line;
240: settty();
241: }
242: }
243: }
244: if (bp>obp && linep==line)
245: write(rem, obp, bp-obp);
246: }
247:
248: /*
249: * Send data from remote machine to standard output (trivial)
250: */
251: remote(){
252: char buf[1024];
253: register n;
254:
255: n = read(rem, buf, sizeof buf);
256: if(n < 0 && errno == EINTR)
257: return;
258: if(n <= 0){
259: if(dkverbose) printf("EOF %d\r\n", neofs);
260: if(neofs++ > 4){
261: quit("Eof\r");
262: }
263: return;
264: }
265: neofs = 0;
266: write(1, buf, n);
267: }
268:
269: escape(line)
270: register char *line;
271: {
272:
273: switch(*line++) {
274: case '!':
275: cunix(line);
276: return(0);
277:
278: case '.':
279: case CEOT:
280: quit("eof");
281:
282: case 'b':
283: ioctl(rem, TIOCSBRK, 0);
284: return(0);
285: default:
286: return(1);
287: }
288: }
289:
290: cunix(prog)
291: char *prog;
292: {
293: register int upid;
294: int retcode;
295:
296: if ((upid = fork()) == 0) {
297: signal(SIGINT, savint);
298: signal(SIGQUIT, savquit);
299: resettty();
300: if (*prog == '\n')
301: execl("/bin/sh", "sh", "-i", 0);
302: else
303: execl("/bin/sh","sh","-c",prog,0);
304: exit(0100);
305: }
306: if (upid < 0)
307: printf("can't fork\n");
308: else {
309: signal(SIGINT, SIG_IGN);
310: signal(SIGQUIT, SIG_IGN);
311: while((wait(&retcode) !=upid))
312: ;
313: }
314: signal(SIGINT, intcatch);
315: signal(SIGQUIT, quitcatch);
316: settty();
317: printf("!!\n");
318: }
319:
320: dkscript(r,f)
321: FILE *f;
322: {
323: char sline[LINSIZ];
324: while(fgets(sline,100,f)) {
325: if(rget(r,strtok(sline,space)) < 0)
326: return(-1);
327: if(fgets(sline,100,f)==0)
328: return(-1);
329: if(dkverbose) fprintf(stderr,"sending %s",sline);
330: write(r,sline,strlen(sline));
331: }
332: return(1);
333: }
334:
335: rget(r,s)
336: char *s;
337: {
338: int i;
339: char buf[LINSIZ];
340: int brkchr = s[strlen(s)-1];
341: for(;;) {
342: for(i=0; ; i++) {
343: if(i>=LINSIZ-2) {
344: buf[i] = 0;
345: strcpy(buf,&buf[LINSIZ/2]);
346: i = strlen(buf);
347: }
348: if(read(r,&buf[i],1) <= 0)
349: return(-1);
350: buf[i] &= 0177;
351: if(buf[i] == brkchr)
352: break;
353: }
354: buf[i+1] = 0;
355: while(i>=0 && buf[i] && !strchr(space,buf[i]))
356: i--;
357: i++;
358: if(dkverbose) fprintf(stderr,"check '%s' vs '%s'\n",s,&buf[i]);
359: if(strcmp(s,&buf[i]) == 0)
360: return(1);
361: }
362: /*NOTREACHED*/
363: }
364:
365: FILE *
366: scriptopen(s)
367: char *s;
368: {
369: FILE *script = fopen(s, "r");
370: if(script == NULL)
371: return(NULL);
372: if(fgets(s,LINSIZ,script) == NULL)
373: return(NULL);
374: if(dkverbose) fprintf(stderr,"calling %s\n",s);
375: strtok(s,"\n");
376: return script;
377: }
378:
379: savetty()
380: {
381: if (ioctl(0, TIOCGETC, &savechars) >= 0) {
382: intrchar = savechars.t_intrc;
383: quitchar = savechars.t_quitc;
384: }
385: ioctl(0, TIOCGLTC, &lsavechars);
386: ioctl(0, TIOCGETP, &savloc);
387: }
388:
389: settty()
390: {
391: struct sgttyb s;
392:
393: s = savloc;
394: s.sg_flags &=~ (CRMOD|ECHO|XTABS);
395: s.sg_flags |= CBREAK;
396: ioctl(0, TIOCSETP, &s);
397: ioctl(0, TIOCSLTC, &nlchars);
398: }
399:
400: resettty()
401: {
402: ioctl(0, TIOCSETP, &savloc);
403: ioctl(0, TIOCSLTC, &lsavechars);
404: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.