示例#1
0
文件: md.c 项目: ryo/netbsd-src
/*
 * hook called after upgrade() or install() has finished setting
 * up the target disk but immediately before the user is given the
 * ``disks are now set up'' message.
 *
 * On the ews4800mips, we use this opportunity to install the boot blocks.
 */
int
md_post_newfs(void)
{
	int flags;

	flags = RUN_DISPLAY | RUN_FATAL;
	cp_to_target("/usr/mdec/boot", "/stand/boot");
	run_program(flags, "/usr/sbin/installboot /dev/r%s%c %s",
	    pm->diskdev, 'a' + getrawpartition(),
	    "/usr/mdec/bootxx_bfs");

	return 0;
}
示例#2
0
static int
__opendisk(const char *path, int flags, char *buf, size_t buflen, int iscooked,
	int (*ofn)(const char *, int, ...))
{
#ifndef __minix
	int f, rawpart;
#else
	int f;
#endif 

	if (buf == NULL) {
		errno = EFAULT;
		return (-1);
	}
	snprintf(buf, buflen, "%s", path);

	if ((flags & O_CREAT) != 0) {
		errno = EINVAL;
		return (-1);
	}

#ifndef __minix
	rawpart = getrawpartition();
	if (rawpart < 0)
		return (-1);	/* sysctl(3) in getrawpartition sets errno */
#endif

	f = ofn(buf, flags, 0);
	if (f != -1 || errno != ENOENT)
		return (f);

#ifndef __minix
	snprintf(buf, buflen, "%s%c", path, 'a' + rawpart);
	f = ofn(buf, flags, 0);
	if (f != -1 || errno != ENOENT)
		return (f);

	if (strchr(path, '/') != NULL)
		return (-1);

	snprintf(buf, buflen, "%s%s%s", _PATH_DEV, iscooked ? "" : "r", path);
	f = ofn(buf, flags, 0);
	if (f != -1 || errno != ENOENT)
		return (f);

	snprintf(buf, buflen, "%s%s%s%c", _PATH_DEV, iscooked ? "" : "r", path,
	    'a' + rawpart);
	f = ofn(buf, flags, 0);
#endif
	return (f);
}
示例#3
0
文件: label.c 项目: ryo/netbsd-src
static void
set_label_texts(menudesc *menu, void *arg)
{
	struct ptn_menu_info *pi = arg;
	menu_ent *m;
	int ptn, show_unused_ptn;
	int rawptn = getrawpartition();
	int maxpart = getmaxpartitions();

	msg_display(MSG_fspart);
	msg_table_add(MSG_fspart_header, multname, multname, multname);

	for (show_unused_ptn = 0, ptn = 0; ptn < maxpart; ptn++) {
		m = &menu->opts[ptn];
		m->opt_menu = OPT_NOMENU;
		m->opt_name = NULL;
		m->opt_action = edit_ptn;
		if (ptn == rawptn
#ifdef PART_BOOT
		    || ptn == PART_BOOT
#endif
		    || ptn == PART_C) {
			m->opt_flags = OPT_IGNORE;
		} else {
			m->opt_flags = 0;
			if (pm->bsdlabel[ptn].pi_fstype == FS_UNUSED)
				continue;
		}
		show_unused_ptn = ptn + 2;
	}

	if (!(pi->flags & PIF_SHOW_UNUSED) && ptn > show_unused_ptn) {
		ptn = show_unused_ptn;
		m = &menu->opts[ptn];
		m->opt_name = MSG_show_all_unused_partitions;
		m->opt_action = show_all_unused;
		ptn++;
	}

	m = &menu->opts[ptn];
	m->opt_menu = MENU_sizechoice; 
	m->opt_flags = OPT_SUB; 
	m->opt_action = NULL;
	m->opt_name = MSG_askunits;

	menu->numopts = ptn + 1;
}
示例#4
0
文件: md.c 项目: ryo/netbsd-src
int
md_get_info(void)
{
	struct disklabel disklabel;
	int fd;
	char dev_name[100];

	snprintf(dev_name, 100, "/dev/r%s%c", pm->diskdev, 'a' + getrawpartition());

	fd = open(dev_name, O_RDONLY, 0);
	if (fd < 0) {
		endwin();
		fprintf (stderr, "Can't open %s\n", dev_name);
		exit(1);
	}
	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
		endwin();
		fprintf (stderr, "Can't read disklabel on %s.\n", dev_name);
		close(fd);
		exit(1);
	}
	close(fd);

	pm->dlcyl = disklabel.d_ncylinders;
	pm->dlhead = disklabel.d_ntracks;
	pm->dlsec = disklabel.d_nsectors;
	pm->sectorsize = disklabel.d_secsize;
	pm->dlcylsize = disklabel.d_secpercyl;

	/*
	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
	 * and secperunit,  just in case the disk is already labelled.
	 * (If our new label's RAW_PART size ends up smaller than the
	 * in-core RAW_PART size  value, updating the label will fail.)
	 */
	pm->dlsize = pm->dlcyl * pm->dlhead * pm->dlsec;
	if (disklabel.d_secperunit > pm->dlsize)
		pm->dlsize = disklabel.d_secperunit;

	return 1;
}
示例#5
0
文件: md.c 项目: enukane/netbsd-src
int
md_get_info(void)
{
	struct disklabel disklabel;
	int fd;
	char dev_name[100];

	snprintf (dev_name, 100, "/dev/r%s%c", diskdev, 'a' + getrawpartition());

	fd = open (dev_name, O_RDONLY, 0);
	if (fd < 0) {
		endwin();
		fprintf (stderr, "Can't open %s\n", dev_name);
		exit(1);
	}
	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
		endwin();
		fprintf (stderr, "Can't read disklabel on %s.\n", dev_name);
		close(fd);
		exit(1);
	}
	close(fd);

	dlcyl = disklabel.d_ncylinders;
	dlhead = disklabel.d_ntracks;
	sectorsize = disklabel.d_secsize;
	dlsize = disklabel.d_secperunit;

	/*
	 * Tru64 UNIX's disklabel is the same format as BSD disklabel,
	 * and it seems Tru64 stores incorrect geometry values in
	 * d_nsectors (sectors/track) and d_secpercyl (sectors/cylinder).
	 * d_secperunit seems always reliable so use it to get
	 * dlsec (sectors/track) and dlcylsize (sectors/cylinder) values.
	 * See PR/48697 for details.
	 */
	dlsec = dlsize / (dlhead * dlcyl);
	dlcylsize = dlsec * dlhead;

	return 1;
}
示例#6
0
文件: t_cd.c 项目: Hooman3/minix
ATF_TC_BODY(noisyeject, tc)
{
	static char fname[] = "/dev/rcd0_";
	int part, fd, arg = 0;

	RL(part = getrawpartition());
	fname[strlen(fname)-1] = 'a' + part;
	rump_init();
	/*
	 * Rump CD emulation has been fixed, so no longer a problem.
	 *
	atf_tc_expect_signal(SIGSEGV, "PR kern/47646: Broken test or "
	    "a real problem in rump or the driver");
	 */
	RL(fd = rump_sys_open(fname, O_RDWR));
	RL(rump_sys_ioctl(fd, DIOCEJECT, &arg));

	ATF_REQUIRE_EQ(rump_scsitest_err[RUMP_SCSITEST_NOISYSYNC], 0);
	RL(rump_sys_close(fd));
	// atf_tc_expect_fail("PR kern/43785");
	ATF_REQUIRE_EQ(rump_scsitest_err[RUMP_SCSITEST_NOISYSYNC], 0);
}
示例#7
0
int
opendisk(const char *path, int flags, char *buf, size_t buflen, int iscooked)
{
	int f, rawpart;

	snprintf(buf, buflen, "%s", path);

	if ((flags & O_CREAT) != 0) {
		errno = EINVAL;
		return (-1);
	}

	rawpart = getrawpartition();
	if (rawpart < 0)
		return (-1);	/* sysctl(3) in getrawpartition sets errno */

	f = open(buf, flags);
	if (f != -1 || errno != ENOENT)
		return (f);

	snprintf(buf, buflen, "%s%c", path, 'a' + rawpart);
	f = open(buf, flags);
	if (f != -1 || errno != ENOENT)
		return (f);

	if (strchr(path, '/') != NULL)
		return (-1);

	snprintf(buf, buflen, "%s%s%s", _PATH_DEV, iscooked ? "" : "r", path);
	f = open(buf, flags);
	if (f != -1 || errno != ENOENT)
		return (f);

	snprintf(buf, buflen, "%s%s%s%c", _PATH_DEV, iscooked ? "" : "r", path,
	    'a' + rawpart);
	f = open(buf, flags);
	return (f);
}
示例#8
0
int
main(int argc, char **argv)
{
	int	sd, ch, changed;
	char	name[MAXPATHLEN];
	int	force;			/* force label update */
	int	raw;			/* update on-disk label as well */
	int	verbose;		/* verbose output */
	int	write_it;		/* update in-core label if changed */

	force = 0;
	raw = 0;
	verbose = 1;
	write_it = 0;
	while ((ch = getopt(argc, argv, "fqrw")) != -1) {
		switch (ch) {
		case 'f':
			force = 1;
			break;
		case 'q':
			verbose = 0;
			break;
		case 'r':
			raw = 1;
			break;
		case 'w':
			write_it = 1;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;
	if (argc != 1)
		usage();

	rawpart = getrawpartition();
	if (rawpart < 0)
		err(EXIT_FAILURE, "getrawpartition");

	if ((sd = opendisk(argv[0], write_it ? O_RDWR : O_RDONLY, name,
	    (size_t)MAXPATHLEN, 1)) < 0) {
		perror(argv[0]);
		exit(1);
	}
	getlabel(sd);
	changed = getparts(sd, verbose);

	if (verbose) {
		putchar('\n');
		showpartitions(stdout, &label, 0);
		putchar('\n');
	}
	if (write_it) {
		if (! changed && ! force)
			printf("No change; not updating disk label.\n");
		else {
			if (verbose)
				printf("Updating in-core %sdisk label.\n",
				    raw ? "and on-disk " : "");
raw = 0; /* XXX */
			setlabel(sd, raw);
		}
	} else {
		printf("Not updating disk label.\n");
	}
	close(sd);
	return (0);
}
示例#9
0
/*
 * Try to get a disklabel for the specified device, and return mount_xxx
 * style filesystem type name for the specified partition.
 */
char *
readlabelfs(char *device, int verbose)
{
	char rpath[MAXPATHLEN];
	struct dk_diskmap dm;
	struct disklabel dk;
	char part, *type;
	struct stat sbuf;
	int fd = -1;

	/* Perform disk mapping if device is given as a DUID. */
	if (isduid(device, 0)) {
		if ((fd = open("/dev/diskmap", O_RDONLY)) != -1) {
			bzero(&dm, sizeof(struct dk_diskmap));
			strlcpy(rpath, device, sizeof(rpath));
			part = rpath[strlen(rpath) - 1];
			dm.device = rpath;
			dm.fd = fd;
			dm.flags = DM_OPENPART;
			if (ioctl(fd, DIOCMAP, &dm) == -1)
				close(fd);
			else
				goto disklabel;
		}
	}

	/* Assuming device is of the form /dev/??p, build a raw partition. */
	if (stat(device, &sbuf) < 0) {
		if (verbose)
			warn("%s", device);
		return (NULL);
	}
	switch (sbuf.st_mode & S_IFMT) {
	case S_IFCHR:
		/* Ok... already a raw device.  Hmm. */
		strlcpy(rpath, device, sizeof(rpath));

		/* Change partition name. */
		part = rpath[strlen(rpath) - 1];
		rpath[strlen(rpath) - 1] = 'a' + getrawpartition();
		break;
	case S_IFBLK:
		if (strlen(device) > sizeof(_PATH_DEV) - 1) {
			snprintf(rpath, sizeof(rpath), "%sr%s", _PATH_DEV,
			    &device[sizeof(_PATH_DEV) - 1]);
			/* Change partition name. */
			part = rpath[strlen(rpath) - 1];
			rpath[strlen(rpath) - 1] = 'a' + getrawpartition();
			break;
		}
		/* FALLTHROUGH */
	default:
		if (verbose)
			warnx("%s: not a device node", device);
		return (NULL);
	}

	/* If rpath doesn't exist, change that partition back. */
	fd = open(rpath, O_RDONLY);
	if (fd < 0) {
		if (errno == ENOENT) {
			rpath[strlen(rpath) - 1] = part;

			fd = open(rpath, O_RDONLY);
			if (fd < 0) {
				if (verbose)
					warn("%s", rpath);
				return (NULL);
			}
		} else {
			if (verbose)
				warn("%s", rpath);
			return (NULL);
		}
	}

disklabel:

	if (ioctl(fd, DIOCGDINFO, &dk) < 0) {
		if (verbose)
			warn("%s: couldn't read disklabel", rpath);
		close(fd);
		return (NULL);
	}
	close(fd);

	if (dk.d_partitions[part - 'a'].p_fstype >= FSMAXTYPES) {
		if (verbose)
			warnx("%s: bad filesystem type in label", rpath);
		return (NULL);
	}

	type = fstypesnames[dk.d_partitions[part - 'a'].p_fstype];
	return ((type[0] == '\0') ? NULL : type);
}
示例#10
0
char* DefaultDevice()
{  DeviceHandle *dh;
   char *disknames, *p, raw;
   int dev_type, sysctl_mib[2];
   size_t sysctl_len;

   raw = 'a' + getrawpartition();

   sysctl_mib[0] = CTL_HW;
   sysctl_mib[1] = HW_DISKNAMES;
   if (-1 == sysctl(sysctl_mib, 2, NULL, &sysctl_len, NULL, 0)) {
     PrintLog("Failed to get value of sysctl `hw.disknames'\n");
     return g_strdup("no_drives");
   }
   if (!(disknames = g_malloc(sysctl_len))) {
     PrintLog("Out of memory constructing scan device list\n");
     return g_strdup("no_drives");
   }
   if (-1 == sysctl(sysctl_mib, 2, disknames, &sysctl_len, NULL, 0)) {
     PrintLog("Failed to get value of sysctl `hw.disknames'\n");
     g_free(disknames);
     return g_strdup("no_drives");
   }

   dh = g_malloc(sizeof(DeviceHandle));

   for (p = strtok(disknames, " "); p; p = strtok(NULL, " "))
   {  
     if(!strncmp(p,"cd",2))
     { char buf[80];

       sprintf(buf,"/dev/r%s%c", p, raw);

       memset(dh, 0, sizeof(DeviceHandle));
       dh->fd = open(buf, O_RDONLY | O_NONBLOCK);
       dh->device = buf;

       if(dh->fd < 0)   /* device not even present */
	 continue;

       dev_type = InquireDevice(dh, 1);
       close(dh->fd);

       if(dev_type != 5)  /* not a CD/DVD ROM */
	 continue;

       g_ptr_array_add(Closure->deviceNodes, g_strdup(buf));
       sprintf(buf, "%s (/dev/r%s%c)", dh->devinfo, p, raw);
       g_ptr_array_add(Closure->deviceNames, g_strdup(buf));
     }
   }

   g_free(dh);

   if(Closure->deviceNodes->len)
     return g_strdup(g_ptr_array_index(Closure->deviceNodes, 0));
   else
   {  PrintLog(_("No CD/DVD drives found.\n"
		  "No drives will be pre-selected.\n"));

      return g_strdup("no_drives");
   }
}
示例#11
0
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);
}
示例#12
0
int
md_get_info(void)
{
	struct disklabel disklabel;
	int fd, i;
	char dev_name[100];
	struct apple_part_map_entry block;

	snprintf(dev_name, sizeof(dev_name), "/dev/r%s%c",
		diskdev, 'a' + getrawpartition());

	/*
	 * Open the disk as a raw device
	 */
	fd = open(dev_name, O_RDONLY, 0);
	if (fd < 0) {
		endwin();
		fprintf (stderr, "Can't open %s\n", dev_name);
		exit(1);
	}
	/*
	 * Try to get the default disklabel info for the device
	 */
	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
		endwin();
		fprintf (stderr, "Can't read disklabel on %s\n", dev_name);
		close(fd);
		exit(1);
	}
	/*
	 * Get the disk parameters from the disk driver.  It should have
	 *  obained them by querying the disk itself.
	 */
	blk_size = disklabel.d_secsize;
	dlcyl = disklabel.d_ncylinders;
	dlhead = disklabel.d_ntracks;
	dlsec = disklabel.d_nsectors;
	/*
	 * Just in case, initialize the structures we'll need if we
	 *  need to completely initialize the disk.
	 */
	dlsize = disklabel.d_secperunit;
	for (i=0;i<NEW_MAP_SIZE;i++) {
	   if (i > 0)
		new_map[i].pmPyPartStart = new_map[i-1].pmPyPartStart +
			new_map[i-1].pmPartBlkCnt;
	   new_map[i].pmDataCnt = new_map[i].pmPartBlkCnt;
	   if (new_map[i].pmPartBlkCnt == 0) {
		new_map[i].pmPartBlkCnt = dlsize;
		new_map[i].pmDataCnt = dlsize;
		break;
	   }
	   dlsize -= new_map[i].pmPartBlkCnt;
	}
	dlsize = disklabel.d_secperunit;
#if 0
	msg_display(MSG_dldebug, blk_size, dlcyl, dlhead, dlsec, dlsize);
	process_menu(MENU_ok, NULL);
#endif
	map.size = 0;
	/*
	 * Verify the disk has been initialized for MacOS use by checking
	 *  to see if the disk have a Boot Block
	 */
	if (lseek(fd, (off_t)0 * blk_size, SEEK_SET) < 0 ||
	    read(fd,  &block, sizeof(block)) - sizeof(block) != 0 ||
	    block.pmSig != 0x4552) {
             process_menu(MENU_nodiskmap, NULL);
        }
	else {
	   /*
	    * Scan for the Partition Map entry that describes the Partition
	    *  Map itself.  We need to know the number of blocks allocated
	    *  to it and the number currently in use.
	    */
	   for (i=0;i<MAXMAXPARTITIONS;i++) {
		lseek(fd, (off_t)(i+1) * blk_size, SEEK_SET);
		read(fd, &block, sizeof(block));
		if (stricmp("Apple_partition_map", (char *)block.pmPartType) == 0) {
		    map.size = block.pmPartBlkCnt;
		    map.in_use_cnt = block.pmMapBlkCnt;
		    map.blk = (struct apple_part_map_entry *)malloc(map.size * blk_size);
		    break;
	        }
            }
	    lseek(fd, (off_t)1 * blk_size, SEEK_SET);
	    read(fd, map.blk, map.size * blk_size);
	}
	close(fd);
	/*
	 * Setup the disktype so /etc/disktab gets proper info
	 */
	if (strncmp(diskdev, "sd", 2) == 0) {
		disktype = "SCSI";
		doessf = "sf:";
	} else
		disktype = "IDE";

	return edit_diskmap();
}
示例#13
0
/*
 * This routine is a generic rewrite of the original code found in
 * disklabel(8).
 */
int
opendev(const char *path, int oflags, int dflags, char **realpath)
{
	static char namebuf[PATH_MAX];
	struct dk_diskmap dm;
	char *slash, *prefix;
	int fd;

	/* Initial state */
	fd = -1;
	errno = ENOENT;

	if (dflags & OPENDEV_BLCK)
		prefix = "";			/* block device */
	else
		prefix = "r";			/* character device */

	if ((slash = strchr(path, '/'))) {
		strlcpy(namebuf, path, sizeof(namebuf));
		fd = open(namebuf, oflags);
	} else if (isduid(path, dflags)) {
		strlcpy(namebuf, path, sizeof(namebuf));
		if ((fd = open("/dev/diskmap", oflags)) != -1) {
			bzero(&dm, sizeof(struct dk_diskmap));
			dm.device = namebuf;
			dm.fd = fd;
			if (dflags & OPENDEV_PART)
				dm.flags |= DM_OPENPART;
			if (dflags & OPENDEV_BLCK)
				dm.flags |= DM_OPENBLCK;

			if (ioctl(fd, DIOCMAP, &dm) == -1) {
				close(fd);
				fd = -1;
				errno = ENOENT;
			}
		}
	}
	if (!slash && fd == -1 && errno == ENOENT) {
		if (dflags & OPENDEV_PART) {
			/*
			 * First try raw partition (for removable drives)
			 */
			if (snprintf(namebuf, sizeof(namebuf), "%s%s%s%c",
			    _PATH_DEV, prefix, path, 'a' + getrawpartition())
			    < sizeof(namebuf)) {
				fd = open(namebuf, oflags);
			} else
				errno = ENAMETOOLONG;
		}
		if (fd == -1 && errno == ENOENT) {
			if (snprintf(namebuf, sizeof(namebuf), "%s%s%s",
			    _PATH_DEV, prefix, path) < sizeof(namebuf)) {
				fd = open(namebuf, oflags);
			} else
				errno = ENAMETOOLONG;
		}
	}
	if (realpath)
		*realpath = namebuf;

	return (fd);
}
示例#14
0
/*
 * md back-end code for menu-driven BSD disklabel editor.
 */
int
md_make_bsd_partitions(void)
{
    int i;
    int part;
    int maxpart = getmaxpartitions();
    int partstart;
    int part_raw, part_bsd;
    int ptend;
    int no_swap = 0;
    partinfo *p;

    /*
     * Initialize global variables that track space used on this disk.
     * Standard 4.4BSD 8-partition labels always cover whole disk.
     */
    if (ptsize == 0)
        ptsize = dlsize - ptstart;
    if (dlsize == 0)
        dlsize = ptstart + ptsize;

    partstart = ptstart;
    ptend = ptstart + ptsize;

    /* Ask for layout type -- standard or special */
    msg_display(MSG_layout,
                ptsize / (MEG / sectorsize),
                DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE,
                DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE + XNEEDMB);

    process_menu(MENU_layout, NULL);

    /* Set so we use the 'real' geometry for rounding, input in MB */
    current_cylsize = dlcylsize;
    set_sizemultname_meg();

    /* Build standard partitions */
    memset(&bsdlabel, 0, sizeof bsdlabel);

    /* Set initial partition types to unused */
    for (part = 0 ; part < maxpart ; ++part)
        bsdlabel[part].pi_fstype = FS_UNUSED;

    /* Whole disk partition */
    part_raw = getrawpartition();
    if (part_raw == -1)
        part_raw = PART_C;	/* for sanity... */
    bsdlabel[part_raw].pi_offset = 0;
    bsdlabel[part_raw].pi_size = dlsize;

    if (part_raw == PART_D) {
        /* Probably a system that expects an i386 style mbr */
        part_bsd = PART_C;
        bsdlabel[PART_C].pi_offset = ptstart;
        bsdlabel[PART_C].pi_size = ptsize;
    } else {
        part_bsd = part_raw;
    }

    if (bootsize != 0) {
        bsdlabel[PART_BOOT_FAT12].pi_fstype = FS_MSDOS;
        bsdlabel[PART_BOOT_FAT12].pi_size = bootsize;
        bsdlabel[PART_BOOT_FAT12].pi_offset = bootstart;
        bsdlabel[PART_BOOT_FAT12].pi_flags |= PART_BOOT_FAT12_PI_FLAGS;
        strlcpy(bsdlabel[PART_BOOT_FAT12].pi_mount,
                PART_BOOT_FAT12_PI_MOUNT,
                sizeof bsdlabel[PART_BOOT_FAT12].pi_mount);
    }

#ifdef PART_REST
    bsdlabel[PART_REST].pi_offset = 0;
    bsdlabel[PART_REST].pi_size = ptstart;
#endif

    /*
     * Save any partitions that are outside the area we are
     * going to use.
     * In particular this saves details of the other MBR
     * partitions on a multiboot i386 system.
     */
    for (i = maxpart; i--;) {
        if (bsdlabel[i].pi_size != 0)
            /* Don't overwrite special partitions */
            continue;
        p = &oldlabel[i];
        if (p->pi_fstype == FS_UNUSED || p->pi_size == 0)
            continue;
        if (layoutkind == 4) {
            if (PI_ISBSDFS(p))
                p->pi_flags |= PIF_MOUNT;
        } else {
            if (p->pi_offset < ptstart + ptsize &&
                    p->pi_offset + p->pi_size > ptstart)
                /* Not outside area we are allocating */
                continue;
            if (p->pi_fstype == FS_SWAP)
                no_swap = 1;
        }
        bsdlabel[i] = oldlabel[i];
    }

    if (layoutkind == 4) {
        /* XXX Check we have a sensible layout */
        ;
    } else
        get_ptn_sizes(partstart, ptend - partstart, no_swap);

    /*
     * OK, we have a partition table. Give the user the chance to
     * edit it and verify it's OK, or abort altogether.
     */
edit_check:
    if (edit_and_check_label(bsdlabel, maxpart, part_raw, part_bsd) == 0) {
        msg_display(MSG_abort);
        return 0;
    }
    if (md_check_partitions() == 0)
        goto edit_check;

    /* Disk name */
    msg_prompt(MSG_packname, bsddiskname, bsddiskname, sizeof bsddiskname);

    /* save label to disk for MI code to update. */
    (void)savenewlabel(bsdlabel, maxpart);

    /* Everything looks OK. */
    return 1;
}
示例#15
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;
}
示例#16
0
int
main(int argc, char *argv[])
{
	int	c, devfd;
	char	*protostore;
	long	protosize;
	struct stat disksb, bootsb;
	struct disklabel dl;
	daddr64_t partoffset;
#define BBPAD   0x1e0
	struct bb {
		char	bb_pad[BBPAD];	/* disklabel lives in here, actually */
		long	bb_secsize;	/* size of secondary boot block */
		long	bb_secstart;	/* start of secondary boot block */
		long	bb_flags;	/* unknown; always zero */
		long	bb_cksum;	/* checksum of the boot block, as longs. */
	} bb;
	long *lp, *ep;

	while ((c = getopt(argc, argv, "vns:e:")) != -1) {
		switch (c) {
		case 'n':
			/* Do not actually write the bootblock to disk */
			nowrite = 1;
			break;
		case 'v':
			/* Chat */
			verbose = 1;
			break;
		case 's':
			isofsblk = atoi(optarg);
			break;
		case 'e':
			isofseblk = atoi(optarg);
			break;
		default:
			usage();
		}
	}

	if (argc - optind < 3)
		usage();

	boot = argv[optind];
	proto = argv[optind + 1];
	dev = argv[optind + 2];

	if (verbose) {
		(void)printf("boot: %s\n", boot);
		(void)printf("proto: %s\n", proto);
		(void)printf("device: %s\n", dev);
	}

	/* Load proto blocks into core */
	if ((protostore = loadprotoblocks(proto, &protosize)) == NULL)
		exit(1);

	/* Open and check raw disk device */
	if ((devfd = opendev(dev, O_RDONLY, OPENDEV_PART, &dev)) < 0)
		err(1, "open: %s", dev);
	if (fstat(devfd, &disksb) == -1)
		err(1, "fstat: %s", dev);
	if (!S_ISCHR(disksb.st_mode))
		errx(1, "%s must be a character device node", dev);
	if ((minor(disksb.st_rdev) % getmaxpartitions()) != getrawpartition())
		errx(1, "%s must be the raw partition", dev);

	/* Extract and load block numbers */
	if (stat(boot, &bootsb) == -1)
		err(1, "stat: %s", boot);
	if (!S_ISREG(bootsb.st_mode))
		errx(1, "%s must be a regular file", boot);
	if ((minor(disksb.st_rdev) / getmaxpartitions()) !=
	    (minor(bootsb.st_dev) / getmaxpartitions()))
		errx(1, "%s must be somewhere on %s", boot, dev);

	/*
	 * Find the offset of the secondary boot block's partition
	 * into the disk.  If disklabels not supported, assume zero.
	 */
	if (ioctl(devfd, DIOCGDINFO, &dl) != -1) {
		partoffset = DL_GETPOFFSET(&dl.d_partitions[minor(bootsb.st_dev) %
		    getmaxpartitions()]);
	} else {
		if (errno != ENOTTY)
			err(1, "read disklabel: %s", dev);
		warnx("couldn't read label from %s, using part offset of 0",
		    dev);
		partoffset = 0;
	}
	if (verbose)
		(void)printf("%s partition offset = 0x%lx\n", boot, partoffset);

	/* Sync filesystems (make sure boot's block numbers are stable) */
	sync();
	sleep(2);
	sync();
	sleep(2);

	if (loadblocknums(boot, devfd, partoffset) != 0)
		exit(1);

	(void)close(devfd);

	if (nowrite)
		return 0;

#if 0
	/* Write patched proto bootblocks into the superblock */
	if (protosize > SBSIZE - DEV_BSIZE)
		errx(1, "proto bootblocks too big");
#endif

	if ((devfd = opendev(dev, O_RDWR, OPENDEV_PART, &dev)) < 0)
		err(1, "open: %s", dev);

	if (lseek(devfd, DEV_BSIZE, SEEK_SET) != DEV_BSIZE)
		err(1, "lseek bootstrap");

	if (write(devfd, protostore, protosize) != protosize)
		err(1, "write bootstrap");

	if (lseek(devfd, 0, SEEK_SET) != 0)
		err(1, "lseek label");

	if (read(devfd, &bb, sizeof (bb)) != sizeof (bb))
		err(1, "read label");

	bb.bb_secsize = 15;
	bb.bb_secstart = 1;
	bb.bb_flags = 0;
	bb.bb_cksum = 0;

	for (lp = (long *)&bb, ep = &bb.bb_cksum; lp < ep; lp++)
		bb.bb_cksum += *lp;

	if (lseek(devfd, 0, SEEK_SET) != 0)
		err(1, "lseek label 2");

	if (write(devfd, &bb, sizeof bb) != sizeof bb)
		err(1, "write label ");

	(void)close(devfd);
	return 0;
}