/** * fdisk_create_disklabel: * @cxt: fdisk context * @name: label name * * Creates a new disk label of type @name. If @name is NULL, then it * will create a default system label type, either SUN or DOS. * * Returns 0 on success, otherwise, a corresponding error. */ int fdisk_create_disklabel(struct fdisk_context *cxt, const char *name) { int haslabel = 0; struct fdisk_label *lb; if (!cxt) return -EINVAL; if (!name) { /* use default label creation */ #ifdef __sparc__ name = "sun"; #else name = "dos"; #endif } if (cxt->label) { fdisk_deinit_label(cxt->label); haslabel = 1; } lb = fdisk_context_get_label(cxt, name); if (!lb || lb->disabled) return -EINVAL; if (!lb->op->create) return -ENOSYS; __fdisk_context_switch_label(cxt, lb); if (haslabel && !cxt->parent) fdisk_reset_device_properties(cxt); DBG(CXT, ul_debugobj(cxt, "create a new %s label", lb->name)); return cxt->label->op->create(cxt); }
void toggle_dos_compatibility_flag(struct fdisk_context *cxt) { struct fdisk_label *lb = fdisk_context_get_label(cxt, "dos"); int flag; if (!lb) return; flag = !fdisk_dos_is_compatible(lb); fdisk_info(cxt, flag ? _("DOS Compatibility flag is set (DEPRECATED!)") : _("DOS Compatibility flag is not set")); fdisk_dos_enable_compatible(lb, flag); if (fdisk_is_disklabel(cxt, DOS)) fdisk_reset_alignment(cxt); /* reset the current label */ }
/* It would be possible to use fdisk_table_to_string(), but we want some * extension to the output format, so let's do it without libfdisk */ static char *table_to_string(struct cfdisk *cf, struct fdisk_table *tb) { const struct fdisk_column *col; struct fdisk_partition *pa; struct fdisk_label *lb; struct fdisk_iter *itr = NULL; struct libscols_table *table = NULL; struct libscols_iter *s_itr = NULL; char *res = NULL; size_t i; int tree = 0; struct libscols_line *ln, *ln_cont = NULL; DBG(FRONTEND, ul_debug("table: convert to string")); assert(cf); assert(cf->cxt); assert(cf->cols); assert(tb); lb = fdisk_context_get_label(cf->cxt, NULL); assert(lb); itr = fdisk_new_iter(FDISK_ITER_FORWARD); if (!itr) goto done; /* get container (e.g. extended partition) */ while (fdisk_table_next_partition(tb, itr, &pa) == 0) { if (fdisk_partition_is_nested(pa)) { DBG(FRONTEND, ul_debug("table: nested detected, using tree")); tree = SCOLS_FL_TREE; break; } } table = scols_new_table(); if (!table) goto done; scols_table_enable_maxout(table, 1); /* headers */ for (i = 0; i < cf->ncols; i++) { col = fdisk_label_get_column(lb, cf->cols[i]); if (col) { int fl = col->scols_flags; if (tree && col->id == FDISK_COL_DEVICE) fl |= SCOLS_FL_TREE; if (!scols_table_new_column(table, col->name, col->width, fl)) goto done; } } /* data */ fdisk_reset_iter(itr, FDISK_ITER_FORWARD); while (fdisk_table_next_partition(tb, itr, &pa) == 0) { struct libscols_line *parent = fdisk_partition_is_nested(pa) ? ln_cont : NULL; ln = scols_table_new_line(table, parent); if (!ln) goto done; for (i = 0; i < cf->ncols; i++) { char *cdata = NULL; col = fdisk_label_get_column(lb, cf->cols[i]); if (!col) continue; if (fdisk_partition_to_string(pa, cf->cxt, col->id, &cdata)) continue; scols_line_refer_data(ln, i, cdata); } if (tree && fdisk_partition_is_container(pa)) ln_cont = ln; scols_line_set_userdata(ln, (void *) pa); fdisk_ref_partition(pa); } if (scols_table_is_empty(table)) goto done; scols_table_reduce_termwidth(table, ARROW_CURSOR_WIDTH); scols_print_table_to_string(table, &res); /* scols_* code might reorder lines, let's reorder @tb according to the * final output (it's no problem because partitions are addressed by * parno stored within struct fdisk_partition) */ /* remove all */ fdisk_reset_iter(itr, FDISK_ITER_FORWARD); while (fdisk_table_next_partition(tb, itr, &pa) == 0) fdisk_table_remove_partition(tb, pa); s_itr = scols_new_iter(SCOLS_ITER_FORWARD); if (!s_itr) goto done; /* add all in the right order (don't forget the output is tree) */ while (scols_table_next_line(table, s_itr, &ln) == 0) { if (scols_line_get_parent(ln)) continue; if (partition_from_scols(tb, ln)) break; } done: scols_unref_table(table); scols_free_iter(s_itr); fdisk_free_iter(itr); return res; }
int main(int argc, char **argv) { int i, c, act = ACT_FDISK; int colormode = UL_COLORMODE_AUTO; struct fdisk_context *cxt; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); fdisk_init_debug(0); cxt = fdisk_new_context(); if (!cxt) err(EXIT_FAILURE, _("failed to allocate libfdisk context")); fdisk_context_set_ask(cxt, ask_callback, NULL); while ((c = getopt(argc, argv, "b:c::C:hH:lL::sS:t:u::vV")) != -1) { switch (c) { case 'b': { size_t sz = strtou32_or_err(optarg, _("invalid sector size argument")); if (sz != 512 && sz != 1024 && sz != 2048 && sz != 4096) usage(stderr); fdisk_save_user_sector_size(cxt, sz, sz); break; } case 'C': fdisk_save_user_geometry(cxt, strtou32_or_err(optarg, _("invalid cylinders argument")), 0, 0); break; case 'c': if (optarg) { /* this setting is independent on the current * actively used label */ struct fdisk_label *lb = fdisk_context_get_label(cxt, "dos"); if (!lb) err(EXIT_FAILURE, _("not found DOS label driver")); if (strcmp(optarg, "=dos") == 0) fdisk_dos_enable_compatible(lb, TRUE); else if (strcmp(optarg, "=nondos") == 0) fdisk_dos_enable_compatible(lb, FALSE); else usage(stderr); } /* use default if no optarg specified */ break; case 'H': fdisk_save_user_geometry(cxt, 0, strtou32_or_err(optarg, _("invalid heads argument")), 0); break; case 'S': fdisk_save_user_geometry(cxt, 0, 0, strtou32_or_err(optarg, _("invalid sectors argument"))); break; case 'l': act = ACT_LIST; break; case 'L': if (optarg) colormode = colormode_or_err(optarg, _("unsupported color mode")); break; case 's': act = ACT_SHOWSIZE; break; case 't': { struct fdisk_label *lb = NULL; while (fdisk_context_next_label(cxt, &lb) == 0) fdisk_label_set_disabled(lb, 1); lb = fdisk_context_get_label(cxt, optarg); if (!lb) errx(EXIT_FAILURE, _("unsupported disklabel: %s"), optarg); fdisk_label_set_disabled(lb, 0); } case 'u': if (optarg && *optarg == '=') optarg++; if (fdisk_context_set_unit(cxt, optarg) != 0) usage(stderr); break; case 'V': case 'v': printf(UTIL_LINUX_VERSION); return EXIT_SUCCESS; case 'h': usage(stdout); default: usage(stderr); } } if (argc-optind != 1 && fdisk_has_user_device_properties(cxt)) warnx(_("The device properties (sector size and geometry) should" " be used with one specified device only.")); colors_init(colormode); switch (act) { case ACT_LIST: fdisk_context_enable_listonly(cxt, 1); if (argc > optind) { int k; for (k = optind; k < argc; k++) print_device_pt(cxt, argv[k]); } else print_all_devices_pt(cxt); break; case ACT_SHOWSIZE: /* deprecated */ if (argc - optind <= 0) usage(stderr); for (i = optind; i < argc; i++) { if (argc - optind == 1) printf("%llu\n", get_dev_blocks(argv[i])); else printf("%s: %llu\n", argv[i], get_dev_blocks(argv[i])); } break; case ACT_FDISK: if (argc-optind != 1) usage(stderr); if (fdisk_context_assign_device(cxt, argv[optind], 0) != 0) err(EXIT_FAILURE, _("cannot open %s"), argv[optind]); /* Here starts interactive mode, use fdisk_{warn,info,..} functions */ color_enable(UL_COLOR_GREEN); fdisk_info(cxt, _("Welcome to fdisk (%s)."), PACKAGE_STRING); color_disable(); fdisk_info(cxt, _("Changes will remain in memory only, until you decide to write them.\n" "Be careful before using the write command.\n")); fflush(stdout); if (!fdisk_dev_has_disklabel(cxt)) { fdisk_warnx(cxt, _("Device does not contain a recognized partition table.")); fdisk_create_disklabel(cxt, NULL); } while (1) process_fdisk_menu(&cxt); } fdisk_free_context(cxt); return EXIT_SUCCESS; }
int fdisk_context_switch_label(struct fdisk_context *cxt, const char *name) { return __fdisk_context_switch_label(cxt, fdisk_context_get_label(cxt, name)); }