]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: add new API to read label specific data
authorKarel Zak <kzak@redhat.com>
Thu, 11 Jun 2015 12:19:47 +0000 (14:19 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 11 Jun 2015 12:19:47 +0000 (14:19 +0200)
* removes list() label operation from internal API

  The list() has been based on fdisk_info() it was useless for
  anything else than print on stdout...

* add a new get_item() label operation and fdisk_get_disklabel_item() public API

  The new API provides abstract and pretty simple way how to get label
  specific disk label information, for example

     fdisk_get_disklabel_item(cxt, GPT_LABELITEM_ENTRIESLBA, &iterm);

  return LBA of the array with GPT entries.

  Note that this patch does not implement public functions to get
  data from the @item object.

* removes get_id() label operation -- it's subset of the new get_item()

* the new internal API is also used to implement backwardly compatible
  fdisk_list_disklabel() and fdisk_get_disklabel_id()

Signed-off-by: Karel Zak <kzak@redhat.com>
disk-utils/fdisk-list.c
libfdisk/src/bsd.c
libfdisk/src/dos.c
libfdisk/src/fdiskP.h
libfdisk/src/gpt.c
libfdisk/src/label.c
libfdisk/src/libfdisk.h.in
libfdisk/src/libfdisk.sym
libfdisk/src/sgi.c
libfdisk/src/sun.c

index b2b528e97c79a81e66d9675fa60a6d32fcb15536..5ef92b13c6d37883f0b9fab1ea9ec37cf9eb95e4 100644 (file)
@@ -75,7 +75,7 @@ void list_disk_geometry(struct fdisk_context *cxt)
                fdisk_info(cxt, _("Disklabel type: %s"),
                                fdisk_label_get_name(lb));
 
-       if (fdisk_get_disklabel_id(cxt, &id) == 0 && id)
+       if (!fdisk_is_details(cxt) && fdisk_get_disklabel_id(cxt, &id) == 0 && id)
                fdisk_info(cxt, _("Disk identifier: %s"), id);
 }
 
index 618a3eef98aee1f5debee22163f495f6b61547b1..9d4135d60625286641c63bd77f2a53806009b44f 100644 (file)
@@ -89,7 +89,6 @@ struct fdisk_bsd_label {
 #endif
 };
 
-static int bsd_list_disklabel(struct fdisk_context *cxt);
 static int bsd_initlabel(struct fdisk_context *cxt);
 static int bsd_readlabel(struct fdisk_context *cxt);
 static void sync_disks(struct fdisk_context *cxt);
@@ -398,14 +397,8 @@ static int bsd_create_disklabel(struct fdisk_context *cxt)
 
        rc = bsd_initlabel(cxt);
        if (!rc) {
-               int org = fdisk_is_details(cxt);
-
                cxt->label->nparts_cur = d->d_npartitions;
                cxt->label->nparts_max = BSD_MAXPARTITIONS;
-
-               fdisk_enable_details(cxt, 1);
-               bsd_list_disklabel(cxt);
-               fdisk_enable_details(cxt, org);
        }
 
        return rc;
@@ -430,48 +423,114 @@ static int bsd_delete_part(
        return 0;
 }
 
-static int bsd_list_disklabel(struct fdisk_context *cxt)
+static int bsd_get_disklabel_item(struct fdisk_context *cxt, struct fdisk_labelitem *item)
 {
-       struct bsd_disklabel *d = self_disklabel(cxt);
+       struct bsd_disklabel *d;
+       int rc = 0;
 
        assert(cxt);
        assert(cxt->label);
        assert(fdisk_is_label(cxt, BSD));
 
-       if (fdisk_is_details(cxt)) {
-               fdisk_info(cxt, "# %s:", cxt->dev_path);
-
-               if ((unsigned) d->d_type < BSD_DKMAXTYPES)
-                       fdisk_info(cxt, _("type: %s"), bsd_dktypenames[d->d_type]);
-               else
-                       fdisk_info(cxt, _("type: %d"), d->d_type);
-
-               fdisk_info(cxt, _("disk: %.*s"), (int) sizeof(d->d_typename), d->d_typename);
-               fdisk_info(cxt, _("label: %.*s"), (int) sizeof(d->d_packname), d->d_packname);
+       d = self_disklabel(cxt);
 
-               fdisk_info(cxt, _("flags: %s"),
+       switch (item->id) {
+       case BSD_LABELITEM_TYPE:
+               item->name = _("Type");
+               item->type = 's';
+               if ((unsigned) d->d_type < BSD_DKMAXTYPES) {
+                       item->data.str = strdup(bsd_dktypenames[d->d_type]);
+                       if (!item->data.str)
+                               rc = -ENOMEM;
+               } else if (asprintf(&item->data.str, "%d", d->d_type) < 0)
+                       rc = -ENOMEM;
+               break;
+       case BSD_LABELITEM_DISK:
+               item->name = _("Disk");
+               item->type = 's';
+               item->data.str = strndup(d->d_typename, sizeof(d->d_typename));
+               if (!item->data.str)
+                       rc = -ENOMEM;
+               break;
+       case BSD_LABELITEM_PACKNAME:
+               item->name = _("Packname");
+               item->type = 's';
+               item->data.str = strndup(d->d_packname, sizeof(d->d_packname));
+               if (!item->data.str)
+                       rc = -ENOMEM;
+               break;
+       case BSD_LABELITEM_FLAGS:
+               item->name = _("Flags");
+               item->type = 's';
+               item->data.str = strdup(
                        d->d_flags & BSD_D_REMOVABLE ? _(" removable") :
                        d->d_flags & BSD_D_ECC ? _(" ecc") :
                        d->d_flags & BSD_D_BADSECT ? _(" badsect") : "");
+               if (!item->data.str)
+                       rc = -ENOMEM;
+               break;
 
-               /* On various machines the fields of *lp are short/int/long */
-               /* In order to avoid problems, we cast them all to long. */
-               fdisk_info(cxt, _("bytes/sector: %ld"), (long) d->d_secsize);
-               fdisk_info(cxt, _("sectors/track: %ld"), (long) d->d_nsectors);
-               fdisk_info(cxt, _("tracks/cylinder: %ld"), (long) d->d_ntracks);
-               fdisk_info(cxt, _("sectors/cylinder: %ld"), (long) d->d_secpercyl);
-               fdisk_info(cxt, _("cylinders: %ld"), (long) d->d_ncylinders);
-               fdisk_info(cxt, _("rpm: %d"), d->d_rpm);
-               fdisk_info(cxt, _("interleave: %d"), d->d_interleave);
-               fdisk_info(cxt, _("trackskew: %d"), d->d_trackskew);
-               fdisk_info(cxt, _("cylinderskew: %d"), d->d_cylskew);
-               fdisk_info(cxt, _("headswitch: %ld (milliseconds)"), (long) d->d_headswitch);
-               fdisk_info(cxt, _("track-to-track seek: %ld (milliseconds)"), (long) d->d_trkseek);
+       /* On various machines the fields of *lp are short/int/long */
+       /* In order to avoid problems, we cast them all uint64. */
+       case BSD_LABELITEM_SECSIZE:
+               item->name = _("Bytes/Sector");
+               item->type = 'j';
+               item->data.num64 = (uint64_t) d->d_secsize;
+               break;
+       case BSD_LABELITEM_NTRACKS:
+               item->name = _("Tracks/Cylinder");
+               item->type = 'j';
+               item->data.num64 = (uint64_t) d->d_ntracks;
+               break;
+       case BSD_LABELITEM_SECPERCYL:
+               item->name = _("Sectors/Cylinder");
+               item->data.num64 = (uint64_t) d->d_secpercyl;
+               item->type = 'j';
+               break;
+       case BSD_LABELITEM_CYLINDERS:
+               item->name = _("Cylinders");
+               item->data.num64 = (uint64_t) d->d_ncylinders;
+               item->type = 'j';
+               break;
+       case BSD_LABELITEM_RPM:
+               item->name = _("Rpm");
+               item->data.num64 = (uint64_t) d->d_rpm;
+               item->type = 'j';
+               break;
+       case BSD_LABELITEM_INTERLEAVE:
+               item->name = _("Interleave");
+               item->data.num64 = (uint64_t) d->d_interleave;
+               item->type = 'j';
+               break;
+       case BSD_LABELITEM_TRACKSKEW:
+               item->name = _("Trackskew");
+               item->data.num64 = (uint64_t) d->d_trackskew;
+               item->type = 'j';
+               break;
+       case BSD_LABELITEM_CYLINDERSKEW:
+               item->name = _("Cylinderskew");
+               item->data.num64 = (uint64_t) d->d_cylskew;
+               item->type = 'j';
+               break;
+       case BSD_LABELITEM_HEADSWITCH:
+               item->name = _("Headswitch");
+               item->data.num64 = (uint64_t) d->d_headswitch;
+               item->type = 'j';
+               break;
+       case BSD_LABELITEM_TRKSEEK:
+               item->name = _("Track-to-track seek");
+               item->data.num64 = (uint64_t) d->d_trkseek;
+               item->type = 'j';
+               break;
+       default:
+               if (item->id < __FDISK_NLABELITEMS)
+                       rc = 1; /* unssupported generic item */
+               else
+                       rc = 2; /* out of range */
+               break;
        }
 
-       fdisk_info(cxt, _("partitions: %d"), d->d_npartitions);
-
-       return 0;
+       return rc;
 }
 
 static int bsd_get_partition(struct fdisk_context *cxt, size_t n,
@@ -934,7 +993,7 @@ static int bsd_partition_is_used(
 static const struct fdisk_label_operations bsd_operations =
 {
        .probe          = bsd_probe_label,
-       .list           = bsd_list_disklabel,
+       .get_item       = bsd_get_disklabel_item,
        .write          = bsd_write_disklabel,
        .create         = bsd_create_disklabel,
 
index de70728c2a21383dee0acc2bd2b6e9445ad3682e..b9fb77cb78e4e213a9fcaceafd8632885c18f703 100644 (file)
@@ -615,22 +615,6 @@ static void read_extended(struct fdisk_context *cxt, size_t ext)
        DBG(LABEL, ul_debug("DOS: nparts_max: %zu", cxt->label->nparts_max));
 }
 
-static int dos_get_disklabel_id(struct fdisk_context *cxt, char **id)
-{
-       unsigned int num;
-
-       assert(cxt);
-       assert(id);
-       assert(cxt->label);
-       assert(fdisk_is_label(cxt, DOS));
-
-       num = mbr_get_id(cxt->firstsector);
-       if (asprintf(id, "0x%08x", num) > 0)
-               return 0;
-
-       return -ENOMEM;
-}
-
 static int dos_create_disklabel(struct fdisk_context *cxt)
 {
        unsigned int id = 0;
@@ -1852,13 +1836,34 @@ static int wrong_p_order(struct fdisk_context *cxt, size_t *prev)
        return 0;
 }
 
-static int dos_list_disklabel(struct fdisk_context *cxt)
+static int dos_get_disklabel_item(struct fdisk_context *cxt, struct fdisk_labelitem *item)
 {
+       int rc = 0;
+
        assert(cxt);
        assert(cxt->label);
        assert(fdisk_is_label(cxt, DOS));
 
-       return 0;
+       switch (item->id) {
+       case FDISK_LABELITEM_ID:
+       {
+               unsigned int num = mbr_get_id(cxt->firstsector);
+               item->name = _("Disk identifier");
+               item->type = 's';
+               if (asprintf(&item->data.str, "0x%08x", num) < 0)
+                       rc = -ENOMEM;
+               break;
+       }
+       default:
+               if (item->id < __FDISK_NLABELITEMS)
+                       rc = 1; /* unssupported generic item */
+               else
+                       rc = 2; /* out of range */
+               break;
+       }
+
+       return rc;
+
 }
 
 static int dos_get_partition(struct fdisk_context *cxt, size_t n,
@@ -2273,15 +2278,14 @@ static const struct fdisk_label_operations dos_operations =
        .verify         = dos_verify_disklabel,
        .create         = dos_create_disklabel,
        .locate         = dos_locate_disklabel,
-       .list           = dos_list_disklabel,
-       .reorder        = dos_reorder,
-       .get_id         = dos_get_disklabel_id,
+       .get_item       = dos_get_disklabel_item,
        .set_id         = dos_set_disklabel_id,
 
        .get_part       = dos_get_partition,
        .set_part       = dos_set_partition,
        .add_part       = dos_add_partition,
        .del_part       = dos_delete_partition,
+       .reorder        = dos_reorder,
 
        .part_toggle_flag = dos_toggle_partition_flag,
        .part_is_used   = dos_partition_is_used,
index 5e8ed9c3552f26af4daaf2b666ceef66d57835ee..10380e15b422377a25bbfca12e8406fb3dc63333 100644 (file)
@@ -197,16 +197,13 @@ struct fdisk_label_operations {
        int (*verify)(struct fdisk_context *cxt);
        /* create new disk label */
        int (*create)(struct fdisk_context *cxt);
-       /* list disklabel details */
-       int (*list)(struct fdisk_context *cxt);
        /* returns offset and size of the 'n' part of the PT */
        int (*locate)(struct fdisk_context *cxt, int n, const char **name,
                      uint64_t *offset, size_t *size);
        /* reorder partitions */
        int (*reorder)(struct fdisk_context *cxt);
-
-       /* get disk label ID */
-       int (*get_id)(struct fdisk_context *cxt, char **id);
+       /* get details from label */
+       int (*get_item)(struct fdisk_context *cxt, struct fdisk_labelitem *item);
        /* set disk label ID */
        int (*set_id)(struct fdisk_context *cxt);
 
@@ -427,6 +424,18 @@ extern char *fdisk_partname(const char *dev, size_t partno);
 extern int fdisk_probe_labels(struct fdisk_context *cxt);
 extern void fdisk_deinit_label(struct fdisk_label *lb);
 
+struct fdisk_labelitem {
+       int             id;             /* <label>_ITEM_* */
+       char            type;           /* s = string, j = uint64 */
+       const char      *name;
+
+       union {
+               char            *str;
+               uint64_t        num64;
+       } data;
+};
+
+
 /* ask.c */
 struct fdisk_ask *fdisk_new_ask(void);
 void fdisk_reset_ask(struct fdisk_ask *ask);
index 007840f602606124ef5f5966a6765006c285d027..33526190f6b6fb57c4c7558c48cee8ca064d7349 100644 (file)
@@ -395,6 +395,16 @@ static inline int partition_unused(const struct gpt_entry *e)
                        sizeof(struct gpt_guid));
 }
 
+static char *gpt_get_header_id(struct gpt_header *header)
+{
+       char str[37];
+
+       guid_to_string(&header->disk_guid, str);
+
+       return strdup(str);
+}
+
+
 /*
  * Builds a clean new valid protective MBR - will wipe out any existing data.
  * Returns 0 on success, otherwise < 0 on error.
@@ -1034,7 +1044,62 @@ static int gpt_locate_disklabel(struct fdisk_context *cxt, int n,
        return 0;
 }
 
+static int gpt_get_disklabel_item(struct fdisk_context *cxt, struct fdisk_labelitem *item)
+{
+       struct gpt_header *h;
+       int rc = 0;
+
+       assert(cxt);
+       assert(cxt->label);
+       assert(fdisk_is_label(cxt, GPT));
+
+       h = self_label(cxt)->pheader;
 
+       switch (item->id) {
+       case GPT_LABELITEM_ID:
+               item->name = _("Disk identifier");
+               item->type = 's';
+               item->data.str = gpt_get_header_id(h);
+               if (!item->data.str)
+                       rc = -ENOMEM;
+               break;
+       case GPT_LABELITEM_FIRSTLBA:
+               item->name = _("First LBA");
+               item->type = 'j';
+               item->data.num64 = le64_to_cpu(h->first_usable_lba);
+               break;
+       case GPT_LABELITEM_LASTLBA:
+               item->name = _("Last LBA");
+               item->type = 'j';
+               item->data.num64 = le64_to_cpu(h->last_usable_lba);
+               break;
+       case GPT_LABELITEM_ALTLBA:
+               /* TRANSLATORS: The LBA (Logical Block Address) of the backup GPT header. */
+               item->name = _("Alternative LBA");
+               item->type = 'j';
+               item->data.num64 = le64_to_cpu(h->alternative_lba);
+               break;
+       case GPT_LABELITEM_ENTRIESLBA:
+               /* TRANSLATORS: The start of the array of partition entries. */
+               item->name = _("Partition entries LBA");
+               item->type = 'j';
+               item->data.num64 = le64_to_cpu(h->partition_entry_lba);
+               break;
+       case GPT_LABELITEM_ENTRIESALLOC:
+               item->name = _("Allocated partition entries");
+               item->type = 'j';
+               item->data.num64 = le32_to_cpu(h->npartition_entries);
+               break;
+       default:
+               if (item->id < __FDISK_NLABELITEMS)
+                       rc = 1; /* unssupported generic item */
+               else
+                       rc = 2; /* out of range */
+               break;
+       }
+
+       return rc;
+}
 
 /*
  * Returns the number of partitions that are in use.
@@ -1662,29 +1727,6 @@ static int gpt_set_partition(struct fdisk_context *cxt, size_t n,
 }
 
 
-/*
- * List label partitions.
- */
-static int gpt_list_disklabel(struct fdisk_context *cxt)
-{
-       assert(cxt);
-       assert(cxt->label);
-       assert(fdisk_is_label(cxt, GPT));
-
-       if (fdisk_is_details(cxt)) {
-               struct gpt_header *h = self_label(cxt)->pheader;
-
-               fdisk_info(cxt, _("First LBA: %ju"), le64_to_cpu(h->first_usable_lba));
-               fdisk_info(cxt, _("Last LBA: %ju"), le64_to_cpu(h->last_usable_lba));
-               /* TRANSLATORS: The LBA (Logical Block Address) of the backup GPT header. */
-               fdisk_info(cxt, _("Alternative LBA: %ju"), le64_to_cpu(h->alternative_lba));
-               /* TRANSLATORS: The start of the array of partition entries. */
-               fdisk_info(cxt, _("Partition entries LBA: %ju"), le64_to_cpu(h->partition_entry_lba));
-               fdisk_info(cxt, _("Allocated partition entries: %u"), le32_to_cpu(h->npartition_entries));
-       }
-
-       return 0;
-}
 
 /*
  * Write partitions.
@@ -2329,25 +2371,6 @@ done:
        return rc;
 }
 
-static int gpt_get_disklabel_id(struct fdisk_context *cxt, char **id)
-{
-       struct fdisk_gpt_label *gpt;
-       char str[37];
-
-       assert(cxt);
-       assert(id);
-       assert(cxt->label);
-       assert(fdisk_is_label(cxt, GPT));
-
-       gpt = self_label(cxt);
-       guid_to_string(&gpt->pheader->disk_guid, str);
-
-       *id = strdup(str);
-       if (!*id)
-               return -ENOMEM;
-       return 0;
-}
-
 static int gpt_set_disklabel_id(struct fdisk_context *cxt)
 {
        struct fdisk_gpt_label *gpt;
@@ -2372,7 +2395,7 @@ static int gpt_set_disklabel_id(struct fdisk_context *cxt)
                return rc;
        }
 
-       gpt_get_disklabel_id(cxt, &old);
+       old = gpt_get_header_id(gpt->pheader);
 
        gpt->pheader->disk_guid = uuid;
        gpt->bheader->disk_guid = uuid;
@@ -2380,7 +2403,7 @@ static int gpt_set_disklabel_id(struct fdisk_context *cxt)
        gpt_recompute_crc(gpt->pheader, gpt->ents);
        gpt_recompute_crc(gpt->bheader, gpt->ents);
 
-       gpt_get_disklabel_id(cxt, &new);
+       new = gpt_get_header_id(gpt->pheader);
 
        fdisk_info(cxt, _("Disk identifier changed from %s to %s."), old, new);
 
@@ -2674,16 +2697,15 @@ static const struct fdisk_label_operations gpt_operations =
        .write          = gpt_write_disklabel,
        .verify         = gpt_verify_disklabel,
        .create         = gpt_create_disklabel,
-       .list           = gpt_list_disklabel,
        .locate         = gpt_locate_disklabel,
-       .reorder        = gpt_reorder,
-       .get_id         = gpt_get_disklabel_id,
+       .get_item       = gpt_get_disklabel_item,
        .set_id         = gpt_set_disklabel_id,
 
        .get_part       = gpt_get_partition,
        .set_part       = gpt_set_partition,
        .add_part       = gpt_add_partition,
        .del_part       = gpt_delete_partition,
+       .reorder        = gpt_reorder,
 
        .part_is_used   = gpt_part_is_used,
        .part_toggle_flag = gpt_toggle_partition_flag,
index dd9fef040bb016314d7d69aebf1ce292cb11b7aa..92b82cc18b27cdc570625e5387f78968cd3c751b 100644 (file)
@@ -336,19 +336,46 @@ int fdisk_verify_disklabel(struct fdisk_context *cxt)
  *
  * Lists details about disklabel, but no partitions.
  *
- * This function uses libfdisk ASK interface to print data. The details about
- * partitions table are printed by FDISK_ASKTYPE_INFO.
+ * This function is based on fdisk_get_disklabel_item() and prints all label
+ * specific information by ASK interface (FDISK_ASKTYPE_INFO, aka fdisk_info()).
+ * The function requires enabled "details" by fdisk_enable_details().
+ *
+ * It's recommended to use fdisk_get_disklabel_item() if you need better
+ * control on output and formmatting.
  *
  * Returns: 0 on success, otherwise, a corresponding error.
  */
 int fdisk_list_disklabel(struct fdisk_context *cxt)
 {
+       int id = 0, rc = 0;
+       struct fdisk_labelitem item = { .id = id };
+
        if (!cxt || !cxt->label)
                return -EINVAL;
-       if (!cxt->label->op->list)
-               return -ENOSYS;
 
-       return cxt->label->op->list(cxt);
+       if (!cxt->display_details)
+               return 0;
+
+       /* List all label items */
+       do {
+               /* rc: < 0 error, 0 success, 1 unknown item, 2 out of range */
+               rc = fdisk_get_disklabel_item(cxt, id++, &item);
+               if (rc != 0)
+                       continue;
+               switch (item.type) {
+               case 'j':
+                       fdisk_info(cxt, "%s: %ju", item.name, item.data.num64);
+                       break;
+               case 's':
+                       if (item.data.str && item.name)
+                               fdisk_info(cxt, "%s: %s", item.name, item.data.str);
+                       free(item.data.str);
+                       item.data.str = NULL;
+                       break;
+               }
+       } while (rc == 0 || rc == 1);
+
+       return rc < 0 ? rc : 0;
 }
 
 /**
@@ -437,13 +464,46 @@ int fdisk_locate_disklabel(struct fdisk_context *cxt, int n, const char **name,
  */
 int fdisk_get_disklabel_id(struct fdisk_context *cxt, char **id)
 {
-       if (!cxt || !cxt->label)
+       struct fdisk_labelitem item;
+       int rc;
+
+       if (!cxt || !cxt->label || !id)
                return -EINVAL;
-       if (!cxt->label->op->get_id)
-               return -ENOSYS;
 
        DBG(CXT, ul_debugobj(cxt, "asking for disk %s ID", cxt->label->name));
-       return cxt->label->op->get_id(cxt, id);
+
+       rc = fdisk_get_disklabel_item(cxt, FDISK_LABELITEM_ID, &item);
+       if (rc == 0)
+               *id = item.data.str;
+       if (rc > 0)
+               rc = 0;
+       return rc;
+}
+
+/**
+ * fdisk_get_disklabel_item:
+ * @cxt: fdisk context
+ * @id: item ID (FDISK_LABELITEM_* or {GPT,MBR,...}_LABELITEM_*)
+ * @item: specifies and returns the item
+ *
+ * Note that @id is always in range 0..N. It's fine to use the function in loop
+ * until it returns error or 2, the result in @item should be ignored when
+ * function returns 1.
+ *
+ * Returns: 0 on success, < 0 on error, 1 on unssupported item, 2 @id out of range
+ */
+int fdisk_get_disklabel_item(struct fdisk_context *cxt, int id, struct fdisk_labelitem *item)
+{
+       if (!cxt || !cxt->label || !item)
+               return -EINVAL;
+
+       item->id = id;
+       DBG(CXT, ul_debugobj(cxt, "asking for disk %s item %d", cxt->label->name, item->id));
+
+       if (!cxt->label->op->get_item)
+               return -ENOSYS;
+
+       return cxt->label->op->get_item(cxt, item);
 }
 
 /**
index bfb22a2f7687b91a6b4e1be53c7599db1a608df2..ba6539e23bb336e9dd9aa254ee69deebee4071ee 100644 (file)
@@ -99,7 +99,7 @@ struct fdisk_field;
 /**
  * fdisk_script
  *
- * library handler for sfdisk compatible scripts
+ * library handler for sfdisk compatible scripts and dumps
  */
 struct fdisk_script;
 
@@ -123,6 +123,14 @@ enum fdisk_labeltype {
        FDISK_DISKLABEL_GPT = (1 << 5)
 };
 
+/**
+ * fdisk_labelitem
+ *
+ * library handler for label specific information. See
+ * generic FDISK_LABELITEM_* and label specific {GPT,MBR,..}_LABELITEM_*.
+ */
+struct fdisk_labelitem;
+
 /**
  * fdisk_asktype:
  *
@@ -140,6 +148,7 @@ enum fdisk_asktype {
        FDISK_ASKTYPE_MENU
 };
 
+
 /* init.c */
 extern void fdisk_init_debug(int mask);
 
@@ -246,7 +255,7 @@ int fdisk_parttype_is_unknown(const struct fdisk_parttype *t);
 /**
  * fdisk_fieldtype
  *
- * Types of fdisk_field
+ * Types of fdisk_field. The fields describe a partition.
  */
 enum fdisk_fieldtype {
        FDISK_FIELD_NONE = 0,
@@ -289,6 +298,18 @@ extern int fdisk_locate_disklabel(struct fdisk_context *cxt, int n,
                                  uint64_t *offset,
                                  size_t *size);
 
+/**
+ * fdisk_labelitem_gen
+ *
+ * Generic disklabel items
+ */
+enum fdisk_labelitem_gen {
+       FDISK_LABELITEM_ID = 0,         /* Unique disk identifier */
+
+       __FDISK_NLABELITEMS = 8         /* Specifies reserved range for generic items (0..7) */
+};
+
+extern int fdisk_get_disklabel_item(struct fdisk_context *cxt, int id, struct fdisk_labelitem *item);
 extern int fdisk_get_disklabel_id(struct fdisk_context *cxt, char **id);
 extern int fdisk_set_disklabel_id(struct fdisk_context *cxt);
 
@@ -477,17 +498,52 @@ extern int fdisk_sun_set_ilfact(struct fdisk_context *cxt);
 extern int fdisk_sun_set_rspeed(struct fdisk_context *cxt);
 extern int fdisk_sun_set_pcylcount(struct fdisk_context *cxt);
 
+enum fdisk_labelitem_sun {
+       SUN_LABELITEM_LABELID = __FDISK_NLABELITEMS,
+       SUN_LABELITEM_VTOCID,
+       SUN_LABELITEM_RPM,
+       SUN_LABELITEM_ACYL,
+       SUN_LABELITEM_PCYL,
+       SUN_LABELITEM_APC,
+       SUN_LABELITEM_INTRLV
+};
+
 /* bsd.c */
 extern int fdisk_bsd_edit_disklabel(struct fdisk_context *cxt);
 extern int fdisk_bsd_write_bootstrap(struct fdisk_context *cxt);
 extern int fdisk_bsd_link_partition(struct fdisk_context *cxt);
 
+enum fdisk_labelitem_bsd {
+       /* specific */
+       BSD_LABELITEM_TYPE = __FDISK_NLABELITEMS,
+       BSD_LABELITEM_DISK,
+       BSD_LABELITEM_PACKNAME,
+       BSD_LABELITEM_FLAGS,
+       BSD_LABELITEM_SECSIZE,
+       BSD_LABELITEM_NTRACKS,
+       BSD_LABELITEM_SECPERCYL,
+       BSD_LABELITEM_CYLINDERS,
+       BSD_LABELITEM_RPM,
+       BSD_LABELITEM_INTERLEAVE,
+       BSD_LABELITEM_TRACKSKEW,
+       BSD_LABELITEM_CYLINDERSKEW,
+       BSD_LABELITEM_HEADSWITCH,
+       BSD_LABELITEM_TRKSEEK
+};
+
 /* sgi.h */
 #define SGI_FLAG_BOOT  1
 #define SGI_FLAG_SWAP  2
 extern int fdisk_sgi_set_bootfile(struct fdisk_context *cxt);
 extern int fdisk_sgi_create_info(struct fdisk_context *cxt);
 
+enum fdisk_labelitem_sgi {
+       SGI_LABELITEM_PCYLCOUNT = __FDISK_NLABELITEMS,
+       SGI_LABELITEM_SPARECYL,
+       SGI_LABELITEM_ILFACT,
+       SGI_LABELITEM_BOOTFILE
+};
+
 /* gpt */
 
 /*
@@ -539,6 +595,16 @@ extern int fdisk_gpt_is_hybrid(struct fdisk_context *cxt);
 extern int fdisk_gpt_get_partition_attrs(struct fdisk_context *cxt, size_t partnum, uint64_t *attrs);
 extern int fdisk_gpt_set_partition_attrs(struct fdisk_context *cxt, size_t partnum, uint64_t attrs);
 
+enum fdisk_labelitem_gpt {
+       /* generic */
+       GPT_LABELITEM_ID = FDISK_LABELITEM_ID,          /* GPT disklabel UUID (!= partition UUID) */
+       /* specific */
+       GPT_LABELITEM_FIRSTLBA = __FDISK_NLABELITEMS,   /* First Usable LBA */
+       GPT_LABELITEM_LASTLBA,                          /* Last Usable LBA */
+       GPT_LABELITEM_ALTLBA,                           /* Alternative LBA (backup header LBA) */
+       GPT_LABELITEM_ENTRIESLBA,                       /* Partitions entires array LBA */
+       GPT_LABELITEM_ENTRIESALLOC                      /* Number of allocated entries in entries array */
+};
 
 /* script.c */
 struct fdisk_script *fdisk_new_script(struct fdisk_context *cxt);
index 15c268ee30d6733ad579046a0b681fd664947cb0..7cf5d2f0c7082f355f3eff2e609dfb51ea317847 100644 (file)
@@ -250,4 +250,5 @@ FDISK_2.27 {
        fdisk_script_set_fgets;
        fdisk_script_set_userdata;
        fdisk_table_get_partition_by_partno;
+       fdisk_get_disklabel_item;
 } FDISK_2.26;
index 7cc68b501583c02f5cbca1c755a3e5641d5f8828..8e0c0e72bac690fb03262d99646c7d14cc1f60bc 100644 (file)
@@ -264,22 +264,48 @@ static int sgi_probe_label(struct fdisk_context *cxt)
        return 1;
 }
 
-static int sgi_list_table(struct fdisk_context *cxt)
+static int sgi_get_disklabel_item(struct fdisk_context *cxt, struct fdisk_labelitem *item)
 {
-       struct sgi_disklabel *sgilabel = self_disklabel(cxt);
-       struct sgi_device_parameter *sgiparam = &sgilabel->devparam;
+       struct sgi_disklabel *sgilabel;
+       struct sgi_device_parameter *sgiparam;
        int rc = 0;
 
-       if (fdisk_is_details(cxt))
-               fdisk_info(cxt, _(
-                       "Label geometry: %d heads, %llu sectors\n"
-                       "                %llu cylinders, %d physical cylinders\n"
-                       "                %d extra sects/cyl, interleave %d:1\n"),
-                       cxt->geom.heads, cxt->geom.sectors,
-                       cxt->geom.cylinders, be16_to_cpu(sgiparam->pcylcount),
-                       (int) sgiparam->sparecyl, be16_to_cpu(sgiparam->ilfact));
+       assert(cxt);
+       assert(cxt->label);
+       assert(fdisk_is_label(cxt, SGI));
+
+       sgilabel = self_disklabel(cxt);
+       sgiparam = &sgilabel->devparam;
+
+       switch (item->id) {
+       case SGI_LABELITEM_PCYLCOUNT:
+               item->name = _("Physical cylinders");
+               item->type = 'j';
+               item->data.num64 = (uint64_t) be16_to_cpu(sgiparam->pcylcount);
+               break;
+       case SGI_LABELITEM_SPARECYL:
+               item->name = _("Extra sects/cyl");
+               item->type = 'j';
+               item->data.num64 = (uint64_t) sgiparam->sparecyl;
+               break;
+       case SGI_LABELITEM_ILFACT:
+               item->name = _("Interleave");
+               item->type = 'j';
+               item->data.num64 = (uint64_t) be16_to_cpu(sgiparam->ilfact);
+               break;
+       case SGI_LABELITEM_BOOTFILE:
+               item->name = _("Bootfile");
+               item->type = 's';
+               item->data.str = *sgilabel->boot_file ? strdup((char *) sgilabel->boot_file) : NULL;
+               break;
+       default:
+               if (item->id < __FDISK_NLABELITEMS)
+                       rc = 1; /* unssupported generic item */
+               else
+                       rc = 2; /* out of range */
+               break;
+       }
 
-       fdisk_info(cxt, _("Bootfile: %s"), sgilabel->boot_file);
        return rc;
 }
 
@@ -1145,8 +1171,8 @@ static const struct fdisk_label_operations sgi_operations =
        .probe          = sgi_probe_label,
        .write          = sgi_write_disklabel,
        .verify         = sgi_verify_disklabel,
+       .get_item       = sgi_get_disklabel_item,
        .create         = sgi_create_disklabel,
-       .list           = sgi_list_table,
 
        .get_part       = sgi_get_partition,
        .set_part       = sgi_set_partition,
index 27e3bdd0028d82b453a1d2009979bdd95216f8c3..d5c76ae8095fe00519fa100497eb9b23e0be8a76 100644 (file)
@@ -731,10 +731,10 @@ static int sun_delete_partition(struct fdisk_context *cxt,
        return 0;
 }
 
-
-static int sun_list_disklabel(struct fdisk_context *cxt)
+static int sun_get_disklabel_item(struct fdisk_context *cxt, struct fdisk_labelitem *item)
 {
        struct sun_disklabel *sunlabel;
+       int rc = 0;
 
        assert(cxt);
        assert(cxt->label);
@@ -742,21 +742,51 @@ static int sun_list_disklabel(struct fdisk_context *cxt)
 
        sunlabel = self_disklabel(cxt);
 
-       if (fdisk_is_details(cxt)) {
-               fdisk_info(cxt,
-               _("Label geometry: %d rpm, %d alternate and %d physical cylinders,\n"
-                 "                %d extra sects/cyl, interleave %d:1"),
-                      be16_to_cpu(sunlabel->rpm),
-                      be16_to_cpu(sunlabel->acyl),
-                      be16_to_cpu(sunlabel->pcyl),
-                      be16_to_cpu(sunlabel->apc),
-                      be16_to_cpu(sunlabel->intrlv));
-               fdisk_info(cxt, _("Label ID: %s"), sunlabel->label_id);
-               fdisk_info(cxt, _("Volume ID: %s"),
-                      *sunlabel->vtoc.volume_id ? sunlabel->vtoc.volume_id : _("<none>"));
+       switch (item->id) {
+       case SUN_LABELITEM_LABELID:
+               item->name =_("Label ID");
+               item->type = 's';
+               item->data.str = *sunlabel->label_id ? strndup((char *)sunlabel->label_id, sizeof(sunlabel->label_id)) : NULL;
+               break;
+       case SUN_LABELITEM_VTOCID:
+               item->name =_("Volume ID");
+               item->type = 's';
+               item->data.str = *sunlabel->vtoc.volume_id ? strndup((char *)sunlabel->vtoc.volume_id, sizeof(sunlabel->vtoc.volume_id)) : NULL;
+               break;
+       case SUN_LABELITEM_RPM:
+               item->name =_("Rpm");
+               item->type = 'j';
+               item->data.num64 = be16_to_cpu(sunlabel->rpm);
+               break;
+       case SUN_LABELITEM_ACYL:
+               item->name =_("Alternate cylinders");
+               item->type = 'j';
+               item->data.num64 = be16_to_cpu(sunlabel->acyl);
+               break;
+       case SUN_LABELITEM_PCYL:
+               item->name =_("Physical cylinders");
+               item->type = 'j';
+               item->data.num64 = be16_to_cpu(sunlabel->pcyl);
+               break;
+       case SUN_LABELITEM_APC:
+               item->name =_("Extra sects/cyl");
+               item->type = 'j';
+               item->data.num64 = be16_to_cpu(sunlabel->apc);
+               break;
+       case SUN_LABELITEM_INTRLV:
+               item->name =_("Interleave");
+               item->type = 'j';
+               item->data.num64 = be16_to_cpu(sunlabel->intrlv);
+               break;
+       default:
+               if (item->id < __FDISK_NLABELITEMS)
+                       rc = 1; /* unssupported generic item */
+               else
+                       rc = 2; /* out of range */
+               break;
        }
 
-       return 0;
+       return rc;
 }
 
 static struct fdisk_parttype *sun_get_parttype(
@@ -1090,7 +1120,7 @@ const struct fdisk_label_operations sun_operations =
        .write          = sun_write_disklabel,
        .verify         = sun_verify_disklabel,
        .create         = sun_create_disklabel,
-       .list           = sun_list_disklabel,
+       .get_item       = sun_get_disklabel_item,
 
        .get_part       = sun_get_partition,
        .set_part       = sun_set_partition,