|
|
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.