/* * File system mapping */ #include #include #include #include #include #include #include #include #include #include #include static dev_t root_dev; static long root_blksize; static long root_fblksize; static long root_blocks; static long root_bfree; void init_root_dev(void) { struct stat sbuf; struct statvfs vfsbuf; int fd; int ret; ret = stat("/", &sbuf); if (ret != 0) { fprintf(stderr, "Failed to stat /\n"); exit(1); } root_dev = sbuf.st_dev; fd = open("/", O_RDONLY); if (fd == -1) { fprintf(stderr, "Failed to read /\n"); exit(1); } if (fstatvfs(fd, &vfsbuf) < 0) { fprintf(stderr, "Failed to statfs /\n"); exit(1); } root_blksize = vfsbuf.f_bsize; root_fblksize = vfsbuf.f_frsize; root_blocks = vfsbuf.f_blocks; root_bfree = vfsbuf.f_bfree; close(fd); /* printf("/ : %lu data %lu free KB\n", root_blocks * (root_fblksize / 1024), root_bfree * (root_fblksize / 1024)); */ printf(" \n", root_blocks * (root_fblksize / 1024), root_bfree * (root_fblksize / 1024), vfsbuf.f_bavail * (root_blksize / 1024)); } int dump_file(const char *path) { int ret, i, err = 0; int fd; long blksize; off_t filesz; long fileblks, blk; long start = -1, end = -1; long first_logical = -1; struct stat sbuf; blksize = root_blksize; fd = open(path, O_RDONLY); if (fd == -1) { return(1); } ret = fstat(fd, &sbuf); if (ret < 0) { close(fd); return(1); } printf(" \n", path, sbuf.st_size); if (sbuf.st_dev != root_dev) { close(fd); printf(" \n"); return(1); } filesz = sbuf.st_size; fileblks = (filesz + root_blksize - 1) / root_blksize; err = 0; for (blk = 0; blk < fileblks; blk++) { long devblk = blk; if (ioctl(fd, FIBMAP, &devblk) == -1) { if (errno == -EPERM) { close(fd); return(1); } err++; } else { if (start == -1) { start = devblk; end = devblk; first_logical = blk; } else { if (devblk == end + 1) { end++; } else { printf(" \n", first_logical, end - start + 1, start, end); /* printf("%ld-%ld: %ld-%ld (%ld)\n", first_logical, first_logical + (end - start), start, end, end - start + 1); */ start = devblk; end = devblk; first_logical = blk; } } } } if (start != -1) { /* printf("%ld-%ld: %ld-%ld (%ld)\n", first_logical, first_logical + (end - start), start, end, end - start + 1); */ printf(" \n", first_logical, end - start + 1, start, end); } close(fd); printf(" \n"); return(err); } void usage(const char *name) { fprintf(stderr, "Usage: %s file(s)...\n", name); fprintf(stderr, " or %s --list filelist\n", name); } #define IS_BLANK(p) ((*(p) == ' ') || (*(p) == '\t') || \ (*(p) == '\n') || (*(p) == '\r')) int main(int argc, char **argv) { int i; int err = 0; if (argc < 2) { usage(argv[0]); exit(2); } if (strcmp(argv[1], "--list") == 0) { FILE *f; char *filename = argv[2], *cur; char filepath[4096 + 201]; if (filename == NULL) { usage(argv[0]); exit(2); } if (strcmp(filename, "-")) { f = fopen(filename, "r"); } else { f = fdopen(0, "r"); } if (f == NULL) { fprintf(stderr, "Unable to read %s\n", filename); exit(1); } printf("\n"); init_root_dev(); while (fgets(filepath, 4096 + 200, f)) { filename = filepath; while (IS_BLANK(filename)) filename++; if (*filename == 0) continue; cur = filename; while ((*cur != 0) && (!IS_BLANK(cur))) cur++; *cur = 0; err += dump_file(filename); } printf("\n"); fclose(f); } else { printf("\n"); init_root_dev(); for (i = 1;i < argc;i++) { err += dump_file(argv[i]); } printf("\n"); } exit(err ? 1 : 0); }