int main(int argc, char *argv[]) { int ch, oflags; char fname[FILENAME_MAX]; char *endp; quiet = 0; mode = ' '; while ((ch = getopt(argc, argv, "irwlpdqfh:")) != -1) { switch (ch) { case 'q': quiet = 1; break; case 'f': /* Legacy. Do nothing. */ break; case 'i': mode = 'i'; break; case 'h': volhdr_size = strtol(optarg, &endp, 0); if (*endp != '\0' || errno != 0) errx(1, "incorrect volume header size: %s", optarg); break; case 'r': mode = 'r'; break; case 'w': mode = 'w'; break; case 'l': mode = 'l'; break; case 'd': mode = 'd'; break; case 'p': mode = 'p'; break; default: usage(); } } argc -= optind; argv += optind; if (mode == 'r' || mode == 'w' || mode == 'l') { if (argc != 3) usage(); vfilename = argv[0]; ufilename = argv[1]; argc -= 2; argv += 2; } else if (mode == 'd') { if (argc != 2) usage(); vfilename = argv[0]; argc--; argv++; } else if (mode == 'p') { if (argc != 5) usage(); partno = strtol(argv[0], &endp, 0); if (*endp != '\0' || errno != 0 || partno < 0 || partno > SGI_SIZE_VOLDIR) errx(1, "invalid partition number: %s", argv[0]); partfirst = strtol(argv[1], &endp, 0); if (*endp != '\0' || errno != 0) errx(1, "invalid partition start: %s", argv[1]); partblocks = strtol(argv[2], &endp, 0); if (*endp != '\0' || errno != 0) errx(1, "invalid partition size: %s", argv[2]); parttype = strtol(argv[3], &endp, 0); if (*endp != '\0' || errno != 0) errx(1, "invalid partition type: %s", argv[3]); argc -= 4; argv += 4; } if (argc != 1) usage(); oflags = ((mode == 'i' || mode == 'w' || mode == 'l' || mode == 'd' || mode == 'p') ? O_RDWR : O_RDONLY); /* Open raw device. */ if ((fd = open(argv[0], oflags)) < 0) { snprintf(fname, sizeof(fname), "/dev/r%s%c", argv[0], 'a' + getrawpartition()); if ((fd = open(fname, oflags)) < 0) err(1, "open %s", fname); } /* Get disklabel for device. */ if (ioctl(fd, DIOCGDINFO, &lbl) == -1) err(1, "ioctl DIOCGDINFO"); /* Allocate a buffer that matches the device sector size. */ bufsize = lbl.d_secsize; if (bufsize < sizeof(struct sgilabel)) errx(1, "sector size is smaller than SGI volume header!\n"); if ((buf = malloc(bufsize)) == NULL) err(1, "failed to allocate buffer"); /* Read SGI volume header. */ if (read(fd, buf, bufsize) != bufsize) err(1, "read volhdr"); volhdr = (struct sgilabel *)buf; if (mode == 'i') { init_volhdr(); exit(0); } if (betoh32(volhdr->magic) != SGILABEL_MAGIC) errx(2, "no Volume Header found, magic=%x. Use -i first.", betoh32(volhdr->magic)); if (mode == 'r') read_file(); else if (mode == 'w') write_file(); else if (mode == 'l') link_file(); else if (mode == 'd') delete_file(); else if (mode == 'p') modify_partition(); else if (!quiet) display_vol(); exit (0); }
int main(int argc, char *argv[]) { #define RESET_OPTS() opt_i = opt_m = opt_r = opt_w = opt_d = opt_p = 0 int ch; while ((ch = getopt(argc, argv, "qfih:rwdmp?")) != -1) { switch (ch) { /* -i, -r, -w, -d, -m and -p override each other */ /* -q implies -f */ case 'q': ++opt_q; ++opt_f; break; case 'f': ++opt_f; break; case 'i': RESET_OPTS(); ++opt_i; break; case 'h': volhdr_size = atoi(optarg); break; case 'r': RESET_OPTS(); ++opt_r; break; case 'w': RESET_OPTS(); ++opt_w; break; case 'd': RESET_OPTS(); ++opt_d; break; case 'm': RESET_OPTS(); ++opt_m; break; case 'p': RESET_OPTS(); ++opt_p; partno = atoi(argv[0]); partfirst = atoi(argv[1]); partblocks = atoi(argv[2]); parttype = atoi(argv[3]); break; case '?': default: usage(); } } argc -= optind; argv += optind; if (opt_m || opt_r || opt_w) { if (argc != 3) usage(); vfilename = argv[0]; ufilename = argv[1]; argc -= 2; argv += 2; } if (opt_d) { if (argc != 2) usage(); vfilename = argv[0]; argc--; argv++; } if (opt_p) { if (argc != 5) usage(); partno = atoi(argv[0]); partfirst = atoi(argv[1]); partblocks = atoi(argv[2]); parttype = atoi(argv[3]); argc -= 4; argv += 4; } if (argc != 1) usage(); fd = open(argv[0], (opt_i | opt_m | opt_w | opt_d | opt_p) ? O_RDWR : O_RDONLY); if (fd < 0) { #if HAVE_NBTOOL_CONFIG_H perror("File open"); exit(1); #else sprintf((char *)buf, "/dev/r%s%c", argv[0], 'a' + getrawpartition()); fd = open((char *)buf, (opt_i | opt_w | opt_d | opt_p) ? O_RDWR : O_RDONLY); if (fd < 0) { printf("Error opening device %s: %s\n", argv[0], strerror(errno)); exit(1); } #endif } if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { perror("read volhdr"); exit(1); } #if HAVE_NBTOOL_CONFIG_H if (fstat(fd, &st) < 0) { perror("stat error"); exit(1); } if (!S_ISREG(st.st_mode)) { printf("Must be regular file\n"); exit(1); } if (st.st_size % SGI_BOOT_BLOCK_BLOCKSIZE) { printf("Size must be multiple of %d\n", SGI_BOOT_BLOCK_BLOCKSIZE); exit(1); } if (st.st_size < (SGIVOL_NBTOOL_NSECS * SGIVOL_NBTOOL_NTRACKS)) { printf("Minimum size of %d required\n", SGIVOL_NBTOOL_NSECS * SGIVOL_NBTOOL_NTRACKS); exit(1); } #else if (ioctl(fd, DIOCGDINFO, &lbl) < 0) { perror("DIOCGDINFO"); exit(1); } #endif volhdr = (struct sgi_boot_block *) buf; if (opt_i) { init_volhdr(); exit(0); } if (be32toh(volhdr->magic) != SGI_BOOT_BLOCK_MAGIC) { printf("No Volume Header found, magic=%x. Use -i first.\n", be32toh(volhdr->magic)); exit(1); } if (opt_r) { read_file(); exit(0); } if (opt_w) { write_file(); exit(0); } if (opt_d) { delete_file(); exit(0); } if (opt_m) { move_file(); exit(0); } if (opt_p) { modify_partition(); exit(0); } if (!opt_q) display_vol(); return 0; }