1: # 2: struct 3: { 4: char *s_isize; 5: char *s_fsize; 6: int s_nfree; 7: int s_free[100]; 8: int s_ninode; 9: int s_inode[100]; 10: char s_flock; 11: char s_ilock; 12: char s_fmod; 13: int s_time[2]; 14: } filsys; 15: 16: struct inode 17: { 18: int i_number; 19: int i_mode; 20: char i_nlink; 21: char i_uid; 22: char i_gid; 23: char i_size0; 24: char *i_size1; 25: int i_addr[8]; 26: int i_time[4]; 27: }; 28: 29: /* modes */ 30: #define IALLOC 0100000 31: #define IFMT 060000 32: #define IFDIR 040000 33: #define IFCHR 020000 34: #define IFBLK 060000 35: #define ILARG 010000 36: #define ISUID 04000 37: #define ISGID 02000 38: #define IREAD 0400 39: #define IWRITE 0200 40: #define IEXEC 0100 41: 42: int utime[2]; 43: int fin; 44: int fsi; 45: int fso; 46: char *charp; 47: int buf[256]; 48: char string[50]; 49: char *fsys; 50: char *proto; 51: int f_n 1; 52: int f_m 1; 53: 54: main(argc, argv) 55: char **argv; 56: { 57: int f, n; 58: 59: /* 60: * open relevent files 61: */ 62: 63: time(utime); 64: if(argc != 3) { 65: printf("arg count\n"); 66: exit(); 67: } 68: fsys = argv[1]; 69: for(n=0; f=fsys[n+1]; n++) 70: if(fsys[n] == 'r') { 71: if(f == 'k') { 72: f_n = 24; 73: f_m = 3; 74: } 75: if(f == 'p') { 76: f_n = 10; 77: f_m = 4; 78: } 79: } 80: proto = argv[2]; 81: fso = creat(fsys, 0666); 82: if(fso < 0) { 83: printf("%s: cannot create\n", fsys); 84: exit(); 85: } 86: fsi = open(fsys, 0); 87: if(fsi < 0) { 88: printf("%s: cannot open\n", fsys); 89: exit(); 90: } 91: fin = open(proto, 0); 92: if(fin < 0) { 93: n = 0; 94: for(f=0; proto[f]; f++) { 95: if(proto[f]<'0' || proto[f]>'9') { 96: printf("%s: cannot open\n", proto); 97: exit(); 98: } 99: n = n*10 + proto[f]-'0'; 100: } 101: filsys.s_fsize = n; 102: filsys.s_isize = ldiv(0, n, 43+ldiv(0, n, 1000)); 103: printf("isize = %d\n", filsys.s_isize); 104: if(f_n != 1) 105: printf("free list %d/%d\n", f_m, f_n); 106: charp = "d--777 0 0 $ "; 107: goto f3; 108: } 109: 110: /* 111: * get name of boot load program 112: * and read onto block 0 113: */ 114: 115: getstr(); 116: f = open(string, 0); 117: if(f < 0) { 118: printf("%s: cannot open init\n", string); 119: goto f2; 120: } 121: read(f, buf, 020); 122: if(buf[0] != 0407) { 123: printf("%s: bad format\n", string); 124: goto f1; 125: } 126: n = buf[1]+buf[2]; 127: if(n > 512) { 128: printf("%s: too big\n", string); 129: goto f1; 130: } 131: read(f, buf, n); 132: wtfs(0, buf); 133: 134: f1: 135: close(f); 136: 137: /* 138: * get total disk size 139: * and inode block size 140: */ 141: 142: f2: 143: filsys.s_fsize = getnum(); 144: filsys.s_isize = getnum(); 145: 146: f3: 147: if(filsys.s_isize > filsys.s_fsize || 148: filsys.s_fsize-filsys.s_isize-2 < filsys.s_isize) { 149: printf("%l/%l: bad ratio\n", filsys.s_fsize, filsys.s_isize); 150: exit(); 151: } 152: bflist(); 153: 154: /* 155: * initialize files 156: */ 157: 158: for(n=0; n<256; n++) 159: buf[n] = 0; 160: for(n=0; n!=filsys.s_isize; n++) 161: wtfs(n+2, buf); 162: cfile(0); 163: 164: /* 165: * write out super block 166: */ 167: 168: for(n=0; n<256; n++) 169: buf[n] = 0; 170: filsys.s_time[0] = utime[0]; 171: filsys.s_time[1] = utime[1]; 172: wtfs(1, &filsys); 173: } 174: 175: cfile(par) 176: struct inode *par; 177: { 178: struct inode in; 179: int db[256], ib[256]; 180: int dbc, ibc; 181: static ino; 182: int i, f, *p1, *p2; 183: 184: /* 185: * get mode, uid and gid 186: */ 187: 188: getstr(); 189: in.i_mode = IALLOC; 190: in.i_mode =| gmode(string[0], "bcd", IFBLK, IFCHR, IFDIR); 191: in.i_mode =| gmode(string[1], "u", ISUID); 192: in.i_mode =| gmode(string[2], "g", ISGID); 193: for(i=3; i<6; i++) { 194: if(string[i]<'0' || string[i]>'7') { 195: printf("%c/%s: bad digit\n", string[i], string); 196: exit(); 197: } 198: in.i_mode =| (string[i]-'0')<<(15-3*i); 199: } 200: in.i_uid = getnum(); 201: in.i_gid = getnum(); 202: 203: /* 204: * general initialization prior to 205: * switching on format 206: */ 207: 208: ino++; 209: in.i_number = ino; 210: if(ldiv(0, ino, 16) > filsys.s_isize) { 211: printf("too many inodes\n"); 212: exit(); 213: } 214: in.i_nlink = 1; 215: in.i_size0 = 0; 216: in.i_size1 = 0; 217: for(i=0; i<8; i++) 218: in.i_addr[i] = 0; 219: for(i=0; i<256; i++) { 220: db[i] = 0; 221: ib[i] = 0; 222: } 223: if(par == 0) { 224: par = ∈ 225: in.i_nlink--; 226: } 227: dbc = 0; 228: ibc = 0; 229: switch(in.i_mode&IFMT) { 230: 231: case 0: 232: /* 233: * regular file 234: * contents is a file name 235: */ 236: 237: getstr(); 238: f = open(string, 0); 239: if(f < 0) { 240: printf("%s: cannot open\n", string); 241: break; 242: } 243: while((i=read(f, db, 512)) > 0) { 244: in.i_size1 =+ i; 245: newblk(&dbc, db, &ibc, ib); 246: } 247: close(f); 248: break; 249: 250: case IFBLK: 251: case IFCHR: 252: /* 253: * special file 254: * content is maj/min types 255: */ 256: 257: in.i_addr[0] = getnum()<<8; 258: in.i_addr[0] =| getnum(); 259: break; 260: 261: case IFDIR: 262: /* 263: * directory 264: * put in extra links 265: * call recursively until 266: * name of "$" found 267: */ 268: 269: par->i_nlink++; 270: entry(par->i_number, "..", &dbc, db, &ibc, ib); 271: in.i_nlink++; 272: entry(in.i_number, ".", &dbc, db, &ibc, ib); 273: in.i_size1 = 32; 274: for(;;) { 275: getstr(); 276: if(string[0]=='$' && string[1]=='\0') 277: break; 278: entry(ino+1, string, &dbc, db, &ibc, ib); 279: in.i_size1 =+ 16; 280: cfile(&in); 281: } 282: break; 283: } 284: if(dbc != 0) 285: newblk(&dbc, db, &ibc, ib); 286: if(ibc > 8) { 287: in.i_mode =| ILARG; 288: dbc = alloc(); 289: wtfs(dbc, ib); 290: in.i_addr[0] = dbc; 291: } else 292: for(i=0; i<ibc; i++) 293: in.i_addr[i] = ib[i]; 294: in.i_time[0] = in.i_time[2] = utime[0]; 295: in.i_time[1] = in.i_time[3] = utime[1]; 296: i = in.i_number + 31; 297: dbc = ldiv(0, i, 16); 298: p1 = &buf[lrem(0, i, 16)*16]; 299: p2 = &in.i_mode; 300: rdfs(dbc, buf); 301: for(i=0; i<16; i++) 302: *p1++ = *p2++; 303: wtfs(dbc, buf); 304: } 305: 306: gmode(c, s, m0, m1, m2, m3) 307: char c, *s; 308: { 309: int i; 310: 311: for(i=0; s[i]!='\0'; i++) 312: if(c == s[i]) 313: return((&m0)[i]); 314: if(c == '-') 315: return(0); 316: printf("%c/%s: bad mode\n", c, string); 317: exit(); 318: } 319: 320: getnum() 321: { 322: int n, i; 323: 324: getstr(); 325: n = 0; 326: i = 0; 327: for(i=0; string[i]!='\0'; i++) { 328: if(string[i]<'0' || string[i]>'9') { 329: printf("%s: bad number\n", string); 330: exit(); 331: } 332: n = n*10 + string[i] - '0'; 333: } 334: return(n); 335: } 336: 337: getstr() 338: { 339: int i, c; 340: 341: loop: 342: switch(c=getch()) { 343: 344: case ' ': 345: case '\t': 346: case '\n': 347: goto loop; 348: 349: case '\0': 350: printf("EOF\n"); 351: exit(); 352: 353: case ':': 354: while(getch() != '\n'); 355: goto loop; 356: 357: } 358: i = 0; 359: 360: do { 361: string[i++] = c; 362: c = getch(); 363: } while(c!=' '&&c!='\t'&&c!='\n'&&c!='\0'); 364: string[i] = '\0'; 365: } 366: 367: rdfs(bno, bf) 368: { 369: int n; 370: 371: seek(fsi, bno, 3); 372: n = read(fsi, bf, 512); 373: if(n != 512) { 374: printf("read error: %l\n", bno); 375: exit(); 376: } 377: } 378: 379: wtfs(bno, bf) 380: { 381: int n; 382: 383: seek(fso, bno, 3); 384: n = write(fso, bf, 512); 385: if(n != 512) { 386: printf("write error: %l\n", bno); 387: exit(); 388: } 389: } 390: 391: alloc() 392: { 393: int bno, i; 394: 395: filsys.s_nfree--; 396: bno = filsys.s_free[filsys.s_nfree]; 397: filsys.s_free[filsys.s_nfree] = 0; 398: if(bno == 0) { 399: printf("out of free space\n"); 400: exit(); 401: } 402: if(filsys.s_nfree <= 0) { 403: rdfs(bno, buf); 404: filsys.s_nfree = buf[0]; 405: for(i=0; i<100; i++) 406: filsys.s_free[i] = buf[i+1]; 407: } 408: return(bno); 409: } 410: 411: free(bno) 412: { 413: int i; 414: 415: if(filsys.s_nfree >= 100) { 416: buf[0] = filsys.s_nfree; 417: for(i=0; i<100; i++) 418: buf[i+1] = filsys.s_free[i]; 419: wtfs(bno, buf); 420: filsys.s_nfree = 0; 421: } 422: filsys.s_free[filsys.s_nfree] = bno; 423: filsys.s_nfree++; 424: } 425: 426: entry(ino, str, adbc, db, aibc, ib) 427: char *str; 428: int *adbc, *db, *aibc, *ib; 429: { 430: char *s; 431: int i; 432: 433: db[*adbc] = ino; 434: (*adbc)++; 435: s = &db[*adbc]; 436: for(i=0; i<14; i++) { 437: *s++ = *str; 438: if(*str != '\0') 439: str++; 440: } 441: *adbc =+ 7; 442: if(*adbc >= 256) 443: newblk(adbc, db, aibc, ib); 444: } 445: 446: newblk(adbc, db, aibc, ib) 447: int *adbc, *db, *aibc, *ib; 448: { 449: int bno, i; 450: 451: bno = alloc(); 452: wtfs(bno, db); 453: for(i=0; i<256; i++) 454: db[i] = 0; 455: *adbc = 0; 456: ib[*aibc] = bno; 457: (*aibc)++; 458: if(*aibc >= 256) { 459: printf("indirect block full\n"); 460: exit(); 461: } 462: } 463: 464: getch() 465: { 466: 467: if(charp) 468: return(*charp++); 469: return(getchar()); 470: } 471: 472: bflist() 473: { 474: char flg[100], adr[100]; 475: register i, j; 476: char *low, *high; 477: 478: if(f_n > 100) 479: f_n = 100; 480: for(i=0; i<f_n; i++) 481: flg[i] = 0; 482: i = 0; 483: for(j=0; j<f_n; j++) { 484: while(flg[i]) 485: i = (i+1)%f_n; 486: adr[j] = i; 487: flg[i]++; 488: i = (i+f_m)%f_n; 489: } 490: 491: high = filsys.s_fsize-1; 492: low = filsys.s_isize+2; 493: free(0); 494: for(i=high; lrem(0,i+1,f_n); i--) { 495: if(i < low) 496: break; 497: free(i); 498: } 499: for(; i >= low+f_n; i =- f_n) 500: for(j=0; j<f_n; j++) 501: free(i-adr[j]); 502: for(;i >= low; i--) 503: free(i); 504: }