diff --git a/commands/Makefile b/commands/Makefile index f6e4705eb..a69076488 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -26,7 +26,7 @@ SUBDIR= aal add_route adduser arp ash at autil awk \ readfs reboot remsync rev rget rlogin rlogind rmdir \ rotate rsh rshd sed service setup shar acksize \ sleep slip sort spell split srccrc ackstrip \ - stty su sum svclog swapfs swifi sync synctree sysenv \ + stty su sum svclog swifi sync synctree sysenv \ syslogd tail tar tcpd tcpdp tcpstat tee telnet \ telnetd term termcap tget time tinyhalt touch tr \ truncate tsort tty udpstat umount uname unexpand \ diff --git a/commands/swapfs/Makefile b/commands/swapfs/Makefile deleted file mode 100644 index ea41986c4..000000000 --- a/commands/swapfs/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -PROG= swapfs -MAN= - -.include diff --git a/commands/swapfs/swapfs.c b/commands/swapfs/swapfs.c deleted file mode 100644 index b72ea5312..000000000 --- a/commands/swapfs/swapfs.c +++ /dev/null @@ -1,1044 +0,0 @@ -/* swapfs - swap a Minix file system Author: Niels C. Willems */ - - -/* Swapfs, a program to convert V1 or V2 Minix file systems from big endian - byte order to little endian and vv. - - Some examples: - swapfs -v disk.01 ! only show verbose information. - swapfs /dev/fd0 | compress > fd0r.Z ! convert and compress filesystem. - swapfs -v fileA fileA ! read, convert and write the same filesystem. - - This program uses one byte of heap memory for each data block (1Kbytes) - in the file system, so with Minix-PC 16-bit you can't swap file systems - bigger than about 32 Mbytes - - Be careful with 'swapfs fileA fileA'. If the program aborts e.g. by - user interrupt, power failure or an inconsistent file system, you - better have a backup of fileA - - This program only converts directories and indirect blocks of files - that are in use. Converting indirect blocks or directories of deleted - files is hard and not yet done. - - If you have a (1.6.xx, xx < 18) version of Minix that supports the - mounting of reversed file systems always mount them read-only and - avoid any attemp to modify them (mkdir, open, creat) too! - These problems have been fixed in Minix 1.6.18. - - In this version you can get some more information about the - file system with the -d (debug) flag. - - Please send your bug reports or ideas to ncwille@cs.vu.nl - */ - - -#define _POSIX_SOURCE 1 - -#include -#include -#include -#include -#include -#include -#include - -#include - -#if __STDC__ == 1 -#define _PROTOTYPE(function, params) function params -#else -#define _PROTOTYPE(function, params) function() -#endif - -#define BLOCK_SIZE 1024 - -#define BOOT_BLOCK_OFF (blockn_t) 0 -#define SUPER_BLOCK_OFF (blockn_t) 1 - -#define V1_MAGIC 0x137F -#define V2_MAGIC 0x2468 -#define NINODES_OFFSET 0 -#define V1_ZONES_OFFSET 2 -#define IMAP_BLOCKS_OFFSET 4 -#define ZMAP_BLOCKS_OFFSET 6 -#define FIRSTDATAZONE_OFFSET 8 -#define LOG_ZONE_SIZE_OFFSET 10 -#define MAGIC_OFFSET 16 -#define V2_ZONES_OFFSET 20 - - -#define NR_DIRECT_ZONES 7 -#define V1_NR_TZONES 9 -#define V2_NR_TZONES 10 -#define V1_INODE_SIZE 32 -#define V2_INODE_SIZE 64 - -#define INODE1_MODE_OFF 0 -#define INODE1_SIZE_OFF 4 -#define INODE1_DIRECT_OFF 14 -#define INODE1_IND1_OFF 28 -#define INODE1_IND2_OFF 30 - -#define INODE2_MODE_OFF 0 -#define INODE2_SIZE_OFF 8 -#define INODE2_DIRECT_OFF 24 -#define INODE2_IND1_OFF 52 -#define INODE2_IND2_OFF 56 -#define INODE2_IND3_OFF 60 - -#define INODE_MODE_MASK 0xf000 /* file type mask */ -#define INODE_DIR_MODE 0x4000 /* directory */ -#define INODE_BLK_SPECIAL_MODE 0x6000 /* block special */ -#define INODE_CHR_SPECIAL_MODE 0x2000 /* character special */ - -#define T_MASK 0x1c -#define T_UNKNOWN 0x00 -#define T_MAYBE_OLD_DIR 0x04 -#define T_OLD_NON_DIR 0x08 -#define T_DIR 0x0c -#define T_NON_DIR 0x10 - -#define INDIRECT_MASK 0x03 - -#define IND_PROCESSED_BIT 0x20 /* set when all blocks in ind block are - * marked */ -#define IND_CONFLICT_BIT 0x40 -#define TYPE_CONFLICT_BIT 0x80 - -#define DIR_ENTRY_SIZE 16 - -typedef enum { - Unused_zone, Old_zone, In_use_zone -} class_t; - -typedef unsigned long blockn_t; -typedef unsigned int inodesn_t; - -typedef struct { - inodesn_t ninodes; /* # usable inodes on the minor device */ - blockn_t imap_blocks; /* # of blocks used by inode bit map */ - blockn_t zmap_blocks; /* # of blocks used by zone bit map */ - blockn_t firstdatazone; /* number of first data zone */ - int log_zone_size; /* log2 of blocks/zone */ - blockn_t zones; /* number of zones */ - - int version; /* file system version */ - inodesn_t inodes_per_block; - blockn_t first_imap_block; - blockn_t first_zmap_block; - blockn_t first_inode_block; /* number of first block with inodes */ - size_t dzmap_size; /* # of data zone blocks */ -} super_t; - - -typedef struct { /* summary of inode */ - long size; /* current file size in bytes */ - blockn_t direct[NR_DIRECT_ZONES]; /* block numbers for direct, - * ind, ... */ - blockn_t ind1; /* single indirect block number */ - blockn_t ind2; /* double indirect block number */ - blockn_t ind3; /* triple indirect block number */ - int ztype; /* type of zones that belong to this inode */ -} inode_t; - -static int super_format[] = {2, 2, 2, 2, 2, 2, 4, 2, 2, 4, 0}; -static int inode1_format[] = {2, 2, 4, 4, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0}; -static int inode2_format[] = {2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 0}; - -static char *ind_str[4] = {"direct", "single indirect", - "double indirect", "triple indirect"}; - -static int big_endian_fs; /* set in init_super(), 1 iff file system has - * big endian byte order */ -static int verbose_flag; -static int debug_flag; -static int test_flag; - -typedef unsigned char *dzmap_t; - - -int _PROTOTYPE(main, (int argc, char *argv[])); -static void _PROTOTYPE(parse_args_init_io, (int argc, char *argv[])); -static void _PROTOTYPE(rw_boot, (void)); -static void _PROTOTYPE(rw_init_super, (super_t * sp)); -static void _PROTOTYPE(init_dzmap, (dzmap_t * dzmap_ptr, size_t dzmap_size)); -static void _PROTOTYPE(rw_ibmap, (super_t super)); -static void _PROTOTYPE(rw_zbmap, (super_t super)); -static void _PROTOTYPE(print_stat, (dzmap_t dzmap, super_t super)); -static void _PROTOTYPE(p1_rw_inodes, (dzmap_t dzmap, super_t super)); -static void _PROTOTYPE(rd_indirects, (dzmap_t dzmap, super_t super, int ind, - class_t required_class)); -static void _PROTOTYPE(rw_data_zones, (dzmap_t dzmap, super_t super)); - -static int _PROTOTYPE(read_block, (char *buf, blockn_t offset)); -static void _PROTOTYPE(write_block, (char *buf)); -static int _PROTOTYPE(convcpy, (char *dst, char *src, int *format)); -static void _PROTOTYPE(conv2_blkcpy, (char *dst, char *src)); -static void _PROTOTYPE(conv4_blkcpy, (char *dst, char *src)); -static void _PROTOTYPE(conv2cpy, (char *dst, char *src)); -static int _PROTOTYPE(inode_size, (int version)); - -static void _PROTOTYPE(init_super, (super_t * sp, char *buf)); -static void _PROTOTYPE(get_inode, (inode_t * ip, char *buf, int version)); -static int _PROTOTYPE(check_inode, (inode_t inode, super_t super)); -static int _PROTOTYPE(was_blk_special, (inode_t inode)); -static int _PROTOTYPE(check_blk_number, (blockn_t num, super_t super)); -static void _PROTOTYPE(cw_inode_block, (char *buf, inodesn_t ninodes, - int version)); -static void _PROTOTYPE(proc_ind, (dzmap_t dzmap, size_t curr_ind, - char *buf, super_t super)); -static void _PROTOTYPE(cw_dir_block, (char *buf)); -static void _PROTOTYPE(dzmap_add_inode, (dzmap_t dzmap, inode_t inode, - super_t super)); -static void _PROTOTYPE(dz_update, (dzmap_t dzmap, blockn_t blknum, - int new_indnum, int new_ztype, super_t super)); -static class_t _PROTOTYPE(ztype_class, (int ztype)); - -static unsigned int _PROTOTYPE(two_bytes, (char buf[2])); -static long _PROTOTYPE(four_bytes, (char buf[4])); - -static void _PROTOTYPE(fail, (char *string)); -static void _PROTOTYPE(usage, (char *arg0)); - - -int main(argc, argv) -int argc; -char *argv[]; -{ - super_t super; - dzmap_t dzmap; - - parse_args_init_io(argc, argv); - rw_boot(); - rw_init_super(&super); - init_dzmap(&dzmap, super.dzmap_size); - rw_ibmap(super); - rw_zbmap(super); - p1_rw_inodes(dzmap, super); - - rd_indirects(dzmap, super, 3, In_use_zone); - rd_indirects(dzmap, super, 2, In_use_zone); - rd_indirects(dzmap, super, 1, In_use_zone); - if (verbose_flag) putc('\n', stderr); - - print_stat(dzmap, super); - rw_data_zones(dzmap, super); - return 0; -} - - -static void parse_args_init_io(argc, argv) -int argc; -char *argv[]; -{ - char *str; - struct stat buf; - ino_t src_ino; - int i; - - debug_flag = 0; - verbose_flag = 0; - test_flag = 0; - - for (i = 1; i < argc; i++) { - str = argv[i]; - if (*str != '-') break; - switch (*++str) { - case 'v': verbose_flag = 1; break; - case 'd': - debug_flag = 1; - verbose_flag = 1; - break; - case 't': test_flag = 1; break; - default: usage(argv[0]); - } - } - if ((argc - i == 0 && isatty(0)) || (argc - i) > 2) usage(argv[0]); - - if (argc - i > 0) { - (void) close(0); - if (open(argv[i], O_RDONLY) != 0) { - fprintf(stderr, "Can't open input file %s", argv[i]); - fail(""); - } - } - if (isatty(1) || argc - i == 2) { - if (argc - i < 2) - test_flag = 1; - else { - i++; - (void) close(1); - (void) fstat(0, &buf); - src_ino = buf.st_ino; - if (stat(argv[i], &buf) == 0 && src_ino == buf.st_ino) { - /* Src and dest are the same */ - if (open(argv[i], O_WRONLY) != 1) { - fprintf(stderr, "Can't open output file %s", argv[i]); - fail(""); - } - } else if (creat(argv[i], 0644) != 1) { - fprintf(stderr, "Can't creat output file %s", argv[i]); - fail(""); - } - } - } -} - - -static void rw_boot() -{ - char buf[BLOCK_SIZE]; - - if (read_block(buf, BOOT_BLOCK_OFF) != BLOCK_SIZE) - fail("Can't read bootblock"); - write_block(buf); -} - - -static void rw_init_super(sp) -super_t *sp; -{ - char ibuf[BLOCK_SIZE], obuf[BLOCK_SIZE]; - - if (read_block(ibuf, SUPER_BLOCK_OFF) != BLOCK_SIZE) - fail("Can't read superblock"); - - init_super(sp, ibuf); - - memcpy(obuf, ibuf, (size_t) BLOCK_SIZE); /* preserve 'unused' data */ - (void) convcpy(obuf, ibuf, super_format); - - write_block(obuf); -} - - -static void init_dzmap(dzmap_ptr, dzmap_size) -dzmap_t *dzmap_ptr; -size_t dzmap_size; -{ - if ((*dzmap_ptr = (dzmap_t) malloc(dzmap_size)) == (dzmap_t) NULL) - fail("Not enough space for data zone map"); - memset(*dzmap_ptr, '\0', (size_t) dzmap_size); -} - - -static void rw_ibmap(super) -super_t super; -{ - char ibuf[BLOCK_SIZE], obuf[BLOCK_SIZE]; - blockn_t i; - - for (i = 0; i < super.imap_blocks; i++) { - if (read_block(ibuf, super.first_imap_block + i) != BLOCK_SIZE) - fail("Can't read inode bit map"); - conv2_blkcpy(obuf, ibuf); - write_block(obuf); - } -} - - -static void rw_zbmap(super) -super_t super; -{ - char ibuf[BLOCK_SIZE], obuf[BLOCK_SIZE]; - blockn_t i; - - for (i = 0; i < super.zmap_blocks; i++) { - if (read_block(ibuf, super.first_zmap_block + i) != BLOCK_SIZE) - fail("Can't read zone bit map"); - conv2_blkcpy(obuf, ibuf); - write_block(obuf); - } -} - - -static void p1_rw_inodes(dzmap, super) -dzmap_t dzmap; -super_t super; -{ - char buf[BLOCK_SIZE], *buf_ptr; - inodesn_t i, num_inodes; - blockn_t next_block; - inode_t inode; - - - next_block = super.first_inode_block; - - for (i = 1; i <= super.ninodes; i++) { - if ((i - 1) % super.inodes_per_block == 0) { - if (read_block(buf, next_block) != BLOCK_SIZE) - fail("read failed in inode block"); - buf_ptr = buf; - next_block++; - num_inodes = super.ninodes + 1 - i; - if (num_inodes > super.inodes_per_block) - num_inodes = super.inodes_per_block; - cw_inode_block(buf, num_inodes, super.version); - } - get_inode(&inode, buf_ptr, super.version); - dzmap_add_inode(dzmap, inode, super); - buf_ptr += inode_size(super.version); - } -} - - -static void print_stat(dzmap, super) -dzmap_t dzmap; -super_t super; -{ - size_t i; - register unsigned char dz; - int both_conflict = 0, ind_conflict = 0, type_conflict = 0, unreferenced = 0; - int not_in_use = 0; - - if (!verbose_flag) return; - - for (i = 0; i < super.dzmap_size; i++) { - dz = dzmap[i]; - if (dz & IND_CONFLICT_BIT && dz & TYPE_CONFLICT_BIT) - both_conflict++; - else if (dz & IND_CONFLICT_BIT) - ind_conflict++; - else if (dz & TYPE_CONFLICT_BIT) - type_conflict++; - - if (dz == 0) unreferenced++; - if (ztype_class(dz & T_MASK) < In_use_zone) not_in_use++; - - } - if (debug_flag) { - fprintf(stderr, "%5d zone blocks with conflicting indir.\n", - ind_conflict); - fprintf(stderr, "%5d zone blocks with conflicting types.\n", - type_conflict); - fprintf(stderr, "%5d zone blocks with conflicting types and indir.\n", - both_conflict); - fprintf(stderr, "%5d zone blocks never referenced.\n", unreferenced); - } - fprintf(stderr, "%5d zone blocks not in use.\n", not_in_use); - putc('\n', stderr); -} - - -static void rd_indirects(dzmap, super, ind, required_class) -dzmap_t dzmap; -super_t super; -int ind; -class_t required_class; -{ - size_t i; - int ind_cnt; - off_t dz_offset; - char buf[BLOCK_SIZE]; - - dz_offset = super.firstdatazone; - ind_cnt = 0; - for (i = 0; i < super.dzmap_size; i++) { - if (ztype_class(dzmap[i] & T_MASK) != required_class || - (dzmap[i] & INDIRECT_MASK) != ind || - (dzmap[i] & IND_PROCESSED_BIT)) - continue; - - ind_cnt++; - if (read_block(buf, dz_offset + i) != BLOCK_SIZE) { - fprintf(stderr, "Can't read %s block", ind_str[ind]); - fail(""); - } - proc_ind(dzmap, i, buf, super); - } - if ((verbose_flag && ind_cnt > 0) || debug_flag) - fprintf(stderr, "%5d %s zone blocks.\n", ind_cnt, ind_str[ind]); -} - - -static void rw_data_zones(dzmap, super) -dzmap_t dzmap; -super_t super; -{ - char ibuf[BLOCK_SIZE], obuf[BLOCK_SIZE]; - size_t i; - int ztype, ind, last_read; - off_t dz_offset; - - dz_offset = super.firstdatazone; - for (i = 0; i < super.dzmap_size; i++) { - last_read = read_block(ibuf, dz_offset + i); - if (last_read != BLOCK_SIZE) break; - - ind = dzmap[i] & INDIRECT_MASK; - if (ind == 0) { - ztype = dzmap[i] & T_MASK; - if (ztype == T_DIR) - cw_dir_block(ibuf); - else - write_block(ibuf); - } else { - if (super.version == 1) - conv2_blkcpy(obuf, ibuf); - else - conv4_blkcpy(obuf, ibuf); - write_block(obuf); - } - if (verbose_flag && i && i % 1024 == 0) { - fprintf(stderr, "."); - fflush(stderr); - } - } - if (verbose_flag && i > 1024) putc('\n', stderr); - - if (last_read != BLOCK_SIZE) for (; i < super.dzmap_size; i++) - if (ztype_class(dzmap[i] & T_MASK) == In_use_zone) - fail("Can't read data zone"); -} - - -static int read_block(buf, offset) -char *buf; -blockn_t offset; -{ - static blockn_t curr_offset = 0; - int bytes; - - if (offset != curr_offset) { - if (lseek(0, (off_t) offset * BLOCK_SIZE, 0) == -1) - fail("lseek failed on input file"); - curr_offset = offset; - } - bytes = read(0, buf, BLOCK_SIZE); - if (bytes < 0) fail("read failed on input file"); - - curr_offset += bytes; - - return bytes; -} - - -static void write_block(buf) -char *buf; -{ - if (test_flag) return; - - if (write(1, buf, BLOCK_SIZE) != BLOCK_SIZE) - fail("write failed on output file"); -} - - -static int convcpy(dst, src, format) -char *dst; -char *src; -int *format; -{ - char *old_src = src; - register char tmp; - int i; - - for (i = 0; format[i] > 0; i++) { - switch (format[i]) { - case 1: *dst++ = *src++; break; - case 2: - tmp = *src++; - *dst++ = *src++; - *dst++ = tmp; - break; - case 4: - tmp = src[0]; - dst[0] = src[3]; - dst[3] = tmp; - tmp = src[1]; - dst[1] = src[2]; - dst[2] = tmp; - src += 4; - dst += 4; - break; - default: - fail("wrong format array for convcpy"); - } - } - return(src - old_src); -} - - -static void conv2_blkcpy(dst, src) -char *dst; -char *src; -{ - int i; - register char tmp; - - for (i = 0; i < BLOCK_SIZE; i += 2) { - tmp = *src++; - *dst++ = *src++; - *dst++ = tmp; - } -} - - -static void conv4_blkcpy(dst, src) -char *dst; -char *src; -{ - int i; - register char tmp; - - for (i = 0; i < BLOCK_SIZE; i += 4) { - tmp = src[0]; - dst[0] = src[3]; - dst[3] = tmp; - - tmp = src[1]; - dst[1] = src[2]; - dst[2] = tmp; - - src += 4; - dst += 4; - } -} - - -static void conv2cpy(dst, src) -char *dst; -char *src; -{ - register char tmp; - tmp = *src++; - *dst++ = *src++; - *dst++ = tmp; -} - - -static int inode_size(version) -int version; -{ - return(version == 1) ? V1_INODE_SIZE : V2_INODE_SIZE; -} - - -static void init_super(sp, buf) -super_t *sp; -char *buf; -{ - int magic; - long imapblks, zmapblks; - - big_endian_fs = 0; /* guess the file system is little endian */ - magic = two_bytes(buf + MAGIC_OFFSET); - - if (magic != V1_MAGIC && magic != V2_MAGIC) { - big_endian_fs = 1; - magic = two_bytes(buf + MAGIC_OFFSET); - } - switch (magic) { - case V1_MAGIC: sp->version = 1; break; - case V2_MAGIC: sp->version = 2; break; - default: fail("Not a Minix file system"); -} - - if (verbose_flag) fprintf(stderr, "\nVersion = V%d, %s endian.\n", - sp->version, big_endian_fs ? "big" : "little"); - - sp->ninodes = two_bytes(buf + NINODES_OFFSET); - imapblks = two_bytes(buf + IMAP_BLOCKS_OFFSET); - sp->imap_blocks = imapblks; - zmapblks = two_bytes(buf + ZMAP_BLOCKS_OFFSET); - sp->zmap_blocks = zmapblks; - sp->firstdatazone = two_bytes(buf + FIRSTDATAZONE_OFFSET); - sp->log_zone_size = two_bytes(buf + LOG_ZONE_SIZE_OFFSET); - - if (sp->version == 1) - sp->zones = two_bytes(buf + V1_ZONES_OFFSET); - else - sp->zones = four_bytes(buf + V2_ZONES_OFFSET); - - sp->inodes_per_block = BLOCK_SIZE / inode_size(sp->version); - - if (imapblks < 0 || zmapblks < 0 || sp->ninodes < 1 || sp->zones < 1) - fail("Bad superblock"); - - - if (sp->log_zone_size != 0) - fail("Can't swap file systems with different zone and block sizes"); - - sp->first_imap_block = SUPER_BLOCK_OFF + 1; - sp->first_zmap_block = sp->first_imap_block + sp->imap_blocks; - sp->first_inode_block = sp->first_zmap_block + sp->zmap_blocks; - - sp->dzmap_size = sp->zones - sp->firstdatazone; - if (verbose_flag) { - fprintf(stderr, "nzones = %ld, ", sp->zones); - fprintf(stderr, "ninodes = %u, ", sp->ninodes); - fprintf(stderr, "first data zone = %ld.\n\n", sp->firstdatazone); - } -} - - -static void get_inode(ip, buf, version) -inode_t *ip; -char *buf; -int version; -{ - int i; - int mode; - - if (version == 1) { - mode = two_bytes(buf + INODE1_MODE_OFF); - ip->size = four_bytes(buf + INODE1_SIZE_OFF); - ip->ind1 = two_bytes(buf + INODE1_IND1_OFF); - ip->ind2 = two_bytes(buf + INODE1_IND2_OFF); - ip->ind3 = 0; - for (i = 0; i < NR_DIRECT_ZONES; i++) - ip->direct[i] = two_bytes(buf + INODE1_DIRECT_OFF + 2 * i); - } else { - mode = two_bytes(buf + INODE2_MODE_OFF); - ip->size = four_bytes(buf + INODE2_SIZE_OFF); - ip->ind1 = four_bytes(buf + INODE2_IND1_OFF); - ip->ind2 = four_bytes(buf + INODE2_IND2_OFF); - ip->ind3 = four_bytes(buf + INODE2_IND3_OFF); - for (i = 0; i < NR_DIRECT_ZONES; i++) - ip->direct[i] = four_bytes(buf + INODE2_DIRECT_OFF + 4 * i); - } - - if (mode == 0) { - if (ip->size % DIR_ENTRY_SIZE == 0) - ip->ztype = T_MAYBE_OLD_DIR; - else - ip->ztype = T_OLD_NON_DIR; - if (was_blk_special(*ip)) ip->size = 0; - } else { - mode = mode & INODE_MODE_MASK; - if (mode == INODE_BLK_SPECIAL_MODE || mode == INODE_CHR_SPECIAL_MODE) - ip->size = 0; /* prevent the use of the block numbers. */ - ip->ztype = (mode == INODE_DIR_MODE) ? T_DIR : T_NON_DIR; - } -} - - -static int check_inode(inode, super) -inode_t inode; -super_t super; -{ - int i; - - for (i = 0; i < NR_DIRECT_ZONES; i++) - if (!check_blk_number(inode.direct[i], super)) return 0; - - return(check_blk_number(inode.ind1, super) && - check_blk_number(inode.ind2, super) && - check_blk_number(inode.ind3, super)); -} - - -static int check_blk_number(num, super) -blockn_t num; -super_t super; -{ - if (num == 0 || (num >= super.firstdatazone && num < super.zones)) - return 1; - - fprintf(stderr, "warning bad block number %ld in inode.\n", num); - return 0; -} - - -static int was_blk_special(inode) -inode_t inode; -{ - int i, result; - blockn_t block_size; - - if (inode.size % BLOCK_SIZE || inode.ind1) return 0; - block_size = inode.size / BLOCK_SIZE; - - for (i = NR_DIRECT_ZONES - 1; i >= 0; i--) - if (inode.direct[i] != 0) break; - - result = (i < 1 && block_size > i + 1); - - if (debug_flag && result) { - fprintf(stderr, "old block special file detected (slot = %d).\n", i); - } - return result; -} - - -static void cw_inode_block(buf, ninodes, version) -char *buf; -inodesn_t ninodes; -int version; -{ - char output_buf[BLOCK_SIZE]; - char *src, *dst; - inodesn_t i; - int cnt, free_bytes; - int *format; - - src = buf; - dst = output_buf; - - format = (version == 1) ? inode1_format : inode2_format; - for (i = 0; i < ninodes; i++) { - cnt = convcpy(dst, src, format); - src += cnt; - dst += cnt; - } - - assert(cnt == inode_size(version)); - - free_bytes = BLOCK_SIZE - (src - buf); - assert(free_bytes >= 0); - if (verbose_flag && free_bytes > 0) { - /* There is a small change that the last free inode has no - * matching bit in the last inode bit map block: e.g. if - * sp->ninodes == 8191. */ - fprintf(stderr, "%5d bytes (%d inodes) free in last inode block.\n", - free_bytes, free_bytes / inode_size(version)); - memcpy(dst, src, (size_t) free_bytes); - } - write_block(output_buf); -} - - -static void proc_ind(dzmap, curr_ind, buf, super) -dzmap_t dzmap; -size_t curr_ind; -char *buf; -super_t super; -{ - int indnum, i, ztype; - int word_size; /* size of zone block number in ind. block in - * bytes */ - unsigned char dz, tmp_dz; - blockn_t blk, ind_blk; - int bad_range = 0, hidden_zero = 0, zero_flag = 0, expired = 0; - size_t blk_index; - - dz = dzmap[curr_ind]; - indnum = dz & INDIRECT_MASK; - ztype = dz & T_MASK; - ind_blk = curr_ind + super.firstdatazone; - - word_size = (super.version == 1) ? 2 : 4; - assert(indnum > 0); - - for (i = 0; i < BLOCK_SIZE; i += word_size) { - if (word_size == 2) - blk = two_bytes(buf + i); - else - blk = four_bytes(buf + i); - - if (blk == 0) - zero_flag = 1; - else if (blk < super.firstdatazone || blk >= super.zones) - bad_range = 1; - else { - if (zero_flag) hidden_zero = 1; - blk_index = blk - super.firstdatazone; - tmp_dz = dzmap[blk_index]; - if (ztype_class(tmp_dz & T_MASK) == In_use_zone) expired = 1; - } - - } - - if (ztype_class(ztype) == In_use_zone) { - if (bad_range) { - fprintf(stderr, "%s zone block contains ", ind_str[indnum]); - fail("illegal value"); - } - if ((ztype == T_DIR || indnum > 1) && hidden_zero) { - fprintf(stderr, "WARNING: %s zone block %ld contains ", - ind_str[indnum], ind_blk); - fprintf(stderr, "unexpected zero block numbers\n"); - } - } else { - if (expired) { - dzmap[curr_ind] &= ~(INDIRECT_MASK & IND_CONFLICT_BIT); - return; - } - - /* Not yet implemented. :-( if (bad_range || (indnum > 1 && - * hidden_zero) || equal_values(buf, super.version ) { } */ - } - - for (i = 0; i < BLOCK_SIZE; i += word_size) { - if (word_size == 2) - blk = two_bytes(buf + i); - else - blk = four_bytes(buf + i); - - if (blk == 0) continue; - blk_index = blk - super.firstdatazone; - tmp_dz = dzmap[blk_index]; - if (ztype_class(tmp_dz & T_MASK) == In_use_zone) { /* trouble */ - if ((tmp_dz & INDIRECT_MASK) == indnum - 1 && - (tmp_dz & T_MASK) == ztype) - fprintf(stderr, "WARNING: %s zone block %ld used more \ -than once\n", ind_str[indnum - 1], blk); - else { - fprintf(stderr, "Block %ld used more than ", blk); - fail("once with different types"); - } - } - dzmap[blk_index] = (dz & ~INDIRECT_MASK) | (indnum - 1); - } - dzmap[curr_ind] |= IND_PROCESSED_BIT; -} - - -static void cw_dir_block(buf) -char *buf; -{ - char output_buf[BLOCK_SIZE]; - int ino, i, old_ino_offset; - - memcpy(output_buf, buf, BLOCK_SIZE); - - for (i = 0; i < BLOCK_SIZE; i += DIR_ENTRY_SIZE) { - ino = two_bytes(buf + i); - if (ino == 0) { - old_ino_offset = i + DIR_ENTRY_SIZE - 2; - conv2cpy(output_buf + old_ino_offset, buf + old_ino_offset); - } else - conv2cpy(output_buf + i, buf + i); - } - write_block(output_buf); -} - - -static void dzmap_add_inode(dzmap, inode, super) -dzmap_t dzmap; -inode_t inode; -super_t super; -{ - int i; - - if (inode.size == 0 || !check_inode(inode, super)) return; - - for (i = 0; i < NR_DIRECT_ZONES; i++) - dz_update(dzmap, inode.direct[i], 0, inode.ztype, super); - - dz_update(dzmap, inode.ind1, 1, inode.ztype, super); - dz_update(dzmap, inode.ind2, 2, inode.ztype, super); - dz_update(dzmap, inode.ind3, 3, inode.ztype, super); -} - - -static void dz_update(dzmap, blknum, new_indnum, new_ztype, super) -dzmap_t dzmap; -blockn_t blknum; -int new_indnum; -int new_ztype; -super_t super; -{ - size_t dznum; - int old_indnum; - int old_ztype; - unsigned char *dz; - char new_dz; - - - if (blknum == 0) return; - - dznum = (size_t) (blknum - super.firstdatazone); - - dz = &dzmap[dznum]; - old_indnum = *dz & INDIRECT_MASK; - old_ztype = *dz & T_MASK; - - new_dz = new_ztype | new_indnum; - - if (ztype_class(new_ztype) > ztype_class(old_ztype)) { - *dz = new_dz; - return; - } else if (ztype_class(new_ztype) < ztype_class(old_ztype)) - return; - - /* Collision: old and new have the same class */ - - if (ztype_class(old_ztype) == In_use_zone) { /* trouble */ - if (new_indnum == old_indnum && new_ztype == old_ztype) { - fprintf(stderr, "WARNING: file system corrupt, zone block %ld \ -is used more than once.\n", blknum); - return; - } - fprintf(stderr, "ERROR: file system corrupt, zone block %ld is used \ -more than once.\n", blknum); - fail("Can't determine its type"); - } - assert(ztype_class(old_ztype) == Old_zone); - - - if (new_indnum != old_indnum) { - *dz |= IND_CONFLICT_BIT; - if (new_indnum > old_indnum) { - *dz &= ~INDIRECT_MASK; - *dz |= new_indnum; - } - } - if (new_ztype == T_MAYBE_OLD_DIR || old_ztype == T_MAYBE_OLD_DIR) { - *dz |= TYPE_CONFLICT_BIT; - *dz &= ~T_MASK; - *dz |= T_MAYBE_OLD_DIR; - } -} - - -static class_t ztype_class(ztype) -int ztype; -{ - class_t class; - - if (ztype == T_MAYBE_OLD_DIR || ztype == T_OLD_NON_DIR) - class = Old_zone; - else if (ztype == T_DIR || ztype == T_NON_DIR) - class = In_use_zone; - else - class = Unused_zone; - - return class; -} - - -static void fail(str) -char *str; -{ - fprintf(stderr, "%s\n", str); - exit(1); -} - - -static unsigned int two_bytes(buf) -char buf[2]; -{ - unsigned char *ubuf = (unsigned char *) buf; - - if (big_endian_fs) - return(ubuf[0] << 8) | ubuf[1]; - else - return(ubuf[1] << 8) | ubuf[0]; -} - - -static long four_bytes(buf) -char buf[4]; -{ - unsigned char *ubuf = (unsigned char *) buf; - register int r1, r2; - - if (big_endian_fs) { - r1 = (ubuf[0] << 8) | ubuf[1]; - r2 = (ubuf[2] << 8) | ubuf[3]; - } else { - r2 = (ubuf[1] << 8) | ubuf[0]; - r1 = (ubuf[3] << 8) | ubuf[2]; - } - return((long) r1 << 16) | r2; -} - - -static void usage(arg0) -char *arg0; -{ - fprintf(stderr, "usage: %s [-v] srcfs [destfs]\n", arg0); - exit(2); -}