|
|
1.1 root 1: /*
2: * process client requests
3: */
4:
5: #include "faceproto.h"
6: #include "faces.h"
7: #include <sys/types.h>
8: #include <sys/stat.h>
9: #include <stdio.h> /* just for NULL */
10:
11: /*
12: * process one request
13: * returns 1 if all is well,
14: * 0 if client communication fell down
15: */
16: dorequest(fd)
17: int fd;
18: {
19: char msg[F_DATA+FMAXDATA+1];
20: register unsigned char *p;
21: int n, len;
22: File *f;
23: long off;
24: int bsize;
25:
26: p = (unsigned char *)msg;
27: if ((n = gread(fd, msg, F_DATA)) != F_DATA) { /* read header */
28: if (n != 0) /* don't fuss about EOF */
29: log("fd %d: bad header: read %d\n", fd, n);
30: return (0);
31: }
32: len = frfshort(p, F_LEN);
33: if (len < 0 || len > FMAXDATA) {
34: log("fd %d: ill message len %d\n", fd, len);
35: return (0);
36: }
37: if (len && (n = gread(fd, msg+F_DATA, len)) != len) {
38: log("fd %d: bad data read: want %d got %d\n", fd, len, n);
39: return (0);
40: }
41: msg[F_DATA + len] = 0;
42: switch(p[F_TYPE]) {
43: case DOSTAT:
44: if ((f = lookfile(p + F_DATA)) == NULL
45: || dostat(f) < 0) {
46: toflong(p, F_P1, -1);
47: len = 0;
48: } else {
49: copystat(f, p + F_DATA);
50: toflong(p, F_P1, 0);
51: len = STLEN;
52: }
53: break;
54:
55: case DOREAD:
56: off = frflong(p, F_P1);
57: bsize = frflong(p, F_P2);
58: if (bsize <= 0 || bsize > FMAXDATA
59: || (f = lookfile(p + F_DATA)) == NULL
60: || (len = doread(f, msg + F_DATA, bsize, off)) < 0) {
61: toflong(p, F_P1, -1);
62: len = 0;
63: } else
64: toflong(p, F_P1, len);
65: break;
66:
67: default:
68: log("fd %d: ill msg %d\n", fd, p[F_TYPE]);
69: return (0);
70: }
71: tofshort(p, F_LEN, len);
72: len += F_DATA; /* header */
73: if ((n = write(fd, msg, len)) != len) {
74: log("fd %d: write %d returned %d\n", fd, len, n);
75: return (0);
76: }
77: return (1);
78: }
79:
80: dostat(f)
81: register File *f;
82: {
83: struct stat st;
84:
85: if (isdir(f))
86: f->size = f->nfiles * FDLEN;
87: else {
88: if (stat(f->data, &st) < 0)
89: return (-1);
90: f->size = st.st_size;
91: f->ta = st.st_atime;
92: f->tm = st.st_mtime;
93: f->tc = st.st_ctime;
94: }
95: return (0);
96: }
97:
98: copystat(f, s)
99: register File *f;
100: register unsigned char *s;
101: {
102:
103: tofshort(s, ST_DEV, 0); /* junk */
104: tofshort(s, ST_INO, f->ino);
105: if (isdir(f))
106: tofshort(s, ST_MODE, STDIR|0555);
107: else
108: tofshort(s, ST_MODE, 0444);
109: tofshort(s, ST_NLINK, f->nlinks);
110: tofshort(s, ST_UID, 0); /* junk */
111: tofshort(s, ST_GID, 0); /* junk */
112: tofshort(s, ST_RDEV, 0); /* junk */
113: toflong(s, ST_SIZE, f->size);
114: toflong(s, ST_ATIME, f->ta);
115: toflong(s, ST_MTIME, f->tm);
116: toflong(s, ST_CTIME, f->tc);
117: }
118:
119: /*
120: * reading regular files might be sped up
121: * by caching the file descriptor somewhere
122: */
123: doread(f, buf, len, off)
124: register File *f;
125: char *buf;
126: int len;
127: long off;
128: {
129: int fd;
130:
131: if (isdir(f)) {
132: if (f->data == NULL)
133: dirdata(f);
134: if (off + len > f->size)
135: len = f->size - off;
136: if (len < 0 || off < 0)
137: return (0);
138: memcpy(buf, f->data + off, len);
139: return (len);
140: }
141: if ((fd = open(f->data, 0)) < 0) {
142: log("%s: cannot open\n", f->data);
143: return (-1);
144: }
145: lseek(fd, off, 0);
146: len = read(fd, buf, len);
147: close(fd);
148: return (len);
149: }
150:
151: /*
152: * gather data that may come in dribs and drabs
153: */
154:
155: int
156: gread(fd, buf, size)
157: int fd;
158: char *buf;
159: int size;
160: {
161: register int n, tot;
162:
163: tot = 0;
164: while (size > 0) {
165: if ((n = read(fd, buf, size)) <= 0)
166: break;
167: buf += n;
168: size -= n;
169: tot += n;
170: }
171: if (tot)
172: return (tot);
173: return (n);
174: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.