|
|
1.1 root 1: /*
2: * files-11 subroutines,
3: * mostly concerned directly with
4: * filesystem structures
5: */
6:
7: #include <time.h>
8: #include <ctype.h>
9: #include <rf.h>
10: #include "files11.h"
11: #include "f11.h"
12:
13: #define NULL 0
14:
15: /*
16: * convert files-11 ascii time to unix binary time
17: * 13 bytes: DDMMMYYhhmmss
18: */
19:
20: static char *months[] = {
21: "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
22: "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", 0
23: };
24:
25: static int i2val();
26:
27: long
28: htoutime(ht)
29: register char *ht;
30: {
31: struct tm tm;
32: register int mon;
33:
34: if (*ht == 0)
35: return (0);
36: tm.tm_yday = 0;
37: tm.tm_mday = i2val(ht);
38: ht += 2;
39: for (mon = 0; months[mon]; mon++)
40: if (strncmp(ht, months[mon], 3) == 0)
41: break;
42: tm.tm_mon = mon;
43: ht += 3;
44: tm.tm_year = i2val(ht);
45: ht += 2;
46: tm.tm_hour = i2val(ht);
47: ht += 2;
48: tm.tm_min = i2val(ht);
49: ht += 2;
50: tm.tm_sec = i2val(ht);
51: return (timelocal(&tm, (char *)NULL));
52: }
53:
54: static int
55: i2val(s)
56: register char *s;
57: {
58: if (!isdigit(s[0]) || !isdigit(s[1]))
59: return (0);
60: return ((s[0]-'0') * 10 + (s[1]-'0'));
61: }
62:
63: /*
64: * convert f11 protection to unix permissions
65: * information is lost, most importantly the delete flag
66: */
67: int
68: htouperm(hp)
69: register int hp;
70: {
71: register int up;
72: register int i;
73:
74: hp >>= 4; /* discard `system' field */
75: up = 0;
76: for (i = 0; i < 3; i++) { /* and do owner, group, world */
77: up <<= 3;
78: if ((hp & 1) == 0) /* read */
79: up |= 4;
80: if ((hp & 2) == 0) /* write */
81: up |= 2;
82: if ((hp & 4) == 0) /* execute */
83: up |= 1;
84: hp >>= 4;
85: }
86: return (up);
87: }
88:
89: /*
90: * compute the file size
91: * use the FCS attributes if they look valid,
92: * else just count the blocks
93: */
94:
95: long
96: hfilesize(h)
97: register struct header *h;
98: {
99: register int i;
100: register long sz;
101: register Bmap *bp;
102:
103: if (h->h_fcs.f_rtyp != 0) {
104: sz = plong(h->h_fcs.f_efbk) - 1;
105: sz *= BLKSIZ;
106: sz += h->h_fcs.f_ffby;
107: return (sz);
108: }
109: for (sz = 0, i = 0; bp = getmap(&h->h_map, i); i++)
110: sz += bp->count;
111: return (sz * BLKSIZ);
112: }
113:
114: /*
115: * search a directory
116: * return the file id
117: */
118:
119: int
120: f11walk(df, name)
121: Rfile *df;
122: char *name;
123: {
124: struct filnam fn;
125: register struct directory *dp;
126: register struct filnam *fp;
127: register unsigned short bestfid, bestver;
128: char buf[BLKSIZ];
129: long bno;
130:
131: if (utohname(name, &fn) == 0) {
132: fserrno = RFEINVAL;
133: return (0);
134: }
135: bestfid = 0;
136: bestver = 0;
137: fp = &fn;
138: for (bno = 0; f11rblk(df, bno, buf) > 0; bno++) {
139: dp = (struct directory *)buf;
140: for (; dp < (struct directory *)&buf[BLKSIZ]; dp++) {
141: if (dp->d_fid.f_num == 0)
142: continue;
143: if (dp->d_fname.f_nam[0] != fp->f_nam[0]
144: || dp->d_fname.f_nam[1] != fp->f_nam[1]
145: || dp->d_fname.f_nam[2] != fp->f_nam[2]
146: || dp->d_fname.f_typ != fp->f_typ)
147: continue;
148: if (dp->d_fname.f_ver == fp->f_ver)
149: return (dp->d_fid.f_num); /* exact match */
150: if (fp->f_ver)
151: continue; /* exact wanted */
152: if (dp->d_fname.f_ver > bestver) {
153: bestver = dp->d_fname.f_ver;
154: bestfid = dp->d_fid.f_num;
155: }
156: }
157: }
158: if (bestfid == 0)
159: fserrno = RFENOENT;
160: return (bestfid);
161: }
162:
163: /*
164: * convert an ascii filename into a files-11 one
165: * unspecified parts are left 0
166: * returns 0 for bad filename, 1 for ok
167: */
168:
169: int
170: utohname(name, f)
171: char *name;
172: register struct filnam *f;
173: {
174: char *n;
175: register char *e;
176: register int i;
177: register int x;
178:
179: f->f_nam[0] = f->f_nam[1] = f->f_nam[2] = 0;
180: f->f_typ = 0;
181: f->f_ver = 0;
182: n = name;
183: for (e = n; *e && *e != '.'; e++)
184: ;
185: if (e - n > 9)
186: return (0);
187: if (*e)
188: *e++ = 0;
189: for (i = 0; i < 3; i++) {
190: if ((x = ator50(&n)) < 0)
191: return (0);
192: f->f_nam[i] = x;
193: }
194: n = e;
195: for (; *e && *e != '.'; e++)
196: ;
197: if (e - n > 3)
198: return (0);
199: if (*e)
200: *e++ = 0;
201: if ((x = ator50(&n)) < 0)
202: return (0);
203: f->f_typ = x;
204: if (*e) {
205: x = atoi(e);
206: if (x < 0 || x > 65535)
207: return (0);
208: f->f_ver = x;
209: }
210: return (1);
211: }
212:
213: /*
214: * read a block from a file
215: */
216: int
217: f11rblk(f, bno, buf)
218: Rfile *f;
219: long bno;
220: char *buf;
221: {
222: register Bmap *bp;
223:
224: if ((bp = getblk(fsp(f), bno)) == NULL)
225: return (0);
226: lseek(diskfd, (long)bp->bno * BLKSIZ, 0);
227: if (read(diskfd, buf, BLKSIZ) != BLKSIZ)
228: return (-1);
229: return (1);
230: }
231:
232: /*
233: * get the header for a file
234: */
235:
236: int
237: gethdr(fid, hp)
238: unsigned short fid;
239: struct header *hp;
240: {
241: long bno;
242: register Bmap *bp;
243:
244: bno = IBITMAP + home.H_ibsz + fidtob(fid);
245: if ((bp = getblk(&indexf, bno)) == NULL)
246: return (0);
247: lseek(diskfd, (long)bp->bno * BLKSIZ, 0);
248: if (read(diskfd, (char *)hp, sizeof(*hp)) != sizeof(*hp))
249: return (0);
250: if (hp->h_fnum != fid)
251: fprint(2, "gethdr: wanted fid %d, got %d\n", fid, hp->h_fnum);
252: return (1);
253: }
254:
255: /*
256: * get the map for a chunk of a file,
257: * starting at block bno
258: */
259:
260: Bmap *
261: getblk(fsf, bno)
262: register Fsfile *fsf;
263: long bno;
264: {
265: static Bmap b;
266: long offset;
267: int mi;
268: long mbno;
269: register Bmap *bp;
270:
271: offset = bno - fsf->lbase;
272: if (offset > 0 && offset < fsf->lmap.count) { /* within cached map */
273: b.count = fsf->lmap.count - offset;
274: b.bno = fsf->lmap.bno + offset;
275: return (&b);
276: }
277: if (offset > 0) {
278: mi = fsf->lmi + 1;
279: mbno = fsf->lbase + fsf->lmap.count;
280: } else {
281: mi = 0;
282: mbno = 0;
283: }
284: while ((bp = getmap(&fsf->h.h_map, mi)) != NULL) {
285: if (mbno + bp->count < bno) {
286: mbno += bp->count;
287: mi++;
288: continue;
289: }
290: fsf->lbase = mbno;
291: fsf->lmi = mi;
292: fsf->lmap = *bp;
293: offset = bno - mbno;
294: b.count = bp->count - offset;
295: b.bno = bp->bno + offset;
296: return (&b);
297: }
298: return (NULL);
299: }
300:
301: /*
302: * fetch the n'th retrieval pointer from a map
303: * no hope for extended headers yet
304: */
305:
306: #define RS(c, l) ((c << 8)|l)
307:
308: Bmap *
309: getmap(m, n)
310: register struct map *m;
311: int n;
312: {
313: static Bmap b;
314: register unsigned char *p;
315: register int off;
316:
317: off = m->m_ctsz + m->m_lbsz;
318: off *= n;
319: if (off >= m->m_use * sizeof(short))
320: return (NULL);
321: p = m->m_rtrvp + off;
322: switch (RS(m->m_ctsz, m->m_lbsz)) {
323: case RS(1, 3):
324: b.count = p[1];
325: b.bno = (p[0]<<24) | p[2] | (p[3]<<8);
326: break;
327:
328: case RS(2, 2):
329: b.count = p[0] | (p[1]<<8);
330: b.bno = p[2] | (p[3]<<8);
331: break;
332:
333: case RS(2, 4):
334: b.count = p[0] | (p[1]<<8);
335: b.bno = (p[3]<<16) | (p[4]<<24) | p[4] | (p[5]<<8);
336: break;
337:
338: default:
339: return (NULL);
340: }
341: b.count++;
342: return (&b);
343: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.