|
|
1.1 root 1: #include <stdio.h>
2: #include <errno.h>
3: #include <dk.h>
4: #include <sys/types.h>
5: #include <sys/stat.h>
6: #include <sys/filio.h>
7: #include <sys/ttyio.h>
8: #include <sys/stream.h>
9: #include <signal.h>
10:
11: /*
12: * program to run a command
13: * on another cpu on Datakit w/ transparent ioctls,
14: * sometimes.
15: */
16:
17: #define msglen(mp) ((mp)->losize + ((mp)->hisize<<8))
18:
19: int rem; /* remote file descriptor */
20: extern int mesg_ld;
21: extern errno;
22: extern char *dkerror;
23: int nomesg;
24:
25: #define MAXCHARS 8192
26: char args[MAXCHARS];
27:
28: char *bldargs(argv)
29: register char *argv[];
30: {
31: register char *s=args, *t;
32: while(t= *argv++){ /* assignment = */
33: while(*s = *t++)
34: if(s++ >= &args[MAXCHARS-1]){
35: fprintf(stderr, "rx: arg list too long\n");
36: exit(1);
37: }
38: *s++=' ';
39: }
40: s[-1]='\0';
41: return(args);
42: }
43:
44: char *
45: basename(s)
46: register char *s;
47: {
48: register char *t;
49: extern char *rindex();
50: t=rindex(s, '/');
51: return(t? t+1 : s);
52: }
53:
54: setmsgl(mp, n)
55: register struct mesg *mp;
56: int n;
57: {
58: mp->losize = n;
59: mp->hisize = n >> 8;
60: }
61:
62: finish()
63: {
64:
65: if(ioctl(0, FIOLOOKLD, 0) == mesg_ld) {
66: ioctl(0, FIOPOPLD, 0);
67: ioctl(0, TIOCFLUSH, 0);
68: }
69: exit(0);
70: }
71:
72: main(argc, argv)
73: char **argv;
74: {
75: char *host, *cmd;
76:
77: host = cmd = basename(argv[0]);
78: if(strcmp(host, "rx")==0 || strcmp(host, "rexec")==0
79: || strcmp(host, "nrx")==0){
80: host=argv[1];
81: argv++;
82: }
83: if(host==0){
84: fprintf(stderr, "usage: %s host [command]\n", cmd);
85: exit(1);
86: }
87: if(argv[1]==0){
88: execl("/usr/bin/ndcon", argv[1], argv[1], (char *)0);
89: perror("ndcon");
90: exit(1);
91: }
92: rem = mesgexec(host, bldargs(&argv[1]));
93: if (rem<0) {
94: fprintf(stderr, "%s: call to %s failed: %s\n", cmd , host, dkerror);
95: exit(1);
96: }
97: setmesg();
98: signal(SIGHUP, finish);
99: signal(SIGPIPE, SIG_IGN);
100: go(rem);
101: finish();
102: /* NOTREACHED */
103: }
104:
105: /*
106: * if standard input and output are the same,
107: * try to push the message line discipline
108: * otherwise we're in a pipeline and it's not safe
109: */
110: setmesg()
111: {
112: struct stat st0, st1;
113:
114: if (fstat(0, &st0) < 0 || fstat(1, &st1) < 0
115: || st0.st_dev != st1.st_dev || st0.st_ino != st1.st_ino) {
116: nomesg = 1;
117: return;
118: }
119: if(ioctl(0, FIOPUSHLD, &mesg_ld) < 0)
120: nomesg = 1;
121: }
122:
123: /*
124: * hack:
125: * until some message comes back from the remote,
126: * ignore local data
127: */
128: go(fd)
129: {
130: int rbits, wbits, srbits;
131: int n;
132: char buf[4096+MSGHLEN];
133: struct mesg *mp;
134: int first = 0;
135:
136: mp = (struct mesg *) buf;
137: wbits = 0;
138: srbits = (1<<0)|(1<<fd);
139: while(1){
140: rbits = srbits;
141: if(select(20, &rbits, &wbits, 20000) < 0){
142: if(errno != EINTR)
143: return;
144: continue;
145: }
146: if(rbits & 1){
147: n = rdmesg(0, buf, sizeof(buf));
148: if(n <= 0) {
149: srbits &=~ 1;
150: continue;
151: }
152: mp->magic = MSGMAGIC; /* temporary safety */
153: if(write(fd, buf, n) != n)
154: return;
155: if(mp->type == M_FLUSH)
156: remflush();
157: }
158: if(rbits & (1<<fd)){
159: n = read(fd, buf, sizeof(buf));
160: if(n <= 0)
161: return;
162: if(mp->type == M_HANGUP)
163: return;
164: if(mp->type == M_IOCTL){
165: doioctl(buf, n);
166: } else {
167: mp->magic = MSGMAGIC; /* temp safety */
168: if(wrmesg(1, buf, n) != n)
169: return;
170: }
171: }
172: }
173: }
174:
175: #define MAXEOF 10
176:
177: rdmesg(f, buf, n)
178: char *buf;
179: {
180: register struct mesg *mp;
181: static int eof = 0;
182:
183: if (nomesg == 0)
184: return (read(f, buf, n));
185: if (eof > MAXEOF)
186: return (0);
187: n = read(f, buf + MSGHLEN, n - (2 * MSGHLEN));
188: if (n < 0)
189: return (n);
190: mp = (struct mesg *)buf;
191: if (n == 0) {
192: eof++;
193: mp->type = M_DELIM;
194: mp->magic = MSGMAGIC;
195: setmsgl(mp, 0);
196: return (MSGHLEN);
197: }
198: eof = 0;
199: setmsgl(buf, n);
200: mp->type = M_DATA;
201: mp->magic = MSGMAGIC;
202: mp = (struct mesg *)(buf + MSGHLEN + n);
203: mp->type = M_DELIM;
204: mp->magic = MSGMAGIC;
205: setmsgl(buf, 0);
206: return (n + 2*MSGHLEN);
207: }
208:
209: wrmesg(f, buf, n)
210: char *buf;
211: {
212: if (nomesg == 0)
213: return (write(f, buf, n));
214: if (((struct mesg *)buf)->type != M_DATA)
215: return (n); /* toss it */
216: if (write(f, buf + MSGHLEN, n - MSGHLEN) != n - MSGHLEN)
217: return (-1);
218: return (n);
219: }
220:
221: doioctl(buf, n)
222: char *buf;
223: {
224: struct mesg *mp;
225: struct iofoo{
226: int cmd;
227: union{
228: int i;
229: char errno;
230: struct insld insld;
231: } u;
232: } *iop;
233: int cmd, ld;
234:
235: iop = (struct iofoo *)(buf + MSGHLEN);
236: mp = (struct mesg *) buf;
237: if (nomesg) {
238: errno = ENOTTY;
239: goto bad;
240: }
241: cmd = iop->cmd;
242: n -= MSGHLEN;
243: n -= sizeof(iop->cmd);
244: switch(cmd){
245: case FIOLOOKLD:
246: if(n > 0)
247: ld = iop->u.i;
248: else
249: ld = 0;
250: ld++;
251: if(ioctl(1, FIOLOOKLD, &ld) < 0)
252: goto bad;
253: iop->cmd = ld;
254: n = sizeof(iop->cmd);
255: break;
256:
257: case FIOPOPLD:
258: if(n > 0)
259: ld = iop->u.i;
260: else
261: ld = 0;
262: ld++;
263: if(ioctl(1, FIOPOPLD, &ld) < 0)
264: goto bad;
265: n = 0;
266: break;
267:
268: case FIOPUSHLD:
269: iop->u.insld.level = 0;
270: /* fall through... */
271: case FIOINSLD:
272: iop->u.insld.level++;
273: if(ioctl(1, FIOINSLD, &(iop->u.insld)) < 0)
274: goto bad;
275: n = 0;
276: break;
277:
278: default:
279: mp->magic = MSGMAGIC; /* safety */
280: write(1, buf, MSGHLEN + msglen(mp));
281: return;
282: }
283: /* locally successful */
284: mp->type = M_IOCACK;
285: mp->magic = MSGMAGIC;
286: setmsgl(mp, n);
287: write(rem, buf, MSGHLEN + msglen(mp));
288: return;
289: bad:
290: mp->type = M_IOCNAK;
291: mp->magic = MSGMAGIC;
292: setmsgl(mp, sizeof(struct iofoo));
293: iop->u.errno = errno;
294: n = write(rem, buf, MSGHLEN + msglen(mp));
295: }
296:
297: remflush()
298: {
299: char buf[5000];
300: struct mesg *mp;
301: int n;
302:
303: mp = (struct mesg *) buf;
304: mp->type = M_IOCTL;
305: mp->magic = MSGMAGIC;
306: setmsgl(mp, sizeof(int));
307: write(rem, buf, MSGHLEN + msglen(mp));
308:
309: while((n = read(rem, buf, sizeof(buf))) > 0){
310: if(mp->type == M_IOCNAK || mp->type == M_IOCACK){
311: return;
312: }
313: }
314: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.