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