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