|
|
1.1 ! root 1: #include "share.h" ! 2: #include "signal.h" ! 3: /* this is the main server routine. All the real work is in work.c, but ! 4: * the messages are built here, and converted from the client's types */ ! 5: ! 6: struct client client; ! 7: unsigned char *inbuf, *nmbuf; ! 8: int inlen, hisdev, proto, iamroot; ! 9: int clienttype; ! 10: extern char *cmdname[]; ! 11: ! 12: server(len) ! 13: { int i, n; ! 14: inbuf = (unsigned char *) malloc(inlen = len); ! 15: nmbuf = (unsigned char *) malloc(inlen); ! 16: error("max msg %d bytes\n", len); ! 17: iamroot = getuid() == 0; ! 18: getexcepts(); /* read the exception table */ ! 19: getuids(); ! 20: getgids(); ! 21: doneexcepts(); ! 22: /* put the root into files[] */ ! 23: addroot(); ! 24: signals(); ! 25: loop: ! 26: switch(proto) { ! 27: default: ! 28: fatal("unk protocol %d |%c|\n", proto, proto); ! 29: case 'd': /* datakit, so messages */ ! 30: n = read(cfd, inbuf, inlen); ! 31: if(n < 16) /* header is known to be 16 bytes long */ ! 32: fatal("server read %d (<16)\n", n); ! 33: if(inbuf[0] != NETB) ! 34: fatal("server wanted version %d, got %d\n", NETB, inbuf[0]); ! 35: break; ! 36: case 't': /* tcp, wretched byte stream */ ! 37: n = tcpread(); ! 38: break; ! 39: } ! 40: /* now convert the damned structures */ ! 41: debug("server %d bytes for %s (%d)\n", n, cmdname[inbuf[1]], inbuf[1]); ! 42: fromclient(n); ! 43: goto loop; ! 44: } ! 45: ! 46: gotsig(n) ! 47: { ! 48: error("exiting on signal %d\n", n); ! 49: abort(); ! 50: exit(1); ! 51: } ! 52: ! 53: signals() ! 54: { int i; ! 55: for(i = 1; i < NSIG; i++) ! 56: signal(i, gotsig); ! 57: } ! 58: ! 59: tcpread() ! 60: { unsigned char *p; ! 61: int cnt, n, len; ! 62: p = inbuf; ! 63: /* first read a sendb struct, which is known to be 16 bytes long */ ! 64: cnt = 0; ! 65: moreheader: ! 66: n = read(cfd, p, inlen); ! 67: if(n < 0) ! 68: fatal("tcpread -1 (%d)\n", errno); ! 69: if(n == 0) ! 70: fatal("tcp first read 0\n"); ! 71: p += n; ! 72: cnt += n; ! 73: if(cnt < 16) ! 74: goto moreheader; ! 75: /* the first byte must be NETB */ ! 76: if(inbuf[0] != NETB) ! 77: fatal("tcp read version %d, not %d\n", inbuf[0], NETB); ! 78: len = clientlong(inbuf + 8); /* server knows where len is in header */ ! 79: if(cnt > len) ! 80: fatal("tcp read %d (>%d)\n", cnt, len); ! 81: more: ! 82: if(cnt >= len) ! 83: return(cnt); ! 84: n = read(cfd, p, len - cnt); ! 85: if(n <= 0) ! 86: fatal("tcp read loop %d after %d (%d)\n", n, cnt, errno); ! 87: cnt += n; ! 88: p += n; ! 89: goto more; ! 90: } ! 91: ! 92: struct client nilclient; ! 93: /* knows what clients send. when they're not all vaxes, change this */ ! 94: fromclient(len) ! 95: { unsigned char *p = inbuf; ! 96: client = nilclient; /* can you remember who sets what? */ ! 97: /* first the struct sendb */ ! 98: p++; /* skip version */ ! 99: client.cmd = *p++; ! 100: client.flags = *p++; ! 101: p++; /* skip */ ! 102: client.trannum = clientlong(p); ! 103: p += 4; ! 104: client.len = clientlong(p); ! 105: p += 4; ! 106: client.tag = clientlong(p); ! 107: p += 4; ! 108: if(client.len != len) ! 109: fatal("client sent %d, claimed len was %d\n", len, client.len); ! 110: if(client.tag == 0) { ! 111: error("client sent tag 0 (cmd %d)\n", client.cmd); ! 112: client.errno = ENOENT; ! 113: goto respond; ! 114: } ! 115: /* now per individual requirement */ ! 116: switch(client.cmd) { ! 117: default: ! 118: fatal("client send unknown command %d %d\n", client.cmd, inbuf[1]); ! 119: case NBPUT: ! 120: if(len != p - inbuf) ! 121: fatal("client put size, %d (!= %d)\n", len, p - inbuf); ! 122: doput(); ! 123: break; ! 124: case NBUPD: ! 125: p += 4; /* skip */ ! 126: client.uid = clientshort(p); ! 127: p += 2; ! 128: client.gid = clientshort(p); ! 129: p += 2; ! 130: client.mode = clientshort(p); ! 131: p += 2; ! 132: client.dev = clientshort(p); ! 133: p += 2; ! 134: p += 4; /* skip */ ! 135: client.ta = clientlong(p); ! 136: p += 4; ! 137: client.tm = clientlong(p); ! 138: p += 4; ! 139: if(len != p - inbuf) ! 140: fatal("client upd size, %d (!= %d)\n", len, p - inbuf); ! 141: doupdate(); ! 142: break; ! 143: case NBREAD: ! 144: client.count = clientlong(p); /* sanity check in doread() */ ! 145: p += 4; ! 146: client.offset = clientlong(p); ! 147: p += 4; ! 148: if(len != p - inbuf) ! 149: fatal("client read size, %d (!= %d)\n", len, p - inbuf); ! 150: doread(); ! 151: break; ! 152: case NBWRT: ! 153: client.count = clientlong(p); /* sanity check in dowrite() */ ! 154: p += 4; ! 155: client.offset = clientlong(p); ! 156: p += 4; ! 157: if(len != p - inbuf + client.count) ! 158: fatal("client write size, %d (!= %d)\n", len, p - inbuf + client.count); ! 159: dowrite(p); ! 160: break; ! 161: case NBNAMI: ! 162: p += 4; /* skip */ ! 163: client.uid = clientshort(p); ! 164: p += 2; ! 165: client.gid = clientshort(p); ! 166: p += 2; ! 167: client.mode = clientshort(p); ! 168: p += 2; ! 169: client.dev = clientshort(p); ! 170: p += 2; ! 171: client.ino = clientlong(p); ! 172: p += 4; ! 173: donami(p, len - (p - inbuf)); ! 174: break; ! 175: case NBSTAT: ! 176: client.ta = clientlong(p); ! 177: p += 4; ! 178: p += 4; /* skip */ ! 179: if(len != p - inbuf) ! 180: fatal("client stat too long, %d (> %d)\n", len, p - inbuf); ! 181: dostat(); ! 182: break; ! 183: case NBTRNC: ! 184: if(len != p - inbuf) ! 185: fatal("client trunc too long, %d (> %d)\n", len, p - inbuf); ! 186: dotrunc(); ! 187: break; ! 188: } ! 189: respond: ! 190: responce(client.cmd); ! 191: } ! 192: #ifdef ns32000 ! 193: #define vax 1 ! 194: #endif ! 195: #if vax == 1 ! 196: /* clients to vax */ ! 197: clientlong(p) ! 198: unsigned char *p; ! 199: { ! 200: switch (clienttype) { ! 201: case 'v': ! 202: return(*(long *)p); ! 203: case 's': ! 204: return(rev4(p)); ! 205: } ! 206: } ! 207: ! 208: clientshort(p) ! 209: unsigned char *p; ! 210: { ! 211: switch (clienttype) { ! 212: case 'v': ! 213: return(*(short *)p); ! 214: case 's': ! 215: return(rev2(p)); ! 216: } ! 217: } ! 218: #endif ! 219: #if cray == 1 ! 220: /* client to cray */ ! 221: clientlong(p) ! 222: unsigned char *p; ! 223: { union { ! 224: int x; ! 225: unsigned char b[8]; ! 226: } u; ! 227: int i; ! 228: u.x = 0; ! 229: switch (clienttype) { ! 230: case 'v': ! 231: for(i = 0; i < 4; i++) ! 232: u.b[7-i] = *p++; ! 233: return(u.x); ! 234: case 's': ! 235: for(i = 0; i < 4; i++) ! 236: u.b[4+i] = *p++; ! 237: return(u.x); ! 238: } ! 239: } ! 240: clientshort(p) ! 241: unsigned char *p; ! 242: { union { ! 243: int x; ! 244: unsigned char b[8]; ! 245: } u; ! 246: int i; ! 247: u.x = 0; ! 248: switch (clienttype) { ! 249: case 'v': ! 250: for(i = 0; i < 2; i++) ! 251: u.b[7-i] = *p++; ! 252: return(u.x); ! 253: case 's': ! 254: for(i = 0; i < 2; i++) ! 255: u.b[6+i] = *p++; ! 256: return(u.x); ! 257: } ! 258: } ! 259: #endif ! 260: #if sun == 1 ! 261: /* client to sun */ ! 262: clientlong(p) ! 263: unsigned char *p; ! 264: { ! 265: switch (clienttype) { ! 266: case 'v': ! 267: return(rev4(p)); ! 268: case 's': ! 269: return(*(long *)p); ! 270: } ! 271: } ! 272: ! 273: clientshort(p) ! 274: unsigned char *p; ! 275: { ! 276: switch (clienttype) { ! 277: case 'v': ! 278: return(rev2(p)); ! 279: case 's': ! 280: return(*(short *)p); ! 281: } ! 282: } ! 283: #endif ! 284: ! 285: rev4(p) ! 286: unsigned char *p; ! 287: { union { ! 288: long x; ! 289: unsigned char b[4]; ! 290: } u; ! 291: int i; ! 292: for(i = 0; i < 4; i++) ! 293: u.b[3-i] = *p++; ! 294: return(u.x); ! 295: } ! 296: rev2(p) ! 297: unsigned char *p; ! 298: { union { /* this better work! */ ! 299: short x; ! 300: unsigned char b[2]; ! 301: } u; ! 302: int i; ! 303: u.x = 0; ! 304: for(i = 0; i < 2; i++) ! 305: u.b[1-i] = *p++; ! 306: return(u.x); ! 307: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.