|
|
1.1 root 1: #include <stdio.h>
2: #include <dk.h>
3: #include <sgtty.h>
4: #include <sys/stream.h>
5: #include <errno.h>
6: #include <signal.h>
7: #include <sys/stat.h>
8:
9: /*
10: * program to connect to
11: * another cpu on Datakit w/ transparent ioctls
12: */
13:
14: int rem; /* remote file descriptor */
15: extern int mesg_ld, dkp_ld;
16: extern errno;
17: extern char *dkerror;
18: struct sgttyb sgbuf;
19: char *ttyn;
20: int perms;
21:
22: struct sigmsg {
23: struct mesg m;
24: char sig[1];
25: };
26:
27: #define msglen(mp) ((mp)->losize + ((mp)->hisize<<8))
28:
29: main(argc, argv)
30: char **argv;
31: {
32: char *host;
33: char dest[128];
34: struct stat sb;
35: extern int hupcatch();
36: char *ttyname();
37:
38: while(argc > 1 && argv[1][0] == '-'){
39: argv++;
40: argc--;
41: }
42: host = argv[1];
43:
44: if(host==0){
45: printf("usage: %s host\n", argv[0]);
46: exit(1);
47: }
48:
49: ioctl(0, TIOCGETP, &sgbuf);
50: sprintf(dest, "%s.mesgdcon", host);
51: rem = tdkdial(dest, 0);
52: if (rem<0) {
53: printf("%s: call to %s failed: %s\n", argv[0], dest, dkerror);
54: exit(1);
55: }
56: if(dkproto(rem, dkp_ld) < 0){
57: printf("%s: can't push dk line discipline\n", argv[0]);
58: exit(1);
59: }
60: if(tdklogin(rem) < 0){
61: printf("%s: can't log in\n", argv[0]);
62: exit(1);
63: }
64: signal(SIGHUP, hupcatch);
65: signal(SIGQUIT, SIG_IGN);
66: signal(SIGPIPE, SIG_IGN);
67: if ((ttyn = ttyname(0)) != NULL
68: && stat(ttyn, &sb) >= 0) {
69: perms = sb.st_mode & ~S_IFMT;
70: chmod(ttyn, 0);
71: }
72: ioctl(0, TIOCFLUSH, (char *)0); /* race with readahead still possible */
73: if(ioctl(0, FIOPUSHLD, &mesg_ld) < 0){
74: printf("%s: can't push mesg_ld\n", argv[0]);
75: finish(1);
76: }
77:
78: go(rem);
79:
80: finish(0);
81: /* NOTREACHED */
82: }
83:
84: go(fd)
85: {
86: int rbits, wbits, n;
87: char buf[4096+MSGHLEN];
88: struct mesg *mp;
89:
90: mp = (struct mesg *) buf;
91: wbits = 0;
92: while(1){
93: rbits = 1 | (1<<fd);
94: if(select(20, &rbits, &wbits, 20000) < 0){
95: if(errno != EINTR)
96: return;
97: continue;
98: }
99: if(rbits & 1){
100: n = read(0, buf, sizeof(buf));
101: if(n <= 0)
102: return;
103: if (mp->type==M_SIGNAL
104: && ((struct sigmsg *)mp)->sig[0]==SIGQUIT) {
105: dolocal(fd, buf, n);
106: continue;
107: }
108: mp->magic = MSGMAGIC; /* temp safety */
109: if(write(fd, buf, n) != n)
110: return;
111: if(mp->type == M_FLUSH) {
112: remflush();
113: rbits = 0;
114: }
115: }
116: if(rbits & (1<<fd)){
117: n = read(fd, buf, sizeof(buf));
118: if(n <= 0)
119: return;
120: if(mp->type == M_HANGUP)
121: return;
122: if(mp->type == M_IOCTL){
123: doioctl(buf, n);
124: } else {
125: mp->magic = MSGMAGIC; /* temp safety */
126: if(write(1, buf, n) != n)
127: return;
128: }
129: }
130: }
131: }
132:
133: doioctl(buf, n)
134: char *buf;
135: {
136: struct mesg *mp;
137: struct iofoo{
138: int cmd;
139: union{
140: int i;
141: char errno;
142: struct insld insld;
143: } u;
144: } *iop;
145: int cmd, ld;
146:
147: iop = (struct iofoo *)(buf + MSGHLEN);
148: mp = (struct mesg *) buf;
149:
150: cmd = iop->cmd;
151: n -= MSGHLEN;
152: n -= sizeof(iop->cmd);
153: switch(cmd){
154: case FIOLOOKLD:
155: if(n > 0)
156: ld = iop->u.i;
157: else
158: ld = 0;
159: ld++;
160: if(ioctl(1, FIOLOOKLD, &ld) < 0)
161: goto bad;
162: iop->cmd = ld;
163: n = sizeof(iop->cmd);
164: break;
165:
166: case FIOPOPLD:
167: if(n > 0)
168: ld = iop->u.i;
169: else
170: ld = 0;
171: ld++;
172: if(ioctl(1, FIOPOPLD, &ld) < 0)
173: goto bad;
174: n = 0;
175: break;
176:
177: case FIOPUSHLD:
178: iop->u.insld.level = 0;
179: /* fall through... */
180: case FIOINSLD:
181: iop->u.insld.level++;
182: if(ioctl(1, FIOINSLD, &(iop->u.insld)) < 0)
183: goto bad;
184: n = 0;
185: break;
186:
187: default:
188: mp->magic = MSGMAGIC; /* safety */
189: write(1, buf, MSGHLEN + msglen(mp));
190: return;
191: }
192: /* locally successful */
193: mp->type = M_IOCACK;
194: mp->magic = MSGMAGIC;
195: setmsgl(mp, n);
196: write(rem, buf, MSGHLEN + msglen(mp));
197: return;
198: bad:
199: mp->type = M_IOCNAK;
200: mp->magic = MSGMAGIC;
201: setmsgl(mp, sizeof(struct iofoo));
202: iop->u.errno = errno;
203: write(rem, buf, MSGHLEN + msglen(mp));
204: }
205:
206: remflush()
207: {
208: char buf[5000];
209: struct mesg *mp;
210: int n;
211:
212: mp = (struct mesg *) buf;
213: mp->type = M_IOCTL;
214: setmsgl(mp, sizeof(int));
215: mp->magic = MSGMAGIC;
216: write(rem, buf, sizeof(struct mesg) + msglen(mp));
217:
218: while((n = read(rem, buf, sizeof(buf))) > 0){
219: if(mp->type == M_IOCNAK || mp->type == M_IOCACK)
220: return;
221: }
222: }
223:
224: setmsgl(mp, n)
225: register struct mesg *mp;
226: int n;
227: {
228: mp->losize = n;
229: mp->hisize = n >> 8;
230: }
231:
232: hupcatch()
233: {
234: finish(0);
235: }
236:
237: finish(sts)
238: {
239: struct mesg m;
240:
241: if(ioctl(0, FIOLOOKLD, 0) == mesg_ld)
242: ioctl(0, FIOPOPLD, 0);
243: if (ttyn)
244: chmod(ttyn, perms);
245: if (sts == 0)
246: printf("Eof\n");
247: exit(sts);
248: }
249:
250: dolocal(fp, buf, n)
251: char *buf;
252: {
253: char lbuf[128+1];
254: register char *lp;
255: struct sgttyb nsgbuf;
256: register struct mesg *mp = (struct mesg *)buf;
257:
258: ioctl(0, FIOPOPLD, (char *)0);
259: ioctl(0, TIOCFLUSH, (char *)0);
260: ioctl(0, TIOCGETP, &nsgbuf);
261: ioctl(0, TIOCSETP, &sgbuf);
262: chmod(ttyn, perms);
263: for (;;) {
264: lp = lbuf;
265: printf( "dcon>> ");
266: fflush(stdout);
267: while (lp < &lbuf[128] && read(0, lp, 1)>0 && *lp!='\n')
268: lp++;
269: *lp = '\0';
270: if (*lbuf=='i')
271: break;
272: else if (*lbuf=='q'||*lbuf=='x'||*lbuf=='.')
273: exit(0);
274: else if (*lbuf=='!') {
275: system(lbuf+1);
276: printf("!!\n");
277: fflush(stdout);
278: mp->type = 0;
279: break;
280: } else if (*lbuf=='\0') {
281: mp->type = 0;
282: break;
283: } else {
284: printf("[qx.] to exit, i for quit signal, !cmd for shell\n");
285: fflush(stdout);
286: }
287: }
288: ioctl(0, TIOCSETP, &nsgbuf);
289: ioctl(0, FIOPUSHLD, &mesg_ld);
290: chmod(ttyn, 0);
291: if (mp->type) {
292: mp->magic = MSGMAGIC; /* safety */
293: write(fp, buf, n);
294: }
295: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.