/* * 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; }
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); }
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; }
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; }
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; }
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); }
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); }
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); }
/* * 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); }
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"); } }
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 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(); }
/* * 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); }
/* * 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; }
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; }
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; }