home *** CD-ROM | disk | FTP | other *** search
- #
- struct
- {
- char *s_isize;
- char *s_fsize;
- int s_nfree;
- int s_free[100];
- int s_ninode;
- int s_inode[100];
- char s_flock;
- char s_ilock;
- char s_fmod;
- int s_time[2];
- } filsys;
-
- struct inode
- {
- int i_number;
- int i_mode;
- char i_nlink;
- char i_uid;
- char i_gid;
- char i_size0;
- char *i_size1;
- int i_addr[8];
- int i_time[4];
- };
-
- /* modes */
- #define IALLOC 0100000
- #define IFMT 060000
- #define IFDIR 040000
- #define IFCHR 020000
- #define IFBLK 060000
- #define ILARG 010000
- #define ISUID 04000
- #define ISGID 02000
- #define IREAD 0400
- #define IWRITE 0200
- #define IEXEC 0100
-
- int utime[2];
- int fin;
- int fsi;
- int fso;
- char *charp;
- int buf[256];
- char string[50];
- char *fsys;
- char *proto;
- int f_n 1;
- int f_m 1;
-
- main(argc, argv)
- char **argv;
- {
- int f, n;
-
- /*
- * open relevent files
- */
-
- time(utime);
- if(argc != 3) {
- printf("arg count\n");
- exit();
- }
- fsys = argv[1];
- for(n=0; f=fsys[n+1]; n++)
- if(fsys[n] == 'r') {
- if(f == 'k') {
- f_n = 24;
- f_m = 3;
- }
- if(f == 'p') {
- f_n = 10;
- f_m = 4;
- }
- }
- proto = argv[2];
- fso = creat(fsys, 0666);
- if(fso < 0) {
- printf("%s: cannot create\n", fsys);
- exit();
- }
- fsi = open(fsys, 0);
- if(fsi < 0) {
- printf("%s: cannot open\n", fsys);
- exit();
- }
- fin = open(proto, 0);
- if(fin < 0) {
- n = 0;
- for(f=0; proto[f]; f++) {
- if(proto[f]<'0' || proto[f]>'9') {
- printf("%s: cannot open\n", proto);
- exit();
- }
- n = n*10 + proto[f]-'0';
- }
- filsys.s_fsize = n;
- filsys.s_isize = ldiv(0, n, 43+ldiv(0, n, 1000));
- printf("isize = %d\n", filsys.s_isize);
- if(f_n != 1)
- printf("free list %d/%d\n", f_m, f_n);
- charp = "d--777 0 0 $ ";
- goto f3;
- }
-
- /*
- * get name of boot load program
- * and read onto block 0
- */
-
- getstr();
- f = open(string, 0);
- if(f < 0) {
- printf("%s: cannot open init\n", string);
- goto f2;
- }
- read(f, buf, 020);
- if(buf[0] != 0407) {
- printf("%s: bad format\n", string);
- goto f1;
- }
- n = buf[1]+buf[2];
- if(n > 512) {
- printf("%s: too big\n", string);
- goto f1;
- }
- read(f, buf, n);
- wtfs(0, buf);
-
- f1:
- close(f);
-
- /*
- * get total disk size
- * and inode block size
- */
-
- f2:
- filsys.s_fsize = getnum();
- filsys.s_isize = getnum();
-
- f3:
- if(filsys.s_isize > filsys.s_fsize ||
- filsys.s_fsize-filsys.s_isize-2 < filsys.s_isize) {
- printf("%l/%l: bad ratio\n", filsys.s_fsize, filsys.s_isize);
- exit();
- }
- bflist();
-
- /*
- * initialize files
- */
-
- for(n=0; n<256; n++)
- buf[n] = 0;
- for(n=0; n!=filsys.s_isize; n++)
- wtfs(n+2, buf);
- cfile(0);
-
- /*
- * write out super block
- */
-
- for(n=0; n<256; n++)
- buf[n] = 0;
- filsys.s_time[0] = utime[0];
- filsys.s_time[1] = utime[1];
- wtfs(1, &filsys);
- }
-
- cfile(par)
- struct inode *par;
- {
- struct inode in;
- int db[256], ib[256];
- int dbc, ibc;
- static ino;
- int i, f, *p1, *p2;
-
- /*
- * get mode, uid and gid
- */
-
- getstr();
- in.i_mode = IALLOC;
- in.i_mode =| gmode(string[0], "bcd", IFBLK, IFCHR, IFDIR);
- in.i_mode =| gmode(string[1], "u", ISUID);
- in.i_mode =| gmode(string[2], "g", ISGID);
- for(i=3; i<6; i++) {
- if(string[i]<'0' || string[i]>'7') {
- printf("%c/%s: bad digit\n", string[i], string);
- exit();
- }
- in.i_mode =| (string[i]-'0')<<(15-3*i);
- }
- in.i_uid = getnum();
- in.i_gid = getnum();
-
- /*
- * general initialization prior to
- * switching on format
- */
-
- ino++;
- in.i_number = ino;
- if(ldiv(0, ino, 16) > filsys.s_isize) {
- printf("too many inodes\n");
- exit();
- }
- in.i_nlink = 1;
- in.i_size0 = 0;
- in.i_size1 = 0;
- for(i=0; i<8; i++)
- in.i_addr[i] = 0;
- for(i=0; i<256; i++) {
- db[i] = 0;
- ib[i] = 0;
- }
- if(par == 0) {
- par = ∈
- in.i_nlink--;
- }
- dbc = 0;
- ibc = 0;
- switch(in.i_mode&IFMT) {
-
- case 0:
- /*
- * regular file
- * contents is a file name
- */
-
- getstr();
- f = open(string, 0);
- if(f < 0) {
- printf("%s: cannot open\n", string);
- break;
- }
- while((i=read(f, db, 512)) > 0) {
- in.i_size1 =+ i;
- newblk(&dbc, db, &ibc, ib);
- }
- close(f);
- break;
-
- case IFBLK:
- case IFCHR:
- /*
- * special file
- * content is maj/min types
- */
-
- in.i_addr[0] = getnum()<<8;
- in.i_addr[0] =| getnum();
- break;
-
- case IFDIR:
- /*
- * directory
- * put in extra links
- * call recursively until
- * name of "$" found
- */
-
- par->i_nlink++;
- entry(par->i_number, "..", &dbc, db, &ibc, ib);
- in.i_nlink++;
- entry(in.i_number, ".", &dbc, db, &ibc, ib);
- in.i_size1 = 32;
- for(;;) {
- getstr();
- if(string[0]=='$' && string[1]=='\0')
- break;
- entry(ino+1, string, &dbc, db, &ibc, ib);
- in.i_size1 =+ 16;
- cfile(&in);
- }
- break;
- }
- if(dbc != 0)
- newblk(&dbc, db, &ibc, ib);
- if(ibc > 8) {
- in.i_mode =| ILARG;
- dbc = alloc();
- wtfs(dbc, ib);
- in.i_addr[0] = dbc;
- } else
- for(i=0; i<ibc; i++)
- in.i_addr[i] = ib[i];
- in.i_time[0] = in.i_time[2] = utime[0];
- in.i_time[1] = in.i_time[3] = utime[1];
- i = in.i_number + 31;
- dbc = ldiv(0, i, 16);
- p1 = &buf[lrem(0, i, 16)*16];
- p2 = &in.i_mode;
- rdfs(dbc, buf);
- for(i=0; i<16; i++)
- *p1++ = *p2++;
- wtfs(dbc, buf);
- }
-
- gmode(c, s, m0, m1, m2, m3)
- char c, *s;
- {
- int i;
-
- for(i=0; s[i]!='\0'; i++)
- if(c == s[i])
- return((&m0)[i]);
- if(c == '-')
- return(0);
- printf("%c/%s: bad mode\n", c, string);
- exit();
- }
-
- getnum()
- {
- int n, i;
-
- getstr();
- n = 0;
- i = 0;
- for(i=0; string[i]!='\0'; i++) {
- if(string[i]<'0' || string[i]>'9') {
- printf("%s: bad number\n", string);
- exit();
- }
- n = n*10 + string[i] - '0';
- }
- return(n);
- }
-
- getstr()
- {
- int i, c;
-
- loop:
- switch(c=getch()) {
-
- case ' ':
- case '\t':
- case '\n':
- goto loop;
-
- case '\0':
- printf("EOF\n");
- exit();
-
- case ':':
- while(getch() != '\n');
- goto loop;
-
- }
- i = 0;
-
- do {
- string[i++] = c;
- c = getch();
- } while(c!=' '&&c!='\t'&&c!='\n'&&c!='\0');
- string[i] = '\0';
- }
-
- rdfs(bno, bf)
- {
- int n;
-
- seek(fsi, bno, 3);
- n = read(fsi, bf, 512);
- if(n != 512) {
- printf("read error: %l\n", bno);
- exit();
- }
- }
-
- wtfs(bno, bf)
- {
- int n;
-
- seek(fso, bno, 3);
- n = write(fso, bf, 512);
- if(n != 512) {
- printf("write error: %l\n", bno);
- exit();
- }
- }
-
- alloc()
- {
- int bno, i;
-
- filsys.s_nfree--;
- bno = filsys.s_free[filsys.s_nfree];
- filsys.s_free[filsys.s_nfree] = 0;
- if(bno == 0) {
- printf("out of free space\n");
- exit();
- }
- if(filsys.s_nfree <= 0) {
- rdfs(bno, buf);
- filsys.s_nfree = buf[0];
- for(i=0; i<100; i++)
- filsys.s_free[i] = buf[i+1];
- }
- return(bno);
- }
-
- free(bno)
- {
- int i;
-
- if(filsys.s_nfree >= 100) {
- buf[0] = filsys.s_nfree;
- for(i=0; i<100; i++)
- buf[i+1] = filsys.s_free[i];
- wtfs(bno, buf);
- filsys.s_nfree = 0;
- }
- filsys.s_free[filsys.s_nfree] = bno;
- filsys.s_nfree++;
- }
-
- entry(ino, str, adbc, db, aibc, ib)
- char *str;
- int *adbc, *db, *aibc, *ib;
- {
- char *s;
- int i;
-
- db[*adbc] = ino;
- (*adbc)++;
- s = &db[*adbc];
- for(i=0; i<14; i++) {
- *s++ = *str;
- if(*str != '\0')
- str++;
- }
- *adbc =+ 7;
- if(*adbc >= 256)
- newblk(adbc, db, aibc, ib);
- }
-
- newblk(adbc, db, aibc, ib)
- int *adbc, *db, *aibc, *ib;
- {
- int bno, i;
-
- bno = alloc();
- wtfs(bno, db);
- for(i=0; i<256; i++)
- db[i] = 0;
- *adbc = 0;
- ib[*aibc] = bno;
- (*aibc)++;
- if(*aibc >= 256) {
- printf("indirect block full\n");
- exit();
- }
- }
-
- getch()
- {
-
- if(charp)
- return(*charp++);
- return(getchar());
- }
-
- bflist()
- {
- char flg[100], adr[100];
- register i, j;
- char *low, *high;
-
- if(f_n > 100)
- f_n = 100;
- for(i=0; i<f_n; i++)
- flg[i] = 0;
- i = 0;
- for(j=0; j<f_n; j++) {
- while(flg[i])
- i = (i+1)%f_n;
- adr[j] = i;
- flg[i]++;
- i = (i+f_m)%f_n;
- }
-
- high = filsys.s_fsize-1;
- low = filsys.s_isize+2;
- free(0);
- for(i=high; lrem(0,i+1,f_n); i--) {
- if(i < low)
- break;
- free(i);
- }
- for(; i >= low+f_n; i =- f_n)
- for(j=0; j<f_n; j++)
- free(i-adr[j]);
- for(;i >= low; i--)
- free(i);
- }
-