(root)/
util-linux-2.39/
libfdisk/
src/
item.c
       1  
       2  #include <inttypes.h>
       3  
       4  #include "fdiskP.h"
       5  
       6  /**
       7   * SECTION: item
       8   * @title: Labelitem
       9   * @short_description: disk label items
      10   *
      11   * The labelitem is label specific items stored in the partition table header.
      12   * The information provided by labelitems are not specific to the partitions.
      13   *
      14   * For example
      15   *
      16   * <informalexample>
      17   *  <programlisting>
      18   *	struct fdisk_labelitem *item = fdisk_new_labelitem();
      19   *
      20   *	fdisk_get_disklabel_item(cxt, GPT_LABELITEM_ALTLBA, item);
      21   *	print("Backup header LBA: %ju\n", fdisk_labelitem_get_data_u64(item));
      22   *
      23   *	fdisk_unref_labelitem(item);
      24   *  </programlisting>
      25   * </informalexample>
      26   *
      27   * returns LBA of the alternative GPT header.
      28   *
      29   * See also fdisk_get_disklabel_item(). The IDs are generic (e.g.
      30   * FDISK_LABEL_ITEM_*) and label specific ((e.g. GPT_LABELITEM_*).
      31   */
      32  
      33  /**
      34   * fdisk_new_labelitem
      35   *
      36   * Returns: new instance.
      37   * Since: 2.29
      38   */
      39  struct fdisk_labelitem *fdisk_new_labelitem(void)
      40  {
      41  	struct fdisk_labelitem *li = calloc(1, sizeof(*li));
      42  
      43  	if (!li)
      44  		return NULL;
      45  
      46  	li->refcount = 1;
      47  	DBG(ITEM, ul_debugobj(li, "alloc"));
      48  	return li;
      49  }
      50  
      51  /**
      52   * fdisk_ref_labelitem:
      53   * @li: label item
      54   *
      55   * Increments reference counter.
      56   * Since: 2.29
      57   */
      58  void fdisk_ref_labelitem(struct fdisk_labelitem *li)
      59  {
      60  	if (li) {
      61  		/* me sure we do not use refcouting for static items */
      62  		assert(li->refcount > 0);
      63  		li->refcount++;
      64  	}
      65  }
      66  
      67  /**
      68   * fdisk_reset_labelitem:
      69   * @li: label item
      70   *
      71   * Zeroize data stored in the @li (does not modify anything in disk label).
      72   *
      73   * Returns: 0 on success, or <0 in case of error
      74   * Since: 2.29
      75   */
      76  int fdisk_reset_labelitem(struct fdisk_labelitem *li)
      77  {
      78  	int refcount;
      79  
      80  	if (!li)
      81  		return -EINVAL;
      82  	if (li->type == 's')
      83  		free(li->data.str);
      84  
      85  	refcount = li->refcount;
      86  	memset(li, 0, sizeof(*li));
      87  	li->refcount = refcount;
      88  	return 0;
      89  }
      90  
      91  /**
      92   * fdisk_unref_labelitem:
      93   * @li: label item
      94   *
      95   * Decrements reference counter, on zero the @li is automatically
      96   * deallocated.
      97   *
      98   * Since: 2.29
      99   */
     100  void fdisk_unref_labelitem(struct fdisk_labelitem *li)
     101  {
     102  	if (!li)
     103  		return;
     104  
     105  	/* me sure we do not use refcouting for static items */
     106  	assert(li->refcount > 0);
     107  
     108  	li->refcount--;
     109  	if (li->refcount <= 0) {
     110  		DBG(ITEM, ul_debugobj(li, "free"));
     111  		fdisk_reset_labelitem(li);
     112  		free(li);
     113  	}
     114  }
     115  
     116  /**
     117   * fdisk_labelitem_get_name:
     118   * @li: label item
     119   *
     120   * Returns: item name or NULL.
     121   * Since: 2.29
     122   */
     123  const char *fdisk_labelitem_get_name(struct fdisk_labelitem *li)
     124  {
     125  	return li ? li->name : NULL;
     126  }
     127  
     128  /**
     129   * fdisk_labelitem_get_id:
     130   * @li: label item
     131   *
     132   * Returns: item Id or <0 in case of error.
     133   * Since: 2.29
     134   */
     135  int fdisk_labelitem_get_id(struct fdisk_labelitem *li)
     136  {
     137  	return li ? li->id : -EINVAL;
     138  }
     139  
     140  
     141  /**
     142   * fdisk_labelitem_get_data_u64:
     143   * @li: label item
     144   * @data: returns data
     145   *
     146   * Returns: 0 on success, <0 on error
     147   * Since: 2.29
     148   */
     149  int fdisk_labelitem_get_data_u64(struct fdisk_labelitem *li, uint64_t *data)
     150  {
     151  	if (!li || li->type != 'j')
     152  		return -EINVAL;
     153  
     154  	if (data)
     155  		*data = li->data.num64;
     156  	return 0;
     157  }
     158  
     159  /**
     160   * fdisk_labelitem_get_data_string:
     161   * @li: label item
     162   * @data: returns data
     163   *
     164   * Returns: 0 on success, <0 on error.
     165   * Since: 2.29
     166   */
     167  int fdisk_labelitem_get_data_string(struct fdisk_labelitem *li, const char **data)
     168  {
     169  	if (!li || li->type != 's')
     170  		return -EINVAL;
     171  
     172  	if (data)
     173  		*data = li->data.str;
     174  	return 0;
     175  }
     176  
     177  /**
     178   * fdisk_labelitem_is_string:
     179   * @li: label item
     180   *
     181   * Returns: 0 or 1
     182   * Since: 2.29
     183   */
     184  int fdisk_labelitem_is_string(struct fdisk_labelitem *li)
     185  {
     186  	return li && li->type == 's';
     187  }
     188  
     189  /**
     190   * fdisk_labelitem_is_number:
     191   * @li: label item
     192   *
     193   * Returns: 0 or 1
     194   * Since: 2.29
     195   */
     196  int fdisk_labelitem_is_number(struct fdisk_labelitem *li)
     197  {
     198  	return li && li->type == 'j';
     199  }
     200  
     201  #ifdef TEST_PROGRAM
     202  static int test_listitems(struct fdisk_test *ts, int argc, char *argv[])
     203  {
     204  	const char *disk = argv[1];
     205  	struct fdisk_context *cxt;
     206  	struct fdisk_labelitem *item;
     207  	int i = 0, rc;
     208  
     209  	cxt = fdisk_new_context();
     210  	item = fdisk_new_labelitem();
     211  
     212  	fdisk_assign_device(cxt, disk, 1);
     213  
     214  	do {
     215  		rc = fdisk_get_disklabel_item(cxt, i++, item);
     216  		switch (rc) {
     217  		case 0:	/* success */
     218  		{
     219  			const char *name = fdisk_labelitem_get_name(item);
     220  			const char *str;
     221  			uint64_t num;
     222  
     223  			if (fdisk_labelitem_is_string(item)
     224  			    && fdisk_labelitem_get_data_string(item, &str) == 0)
     225  				printf("%s: %s\n", name, str);
     226  			else if (fdisk_labelitem_get_data_u64(item, &num) == 0)
     227  				printf("%s: %"PRIu64"\n", name, num);
     228  			break;
     229  		}
     230  		case 1: /* item unsupported by label -- ignore */
     231  			rc = 0;
     232  			break;
     233  		case 2:	/* end (out of range) */
     234  			break;
     235  		default: /* error */
     236  			break;
     237  		}
     238  	} while (rc == 0);
     239  
     240  	fdisk_unref_labelitem(item);
     241  	fdisk_unref_context(cxt);
     242  	return rc < 0 ? rc : 0;
     243  }
     244  
     245  int main(int argc, char *argv[])
     246  {
     247  	struct fdisk_test tss[] = {
     248  		{ "--list-items",  test_listitems,  "<disk>             list items" },
     249  		{ NULL }
     250  	};
     251  
     252  	return fdisk_run_test(tss, argc, argv);
     253  }
     254  
     255  #endif