summaryrefslogtreecommitdiffstats
path: root/libfdisk/samples
diff options
context:
space:
mode:
Diffstat (limited to 'libfdisk/samples')
-rw-r--r--libfdisk/samples/Makemodule.am16
-rw-r--r--libfdisk/samples/mkpart-fullspec.c192
-rw-r--r--libfdisk/samples/mkpart.c205
3 files changed, 413 insertions, 0 deletions
diff --git a/libfdisk/samples/Makemodule.am b/libfdisk/samples/Makemodule.am
new file mode 100644
index 0000000..b67b121
--- /dev/null
+++ b/libfdisk/samples/Makemodule.am
@@ -0,0 +1,16 @@
+
+check_PROGRAMS += \
+ sample-fdisk-mkpart \
+ sample-fdisk-mkpart-fullspec
+
+sample_fdisk_cflags = $(AM_CFLAGS) $(NO_UNUSED_WARN_CFLAGS) \
+ -I$(ul_libfdisk_incdir)
+sample_fdisk_ldadd = $(LDADD) libfdisk.la
+
+sample_fdisk_mkpart_SOURCES = libfdisk/samples/mkpart.c
+sample_fdisk_mkpart_LDADD = $(sample_fdisk_ldadd) libcommon.la
+sample_fdisk_mkpart_CFLAGS = $(sample_fdisk_cflags)
+
+sample_fdisk_mkpart_fullspec_SOURCES = libfdisk/samples/mkpart-fullspec.c
+sample_fdisk_mkpart_fullspec_LDADD = $(sample_fdisk_ldadd) libcommon.la
+sample_fdisk_mkpart_fullspec_CFLAGS = $(sample_fdisk_cflags)
diff --git a/libfdisk/samples/mkpart-fullspec.c b/libfdisk/samples/mkpart-fullspec.c
new file mode 100644
index 0000000..821a688
--- /dev/null
+++ b/libfdisk/samples/mkpart-fullspec.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2017 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ *
+ *
+ * Libfdisk sample to create partitions by specify all required partition
+ * properties (partno, start and size). The default is only partition type
+ * (except MBR where 4th partition is extended).
+ */
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <getopt.h>
+
+#include "c.h"
+#include "nls.h"
+#include "strutils.h"
+#include "xalloc.h"
+
+#include "libfdisk.h"
+
+static int ask_callback(struct fdisk_context *cxt __attribute__((__unused__)),
+ struct fdisk_ask *ask,
+ void *data)
+{
+ switch(fdisk_ask_get_type(ask)) {
+ case FDISK_ASKTYPE_INFO:
+ fputs(fdisk_ask_print_get_mesg(ask), stdout);
+ fputc('\n', stdout);
+ break;
+ case FDISK_ASKTYPE_WARNX:
+ fflush(stdout);
+ fputs(fdisk_ask_print_get_mesg(ask), stderr);
+ fputc('\n', stderr);
+ break;
+ case FDISK_ASKTYPE_WARN:
+ fflush(stdout);
+ fputs(fdisk_ask_print_get_mesg(ask), stderr);
+ errno = fdisk_ask_print_get_errno(ask);
+ fprintf(stderr, ": %m\n");
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ struct fdisk_context *cxt;
+ struct fdisk_partition *pa;
+ const char *label = NULL, *device = NULL;
+ int c;
+ size_t n = 1;
+
+ static const struct option longopts[] = {
+ { "label", required_argument, NULL, 'x' },
+ { "device", required_argument, NULL, 'd' },
+ { "help", no_argument, NULL, 'h' },
+ { NULL, 0, NULL, 0 },
+ };
+
+ setlocale(LC_ALL, ""); /* just to have enable UTF8 chars */
+
+ fdisk_init_debug(0);
+
+ while((c = getopt_long(argc, argv, "x:d:h", longopts, NULL)) != -1) {
+ switch(c) {
+ case 'x':
+ label = optarg;
+ break;
+ case 'd':
+ device = optarg;
+ break;
+ case 'h':
+ printf("%s [options] -- <partno,start,size> ...", program_invocation_short_name);
+ fputs(USAGE_SEPARATOR, stdout);
+ puts("Make disklabel and partitions.");
+ puts(" <partno> 1..n (4th is extended for MBR), or '-' for default");
+ puts(" <start> partition start offset in sectors");
+ puts(" <size> partition size in sectors");
+ fputs(USAGE_OPTIONS, stdout);
+ puts(" -x, --label <dos,gpt,...> disk label type (default MBR)");
+ puts(" -d, --device <path> block device");
+ puts(" -h, --help this help");
+ fputs(USAGE_SEPARATOR, stdout);
+ return EXIT_SUCCESS;
+ }
+ }
+
+ if (!device)
+ errx(EXIT_FAILURE, "no device specified");
+ if (!label)
+ label = "dos";
+
+ cxt = fdisk_new_context();
+ if (!cxt)
+ err_oom();
+ fdisk_set_ask(cxt, ask_callback, NULL);
+
+ pa = fdisk_new_partition();
+ if (!pa)
+ err_oom();
+
+ if (fdisk_assign_device(cxt, device, 0))
+ err(EXIT_FAILURE, "failed to assign device");
+ if (fdisk_create_disklabel(cxt, label))
+ err(EXIT_FAILURE, "failed to create disk label");
+
+ fdisk_disable_dialogs(cxt, 1);
+
+ while (optind < argc) {
+ int rc;
+ unsigned int partno = 0;
+ uint64_t start = 0, size = 0;
+ const char *str = argv[optind];
+
+ fdisk_reset_partition(pa);
+ fdisk_partition_end_follow_default(pa, 0);
+
+ if (*str == '-') {
+ /* partno unspecified */
+ if (sscanf(str, "-,%"SCNu64",%"SCNu64"", &start, &size) != 2)
+ errx(EXIT_FAILURE, "failed to parse %s", str);
+ fdisk_partition_partno_follow_default(pa, 1);
+ fdisk_partition_unset_partno(pa);
+ } else {
+ /* partno specified */
+ if (sscanf(str, "%u,%"SCNu64",%"SCNu64"", &partno, &start, &size) != 3)
+ errx(EXIT_FAILURE, "failed to parse %s", str);
+
+ fdisk_partition_partno_follow_default(pa, 0);
+ fdisk_partition_set_partno(pa, partno - 1); /* library uses 0..n */
+ }
+
+ fdisk_partition_set_start(pa, start);
+ fdisk_partition_set_size(pa, size);
+
+ if (fdisk_partition_has_partno(pa))
+ fprintf(stdout, "Requested partition: <partno=%zu,start=%ju,size=%ju>\n",
+ fdisk_partition_get_partno(pa),
+ (uintmax_t) fdisk_partition_get_start(pa),
+ (uintmax_t) fdisk_partition_get_size(pa));
+ else
+ fprintf(stdout, "Requested partition: <partno=<default>,start=%ju,size=%ju>\n",
+ (uintmax_t) fdisk_partition_get_start(pa),
+ (uintmax_t) fdisk_partition_get_size(pa));
+
+ if (fdisk_is_label(cxt, DOS)) {
+ /* Make sure last primary partition is extended if user
+ * wants more than 4 partitions.
+ */
+ if ((partno == 4 || (n == 4 && !fdisk_partition_has_partno(pa)))
+ && optind + 1 < argc) {
+ struct fdisk_parttype *type =
+ fdisk_label_parse_parttype(
+ fdisk_get_label(cxt, NULL), "05");
+ if (!type)
+ err_oom();
+ fdisk_partition_set_type(pa, type);
+ fdisk_unref_parttype(type);
+ }
+ }
+
+ rc = fdisk_add_partition(cxt, pa, NULL);
+ if (rc) {
+ errno = -rc;
+ errx(EXIT_FAILURE, "failed to add #%zu partition",
+ fdisk_partition_has_partno(pa) ?
+ fdisk_partition_get_partno(pa) + 1: n);
+ }
+
+ fdisk_reset_partition(pa);
+ optind++;
+ n++;
+ }
+
+ if (fdisk_write_disklabel(cxt))
+ err(EXIT_FAILURE, "failed to write disk label");
+
+ fdisk_deassign_device(cxt, 1);
+ fdisk_unref_context(cxt);
+ fdisk_unref_partition(pa);
+
+ return EXIT_SUCCESS;
+}
diff --git a/libfdisk/samples/mkpart.c b/libfdisk/samples/mkpart.c
new file mode 100644
index 0000000..1e5fd99
--- /dev/null
+++ b/libfdisk/samples/mkpart.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2017 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ *
+ *
+ * Libfdisk sample to create partitions by specify size, for example:
+ *
+ * mkpart --label dos --device /dev/sdc 2M 2M 2M 10M 1M -
+ *
+ * creates 6 partitions:
+ * - 3 primary (3x 2M)
+ * - 1 extended (1x 10M)
+ * - 2 logical (1x 1M, 1x remaining-space-in-extended-partition)
+ *
+ * Notes:
+ * The sample specifies size and partno for MBR, and size only for another
+ * labels (e.g. GPT).
+ *
+ * The Ask-API does not use anything else than warning/info. The
+ * partitionning has to be done non-interactive.
+ */
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <getopt.h>
+
+#include "c.h"
+#include "nls.h"
+#include "strutils.h"
+#include "xalloc.h"
+
+#include "libfdisk.h"
+
+static int ask_callback(struct fdisk_context *cxt __attribute__((__unused__)),
+ struct fdisk_ask *ask,
+ void *data)
+{
+ switch(fdisk_ask_get_type(ask)) {
+ case FDISK_ASKTYPE_INFO:
+ fputs(fdisk_ask_print_get_mesg(ask), stdout);
+ fputc('\n', stdout);
+ break;
+ case FDISK_ASKTYPE_WARNX:
+ fflush(stdout);
+ fputs(fdisk_ask_print_get_mesg(ask), stderr);
+ fputc('\n', stderr);
+ break;
+ case FDISK_ASKTYPE_WARN:
+ fflush(stdout);
+ fputs(fdisk_ask_print_get_mesg(ask), stderr);
+ errno = fdisk_ask_print_get_errno(ask);
+ fprintf(stderr, ": %m\n");
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ struct fdisk_context *cxt;
+ struct fdisk_partition *pa;
+ const char *label = NULL, *device = NULL;
+ int n = 0, c, nopartno = 0;
+ unsigned int sectorsize;
+ uint64_t grain = 0;
+
+ static const struct option longopts[] = {
+ { "label", required_argument, NULL, 'x' },
+ { "device", required_argument, NULL, 'd' },
+ { "nopartno", no_argument, NULL, 'p' },
+ { "grain", required_argument, NULL, 'g' },
+ { "help", no_argument, NULL, 'h' },
+ { NULL, 0, NULL, 0 },
+ };
+
+ setlocale(LC_ALL, ""); /* just to have enable UTF8 chars */
+
+ fdisk_init_debug(0);
+
+ while((c = getopt_long(argc, argv, "g:x:d:h", longopts, NULL)) != -1) {
+ switch(c) {
+ case 'x':
+ label = optarg;
+ break;
+ case 'd':
+ device = optarg;
+ break;
+ case 'p':
+ nopartno = 1;
+ break;
+ case 'g':
+ grain = strtosize_or_err(optarg, "failed to parse grain");
+ break;
+ case 'h':
+ printf("%s [options] <size> ...", program_invocation_short_name);
+ fputs(USAGE_SEPARATOR, stdout);
+ fputs("Make disklabel and partitions.\n", stdout);
+ fputs(USAGE_OPTIONS, stdout);
+ fputs(" -x, --label <dos,gpt,...> disk label type\n", stdout);
+ fputs(" -d, --device <path> block device\n", stdout);
+ fputs(" -p, --nopartno don't set partno (use default)\n", stdout);
+ fputs(" -h, --help this help\n", stdout);
+ fputs(USAGE_SEPARATOR, stdout);
+ return EXIT_SUCCESS;
+ }
+ }
+
+ if (!device)
+ errx(EXIT_FAILURE, "no device specified");
+ if (!label)
+ label = "dos";
+
+ cxt = fdisk_new_context();
+ if (!cxt)
+ err_oom();
+ fdisk_set_ask(cxt, ask_callback, NULL);
+
+ if (grain)
+ fdisk_save_user_grain(cxt, grain);
+
+ pa = fdisk_new_partition();
+ if (!pa)
+ err_oom();
+
+ if (fdisk_assign_device(cxt, device, 0))
+ err(EXIT_FAILURE, "failed to assign device");
+ if (fdisk_create_disklabel(cxt, label))
+ err(EXIT_FAILURE, "failed to create disk label");
+
+ sectorsize = fdisk_get_sector_size(cxt);
+
+ fdisk_disable_dialogs(cxt, 1);
+
+ while (optind < argc) {
+ int rc;
+ uint64_t size;
+ const char *str = argv[optind];
+
+ /* defaults */
+ fdisk_partition_start_follow_default(pa, 1);
+ fdisk_partition_end_follow_default(pa, 1);
+ fdisk_partition_partno_follow_default(pa, 1);
+
+ /* set size */
+ if (isdigit(*str)) {
+ size = strtosize_or_err(argv[optind], "failed to parse partition size");
+ fdisk_partition_set_size(pa, size / sectorsize);
+ fdisk_partition_end_follow_default(pa, 0);
+
+ } else if (*str == '-') {
+ fdisk_partition_end_follow_default(pa, 1);
+ }
+
+ if (fdisk_is_label(cxt, DOS)) {
+ /* For MBR we want to avoid primary/logical dialog.
+ * This is possible by explicitly specified partition
+ * number, <4 means primary, >=4 means logical.
+ */
+ if (!nopartno) {
+ fdisk_partition_partno_follow_default(pa, 0);
+ fdisk_partition_set_partno(pa, n);
+ }
+
+ /* Make sure last primary partition is extended if user
+ * wants more than 4 partitions.
+ */
+ if (n == 3 && optind + 1 < argc) {
+ struct fdisk_parttype *type =
+ fdisk_label_parse_parttype(
+ fdisk_get_label(cxt, NULL), "05");
+ if (!type)
+ err_oom();
+ fdisk_partition_set_type(pa, type);
+ fdisk_unref_parttype(type);
+ }
+ }
+
+ rc = fdisk_add_partition(cxt, pa, NULL);
+ if (rc) {
+ errno = -rc;
+ errx(EXIT_FAILURE, "failed to add #%d partition", n + 1);
+ }
+
+ fdisk_reset_partition(pa);
+ optind++;
+ n++;
+ }
+
+ if (fdisk_write_disklabel(cxt))
+ err(EXIT_FAILURE, "failed to write disk label");
+
+ fdisk_deassign_device(cxt, 1);
+ fdisk_unref_context(cxt);
+ fdisk_unref_partition(pa);
+
+ return EXIT_SUCCESS;
+}