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