home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / source / s2 / mkfs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1975-05-13  |  7.4 KB  |  505 lines

  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. }
  505.