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);
}
Exemple #2
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;
}