diff options
author | Karel Zak | 2014-10-03 12:40:04 +0200 |
---|---|---|
committer | Karel Zak | 2014-10-07 14:55:32 +0200 |
commit | fff8ad5882308825a131c645e4d28bcaef943351 (patch) | |
tree | 93c86191fb81b0787a01628bce9ffef1eeb1fba6 | |
parent | libfdisk: add fdisk_label_get_field_by_name() and const for labels (diff) | |
download | kernel-qcow2-util-linux-fff8ad5882308825a131c645e4d28bcaef943351.tar.gz kernel-qcow2-util-linux-fff8ad5882308825a131c645e4d28bcaef943351.tar.xz kernel-qcow2-util-linux-fff8ad5882308825a131c645e4d28bcaef943351.zip |
fdisk: add --output <list> for print command(s)
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r-- | disk-utils/fdisk-list.c | 118 | ||||
-rw-r--r-- | disk-utils/fdisk-list.h | 3 | ||||
-rw-r--r-- | disk-utils/fdisk.8 | 8 | ||||
-rw-r--r-- | disk-utils/fdisk.c | 11 |
4 files changed, 137 insertions, 3 deletions
diff --git a/disk-utils/fdisk-list.c b/disk-utils/fdisk-list.c index 708e6939a..42dfda8cb 100644 --- a/disk-utils/fdisk-list.c +++ b/disk-utils/fdisk-list.c @@ -12,9 +12,16 @@ #include "strutils.h" #include "sysfs.h" #include "colors.h" +#include "ttyutils.h" #include "fdisk-list.h" +/* see init_fields() */ +static const char *fields_string; +static int *fields_ids; +static size_t fields_nids; +static const struct fdisk_label *fields_label; + static int is_ide_cdrom_or_tape(char *device) { int fd, ret; @@ -90,7 +97,8 @@ void list_disklabel(struct fdisk_context *cxt) if (fdisk_get_partitions(cxt, &tb) || fdisk_table_get_nents(tb) <= 0) goto done; - if (fdisk_label_get_fields_ids(NULL, cxt, &ids, &nids)) + ids = init_fields(cxt, NULL, &nids); + if (!ids) goto done; itr = fdisk_new_iter(FDISK_ITER_FORWARD); @@ -171,7 +179,6 @@ void list_disklabel(struct fdisk_context *cxt) if (fdisk_table_wrong_order(tb)) fdisk_info(cxt, _("Partition table entries are not in disk order.")); done: - free(ids); scols_unref_table(out); fdisk_unref_table(tb); fdisk_free_iter(itr); @@ -254,3 +261,110 @@ void print_all_devices_pt(struct fdisk_context *cxt, int verify) } } +/* usable for example in usage() */ +void list_available_columns(FILE *out) +{ + size_t i; + int termwidth; + struct fdisk_label *lb = NULL; + struct fdisk_context *cxt = fdisk_new_context(); + + if (!cxt) + return; + + termwidth = get_terminal_width(); + if (termwidth <= 0) + termwidth = 80; + + fprintf(out, _("\nAvailable columns: (for -o)\n")); + + while (fdisk_next_label(cxt, &lb) == 0) { + size_t width = 6; /* label name and separators */ + + fprintf(out, " %s:", fdisk_label_get_name(lb)); + for (i = 1; i < FDISK_NFIELDS; i++) { + const struct fdisk_field *fl = fdisk_label_get_field(lb, i); + const char *name = fl ? fdisk_field_get_name(fl) : NULL; + size_t len; + + if (!name) + continue; + len = strlen(name) + 1; + if (width + len > (size_t) termwidth) { + fputs("\n ", out); + width = 6; + } + fprintf(out, " %s", name); + width += len; + } + fputc('\n', out); + } + + fdisk_unref_context(cxt); +} + +static int fieldname_to_id(const char *name, size_t namesz) +{ + const struct fdisk_field *fl; + char buf[namesz + 1]; + + assert(name); + assert(namesz); + assert(fields_label); + + memcpy(buf, name, namesz); + buf[namesz] = '\0'; + + fl = fdisk_label_get_field_by_name(fields_label, buf); + if (!fl) { + warnx(_("%s unknown column: %s"), + fdisk_label_get_name(fields_label), buf); + return -1; + } + return fdisk_field_get_id(fl); +} + +/* + * Initialize array with output columns (fields_ids[]) according to + * comma delimited list of columns (@str). If the list string is not + * defined then use library defaults. This function is "-o <list>" + * backend. + * + * If the columns are already initialized then returns already existing columns. + */ +int *init_fields(struct fdisk_context *cxt, const char *str, size_t *n) +{ + int *dflt_ids = NULL; + + if (!fields_string) + fields_string = str; + + if (!cxt || fields_nids) + goto done; + + fields_label = fdisk_get_label(cxt, NULL); + if (!fields_label) + goto done; + + /* library default */ + if (fdisk_label_get_fields_ids(NULL, cxt, &dflt_ids, &fields_nids)) + goto done; + + fields_ids = xcalloc(sizeof(int), FDISK_NFIELDS * 2); + + /* copy defaults to the list with wanted fields */ + memcpy(fields_ids, dflt_ids, fields_nids * sizeof(int)); + free(dflt_ids); + + /* extend or replace fields_nids[] according to fields_string */ + if (fields_string && + string_add_to_idarray(fields_string, fields_ids, FDISK_NFIELDS * 2, + (int *) &fields_nids, fieldname_to_id) < 0) + exit(EXIT_FAILURE); +done: + fields_label = NULL; + if (n) + *n = fields_nids; + return fields_ids; +} + diff --git a/disk-utils/fdisk-list.h b/disk-utils/fdisk-list.h index 0a6ff734c..9dbdbadd1 100644 --- a/disk-utils/fdisk-list.h +++ b/disk-utils/fdisk-list.h @@ -8,4 +8,7 @@ extern char *next_proc_partition(FILE **f); extern int print_device_pt(struct fdisk_context *cxt, char *device, int warnme, int verify); extern void print_all_devices_pt(struct fdisk_context *cxt, int verify); +extern void list_available_columns(FILE *out); +extern int *init_fields(struct fdisk_context *cxt, const char *str, size_t *n); + #endif /* UTIL_LINUX_FDISK_LIST_H */ diff --git a/disk-utils/fdisk.8 b/disk-utils/fdisk.8 index 1da15d903..2ee5f6448 100644 --- a/disk-utils/fdisk.8 +++ b/disk-utils/fdisk.8 @@ -73,6 +73,14 @@ If no devices are given, those mentioned in .I /proc/partitions (if that file exists) are used. .TP +.BR \-o , " \-\-output " \fIlist\fP +Specify which output columns to print. Use +.B \-\-help +to get a list of all supported columns. + +The default list of columns may be extended if \fIlist\fP is +specified in the format \fI+list\fP (e.g. \fB-o +UUID\fP). +.TP \fB\-s\fR, \fB\-\-getsz\fR Print the size in 512-byte sectors of each given block device. This option is DEPRECATED in favour of diff --git a/disk-utils/fdisk.c b/disk-utils/fdisk.c index b7063b81d..ee4dd6c61 100644 --- a/disk-utils/fdisk.c +++ b/disk-utils/fdisk.c @@ -654,6 +654,8 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out) fputs(USAGE_HELP, out); fputs(USAGE_VERSION, out); + list_available_columns(out); + fprintf(out, USAGE_MAN_TAIL("fdisk(8)")); exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); } @@ -670,6 +672,7 @@ int main(int argc, char **argv) int rc, i, c, act = ACT_FDISK; int colormode = UL_COLORMODE_UNDEF; struct fdisk_context *cxt; + char *outarg = NULL; static const struct option longopts[] = { { "color", optional_argument, NULL, 'L' }, @@ -701,7 +704,7 @@ int main(int argc, char **argv) fdisk_set_ask(cxt, ask_callback, NULL); - while ((c = getopt_long(argc, argv, "b:c::C:hH:lL::sS:t:u::vV", + while ((c = getopt_long(argc, argv, "b:c::C:hH:lL::o:sS:t:u::vV", longopts, NULL)) != -1) { switch (c) { case 'b': @@ -759,6 +762,9 @@ int main(int argc, char **argv) colormode = colormode_or_err(optarg, _("unsupported color mode")); break; + case 'o': + outarg = optarg; + break; case 's': act = ACT_SHOWSIZE; break; @@ -800,6 +806,7 @@ int main(int argc, char **argv) switch (act) { case ACT_LIST: fdisk_enable_listonly(cxt, 1); + init_fields(cxt, outarg, NULL); if (argc > optind) { int k; @@ -853,6 +860,8 @@ int main(int argc, char **argv) "A hybrid GPT was detected. You have to sync " "the hybrid MBR manually (expert command 'M').")); + init_fields(cxt, outarg, NULL); /* -o <columns> */ + while (1) process_fdisk_menu(&cxt); } |