#include <ctype.h>
#include "nls.h"
#include "fdiskP.h"
/**
* fdisk_get_parttype_from_code:
* @cxt: fdisk context
* @code: code to search for
*
* Search in lable-specific table of supported partition types by code.
*
* Returns partition type or NULL upon failure or invalid @code.
*/
struct fdisk_parttype *fdisk_get_parttype_from_code(
struct fdisk_context *cxt,
unsigned int code)
{
size_t i;
if (!cxt->label->nparttypes)
return NULL;
for (i = 0; i < cxt->label->nparttypes; i++)
if (cxt->label->parttypes[i].type == code)
return &cxt->label->parttypes[i];
return NULL;
}
/**
* fdisk_get_parttype_from_string:
* @cxt: fdisk context
* @str: string to search for
*
* Search in lable-specific table of supported partition types by typestr.
*
* Returns partition type or NULL upon failure or invalid @str.
*/
struct fdisk_parttype *fdisk_get_parttype_from_string(
struct fdisk_context *cxt,
const char *str)
{
size_t i;
if (!cxt->label->nparttypes)
return NULL;
for (i = 0; i < cxt->label->nparttypes; i++)
if (cxt->label->parttypes[i].typestr
&&strcasecmp(cxt->label->parttypes[i].typestr, str) == 0)
return &cxt->label->parttypes[i];
return NULL;
}
/**
* fdisk_new_unknown_parttype:
* @type: type as number
* @typestr: type as string
* Allocates new 'unknown' partition type. Use fdisk_free_parttype() to
* deallocate.
*
* Returns newly allocated partition type, or NULL upon failure.
*/
struct fdisk_parttype *fdisk_new_unknown_parttype(unsigned int type,
const char *typestr)
{
struct fdisk_parttype *t;
t = calloc(1, sizeof(*t));
if (!t)
return NULL;
if (typestr) {
t->typestr = strdup(typestr);
if (!t->typestr) {
free(t);
return NULL;
}
}
t->name = _("unknown");
t->type = type;
t->flags |= FDISK_PARTTYPE_UNKNOWN | FDISK_PARTTYPE_ALLOCATED;
DBG(PARTTYPE, ul_debugobj(t, "allocated new unknown type"));
return t;
}
/**
* fdisk_parse_parttype:
* @cxt: fdisk context
* @str: string to parse from
*
* Returns pointer to static table of the partition types, or newly allocated
* partition type for unknown types. It's safe to call fdisk_free_parttype()
* for all results.
*/
struct fdisk_parttype *fdisk_parse_parttype(
struct fdisk_context *cxt,
const char *str)
{
struct fdisk_parttype *types, *ret;
unsigned int code = 0;
char *typestr = NULL, *end = NULL;
if (!cxt->label->nparttypes)
return NULL;
DBG(CXT, ul_debugobj(cxt, "parsing '%s' partition type", str));
types = cxt->label->parttypes;
if (types[0].typestr == NULL && isxdigit(*str)) {
errno = 0;
code = strtol(str, &end, 16);
if (errno || *end != '\0') {
DBG(CXT, ul_debugobj(cxt, "parsing failed: %m"));
return NULL;
}
ret = fdisk_get_parttype_from_code(cxt, code);
if (ret)
goto done;
} else {
int i;
/* maybe specified by type string (e.g. UUID) */
ret = fdisk_get_parttype_from_string(cxt, str);
if (ret)
goto done;
/* maybe specified by order number */
errno = 0;
i = strtol(str, &end, 0);
if (errno == 0 && *end == '\0' && i > 0
&& i - 1 < (int) cxt->label->nparttypes) {
ret = &types[i - 1];
goto done;
}
}
ret = fdisk_new_unknown_parttype(code, typestr);
done:
DBG(PARTTYPE, ul_debugobj(ret, "returns '%s' partition type", ret->name));
return ret;
}
/**
* fdisk_free_parttype:
* @t: new type
*
* Free the @type.
*/
void fdisk_free_parttype(struct fdisk_parttype *t)
{
if (t && (t->flags & FDISK_PARTTYPE_ALLOCATED)) {
DBG(PARTTYPE, ul_debugobj(t, "free"));
free(t->typestr);
free(t);
}
}