9 * @title: Partition types
10 * @short_description: abstraction to partition types
12 * There are two basic types of parttypes, string based (e.g. GPT)
13 * and code/hex based (e.g. MBR).
19 * It's recommended to use fdisk_label_get_parttype_from_code() or
20 * fdisk_label_get_parttype_from_string() for well known types rather
21 * than allocate a new instance.
23 * Returns: new instance.
25 struct fdisk_parttype
*fdisk_new_parttype(void)
27 struct fdisk_parttype
*t
= calloc(1, sizeof(*t
));
30 t
->flags
= FDISK_PARTTYPE_ALLOCATED
;
31 DBG(PARTTYPE
, ul_debugobj(t
, "alloc"));
39 * Increments reference counter for allocated types
41 void fdisk_ref_parttype(struct fdisk_parttype
*t
)
43 if (fdisk_parttype_is_allocated(t
))
48 * fdisk_unref_parttype
49 * @t: partition pointer
51 * Decrements reference counter, on zero the @t is automatically
54 void fdisk_unref_parttype(struct fdisk_parttype
*t
)
56 if (!fdisk_parttype_is_allocated(t
))
60 if (t
->refcount
<= 0) {
61 DBG(PARTTYPE
, ul_debugobj(t
, "free"));
69 * fdisk_parttype_set_name:
73 * Sets type name to allocated partition type, for static types
76 * Return: 0 on success, <0 on error
78 int fdisk_parttype_set_name(struct fdisk_parttype
*t
, const char *str
)
80 if (!t
|| !fdisk_parttype_is_allocated(t
))
82 return strdup_to_struct_member(t
, name
, str
);
86 * fdisk_parttype_set_typestr:
88 * @str: type identifier (e.g. GUID for GPT)
90 * Sets type string to allocated partition type, for static types
91 * it returns -EINVAL. Don't use this function for MBR, see
92 * fdisk_parttype_set_code().
94 * Return: 0 on success, <0 on error
96 int fdisk_parttype_set_typestr(struct fdisk_parttype
*t
, const char *str
)
98 if (!t
|| !fdisk_parttype_is_allocated(t
))
100 return strdup_to_struct_member(t
, typestr
, str
);
104 * fdisk_parttype_set_code:
106 * @code: type identifier (e.g. MBR type codes)
108 * Sets type code to allocated partition type, for static types it returns
109 * -EINVAL. Don't use this function for GPT, see fdisk_parttype_set_typestr().
111 * Return: 0 on success, <0 on error
113 int fdisk_parttype_set_code(struct fdisk_parttype
*t
, int code
)
115 if (!t
|| !fdisk_parttype_is_allocated(t
))
122 * fdisk_label_get_nparttypes:
125 * Returns: number of types supported by label.
127 size_t fdisk_label_get_nparttypes(const struct fdisk_label
*lb
)
131 return lb
->nparttypes
;
135 * fdisk_label_get_parttype:
139 * Returns: return parttype
141 struct fdisk_parttype
*fdisk_label_get_parttype(const struct fdisk_label
*lb
, size_t n
)
143 if (!lb
|| n
>= lb
->nparttypes
)
145 return &lb
->parttypes
[n
];
149 * fdisk_label_get_parttype_shortcut:
152 * @typestr: returns type as string
153 * @shortcut: returns type shortcut string
154 * @alias: returns type alias string
156 * Returns: return 0 on success, <0 on error, 2 for deprecated alias, 1 for @n out of range
160 int fdisk_label_get_parttype_shortcut(const struct fdisk_label
*lb
, size_t n
,
161 const char **typestr
, const char **shortcut
, const char **alias
)
163 const struct fdisk_shortcut
*sc
;
167 if (n
>= lb
->nparttype_cuts
)
170 sc
= &lb
->parttype_cuts
[n
];
174 *shortcut
= sc
->shortcut
;
178 return sc
->deprecated
== 1 ? 2 : 0;
184 * fdisk_label_has_code_parttypes:
187 * Returns: 1 if the label uses code as partition type
188 * identifiers (e.g. MBR) or 0.
190 int fdisk_label_has_code_parttypes(const struct fdisk_label
*lb
)
194 if (lb
->parttypes
&& lb
->parttypes
[0].typestr
)
200 * fdisk_label_has_parttypes_shortcuts
203 * Returns: 1 if the label support shortuts/aliases for partition types or 0.
207 int fdisk_label_has_parttypes_shortcuts(const struct fdisk_label
*lb
)
210 return lb
->nparttype_cuts
? 1 : 0;
215 * fdisk_label_get_parttype_from_code:
217 * @code: code to search for
219 * Search for partition type in label-specific table. The result
220 * is pointer to static array of label types.
222 * Returns: partition type or NULL upon failure or invalid @code.
224 struct fdisk_parttype
*fdisk_label_get_parttype_from_code(
225 const struct fdisk_label
*lb
,
235 for (i
= 0; i
< lb
->nparttypes
; i
++)
236 if (lb
->parttypes
[i
].code
== code
)
237 return &lb
->parttypes
[i
];
242 * fdisk_label_get_parttype_from_string:
244 * @str: string to search for
246 * Search for partition type in label-specific table. The result
247 * is pointer to static array of label types.
249 * Returns: partition type or NULL upon failure or invalid @str.
251 struct fdisk_parttype
*fdisk_label_get_parttype_from_string(
252 const struct fdisk_label
*lb
,
262 for (i
= 0; i
< lb
->nparttypes
; i
++)
263 if (lb
->parttypes
[i
].typestr
264 && strcasecmp(lb
->parttypes
[i
].typestr
, str
) == 0)
265 return &lb
->parttypes
[i
];
271 * fdisk_new_unknown_parttype:
272 * @code: type as number
273 * @typestr: type as string
275 * Allocates new 'unknown' partition type. Use fdisk_unref_parttype() to
278 * Returns: newly allocated partition type, or NULL upon failure.
280 struct fdisk_parttype
*fdisk_new_unknown_parttype(unsigned int code
,
283 struct fdisk_parttype
*t
= fdisk_new_parttype();
288 fdisk_parttype_set_name(t
, _("unknown"));
289 fdisk_parttype_set_code(t
, code
);
290 fdisk_parttype_set_typestr(t
, typestr
);
291 t
->flags
|= FDISK_PARTTYPE_UNKNOWN
;
297 * fdisk_copy_parttype:
298 * @type: type to copy
300 * Use fdisk_unref_parttype() to deallocate.
302 * Returns: newly allocated partition type, or NULL upon failure.
304 struct fdisk_parttype
*fdisk_copy_parttype(const struct fdisk_parttype
*type
)
306 struct fdisk_parttype
*t
= fdisk_new_parttype();
311 fdisk_parttype_set_name(t
, type
->name
);
312 fdisk_parttype_set_code(t
, type
->code
);
313 fdisk_parttype_set_typestr(t
, type
->typestr
);
318 static struct fdisk_parttype
*parttype_from_data(
319 const struct fdisk_label
*lb
,
324 struct fdisk_parttype
*types
, *ret
= NULL
;
335 DBG(LABEL
, ul_debugobj(lb
, " parsing '%s' data", str
));
336 types
= lb
->parttypes
;
338 if (types
[0].typestr
== NULL
) {
341 DBG(LABEL
, ul_debugobj(lb
, " +hex"));
344 code
= strtol(str
, &end
, 16);
346 if (errno
|| *end
!= '\0') {
347 DBG(LABEL
, ul_debugobj(lb
, " failed: %m"));
352 ret
= fdisk_label_get_parttype_from_code(lb
, code
);
354 DBG(LABEL
, ul_debugobj(lb
, " +string"));
356 /* maybe specified by type string (e.g. UUID) */
357 ret
= fdisk_label_get_parttype_from_string(lb
, str
);
360 /* maybe specified by order number */
364 i
= strtol(str
, &end
, 0);
366 if (use_seqnum
&& errno
== 0
367 && *end
== '\0' && i
> 0
368 && i
- 1 < (int) lb
->nparttypes
)
374 DBG(PARTTYPE
, ul_debugobj(ret
, " result '%s'", ret
->name
));
378 static struct fdisk_parttype
*parttype_from_shortcut(
379 const struct fdisk_label
*lb
,
380 const char *str
, int deprecated
)
384 DBG(LABEL
, ul_debugobj(lb
, " parsing '%s' shortcut", str
));
386 for (i
= 0; i
< lb
->nparttype_cuts
; i
++) {
387 const struct fdisk_shortcut
*sc
= &lb
->parttype_cuts
[i
];
389 if (sc
->deprecated
&& !deprecated
)
391 if (sc
->shortcut
&& strcmp(sc
->shortcut
, str
) == 0)
392 return parttype_from_data(lb
, sc
->data
, NULL
, 0);
397 static struct fdisk_parttype
*parttype_from_alias(
398 const struct fdisk_label
*lb
,
399 const char *str
, int deprecated
)
403 DBG(LABEL
, ul_debugobj(lb
, " parsing '%s' alias", str
));
405 for (i
= 0; i
< lb
->nparttype_cuts
; i
++) {
406 const struct fdisk_shortcut
*sc
= &lb
->parttype_cuts
[i
];
408 if (sc
->deprecated
&& !deprecated
)
410 if (sc
->alias
&& strcmp(sc
->alias
, str
) == 0)
411 return parttype_from_data(lb
, sc
->data
, NULL
, 0);
417 * fdisk_label_advparse_parttype:
419 * @str: string to parse from
420 * @flags: FDISK_PARTTYPE_PARSE_*
422 * This function is advanced partition types parser. It parses partition type
423 * from @str according to the label. The function returns a pointer to static
424 * table of the partition types, or newly allocated partition type for unknown
425 * types (see fdisk_parttype_is_unknown(). It's safe to call fdisk_unref_parttype()
428 * The @str may be type data (hex code or UUID), alias or shortcut. For GPT
429 * also sequence number of the type in the list of the supported types.
431 * Returns: pointer to type or NULL on error.
433 struct fdisk_parttype
*fdisk_label_advparse_parttype(
434 const struct fdisk_label
*lb
,
438 struct fdisk_parttype
*res
= NULL
;
439 unsigned int code
= 0;
444 DBG(LABEL
, ul_debugobj(lb
, "parsing '%s' (%s) type", str
, lb
->name
));
446 if ((flags
& FDISK_PARTTYPE_PARSE_DATA
)
447 && !(flags
& FDISK_PARTTYPE_PARSE_DATALAST
))
448 res
= parttype_from_data(lb
, str
, &code
,
449 flags
& FDISK_PARTTYPE_PARSE_SEQNUM
);
451 if (!res
&& (flags
& FDISK_PARTTYPE_PARSE_ALIAS
))
452 res
= parttype_from_alias(lb
, str
,
453 flags
& FDISK_PARTTYPE_PARSE_DEPRECATED
);
455 if (!res
&& (flags
& FDISK_PARTTYPE_PARSE_SHORTCUT
))
456 res
= parttype_from_shortcut(lb
, str
,
457 flags
& FDISK_PARTTYPE_PARSE_DEPRECATED
);
459 if (!res
&& (flags
& FDISK_PARTTYPE_PARSE_DATA
)
460 && (flags
& FDISK_PARTTYPE_PARSE_DATALAST
))
461 res
= parttype_from_data(lb
, str
, &code
,
462 flags
& FDISK_PARTTYPE_PARSE_SEQNUM
);
464 if (!res
&& !(flags
& FDISK_PARTTYPE_PARSE_NOUNKNOWN
)) {
465 if (lb
->parttypes
[0].typestr
)
466 res
= fdisk_new_unknown_parttype(0, str
);
468 res
= fdisk_new_unknown_parttype(code
, NULL
);
472 DBG(PARTTYPE
, ul_debugobj(res
, "returns parsed '%s' [%s] partition type",
473 res
->name
, res
->typestr
? : ""));
478 * fdisk_label_parse_parttype:
480 * @str: string to parse from (type name, UUID, etc.)
482 * Parses partition type from @str according to the label. The function returns
483 * a pointer to static table of the partition types, or newly allocated
484 * partition type for unknown types (see fdisk_parttype_is_unknown(). It's
485 * safe to call fdisk_unref_parttype() for all results.
487 * Note that for GPT it accepts sequence number of UUID.
489 * Returns: pointer to type or NULL on error.
491 struct fdisk_parttype
*fdisk_label_parse_parttype(
492 const struct fdisk_label
*lb
,
495 return fdisk_label_advparse_parttype(lb
, str
, FDISK_PARTTYPE_PARSE_DATA
);
499 * fdisk_parttype_get_string:
502 * Returns: partition type string (e.g. GUID for GPT)
504 const char *fdisk_parttype_get_string(const struct fdisk_parttype
*t
)
507 return t
->typestr
&& *t
->typestr
? t
->typestr
: NULL
;
511 * fdisk_parttype_get_code:
514 * Returns: partition type code (e.g. for MBR)
516 unsigned int fdisk_parttype_get_code(const struct fdisk_parttype
*t
)
523 * fdisk_parttype_get_name:
526 * Returns: partition type human readable name
528 const char *fdisk_parttype_get_name(const struct fdisk_parttype
*t
)
535 * fdisk_parttype_is_unknown:
538 * Checks for example result from fdisk_label_parse_parttype().
540 * Returns: 1 is type is "unknown" or 0.
542 int fdisk_parttype_is_unknown(const struct fdisk_parttype
*t
)
544 return t
&& (t
->flags
& FDISK_PARTTYPE_UNKNOWN
) ? 1 : 0;