]> git.ipfire.org Git - thirdparty/util-linux.git/blame - libfdisk/samples/mkpart-fullspec.c
wipefs: add --lock and LOCK_BLOCK_DEVICE
[thirdparty/util-linux.git] / libfdisk / samples / mkpart-fullspec.c
CommitLineData
5fb427c8
KZ
1/*
2 * Copyright (C) 2017 Karel Zak <kzak@redhat.com>
3 *
4 * This file may be redistributed under the terms of the
5 * GNU Lesser General Public License.
6 *
7 *
8 * Libfdisk sample to create partitions by specify all required partition
11026083 9 * properties (partno, start and size). The default is only partition type
5fb427c8
KZ
10 * (except MBR where 4th partition is extended).
11 */
12#include <stdlib.h>
13#include <unistd.h>
14#include <string.h>
15#include <errno.h>
16#include <sys/types.h>
17#include <sys/stat.h>
18#include <dirent.h>
19#include <getopt.h>
20
21#include "c.h"
22#include "nls.h"
23#include "strutils.h"
24#include "xalloc.h"
25
26#include "libfdisk.h"
27
28static int ask_callback(struct fdisk_context *cxt __attribute__((__unused__)),
29 struct fdisk_ask *ask,
30 void *data)
31{
32 switch(fdisk_ask_get_type(ask)) {
33 case FDISK_ASKTYPE_INFO:
34 fputs(fdisk_ask_print_get_mesg(ask), stdout);
35 fputc('\n', stdout);
36 break;
37 case FDISK_ASKTYPE_WARNX:
38 fflush(stdout);
39 fputs(fdisk_ask_print_get_mesg(ask), stderr);
40 fputc('\n', stderr);
41 break;
42 case FDISK_ASKTYPE_WARN:
43 fflush(stdout);
44 fputs(fdisk_ask_print_get_mesg(ask), stderr);
45 errno = fdisk_ask_print_get_errno(ask);
46 fprintf(stderr, ": %m\n");
47 break;
48 default:
49 break;
50 }
51 return 0;
52}
53
54int main(int argc, char *argv[])
55{
56 struct fdisk_context *cxt;
57 struct fdisk_partition *pa;
58 const char *label = NULL, *device = NULL;
59 int c;
ea369079 60 size_t n = 1;
5fb427c8
KZ
61
62 static const struct option longopts[] = {
63 { "label", required_argument, NULL, 'x' },
64 { "device", required_argument, NULL, 'd' },
65 { "help", no_argument, NULL, 'h' },
66 { NULL, 0, NULL, 0 },
67 };
68
69 setlocale(LC_ALL, ""); /* just to have enable UTF8 chars */
70
71 fdisk_init_debug(0);
72
73 while((c = getopt_long(argc, argv, "x:d:h", longopts, NULL)) != -1) {
74 switch(c) {
75 case 'x':
76 label = optarg;
77 break;
78 case 'd':
79 device = optarg;
80 break;
81 case 'h':
ea369079 82 printf("%s [options] -- <partno,start,size> ...", program_invocation_short_name);
5fb427c8
KZ
83 fputs(USAGE_SEPARATOR, stdout);
84 puts("Make disklabel and partitions.");
ea369079 85 puts(" <partno> 1..n (4th is extended for MBR), or '-' for default");
5fb427c8
KZ
86 puts(" <start> partition start offset in sectors");
87 puts(" <size> partition size in sectors");
88 fputs(USAGE_OPTIONS, stdout);
89 puts(" -x, --label <dos,gpt,...> disk label type (default MBR)");
90 puts(" -d, --device <path> block device");
91 puts(" -h, --help this help");
92 fputs(USAGE_SEPARATOR, stdout);
93 return EXIT_SUCCESS;
94 }
95 }
96
97 if (!device)
98 errx(EXIT_FAILURE, "no device specified");
99 if (!label)
100 label = "dos";
101
102 cxt = fdisk_new_context();
103 if (!cxt)
104 err_oom();
105 fdisk_set_ask(cxt, ask_callback, NULL);
106
107 pa = fdisk_new_partition();
108 if (!pa)
109 err_oom();
110
111 if (fdisk_assign_device(cxt, device, 0))
112 err(EXIT_FAILURE, "failed to assign device");
f2b6a0c0 113 if (fdisk_create_disklabel(cxt, label))
5fb427c8
KZ
114 err(EXIT_FAILURE, "failed to create disk label");
115
ea369079
KZ
116 fdisk_disable_dialogs(cxt, 1);
117
5fb427c8
KZ
118 while (optind < argc) {
119 int rc;
120 unsigned int partno = 0;
121 uint64_t start = 0, size = 0;
122 const char *str = argv[optind];
123
ea369079 124 fdisk_reset_partition(pa);
5fb427c8
KZ
125 fdisk_partition_end_follow_default(pa, 0);
126
ea369079
KZ
127 if (*str == '-') {
128 /* partno unspecified */
129 if (sscanf(str, "-,%"SCNu64",%"SCNu64"", &start, &size) != 2)
73afd3f8 130 errx(EXIT_FAILURE, "failed to parse %s", str);
ea369079
KZ
131 fdisk_partition_partno_follow_default(pa, 1);
132 fdisk_partition_unset_partno(pa);
133 } else {
134 /* partno specified */
135 if (sscanf(str, "%u,%"SCNu64",%"SCNu64"", &partno, &start, &size) != 3)
73afd3f8 136 errx(EXIT_FAILURE, "failed to parse %s", str);
ea369079
KZ
137
138 fdisk_partition_partno_follow_default(pa, 0);
139 fdisk_partition_set_partno(pa, partno - 1); /* library uses 0..n */
140 }
141
5fb427c8
KZ
142 fdisk_partition_set_start(pa, start);
143 fdisk_partition_set_size(pa, size);
144
ea369079 145 if (fdisk_partition_has_partno(pa))
b161f810 146 fprintf(stdout, "Requested partition: <partno=%zu,start=%ju,size=%ju>\n",
ea369079
KZ
147 fdisk_partition_get_partno(pa),
148 (uintmax_t) fdisk_partition_get_start(pa),
149 (uintmax_t) fdisk_partition_get_size(pa));
150 else
b161f810 151 fprintf(stdout, "Requested partition: <partno=<default>,start=%ju,size=%ju>\n",
ea369079
KZ
152 (uintmax_t) fdisk_partition_get_start(pa),
153 (uintmax_t) fdisk_partition_get_size(pa));
5fb427c8
KZ
154
155 if (fdisk_is_label(cxt, DOS)) {
156 /* Make sure last primary partition is extended if user
157 * wants more than 4 partitions.
158 */
ea369079
KZ
159 if ((partno == 4 || (n == 4 && !fdisk_partition_has_partno(pa)))
160 && optind + 1 < argc) {
5fb427c8
KZ
161 struct fdisk_parttype *type =
162 fdisk_label_parse_parttype(
163 fdisk_get_label(cxt, NULL), "05");
164 if (!type)
165 err_oom();
166 fdisk_partition_set_type(pa, type);
167 fdisk_unref_parttype(type);
168 }
169 }
170
171 rc = fdisk_add_partition(cxt, pa, NULL);
172 if (rc) {
173 errno = -rc;
ea369079
KZ
174 errx(EXIT_FAILURE, "failed to add #%zu partition",
175 fdisk_partition_has_partno(pa) ?
176 fdisk_partition_get_partno(pa) + 1: n);
5fb427c8
KZ
177 }
178
179 fdisk_reset_partition(pa);
180 optind++;
ea369079 181 n++;
5fb427c8
KZ
182 }
183
184 if (fdisk_write_disklabel(cxt))
185 err(EXIT_FAILURE, "failed to write disk label");
186
187 fdisk_deassign_device(cxt, 1);
188 fdisk_unref_context(cxt);
189 fdisk_unref_partition(pa);
190
191 return EXIT_SUCCESS;
192}