1 /* sys.c 4.6 82/07/15 */ 2 3 #include "../h/param.h" 4 #include "../h/inode.h" 5 #include "../h/fs.h" 6 #include "../h/dir.h" 7 #include "saio.h" 8 9 ino_t dlook(); 10 11 struct dirstuff { 12 int loc; 13 struct iob *io; 14 }; 15 16 static 17 openi(n,io) 18 register struct iob *io; 19 { 20 register struct dinode *dp; 21 22 io->i_offset = 0; 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; 25 io->i_ma = io->i_buf; 26 devread(io); 27 dp = (struct dinode *)io->i_buf; 28 io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic; 29 } 30 31 static 32 find(path, file) 33 register char *path; 34 struct iob *file; 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 70 static daddr_t 71 sbmap(io, bn) 72 register struct iob *io; 73 daddr_t bn; 74 { 75 register struct inode *ip; 76 int i, j, sh; 77 daddr_t nb, *bap; 78 79 ip = &io->i_ino; 80 if (bn < 0) { 81 printf("bn negative\n"); 82 return((daddr_t)0); 83 } 84 85 /* 86 * blocks 0..NDADDR are direct blocks 87 */ 88 if(bn < NDADDR) { 89 nb = ip->i_db[bn]; 90 return(nb); 91 } 92 93 /* 94 * addresses NIADDR have single and double indirect blocks. 95 * the first step is to determine how many levels of indirection. 96 */ 97 sh = 1; 98 bn -= NDADDR; 99 for (j = NIADDR; j > 0; j--) { 100 sh *= NINDIR(&io->i_fs); 101 if (bn < sh) 102 break; 103 bn -= sh; 104 } 105 if (j == 0) { 106 printf("bn ovf %D\n", bn); 107 return ((daddr_t)0); 108 } 109 110 /* 111 * fetch the first indirect block address from the inode 112 */ 113 nb = ip->i_ib[NIADDR - j]; 114 if (nb == 0) { 115 printf("bn void %D\n",bn); 116 return((daddr_t)0); 117 } 118 119 /* 120 * fetch through the indirect blocks 121 */ 122 for (; j <= NIADDR; j++) { 123 if (blknos[j] != nb) { 124 io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff; 125 io->i_ma = b[j]; 126 io->i_cc = io->i_fs.fs_bsize; 127 devread(io); 128 blknos[j] = nb; 129 } 130 bap = (daddr_t *)b[j]; 131 sh /= NINDIR(&io->i_fs); 132 i = (bn / sh) % NINDIR(&io->i_fs); 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 142 static ino_t 143 dlook(s, io) 144 char *s; 145 register struct iob *io; 146 { 147 register struct direct *dp; 148 register struct inode *ip; 149 struct dirstuff dirp; 150 int len; 151 152 if (s == NULL || *s == '\0') 153 return(0); 154 ip = &io->i_ino; 155 if ((ip->i_mode&IFMT) != IFDIR) { 156 printf("not a directory\n"); 157 return(0); 158 } 159 if (ip->i_size == 0) { 160 printf("zero length directory\n"); 161 return(0); 162 } 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)) 170 return(dp->d_ino); 171 } 172 return(0); 173 } 174 175 /* 176 * get next entry in a directory. 177 */ 178 struct direct * 179 readdir(dirp) 180 register struct dirstuff *dirp; 181 { 182 register struct direct *dp; 183 register struct iob *io; 184 daddr_t lbn, d; 185 int off; 186 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); 207 } 208 } 209 210 lseek(fdesc, addr, ptr) 211 int fdesc; 212 off_t addr; 213 int ptr; 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; 222 if (fdesc < 0 || fdesc >= NFILES || 223 ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) 224 return(-1); 225 io->i_offset = addr; 226 io->i_bn = addr / DEV_BSIZE; 227 io->i_cc = 0; 228 return(0); 229 } 230 231 getc(fdesc) 232 int fdesc; 233 { 234 register struct iob *io; 235 register struct fs *fs; 236 register char *p; 237 int c, lbn, off, size, diff; 238 239 240 if (fdesc >= 0 && fdesc <= 2) 241 return(getchar()); 242 fdesc -= 3; 243 if (fdesc < 0 || fdesc >= NFILES || 244 ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 245 return(-1); 246 p = io->i_ma; 247 if (io->i_cc <= 0) { 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 } 262 io->i_ma = io->i_buf; 263 io->i_cc = size; 264 devread(io); 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; 268 io->i_cc -= off; 269 } 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 } 278 279 /* does this port? 280 getw(fdesc) 281 int fdesc; 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 301 read(fdesc, buf, count) 302 int fdesc; 303 char *buf; 304 int count; 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; 317 if (fdesc < 0 || fdesc >= NFILES || 318 ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 319 return(-1); 320 if ((file->i_flgs&F_READ) == 0) 321 return(-1); 322 if ((file->i_flgs & F_FILE) == 0) { 323 if (count % DEV_BSIZE) 324 printf("count=%d?\n", count); 325 file->i_cc = count; 326 file->i_ma = buf; 327 file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 328 i = devread(file); 329 file->i_offset += count; 330 return(i); 331 } else { 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 343 write(fdesc, buf, count) 344 int fdesc; 345 char *buf; 346 int count; 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; 358 if (fdesc < 0 || fdesc >= NFILES || 359 ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 360 return(-1); 361 if ((file->i_flgs&F_WRITE) == 0) 362 return(-1); 363 if (count % DEV_BSIZE) 364 printf("count=%d?\n", count); 365 file->i_cc = count; 366 file->i_ma = buf; 367 file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 368 i = devwrite(file); 369 file->i_offset += count; 370 return(i); 371 } 372 373 int openfirst = 1; 374 375 open(str, how) 376 char *str; 377 int how; 378 { 379 register char *cp; 380 int i; 381 register struct iob *file; 382 register struct devsw *dp; 383 int fdesc; 384 long atol(); 385 386 if (openfirst) { 387 for (i = 0; i < NFILES; i++) 388 iob[i].i_flgs = 0; 389 openfirst = 0; 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"); 396 gotfile: 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++) { 408 if (!strcmp(str, dp->dv_name)) 409 goto gotdev; 410 } 411 printf("Unknown device\n"); 412 file->i_flgs = 0; 413 return(-1); 414 gotdev: 415 *(cp-1) = '('; 416 file->i_ino.i_dev = dp-devsw; 417 file->i_unit = *cp++ - '0'; 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) { 421 printf("Bad unit specifier\n"); 422 file->i_flgs = 0; 423 return(-1); 424 } 425 if (*cp++ != ',') { 426 badoff: 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 } 446 file->i_ma = (char *)(&file->i_fs); 447 file->i_cc = SBSIZE; 448 file->i_bn = SBLOCK + file->i_boff; 449 file->i_offset = 0; 450 devread(file); 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 467 close(fdesc) 468 int fdesc; 469 { 470 struct iob *file; 471 472 fdesc -= 3; 473 if (fdesc < 0 || fdesc >= NFILES || 474 ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 475 return(-1); 476 if ((file->i_flgs&F_FILE) == 0) 477 devclose(file); 478 file->i_flgs = 0; 479 return(0); 480 } 481 482 exit() 483 { 484 _stop("Exit called"); 485 } 486 487 _stop(s) 488 char *s; 489 { 490 int i; 491 492 for (i = 0; i < NFILES; i++) 493 if (iob[i].i_flgs != 0) 494 close(i); 495 printf("%s\n", s); 496 _rtt(); 497 } 498 499 trap(ps) 500 int ps; 501 { 502 printf("Trap %o\n", ps); 503 for (;;) 504 ; 505 } 506