]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - disk-utils/cfdisk.c
wipefs: add --lock and LOCK_BLOCK_DEVICE
[thirdparty/util-linux.git] / disk-utils / cfdisk.c
index 8f590387fdc0c2d4e8c9489755ea850352ee2016..c783f9daa3154143303f6effb1d69d0603b55ead 100644 (file)
@@ -64,6 +64,7 @@
 #include "colors.h"
 #include "debug.h"
 #include "list.h"
+#include "blkdev.h"
 
 static const char *default_disks[] = {
 #ifdef __GNU__
@@ -147,8 +148,8 @@ static void ui_draw_menu(struct cfdisk *cf);
 static int ui_menu_move(struct cfdisk *cf, int key);
 static void ui_menu_resize(struct cfdisk *cf);
 
-static int ui_get_size(struct cfdisk *cf, const char *prompt, uintmax_t *res,
-                      uintmax_t low, uintmax_t up, int *expsize);
+static int ui_get_size(struct cfdisk *cf, const char *prompt, uint64_t *res,
+                      uint64_t low, uint64_t up, int *expsize);
 
 static int ui_enabled;
 static volatile sig_atomic_t sig_resize;
@@ -436,9 +437,7 @@ static char *table_to_string(struct cfdisk *cf, struct fdisk_table *tb)
         * 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);
+       fdisk_reset_table(tb);
 
        s_itr = scols_new_iter(SCOLS_ITER_FORWARD);
        if (!s_itr)
@@ -988,7 +987,9 @@ static size_t menuitem_get_line(struct cfdisk *cf, size_t idx)
                if (!m->page_sz)                                /* small menu */
                        return (ui_lines - (cf->menu->nitems + 1)) / 2 + idx;
                return (idx % m->page_sz) + 1;
-       } else {
+       }
+
+       {
                size_t len = MENU_H_ITEMWIDTH(m) + MENU_H_BETWEEN; /** item width */
                size_t items = ui_cols / len;                   /* items per line */
 
@@ -1005,7 +1006,9 @@ static int menuitem_get_column(struct cfdisk *cf, size_t idx)
                if ((size_t) ui_cols <= nc)
                        return 0;
                return (ui_cols - nc) / 2;
-       } else {
+       }
+
+       {
                size_t len = MENU_H_ITEMWIDTH(cf->menu) + MENU_H_BETWEEN; /* item width */
                size_t items = ui_cols / len;                           /* items per line */
                size_t extra = items < cf->menu->nitems ?               /* extra space on line */
@@ -1268,7 +1271,10 @@ static char *get_mountpoint(struct cfdisk *cf, const char *tagname, const char *
                        cf->fstab = mnt_new_table();
                        if (cf->fstab) {
                                mnt_table_set_cache(cf->fstab, cf->mntcache);
-                               mnt_table_parse_fstab(cf->fstab, NULL);
+                               if (mnt_table_parse_fstab(cf->fstab, NULL) != 0) {
+                                       mnt_unref_table(cf->fstab);
+                                       cf->fstab = NULL;
+                               }
                        }
                }
                if (cf->fstab)
@@ -1699,7 +1705,8 @@ static int ui_refresh(struct cfdisk *cf)
        if (!ui_enabled)
                return -EINVAL;
 
-       strsz = size_to_human_string(SIZE_SUFFIX_SPACE
+       strsz = size_to_human_string(SIZE_DECIMAL_2DIGITS
+                               | SIZE_SUFFIX_SPACE
                                | SIZE_SUFFIX_3LETTER, bytes);
 
        lb = fdisk_get_label(cf->cxt, NULL);
@@ -1711,7 +1718,7 @@ static int ui_refresh(struct cfdisk *cf)
        attron(A_BOLD);
        ui_center(0, _("Disk: %s"), fdisk_get_devname(cf->cxt));
        attroff(A_BOLD);
-       ui_center(1, _("Size: %s, %ju bytes, %ju sectors"),
+       ui_center(1, _("Size: %s, %"PRIu64" bytes, %ju sectors"),
                        strsz, bytes, (uintmax_t) fdisk_get_nsectors(cf->cxt));
        if (fdisk_get_disklabel_id(cf->cxt, &id) == 0 && id)
                ui_center(2, _("Label: %s, identifier: %s"),
@@ -1719,6 +1726,7 @@ static int ui_refresh(struct cfdisk *cf)
        else
                ui_center(2, _("Label: %s"), fdisk_label_get_name(lb));
        free(strsz);
+       free(id);
 
        ui_draw_table(cf);
        ui_draw_menu(cf);
@@ -1745,7 +1753,7 @@ static ssize_t ui_get_string(const char *prompt,
        clrtoeol();
 
        if (prompt) {
-               mvaddstr(ln, cl, (char *) prompt);
+               mvaddstr(ln, cl, prompt);
                cl += mbs_safe_width(prompt);
        }
 
@@ -1847,17 +1855,17 @@ done:
 
 static int ui_get_size(struct cfdisk *cf,      /* context */
                       const char *prompt,      /* UI dialog string */
-                      uintmax_t *res,          /* result in bytes */
-                      uintmax_t low,           /* minimal size */
-                      uintmax_t up,            /* maximal size */
+                      uint64_t *res,           /* result in bytes */
+                      uint64_t low,            /* minimal size */
+                      uint64_t up,             /* maximal size */
                       int *expsize)            /* explicitly specified size */
 {
        char buf[128];
-       uintmax_t user = 0;
+       uint64_t user = 0;
        ssize_t rc;
        char *dflt = size_to_human_string(0, *res);
 
-       DBG(UI, ul_debug("get_size (default=%ju)", *res));
+       DBG(UI, ul_debug("get_size (default=%"PRIu64")", *res));
 
        ui_clean_info();
 
@@ -1875,7 +1883,7 @@ static int ui_get_size(struct cfdisk *cf, /* context */
                if (rc == 0) {
                        ui_warnx(_("Please, specify size."));
                        continue;                       /* nothing specified */
-               } else if (rc == -CFDISK_ERR_ESC)
+               } if (rc == -CFDISK_ERR_ESC)
                        break;                          /* cancel dialog */
 
                if (strcmp(buf, dflt) == 0)
@@ -1886,16 +1894,16 @@ static int ui_get_size(struct cfdisk *cf,       /* context */
                                insec = 1;
                                buf[len - 1] = '\0';
                        }
-                       rc = parse_size(buf, &user, &pwr);      /* parse */
+                       rc = parse_size(buf, (uintmax_t *)&user, &pwr); /* parse */
                }
 
                if (rc == 0) {
-                       DBG(UI, ul_debug("get_size user=%ju, power=%d, in-sectors=%s",
+                       DBG(UI, ul_debug("get_size user=%"PRIu64", power=%d, in-sectors=%s",
                                                user, pwr, insec ? "yes" : "no"));
                        if (insec)
                                user *= fdisk_get_sector_size(cf->cxt);
                        if (user < low) {
-                               ui_warnx(_("Minimum size is %ju bytes."), low);
+                               ui_warnx(_("Minimum size is %"PRIu64" bytes."), low);
                                rc = -ERANGE;
                        }
                        if (user > up && pwr && user < up + (1ULL << pwr * 10))
@@ -1904,7 +1912,7 @@ static int ui_get_size(struct cfdisk *cf, /* context */
                                user = up;
 
                        if (user > up) {
-                               ui_warnx(_("Maximum size is %ju bytes."), up);
+                               ui_warnx(_("Maximum size is %"PRIu64" bytes."), up);
                                rc = -ERANGE;
                        }
                        if (rc == 0 && insec && expsize)
@@ -1918,7 +1926,7 @@ static int ui_get_size(struct cfdisk *cf, /* context */
                *res = user;
        free(dflt);
 
-       DBG(UI, ul_debug("get_size (result=%ju, rc=%zd)", *res, rc));
+       DBG(UI, ul_debug("get_size (result=%"PRIu64", rc=%zd)", *res, rc));
        return rc;
 }
 
@@ -2636,10 +2644,13 @@ static void __attribute__((__noreturn__)) usage(void)
        fputs(_("Display or manipulate a disk partition table.\n"), out);
 
        fputs(USAGE_OPTIONS, out);
-       fputs(_(" -L, --color[=<when>]     colorize output (auto, always or never)\n"), out);
+       fprintf(out,
+             _(" -L, --color[=<when>]     colorize output (%s, %s or %s)\n"), "auto", "always", "never");
        fprintf(out,
                "                            %s\n", USAGE_COLORS_DEFAULT);
        fputs(_(" -z, --zero               start with zeroed partition table\n"), out);
+       fprintf(out,
+             _("     --lock[=<mode>]      use exclusive device lock (%s, %s or %s)\n"), "yes", "no", "nonblock");
 
        fputs(USAGE_SEPARATOR, out);
        printf(USAGE_HELP_OPTIONS(26));
@@ -2650,13 +2661,16 @@ static void __attribute__((__noreturn__)) usage(void)
 
 int main(int argc, char *argv[])
 {
-       const char *diskpath = NULL;
+       const char *diskpath = NULL, *lockmode = NULL;
        int rc, c, colormode = UL_COLORMODE_UNDEF;
        struct cfdisk _cf = { .lines_idx = 0 },
                      *cf = &_cf;
-
+       enum {
+               OPT_LOCK        = CHAR_MAX + 1
+       };
        static const struct option longopts[] = {
                { "color",   optional_argument, NULL, 'L' },
+               { "lock",    optional_argument, NULL, OPT_LOCK },
                { "help",    no_argument,       NULL, 'h' },
                { "version", no_argument,       NULL, 'V' },
                { "zero",    no_argument,       NULL, 'z' },
@@ -2666,7 +2680,7 @@ int main(int argc, char *argv[])
        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
-       atexit(close_stdout);
+       close_stdout_atexit();
 
        while((c = getopt_long(argc, argv, "L::hVz", longopts, NULL)) != -1) {
                switch(c) {
@@ -2680,11 +2694,18 @@ int main(int argc, char *argv[])
                                                _("unsupported color mode"));
                        break;
                case 'V':
-                       printf(UTIL_LINUX_VERSION);
-                       return EXIT_SUCCESS;
+                       print_version(EXIT_SUCCESS);
                case 'z':
                        cf->zero_start = 1;
                        break;
+               case OPT_LOCK:
+                       lockmode = "1";
+                       if (optarg) {
+                               if (*optarg == '=')
+                                       optarg++;
+                               lockmode = optarg;
+                       }
+                       break;
                default:
                        errtryhelp(EXIT_FAILURE);
                }
@@ -2722,6 +2743,9 @@ int main(int argc, char *argv[])
                err(EXIT_FAILURE, _("cannot open %s"), diskpath);
 
        if (!fdisk_is_readonly(cf->cxt)) {
+               if (blkdev_lock(fdisk_get_devfd(cf->cxt), diskpath, lockmode) != 0)
+                       return EXIT_FAILURE;
+
                cf->device_is_used = fdisk_device_is_used(cf->cxt);
                fdisk_get_partitions(cf->cxt, &cf->original_layout);
        }
@@ -2733,6 +2757,7 @@ int main(int argc, char *argv[])
 
        cfdisk_free_lines(cf);
        free(cf->linesbuf);
+       free(cf->fields);
 
        fdisk_unref_table(cf->table);
 #ifdef HAVE_LIBMOUNT