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