summaryrefslogtreecommitdiffstats
path: root/libfdisk/src/script.c
diff options
context:
space:
mode:
authorKarel Zak2015-06-15 13:18:09 +0200
committerKarel Zak2015-06-15 13:18:09 +0200
commit3c7fde5f922ce67ba773487e39f44db1eaa60f5e (patch)
treeaf07b8a1e8169260ec1ea1ab02b71d0ec3988e75 /libfdisk/src/script.c
parentlibfdisk: rename script functions to improve readability (diff)
downloadkernel-qcow2-util-linux-3c7fde5f922ce67ba773487e39f44db1eaa60f5e.tar.gz
kernel-qcow2-util-linux-3c7fde5f922ce67ba773487e39f44db1eaa60f5e.tar.xz
kernel-qcow2-util-linux-3c7fde5f922ce67ba773487e39f44db1eaa60f5e.zip
libfdisk: add JSON dump output
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libfdisk/src/script.c')
-rw-r--r--libfdisk/src/script.c189
1 files changed, 179 insertions, 10 deletions
diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c
index 452dd2d75..e582e1717 100644
--- a/libfdisk/src/script.c
+++ b/libfdisk/src/script.c
@@ -1,6 +1,7 @@
#include "fdiskP.h"
#include "strutils.h"
+#include "carefulputc.h"
/**
* SECTION: script
@@ -33,8 +34,9 @@ struct fdisk_script {
/* parser's state */
size_t nlines;
- int fmt; /* input format */
struct fdisk_label *label;
+
+ unsigned int json : 1; /* JSON output */
};
@@ -404,41 +406,189 @@ int fdisk_script_read_context(struct fdisk_script *dp, struct fdisk_context *cxt
rc = fdisk_script_set_header(dp, "unit", "sectors");
if (!rc && fdisk_is_label(cxt, GPT)) {
+ struct fdisk_labelitem item;
char buf[64];
- snprintf(buf, sizeof(buf), "%ju", cxt->first_lba);
- rc = fdisk_script_set_header(dp, "first-lba", buf);
+ rc = fdisk_get_disklabel_item(cxt, GPT_LABELITEM_FIRSTLBA, &item);
+ if (rc == 0) {
+ snprintf(buf, sizeof(buf), "%ju", item.data.num64);
+ rc = fdisk_script_set_header(dp, "first-lba", buf);
+ }
+ if (rc < 0)
+ goto done;
- if (!rc) {
- snprintf(buf, sizeof(buf), "%ju", cxt->last_lba);
+ rc = fdisk_get_disklabel_item(cxt, GPT_LABELITEM_LASTLBA, &item);
+ if (rc == 0) {
+ snprintf(buf, sizeof(buf), "%ju", item.data.num64);
rc = fdisk_script_set_header(dp, "last-lba", buf);
}
+ if (rc < 0)
+ goto done;
}
+done:
DBG(SCRIPT, ul_debugobj(dp, "read context done [rc=%d]", rc));
return rc;
}
/**
- * fdisk_script_write_file:
+ * fdisk_script_enable_json:
* @dp: script
- * @f: output file
+ * @json: 0 or 1
*
- * Writes script @dp to the ile @f.
+ * Disable/Enable JSON output format.
*
* Returns: 0 on success, <0 on error.
*/
-int fdisk_script_write_file(struct fdisk_script *dp, FILE *f)
+int fdisk_script_enable_json(struct fdisk_script *dp, int json)
+{
+ assert(dp);
+
+ dp->json = json;
+ return 0;
+}
+
+static void fput_indent(int indent, FILE *f)
+{
+ int i;
+
+ for (i = 0; i <= indent; i++)
+ fputs(" ", f);
+}
+
+static int write_file_json(struct fdisk_script *dp, FILE *f)
{
struct list_head *h;
struct fdisk_partition *pa;
struct fdisk_iter itr;
const char *devname = NULL;
+ int ct = 0, indent = 0;
assert(dp);
assert(f);
- DBG(SCRIPT, ul_debugobj(dp, "writing script to file"));
+ DBG(SCRIPT, ul_debugobj(dp, "writing json dump to file"));
+
+ fputs("{\n", f);
+
+ fput_indent(indent, f);
+ fputs("\"partitiontable\": {\n", f);
+ indent++;
+
+ /* script headers */
+ list_for_each(h, &dp->headers) {
+ struct fdisk_scriptheader *fi = list_entry(h, struct fdisk_scriptheader, headers);
+ const char *name = fi->name;
+ int num = 0;
+
+ if (strcmp(name, "first-lba") == 0) {
+ name = "firstlba";
+ num = 1;
+ } else if (strcmp(name, "last-lba") == 0) {
+ name = "lastlba";
+ num = 1;
+ } else if (strcmp(name, "label-id") == 0)
+ name = "id";
+
+ fput_indent(indent, f);
+ fputs_quoted_lower(name, f);
+ fputs(": ", f);
+ if (!num)
+ fputs_quoted(fi->data, f);
+ else
+ fputs(fi->data, f);
+ if (!dp->table && fi == list_last_entry(&dp->headers, struct fdisk_scriptheader, headers))
+ fputc('\n', f);
+ else
+ fputs(",\n", f);
+
+ if (strcmp(name, "device") == 0)
+ devname = fi->data;
+ }
+
+
+ if (!dp->table) {
+ DBG(SCRIPT, ul_debugobj(dp, "script table empty"));
+ goto done;
+ }
+
+ DBG(SCRIPT, ul_debugobj(dp, "%zu entries", fdisk_table_get_nents(dp->table)));
+
+ fput_indent(indent, f);
+ fputs("\"partitions\": [\n", f);
+ indent++;
+
+ fdisk_reset_iter(&itr, FDISK_ITER_FORWARD);
+ while (fdisk_table_next_partition(dp->table, &itr, &pa) == 0) {
+ char *p = NULL;
+
+ ct++;
+ fput_indent(indent, f);
+ fputc('{', f);
+ if (devname)
+ p = fdisk_partname(devname, pa->partno + 1);
+ if (p) {
+ DBG(SCRIPT, ul_debugobj(dp, "write %s entry", p));
+ fputs("\"node\": ", f);
+ fputs_quoted(p, f);
+ }
+
+ if (fdisk_partition_has_start(pa))
+ fprintf(f, ", \"start\": %ju", pa->start);
+ if (fdisk_partition_has_size(pa))
+ fprintf(f, ", \"size\": %ju", pa->size);
+
+ if (pa->type && fdisk_parttype_get_string(pa->type))
+ fprintf(f, ", \"type\": \"%s\"", fdisk_parttype_get_string(pa->type));
+ else if (pa->type)
+ fprintf(f, ", \"type\": \"%x\"", fdisk_parttype_get_code(pa->type));
+
+ if (pa->uuid)
+ fprintf(f, ", \"uuid\": \"%s\"", pa->uuid);
+ if (pa->name && *pa->name) {
+ fputs(", \"name\": ", f),
+ fputs_quoted(pa->name, f);
+ }
+
+ /* for MBR attr=80 means bootable */
+ if (pa->attrs) {
+ struct fdisk_label *lb = script_get_label(dp);
+
+ if (!lb || fdisk_label_get_type(lb) != FDISK_DISKLABEL_DOS)
+ fprintf(f, ", \"attrs\": \"%s\"", pa->attrs);
+ }
+ if (fdisk_partition_is_bootable(pa))
+ fprintf(f, ", \"bootable\": true");
+
+ if (ct < fdisk_table_get_nents(dp->table))
+ fputs("},\n", f);
+ else
+ fputs("}\n", f);
+ }
+
+ indent--;
+ fput_indent(indent, f);
+ fputs("]\n", f);
+done:
+ indent--;
+ fput_indent(indent, f);
+ fputs("}\n}\n", f);
+
+ DBG(SCRIPT, ul_debugobj(dp, "write script done"));
+ return 0;
+}
+
+static int write_file_sfdisk(struct fdisk_script *dp, FILE *f)
+{
+ struct list_head *h;
+ struct fdisk_partition *pa;
+ struct fdisk_iter itr;
+ const char *devname = NULL;
+
+ assert(dp);
+ assert(f);
+
+ DBG(SCRIPT, ul_debugobj(dp, "writing sfdisk-like script to file"));
/* script headers */
list_for_each(h, &dp->headers) {
@@ -500,6 +650,25 @@ int fdisk_script_write_file(struct fdisk_script *dp, FILE *f)
return 0;
}
+/**
+ * fdisk_script_write_file:
+ * @dp: script
+ * @f: output file
+ *
+ * Writes script @dp to the ile @f.
+ *
+ * Returns: 0 on success, <0 on error.
+ */
+int fdisk_script_write_file(struct fdisk_script *dp, FILE *f)
+{
+ assert(dp);
+
+ if (dp->json)
+ return write_file_json(dp, f);
+
+ return write_file_sfdisk(dp, f);
+}
+
static inline int is_header_line(const char *s)
{
const char *p = strchr(s, ':');