home *** CD-ROM | disk | FTP | other *** search
- /* minit Minix INITializer . Freely distributable Minix filesys creator.
- * Copyright S N Henson Nov 1991 .
- * Use entirely at your own risk ! If it trashes your hard-drive then
- * it isn't my fault !
- */
-
- /* Version 0.211 */
- /* Compile with gcc -O -o minit.ttp minit.c -liio */
-
- #include <osbind.h>
- #include <stdio.h>
- #include <time.h>
- #include <string.h>
- #include <unistd.h>
- #include <stdlib.h>
-
- /* New extended Rwabs function , same as Rwabs except sectors can
- * be specified as longs , this will be needed for large V2 filesystems.
- * you will need to change this for other compilers ....
- */
-
- #define _XRwabs(a,b,c,d,e,f) \
- trap_13_wwlwwwl((short)(0x04),(short)(a),(long)(b),(short)(c),(short)(d)\
- ,(short)(e),(long)(f) )
-
- #define trap_13_wwlwwwl(n, a, b, c, d, e, f) \
- ({ \
- register long retvalue __asm__("d0"); \
- volatile short _a = (volatile short)(a); \
- volatile long _b = (volatile long) (b); \
- volatile short _c = (volatile short)(c); \
- volatile short _d = (volatile short)(d); \
- volatile short _e = (volatile short)(e); \
- volatile long _f = (volatile long) (f); \
- \
- __asm__ volatile \
- ("\
- movl %5,sp@-; \
- movw %4,sp@-; \
- movw %3,sp@-; \
- movw %2,sp@-; \
- movl %1,sp@-; \
- movw %0,sp@- " \
- : /* outputs */ \
- : "g"(_a), "g"(_b), "g"(_c), "g"(_d), "g"(_e), "g"(_f) /* inputs */ \
- ); \
- \
- __asm__ volatile \
- ("\
- movw %1,sp@-; \
- trap #13; \
- addw #18,sp " \
- : "=r"(retvalue) /* outputs */ \
- : "g"(n) /* inputs */ \
- : "d0", "d1", "d2", "a0", "a1", "a2" /* clobbered regs */ \
- ); \
- retvalue; \
- })
-
-
- /* Change this if needed , but only if you know what you are doing */
- /* You shouldn't need to with the -n option though */
-
- #define MNAME_MAX 14
-
- int shift,drive=-1;
- long numblocks,numinodes,incr=1;
-
- /* various flags */
- char protect,sonly,zbpb,v2,lrecno,tst;
-
- unsigned char block_buf[1024];
-
- /* Structures we will need */
-
- typedef struct {
- unsigned short s_ninodes; /* # usable inodes on the minor device */
- unsigned short s_nzones; /* total device size, including bit maps etc */
- unsigned short s_imap_blks; /* # of blocks used by inode bit map */
- unsigned short s_zmap_blks; /* # of blocks used by zone bit map */
- unsigned short s_firstdatazn; /* number of first data zone */
- short int s_log_zsize; /* log2 of blocks/zone */
- unsigned long s_max_size; /* maximum file size on this device */
- short s_magic; /* magic number to recognize super-blocks */
- short pad; /* padding */
- long s_zones; /* equivalent to 's_nzones' for V2 */
- } super_block;
-
-
-
- typedef struct { /* directory entry */
- unsigned short d_inum; /* inode number */
- char d_name[MNAME_MAX]; /* character string */
- } dir_struct;
-
- typedef struct { /* disk inode. */
- unsigned short i_mode; /* file type, protection, etc. */
- unsigned short i_uid; /* user id of the file's owner */
- unsigned long i_size; /* current file size in bytes */
- unsigned long i_mtime; /* when was file data last changed */
- unsigned char i_gid; /* group number */
- unsigned char i_nlinks; /* how many links to this file */
- unsigned short i_zone[9]; /* block nums for direct, ind, and dbl ind */
- } d_inode;
-
- typedef struct {
- unsigned short i_mode;
- unsigned short i_nlinks;
- unsigned short i_uid;
- unsigned short i_gid;
- unsigned long i_size;
- unsigned long i_atime;
- unsigned long i_mtime;
- unsigned long i_ctime;
- long i_zone[10];
- } d_inode2;
-
- /* prototypes */
-
- #ifdef __STDC__
- # define P(s) s
- #else
- # define P(s) ()
- #endif
-
-
- int main P((int argc , char **argv ));
- int nrwabs P((int rw , void *buf , unsigned count , long recno , int drive ));
- void get_block P((long num ));
- void put_block P((long num ));
- void check_lrecno P((void ));
- int warn P((void ));
-
- #undef P
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- extern int optind,opterr;
- extern char *optarg;
- int c ;
- static char err=0;
- int i,j;
- unsigned short *bpb;
- unsigned short ioff,zone1;
- super_block *sblk=(super_block *)block_buf,csblk;
- d_inode *rip=(d_inode *)block_buf;
- d_inode2 *ripn=(d_inode2 *)block_buf;
- dir_struct *dir=(dir_struct *)block_buf;
- unsigned short *srt=(unsigned short *)block_buf;
-
- /* Parse command-line options */
- opterr=0;
- while((c=getopt(argc,argv,"b:B:i:I:n:pPSZtV"))!=EOF)
- {
- switch(c){
-
- case 'B':
- case 'b':
- numblocks=atol(optarg);
- break;
-
- case 'n':
- incr=atol(optarg);
- break;
-
- case 'i':
- case 'I':
- numinodes=atol(optarg);
- break;
-
- case 'P':
- protect=1;
- break;
-
- case 'p':
- protect=2;
- break;
-
- case 'S':
- sonly=1;
- break;
-
- case 'Z':
- zbpb=1;
- break;
-
- case 'V':
- v2=1;
- break;
-
- case 't':
- tst=1;
- break;
-
- case '?':
- err=1;
- break;
- }
- }
-
- if(argc-optind!=1 || err || (zbpb && protect) )
- {
- fprintf(stderr,"Minix-compatible filesystem initializer\n");
- fprintf(stderr,"Copyright S N Henson Nov 1991\n");
- fprintf(stderr,"Version 0.211\n");
- fprintf(stderr,"Usage\t(auto)\t: minit drive\n");
- fprintf(stderr,"\t(manual): minit -b blocks -i inodes drive\n");
- fprintf(stderr,"Also :\t-S only write out super-block\n");
- fprintf(stderr,"\t-P protect filesystem with null disk\n");
- fprintf(stderr,"\t-p make null disk of existing filestystem\n");
- fprintf(stderr,"\t-Z protect with zero BPB\n");
- fprintf(stderr,"\t-V make a V2 filesystem\n");
- fprintf(stderr,"\t-n dirincrement\n");
- fprintf(stderr,"\t-t test for lrecno in driver software\n");
- exit(1);
- }
- drive=(argv[optind][0] & ~32)-'A' ;
-
- /* Sanity checking time */
-
- if((incr < 1) || (incr > 16) || ( (incr) & (incr-1) ) )
- {
- fprintf(stderr,"Dirincrement must be a power of two between\n");
- fprintf(stderr,"1 and 16 (inclusive)\n");
- exit(1);
- }
-
- if( (numinodes < 0) || (numinodes > 65535) )
- {
- fprintf(stderr,"Need at least 1 and no more than 65535 inodes\n");
- exit(1);
- }
-
- if(!(bpb=Getbpb(drive))) {
- fprintf(stderr,"Drive %c : Bad or illegal BPB\n",drive+'A');
- exit(1);
- }
- if(bpb[0]!=512 && bpb[0]!=1024) {
- fprintf(stderr,"Sorry unsupported sector size: %d\n",bpb[0]);
- exit(1);
- }
- if(bpb[0]==512)shift=1;
- else if(protect)
- {
- fprintf(stderr,"Null disk requires 512 byte sectors\n");
- exit(1);
- }
-
- if(drive > 1 ) check_lrecno();
-
- if(tst)
- {
- if(lrecno) fprintf(stderr,"Lrecno supported by this setup\n");
- else fprintf(stderr,"Lrecno not supported by this setup\n");
- exit(0);
- }
-
- /* Work out parameters */
-
- get_block(0); /* Read in boot sector */
- /* Get filesys size from bootsector if not given */
- if(numblocks==0)
- {
- numblocks=(block_buf[19]+( ((long)block_buf[20])<<8))>>shift;
- if(numblocks < 40 ){
- fprintf(stderr,"%ld blocks ? Is that bootsector OK ?\n",numblocks);
- exit(1);
- }
- }
-
- if(!v2 && (numblocks > 65535) ) {
- fprintf(stderr,"V1 filesystems can be at most 65535 blocks\n");
- exit(1);
- }
-
- if( !lrecno && (numblocks > 65535) ) {
- fprintf(stderr,"Filesystems bigger than 64MEG require lrecno\n");
- exit(1);
- }
-
- if( !lrecno && shift && (numblocks > 32767) ) {
- fprintf(stderr,"Filesytems bigger than 32MEG require 1K sectors\n");
- exit(1);
- }
-
- get_block(numblocks-1); /* Try to read last block */
-
- if(numinodes==0)
- {
- numinodes = numblocks/3;
-
- /* Round up inode number to nearest block */
-
- if(v2) numinodes = (numinodes + 15) & ~15;
-
- else numinodes=(numinodes + 31 ) & ~31;
- }
-
- if(numinodes > 65535) numinodes=65535;
-
- if(protect==2)
- {
- get_block(1);
- if( (sblk->s_magic != 0x137f) && (sblk->s_magic!=0x2468) )
- {
- fprintf(stderr,"Fatal: bad magic number\n");
- exit(1);
- }
- }
-
- warn();
-
- /* Set up boot sector */
-
- if(!sonly && (protect || zbpb) )
- {
- get_block(0);
- if(protect)
- {
- /* Make GEMDOS think we have a tiny partition */
- /* With root directory immediately after super-block */
- block_buf[16]=2;
- block_buf[17]=16;
- block_buf[18]=0;
- block_buf[22]=1;
- block_buf[23]=0;
- }
- else if(zbpb)
- {
- block_buf[16]=block_buf[17]=block_buf[18]=0;
- block_buf[22]=block_buf[23]=0;
- }
- strcpy((char *)(&block_buf[2]),"MINIX");
- put_block(0);
- }
-
-
- /* OK lets work out some stuff */
-
- if(protect==2) get_block(1);
- else
- {
- bzero(block_buf,1024l);
- /* Super block */
- sblk->s_ninodes=numinodes;
- if(v2) sblk->s_zones=numblocks;
- else sblk->s_nzones=numblocks;
- sblk->s_imap_blks=(numinodes+8192)/8192;
- sblk->s_zmap_blks=(numblocks+8191)/8192;
- sblk->s_firstdatazn=2+sblk->s_imap_blks+sblk->s_zmap_blks
- + ( v2 ? ((numinodes+15)/16) : ((numinodes+31)/32)) ;
- sblk->s_log_zsize=0;
- sblk->s_max_size= v2 ? 0x4041c00l : 0x10081c00l;
- sblk->s_magic= v2 ? 0x2468 : 0x137f;
- }
-
- /* If protecting fill up the pseudo root directory with vol names */
- if(protect)
- {
- bzero(&block_buf[512],512);
- for(i=512;i<1024;i+=32)
- {
- strncpy((char*)&block_buf[i],"MINIXFS ",11);
- block_buf[i+11]=0x08;
- }
- }
-
- put_block(1);
-
- if( sonly || protect==2 ) exit(0);
-
- csblk=*sblk;
-
- ioff=2+sblk->s_imap_blks+sblk->s_zmap_blks;
- zone1=sblk->s_firstdatazn;
-
- bzero(block_buf,1024l);
-
- /* Inode bitmaps */
-
- for(i=2;i<2+csblk.s_imap_blks;i++)
- {
- long icount=numinodes+1;
- if(i==2)
- {
- srt[0]=3;
- }
- if(icount < 8192) /* Need to mark dead inodes as used */
- {
- if(icount & 15)
- {
- srt[icount/16] = 0xffff << (icount & 15);
- icount+= 16 - (icount & 15);
- }
- for(j=icount/16;j<512;j++)srt[j]=0xffff;
- }
- put_block(i);
- if(i==2)srt[0]=0;
- icount-=8192;
- }
-
- bzero(block_buf,1024l);
-
- /* Zone bitmaps */
-
- for(i=2+csblk.s_imap_blks;i<ioff;i++)
- {
- long zcount=numblocks+1-csblk.s_firstdatazn;
- if(i==2+csblk.s_imap_blks)
- {
- srt[0]=3;
- }
- if(numblocks < 8192) /* Need to mark dead zones as used */
- {
- if(zcount & 15)
- {
- srt[zcount/16] = 0xffff << (zcount & 15);
- zcount+= 16 - (zcount & 15);
- }
- for(j=zcount/16;j<512;j++)srt[j]=0xffff;
- }
- put_block(i);
- if(i==2+csblk.s_imap_blks)srt[0]=0;
- zcount-=8192;
- }
-
- bzero(block_buf,1024l);
-
- /* Initialise inodes */
-
- for(i=ioff;i<ioff+
- (v2 ? ((numinodes +15)/16) : ((numinodes+31)/32 )) ;i++)
- {
- if(i==ioff) /* Root inode , initialise it properly */
- {
- if(v2)
- {
- ripn->i_mode=040777; /* Directory */
- ripn->i_size=32*incr;
- ripn->i_mtime=time((time_t *)0);
- ripn->i_ctime=ripn->i_mtime;
- ripn->i_atime=ripn->i_mtime;
- ripn->i_nlinks=2;
- ripn->i_zone[0]=zone1;
- }
- else
- {
- rip->i_mode=040777; /* Directory */
- rip->i_size=32*incr;
- rip->i_mtime=time((time_t *)0);
- rip->i_nlinks=2;
- rip->i_zone[0]=zone1;
- }
- }
- put_block(i);
- if(i==ioff)bzero(block_buf,1024l);
- }
-
- bzero(block_buf,1024l);
- /* And finally the root directory */
- dir[0].d_inum=1;
- strcpy(dir[0].d_name,".");
- dir[incr].d_inum=1;
- strcpy(dir[incr].d_name,"..");
- put_block(zone1);
- fprintf(stderr,"Initialised OK.\n");
- fprintf(stderr,"%ld Blocks , %ld Inodes.\n",numblocks,numinodes);
- exit(0);
- }
-
- int nrwabs(rw,buf,count,recno,dev)
- int rw;
- void *buf;
- unsigned count;
- long recno;
- int dev;
- {
- if(lrecno && (dev > 1) )
- return (_XRwabs(rw,buf,count,-1,dev,recno) );
- else return (Rwabs(rw,buf,count,(unsigned)(recno),dev) );
- }
-
- void get_block(num)
- long num;
- {
-
-
- if(nrwabs(2,block_buf,1<<shift,num<<shift,drive))
- {
- fprintf(stderr,"Fatal Read Error block %d\n",num);
- exit(0);
- }
- }
-
-
-
-
- void put_block(num)
- long num;
- {
- if(nrwabs(3,block_buf,1<<shift,num<<shift,drive))
- {
- fprintf(stderr,"Fatal Write Error block %d\n",num);
- exit(0);
- }
- }
-
- /* entirely unoffical attempt to check for the existance of 'lrecno' */
-
- char block_buf2[1024];
-
- void check_lrecno()
- {
- /* read in boot block */
- if(Rwabs(2,block_buf,1<<shift,0,drive)) return;
-
- /* read it in with lrecno */
- if( _XRwabs(2,block_buf2,1<<shift,-1,drive,0l) ) return;
-
- /* Compare the two */
- if(bcmp(block_buf,block_buf2,1024)) return;
-
- /* read in next sector with lrecno */
-
- if(_XRwabs(2,block_buf2,1<<shift,-1,drive,1l)) return;
-
- /* compare the two */
-
- if(!bcmp((char *)block_buf,block_buf2,1024)) return;
-
- lrecno=1;
-
- return;
-
- }
-
- warn()
- {
- int ch;
- fprintf(stderr,"WARNING ! THIS %s TOTALLY DESTROY ANY DATA ON ",
- (sonly || protect) ? "MAY":"WILL");
- fprintf(stderr,"DRIVE %c !\n",drive+'A');
- fprintf(stderr,"Are you ABSOLUTELY SURE you want to do this (y/n)?\n");
- ch=Crawcin() & 0xff ;
- if(ch!='Y' && ch!='y')
- {
- fprintf(stderr,"Aborted\n");
- exit(0);
- }
- }
-