]>
Commit | Line | Data |
---|---|---|
3f0ac587 | 1 | /* |
6dbe3af9 | 2 | * Copyright (C) 1992 A. V. Le Blanc (LeBlanc@mcc.ac.uk) |
38b36353 | 3 | * Copyright (C) 2012 Davidlohr Bueso <dave@gnu.org> |
6dbe3af9 | 4 | * |
3f0ac587 KZ |
5 | * Copyright (C) 2007-2013 Karel Zak <kzak@redhat.com> |
6 | * | |
6dbe3af9 KZ |
7 | * This program is free software. You can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License as | |
9 | * published by the Free Software Foundation: either version 1 or | |
10 | * (at your option) any later version. | |
6dbe3af9 | 11 | */ |
6dbe3af9 KZ |
12 | #include <unistd.h> |
13 | #include <stdio.h> | |
14 | #include <stdlib.h> | |
15 | #include <string.h> | |
16 | #include <fcntl.h> | |
17 | #include <ctype.h> | |
6dbe3af9 | 18 | #include <errno.h> |
2b6fc908 | 19 | #include <getopt.h> |
2b6fc908 | 20 | #include <sys/stat.h> |
f26873dc | 21 | #include <sys/time.h> |
bb6aacfe | 22 | #include <time.h> |
ee5355e0 | 23 | #include <limits.h> |
6dbe3af9 | 24 | |
3f0ac587 | 25 | #include "c.h" |
52b38677 | 26 | #include "xalloc.h" |
22853e4a | 27 | #include "nls.h" |
e66ac5d3 | 28 | #include "rpmatch.h" |
810f986b | 29 | #include "blkdev.h" |
b8d22034 | 30 | #include "mbsalign.h" |
726f69e2 | 31 | #include "fdisk.h" |
929f243f | 32 | #include "wholedisk.h" |
6bec8710 KZ |
33 | #include "pathnames.h" |
34 | #include "canonicalize.h" | |
20aa2570 | 35 | #include "strutils.h" |
b2d28533 | 36 | #include "closestream.h" |
5c36a0eb | 37 | |
b4bfbadd | 38 | #include "pt-sun.h" /* to toggle flags */ |
5c36a0eb | 39 | |
48d7b13a | 40 | #ifdef HAVE_LINUX_COMPILER_H |
3f0ac587 | 41 | # include <linux/compiler.h> |
48d7b13a KZ |
42 | #endif |
43 | #ifdef HAVE_LINUX_BLKPG_H | |
3f0ac587 | 44 | # include <linux/blkpg.h> |
7eda085c | 45 | #endif |
6dbe3af9 | 46 | |
fcd9a2a4 KZ |
47 | #include "fdisk.h" |
48 | ||
3f0ac587 KZ |
49 | static void __attribute__ ((__noreturn__)) usage(FILE *out) |
50 | { | |
51 | fputs(USAGE_HEADER, out); | |
52 | ||
53 | fprintf(out, | |
54 | _(" %1$s [options] <disk> change partition table\n" | |
55 | " %1$s [options] -l <disk> list partition table(s)\n" | |
9564e46c | 56 | " %1$s -s <partition> give partition size(s) in blocks (deprecated)\n"), |
3f0ac587 KZ |
57 | program_invocation_short_name); |
58 | ||
59 | fputs(USAGE_OPTIONS, out); | |
60 | fputs(_(" -b <size> sector size (512, 1024, 2048 or 4096)\n"), out); | |
61 | fputs(_(" -c[=<mode>] compatible mode: 'dos' or 'nondos' (default)\n"), out); | |
62 | fputs(_(" -h print this help text\n"), out); | |
80a1712f KZ |
63 | fputs(_(" -c[=<mode>] compatible mode: 'dos' or 'nondos' (default)\n"), out); |
64 | fputs(_(" -L[=<when>] colorize output (auto, always or never)\n"), out); | |
3f0ac587 KZ |
65 | fputs(_(" -u[=<unit>] display units: 'cylinders' or 'sectors' (default)\n"), out); |
66 | fputs(_(" -v print program version\n"), out); | |
67 | fputs(_(" -C <number> specify the number of cylinders\n"), out); | |
68 | fputs(_(" -H <number> specify the number of heads\n"), out); | |
69 | fputs(_(" -S <number> specify the number of sectors per track\n"), out); | |
70 | ||
71 | fprintf(out, USAGE_MAN_TAIL("fdisk(8)")); | |
72 | exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); | |
73 | } | |
74 | ||
7b575fcc | 75 | void list_partition_types(struct fdisk_context *cxt) |
6dbe3af9 | 76 | { |
7b575fcc | 77 | struct fdisk_parttype *types; |
76f17cf2 | 78 | size_t ntypes = 0; |
6dbe3af9 | 79 | |
7b575fcc KZ |
80 | if (!cxt || !cxt->label || !cxt->label->parttypes) |
81 | return; | |
2b6fc908 | 82 | |
7b575fcc | 83 | types = cxt->label->parttypes; |
76f17cf2 | 84 | ntypes = cxt->label->nparttypes; |
6dbe3af9 | 85 | |
7b575fcc KZ |
86 | if (types[0].typestr == NULL) { |
87 | /* | |
88 | * Prints in 4 columns in format <hex> <name> | |
89 | */ | |
76f17cf2 KZ |
90 | size_t last[4], done = 0, next = 0, size; |
91 | int i; | |
b8d22034 | 92 | |
76f17cf2 KZ |
93 | size = ntypes; |
94 | if (types[ntypes - 1].name == NULL) | |
95 | size--; | |
7b575fcc KZ |
96 | |
97 | for (i = 3; i >= 0; i--) | |
98 | last[3 - i] = done += (size + i - done) / (i + 1); | |
99 | i = done = 0; | |
100 | ||
101 | do { | |
102 | #define NAME_WIDTH 15 | |
103 | char name[NAME_WIDTH * MB_LEN_MAX]; | |
104 | size_t width = NAME_WIDTH; | |
105 | struct fdisk_parttype *t = &types[next]; | |
106 | size_t ret; | |
107 | ||
76f17cf2 KZ |
108 | if (t->name) { |
109 | printf("%c%2x ", i ? ' ' : '\n', t->type); | |
110 | ret = mbsalign(_(t->name), name, sizeof(name), | |
111 | &width, MBS_ALIGN_LEFT, 0); | |
7b575fcc | 112 | |
76f17cf2 KZ |
113 | if (ret == (size_t)-1 || ret >= sizeof(name)) |
114 | printf("%-15.15s", _(t->name)); | |
115 | else | |
116 | fputs(name, stdout); | |
117 | } | |
7b575fcc KZ |
118 | |
119 | next = last[i++] + done; | |
120 | if (i > 3 || next >= last[i]) { | |
121 | i = 0; | |
122 | next = ++done; | |
123 | } | |
124 | } while (done < last[0]); | |
125 | ||
126 | } else { | |
127 | /* | |
128 | * Prints 1 column in format <idx> <name> <typestr> | |
129 | */ | |
130 | struct fdisk_parttype *t; | |
76f17cf2 | 131 | size_t i; |
7b575fcc | 132 | |
76f17cf2 KZ |
133 | for (i = 0, t = types; t && i < ntypes; t++, i++) { |
134 | if (t->name) | |
135 | printf("%3zu %-30s %s\n", i + 1, | |
136 | t->name, t->typestr); | |
137 | } | |
7b575fcc | 138 | } |
6dbe3af9 KZ |
139 | putchar('\n'); |
140 | } | |
141 | ||
f02fecd1 | 142 | void toggle_dos_compatibility_flag(struct fdisk_context *cxt) |
852ce62b KZ |
143 | { |
144 | struct fdisk_label *lb = fdisk_context_get_label(cxt, "dos"); | |
145 | int flag; | |
146 | ||
147 | if (!lb) | |
148 | return; | |
149 | ||
150 | flag = !fdisk_dos_is_compatible(lb); | |
151 | ||
152 | if (flag) | |
278f63c0 | 153 | printf(_("DOS Compatibility flag is set (DEPRECATED!)\n")); |
edd7b958 | 154 | else |
7eda085c | 155 | printf(_("DOS Compatibility flag is not set\n")); |
edd7b958 | 156 | |
852ce62b KZ |
157 | fdisk_dos_enable_compatible(lb, flag); |
158 | ||
159 | if (fdisk_is_disklabel(cxt, DOS)) | |
160 | fdisk_reset_alignment(cxt); | |
6dbe3af9 KZ |
161 | } |
162 | ||
27ddd4f1 | 163 | void change_partition_type(struct fdisk_context *cxt) |
e53ced85 | 164 | { |
641a75ca | 165 | size_t i; |
559d921e | 166 | struct fdisk_parttype *t, *org_t; |
6dbe3af9 | 167 | |
e3661531 KZ |
168 | assert(cxt); |
169 | assert(cxt->label); | |
170 | ||
641a75ca | 171 | if (fdisk_ask_partnum(cxt, &i, FALSE)) |
24f4bbff | 172 | return; |
2b6fc908 | 173 | |
010186f2 KZ |
174 | org_t = t = fdisk_get_partition_type(cxt, i); |
175 | if (!t) | |
641a75ca | 176 | printf(_("Partition %zu does not exist yet!\n"), i + 1); |
010186f2 | 177 | |
02460b8a | 178 | else do { |
950edd1a | 179 | t = ask_partition_type(cxt); |
559d921e KZ |
180 | if (!t) |
181 | continue; | |
182 | ||
02460b8a | 183 | if (fdisk_set_partition_type(cxt, i, t) == 0) { |
02460b8a KZ |
184 | printf (_("Changed type of partition '%s' to '%s'\n"), |
185 | org_t ? org_t->name : _("Unknown"), | |
186 | t ? t->name : _("Unknown")); | |
187 | } else { | |
641a75ca | 188 | printf (_("Type of partition %zu is unchanged: %s\n"), |
02460b8a KZ |
189 | i + 1, |
190 | org_t ? org_t->name : _("Unknown")); | |
6dbe3af9 | 191 | } |
02460b8a KZ |
192 | break; |
193 | } while (1); | |
559d921e KZ |
194 | |
195 | fdisk_free_parttype(t); | |
196 | fdisk_free_parttype(org_t); | |
6dbe3af9 KZ |
197 | } |
198 | ||
89309968 | 199 | void list_disk_geometry(struct fdisk_context *cxt) |
21fe3dde KZ |
200 | { |
201 | char *id = NULL; | |
9af73f84 KZ |
202 | uint64_t bytes = cxt->total_sectors * cxt->sector_size; |
203 | char *strsz = size_to_human_string(SIZE_SUFFIX_SPACE | |
204 | | SIZE_SUFFIX_3LETTER, bytes); | |
205 | ||
a41309c2 | 206 | fdisk_info(cxt, _("Disk %s: %s, %llu bytes, %llu sectors"), |
9af73f84 KZ |
207 | cxt->dev_path, strsz, bytes, cxt->total_sectors); |
208 | free(strsz); | |
b1b1a7b7 | 209 | |
0b52b94c | 210 | if (fdisk_require_geometry(cxt)) |
9af73f84 KZ |
211 | fdisk_info(cxt, _("Geometry: %d heads, %llu sectors/track, %llu cylinders"), |
212 | cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders); | |
b1b1a7b7 | 213 | |
9af73f84 | 214 | fdisk_info(cxt, _("Units: %s of %d * %ld = %ld bytes"), |
ec10aa67 KZ |
215 | fdisk_context_get_unit(cxt, PLURAL), |
216 | fdisk_context_get_units_per_sector(cxt), | |
217 | cxt->sector_size, | |
218 | fdisk_context_get_units_per_sector(cxt) * cxt->sector_size); | |
05dc9645 | 219 | |
9af73f84 | 220 | fdisk_info(cxt, _("Sector size (logical/physical): %lu bytes / %lu bytes"), |
e53ced85 | 221 | cxt->sector_size, cxt->phy_sector_size); |
9af73f84 | 222 | fdisk_info(cxt, _("I/O size (minimum/optimal): %lu bytes / %lu bytes"), |
e53ced85 DB |
223 | cxt->min_io_size, cxt->io_size); |
224 | if (cxt->alignment_offset) | |
9af73f84 KZ |
225 | fdisk_info(cxt, _("Alignment offset: %lu bytes"), |
226 | cxt->alignment_offset); | |
b546d442 | 227 | if (fdisk_dev_has_disklabel(cxt)) |
9af73f84 | 228 | fdisk_info(cxt, _("Disk label type: %s"), cxt->label->name); |
21fe3dde KZ |
229 | |
230 | if (fdisk_get_disklabel_id(cxt, &id) == 0 && id) | |
9af73f84 | 231 | fdisk_info(cxt, _("Disk identifier: %s"), id); |
5c36a0eb KZ |
232 | } |
233 | ||
6dbe3af9 KZ |
234 | |
235 | #define MAX_PER_LINE 16 | |
22853e4a | 236 | static void |
e53ced85 | 237 | print_buffer(struct fdisk_context *cxt, unsigned char pbuffer[]) { |
e99da659 | 238 | unsigned int i, l; |
6dbe3af9 | 239 | |
e53ced85 | 240 | for (i = 0, l = 0; i < cxt->sector_size; i++, l++) { |
6dbe3af9 KZ |
241 | if (l == 0) |
242 | printf("0x%03X:", i); | |
be97c5f3 | 243 | printf(" %02X", pbuffer[i]); |
6dbe3af9 KZ |
244 | if (l == MAX_PER_LINE - 1) { |
245 | printf("\n"); | |
246 | l = -1; | |
247 | } | |
248 | } | |
249 | if (l > 0) | |
250 | printf("\n"); | |
251 | printf("\n"); | |
252 | } | |
253 | ||
89309968 | 254 | void print_raw(struct fdisk_context *cxt) |
e53ced85 | 255 | { |
e3661531 KZ |
256 | assert(cxt); |
257 | assert(cxt->label); | |
6dbe3af9 | 258 | |
e53ced85 | 259 | printf(_("Device: %s\n"), cxt->dev_path); |
ff5775bd DB |
260 | if (fdisk_is_disklabel(cxt, SUN) || |
261 | fdisk_is_disklabel(cxt, SGI) || | |
af0df606 KZ |
262 | fdisk_is_disklabel(cxt, GPT) || |
263 | fdisk_is_disklabel(cxt, DOS)) | |
67987b47 | 264 | print_buffer(cxt, cxt->firstsector); |
e3661531 | 265 | |
af0df606 | 266 | /* TODO: print also EBR (extended partition) buffer */ |
6dbe3af9 KZ |
267 | } |
268 | ||
3b622ddd DB |
269 | static int is_ide_cdrom_or_tape(char *device) |
270 | { | |
271 | int fd, ret; | |
2b6fc908 | 272 | |
1c6b3378 | 273 | if ((fd = open(device, O_RDONLY)) < 0) |
e8f26419 | 274 | return 0; |
3b622ddd | 275 | ret = blkdev_is_cdrom(fd); |
2b6fc908 | 276 | |
3b622ddd DB |
277 | close(fd); |
278 | return ret; | |
2b6fc908 KZ |
279 | } |
280 | ||
6aa2ed3b | 281 | static void print_device_pt(struct fdisk_context *cxt, char *device) |
e27b42d5 | 282 | { |
4e0e8253 | 283 | if (fdisk_context_assign_device(cxt, device, 1) != 0) /* read-only */ |
289dcc90 | 284 | err(EXIT_FAILURE, _("cannot open %s"), device); |
823f0fd1 | 285 | |
5e860870 KZ |
286 | list_disk_geometry(cxt); |
287 | ||
b4fb2a61 | 288 | if (fdisk_dev_has_disklabel(cxt)) |
5e860870 | 289 | fdisk_list_disklabel(cxt); |
6dbe3af9 KZ |
290 | } |
291 | ||
6aa2ed3b | 292 | static void print_all_devices_pt(struct fdisk_context *cxt) |
ea4824f1 | 293 | { |
6aa2ed3b KZ |
294 | FILE *f; |
295 | char line[128 + 1]; | |
296 | ||
297 | f = fopen(_PATH_PROC_PARTITIONS, "r"); | |
298 | if (!f) { | |
299 | warn(_("cannot open %s"), _PATH_PROC_PARTITIONS); | |
eb63b9b8 KZ |
300 | return; |
301 | } | |
302 | ||
6aa2ed3b KZ |
303 | while (fgets(line, sizeof(line), f)) { |
304 | char ptname[128 + 1], devname[256]; | |
305 | ||
306 | if (sscanf(line, " %*d %*d %*d %128[^\n ]", ptname) != 4) | |
eb63b9b8 | 307 | continue; |
6aa2ed3b | 308 | |
c07ebfa1 | 309 | snprintf(devname, sizeof(devname), "/dev/%s", ptname); |
6bec8710 KZ |
310 | if (is_whole_disk(devname)) { |
311 | char *cn = canonicalize_path(devname); | |
312 | if (cn) { | |
0c48d371 | 313 | if (!is_ide_cdrom_or_tape(cn)) |
6aa2ed3b | 314 | print_device_pt(cxt, cn); |
6bec8710 KZ |
315 | free(cn); |
316 | } | |
317 | } | |
eb63b9b8 | 318 | } |
6aa2ed3b | 319 | fclose(f); |
eb63b9b8 KZ |
320 | } |
321 | ||
50dec1eb | 322 | static sector_t get_dev_blocks(char *dev) |
6da365de DB |
323 | { |
324 | int fd; | |
50dec1eb | 325 | sector_t size; |
6da365de DB |
326 | |
327 | if ((fd = open(dev, O_RDONLY)) < 0) | |
289dcc90 | 328 | err(EXIT_FAILURE, _("cannot open %s"), dev); |
7737f698 DB |
329 | if (blkdev_get_sectors(fd, &size) == -1) { |
330 | close(fd); | |
331 | err(EXIT_FAILURE, _("BLKGETSIZE ioctl failed on %s"), dev); | |
332 | } | |
6da365de DB |
333 | close(fd); |
334 | return size/2; | |
335 | } | |
336 | ||
5b72b3dd KZ |
337 | enum { |
338 | ACT_FDISK = 0, /* default */ | |
339 | ACT_LIST, | |
340 | ACT_SHOWSIZE | |
341 | }; | |
342 | ||
e1144767 DB |
343 | int main(int argc, char **argv) |
344 | { | |
5b72b3dd | 345 | int i, c, act = ACT_FDISK; |
80a1712f | 346 | int colormode = UL_COLORMODE_AUTO; |
4e0e8253 | 347 | struct fdisk_context *cxt; |
2b6fc908 | 348 | |
7eda085c KZ |
349 | setlocale(LC_ALL, ""); |
350 | bindtextdomain(PACKAGE, LOCALEDIR); | |
351 | textdomain(PACKAGE); | |
b2d28533 | 352 | atexit(close_stdout); |
2b6fc908 | 353 | |
4e0e8253 KZ |
354 | fdisk_init_debug(0); |
355 | cxt = fdisk_new_context(); | |
356 | if (!cxt) | |
357 | err(EXIT_FAILURE, _("failed to allocate libfdisk context")); | |
358 | ||
416c43a9 KZ |
359 | fdisk_context_set_ask(cxt, ask_callback, NULL); |
360 | ||
80a1712f | 361 | while ((c = getopt(argc, argv, "b:c::C:hH:lL::sS:u::vV")) != -1) { |
2b6fc908 KZ |
362 | switch (c) { |
363 | case 'b': | |
6bcd192c KZ |
364 | { |
365 | size_t sz = strtou32_or_err(optarg, | |
366 | _("invalid sector size argument")); | |
367 | if (sz != 512 && sz != 1024 && sz != 2048 && sz != 4096) | |
7c1db6b4 | 368 | usage(stderr); |
6bcd192c | 369 | fdisk_save_user_sector_size(cxt, sz, sz); |
2b6fc908 | 370 | break; |
6bcd192c | 371 | } |
0e6f4a20 | 372 | case 'C': |
1653f0b0 KZ |
373 | fdisk_save_user_geometry(cxt, |
374 | strtou32_or_err(optarg, | |
375 | _("invalid cylinders argument")), | |
376 | 0, 0); | |
0e6f4a20 | 377 | break; |
78498b7b | 378 | case 'c': |
852ce62b | 379 | if (optarg) { |
2b0bc17b KZ |
380 | /* this setting is independent on the current |
381 | * actively used label */ | |
5b72b3dd | 382 | struct fdisk_label *lb = fdisk_context_get_label(cxt, "dos"); |
852ce62b KZ |
383 | if (!lb) |
384 | err(EXIT_FAILURE, _("not found DOS label driver")); | |
385 | if (strcmp(optarg, "=dos") == 0) | |
386 | fdisk_dos_enable_compatible(lb, TRUE); | |
387 | else if (strcmp(optarg, "=nondos") == 0) | |
388 | fdisk_dos_enable_compatible(lb, FALSE); | |
389 | else | |
390 | usage(stderr); | |
391 | } | |
392 | /* use default if no optarg specified */ | |
78498b7b | 393 | break; |
0e6f4a20 | 394 | case 'H': |
1653f0b0 KZ |
395 | fdisk_save_user_geometry(cxt, 0, |
396 | strtou32_or_err(optarg, | |
397 | _("invalid heads argument")), | |
398 | 0); | |
0e6f4a20 KZ |
399 | break; |
400 | case 'S': | |
1653f0b0 KZ |
401 | fdisk_save_user_geometry(cxt, 0, 0, |
402 | strtou32_or_err(optarg, | |
403 | _("invalid sectors argument"))); | |
0e6f4a20 | 404 | break; |
2b6fc908 | 405 | case 'l': |
5b72b3dd | 406 | act = ACT_LIST; |
2b6fc908 | 407 | break; |
80a1712f KZ |
408 | case 'L': |
409 | if (optarg) | |
410 | colormode = colormode_or_err(optarg, | |
411 | _("unsupported color mode")); | |
412 | break; | |
2b6fc908 | 413 | case 's': |
5b72b3dd | 414 | act = ACT_SHOWSIZE; |
2b6fc908 KZ |
415 | break; |
416 | case 'u': | |
ec10aa67 KZ |
417 | if (optarg && *optarg == '=') |
418 | optarg++; | |
419 | if (fdisk_context_set_unit(cxt, optarg) != 0) | |
7c1db6b4 | 420 | usage(stderr); |
2b6fc908 | 421 | break; |
22853e4a | 422 | case 'V': |
2b6fc908 | 423 | case 'v': |
a2482eb3 DB |
424 | printf(UTIL_LINUX_VERSION); |
425 | return EXIT_SUCCESS; | |
e1144767 DB |
426 | case 'h': |
427 | usage(stdout); | |
2b6fc908 | 428 | default: |
7c1db6b4 | 429 | usage(stderr); |
2b6fc908 | 430 | } |
6dbe3af9 | 431 | } |
2b6fc908 | 432 | |
6bcd192c KZ |
433 | if (argc-optind != 1 && fdisk_has_user_device_properties(cxt)) |
434 | warnx(_("The device properties (sector size and geometry) should" | |
435 | " be used with one specified device only.")); | |
7eda085c | 436 | |
5b72b3dd KZ |
437 | switch (act) { |
438 | case ACT_LIST: | |
c10937dc | 439 | fdisk_context_enable_listonly(cxt, 1); |
2b6fc908 KZ |
440 | if (argc > optind) { |
441 | int k; | |
c129767e | 442 | for (k = optind; k < argc; k++) |
6aa2ed3b | 443 | print_device_pt(cxt, argv[k]); |
ea4824f1 | 444 | } else |
6aa2ed3b | 445 | print_all_devices_pt(cxt); |
5b72b3dd | 446 | break; |
2b6fc908 | 447 | |
5b72b3dd | 448 | case ACT_SHOWSIZE: |
9564e46c | 449 | /* deprecated */ |
5b72b3dd | 450 | if (argc - optind <= 0) |
7c1db6b4 | 451 | usage(stderr); |
2b6fc908 | 452 | |
6da365de | 453 | for (i = optind; i < argc; i++) { |
5b72b3dd | 454 | if (argc - optind == 1) |
6da365de | 455 | printf("%llu\n", get_dev_blocks(argv[i])); |
2b6fc908 | 456 | else |
6da365de | 457 | printf("%s: %llu\n", argv[i], get_dev_blocks(argv[i])); |
6dbe3af9 | 458 | } |
5b72b3dd | 459 | break; |
6dbe3af9 | 460 | |
5b72b3dd KZ |
461 | case ACT_FDISK: |
462 | if (argc-optind != 1) | |
463 | usage(stderr); | |
7eda085c | 464 | |
80a1712f KZ |
465 | colors_init(colormode); |
466 | ||
5b72b3dd KZ |
467 | if (fdisk_context_assign_device(cxt, argv[optind], 0) != 0) |
468 | err(EXIT_FAILURE, _("cannot open %s"), argv[optind]); | |
759d093f | 469 | |
5b72b3dd | 470 | /* Here starts interactive mode, use fdisk_{warn,info,..} functions */ |
80a1712f KZ |
471 | color_enable(UL_COLOR_GREEN); |
472 | fdisk_info(cxt, _("Welcome to fdisk (%s).\n"), PACKAGE_STRING); | |
473 | color_disable(); | |
474 | fdisk_info(cxt, _("Changes will remain in memory only, until you decide to write them.\n" | |
475 | "Be careful before using the write command.\n")); | |
5b72b3dd | 476 | fflush(stdout); |
56c07b96 | 477 | |
5b72b3dd KZ |
478 | if (!fdisk_dev_has_disklabel(cxt)) { |
479 | fdisk_warnx(cxt, _("Device does not contain a recognized partition table\n")); | |
480 | fdisk_create_disklabel(cxt, NULL); | |
481 | } | |
6dbe3af9 | 482 | |
5b72b3dd KZ |
483 | while (1) |
484 | process_fdisk_menu(&cxt); | |
485 | } | |
9777759a | 486 | |
4e0e8253 | 487 | fdisk_free_context(cxt); |
5b72b3dd | 488 | return EXIT_SUCCESS; |
6dbe3af9 | 489 | } |