header file cleanup while moving vax files to their own directory
[unix-history] / usr / src / sys / stand.att / sys.c
CommitLineData
b5d17f4d 1/* sys.c 4.6 82/07/15 */
a5a27f5c 2
70b4ffec
KM
3#include "../h/param.h"
4#include "../h/inode.h"
5#include "../h/fs.h"
b5d17f4d 6#include "../h/dir.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) {
b5d17f4d
BJ
323 if (count % DEV_BSIZE)
324 printf("count=%d?\n", count);
a5a27f5c
BJ
325 file->i_cc = count;
326 file->i_ma = buf;
b5d17f4d 327 file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
a5a27f5c 328 i = devread(file);
b5d17f4d 329 file->i_offset += count;
a5a27f5c 330 return(i);
70b4ffec 331 } else {
a5a27f5c
BJ
332 if (file->i_offset+count > file->i_ino.i_size)
333 count = file->i_ino.i_size - file->i_offset;
334 if ((i = count) <= 0)
335 return(0);
336 do {
337 *buf++ = getc(fdesc+3);
338 } while (--i);
339 return(count);
340 }
341}
342
343write(fdesc, buf, count)
70b4ffec
KM
344 int fdesc;
345 char *buf;
346 int count;
a5a27f5c
BJ
347{
348 register i;
349 register struct iob *file;
350
351 if (fdesc >= 0 && fdesc <= 2) {
352 i = count;
353 while (i--)
354 putchar(*buf++);
355 return(count);
356 }
357 fdesc -= 3;
70b4ffec
KM
358 if (fdesc < 0 || fdesc >= NFILES ||
359 ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
a5a27f5c
BJ
360 return(-1);
361 if ((file->i_flgs&F_WRITE) == 0)
362 return(-1);
b5d17f4d
BJ
363 if (count % DEV_BSIZE)
364 printf("count=%d?\n", count);
a5a27f5c
BJ
365 file->i_cc = count;
366 file->i_ma = buf;
b5d17f4d 367 file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
a5a27f5c 368 i = devwrite(file);
b5d17f4d 369 file->i_offset += count;
a5a27f5c
BJ
370 return(i);
371}
372
10899d3a
BJ
373int openfirst = 1;
374
a5a27f5c 375open(str, how)
70b4ffec
KM
376 char *str;
377 int how;
a5a27f5c
BJ
378{
379 register char *cp;
380 int i;
381 register struct iob *file;
382 register struct devsw *dp;
383 int fdesc;
a5a27f5c
BJ
384 long atol();
385
10899d3a 386 if (openfirst) {
a5a27f5c
BJ
387 for (i = 0; i < NFILES; i++)
388 iob[i].i_flgs = 0;
10899d3a 389 openfirst = 0;
a5a27f5c
BJ
390 }
391
392 for (fdesc = 0; fdesc < NFILES; fdesc++)
393 if (iob[fdesc].i_flgs == 0)
394 goto gotfile;
395 _stop("No more file slots");
396gotfile:
397 (file = &iob[fdesc])->i_flgs |= F_ALLOC;
398
399 for (cp = str; *cp && *cp != '('; cp++)
400 ;
401 if (*cp != '(') {
402 printf("Bad device\n");
403 file->i_flgs = 0;
404 return(-1);
405 }
406 *cp++ = '\0';
407 for (dp = devsw; dp->dv_name; dp++) {
70b4ffec 408 if (!strcmp(str, dp->dv_name))
a5a27f5c
BJ
409 goto gotdev;
410 }
411 printf("Unknown device\n");
412 file->i_flgs = 0;
413 return(-1);
414gotdev:
415 *(cp-1) = '(';
416 file->i_ino.i_dev = dp-devsw;
417 file->i_unit = *cp++ - '0';
610c6f01
BJ
418 if (*cp >= '0' && *cp <= '9')
419 file->i_unit = file->i_unit * 10 + *cp++ - '0';
420 if (file->i_unit < 0 || file->i_unit > 31) {
a5a27f5c
BJ
421 printf("Bad unit specifier\n");
422 file->i_flgs = 0;
423 return(-1);
424 }
425 if (*cp++ != ',') {
426badoff:
427 printf("Missing offset specification\n");
428 file->i_flgs = 0;
429 return(-1);
430 }
431 file->i_boff = atol(cp);
432 for (;;) {
433 if (*cp == ')')
434 break;
435 if (*cp++)
436 continue;
437 goto badoff;
438 }
439 devopen(file);
440 if (*++cp == '\0') {
441 file->i_flgs |= how+1;
442 file->i_cc = 0;
443 file->i_offset = 0;
444 return(fdesc+3);
445 }
70b4ffec
KM
446 file->i_ma = (char *)(&file->i_fs);
447 file->i_cc = SBSIZE;
b5d17f4d 448 file->i_bn = SBLOCK + file->i_boff;
70b4ffec
KM
449 file->i_offset = 0;
450 devread(file);
a5a27f5c
BJ
451 if ((i = find(cp, file)) == 0) {
452 file->i_flgs = 0;
453 return(-1);
454 }
455 if (how != 0) {
456 printf("Can't write files yet.. Sorry\n");
457 file->i_flgs = 0;
458 return(-1);
459 }
460 openi(i, file);
461 file->i_offset = 0;
462 file->i_cc = 0;
463 file->i_flgs |= F_FILE | (how+1);
464 return(fdesc+3);
465}
466
467close(fdesc)
70b4ffec 468 int fdesc;
a5a27f5c
BJ
469{
470 struct iob *file;
471
472 fdesc -= 3;
70b4ffec
KM
473 if (fdesc < 0 || fdesc >= NFILES ||
474 ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
a5a27f5c
BJ
475 return(-1);
476 if ((file->i_flgs&F_FILE) == 0)
477 devclose(file);
478 file->i_flgs = 0;
479 return(0);
480}
481
482exit()
483{
484 _stop("Exit called");
485}
486
487_stop(s)
70b4ffec 488 char *s;
a5a27f5c 489{
0b87420c
MT
490 int i;
491
492 for (i = 0; i < NFILES; i++)
493 if (iob[i].i_flgs != 0)
494 close(i);
a5a27f5c
BJ
495 printf("%s\n", s);
496 _rtt();
497}
498
499trap(ps)
70b4ffec 500 int ps;
a5a27f5c
BJ
501{
502 printf("Trap %o\n", ps);
503 for (;;)
504 ;
505}