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