#include #include "fdiskP.h" /** * SECTION: item * @title: Labelitem * @short_description: disk label items * * The labelitem is label specific items stored in the partition table header. * The information provided by labelitems are not specific to the partitions. * * For example * * * * struct fdisk_labelitem *item = fdisk_new_labelitem(); * * fdisk_get_disklabel_item(cxt, GPT_LABELITEM_ALTLBA, item); * print("Backup header LBA: %ju\n", fdisk_labelitem_get_data_u64(item)); * * fdisk_unref_labelitem(item); * * * * returns LBA of the alternative GPT header. * * See also fdisk_get_disklabel_item(). The IDs are generic (e.g. * FDISK_LABEL_ITEM_*) and label specific ((e.g. GPT_LABELITEM_*). */ /** * fdisk_new_labelitem * * Returns: new instance. * Since: 2.29 */ struct fdisk_labelitem *fdisk_new_labelitem(void) { struct fdisk_labelitem *li = calloc(1, sizeof(*li)); li->refcount = 1; DBG(ITEM, ul_debugobj(li, "alloc")); return li; } /** * fdisk_ref_labelitem: * @li: label item * * Increments reference counter. * Since: 2.29 */ void fdisk_ref_labelitem(struct fdisk_labelitem *li) { if (li) { /* me sure we do not use refcouting for static items */ assert(li->refcount > 0); li->refcount++; } } /** * fdisk_reset_labelitem: * @li: label item * * Zeroize data stored in the @li (does not modify anything in disk label). * * Returns: 0 on success, or <0 in case of error * Since: 2.29 */ int fdisk_reset_labelitem(struct fdisk_labelitem *li) { int refcount; if (!li) return -EINVAL; if (li->type == 's') free(li->data.str); refcount = li->refcount; memset(li, 0, sizeof(*li)); li->refcount = refcount; return 0; } /** * fdisk_unref_labelitem: * @li: label item * * Decrements reference counter, on zero the @li is automatically * deallocated. * * Since: 2.29 */ void fdisk_unref_labelitem(struct fdisk_labelitem *li) { if (!li) return; /* me sure we do not use refcouting for static items */ assert(li->refcount > 0); li->refcount--; if (li->refcount <= 0) { DBG(ITEM, ul_debugobj(li, "free")); fdisk_reset_labelitem(li); free(li); } } /** * fdisk_labelitem_get_name: * @li: label item * * Returns: item name or NULL. * Since: 2.29 */ const char *fdisk_labelitem_get_name(struct fdisk_labelitem *li) { return li ? li->name : NULL; } /** * fdisk_labelitem_get_id: * @li: label item * * Returns: item Id or <0 in case of error. * Since: 2.29 */ int fdisk_labelitem_get_id(struct fdisk_labelitem *li) { return li ? li->id : -EINVAL; } /** * fdisk_labelitem_get_data_u64: * @li: label item * @data: returns data * * Returns: 0 on success, <0 on error * Since: 2.29 */ int fdisk_labelitem_get_data_u64(struct fdisk_labelitem *li, uint64_t *data) { if (!li || li->type != 'j') return -EINVAL; if (data) *data = li->data.num64; return 0; } /** * fdisk_labelitem_get_data_string: * @li: label item * @data: returns data * * Returns: 0 on success, <0 on error. * Since: 2.29 */ int fdisk_labelitem_get_data_string(struct fdisk_labelitem *li, const char **data) { if (!li || li->type != 's') return -EINVAL; if (data) *data = li->data.str; return 0; } /** * fdisk_labelitem_is_string: * @li: label item * * Returns: 0 or 1 * Since: 2.29 */ int fdisk_labelitem_is_string(struct fdisk_labelitem *li) { return li && li->type == 's'; } /** * fdisk_labelitem_is_number: * @li: label item * * Returns: 0 or 1 * Since: 2.29 */ int fdisk_labelitem_is_number(struct fdisk_labelitem *li) { return li && li->type == 'j'; } #ifdef TEST_PROGRAM static int test_listitems(struct fdisk_test *ts, int argc, char *argv[]) { const char *disk = argv[1]; struct fdisk_context *cxt; struct fdisk_labelitem *item; int i = 0, rc; cxt = fdisk_new_context(); item = fdisk_new_labelitem(); fdisk_assign_device(cxt, disk, 1); do { rc = fdisk_get_disklabel_item(cxt, i++, item); switch (rc) { case 0: /* success */ { const char *name = fdisk_labelitem_get_name(item); const char *str; uint64_t num; if (fdisk_labelitem_is_string(item) && fdisk_labelitem_get_data_string(item, &str) == 0) printf("%s: %s\n", name, str); else if (fdisk_labelitem_get_data_u64(item, &num) == 0) printf("%s: %"PRIu64"\n", name, num); break; } case 1: /* item unsupported by label -- ignore */ rc = 0; break; case 2: /* end (out of range) */ break; default: /* error */ break; } } while (rc == 0); fdisk_unref_labelitem(item); fdisk_unref_context(cxt); return rc < 0 ? rc : 0; } int main(int argc, char *argv[]) { struct fdisk_test tss[] = { { "--list-items", test_listitems, " list items" }, { NULL } }; return fdisk_run_test(tss, argc, argv); } #endif