Add copyright
[unix-history] / usr / src / sys / stand.att / sys.c
CommitLineData
da7c5cc6
KM
1/*
2 * Copyright (c) 1982 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
6 * @(#)sys.c 6.3 (Berkeley) %G%
7 */
a5a27f5c 8
70b4ffec
KM
9#include "../h/param.h"
10#include "../h/inode.h"
11#include "../h/fs.h"
b5d17f4d 12#include "../h/dir.h"
a5a27f5c
BJ
13#include "saio.h"
14
15ino_t dlook();
16
70b4ffec
KM
17struct dirstuff {
18 int loc;
19 struct iob *io;
20};
21
a5a27f5c 22static
0839bdeb 23openi(n, io)
70b4ffec 24 register struct iob *io;
a5a27f5c
BJ
25{
26 register struct dinode *dp;
9c0778a9 27 int cc;
a5a27f5c
BJ
28
29 io->i_offset = 0;
70b4ffec
KM
30 io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
31 io->i_cc = io->i_fs.fs_bsize;
a5a27f5c 32 io->i_ma = io->i_buf;
9c0778a9 33 cc = devread(io);
a5a27f5c 34 dp = (struct dinode *)io->i_buf;
70b4ffec 35 io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic;
9c0778a9 36 return (cc);
a5a27f5c
BJ
37}
38
39static
40find(path, file)
70b4ffec
KM
41 register char *path;
42 struct iob *file;
a5a27f5c
BJ
43{
44 register char *q;
45 char c;
46 int n;
47
48 if (path==NULL || *path=='\0') {
49 printf("null path\n");
0839bdeb 50 return (0);
a5a27f5c
BJ
51 }
52
9c0778a9
SL
53 if (openi((ino_t) ROOTINO, file) < 0) {
54 printf("can't read root inode\n");
55 return (0);
56 }
a5a27f5c
BJ
57 while (*path) {
58 while (*path == '/')
59 path++;
60 q = path;
61 while(*q != '/' && *q != '\0')
62 q++;
63 c = *q;
64 *q = '\0';
65
9c0778a9
SL
66 if ((n = dlook(path, file)) != 0) {
67 if (c == '\0')
a5a27f5c 68 break;
9c0778a9
SL
69 if (openi(n, file) < 0)
70 return (0);
a5a27f5c
BJ
71 *q = c;
72 path = q;
73 continue;
74 } else {
9c0778a9 75 printf("%s not found\n", path);
0839bdeb 76 return (0);
a5a27f5c
BJ
77 }
78 }
0839bdeb 79 return (n);
a5a27f5c
BJ
80}
81
82static daddr_t
83sbmap(io, bn)
70b4ffec
KM
84 register struct iob *io;
85 daddr_t bn;
a5a27f5c 86{
a5a27f5c 87 register struct inode *ip;
70b4ffec 88 int i, j, sh;
a5a27f5c 89 daddr_t nb, *bap;
a5a27f5c
BJ
90
91 ip = &io->i_ino;
70b4ffec 92 if (bn < 0) {
a5a27f5c 93 printf("bn negative\n");
0839bdeb 94 return ((daddr_t)0);
a5a27f5c
BJ
95 }
96
97 /*
70b4ffec 98 * blocks 0..NDADDR are direct blocks
a5a27f5c 99 */
70b4ffec
KM
100 if(bn < NDADDR) {
101 nb = ip->i_db[bn];
0839bdeb 102 return (nb);
a5a27f5c
BJ
103 }
104
105 /*
70b4ffec
KM
106 * addresses NIADDR have single and double indirect blocks.
107 * the first step is to determine how many levels of indirection.
a5a27f5c 108 */
70b4ffec
KM
109 sh = 1;
110 bn -= NDADDR;
111 for (j = NIADDR; j > 0; j--) {
112 sh *= NINDIR(&io->i_fs);
113 if (bn < sh)
a5a27f5c 114 break;
70b4ffec 115 bn -= sh;
a5a27f5c 116 }
70b4ffec
KM
117 if (j == 0) {
118 printf("bn ovf %D\n", bn);
119 return ((daddr_t)0);
a5a27f5c
BJ
120 }
121
122 /*
70b4ffec 123 * fetch the first indirect block address from the inode
a5a27f5c 124 */
70b4ffec
KM
125 nb = ip->i_ib[NIADDR - j];
126 if (nb == 0) {
a5a27f5c 127 printf("bn void %D\n",bn);
0839bdeb 128 return ((daddr_t)0);
a5a27f5c
BJ
129 }
130
131 /*
132 * fetch through the indirect blocks
133 */
70b4ffec 134 for (; j <= NIADDR; j++) {
a5a27f5c 135 if (blknos[j] != nb) {
70b4ffec 136 io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
a5a27f5c 137 io->i_ma = b[j];
70b4ffec 138 io->i_cc = io->i_fs.fs_bsize;
9c0778a9
SL
139 if (devread(io) != io->i_fs.fs_bsize) {
140 if (io->i_error)
141 errno = io->i_error;
142 printf("bn %D: read error\n", io->i_bn);
143 return ((daddr_t)0);
144 }
a5a27f5c
BJ
145 blknos[j] = nb;
146 }
147 bap = (daddr_t *)b[j];
70b4ffec
KM
148 sh /= NINDIR(&io->i_fs);
149 i = (bn / sh) % NINDIR(&io->i_fs);
a5a27f5c
BJ
150 nb = bap[i];
151 if(nb == 0) {
152 printf("bn void %D\n",bn);
0839bdeb 153 return ((daddr_t)0);
a5a27f5c
BJ
154 }
155 }
0839bdeb 156 return (nb);
a5a27f5c
BJ
157}
158
159static ino_t
160dlook(s, io)
70b4ffec
KM
161 char *s;
162 register struct iob *io;
a5a27f5c
BJ
163{
164 register struct direct *dp;
165 register struct inode *ip;
70b4ffec
KM
166 struct dirstuff dirp;
167 int len;
a5a27f5c 168
70b4ffec 169 if (s == NULL || *s == '\0')
0839bdeb 170 return (0);
a5a27f5c 171 ip = &io->i_ino;
70b4ffec 172 if ((ip->i_mode&IFMT) != IFDIR) {
a5a27f5c 173 printf("not a directory\n");
0839bdeb 174 return (0);
a5a27f5c 175 }
70b4ffec 176 if (ip->i_size == 0) {
a5a27f5c 177 printf("zero length directory\n");
0839bdeb 178 return (0);
a5a27f5c 179 }
70b4ffec
KM
180 len = strlen(s);
181 dirp.loc = 0;
182 dirp.io = io;
183 for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
184 if(dp->d_ino == 0)
185 continue;
186 if (dp->d_namlen == len && !strcmp(s, dp->d_name))
0839bdeb 187 return (dp->d_ino);
a5a27f5c 188 }
0839bdeb 189 return (0);
a5a27f5c
BJ
190}
191
70b4ffec
KM
192/*
193 * get next entry in a directory.
194 */
195struct direct *
196readdir(dirp)
197 register struct dirstuff *dirp;
a5a27f5c 198{
70b4ffec
KM
199 register struct direct *dp;
200 register struct iob *io;
201 daddr_t lbn, d;
202 int off;
a5a27f5c 203
70b4ffec
KM
204 io = dirp->io;
205 for(;;) {
206 if (dirp->loc >= io->i_ino.i_size)
9c0778a9 207 return (NULL);
70b4ffec
KM
208 off = blkoff(&io->i_fs, dirp->loc);
209 if (off == 0) {
210 lbn = lblkno(&io->i_fs, dirp->loc);
211 d = sbmap(io, lbn);
212 if(d == 0)
213 return NULL;
214 io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
215 io->i_ma = io->i_buf;
216 io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn);
9c0778a9
SL
217 if (devread(io) < 0) {
218 errno = io->i_error;
219 printf("bn %D: read error\n", io->i_bn);
220 return (NULL);
221 }
70b4ffec
KM
222 }
223 dp = (struct direct *)(io->i_buf + off);
224 dirp->loc += dp->d_reclen;
225 if (dp->d_ino == 0)
226 continue;
227 return (dp);
a5a27f5c 228 }
a5a27f5c
BJ
229}
230
231lseek(fdesc, addr, ptr)
0839bdeb
SL
232 int fdesc, ptr;
233 off_t addr;
a5a27f5c
BJ
234{
235 register struct iob *io;
236
237 if (ptr != 0) {
238 printf("Seek not from beginning of file\n");
0839bdeb
SL
239 errno = EOFFSET;
240 return (-1);
a5a27f5c
BJ
241 }
242 fdesc -= 3;
70b4ffec 243 if (fdesc < 0 || fdesc >= NFILES ||
0839bdeb
SL
244 ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
245 errno = EBADF;
246 return (-1);
247 }
a5a27f5c 248 io->i_offset = addr;
70b4ffec 249 io->i_bn = addr / DEV_BSIZE;
a5a27f5c 250 io->i_cc = 0;
0839bdeb 251 return (0);
a5a27f5c
BJ
252}
253
254getc(fdesc)
0839bdeb 255 int fdesc;
a5a27f5c
BJ
256{
257 register struct iob *io;
70b4ffec 258 register struct fs *fs;
a5a27f5c 259 register char *p;
70b4ffec 260 int c, lbn, off, size, diff;
a5a27f5c
BJ
261
262
263 if (fdesc >= 0 && fdesc <= 2)
0839bdeb 264 return (getchar());
a5a27f5c 265 fdesc -= 3;
70b4ffec 266 if (fdesc < 0 || fdesc >= NFILES ||
0839bdeb
SL
267 ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
268 errno = EBADF;
269 return (-1);
270 }
a5a27f5c
BJ
271 p = io->i_ma;
272 if (io->i_cc <= 0) {
70b4ffec
KM
273 if ((io->i_flgs & F_FILE) != 0) {
274 diff = io->i_ino.i_size - io->i_offset;
275 if (diff <= 0)
276 return (-1);
277 fs = &io->i_fs;
278 lbn = lblkno(fs, io->i_offset);
279 io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
280 off = blkoff(fs, io->i_offset);
281 size = blksize(fs, &io->i_ino, lbn);
282 } else {
283 io->i_bn = io->i_offset / DEV_BSIZE;
284 off = 0;
285 size = DEV_BSIZE;
286 }
a5a27f5c 287 io->i_ma = io->i_buf;
70b4ffec 288 io->i_cc = size;
9c0778a9
SL
289 if (devread(io) < 0) {
290 errno = io->i_error;
291 return (-1);
292 }
70b4ffec
KM
293 if ((io->i_flgs & F_FILE) != 0) {
294 if (io->i_offset - off + size >= io->i_ino.i_size)
295 io->i_cc = diff + off;
a5a27f5c 296 io->i_cc -= off;
70b4ffec 297 }
a5a27f5c
BJ
298 p = &io->i_buf[off];
299 }
300 io->i_cc--;
301 io->i_offset++;
302 c = (unsigned)*p++;
303 io->i_ma = p;
0839bdeb 304 return (c);
a5a27f5c 305}
70b4ffec 306
a5a27f5c
BJ
307/* does this port?
308getw(fdesc)
0839bdeb 309 int fdesc;
a5a27f5c
BJ
310{
311 register w,i;
312 register char *cp;
313 int val;
314
315 for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) {
316 w = getc(fdesc);
317 if (w < 0) {
318 if (i == 0)
0839bdeb 319 return (-1);
a5a27f5c 320 else
0839bdeb 321 return (val);
a5a27f5c
BJ
322 }
323 *cp++ = w;
324 }
0839bdeb 325 return (val);
a5a27f5c
BJ
326}
327*/
0839bdeb 328int errno;
a5a27f5c
BJ
329
330read(fdesc, buf, count)
0839bdeb
SL
331 int fdesc, count;
332 char *buf;
a5a27f5c
BJ
333{
334 register i;
335 register struct iob *file;
336
0839bdeb 337 errno = 0;
a5a27f5c
BJ
338 if (fdesc >= 0 & fdesc <= 2) {
339 i = count;
340 do {
341 *buf = getchar();
342 } while (--i && *buf++ != '\n');
0839bdeb 343 return (count - i);
a5a27f5c
BJ
344 }
345 fdesc -= 3;
70b4ffec 346 if (fdesc < 0 || fdesc >= NFILES ||
0839bdeb
SL
347 ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
348 errno = EBADF;
349 return (-1);
350 }
351 if ((file->i_flgs&F_READ) == 0) {
352 errno = EBADF;
353 return (-1);
354 }
70b4ffec 355 if ((file->i_flgs & F_FILE) == 0) {
a5a27f5c
BJ
356 file->i_cc = count;
357 file->i_ma = buf;
b5d17f4d 358 file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
a5a27f5c 359 i = devread(file);
b5d17f4d 360 file->i_offset += count;
0839bdeb
SL
361 if (i < 0)
362 errno = file->i_error;
363 return (i);
70b4ffec 364 } else {
a5a27f5c
BJ
365 if (file->i_offset+count > file->i_ino.i_size)
366 count = file->i_ino.i_size - file->i_offset;
367 if ((i = count) <= 0)
0839bdeb 368 return (0);
a5a27f5c
BJ
369 do {
370 *buf++ = getc(fdesc+3);
371 } while (--i);
0839bdeb 372 return (count);
a5a27f5c
BJ
373 }
374}
375
376write(fdesc, buf, count)
0839bdeb
SL
377 int fdesc, count;
378 char *buf;
a5a27f5c
BJ
379{
380 register i;
381 register struct iob *file;
382
0839bdeb 383 errno = 0;
a5a27f5c
BJ
384 if (fdesc >= 0 && fdesc <= 2) {
385 i = count;
386 while (i--)
387 putchar(*buf++);
0839bdeb 388 return (count);
a5a27f5c
BJ
389 }
390 fdesc -= 3;
70b4ffec 391 if (fdesc < 0 || fdesc >= NFILES ||
0839bdeb
SL
392 ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
393 errno = EBADF;
394 return (-1);
395 }
396 if ((file->i_flgs&F_WRITE) == 0) {
397 errno = EBADF;
398 return (-1);
399 }
a5a27f5c
BJ
400 file->i_cc = count;
401 file->i_ma = buf;
b5d17f4d 402 file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
a5a27f5c 403 i = devwrite(file);
b5d17f4d 404 file->i_offset += count;
0839bdeb
SL
405 if (i < 0)
406 errno = file->i_error;
407 return (i);
a5a27f5c
BJ
408}
409
10899d3a
BJ
410int openfirst = 1;
411
a5a27f5c 412open(str, how)
70b4ffec 413 char *str;
0839bdeb 414 int how;
a5a27f5c
BJ
415{
416 register char *cp;
417 int i;
418 register struct iob *file;
419 register struct devsw *dp;
0839bdeb
SL
420 int fdesc;
421 long atol();
a5a27f5c 422
10899d3a 423 if (openfirst) {
a5a27f5c
BJ
424 for (i = 0; i < NFILES; i++)
425 iob[i].i_flgs = 0;
10899d3a 426 openfirst = 0;
a5a27f5c
BJ
427 }
428
429 for (fdesc = 0; fdesc < NFILES; fdesc++)
430 if (iob[fdesc].i_flgs == 0)
431 goto gotfile;
432 _stop("No more file slots");
433gotfile:
434 (file = &iob[fdesc])->i_flgs |= F_ALLOC;
435
436 for (cp = str; *cp && *cp != '('; cp++)
437 ;
438 if (*cp != '(') {
439 printf("Bad device\n");
440 file->i_flgs = 0;
0839bdeb
SL
441 errno = EDEV;
442 return (-1);
a5a27f5c
BJ
443 }
444 *cp++ = '\0';
445 for (dp = devsw; dp->dv_name; dp++) {
70b4ffec 446 if (!strcmp(str, dp->dv_name))
a5a27f5c
BJ
447 goto gotdev;
448 }
449 printf("Unknown device\n");
450 file->i_flgs = 0;
0839bdeb
SL
451 errno = ENXIO;
452 return (-1);
a5a27f5c
BJ
453gotdev:
454 *(cp-1) = '(';
455 file->i_ino.i_dev = dp-devsw;
456 file->i_unit = *cp++ - '0';
610c6f01
BJ
457 if (*cp >= '0' && *cp <= '9')
458 file->i_unit = file->i_unit * 10 + *cp++ - '0';
459 if (file->i_unit < 0 || file->i_unit > 31) {
a5a27f5c
BJ
460 printf("Bad unit specifier\n");
461 file->i_flgs = 0;
0839bdeb
SL
462 errno = EUNIT;
463 return (-1);
a5a27f5c
BJ
464 }
465 if (*cp++ != ',') {
466badoff:
467 printf("Missing offset specification\n");
468 file->i_flgs = 0;
0839bdeb
SL
469 errno = EOFFSET;
470 return (-1);
a5a27f5c
BJ
471 }
472 file->i_boff = atol(cp);
473 for (;;) {
474 if (*cp == ')')
475 break;
476 if (*cp++)
477 continue;
478 goto badoff;
479 }
480 devopen(file);
481 if (*++cp == '\0') {
482 file->i_flgs |= how+1;
483 file->i_cc = 0;
484 file->i_offset = 0;
0839bdeb 485 return (fdesc+3);
a5a27f5c 486 }
70b4ffec
KM
487 file->i_ma = (char *)(&file->i_fs);
488 file->i_cc = SBSIZE;
b5d17f4d 489 file->i_bn = SBLOCK + file->i_boff;
70b4ffec 490 file->i_offset = 0;
9c0778a9
SL
491 if (devread(file) < 0) {
492 errno = file->i_error;
493 printf("super block read error\n");
494 return (-1);
495 }
a5a27f5c
BJ
496 if ((i = find(cp, file)) == 0) {
497 file->i_flgs = 0;
0839bdeb
SL
498 errno = ESRCH;
499 return (-1);
a5a27f5c
BJ
500 }
501 if (how != 0) {
502 printf("Can't write files yet.. Sorry\n");
503 file->i_flgs = 0;
0839bdeb
SL
504 errno = EIO;
505 return (-1);
a5a27f5c 506 }
9c0778a9
SL
507 if (openi(i, file) < 0) {
508 errno = file->i_error;
509 return (-1);
510 }
a5a27f5c
BJ
511 file->i_offset = 0;
512 file->i_cc = 0;
513 file->i_flgs |= F_FILE | (how+1);
0839bdeb 514 return (fdesc+3);
a5a27f5c
BJ
515}
516
517close(fdesc)
0839bdeb 518 int fdesc;
a5a27f5c
BJ
519{
520 struct iob *file;
521
522 fdesc -= 3;
70b4ffec 523 if (fdesc < 0 || fdesc >= NFILES ||
0839bdeb
SL
524 ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
525 errno = EBADF;
526 return (-1);
527 }
a5a27f5c
BJ
528 if ((file->i_flgs&F_FILE) == 0)
529 devclose(file);
530 file->i_flgs = 0;
0839bdeb
SL
531 return (0);
532}
533
534ioctl(fdesc, cmd, arg)
535 int fdesc, cmd;
536 char *arg;
537{
538 register struct iob *file;
539 int error = 0;
540
9a46f589 541 fdesc -= 3;
0839bdeb
SL
542 if (fdesc < 0 || fdesc >= NFILES ||
543 ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
544 errno = EBADF;
545 return (-1);
546 }
547 switch (cmd) {
548
549 case SAIOHDR:
550 file->i_flgs |= F_HDR;
551 break;
552
553 case SAIOCHECK:
554 file->i_flgs |= F_CHECK;
555 break;
556
557 case SAIOHCHECK:
558 file->i_flgs |= F_HCHECK;
559 break;
560
9a46f589
HS
561 case SAIONOBAD:
562 file->i_flgs |= F_NBSF;
563 break;
564
565 case SAIODOBAD:
566 file->i_flgs &= ~F_NBSF;
567 break;
568
569 case SAIOECCLIM:
570 file->i_flgs |= F_ECCLM;
571 break;
572
573 case SAIOECCUNL:
574 file->i_flgs &= ~F_ECCLM;
575 break;
576
71da8ead
MK
577 case SAIOSEVRE:
578 file->i_flgs |= F_SEVRE;
579 break;
580
581 case SAIONSEVRE:
582 file->i_flgs &= ~F_SEVRE;
583 break;
584
0839bdeb
SL
585 default:
586 error = devioctl(file, cmd, arg);
587 break;
588 }
589 if (error < 0)
590 errno = file->i_error;
591 return (error);
a5a27f5c
BJ
592}
593
594exit()
595{
596 _stop("Exit called");
597}
598
599_stop(s)
0839bdeb 600 char *s;
a5a27f5c 601{
0b87420c
MT
602 int i;
603
604 for (i = 0; i < NFILES; i++)
605 if (iob[i].i_flgs != 0)
606 close(i);
a5a27f5c
BJ
607 printf("%s\n", s);
608 _rtt();
609}
610
611trap(ps)
70b4ffec 612 int ps;
a5a27f5c
BJ
613{
614 printf("Trap %o\n", ps);
615 for (;;)
616 ;
617}