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