int main(int argc, char *argv[]) { FILE *t; int ch, error, fd; const char *name; error = 0; name = NULL; while ((ch = getopt(argc, argv, "ABb:efm:nRrw")) != -1) switch (ch) { case 'A': allfields = 1; break; case 'B': ++installboot; break; case 'b': xxboot = optarg; break; case 'f': is_file=1; break; case 'm': if (!strcmp(optarg, "i386") || !strcmp(optarg, "amd64") || !strcmp(optarg, "ia64") || !strcmp(optarg, "pc98")) { labelsoffset = 1; labeloffset = 0; bbsize = 8192; } else { errx(1, "Unsupported architecture"); } break; case 'n': disable_write = 1; break; case 'R': if (op != UNSPEC) usage(); op = RESTORE; break; case 'e': if (op != UNSPEC) usage(); op = EDIT; break; case 'r': /* * We accept and ignore -r for compatibility with * historical disklabel usage. */ break; case 'w': if (op != UNSPEC) usage(); op = WRITE; break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc < 1) usage(); if (labelsoffset < 0 || labeloffset < 0) errx(1, "a -m <architecture> option must be specified"); /* Figure out the names of the thing we're working on */ if (is_file) { specname = argv[0]; } else { specname = g_device_path(argv[0]); if (specname == NULL) { warn("unable to get correct path for %s", argv[0]); return(1); } fd = open(specname, O_RDONLY); if (fd < 0) { warn("error opening %s", specname); return(1); } pname = g_providername(fd); if (pname == NULL) { warn("error getting providername for %s", specname); close(fd); return(1); } close(fd); } if (installboot && op == UNSPEC) op = WRITEBOOT; else if (op == UNSPEC) op = READ; switch(op) { case UNSPEC: break; case EDIT: if (argc != 1) usage(); readlabel(1); fixlabel(&lab); error = edit(); break; case READ: if (argc != 1) usage(); readlabel(1); display(stdout, NULL); error = checklabel(NULL); break; case RESTORE: if (argc != 2) usage(); if (!(t = fopen(argv[1], "r"))) err(4, "fopen %s", argv[1]); readlabel(0); if (!getasciilabel(t, &lab)) exit(1); error = writelabel(); break; case WRITE: if (argc == 2) name = argv[1]; else if (argc == 1) name = "auto"; else usage(); readlabel(0); makelabel(name, &lab); fixlabel(&lab); if (checklabel(NULL) == 0) error = writelabel(); break; case WRITEBOOT: readlabel(1); fixlabel(&lab); if (argc == 2) makelabel(argv[1], &lab); if (checklabel(NULL) == 0) error = writelabel(); break; } exit(error); }
/* * Boot manager installation/configuration utility. */ int main(int argc, char *argv[]) { u_int8_t *mbr, *boot0; int boot0_size, mbr_size; const char *bpath, *fpath; char *disk; int B_flag, o_flag; int d_arg, m_arg, s_arg, t_arg; int o_and, o_or, o_e = -1; int up, c; bpath = "/boot/boot0"; fpath = NULL; B_flag = v_flag = o_flag = 0; d_arg = m_arg = s_arg = t_arg = -1; o_and = 0xff; o_or = 0; while ((c = getopt(argc, argv, "Bvb:d:e:f:i:m:o:s:t:")) != -1) switch (c) { case 'B': B_flag = 1; break; case 'v': v_flag = 1; break; case 'b': bpath = optarg; break; case 'd': d_arg = argtoi(optarg, 0, 0xff, 'd'); break; case 'e': if (optarg[0] == '0' && optarg[1] == 'x') sscanf(optarg, "0x%02x", &o_e); else o_e = optarg[0]; break; case 'f': fpath = optarg; break; case 'i': if (sscanf(optarg, "%02x%02x-%02x%02x", vol_id, vol_id+1, vol_id+2, vol_id+3) == 4) vol_id[4] = 1; else errx(1, "bad argument %s", optarg); break; case 'm': m_arg = argtoi(optarg, 0, 0xf, 'm'); break; case 'o': stropt(optarg, &o_and, &o_or); o_flag = 1; break; case 's': if (strcasecmp(optarg, "pxe") == 0) s_arg = 6; else s_arg = argtoi(optarg, 1, 6, 's'); break; case 't': t_arg = argtoi(optarg, 1, 0xffff, 't'); break; default: usage(); } argc -= optind; argv += optind; if (argc != 1) usage(); disk = g_device_path(*argv); if (disk == NULL) errx(1, "Unable to get providername for %s\n", *argv); up = B_flag || d_arg != -1 || m_arg != -1 || o_flag || s_arg != -1 || t_arg != -1; /* open the disk and read in the existing mbr. Either here or * when reading the block from disk, we do check for the version * and abort if a suitable block is not found. */ mbr_size = read_mbr(disk, &mbr, !B_flag); /* save the existing MBR if we are asked to do so */ if (fpath) write_mbr(fpath, O_CREAT | O_TRUNC, mbr, mbr_size); /* * If we are installing the boot loader, read it from disk and copy the * slice table over from the existing MBR. If not, then point boot0 * back at the MBR we just read in. After this, boot0 is the data to * write back to disk if we are going to do a write. */ if (B_flag) { boot0_size = read_mbr(bpath, &boot0, 1); memcpy(boot0 + OFF_PTBL, mbr + OFF_PTBL, sizeof(struct dos_partition) * NDOSPART); if (b0_ver == 2) /* volume serial number support */ memcpy(boot0 + OFF_SERIAL, mbr + OFF_SERIAL, 4); } else { boot0 = mbr; boot0_size = mbr_size; } /* set the drive */ if (d_arg != -1) boot0[OFF_DRIVE] = d_arg; /* set various flags */ if (m_arg != -1) { boot0[OFF_FLAGS] &= 0xf0; boot0[OFF_FLAGS] |= m_arg; } if (o_flag) { boot0[OFF_FLAGS] &= o_and; boot0[OFF_FLAGS] |= o_or; } /* set the default boot selection */ if (s_arg != -1) boot0[OFF_OPT] = s_arg - 1; /* set the timeout */ if (t_arg != -1) mk2(boot0 + OFF_TICKS, t_arg); /* set the bell char */ if (o_e != -1 && set_bell(boot0, o_e, 0) != -1) up = 1; if (vol_id[4]) { if (b0_ver != 2) errx(1, "incompatible boot block, cannot set volume ID"); boot0[OFF_SERIAL] = vol_id[0]; boot0[OFF_SERIAL+1] = vol_id[1]; boot0[OFF_SERIAL+2] = vol_id[2]; boot0[OFF_SERIAL+3] = vol_id[3]; up = 1; /* force update */ } /* write the MBR back to disk */ if (up) write_mbr(disk, 0, boot0, boot0_size); /* display the MBR */ if (v_flag) display_mbr(boot0); /* clean up */ if (mbr != boot0) free(boot0); free(mbr); free(disk); return 0; }