📄 badblo~1.c
字号:
if (umount(dev_name) == -1) { printf("Can not umount device anymore??? \n"); done(DIR_CREATED); } if ((fd = open(dev_name, O_RDWR)) == -1) { printf("Can not open device %s\n", dev_name); done(DEV_MOUNTED); } if (fstat(fd, &dev_stat) == -1) { printf("fstat on device %s failed\n", dev_name); done(DEV_MOUNTED); } if ((dev_stat.st_mode & S_IFMT) != S_IFBLK) { printf("Device \"%s\" is not a block_special.\n", dev_name); done(DEV_MOUNTED); } get_super(); if (sp->s_log_zone_size) { printf("Block_size != zone_size."); printf("This program can not handle it\n"); done(DIR_CREATED); } /* The number of inodes in a block differs in V1 and V2. */ if (v1fs) { inodes_per_block = V1_INODES_PER_BLOCK; inode_size = V1_INODE_SIZE; } else { inodes_per_block = V2_INODES_PER_BLOCK; inode_size = V2_INODE_SIZE; } get_inode(&stat_buf); for (finished = 0; !finished;) { if (interactive) printf("Give up to %d bad block numbers separated by spaces\n", V_SMALLER); reset_blks(); cnt = 0; /* cnt keep track of the zone's */ while (cnt < V_SMALLER) { int tst; if (interactive) blk_nr = rd_num(); else blk_nr = rd_cmdline(argc, argv); if (blk_nr == -1) break; tst = blk_ok(blk_nr); /* Test if this block is free */ if (tst == OK) { cnt++; save_blk(blk_nr); } else if (tst == QUIT) break; } if (interactive) show_blks(); if (!cnt) done(FILE_EXISTS); if (interactive) { switch (ok("All these blocks ok <y/n/q> (y:Device will change) ")) { case OK: finished = 1; break; case NOT_OK: break; case QUIT: done(FILE_EXISTS); } } else { finished = 1; } } modify(cnt); close(fd); /* free device */ done(SUCCESS); return(0);}long rd_cmdline(argc, argv)int argc;char *argv[];{ if (position == argc) return(-1); return(atol(argv[position++]));}void modify(nr_blocks)int nr_blocks;{ int i; if (nr_blocks == 0) return; if (v1fs) { /* This is a V1 file system. */ for (i = 0; i < nr_blocks; i++) { set_bit(block[i]); ip1->d1_zone[i] = block[i]; } } else { /* This is a V2 file system. */ for (i = 0; i < nr_blocks; i++) { set_bit(block[i]); ip2->d2_zone[i] = block[i]; } } if (v1fs) { ip1->d1_size = (long) (BLOCK_SIZE * nr_blocks); /* give file size */ ip1->d1_mtime = 0; /* Who wants a file from 1970? */ } else { ip2->d2_size = (long) (BLOCK_SIZE * nr_blocks); /* give file size */ ip2->d2_atime = ip2->d2_mtime = ip2->d2_ctime = 0; } put_inode(&stat_buf); /* save the inode on disk */ put_super(); /* bit_maps too */}static blk_cnt = 0;void save_blk(blk_num)block_t blk_num;{ block[blk_cnt++] = blk_num;}void reset_blks(){ int i; for (i = 0; i <= V_NR_DZONES; i++) block[i] = 0; /* Note: Last block_number is set to zero */ blk_cnt = 0;}void show_blks(){ int i; for (i = 0; i < blk_cnt; i++) printf("Block[%d] = %lu\n", i, (unsigned long) block[i]);}int blk_is_used(blk_num)block_t blk_num;{ /* return TRUE(1) if used */ int i; for (i = 0; block[i] && block[i] != blk_num; i++); return(block[i] != 0) ? 1 : 0;} /* ===== bitmap handling ====== */#define BIT_MAP_SHIFT 13#define INT_BITS (SIZE_OF_INT << 3)int blk_ok(num) /* is this zone free (y/n) */block_t num;{ block_t blk_offset; int rd; int blk, offset, words, bit, tst_word; zone_t z_num; if (blk_is_used(num)) { printf("Duplicate block (%lu) given\n", (unsigned long) num); return NOT_OK; } /* Assumption zone_size == block_size */ z_num = num - (sp->s_firstdatazone - 1); /* account offset */ /* Calculate the word in the bitmap. */ blk = z_num >> BIT_MAP_SHIFT; /* which block */ offset = z_num - (blk << BIT_MAP_SHIFT); /* offset */ words = z_num / INT_BITS; /* which word */ blk_offset = (block_t) (2 + sp->s_imap_blocks); /* zone map */ blk_offset *= (block_t) BLOCK_SIZE; /* of course in block */ blk_offset += (block_t) (words * SIZE_OF_INT); /* offset */ lseek(fd, (off_t) 0, SEEK_SET); /* rewind */ lseek(fd, (off_t) blk_offset, SEEK_SET); /* set pointer at word */ rd = read(fd, (char *) &tst_word, SIZE_OF_INT); if (rd != SIZE_OF_INT) { printf("Read error in bitmap\n"); done(DIR_CREATED); } /* We have the tst_word, check if bit was off */ bit = offset % INT_BITS; if (((tst_word >> bit) & 01) == 0) /* free */ return OK; else { printf("Bad number %lu. ", (unsigned long) num); printf("This zone (block) is marked in bitmap\n"); return NOT_OK; }}void set_bit(num) /* write in the bitmap */zone_t num;{ int rwd; long blk_offset; int blk, offset, words, tst_word, bit; unsigned z_num; z_num = num - (sp->s_firstdatazone - 1); blk = z_num >> BIT_MAP_SHIFT; /* which block */ offset = z_num - (blk << BIT_MAP_SHIFT); /* offset in block */ words = z_num / INT_BITS; /* which word */ blk_offset = (long) (2 + sp->s_imap_blocks); blk_offset *= (long) BLOCK_SIZE; blk_offset += (long) (words * SIZE_OF_INT); lseek(fd, (off_t) 0, SEEK_SET); /* rewind */ lseek(fd, (off_t) blk_offset, SEEK_SET); rwd = read(fd, (char *) &tst_word, SIZE_OF_INT); if (rwd != SIZE_OF_INT) { printf("Read error in bitmap\n"); done(DEV_MOUNTED); } bit = offset % INT_BITS; if (((tst_word >> bit) & 01) == 0) { /* free */ lseek(fd, 0L, SEEK_SET);/* rewind */ lseek(fd, (off_t) blk_offset, SEEK_SET); tst_word |= (1 << bit); /* not free anymore */ rwd = write(fd, (char *) &tst_word, SIZE_OF_INT); if (rwd != SIZE_OF_INT) { printf("Bad write in zone map\n"); printf("Check file system \n"); done(DIR_CREATED); } return; } printf("Bit map indicates that block %lu is in use. Not marked.\n", (unsigned long) num);/* done(DIR_CREATED); */ return;} /* ======= interactive interface ======= */long rd_num(){ /* read a number from stdin */ long num; int c; if (eofseen) return(-1); do { c = getchar(); if (c == EOF || c == '\n') return(-1); } while (c != '-' && (c < '0' || c > '9')); if (c == '-') { printf("Block numbers must be positive\n"); exit(1); } num = 0; while (c >= '0' && c <= '9') { num *= 10; num += c - '0'; c = getchar(); if (c == '\n') eofseen = 1; } return num;}int ok(str)char *str;{ int c; for (;;) { printf("%s", str); while ((c = getchar()) != EOF && c != 'y' && c != 'n' && c != 'q') if (c != '\n') printf(" Bad character %c\n", (char) c); switch (c) { case EOF: return QUIT; case 'y': return OK; case 'n': return NOT_OK; case 'q': return QUIT; } printf("\n"); }}void done(nr)int nr;{ switch (nr) { case SUCCESS: case FILE_EXISTS: unlink(file_name); case DEV_MOUNTED: umount(dev_name); case DIR_CREATED: rmdir(dir_name); case HARMLESS:; } sync(); exit(nr == SUCCESS ? 0 : 1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -