struct sfdisk {
int act; /* action */
- size_t partno; /* partition number <1..N> */
struct fdisk_context *cxt; /* libfdisk context */
};
return 0;
}
+static int command_activate(struct sfdisk *sf, int argc, char **argv)
+{
+ int rc, nparts, i;
+ struct fdisk_partition *pa = NULL;
+ const char *devname = NULL;
+
+ if (argc)
+ devname = argv[0];
+ else
+ errx(EXIT_FAILURE, _("no disk device specified"));
+ if (argc > 2)
+ errx(EXIT_FAILURE, _("uneexpected arguments"));
+
+ rc = fdisk_assign_device(sf->cxt, devname, 0);
+ if (rc)
+ err(EXIT_FAILURE, _("cannot open %s"), devname);
+
+ if (!fdisk_is_label(sf->cxt, DOS))
+ errx(EXIT_FAILURE, _("toggle boot flags is supported for MBR only"));
+
+ nparts = fdisk_get_npartitions(sf->cxt);
+ for (i = 0; i < nparts; i++) {
+ char *data = NULL;
+
+ /* note that fdisk_get_partition() reuses the @pa pointer, you
+ * don't have to (re)allocate it */
+ if (fdisk_get_partition(sf->cxt, i, &pa) != 0)
+ continue;
+
+ /* sfdisk --activate list bootable partitions */
+ if (argc == 1) {
+ if (!fdisk_partition_is_bootable(pa))
+ continue;
+ if (fdisk_partition_to_string(pa, sf->cxt,
+ FDISK_FIELD_DEVICE, &data) == 0) {
+ printf("%s\n", data);
+ free(data);
+ }
+
+ /* deactivate all active partitions */
+ } else if (fdisk_partition_is_bootable(pa))
+ fdisk_partition_toggle_flag(sf->cxt, i, DOS_FLAG_ACTIVE);
+ }
+
+ /* sfdisk --activate <partno> [..] */
+ for (i = 1; i < argc; i++) {
+ int n = strtou32_or_err(argv[i], _("failed to parse partition number"));
+
+ fdisk_partition_toggle_flag(sf->cxt, n - 1, DOS_FLAG_ACTIVE);
+ }
+
+ fdisk_unref_partition(pa);
+ rc = fdisk_write_disklabel(sf->cxt);
+ if (!rc)
+ rc = fdisk_deassign_device(sf->cxt, 1);
+ return rc;
+}
+
/*
* sfdisk --dump <device>
*/
/* default command */
static int command_fdisk(struct sfdisk *sf, int argc, char **argv)
{
- int rc;
+ int rc, partno;
const char *devname = NULL;
if (argc)
devname = argv[0];
if (argc > 1)
- sf->partno = strtou32_or_err(argv[1],
+ partno = strtou32_or_err(argv[1],
_("failed to parse partition number"));
if (!devname)
errx(EXIT_FAILURE, _("no disk device specified"));
fputs(USAGE_HEADER, out);
fprintf(out,
- _(" %1$s [options] <disk>\n"
- " %1$s [options] --list <disk> [...]\n"),
+ _(" %1$s [options] --dump <device>\n"
+ " %1$s [options] --list [<device> ...]\n"
+ " %1$s [options] --activate <device> [<partno> ...]\n"),
program_invocation_short_name);
fputs(USAGE_OPTIONS, out);
+ fputs(_(" -a, --activate mark MBR partitions as bootable\n"), out);
fputs(_(" -d, --dump dump partition table (suitable for later input)\n"), out);
fputs(_(" -l, --list list partitions of each device\n"), out);
int main(int argc, char *argv[])
{
- struct sfdisk _sf = { .partno = 0 }, *sf = &_sf;
+ struct sfdisk _sf = { .act = 0 }, *sf = &_sf;
int rc = -EINVAL, c;
static const struct option longopts[] = {
+ { "activate",no_argument, NULL, 'a' },
{ "list", no_argument, NULL, 'l' },
{ "dump", no_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
textdomain(PACKAGE);
atexit(close_stdout);
- while ((c = getopt_long(argc, argv, "dhlsv", longopts, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "adhlsv", longopts, NULL)) != -1) {
switch(c) {
+ case 'a':
+ sf->act = ACT_ACTIVATE;
+ break;
case 'h':
usage(stdout);
break;
sfdisk_init(sf);
switch (sf->act) {
+ case ACT_ACTIVATE:
+ rc = command_activate(sf, argc - optind, argv + optind);
+ break;
+
case ACT_LIST:
rc = command_list_partitions(sf, argc - optind, argv + optind);
break;