]>
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" |
e916600f | 27 | #include "all-io.h" |
22853e4a | 28 | #include "nls.h" |
e66ac5d3 | 29 | #include "rpmatch.h" |
810f986b | 30 | #include "blkdev.h" |
b8d22034 | 31 | #include "mbsalign.h" |
726f69e2 | 32 | #include "fdisk.h" |
929f243f | 33 | #include "wholedisk.h" |
6bec8710 KZ |
34 | #include "pathnames.h" |
35 | #include "canonicalize.h" | |
20aa2570 | 36 | #include "strutils.h" |
b2d28533 | 37 | #include "closestream.h" |
5c36a0eb | 38 | |
b4bfbadd | 39 | #include "pt-sun.h" /* to toggle flags */ |
5c36a0eb | 40 | |
48d7b13a | 41 | #ifdef HAVE_LINUX_COMPILER_H |
3f0ac587 | 42 | # include <linux/compiler.h> |
48d7b13a KZ |
43 | #endif |
44 | #ifdef HAVE_LINUX_BLKPG_H | |
3f0ac587 | 45 | # include <linux/blkpg.h> |
7eda085c | 46 | #endif |
6dbe3af9 | 47 | |
3f0ac587 KZ |
48 | static void __attribute__ ((__noreturn__)) usage(FILE *out) |
49 | { | |
50 | fputs(USAGE_HEADER, out); | |
51 | ||
52 | fprintf(out, | |
38d663a6 KZ |
53 | _(" %1$s [options] <disk> change partition table\n" |
54 | " %1$s [options] -l [<disk>] list partition table(s)\n"), | |
3f0ac587 KZ |
55 | program_invocation_short_name); |
56 | ||
57 | fputs(USAGE_OPTIONS, out); | |
58 | fputs(_(" -b <size> sector size (512, 1024, 2048 or 4096)\n"), out); | |
59 | fputs(_(" -c[=<mode>] compatible mode: 'dos' or 'nondos' (default)\n"), out); | |
60 | fputs(_(" -h print this help text\n"), out); | |
80a1712f KZ |
61 | fputs(_(" -c[=<mode>] compatible mode: 'dos' or 'nondos' (default)\n"), out); |
62 | fputs(_(" -L[=<when>] colorize output (auto, always or never)\n"), out); | |
565b7da6 | 63 | fputs(_(" -t <type> force fdisk to recognize specified partition table type only\n"), out); |
3f0ac587 KZ |
64 | fputs(_(" -u[=<unit>] display units: 'cylinders' or 'sectors' (default)\n"), out); |
65 | fputs(_(" -v print program version\n"), out); | |
66 | fputs(_(" -C <number> specify the number of cylinders\n"), out); | |
67 | fputs(_(" -H <number> specify the number of heads\n"), out); | |
68 | fputs(_(" -S <number> specify the number of sectors per track\n"), out); | |
69 | ||
70 | fprintf(out, USAGE_MAN_TAIL("fdisk(8)")); | |
71 | exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); | |
72 | } | |
73 | ||
7b575fcc | 74 | void list_partition_types(struct fdisk_context *cxt) |
6dbe3af9 | 75 | { |
7b575fcc | 76 | struct fdisk_parttype *types; |
76f17cf2 | 77 | size_t ntypes = 0; |
6dbe3af9 | 78 | |
7b575fcc KZ |
79 | if (!cxt || !cxt->label || !cxt->label->parttypes) |
80 | return; | |
2b6fc908 | 81 | |
7b575fcc | 82 | types = cxt->label->parttypes; |
76f17cf2 | 83 | ntypes = cxt->label->nparttypes; |
6dbe3af9 | 84 | |
7b575fcc KZ |
85 | if (types[0].typestr == NULL) { |
86 | /* | |
87 | * Prints in 4 columns in format <hex> <name> | |
88 | */ | |
76f17cf2 KZ |
89 | size_t last[4], done = 0, next = 0, size; |
90 | int i; | |
b8d22034 | 91 | |
76f17cf2 KZ |
92 | size = ntypes; |
93 | if (types[ntypes - 1].name == NULL) | |
94 | size--; | |
7b575fcc KZ |
95 | |
96 | for (i = 3; i >= 0; i--) | |
97 | last[3 - i] = done += (size + i - done) / (i + 1); | |
98 | i = done = 0; | |
99 | ||
100 | do { | |
101 | #define NAME_WIDTH 15 | |
102 | char name[NAME_WIDTH * MB_LEN_MAX]; | |
103 | size_t width = NAME_WIDTH; | |
104 | struct fdisk_parttype *t = &types[next]; | |
105 | size_t ret; | |
106 | ||
76f17cf2 KZ |
107 | if (t->name) { |
108 | printf("%c%2x ", i ? ' ' : '\n', t->type); | |
109 | ret = mbsalign(_(t->name), name, sizeof(name), | |
110 | &width, MBS_ALIGN_LEFT, 0); | |
7b575fcc | 111 | |
76f17cf2 KZ |
112 | if (ret == (size_t)-1 || ret >= sizeof(name)) |
113 | printf("%-15.15s", _(t->name)); | |
114 | else | |
115 | fputs(name, stdout); | |
116 | } | |
7b575fcc KZ |
117 | |
118 | next = last[i++] + done; | |
119 | if (i > 3 || next >= last[i]) { | |
120 | i = 0; | |
121 | next = ++done; | |
122 | } | |
123 | } while (done < last[0]); | |
124 | ||
125 | } else { | |
126 | /* | |
127 | * Prints 1 column in format <idx> <name> <typestr> | |
128 | */ | |
129 | struct fdisk_parttype *t; | |
76f17cf2 | 130 | size_t i; |
7b575fcc | 131 | |
76f17cf2 KZ |
132 | for (i = 0, t = types; t && i < ntypes; t++, i++) { |
133 | if (t->name) | |
134 | printf("%3zu %-30s %s\n", i + 1, | |
135 | t->name, t->typestr); | |
136 | } | |
7b575fcc | 137 | } |
6dbe3af9 KZ |
138 | putchar('\n'); |
139 | } | |
140 | ||
f02fecd1 | 141 | void toggle_dos_compatibility_flag(struct fdisk_context *cxt) |
852ce62b KZ |
142 | { |
143 | struct fdisk_label *lb = fdisk_context_get_label(cxt, "dos"); | |
144 | int flag; | |
145 | ||
146 | if (!lb) | |
147 | return; | |
148 | ||
149 | flag = !fdisk_dos_is_compatible(lb); | |
09f0c3d9 KZ |
150 | fdisk_info(cxt, flag ? |
151 | _("DOS Compatibility flag is set (DEPRECATED!)") : | |
152 | _("DOS Compatibility flag is not set")); | |
edd7b958 | 153 | |
852ce62b KZ |
154 | fdisk_dos_enable_compatible(lb, flag); |
155 | ||
156 | if (fdisk_is_disklabel(cxt, DOS)) | |
09f0c3d9 | 157 | fdisk_reset_alignment(cxt); /* reset the current label */ |
6dbe3af9 KZ |
158 | } |
159 | ||
27ddd4f1 | 160 | void change_partition_type(struct fdisk_context *cxt) |
e53ced85 | 161 | { |
641a75ca | 162 | size_t i; |
85151521 KZ |
163 | struct fdisk_parttype *t = NULL; |
164 | struct fdisk_partition *pa = NULL; | |
165 | const char *old = NULL; | |
6dbe3af9 | 166 | |
e3661531 KZ |
167 | assert(cxt); |
168 | assert(cxt->label); | |
169 | ||
641a75ca | 170 | if (fdisk_ask_partnum(cxt, &i, FALSE)) |
24f4bbff | 171 | return; |
2b6fc908 | 172 | |
85151521 KZ |
173 | if (fdisk_get_partition(cxt, i, &pa)) { |
174 | fdisk_warnx(cxt, _("Partition %zu does not exist yet!"), i + 1); | |
175 | return; | |
176 | } | |
177 | ||
178 | t = (struct fdisk_parttype *) fdisk_partition_get_type(pa); | |
179 | old = t ? t->name : _("Unknown"); | |
180 | ||
181 | do { | |
182 | t = ask_partition_type(cxt); | |
183 | } while (!t); | |
184 | ||
85151521 KZ |
185 | if (fdisk_set_partition_type(cxt, i, t) == 0) |
186 | fdisk_sinfo(cxt, FDISK_INFO_SUCCESS, | |
187 | _("Changed type of partition '%s' to '%s'."), | |
188 | old, t ? t->name : _("Unknown")); | |
189 | else | |
190 | fdisk_info(cxt, | |
191 | _("Type of partition %zu is unchanged: %s."), | |
192 | i + 1, old); | |
193 | ||
d6cfa8b3 | 194 | fdisk_unref_partition(pa); |
6dbe3af9 KZ |
195 | } |
196 | ||
89309968 | 197 | void list_disk_geometry(struct fdisk_context *cxt) |
21fe3dde KZ |
198 | { |
199 | char *id = NULL; | |
9af73f84 KZ |
200 | uint64_t bytes = cxt->total_sectors * cxt->sector_size; |
201 | char *strsz = size_to_human_string(SIZE_SUFFIX_SPACE | |
202 | | SIZE_SUFFIX_3LETTER, bytes); | |
203 | ||
48d4d931 | 204 | fdisk_colon(cxt, _("Disk %s: %s, %ju bytes, %ju sectors"), |
e39966c6 | 205 | cxt->dev_path, strsz, |
48d4d931 | 206 | bytes, (uintmax_t) cxt->total_sectors); |
9af73f84 | 207 | free(strsz); |
b1b1a7b7 | 208 | |
96dc2798 | 209 | if (fdisk_require_geometry(cxt) || fdisk_context_use_cylinders(cxt)) |
ac1a559a | 210 | fdisk_colon(cxt, _("Geometry: %d heads, %llu sectors/track, %llu cylinders"), |
9af73f84 | 211 | cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders); |
b1b1a7b7 | 212 | |
ac1a559a | 213 | fdisk_colon(cxt, _("Units: %s of %d * %ld = %ld bytes"), |
ec10aa67 KZ |
214 | fdisk_context_get_unit(cxt, PLURAL), |
215 | fdisk_context_get_units_per_sector(cxt), | |
216 | cxt->sector_size, | |
217 | fdisk_context_get_units_per_sector(cxt) * cxt->sector_size); | |
05dc9645 | 218 | |
ac1a559a | 219 | fdisk_colon(cxt, _("Sector size (logical/physical): %lu bytes / %lu bytes"), |
e53ced85 | 220 | cxt->sector_size, cxt->phy_sector_size); |
ac1a559a | 221 | fdisk_colon(cxt, _("I/O size (minimum/optimal): %lu bytes / %lu bytes"), |
e53ced85 DB |
222 | cxt->min_io_size, cxt->io_size); |
223 | if (cxt->alignment_offset) | |
ac1a559a | 224 | fdisk_colon(cxt, _("Alignment offset: %lu bytes"), |
9af73f84 | 225 | cxt->alignment_offset); |
b546d442 | 226 | if (fdisk_dev_has_disklabel(cxt)) |
fd56121a | 227 | fdisk_colon(cxt, _("Disklabel type: %s"), cxt->label->name); |
21fe3dde KZ |
228 | |
229 | if (fdisk_get_disklabel_id(cxt, &id) == 0 && id) | |
ac1a559a | 230 | fdisk_colon(cxt, _("Disk identifier: %s"), id); |
5c36a0eb KZ |
231 | } |
232 | ||
9f670072 KZ |
233 | void list_disklabel(struct fdisk_context *cxt) |
234 | { | |
235 | struct fdisk_table *tb = NULL; | |
236 | char *str; | |
237 | ||
238 | /* print label specific stuff by libfdisk FDISK_ASK_INFO API */ | |
239 | fdisk_list_disklabel(cxt); | |
240 | ||
241 | /* print partitions */ | |
2cec7949 | 242 | if (fdisk_get_partitions(cxt, &tb)) |
9f670072 KZ |
243 | return; |
244 | if (fdisk_table_to_string(tb, cxt, NULL, 0, &str) == 0) { | |
245 | fputc('\n', stdout); | |
849968b9 KZ |
246 | if (str && *str) |
247 | fputs(str, stdout); | |
9f670072 KZ |
248 | } |
249 | fdisk_unref_table(tb); | |
250 | } | |
251 | ||
e916600f KZ |
252 | static size_t skip_empty(const unsigned char *buf, size_t i, size_t sz) |
253 | { | |
254 | size_t next; | |
255 | const unsigned char *p0 = buf + i; | |
256 | ||
257 | for (next = i + 16; next < sz; next += 16) { | |
258 | if (memcmp(p0, buf + next, 16) != 0) | |
259 | break; | |
260 | } | |
261 | ||
262 | return next == i + 16 ? i : next; | |
263 | } | |
6dbe3af9 | 264 | |
e916600f | 265 | static void dump_buffer(off_t base, unsigned char *buf, size_t sz, int all) |
09f0c3d9 | 266 | { |
e916600f KZ |
267 | size_t i, l, next = 0; |
268 | ||
269 | if (!buf) | |
270 | return; | |
271 | for (i = 0, l = 0; i < sz; i++, l++) { | |
272 | if (l == 0) { | |
273 | if (all == 0 && !next) | |
274 | next = skip_empty(buf, i, sz); | |
275 | printf("%08jx ", base + i); | |
276 | } | |
277 | printf(" %02x", buf[i]); | |
278 | if (l == 7) /* words separator */ | |
279 | fputs(" ", stdout); | |
280 | else if (l == 15) { | |
281 | fputc('\n', stdout); /* next line */ | |
6dbe3af9 | 282 | l = -1; |
e916600f KZ |
283 | if (next > i) { |
284 | printf("*\n"); | |
285 | i = next - 1; | |
286 | } | |
287 | next = 0; | |
6dbe3af9 KZ |
288 | } |
289 | } | |
290 | if (l > 0) | |
291 | printf("\n"); | |
6dbe3af9 KZ |
292 | } |
293 | ||
e916600f KZ |
294 | static void dump_blkdev(struct fdisk_context *cxt, const char *name, |
295 | off_t offset, size_t size, int all) | |
e53ced85 | 296 | { |
e916600f KZ |
297 | fdisk_colon(cxt, _("\n%s: offset = %ju, size = %zu bytes."), |
298 | name, offset, size); | |
299 | ||
300 | if (lseek(cxt->dev_fd, offset, SEEK_SET) == (off_t) -1) | |
301 | fdisk_warn(cxt, _("cannot seek")); | |
5afed187 KZ |
302 | else { |
303 | unsigned char *buf = xmalloc(size); | |
304 | ||
305 | if (read_all(cxt->dev_fd, (char *) buf, size) != (ssize_t) size) | |
306 | fdisk_warn(cxt, _("cannot read")); | |
307 | else | |
308 | dump_buffer(offset, buf, size, all); | |
309 | free(buf); | |
310 | } | |
e916600f KZ |
311 | } |
312 | ||
313 | void dump_firstsector(struct fdisk_context *cxt) | |
314 | { | |
315 | int all = !isatty(STDOUT_FILENO); | |
316 | ||
e3661531 KZ |
317 | assert(cxt); |
318 | assert(cxt->label); | |
6dbe3af9 | 319 | |
e916600f KZ |
320 | dump_blkdev(cxt, _("First sector"), 0, cxt->sector_size, all); |
321 | } | |
322 | ||
323 | void dump_disklabel(struct fdisk_context *cxt) | |
324 | { | |
325 | int all = !isatty(STDOUT_FILENO); | |
326 | int i = 0; | |
327 | const char *name = NULL; | |
328 | off_t offset = 0; | |
329 | size_t size = 0; | |
330 | ||
331 | assert(cxt); | |
332 | assert(cxt->label); | |
e3661531 | 333 | |
e916600f KZ |
334 | while (fdisk_locate_disklabel(cxt, i++, &name, &offset, &size) == 0 && size) |
335 | dump_blkdev(cxt, name, offset, size, all); | |
6dbe3af9 KZ |
336 | } |
337 | ||
3b622ddd DB |
338 | static int is_ide_cdrom_or_tape(char *device) |
339 | { | |
340 | int fd, ret; | |
2b6fc908 | 341 | |
1c6b3378 | 342 | if ((fd = open(device, O_RDONLY)) < 0) |
e8f26419 | 343 | return 0; |
3b622ddd | 344 | ret = blkdev_is_cdrom(fd); |
2b6fc908 | 345 | |
3b622ddd DB |
346 | close(fd); |
347 | return ret; | |
2b6fc908 KZ |
348 | } |
349 | ||
6aa2ed3b | 350 | static void print_device_pt(struct fdisk_context *cxt, char *device) |
e27b42d5 | 351 | { |
4e0e8253 | 352 | if (fdisk_context_assign_device(cxt, device, 1) != 0) /* read-only */ |
289dcc90 | 353 | err(EXIT_FAILURE, _("cannot open %s"), device); |
823f0fd1 | 354 | |
5e860870 KZ |
355 | list_disk_geometry(cxt); |
356 | ||
b4fb2a61 | 357 | if (fdisk_dev_has_disklabel(cxt)) |
9f670072 | 358 | list_disklabel(cxt); |
4ec31f10 | 359 | fputc('\n', stdout); |
6dbe3af9 KZ |
360 | } |
361 | ||
6aa2ed3b | 362 | static void print_all_devices_pt(struct fdisk_context *cxt) |
ea4824f1 | 363 | { |
6aa2ed3b KZ |
364 | FILE *f; |
365 | char line[128 + 1]; | |
366 | ||
367 | f = fopen(_PATH_PROC_PARTITIONS, "r"); | |
368 | if (!f) { | |
369 | warn(_("cannot open %s"), _PATH_PROC_PARTITIONS); | |
eb63b9b8 KZ |
370 | return; |
371 | } | |
372 | ||
d31d3fc7 KZ |
373 | DBG(FRONTEND, dbgprint("reading "_PATH_PROC_PARTITIONS)); |
374 | ||
6aa2ed3b KZ |
375 | while (fgets(line, sizeof(line), f)) { |
376 | char ptname[128 + 1], devname[256]; | |
377 | ||
d31d3fc7 | 378 | if (sscanf(line, " %*d %*d %*d %128[^\n ]", ptname) != 1) |
eb63b9b8 | 379 | continue; |
6aa2ed3b | 380 | |
c07ebfa1 | 381 | snprintf(devname, sizeof(devname), "/dev/%s", ptname); |
d31d3fc7 KZ |
382 | |
383 | DBG(FRONTEND, dbgprint("listing %s", devname)); | |
384 | ||
6bec8710 KZ |
385 | if (is_whole_disk(devname)) { |
386 | char *cn = canonicalize_path(devname); | |
387 | if (cn) { | |
0c48d371 | 388 | if (!is_ide_cdrom_or_tape(cn)) |
6aa2ed3b | 389 | print_device_pt(cxt, cn); |
6bec8710 KZ |
390 | free(cn); |
391 | } | |
392 | } | |
eb63b9b8 | 393 | } |
6aa2ed3b | 394 | fclose(f); |
eb63b9b8 KZ |
395 | } |
396 | ||
50dec1eb | 397 | static sector_t get_dev_blocks(char *dev) |
6da365de DB |
398 | { |
399 | int fd; | |
50dec1eb | 400 | sector_t size; |
6da365de DB |
401 | |
402 | if ((fd = open(dev, O_RDONLY)) < 0) | |
289dcc90 | 403 | err(EXIT_FAILURE, _("cannot open %s"), dev); |
7737f698 DB |
404 | if (blkdev_get_sectors(fd, &size) == -1) { |
405 | close(fd); | |
406 | err(EXIT_FAILURE, _("BLKGETSIZE ioctl failed on %s"), dev); | |
407 | } | |
6da365de DB |
408 | close(fd); |
409 | return size/2; | |
410 | } | |
411 | ||
5b72b3dd KZ |
412 | enum { |
413 | ACT_FDISK = 0, /* default */ | |
414 | ACT_LIST, | |
415 | ACT_SHOWSIZE | |
416 | }; | |
417 | ||
e1144767 DB |
418 | int main(int argc, char **argv) |
419 | { | |
5b72b3dd | 420 | int i, c, act = ACT_FDISK; |
d0c9ddc3 | 421 | int colormode = UL_COLORMODE_UNDEF; |
4e0e8253 | 422 | struct fdisk_context *cxt; |
2b6fc908 | 423 | |
7eda085c KZ |
424 | setlocale(LC_ALL, ""); |
425 | bindtextdomain(PACKAGE, LOCALEDIR); | |
426 | textdomain(PACKAGE); | |
b2d28533 | 427 | atexit(close_stdout); |
2b6fc908 | 428 | |
4e0e8253 KZ |
429 | fdisk_init_debug(0); |
430 | cxt = fdisk_new_context(); | |
431 | if (!cxt) | |
432 | err(EXIT_FAILURE, _("failed to allocate libfdisk context")); | |
433 | ||
416c43a9 KZ |
434 | fdisk_context_set_ask(cxt, ask_callback, NULL); |
435 | ||
565b7da6 | 436 | while ((c = getopt(argc, argv, "b:c::C:hH:lL::sS:t:u::vV")) != -1) { |
2b6fc908 KZ |
437 | switch (c) { |
438 | case 'b': | |
6bcd192c KZ |
439 | { |
440 | size_t sz = strtou32_or_err(optarg, | |
441 | _("invalid sector size argument")); | |
442 | if (sz != 512 && sz != 1024 && sz != 2048 && sz != 4096) | |
7c1db6b4 | 443 | usage(stderr); |
6bcd192c | 444 | fdisk_save_user_sector_size(cxt, sz, sz); |
2b6fc908 | 445 | break; |
6bcd192c | 446 | } |
0e6f4a20 | 447 | case 'C': |
1653f0b0 KZ |
448 | fdisk_save_user_geometry(cxt, |
449 | strtou32_or_err(optarg, | |
450 | _("invalid cylinders argument")), | |
451 | 0, 0); | |
0e6f4a20 | 452 | break; |
78498b7b | 453 | case 'c': |
852ce62b | 454 | if (optarg) { |
2b0bc17b KZ |
455 | /* this setting is independent on the current |
456 | * actively used label */ | |
5b72b3dd | 457 | struct fdisk_label *lb = fdisk_context_get_label(cxt, "dos"); |
852ce62b KZ |
458 | if (!lb) |
459 | err(EXIT_FAILURE, _("not found DOS label driver")); | |
460 | if (strcmp(optarg, "=dos") == 0) | |
461 | fdisk_dos_enable_compatible(lb, TRUE); | |
462 | else if (strcmp(optarg, "=nondos") == 0) | |
463 | fdisk_dos_enable_compatible(lb, FALSE); | |
464 | else | |
465 | usage(stderr); | |
466 | } | |
467 | /* use default if no optarg specified */ | |
78498b7b | 468 | break; |
0e6f4a20 | 469 | case 'H': |
1653f0b0 KZ |
470 | fdisk_save_user_geometry(cxt, 0, |
471 | strtou32_or_err(optarg, | |
472 | _("invalid heads argument")), | |
473 | 0); | |
0e6f4a20 KZ |
474 | break; |
475 | case 'S': | |
1653f0b0 KZ |
476 | fdisk_save_user_geometry(cxt, 0, 0, |
477 | strtou32_or_err(optarg, | |
478 | _("invalid sectors argument"))); | |
0e6f4a20 | 479 | break; |
2b6fc908 | 480 | case 'l': |
5b72b3dd | 481 | act = ACT_LIST; |
2b6fc908 | 482 | break; |
80a1712f KZ |
483 | case 'L': |
484 | if (optarg) | |
485 | colormode = colormode_or_err(optarg, | |
486 | _("unsupported color mode")); | |
487 | break; | |
2b6fc908 | 488 | case 's': |
5b72b3dd | 489 | act = ACT_SHOWSIZE; |
2b6fc908 | 490 | break; |
565b7da6 KZ |
491 | case 't': |
492 | { | |
493 | struct fdisk_label *lb = NULL; | |
494 | ||
495 | while (fdisk_context_next_label(cxt, &lb) == 0) | |
496 | fdisk_label_set_disabled(lb, 1); | |
497 | ||
498 | lb = fdisk_context_get_label(cxt, optarg); | |
499 | if (!lb) | |
500 | errx(EXIT_FAILURE, _("unsupported disklabel: %s"), optarg); | |
501 | fdisk_label_set_disabled(lb, 0); | |
502 | } | |
2b6fc908 | 503 | case 'u': |
ec10aa67 KZ |
504 | if (optarg && *optarg == '=') |
505 | optarg++; | |
506 | if (fdisk_context_set_unit(cxt, optarg) != 0) | |
7c1db6b4 | 507 | usage(stderr); |
2b6fc908 | 508 | break; |
22853e4a | 509 | case 'V': |
2b6fc908 | 510 | case 'v': |
a2482eb3 DB |
511 | printf(UTIL_LINUX_VERSION); |
512 | return EXIT_SUCCESS; | |
e1144767 DB |
513 | case 'h': |
514 | usage(stdout); | |
2b6fc908 | 515 | default: |
7c1db6b4 | 516 | usage(stderr); |
2b6fc908 | 517 | } |
6dbe3af9 | 518 | } |
2b6fc908 | 519 | |
6bcd192c KZ |
520 | if (argc-optind != 1 && fdisk_has_user_device_properties(cxt)) |
521 | warnx(_("The device properties (sector size and geometry) should" | |
522 | " be used with one specified device only.")); | |
7eda085c | 523 | |
d0c9ddc3 | 524 | colors_init(colormode, "fdisk"); |
ffcf0540 | 525 | |
5b72b3dd KZ |
526 | switch (act) { |
527 | case ACT_LIST: | |
c10937dc | 528 | fdisk_context_enable_listonly(cxt, 1); |
ffcf0540 | 529 | |
2b6fc908 KZ |
530 | if (argc > optind) { |
531 | int k; | |
c129767e | 532 | for (k = optind; k < argc; k++) |
6aa2ed3b | 533 | print_device_pt(cxt, argv[k]); |
ea4824f1 | 534 | } else |
6aa2ed3b | 535 | print_all_devices_pt(cxt); |
5b72b3dd | 536 | break; |
2b6fc908 | 537 | |
5b72b3dd | 538 | case ACT_SHOWSIZE: |
9564e46c | 539 | /* deprecated */ |
5b72b3dd | 540 | if (argc - optind <= 0) |
7c1db6b4 | 541 | usage(stderr); |
2b6fc908 | 542 | |
6da365de | 543 | for (i = optind; i < argc; i++) { |
5b72b3dd | 544 | if (argc - optind == 1) |
6da365de | 545 | printf("%llu\n", get_dev_blocks(argv[i])); |
2b6fc908 | 546 | else |
6da365de | 547 | printf("%s: %llu\n", argv[i], get_dev_blocks(argv[i])); |
6dbe3af9 | 548 | } |
5b72b3dd | 549 | break; |
6dbe3af9 | 550 | |
5b72b3dd KZ |
551 | case ACT_FDISK: |
552 | if (argc-optind != 1) | |
553 | usage(stderr); | |
7eda085c | 554 | |
5b72b3dd | 555 | /* Here starts interactive mode, use fdisk_{warn,info,..} functions */ |
80a1712f | 556 | color_enable(UL_COLOR_GREEN); |
09f0c3d9 | 557 | fdisk_info(cxt, _("Welcome to fdisk (%s)."), PACKAGE_STRING); |
80a1712f KZ |
558 | color_disable(); |
559 | fdisk_info(cxt, _("Changes will remain in memory only, until you decide to write them.\n" | |
560 | "Be careful before using the write command.\n")); | |
2d8988bd KZ |
561 | |
562 | if (fdisk_context_assign_device(cxt, argv[optind], 0) != 0) | |
563 | err(EXIT_FAILURE, _("cannot open %s"), argv[optind]); | |
564 | ||
5b72b3dd | 565 | fflush(stdout); |
56c07b96 | 566 | |
5b72b3dd | 567 | if (!fdisk_dev_has_disklabel(cxt)) { |
2d8988bd | 568 | fdisk_info(cxt, _("Device does not contain a recognized partition table.")); |
5b72b3dd | 569 | fdisk_create_disklabel(cxt, NULL); |
433d05ff KZ |
570 | |
571 | } else if (fdisk_is_disklabel(cxt, GPT) && fdisk_gpt_is_hybrid(cxt)) | |
572 | fdisk_warnx(cxt, _( | |
573 | "The hybrid GPT detected. You have to sync " | |
574 | "the hybrid MBR manually (expert command 'M').")); | |
6dbe3af9 | 575 | |
5b72b3dd KZ |
576 | while (1) |
577 | process_fdisk_menu(&cxt); | |
578 | } | |
9777759a | 579 | |
4e0e8253 | 580 | fdisk_free_context(cxt); |
5b72b3dd | 581 | return EXIT_SUCCESS; |
6dbe3af9 | 582 | } |