ptes[i].part_table->sys_ind);
}
-
-char *partition_type(struct fdisk_context *cxt, unsigned char type)
-{
- int i;
- struct fdisk_parttype *types = cxt->label->parttypes;
-
- for (i=0; types[i].name; i++)
- if (types[i].type == type)
- return _(types[i].name);
-
- return NULL;
-}
-
void list_partition_types(struct fdisk_context *cxt)
{
struct fdisk_parttype *types;
return *line_ptr;
}
-int
-read_hex(struct fdisk_context *cxt)
+struct fdisk_parttype *read_partition_type(struct fdisk_context *cxt)
{
- int hex;
-
- while (1)
- {
- read_char(_("Hex code (type L to list codes): "));
- if (tolower(*line_ptr) == 'l')
- list_partition_types(cxt);
- else if (isxdigit (*line_ptr))
- {
- hex = 0;
- do
- hex = hex << 4 | hex_val(*line_ptr++);
- while (isxdigit(*line_ptr));
- return hex;
- }
- }
+ if (!cxt || !cxt->label || !cxt->label->nparttypes)
+ return NULL;
+
+ do {
+ size_t sz;
+
+ if (cxt->label->parttypes[0].typestr)
+ read_chars(_("Partition type (type L to list all types): "));
+ else
+ read_chars(_("Hex code (type L to list all codes): "));
+
+ sz = strlen(line_ptr);
+ if (!sz || line_ptr[sz - 1] != '\n' || sz == 1)
+ continue;
+ line_ptr[sz - 1] = '\0';
+
+ if (tolower(*line_ptr) == 'l')
+ list_partition_types(cxt);
+ else
+ return fdisk_parse_parttype(cxt, line_ptr);
+ } while (1);
+
+ return NULL;
}
+
unsigned int
read_int_with_suffix(struct fdisk_context *cxt,
unsigned int low, unsigned int dflt, unsigned int high,
static void change_sysid(struct fdisk_context *cxt)
{
- const char *temp;
- int i, sys, origsys;
+ int i;
+ struct fdisk_parttype *t, *org_t;
struct partition *p;
i = get_existing_partition(cxt, 0, partitions);
if (i == -1)
return;
p = ptes[i].part_table;
- origsys = sys = get_sysid(cxt, i);
+
+ /* TODO: add get_partition_type(xt, partn) to API */
+ org_t = t = fdisk_get_parttype_from_code(cxt, get_sysid(cxt, i));
/* if changing types T to 0 is allowed, then
the reverse change must be allowed, too */
- if (!sys && disklabel != SGI_LABEL && disklabel != SUN_LABEL && !get_nr_sects(p))
+ if (!t && disklabel != SGI_LABEL && disklabel != SUN_LABEL && !get_nr_sects(p))
printf(_("Partition %d does not exist yet!\n"), i + 1);
else while (1) {
- sys = read_hex (cxt);
+ t = read_partition_type(cxt);
- if (!sys && disklabel != SGI_LABEL && disklabel != SUN_LABEL) {
+ if (!t && disklabel != SGI_LABEL && disklabel != SUN_LABEL) {
printf(_("Type 0 means free space to many systems\n"
"(but not to Linux). Having partitions of\n"
"type 0 is probably unwise. You can delete\n"
/* break; */
}
+ if (!t)
+ continue;
+
if (disklabel != SGI_LABEL && disklabel != SUN_LABEL) {
- if (IS_EXTENDED (sys) != IS_EXTENDED (p->sys_ind)) {
+ if (IS_EXTENDED (t->type) != IS_EXTENDED (p->sys_ind)) {
printf(_("You cannot change a partition into"
" an extended one or vice versa\n"
"Delete it first.\n"));
}
}
- if (sys < 256) {
- if (disklabel == SUN_LABEL && i == 2 && sys != SUN_TAG_BACKUP)
+ /* TODO: add set_partition_type(cxt, npart, type) API */
+ if (t->type < 256) {
+ if (disklabel == SUN_LABEL && i == 2 && t->type != SUN_TAG_BACKUP)
printf(_("Consider leaving partition 3 "
"as Whole disk (5),\n"
"as SunOS/Solaris expects it and "
"even Linux likes it.\n\n"));
- if (disklabel == SGI_LABEL && ((i == 10 && sys != ENTIRE_DISK)
- || (i == 8 && sys != 0)))
+ if (disklabel == SGI_LABEL && ((i == 10 && t->type != ENTIRE_DISK)
+ || (i == 8 && t->type != 0)))
printf(_("Consider leaving partition 9 "
"as volume header (0),\nand "
"partition 11 as entire volume (6), "
"as IRIX expects it.\n\n"));
- if (sys == origsys)
- break;
+ if (t == org_t)
+ goto nochange;
+
if (disklabel == SUN_LABEL) {
- ptes[i].changed = sun_change_sysid(cxt, i, sys);
+ ptes[i].changed = sun_change_sysid(cxt, i, t->type);
} else
if (disklabel == SGI_LABEL) {
- ptes[i].changed = sgi_change_sysid(cxt, i, sys);
+ ptes[i].changed = sgi_change_sysid(cxt, i, t->type);
} else {
- p->sys_ind = sys;
+ p->sys_ind = t->type;
ptes[i].changed = 1;
}
- temp = partition_type(cxt, sys) ? : _("Unknown");
+
if (ptes[i].changed)
- printf (_("Changed system type of partition %d "
- "to %x (%s)\n"), i + 1, sys, temp);
- else
- printf (_("System type of partition %d is unchanged: "
- "%x (%s)\n"), i + 1, sys, temp);
- if (is_dos_partition(origsys) ||
- is_dos_partition(sys))
+ printf (_("Changed type of partition '%s' to '%s'\n"),
+ org_t ? org_t->name : _("Unknown"),
+ t ? t->name : _("Unknown"));
+ else {
+nochange:
+ printf (_("Type of partition %d is unchanged: %s\n"),
+ i + 1,
+ org_t ? org_t->name : _("Unknown"));
+ }
+
+ if (is_dos_partition(t->type) || is_dos_partition(t->type))
dos_changed = 1;
break;
}
}
+
+ fdisk_free_parttype(t);
+ fdisk_free_parttype(org_t);
}
/* check_consistency() and long2chs() added Sat Mar 6 12:28:16 1993,
static void
list_table(struct fdisk_context *cxt, int xtra) {
struct partition *p;
- char *type;
int i, w;
if (disklabel == SUN_LABEL) {
unsigned int psects = get_nr_sects(p);
unsigned int pblocks = psects;
unsigned int podd = 0;
+ struct fdisk_parttype *type =
+ fdisk_get_parttype_from_code(cxt, p->sys_ind);
if (cxt->sector_size < 1024) {
pblocks /= (1024 / cxt->sector_size);
- (psects ? 1 : 0)),
/* odd flag on end */ (unsigned long) pblocks, podd ? '+' : ' ',
/* type id */ p->sys_ind,
-/* type name */ (type = partition_type(cxt, p->sys_ind)) ?
- type : _("Unknown"));
+/* type name */ type ? type->name : _("Unknown"));
check_consistency(cxt, p, i);
check_alignment(cxt, get_partition_start(pe), i);
}
{
char *str = size_to_human_string(SIZE_SUFFIX_3LETTER | SIZE_SUFFIX_SPACE,
(uint64_t)(stop - start + 1) * cxt->sector_size);
- printf(_("Partition %d of type %s and of size %s is set\n"), num, partition_type(cxt, sysid), str);
+ struct fdisk_parttype *t = fdisk_get_parttype_from_code(cxt, sysid);
+
+ printf(_("Partition %d of type %s and of size %s is set\n"),
+ num, t ? t->name : _("Unknown"), str);
free(str);
}
*/
struct fdisk_parttype {
unsigned int type; /* type as number or zero */
- char *name; /* description */
+ const char *name; /* description */
char *typestr; /* type as string or NULL */
+
+ unsigned int flags; /* FDISK_PARTTYPE_* flags */
+};
+
+enum {
+ FDISK_PARTTYPE_UNKNOWN = (1 << 1),
+ FDISK_PARTTYPE_INVISIBLE = (1 << 2),
+ FDISK_PARTTYPE_ALLOCATED = (1 << 3)
};
+#define fdisk_parttype_is_unknown(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_UNKNONW))
+#define fdisk_parttype_is_invisible(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_INVISIBLE))
+#define fdisk_parttype_is_allocated(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_ALLOCATED))
+
/*
* Legacy CHS based geometry
*/
/* array with partition types */
struct fdisk_parttype *parttypes;
+ size_t nparttypes; /* number of items in parttypes[] */
/* probe disk label */
int (*probe)(struct fdisk_context *cxt);
extern int fdisk_verify_disklabel(struct fdisk_context *cxt);
extern int fdisk_create_disklabel(struct fdisk_context *cxt, const char *name);
+extern size_t fdisk_get_nparttypes(struct fdisk_context *cxt);
+extern struct fdisk_parttype *fdisk_get_parttype_from_code(struct fdisk_context *cxt,
+ unsigned int code);
+extern struct fdisk_parttype *fdisk_get_parttype_from_string(struct fdisk_context *cxt,
+ const char *str);
+extern struct fdisk_parttype *fdisk_parse_parttype(struct fdisk_context *cxt, const char *str);
+
+extern void fdisk_free_parttype(struct fdisk_parttype *type);
+
/* prototypes for fdisk.c */
extern char *line_ptr;
extern int partitions;
extern void list_partition_types(struct fdisk_context *cxt);
extern int read_line (int *asked);
extern char read_char(char *mesg);
-extern int read_hex(struct fdisk_context *cxt);
+extern struct fdisk_parttype *read_partition_type(struct fdisk_context *cxt);
extern void reread_partition_table(struct fdisk_context *cxt, int leave);
extern struct partition *get_part_table(int);
extern unsigned int read_int(struct fdisk_context *cxt,
xbsd_change_fstype (struct fdisk_context *cxt)
{
int i;
+ struct fdisk_parttype *t;
i = xbsd_get_part_index (xbsd_dlabel.d_npartitions);
- xbsd_dlabel.d_partitions[i].p_fstype = read_hex (cxt);
+ t = read_partition_type(cxt);
+
+ if (t) {
+ xbsd_dlabel.d_partitions[i].p_fstype = t->type;
+ fdisk_free_parttype(t);
+ }
}
static int
{
.name = "bsd",
.parttypes = xbsd_fstypes,
+ .nparttypes = ARRAY_SIZE(xbsd_fstypes),
.probe = osf_probe_label,
.write = xbsd_write_disklabel,
{
.name = "dos",
.parttypes = dos_parttypes,
+ .nparttypes = ARRAY_SIZE(dos_parttypes),
+
.probe = dos_probe_label,
.write = dos_write_disklabel,
.verify = dos_verify_disklabel,
sgi_list_table(struct fdisk_context *cxt, int xtra) {
int i, w;
int kpi = 0; /* kernel partition ID */
- char *type;
w = strlen(cxt->dev_path);
if (sgi_get_num_sectors(cxt, i) || debug) {
uint32_t start = sgi_get_start_sector(cxt, i);
uint32_t len = sgi_get_num_sectors(cxt, i);
+ struct fdisk_parttype *t =
+ fdisk_get_parttype_from_code(cxt, sgi_get_sysid(cxt, i));
+
kpi++; /* only count nonempty partitions */
printf(
"%2d: %s %4s %9ld %9ld %9ld %2x %s\n",
/* start */ (long) scround(start),
/* end */ (long) scround(start+len)-1,
/* no odd flag on end */ (long) len,
-/* type id */ sgi_get_sysid(cxt, i),
-/* type name */ (type = partition_type(cxt, sgi_get_sysid(cxt, i)))
- ? type : _("Unknown"));
+/* type id */ t ? t->type : sgi_get_sysid(cxt, i),
+/* type name */ t ? t->name : _("Unknown"));
}
}
printf(_("----- Bootinfo -----\nBootfile: %s\n"
{
.name = "sgi",
.parttypes = sgi_parttypes,
+ .nparttypes = ARRAY_SIZE(sgi_parttypes),
.probe = sgi_probe_label,
.write = sgi_write_disklabel,
void sun_list_table(struct fdisk_context *cxt, int xtra)
{
int i, w;
- char *type;
w = strlen(cxt->dev_path);
if (xtra)
if (part->num_sectors) {
uint32_t start = SSWAP32(part->start_cylinder) * cxt->geom.heads * cxt->geom.sectors;
uint32_t len = SSWAP32(part->num_sectors);
+ struct fdisk_parttype *t = fdisk_get_parttype_from_code(cxt, SSWAP16(tag->tag));
+
printf(
"%s %c%c %9lu %9lu %9lu%c %2x %s\n",
/* device */ partname(cxt->dev_path, i+1, w),
/* end */ (unsigned long) scround(start+len),
/* odd flag on end */ (unsigned long) len / 2, len & 1 ? '+' : ' ',
/* type id */ SSWAP16(tag->tag),
-/* type name */ (type = partition_type(cxt, SSWAP16(tag->tag)))
- ? type : _("Unknown"));
+/* type name */ t ? t->name : _("Unknown"));
}
}
}
{
.name = "sun",
.parttypes = sun_parttypes,
+ .nparttypes = ARRAY_SIZE(sun_parttypes),
.probe = sun_probe_label,
.write = sun_write_disklabel,
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
+#include <ctype.h>
#ifdef HAVE_LIBBLKID
#include <blkid.h>
#endif
free(cxt->firstsector);
free(cxt);
}
+
+/*
+ * fdisk_get_nparttypes:
+ *
+ * Returns: number of partition types supported by the current label
+ */
+size_t fdisk_get_nparttypes(struct fdisk_context *cxt)
+{
+ if (!cxt || !cxt->label)
+ return 0;
+
+ return cxt->label->nparttypes;
+}
+struct fdisk_parttype *fdisk_get_parttype_from_code(
+ struct fdisk_context *cxt,
+ unsigned int code)
+{
+ size_t i;
+
+ if (!fdisk_get_nparttypes(cxt))
+ return NULL;
+
+ for (i = 0; i < cxt->label->nparttypes; i++)
+ if (cxt->label->parttypes[i].type == code)
+ return &cxt->label->parttypes[i];
+
+ return NULL;
+}
+
+struct fdisk_parttype *fdisk_get_parttype_from_string(
+ struct fdisk_context *cxt,
+ const char *str)
+{
+ size_t i;
+
+ if (!fdisk_get_nparttypes(cxt))
+ 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;
+}
+
+static struct fdisk_parttype *mk_unknown_partype(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;
+
+ return t;
+}
+
+/*
+ * fdisk_parse_parttype
+ * @cxt: fdisk context
+ * @str: string
+ *
+ * Returns pointer to static table of the partition types, or newly allocated
+ * partition type if @unknown is not NULL and partition type in @str is
+ * unknown, or NULL in case of error.
+ */
+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 (!fdisk_get_nparttypes(cxt))
+ return NULL;
+
+ types = cxt->label->parttypes;
+
+ if (types[0].typestr == NULL && isxdigit(*str)) {
+
+ errno = 0;
+ code = strtol(str, &end, 16);
+
+ if (errno || *end != '\0')
+ return NULL;
+
+ ret = fdisk_get_parttype_from_code(cxt, code);
+ if (ret)
+ return ret;
+ } else {
+ int i;
+
+ /* maybe specified by type string (e.g. UUID) */
+ ret = fdisk_get_parttype_from_string(cxt, str);
+ if (ret)
+ return ret;
+
+ /* maybe specified by order number */
+ errno = 0;
+ i = strtol(str, &end, 0);
+ if (errno == 0 && *end == '\0' && i < (int) fdisk_get_nparttypes(cxt))
+ return &types[i];
+ }
+
+ return mk_unknown_partype(code, typestr);
+}
+
+/*
+ * fdisk_free_parttype:
+ *
+ * Free the @type.
+ */
+void fdisk_free_parttype(struct fdisk_parttype *t)
+{
+ if (t && (t->flags & FDISK_PARTTYPE_ALLOCATED)) {
+ free(t->typestr);
+ free(t);
+ }
+}