stamp for 4bsd
[unix-history] / usr / src / sys / stand.att / sys.c
CommitLineData
a7a8eebc 1/* sys.c 4.1 %G% */
a5a27f5c
BJ
2
3#include <sys/param.h>
4#include <sys/ino.h>
5#include <sys/inode.h>
6#include <sys/filsys.h>
7#include <sys/dir.h>
8#include "saio.h"
9
10ino_t dlook();
11
12static
13openi(n,io)
14register struct iob *io;
15{
16 register struct dinode *dp;
17
18 io->i_offset = 0;
19 io->i_bn = fsbtodb(itod(n)) + io->i_boff;
20 io->i_cc = BSIZE;
21 io->i_ma = io->i_buf;
22 devread(io);
23
24 dp = (struct dinode *)io->i_buf;
25 dp = &dp[itoo(n)];
26 io->i_ino.i_number = n;
27 io->i_ino.i_mode = dp->di_mode;
28 io->i_ino.i_size = dp->di_size;
29 l3tol((char *)io->i_ino.i_un.i_addr, (char *)dp->di_addr, NADDR);
30}
31
32static
33find(path, file)
34register char *path;
35struct iob *file;
36{
37 register char *q;
38 char c;
39 int n;
40
41 if (path==NULL || *path=='\0') {
42 printf("null path\n");
43 return(0);
44 }
45
46 openi((ino_t) ROOTINO, file);
47 while (*path) {
48 while (*path == '/')
49 path++;
50 q = path;
51 while(*q != '/' && *q != '\0')
52 q++;
53 c = *q;
54 *q = '\0';
55
56 if ((n=dlook(path, file))!=0) {
57 if (c=='\0')
58 break;
59 openi(n, file);
60 *q = c;
61 path = q;
62 continue;
63 } else {
64 printf("%s not found\n",path);
65 return(0);
66 }
67 }
68 return(n);
69}
70
71static daddr_t
72sbmap(io, bn)
73register struct iob *io;
74daddr_t bn;
75{
76 register i;
77 register struct inode *ip;
78 int j, sh;
79 daddr_t nb, *bap;
80 int ibn = bn;
81
82 ip = &io->i_ino;
83 if(bn < 0) {
84 printf("bn negative\n");
85 return((daddr_t)0);
86 }
87
88 /*
89 * blocks 0..NADDR-4 are direct blocks
90 */
91 if(bn < NADDR-3) {
92 i = bn;
93 nb = ip->i_un.i_addr[i];
94 return(nb);
95 }
96
97 /*
98 * addresses NADDR-3, NADDR-2, and NADDR-1
99 * have single, double, triple indirect blocks.
100 * the first step is to determine
101 * how many levels of indirection.
102 */
103 sh = 0;
104 nb = 1;
105 bn -= NADDR-3;
106 for(j=3; j>0; j--) {
107 sh += NSHIFT;
108 nb <<= NSHIFT;
109 if(bn < nb)
110 break;
111 bn -= nb;
112 }
113 if(j == 0) {
114 printf("bn ovf %D\n",bn);
115 return((daddr_t)0);
116 }
117
118 /*
119 * fetch the address from the inode
120 */
121 nb = ip->i_un.i_addr[NADDR-j];
122 if(nb == 0) {
123 printf("bn void %D\n",bn);
124 return((daddr_t)0);
125 }
126
127 /*
128 * fetch through the indirect blocks
129 */
130 for(; j<=3; j++) {
131 if (blknos[j] != nb) {
132 io->i_bn = fsbtodb(nb) + io->i_boff;
133 io->i_ma = b[j];
134 io->i_cc = BSIZE;
135 devread(io);
136 bap = (daddr_t *)b[j];
137 blknos[j] = nb;
138 }
139 bap = (daddr_t *)b[j];
140 sh -= NSHIFT;
141 i = (bn>>sh) & NMASK;
142 nb = bap[i];
143 if(nb == 0) {
144 printf("bn void %D\n",bn);
145 return((daddr_t)0);
146 }
147 }
148 return(nb);
149}
150
151static ino_t
152dlook(s, io)
153char *s;
154register struct iob *io;
155{
156 register struct direct *dp;
157 register struct inode *ip;
158 daddr_t bn;
159 int n,dc;
160
161 if (s==NULL || *s=='\0')
162 return(0);
163 ip = &io->i_ino;
164 if ((ip->i_mode&IFMT)!=IFDIR) {
165 printf("not a directory\n");
166 return(0);
167 }
168
169 n = ip->i_size/sizeof(struct direct);
170
171 if (n==0) {
172 printf("zero length directory\n");
173 return(0);
174 }
175
176 dc = BSIZE;
177 bn = (daddr_t)0;
178 while(n--) {
179 if (++dc >= BSIZE/sizeof(struct direct)) {
180 io->i_bn = fsbtodb(sbmap(io, bn++)) + io->i_boff;
181 io->i_ma = io->i_buf;
182 io->i_cc = BSIZE;
183 devread(io);
184 dp = (struct direct *)io->i_buf;
185 dc = 0;
186 }
187
188 if (match(s, dp->d_name))
189 return(dp->d_ino);
190 dp++;
191 }
192 return(0);
193}
194
195static
196match(s1,s2)
197register char *s1,*s2;
198{
199 register cc;
200
201 cc = DIRSIZ;
202 while (cc--) {
203 if (*s1 != *s2)
204 return(0);
205 if (*s1++ && *s2++)
206 continue; else
207 return(1);
208 }
209 return(1);
210}
211
212lseek(fdesc, addr, ptr)
213int fdesc;
214off_t addr;
215int ptr;
216{
217 register struct iob *io;
218
219 if (ptr != 0) {
220 printf("Seek not from beginning of file\n");
221 return(-1);
222 }
223 fdesc -= 3;
224 if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
225 return(-1);
226 io->i_offset = addr;
227 io->i_bn = fsbtodb(addr/BSIZE) + io->i_boff;
228 io->i_cc = 0;
229 return(0);
230}
231
232getc(fdesc)
233int fdesc;
234{
235 register struct iob *io;
236 register char *p;
237 register c;
238 int off;
239
240
241 if (fdesc >= 0 && fdesc <= 2)
242 return(getchar());
243 fdesc -= 3;
244 if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
245 return(-1);
246 p = io->i_ma;
247 if (io->i_cc <= 0) {
248 io->i_bn = fsbtodb(io->i_offset/(off_t)BSIZE);
249 if (io->i_flgs&F_FILE)
250 io->i_bn = fsbtodb(sbmap(io, dbtofsb(io->i_bn))) + io->i_boff;
251 io->i_ma = io->i_buf;
252 io->i_cc = BSIZE;
253 devread(io);
254 if (io->i_flgs&F_FILE) {
255 off = io->i_offset % (off_t)BSIZE;
256 if (io->i_offset+(BSIZE-off) >= io->i_ino.i_size)
257 io->i_cc = io->i_ino.i_size - io->i_offset + off;
258 io->i_cc -= off;
259 if (io->i_cc <= 0)
260 return(-1);
261 } else
262 off = 0;
263 p = &io->i_buf[off];
264 }
265 io->i_cc--;
266 io->i_offset++;
267 c = (unsigned)*p++;
268 io->i_ma = p;
269 return(c);
270}
271/* does this port?
272getw(fdesc)
273int fdesc;
274{
275 register w,i;
276 register char *cp;
277 int val;
278
279 for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) {
280 w = getc(fdesc);
281 if (w < 0) {
282 if (i == 0)
283 return(-1);
284 else
285 return(val);
286 }
287 *cp++ = w;
288 }
289 return(val);
290}
291*/
292
293read(fdesc, buf, count)
294int fdesc;
295char *buf;
296int count;
297{
298 register i;
299 register struct iob *file;
300
301 if (fdesc >= 0 & fdesc <= 2) {
302 i = count;
303 do {
304 *buf = getchar();
305 } while (--i && *buf++ != '\n');
306 return(count - i);
307 }
308 fdesc -= 3;
309 if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
310 return(-1);
311 if ((file->i_flgs&F_READ) == 0)
312 return(-1);
313 if ((file->i_flgs&F_FILE) == 0) {
314 file->i_cc = count;
315 file->i_ma = buf;
316 i = devread(file);
317 file->i_bn += CLSIZE;
318 return(i);
319 }
320 else {
321 if (file->i_offset+count > file->i_ino.i_size)
322 count = file->i_ino.i_size - file->i_offset;
323 if ((i = count) <= 0)
324 return(0);
325 do {
326 *buf++ = getc(fdesc+3);
327 } while (--i);
328 return(count);
329 }
330}
331
332write(fdesc, buf, count)
333int fdesc;
334char *buf;
335int count;
336{
337 register i;
338 register struct iob *file;
339
340 if (fdesc >= 0 && fdesc <= 2) {
341 i = count;
342 while (i--)
343 putchar(*buf++);
344 return(count);
345 }
346 fdesc -= 3;
347 if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
348 return(-1);
349 if ((file->i_flgs&F_WRITE) == 0)
350 return(-1);
351 file->i_cc = count;
352 file->i_ma = buf;
353 i = devwrite(file);
354 file->i_bn += CLSIZE;
355 return(i);
356}
357
358open(str, how)
359char *str;
360int how;
361{
362 register char *cp;
363 int i;
364 register struct iob *file;
365 register struct devsw *dp;
366 int fdesc;
367 static first = 1;
368 long atol();
369
370 if (first) {
371 for (i = 0; i < NFILES; i++)
372 iob[i].i_flgs = 0;
373 first = 0;
374 }
375
376 for (fdesc = 0; fdesc < NFILES; fdesc++)
377 if (iob[fdesc].i_flgs == 0)
378 goto gotfile;
379 _stop("No more file slots");
380gotfile:
381 (file = &iob[fdesc])->i_flgs |= F_ALLOC;
382
383 for (cp = str; *cp && *cp != '('; cp++)
384 ;
385 if (*cp != '(') {
386 printf("Bad device\n");
387 file->i_flgs = 0;
388 return(-1);
389 }
390 *cp++ = '\0';
391 for (dp = devsw; dp->dv_name; dp++) {
392 if (match(str, dp->dv_name))
393 goto gotdev;
394 }
395 printf("Unknown device\n");
396 file->i_flgs = 0;
397 return(-1);
398gotdev:
399 *(cp-1) = '(';
400 file->i_ino.i_dev = dp-devsw;
401 file->i_unit = *cp++ - '0';
402 if (file->i_unit < 0 || file->i_unit > 7) {
403 printf("Bad unit specifier\n");
404 file->i_flgs = 0;
405 return(-1);
406 }
407 if (*cp++ != ',') {
408badoff:
409 printf("Missing offset specification\n");
410 file->i_flgs = 0;
411 return(-1);
412 }
413 file->i_boff = atol(cp);
414 for (;;) {
415 if (*cp == ')')
416 break;
417 if (*cp++)
418 continue;
419 goto badoff;
420 }
421 devopen(file);
422 if (*++cp == '\0') {
423 file->i_flgs |= how+1;
424 file->i_cc = 0;
425 file->i_offset = 0;
426 return(fdesc+3);
427 }
428 if ((i = find(cp, file)) == 0) {
429 file->i_flgs = 0;
430 return(-1);
431 }
432 if (how != 0) {
433 printf("Can't write files yet.. Sorry\n");
434 file->i_flgs = 0;
435 return(-1);
436 }
437 openi(i, file);
438 file->i_offset = 0;
439 file->i_cc = 0;
440 file->i_flgs |= F_FILE | (how+1);
441 return(fdesc+3);
442}
443
444close(fdesc)
445int fdesc;
446{
447 struct iob *file;
448
449 fdesc -= 3;
450 if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
451 return(-1);
452 if ((file->i_flgs&F_FILE) == 0)
453 devclose(file);
454 file->i_flgs = 0;
455 return(0);
456}
457
458exit()
459{
460 _stop("Exit called");
461}
462
463_stop(s)
464char *s;
465{
466 printf("%s\n", s);
467 _rtt();
468}
469
470trap(ps)
471int ps;
472{
473 printf("Trap %o\n", ps);
474 for (;;)
475 ;
476}