|
|
1.1 root 1: #include "share.h"
2:
3: file files[FILES]; /* dynamic? */
4: int nfile = FILES;
5: int nmoffset;
6:
7: doput()
8: { int i;
9: for(i = 0; i < nfile; i++)
10: if(files[i].tag == client.tag)
11: break;
12: if(i >= nfile) {
13: error("put: tag 0x%x not found\n", client.tag);
14: client.errno = ENOENT;
15: return;
16: }
17: if(files[i].tag == roottag) /* never toss the root */
18: return;
19: close(files[i].fd);
20: files[i].fd = -1;
21: files[i].tag = 0;
22: free(files[i].name);
23: }
24:
25: /* real paranoia would check that name and fd still refer to the same file */
26: doupdate()
27: { int i,f = 0;
28: for(i = 0; i < nfile; i++)
29: if(files[i].tag == client.tag)
30: break;
31: if(i >= nfile) {
32: error("update: tag 0x%x not found\n", client.tag);
33: client.errno = ENOENT;
34: return;
35: }
36: errno = 0;
37: if(client.ta)
38: f++, client.ta += dtime;
39: else
40: client.ta = files[i].stb.st_atime;
41: if(client.tm)
42: f++, client.tm += dtime;
43: else
44: client.tm = files[i].stb.st_mtime;
45: if(f) /* could someone have changed the file name underfoot? */
46: utime(files[i].name, &client.ta);
47: if(errno) {
48: client.errno = errno;
49: error("update: utime errno %d\n", errno);
50: /* and forget the rest of it */
51: return;
52: }
53: if(client.mode != files[i].stb.st_mode) {
54: if(!isowner(&files[i].stb)) {
55: /* except for client root, this should never happen */
56: error("doupdate: client user %d not owner of %s (chmod)\n",
57: client.uid, files[i].name);
58: client.errno = EPERM;
59: return;
60: }
61: if(cray == 1) { /* stupid thing has no fchmod */
62: chmod(files[i].name, client.mode);
63: if(errno) {
64: error("chmod(%s,0%o) failed %d\n", files[i].name,
65: client.mode, errno);
66: return;
67: }
68: } else {
69: fchmod(files[i].fd, client.mode);
70: if(errno) {
71: error("fchmod(%s,0%o) failed %d\n", files[i].name,
72: client.mode, errno);
73: return;
74: }
75: }
76: }
77: /* refresh the stat? */
78: }
79:
80: doread()
81: { int i, n;
82: for(i = 0; i < nfile; i++)
83: if(client.tag == files[i].tag)
84: break;
85: if(i >= nfile) {
86: error("doread: tag 0x%x missing\n", client.tag);
87: client.errno = ENOENT;
88: return;
89: }
90: /* permissions check missing here */
91: /* trust the client, except for unknown users, and our policy on `other' */
92: /*if(clientuid() == -1 && !otherok) {
93: client.errno = EPERM;
94: return;
95: }*/ /*no point, can't get here */
96: /* if we're doing read-ahead, here's the spot */
97: if((files[i].stb.st_mode & S_IFMT) == S_IFDIR) {
98: /* fancy directory handling would go here
99: doreaddir(i);
100: return;*/
101: }
102: /* now we know that the headers for sndread add up to 16 bytes */
103: if(files[i].pos != client.offset) {
104: lseek(files[i].fd, client.offset, 0);
105: files[i].pos = client.offset; /* are you sure? */
106: }
107: if(16 + client.count > inlen) /* sanity */
108: client.count = inlen - 16;
109: n = read(files[i].fd, inbuf + 16, (int)client.count);
110: if(n < 0) {
111: files[i].pos = (unsigned int)-1; /* can't trust it? */
112: client.errno = errno;
113: return;
114: }
115: client.resplen = 16 + n; /* read sets it */
116: files[i].pos += n;
117: }
118:
119: dowrite(p)
120: unsigned char *p;
121: { int i, n;
122: for(i = 0; i < nfile; i++)
123: if(client.tag == files[i].tag)
124: break;
125: if(i >= nfile) {
126: debug("dowrite: tag 0x%x missing\n", client.tag);
127: client.errno = ENOENT;
128: return;
129: }
130: /*if(clientuid() == -1 && !otherok) {
131: client.errno = EPERM;
132: return;
133: }*/ /* no point, can't happen */
134: if(files[i].flags) {
135: client.errno = EPERM;
136: return;
137: }
138: if(files[i].pos != client.offset) {
139: lseek(files[i].fd, client.offset, 0);
140: files[i].pos = client.offset;
141: }
142: if(24 + client.count > inlen) {
143: client.errno = EFAULT;
144: return;
145: }
146: n = write(files[i].fd, inbuf + 24, (int)client.count); /* secret 24 */
147: if(n != client.count) {
148: client.errno = errno? errno: EIO;
149: files[i].pos = (unsigned int) -1; /* ??? */
150: return;
151: }
152: files[i].pos += i;
153: }
154:
155: donami(p, len)
156: unsigned char *p;
157: { int i, offset;
158: unsigned char *s, *t, *bufend;
159: for(i = 0; i < nfile; i++)
160: if(client.tag == files[i].tag)
161: break;
162: if(i >= nfile) {
163: error("nami: tag 0x%x not found\n", client.tag);
164: client.errno = ENOENT;
165: return;
166: }
167: debug("nbnami: tag 0x%x for %d\n", client.tag, i);
168: /* build the new name in nmbuf */
169: for(s = nmbuf, t = files[i].name; *t; )
170: *s++ = *t++;
171: *s++ = '/';
172: nmoffset = s - nmbuf;
173: bufend = s + len;
174: for(t = p; *t && s < bufend; t++) { /* two tests for paranoia */
175: if(s >= nmbuf + inlen) {
176: fatal("nami overran nmbuf\n");
177: client.errno = EFAULT;
178: return;
179: }
180: *s++ = *t;
181: }
182: *s = 0;
183: debug("nbnami: nmbuf |%s|\n", nmbuf);
184: /* first write the simple code and then worry about . and .. and null */
185: if(client.flags == 0) {
186: openit();
187: return;
188: }
189: switch(client.flags) {
190: default:
191: error("nami: unk flag %d\n", client.flags);
192: client.errno = EINVAL;
193: return;
194: case NI_NXCREAT: /* expects it not to exist */
195: creatit();
196: break;
197: case NI_LINK: /* expects it not to exist */
198: linkit();
199: break;
200: case NI_MKDIR: /* expects it not to exist */
201: mkdirit();
202: break;
203: case NI_RMDIR: /* expects it to exist */
204: rmdirit();
205: break;
206: case NI_DEL: /* expects it to exist */
207: delit();
208: break;
209: case NI_CREAT: /* doesn't care */
210: creatit();
211: break;
212: }
213: }
214:
215: /* are fd and name consistent? (when might they not be?) */
216: /* this is only called on fstat() or stats of the root */
217: dostat()
218: { static int t = 0;
219: int i, n;
220: struct stat *x;
221: if(++t % 3 == 1 || t < 3) {
222: i = time(0) - client.ta;
223: /* if(i != dtime)
224: error("client time %d host time %d dtime %d\n",
225: client.ta, time(0), i);
226: */
227: dtime = i;
228: }
229: for(i = 0; i < nfile; i++)
230: if(client.tag == files[i].tag)
231: break;
232: if(i >= nfile) {
233: error("dostat: tag %d not found\n", client.tag);
234: client.errno = ENOENT;
235: return;
236: }
237: n = fstat(files[i].fd, &files[i].stb);
238: if(n < 0) { /* this is probably a serious error */
239: error("dostat: returned errno %d %s(%d) %x\n", errno, files[i].name,
240: files[i].fd, files[i].tag);
241: client.errno = errno;
242: return;
243: }
244: x = &files[i].stb;
245: client.ino = x->st_ino;
246: client.dev = hostdev(x->st_dev);
247: client.nlink = x->st_nlink;
248: client.uid = hostuid(x->st_uid);
249: client.gid = hostgid(x->st_gid);
250: client.mode = x->st_mode; /* permission calculation? */
251: client.size = x->st_size;
252: client.ta = x->st_atime - dtime;
253: client.tm = x->st_mtime - dtime;
254: client.tc = x->st_ctime - dtime;
255: if(cray && client.size >= 0x80000000)
256: client.size = 0x7fffffff;
257: if((client.mode & S_IFMT) != S_IFREG && (client.mode & S_IFMT) != S_IFDIR)
258: client.mode = 0;
259: }
260:
261: /* paranoia suggests checking that fd and name are consistent */
262: dotrunc()
263: { int i, n;
264: for(i = 0; i < nfile; i++)
265: if(client.tag == files[i].tag)
266: break;
267: if(i >= nfile) {
268: error("trunc: tag %d not found\n", client.tag);
269: client.errno = ENOENT;
270: return;
271: }
272: if(clientuid() == -1 && !otherok) {
273: client.errno = EPERM;
274: return;
275: }
276: n = creat(files[i].name, files[i].stb.st_mode);
277: if(n < 0) {
278: error("dotrunc: creat errno %d %s\n", errno, files[i].name);
279: client.errno = errno;
280: return;
281: }
282: close(n);
283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.