|
|
1.1 root 1: #include <stdio.h>
2: #include <errno.h>
3: #include <dk.h>
4: #include <sgtty.h>
5: #include <sys/stream.h>
6: #include <signal.h>
7:
8: /*
9: * program to run a command
10: * on another cpu on Datakit w/ tranarent ioctls
11: */
12:
13: int rem; /* remote file descriptor */
14: extern int mesg_ld;
15: extern errno;
16: extern char *dkerror;
17:
18: struct mesg{
19: short type;
20: short size;
21: };
22:
23: char *std = "-";
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: hupcatch()
55: {
56:
57: if(ioctl(0, FIOLOOKLD, 0) == mesg_ld)
58: ioctl(0, FIOPOPLD, 0);
59: exit(0);
60: }
61:
62: main(argc, argv)
63: char **argv;
64: {
65: char *host, *cmd;
66:
67: host = cmd = basename(argv[0]);
68: if(strcmp(host, "rx")==0 || strcmp(host, "rexec")==0
69: || strcmp(host, "nrx")==0){
70: host=argv[1];
71: argv++;
72: }
73: if(host==0){
74: fprintf(stderr, "usage: %s host [command]\n", cmd);
75: exit(1);
76: }
77: if(argv[1]==0){
78: fprintf(stderr, "%s: cannot dcon\n", cmd);
79: exit(1);
80: }
81: rem = mesgexec(host, bldargs(&argv[1]));
82: if (rem<0) {
83: fprintf(stderr, "%s: call to %s failed: %s\n", cmd , host, dkerror);
84: exit(1);
85: }
86: if(ioctl(0, FIOPUSHLD, &mesg_ld) < 0){
87: fprintf(stderr, "%s: can't push mesg_ld\n", cmd);
88: exit(1);
89: }
90: signal(SIGHUP, hupcatch);
91: signal(SIGPIPE, SIG_IGN);
92:
93: go(rem);
94:
95: hupcatch();
96: /* NOTREACHED */
97: }
98:
99: go(fd)
100: {
101: int rbits, wbits, n;
102: char buf[4096+sizeof(struct mesg)];
103: struct mesg *mp;
104:
105: mp = (struct mesg *) buf;
106: wbits = 0;
107: while(1){
108: rbits = 1 | (1<<fd);
109: if(select(20, &rbits, &wbits, 20000) < 0){
110: if(errno != EINTR)
111: return;
112: continue;
113: }
114: if(rbits & 1){
115: n = read(0, buf, sizeof(buf));
116: if(n <= 0)
117: return;
118: if(write(fd, buf, n) != n)
119: return;
120: if(mp->type == M_FLUSH)
121: remflush();
122: }
123: if(rbits & (1<<fd)){
124: n = read(fd, buf, sizeof(buf));
125: if(n <= 0)
126: return;
127: if(mp->type == M_HANGUP)
128: return;
129: if(mp->type == M_IOCTL){
130: doioctl(buf, n);
131: } else {
132: if(write(1, buf, n) != n)
133: return;
134: }
135: }
136: }
137: }
138:
139: doioctl(buf, n)
140: char *buf;
141: {
142: struct mesg *mp;
143: struct iofoo{
144: int cmd;
145: union{
146: int i;
147: char errno;
148: struct insld insld;
149: } u;
150: } *iop;
151: int cmd, ld;
152:
153: iop = (struct iofoo *)(buf + sizeof(struct mesg));
154: mp = (struct mesg *) buf;
155:
156: cmd = iop->cmd;
157: n -= sizeof(struct mesg);
158: n -= sizeof(iop->cmd);
159: switch(cmd){
160: case FIOLOOKLD:
161: if(n > 0)
162: ld = iop->u.i;
163: else
164: ld = 0;
165: ld++;
166: if(ioctl(1, FIOLOOKLD, &ld) < 0)
167: goto bad;
168: iop->cmd = ld;
169: n = sizeof(iop->cmd);
170: break;
171:
172: case FIOPOPLD:
173: if(n > 0)
174: ld = iop->u.i;
175: else
176: ld = 0;
177: ld++;
178: if(ioctl(1, FIOPOPLD, &ld) < 0)
179: goto bad;
180: n = 0;
181: break;
182:
183: case FIOPUSHLD:
184: iop->u.insld.level = 0;
185: /* fall through... */
186: case FIOINSLD:
187: iop->u.insld.level++;
188: if(ioctl(1, FIOINSLD, &(iop->u.insld)) < 0)
189: goto bad;
190: n = 0;
191: break;
192:
193: default:
194: write(1, buf, sizeof(struct mesg) + mp->size);
195: return;
196: }
197: /* locally successful */
198: mp->type = M_IOCACK;
199: mp->size = n;
200: write(rem, buf, sizeof(struct mesg) + mp->size);
201: return;
202: bad:
203: mp->type = M_IOCNAK;
204: mp->size = sizeof(struct iofoo);
205: iop->u.errno = errno;
206: write(rem, buf, sizeof(struct mesg) + mp->size);
207: }
208:
209: remflush()
210: {
211: char buf[5000];
212: struct mesg *mp;
213: int n;
214:
215: mp = (struct mesg *) buf;
216: mp->type = M_IOCTL;
217: mp->size = sizeof(int);
218: write(rem, buf, mp->size + sizeof(struct mesg));
219:
220: while((n = read(rem, buf, sizeof(buf))) > 0){
221: if(mp->type == M_IOCNAK || mp->type == M_IOCACK){
222: return;
223: }
224: }
225: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.