int main(int argc, char *argv[]) { /* control variables */ int result; // store result of various system calls int part_number; // copy partition number from argv[3] int count; // counter char temp; // destroy partition or not int part_entry[4]; // copy partition entry int file_desc; /* address variables */ char *dir_entry_tmp; // pointer to dir_entry char *part_type_ptr; // pointer to partition type in partition table unsigned int *pt_ptr; // pointer to partition table unsigned int *empty_ivec; // store empty vector on disk for ivector int *buf_int_ptr; // buffer to store sector struct free_blocks_list *free_local; double percent; if (argc != 4) { instructions(); return 0; } /* Magic block */ for (i=0; i<=511; i++) magic_block[i] = 'a'; magic_block[512] = '\0'; /* Open special file representing partition */ if ( (part_fd = open(argv[1], O_RDWR | O_SYNC)) == -1) { perror("open()"); return 0; } printf("\nInstalling file system..."); printf("\n==========================================================\n"); printf("Using partition %s ", argv[1]); /* Open special file representing disk */ if ( (disk_fd = open(argv[2], O_RDONLY)) == -1) { perror("open()"); return 0; } printf("From device %s\n", argv[2]); sb_off_local = find_magic(sb_off_local); if (sb_off_local == 0) return 0; sb_off_local++; /* off by one */ /* * Determine total number of sectors. */ if ( (result = read(disk_fd, mbr, SEC_SIZE)) == -1) { perror("pread()"); return 0; } /* Convert to partition number */ part_number = atoi(argv[3]); /* Point to partition entry */ for (pt_ptr = (unsigned int *)(mbr + PT_OFF); part_number != 0; pt_ptr += 4, part_number--) ; /* * Make sure not to delete sensible data. */ printf("Partition entry is: \n"); printf("Partition type -> 0x%x\n", (unsigned char)pt_ptr[1]); part_type_ptr = (char *)(pt_ptr[1]); /* save pointer to partition type */ printf("Starting at sector -> %d\n", pt_ptr[2]); printf("And size -> %d (%dMB)\n", pt_ptr[3], ((pt_ptr[3]/1024)*SEC_SIZE)/1024); printf("\n"); if ((unsigned char)pt_ptr[1] != 0) { printf("It appears to be a "); switch ((unsigned char)pt_ptr[1]) { case 0x83: printf("Linux "); break; case 0xa5: printf("FreeBSD "); break; case 0x0c: printf("FAT "); break; case 0x50: printf("SOS "); break; default: printf("unknown "); } printf("partition.\n\n"); write(1, do_you, strnlen(do_you, 255)); do { printf("\n(y or n)\n-> "); scanf("%c", &temp); } while(temp != 'y' && temp != 'n'); if (temp == 'n') return 0; } printf("DESTROYING!!\n"); /* MUAJAJAJAJAJAJAJAJA */ pt_ptr += 2; /* point to 4 bytes that determine start of partition */ /* * Start of partition in sectors. */ part_start_local = *pt_ptr; pt_ptr += 1; part_size = *pt_ptr; /* * Save some values to the superblock structure. */ sb.sb_part_start = part_start_local; sb.sb_off = sb_off_local; sb.sb_part_size_total = part_size; sb.sb_size += sizeof(sb)/SEC_SIZE; /* * Determine the size of one ivector as follows: * Each entry in the ivector is 2 bytes, so 256 entries fit in one sector. * The minimum unit size is BLOCK_SIZE, so we divide the total amount of * sectors in a single address space by BLOCK_SIZE to obtain the number * of blocks in one address space. Finally we divide the number of blocks by * the number of entries in one sector to obtain the number of sectors * necessary to address all blocks in the address space. We add one because * the division might not be exact, and store the remainder. * sb.sb_ivec_size_sec is in sector units. * sb.sb_ivec_size_rem is in entry units (2 bytes). */ sb.sb_ivec_size_sec = (SECS_PER_ADDR_SP/ENTS_IVEC_PER_SEC)+1; sb.sb_ivec_size_rem = SECS_PER_ADDR_SP%ENTS_IVEC_PER_SEC; /* Determine size of free blocks bit map */ sb.sb_free_blocks_map_size_sec = ((sb.sb_part_size_total- (sb.sb_off+sb.sb_size))/ENTS_BITS_PER_SEC)+1; sb.sb_free_blocks_map_size_sec -= sb.sb_free_blocks_map_size_sec/ ENTS_BITS_PER_SEC; sb.sb_free_blocks_map_size_rem = sb.sb_part_size_total%ENTS_BITS_PER_SEC; /* * Calculate usable partition size */ sb.sb_part_size = sb.sb_part_size_total - sb.sb_free_blocks_map_size_sec - sb.sb_off - sb.sb_size; /* * Determine amount of ivectors. */ for (count=0,i=sb.sb_part_start+sb.sb_ivec_off; i<sb.sb_part_start+sb.sb_part_size_total; i+=(SECS_PER_ADDR_SP+1), count++) { sb.sb_num_addr_sp++; } sb.sb_part_size -= sb.sb_ivec_size_sec*count; sb.sb_num_addr_sp += (sb.sb_free_blocks_map_size_sec - sb.sb_ivec_size_sec/count)/SECS_PER_ADDR_SP; sb.sb_free_blocks_map_size_sec -= (sb.sb_ivec_size_sec*count)/ ENTS_BITS_PER_SEC; /* Offset in sectors to the first ivector */ sb.sb_ivec_off = sb.sb_off + sb.sb_size + sb.sb_free_blocks_map_size_sec; /* Offset in sectors to the end of the first ivector */ sb.sb_ivec_end = (sb.sb_ivec_off + sb.sb_ivec_size_sec)+1; /* * Write bit map. */ lseek(part_fd, (sb.sb_off+sb.sb_size)*SEC_SIZE, SEEK_SET); printf("Writing bit map of free blocks...\n"); for (i=0; i<sb.sb_free_blocks_map_size_sec; i++) { if ( (result=write(part_fd, buf_int, SEC_SIZE)) == -1) { perror("write()"); return 0; } verbose_percentage(i, sb.sb_free_blocks_map_size_sec); } /* * Write ivector entries initialized to zero. * Also subtract the ivectors from the partition size and bit map size. */ /* Vector to write to ivector */ empty_ivec = calloc(sb.sb_ivec_size_sec*SEC_SIZE, sizeof(char)); printf("Writing ivectors...\n"); for (count=0; count<sb.sb_num_addr_sp; count++) { if ( (pwrite(part_fd, empty_ivec, sb.sb_ivec_size_sec*SEC_SIZE, (((sb.sb_off+sb.sb_size+sb.sb_free_blocks_map_size_sec)*(SEC_SIZE))+ ((SECS_PER_ADDR_SP+1)*count)))) == -1) { perror("write()"); return 0; } verbose_percentage(count, sb.sb_num_addr_sp); } /* * Be verbose. */ if ( (file_desc = open("./SECTORS_IVEC", O_RDWR | O_CREAT)) == -1) { perror("open()"); return 0; } printf("%d ivectors of size %d sectors (%dKB)\n", sb.sb_num_addr_sp, sb.sb_ivec_size_sec, ((sb.sb_ivec_size_sec*SEC_SIZE)/1024)); for (i=0; i<sb.sb_num_addr_sp; i++) { dprintf(file_desc, "%d-%d\n", (sb.sb_ivec_off+(i*SECS_PER_ADDR_SP)), (sb.sb_ivec_off+sb.sb_ivec_size_sec)+(i*SECS_PER_ADDR_SP)); } printf("Sectors used were written to SECTORS_IVEC in current dir\n"); /* * Point to superblock. */ lseek(part_fd, sb.sb_off*SEC_SIZE, SEEK_SET); /* * Write superblock. */ if ( (result=write(part_fd, &sb, SEC_SIZE)) == -1) { perror("write()"); return 0; } /* * Be verbose. */ printf("The superblock of size %d bytes and bit map of size %d ", sizeof(sb), sb.sb_free_blocks_map_size_sec); printf("sectors (%dKB) was written to sectors %d-%d (%dKB-%dKB) ", (((sb.sb_free_blocks_map_size_sec)*SEC_SIZE)/1024), sb.sb_off, sb.sb_off+sb.sb_size+sb.sb_free_blocks_map_size_sec, (((sb.sb_off)*SEC_SIZE)/1024), (((sb.sb_off+sb.sb_size+sb.sb_free_blocks_map_size_sec)*SEC_SIZE)/1024)); printf("from beginning of partition\n"); /* * Take first ivector and write address in sectors of root inode. */ /* * Point to beginning of first ivector. */ lseek(part_fd, (sb.sb_off+sb.sb_size+sb.sb_free_blocks_map_size_sec) * SEC_SIZE, SEEK_SET); pread(part_fd, buf_int, SEC_SIZE, (sb.sb_off+sb.sb_size+sb.sb_free_blocks_map_size_sec)*SEC_SIZE); buf_int[0] = sb.sb_ivec_size_sec; /* * Write ivector entry for root directory. */ write(part_fd, buf_int, SEC_SIZE); /* * Update bit map to reflect root's inode. */ pread(part_fd, block, SEC_SIZE, ((sb.sb_off+sb.sb_size)*SEC_SIZE)); block[0] = 0x01; /* bit 1 and 2 */ pwrite(part_fd, block, SEC_SIZE, ((sb.sb_off+sb.sb_size)*SEC_SIZE)); /* * Fill inode. */ i_root.i_type = DIRECTORY; /* root is a directory */ i_root.i_dat_cont = TRUE; /* data is contigious */ i_root.i_ivec = ROOT; /* ivector is entry ROOT */ i_root.i_pivec = ROOT; /* parent ivector is entry ROOT */ i_root.i_dsize = 1; /* initial size in sectors of root directory */ count=0; i_root.i_filespec.i_dirspec.i_dirname[0] = '/'; i_root.i_filespec.i_dirspec.i_dir_ents = INIT_ROOT_ENTS; /* * Point to inode describing root directory. */ lseek(part_fd, (sb.sb_off+sb.sb_size+sb.sb_ivec_size_sec+sb.sb_free_blocks_map_size_sec) * SEC_SIZE, SEEK_SET); /* * Write inode of root directory. */ write(part_fd, &i_root, SEC_SIZE); /* * Point to beginning of data in root directory. */ pread(part_fd, buf_int, SEC_SIZE, (sb.sb_ivec_off * SEC_SIZE)); lseek(part_fd, (sb.sb_ivec_off+(buf_int[ROOT]+1))*SEC_SIZE, SEEK_SET); /* * Update bit map to reflect root's data. */ pread(part_fd, block, SEC_SIZE, ((sb.sb_off+sb.sb_size)*SEC_SIZE)); block[1] = 0x01; /* bit 1 and 2 */ pwrite(part_fd, block, SEC_SIZE, ((sb.sb_off+sb.sb_size)*SEC_SIZE)); /* * Write directory data. */ dir_entry_tmp = dir_entries; for (count=0; count<i_root.i_filespec.i_dirspec.i_dir_ents; count++) { strncpy(dir_entry_tmp, root_ents[count], 255); dir_entry_tmp = dir_entry_tmp + 8; /* point to second part of entry */ *dir_entry_tmp = 0; /* copy address space of entry */ dir_entry_tmp += 4; /* next entry */ *dir_entry_tmp = i_root.i_ivec; /* copy current and parent ivector */ dir_entry_tmp += 4; /* next entry */ } write(part_fd, dir_entries, SEC_SIZE); /* * Be verbose. */ printf("Root directory inode is at sector %d (%dKB) from partition start\n", sb.sb_off+sb.sb_size+sb.sb_ivec_size_sec+sb.sb_free_blocks_map_size_sec, (((sb.sb_off+sb.sb_size+sb.sb_ivec_size_sec+sb.sb_free_blocks_map_size_sec)*SEC_SIZE)/1024)); return 0; }
/******************************************************* 通过oid查找magic ********************************************************/ static int find_magic_parameter(const oid *name,int namelen) { return find_magic(name,namelen, PARAMETER_FATHERNODE_LENTH, parameter_variables); }