|
|
1.1 root 1: /*
2: * run and mount a netb file server,
3: * including the uid-login name handshake protocol
4: */
5: #include <stdio.h>
6: #include <signal.h>
7: #include <errno.h>
8: #include <pwd.h>
9: #include <grp.h>
10: #include <sys/types.h> /* for makedev */
11:
12: #define NBFS 4 /* for fmount */
13:
14: /*
15: * setup handshake parameters
16: */
17: #define MAXMSG 5 /* largest message 5*MSGBLOCK -- known to kernel too */
18: #define MSGBLOCK 1024
19:
20: int debug; /* debug level, for server */
21:
22: char *estr();
23:
24: main(argc, argv)
25: int argc;
26: char **argv;
27: {
28: int pfd[2];
29: int pid;
30: int sts;
31:
32: while (--argc > 0 && **++argv == '-') {
33: switch (argv[0][1]) {
34: case 'd':
35: debug = atoi(&argv[0][2]);
36: break;
37:
38: default:
39: fprintf(stderr, "unknown flag %s ignored\n", argv[0]);
40: break;
41: }
42: }
43: if (argc < 2) {
44: fprintf(stderr, "usage: runfs [-dlevel] mpoint server arg ...\n");
45: exit(1);
46: }
47: if (pipe(pfd) < 0) {
48: perror("pipe");
49: exit(1);
50: }
51: if ((pid = fork()) < 0) {
52: perror("fork");
53: exit(1);
54: }
55: /*
56: * child: run setup handshake, mount filesystem
57: */
58: if (pid == 0) {
59: close(pfd[1]); /* for clean error */
60: sts = setup(pfd[0], argv[0]);
61: exit(sts);
62: }
63: /*
64: * parent: exec server
65: */
66: close(pfd[0]);
67: dup2(pfd[1], 0);
68: dup2(pfd[1], 1);
69: close(pfd[1]);
70: execv(argv[1], &argv[1]);
71: fprintf(stderr, "exec %s: %s\n", argv[1], estr());
72: exit(1);
73: }
74:
75: /*
76: * initial protocol with server:
77: * client sends 16 bytes:
78: * max buffer size in 1024-byte units
79: * device number in use
80: * protocol letter
81: * debugging flag
82: * 12 unused
83: * server sends one byte: 1
84: * client sends a list of userids: maxsize bytes
85: * if list won't fit in one buffer, last username is `:'
86: * server acks with one byte 012; client sends more
87: * server sends one byte: 2
88: * client sends a list of groupids: maxsize bytes
89: * if list won't fit in one buffer, last groupname is `:'
90: * server acks with one byte 013; client sends more
91: * server sends one byte: 3
92: * then we mount it, and further messages come from the kernel
93: */
94:
95: #define M1LEN 16
96:
97: setup(fd, mpoint)
98: int fd;
99: char *mpoint;
100: {
101: char m[M1LEN];
102: register int n;
103:
104: signal(SIGPIPE, SIG_DFL);
105: memset(m, 0, M1LEN);
106: m[0] = MAXMSG;
107: /* m[1] = fp->devnum;. */
108: m[1] = 0; /* will this work? */
109: m[2] = 'd'; /* ignored by server? */
110: m[3] = debug;
111: alarm(600);
112: if ((n = write(fd, m, M1LEN)) != M1LEN) {
113: fprintf(stderr, "setup 1: write returned %d; %s\n", n, estr());
114: alarm(0);
115: return (-1);
116: }
117: if (getresp(fd, 1, mpoint) == 0)
118: return (-1);
119: alarm(600);
120: if (senduid(fd, mpoint) < 0) {
121: alarm(0);
122: return (-1);
123: }
124: alarm(600);
125: if (sendgid(fd, mpoint) < 0) {
126: alarm(0);
127: return (-1);
128: }
129: alarm(60);
130: alarm(60);
131: funmount(mpoint); /* bad -- might unmount wrong fs */
132: if (trymount(fd, mpoint) < 0) {
133: fprintf(stderr, "fmount: %s: %s\n", mpoint, estr());
134: alarm(0);
135: return (-1);
136: }
137: alarm(0);
138: return (0);
139: }
140:
141: /*
142: * fmount, but try to guess unique device number
143: */
144:
145: int
146: trymount(fd, mpoint)
147: int fd;
148: char *mpoint;
149: {
150: register int dev;
151:
152: for (dev = 200; dev >= 100; --dev) {
153: if (fmount(NBFS, fd, mpoint, makedev(dev, 0)) >= 0)
154: return (0);
155: if (errno != EBUSY)
156: return (-1);
157: }
158: return (-1);
159: }
160:
161: getresp(fd, id, mpoint)
162: int fd, id;
163: {
164: register int n;
165: char m;
166:
167: alarm(600);
168: n = read(fd, &m, 1);
169: alarm(0); /* assume errno untouched */
170: if (n != 1) {
171: fprintf(stderr, "setup %d: %s: read returned %d: %s\n", id, mpoint, n, estr());
172: return (0);
173: }
174: if (m != id) {
175: fprintf(stderr, "setup %d: %s: received %d (%c)\n", id, mpoint, (unsigned char)m, m);
176: return (0);
177: }
178: return (1);
179: }
180:
181: #define SLOP 50
182:
183: senduid(fd, mpoint)
184: int fd;
185: char *mpoint;
186: {
187: char idbuf[MAXMSG*MSGBLOCK+SLOP];
188: char onebuf[SLOP];
189: register char *p;
190: register struct passwd *pw;
191: register int n, wn;
192:
193: setpwent();
194: p = idbuf;
195: while ((pw = getpwent()) != NULL) {
196: sprintf(onebuf, "%s %d\n", pw->pw_name, pw->pw_uid);
197: n = strlen(onebuf);
198: if (n > &idbuf[MAXMSG*MSGBLOCK] - p - 4) { /* room for ": 1\n" */
199: strcpy(p, ": 1\n"); /* `more coming' */
200: if ((wn = write(fd, idbuf, MAXMSG*MSGBLOCK)) != MAXMSG*MSGBLOCK) {
201: fprintf(stderr, "%s: write uid: %d; %s\n", mpoint, wn, estr());
202: return (-1);
203: }
204: if (getresp(fd, 012, mpoint) == 0)
205: return (-1);
206: p = idbuf;
207: }
208: strcpy(p, onebuf);
209: p += n;
210: }
211: endpwent();
212: if ((wn = write(fd, idbuf, MAXMSG*MSGBLOCK)) != MAXMSG*MSGBLOCK) {
213: fprintf(stderr, "%s: write uid: %d; %s\n", mpoint, wn, estr());
214: return (-1);
215: }
216: if (getresp(fd, 2, mpoint) == 0)
217: return (-1);
218: return (0);
219: }
220:
221: sendgid(fd, mpoint)
222: int fd;
223: char *mpoint;
224: {
225: char idbuf[MAXMSG*MSGBLOCK+SLOP];
226: char onebuf[SLOP];
227: register char *p;
228: register struct group *gr;
229: register int n, wn;
230:
231: setgrent();
232: p = idbuf;
233: while ((gr = getgrent()) != NULL) {
234: sprintf(onebuf, "%s %d\n", gr->gr_name, gr->gr_gid);
235: n = strlen(onebuf);
236: if (n > &idbuf[MAXMSG*MSGBLOCK] - p - 4) { /* room for ": 1\n" */
237: strcpy(p, ": 1\n"); /* `more coming' */
238: if ((wn = write(fd, idbuf, MAXMSG*MSGBLOCK)) != MAXMSG*MSGBLOCK) {
239: fprintf(stderr, "%s: write gid: %d; %s\n", mpoint, wn, estr());
240: return (-1);
241: }
242: if (getresp(fd, 013, mpoint) == 0)
243: return (-1);
244: p = idbuf;
245: }
246: strcpy(p, onebuf);
247: p += n;
248: }
249: endgrent();
250: if ((wn = write(fd, idbuf, MAXMSG*MSGBLOCK)) != MAXMSG*MSGBLOCK) {
251: fprintf(stderr, "%s: write gid: %d; %s\n", mpoint, wn, estr());
252: return (-1);
253: }
254: if (getresp(fd, 3, mpoint) == 0)
255: return (-1);
256: return (0);
257: }
258:
259:
260: char *
261: estr()
262: {
263: static char buf[] = "Error -2147483648";
264:
265: if (errno < 0 || errno >= sys_nerr) {
266: sprintf(buf, "Error %d", errno);
267: return (buf);
268: }
269: return (sys_errlist[errno]);
270: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.