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