]> git.ipfire.org Git - thirdparty/util-linux.git/blob - libfdisk/samples/mkpart.c
tests: do not use plain 0 as NULL [smatch scan]
[thirdparty/util-linux.git] / libfdisk / samples / mkpart.c
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 #include <stdlib.h>
8 #include <unistd.h>
9 #include <string.h>
10 #include <errno.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <dirent.h>
14 #include <getopt.h>
15
16 #include "c.h"
17 #include "nls.h"
18 #include "strutils.h"
19 #include "xalloc.h"
20
21 #include "libfdisk.h"
22
23 static int ask_callback(struct fdisk_context *cxt __attribute__((__unused__)),
24 struct fdisk_ask *ask,
25 void *data)
26 {
27 switch(fdisk_ask_get_type(ask)) {
28 case FDISK_ASKTYPE_INFO:
29 fputs(fdisk_ask_print_get_mesg(ask), stdout);
30 fputc('\n', stdout);
31 break;
32 case FDISK_ASKTYPE_WARNX:
33 fflush(stdout);
34 fputs(fdisk_ask_print_get_mesg(ask), stderr);
35 fputc('\n', stderr);
36 break;
37 case FDISK_ASKTYPE_WARN:
38 fflush(stdout);
39 fputs(fdisk_ask_print_get_mesg(ask), stderr);
40 errno = fdisk_ask_print_get_errno(ask);
41 fprintf(stderr, ": %m\n");
42 break;
43 default:
44 break;
45 }
46 return 0;
47 }
48
49 int main(int argc, char *argv[])
50 {
51 struct fdisk_context *cxt;
52 struct fdisk_partition *pa;
53 const char *label = NULL, *device = NULL;
54 int n = 0, c;
55 unsigned int sectorsize;
56
57 static const struct option longopts[] = {
58 { "label", required_argument, NULL, 'x' },
59 { "device", required_argument, NULL, 'd' },
60 { "help", no_argument, NULL, 'h' },
61 { NULL, 0, NULL, 0 },
62 };
63
64 setlocale(LC_ALL, ""); /* just to have enable UTF8 chars */
65
66 fdisk_init_debug(0);
67
68 while((c = getopt_long(argc, argv, "x:d:h", longopts, NULL)) != -1) {
69 switch(c) {
70 case 'x':
71 label = optarg;
72 break;
73 case 'd':
74 device = optarg;
75 break;
76 case 'h':
77 printf("%s [options] <size> ...", program_invocation_short_name);
78 fputs(USAGE_SEPARATOR, stdout);
79 fputs("Make disklabel and partitions.\n", stdout);
80 fputs(USAGE_OPTIONS, stdout);
81 fputs(" -x, --label <dos,gpt,...> disk label type\n", stdout);
82 fputs(" -d, --device <path> block device\n", stdout);
83 fputs(" -h, --help this help\n", stdout);
84 fputs(USAGE_SEPARATOR, stdout);
85 return EXIT_SUCCESS;
86 }
87 }
88
89 if (!device)
90 errx(EXIT_FAILURE, "no device specified");
91 if (!label)
92 label = "dos";
93
94 cxt = fdisk_new_context();
95 if (!cxt)
96 err_oom();
97 fdisk_set_ask(cxt, ask_callback, NULL);
98
99 pa = fdisk_new_partition();
100 if (!pa)
101 err_oom();
102
103 if (fdisk_assign_device(cxt, device, 0))
104 err(EXIT_FAILURE, "failed to assign device");
105 if (fdisk_create_disklabel(cxt, "dos"))
106 err(EXIT_FAILURE, "failed to create disk label");
107
108 sectorsize = fdisk_get_sector_size(cxt);
109
110 while (optind < argc) {
111 int rc;
112 uint64_t size;
113 const char *str = argv[optind];
114
115 /* defaults */
116 fdisk_partition_start_follow_default(pa, 1);
117 fdisk_partition_end_follow_default(pa, 1);
118
119 /* set size */
120 if (isdigit(*str)) {
121 size = strtosize_or_err(argv[optind], "failed to parse partition size");
122 fdisk_partition_set_size(pa, size / sectorsize);
123 fdisk_partition_end_follow_default(pa, 0);
124
125 } else if (*str == '-') {
126 fdisk_partition_end_follow_default(pa, 1);
127 }
128
129 if (fdisk_is_label(cxt, DOS)) {
130 /* For MBR we want to avoid primary/logical dialog.
131 * This is possible by explicitly specified partition
132 * number, <4 means primary, >=4 means logical.
133 */
134 fdisk_partition_partno_follow_default(pa, 0);
135 fdisk_partition_set_partno(pa, n);
136
137 /* Make sure last primary partition is extended if user
138 * wants more than 4 partitions.
139 */
140 if (n == 3 && optind + 1 < argc) {
141 struct fdisk_parttype *type =
142 fdisk_label_parse_parttype(
143 fdisk_get_label(cxt, NULL), "05");
144 if (!type)
145 err_oom();
146 fdisk_partition_set_type(pa, type);
147 fdisk_unref_parttype(type);
148 }
149 } else
150 fdisk_partition_partno_follow_default(pa, 1);
151
152
153 rc = fdisk_add_partition(cxt, pa, NULL);
154 if (rc) {
155 errno = -rc;
156 err(EXIT_FAILURE, "failed to add #%d partition", n + 1);
157 }
158
159 fdisk_reset_partition(pa);
160 optind++;
161 n++;
162 }
163
164 if (fdisk_write_disklabel(cxt))
165 err(EXIT_FAILURE, "failed to write disk label");
166
167 fdisk_deassign_device(cxt, 1);
168 fdisk_unref_context(cxt);
169 fdisk_unref_partition(pa);
170
171 return EXIT_SUCCESS;
172 }