#include "gpt.h"
-int MBRbuffer_changed;
-
#define hex_val(c) ({ \
char _c = (c); \
isdigit(_c) ? _c - '0' : \
return ptes[i].part_table;
}
-void
-set_all_unchanged(void) {
- int i;
-
- for (i = 0; i < MAXIMUM_PARTS; i++)
- ptes[i].changed = 0;
-}
-
-void
-set_changed(int i) {
- ptes[i].changed = 1;
-}
-
static int
is_garbage_table(void) {
int i;
}
}
-static int is_partition_table_changed(void)
-{
- int i;
-
- for (i = 0; i < partitions; i++)
- if (ptes[i].changed)
- return 1;
- return 0;
-}
-
-static void maybe_exit(int rc, int *asked)
+static void maybe_exit(struct fdisk_context *cxt, int rc, int *asked)
{
char line[LINE_LENGTH];
+ assert(cxt);
+ assert(cxt->label);
+
putchar('\n');
if (asked)
*asked = 0;
- if (is_partition_table_changed() || MBRbuffer_changed) {
+ if (fdisk_label_is_changed(cxt->label)) {
fprintf(stderr, _("Do you really want to quit? "));
if (!fgets(line, LINE_LENGTH, stdin) || rpmatch(line) == 1)
- exit(rc);
+ goto leave;
if (asked)
*asked = 1;
- } else
- exit(rc);
+ return;
+ }
+leave:
+ fdisk_free_context(cxt);
+ exit(rc);
}
/* read line; return 0 or first char */
-int
-read_line(int *asked)
+int read_line(struct fdisk_context *cxt, int *asked)
{
line_ptr = line_buffer;
if (!fgets(line_buffer, LINE_LENGTH, stdin)) {
- maybe_exit(1, asked);
+ maybe_exit(cxt, 1, asked);
return 0;
}
if (asked)
return *line_ptr;
}
-char
-read_char(char *mesg)
+char read_char(struct fdisk_context *cxt, char *mesg)
{
do {
fputs(mesg, stdout);
fflush (stdout); /* requested by niles@scyld.com */
- } while (!read_line(NULL));
+
+ } while (!read_line(cxt, NULL));
+
return *line_ptr;
}
-char
-read_chars(char *mesg)
+char read_chars(struct fdisk_context *cxt, char *mesg)
{
int rc, asked = 0;
do {
fputs(mesg, stdout);
fflush (stdout); /* niles@scyld.com */
- rc = read_line(&asked);
+ rc = read_line(cxt, &asked);
} while (asked);
if (!rc) {
size_t sz;
if (cxt->label->parttypes[0].typestr)
- read_chars(_("Partition type (type L to list all types): "));
+ read_chars(cxt, _("Partition type (type L to list all types): "));
else
- read_chars(_("Hex code (type L to list all codes): "));
+ read_chars(cxt, _("Hex code (type L to list all codes): "));
sz = strlen(line_ptr);
if (!sz || line_ptr[sz - 1] != '\n' || sz == 1)
int use_default = default_ok;
/* ask question and read answer */
- while (read_chars(ms) != '\n' && !isdigit(*line_ptr)
+ while (read_chars(cxt, ms) != '\n' && !isdigit(*line_ptr)
&& *line_ptr != '-' && *line_ptr != '+')
continue;
}
static void
-toggle_active(int i) {
+toggle_active(struct fdisk_context *cxt, int i) {
struct pte *pe = &ptes[i];
struct partition *p = pe->part_table;
i + 1);
p->boot_ind = (p->boot_ind ? 0 : ACTIVE_FLAG);
pe->changed = 1;
+ fdisk_label_set_changed(cxt->label, 1);
}
static void toggle_dos_compatibility_flag(struct fdisk_context *cxt)
while(1) {
putchar('\n');
- c = tolower(read_char(_("Expert command (m for help): ")));
+ c = tolower(read_char(cxt, _("Expert command (m for help): ")));
switch (c) {
case 'a':
if (fdisk_is_disklabel(cxt, SUN))
while (1) {
putchar('\n');
- c = tolower(read_char(_("Command (m for help): ")));
+ c = tolower(read_char(cxt, _("Command (m for help): ")));
switch (c) {
case 'a':
if (fdisk_is_disklabel(cxt, DOS))
- toggle_active(get_partition(cxt, 1, partitions));
+ toggle_active(cxt, get_partition(cxt, 1, partitions));
else if (fdisk_is_disklabel(cxt, SUN))
toggle_sunflags(cxt, get_partition(cxt, 1, partitions),
SUN_FLAG_UNMNT);
extern void fatal(struct fdisk_context *cxt, enum failure why);
extern int get_partition(struct fdisk_context *cxt, int warn, int max);
extern void list_partition_types(struct fdisk_context *cxt);
-extern int read_line (int *asked);
-extern char read_char(char *mesg);
+extern int read_line(struct fdisk_context *cxt, int *asked);
+extern char read_char(struct fdisk_context *cxt, char *mesg);
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 void fill_bounds(sector_t *first, sector_t *last);
extern char *partition_type(struct fdisk_context *cxt, unsigned char type);
-extern char read_chars(char *mesg);
-extern void set_changed(int);
-extern void set_all_unchanged(void);
+extern char read_chars(struct fdisk_context *cxt, char *mesg);
extern int warn_geometry(struct fdisk_context *cxt);
extern void warn_limits(struct fdisk_context *cxt);
extern unsigned int read_int_with_suffix(struct fdisk_context *cxt,
extern sector_t get_nr_sects(struct partition *p);
extern int nowarn;
-extern int MBRbuffer_changed;
/* start_sect and nr_sects are stored little endian on all machines */
/* moreover, they are not aligned correctly */
static int xbsd_delete_part (struct fdisk_context *cxt,
struct fdisk_label *lb, int partnum);
-static void xbsd_edit_disklabel (void);
+static void xbsd_edit_disklabel (struct fdisk_context *cxt);
static void xbsd_write_bootstrap (struct fdisk_context *cxt);
static void xbsd_change_fstype (struct fdisk_context *cxt, struct fdisk_label *lb);
-static int xbsd_get_part_index (int max);
-static int xbsd_check_new_partition (int *i);
+static int xbsd_get_part_index (struct fdisk_context *cxt, int max);
+static int xbsd_check_new_partition (struct fdisk_context *cxt, int *i);
static unsigned short xbsd_dkcksum (struct xbsd_disklabel *lp);
static int xbsd_initlabel (struct fdisk_context *cxt,
struct partition *p, struct xbsd_disklabel *d,
char mesg[256];
int i, rc;
- rc = xbsd_check_new_partition(&i);
+ rc = xbsd_check_new_partition(cxt, &i);
if (rc)
return rc;
#endif
snprintf (mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
- begin = read_int (cxt, bsd_cround (begin), bsd_cround (begin), bsd_cround (end),
+ begin = read_int(cxt, bsd_cround (begin), bsd_cround (begin), bsd_cround (end),
0, mesg);
if (display_in_cyl_units)
xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED;
lb->nparts_cur = xbsd_dlabel.d_npartitions;
+ fdisk_label_set_changed(lb, 1);
return 0;
}
#endif
while (1) {
- c = read_char (_("Do you want to create a disklabel? (y/n) "));
+ c = read_char(cxt, _("Do you want to create a disklabel? (y/n) "));
if (tolower(c) == 'y') {
if (xbsd_initlabel (cxt,
#if defined (__alpha__) || defined (__powerpc__) || defined (__hppa__) || \
while (1) {
putchar ('\n');
- switch (tolower (read_char (_("BSD disklabel command (m for help): ")))) {
+ switch (tolower (read_char(cxt, _("BSD disklabel command (m for help): ")))) {
case 'd':
- xbsd_delete_part(cxt, cxt->label, xbsd_get_part_index(xbsd_dlabel.d_npartitions));
+ xbsd_delete_part(cxt, cxt->label,
+ xbsd_get_part_index(cxt, xbsd_dlabel.d_npartitions));
break;
case 'e':
- xbsd_edit_disklabel ();
+ xbsd_edit_disklabel (cxt);
break;
case 'i':
xbsd_write_bootstrap (cxt);
xbsd_dlabel.d_npartitions--;
lb->nparts_cur = xbsd_dlabel.d_npartitions;
+ fdisk_label_set_changed(lb, 1);
return 0;
}
}
}
-static int
-edit_int (int def, char *mesg)
+static unsigned long
+edit_int(struct fdisk_context *cxt, unsigned long def, char *mesg)
{
do {
fputs (mesg, stdout);
- printf (" (%d): ", def);
- if (!read_line (NULL))
+ printf (" (%lu): ", def);
+ if (!read_line(cxt, NULL))
return def;
- }
- while (!isdigit (*line_ptr));
- return atoi (line_ptr);
+ } while (!isdigit (*line_ptr));
+
+ return strtoul(line_ptr, NULL, 10); /* TODO check it! */
}
static void
-xbsd_edit_disklabel (void)
+xbsd_edit_disklabel(struct fdisk_context *cxt)
{
struct xbsd_disklabel *d;
d = &xbsd_dlabel;
#if defined (__alpha__) || defined (__ia64__)
- d -> d_secsize = (unsigned long) edit_int ((unsigned long) d -> d_secsize ,_("bytes/sector"));
- d -> d_nsectors = (unsigned long) edit_int ((unsigned long) d -> d_nsectors ,_("sectors/track"));
- d -> d_ntracks = (unsigned long) edit_int ((unsigned long) d -> d_ntracks ,_("tracks/cylinder"));
- d -> d_ncylinders = (unsigned long) edit_int ((unsigned long) d -> d_ncylinders ,_("cylinders"));
+ d -> d_secsize = edit_int(cxt, d->d_secsize ,_("bytes/sector"));
+ d -> d_nsectors = edit_int(cxt, d->d_nsectors ,_("sectors/track"));
+ d -> d_ntracks = edit_int(cxt, d->d_ntracks ,_("tracks/cylinder"));
+ d -> d_ncylinders = edit_int(cxt, d->d_ncylinders ,_("cylinders"));
#endif
/* d -> d_secpercyl can be != d -> d_nsectors * d -> d_ntracks */
while (1)
{
- d -> d_secpercyl = (unsigned long) edit_int ((unsigned long) d -> d_nsectors * d -> d_ntracks,
+ d -> d_secpercyl = edit_int(cxt, (unsigned long) d->d_nsectors * d -> d_ntracks,
_("sectors/cylinder"));
if (d -> d_secpercyl <= d -> d_nsectors * d -> d_ntracks)
break;
printf (_("Must be <= sectors/track * tracks/cylinder (default).\n"));
}
- d -> d_rpm = (unsigned short) edit_int ((unsigned short) d -> d_rpm ,_("rpm"));
- d -> d_interleave = (unsigned short) edit_int ((unsigned short) d -> d_interleave,_("interleave"));
- d -> d_trackskew = (unsigned short) edit_int ((unsigned short) d -> d_trackskew ,_("trackskew"));
- d -> d_cylskew = (unsigned short) edit_int ((unsigned short) d -> d_cylskew ,_("cylinderskew"));
- d -> d_headswitch = (unsigned long) edit_int ((unsigned long) d -> d_headswitch ,_("headswitch"));
- d -> d_trkseek = (unsigned long) edit_int ((unsigned long) d -> d_trkseek ,_("track-to-track seek"));
+ d -> d_rpm = (unsigned short) edit_int(cxt, d->d_rpm ,_("rpm"));
+ d -> d_interleave = (unsigned short) edit_int(cxt, d->d_interleave,_("interleave"));
+ d -> d_trackskew = (unsigned short) edit_int(cxt, d->d_trackskew ,_("trackskew"));
+ d -> d_cylskew = (unsigned short) edit_int(cxt, d->d_cylskew ,_("cylinderskew"));
+ d -> d_headswitch = edit_int(cxt, d->d_headswitch ,_("headswitch"));
+ d -> d_trkseek = edit_int(cxt, d->d_trkseek ,_("track-to-track seek"));
d -> d_secperunit = d -> d_secpercyl * d -> d_ncylinders;
}
printf (_("Bootstrap: %sboot -> boot%s (%s): "),
dkbasename, dkbasename, dkbasename);
- if (read_line (NULL)) {
+ if (read_line(cxt, NULL)) {
line_ptr[strlen (line_ptr)-1] = '\0';
dkbasename = line_ptr;
}
static void
xbsd_change_fstype (
struct fdisk_context *cxt,
- struct fdisk_label *lb __attribute__((__unused__)))
+ struct fdisk_label *lb)
{
int i;
struct fdisk_parttype *t;
- i = xbsd_get_part_index (xbsd_dlabel.d_npartitions);
+ i = xbsd_get_part_index (cxt, xbsd_dlabel.d_npartitions);
t = read_partition_type(cxt);
if (t) {
xbsd_dlabel.d_partitions[i].p_fstype = t->type;
fdisk_free_parttype(t);
+ fdisk_label_set_changed(lb, 1);
}
}
static int
-xbsd_get_part_index (int max)
+xbsd_get_part_index(struct fdisk_context *cxt, int max)
{
char prompt[256];
char l;
snprintf (prompt, sizeof(prompt), _("Partition (a-%c): "), 'a' + max - 1);
do
- l = tolower (read_char (prompt));
+ l = tolower(read_char(cxt, prompt));
while (l < 'a' || l > 'a' + max - 1);
return l - 'a';
}
static int
-xbsd_check_new_partition (int *i) {
+xbsd_check_new_partition(struct fdisk_context *cxt, int *i) {
/* room for more? various BSD flavours have different maxima */
if (xbsd_dlabel.d_npartitions == BSD_MAXPARTITIONS) {
}
}
- *i = xbsd_get_part_index (BSD_MAXPARTITIONS);
+ *i = xbsd_get_part_index(cxt, BSD_MAXPARTITIONS);
if (*i >= xbsd_dlabel.d_npartitions)
xbsd_dlabel.d_npartitions = (*i) + 1;
#endif
if (lseek (cxt->dev_fd, (off_t) sector * SECTOR_SIZE, SEEK_SET) == -1)
- fatal (cxt, unable_to_seek);
+ return 0;
if (BSD_BBSIZE != read (cxt->dev_fd, disklabelbuffer, BSD_BBSIZE))
- fatal (cxt, unable_to_read);
+ return 0;
memmove (d,
&disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET],
k = get_partition (cxt, 1, partitions);
- if (xbsd_check_new_partition (&i))
+ if (xbsd_check_new_partition(cxt, &i))
return;
p = get_part_table(k);
static int xbsd_set_parttype(
struct fdisk_context *cxt __attribute__((__unused__)),
- struct fdisk_label *lb __attribute__((__unused__)),
+ struct fdisk_label *lb,
int partnum,
struct fdisk_parttype *t)
{
return 0;
p->p_fstype = t->type;
+ fdisk_label_set_changed(lb, 1);
return 0;
}
unsigned int units_per_sector = 1, display_in_cyl_units = 0;
+static int MBRbuffer_changed;
+
void update_units(struct fdisk_context *cxt)
{
int cyl_units = cxt->geom.heads * cxt->geom.sectors;
static int dos_delete_partition(
struct fdisk_context *cxt __attribute__ ((__unused__)),
- struct fdisk_label *lb __attribute__ ((__unused__)),
+ struct fdisk_label *lb,
int partnum)
{
struct pte *pe = &ptes[partnum];
clear_partition(ptes[partnum].part_table);
}
+ fdisk_label_set_changed(lb, 1);
return 0;
}
dos_init(cxt);
fdisk_zeroize_firstsector(cxt);
- set_all_unchanged();
- set_changed(0);
+ fdisk_label_set_changed(cxt->label, 1);
/* Generate an MBR ID for this disk */
mbr_set_id(cxt->firstsector, id);
snprintf(ps, sizeof ps, _("New disk identifier (current 0x%08x): "),
mbr_get_id(cxt->firstsector));
- if (read_chars(ps) == '\n')
+ if (read_chars(cxt, ps) == '\n')
return;
new_id = strtoul(line_ptr, &ep, 0);
mbr_set_id(cxt->firstsector, new_id);
MBRbuffer_changed = 1;
+ fdisk_label_set_changed(cxt->label, 1);
dos_print_mbr_id(cxt);
}
partitions = 5;
}
+ fdisk_label_set_changed(cxt->label, 1);
return 0;
}
extended_offset ? _(" l logical (numbered from 5)") : _(" e extended"),
dflt);
- c = tolower(read_chars(line));
+ c = tolower(read_chars(cxt, line));
if (c == '\n') {
c = dflt;
printf(_("Using default response %c\n"), c);
static int dos_set_parttype(
struct fdisk_context *cxt __attribute__((__unused__)),
- struct fdisk_label *lb __attribute__((__unused__)),
+ struct fdisk_label *lb,
int partnum,
struct fdisk_parttype *t)
{
"information.\n\n"));
p->sys_ind = t->type;
+ fdisk_label_set_changed(lb, 1);
return 0;
}
sgi_set_bootfile(struct fdisk_context *cxt)
{
printf(_("\nThe current boot file is: %s\n"), sgilabel->boot_file);
- if (read_chars(_("Please enter the name of the new boot file: ")) == '\n') {
+ if (read_chars(cxt, _("Please enter the name of the new boot file: ")) == '\n') {
printf(_("Boot file unchanged\n"));
return;
}
sgilabel->partitions[i].id = SSWAP32(sys);
sgilabel->partitions[i].num_sectors = SSWAP32(length);
sgilabel->partitions[i].start_sector = SSWAP32(start);
- set_changed(i);
+
+ fdisk_label_set_changed(cxt->label, 1);
if (sgi_gaps(cxt) < 0) /* rebuild freelist */
printf(_("Partition overlap on the disk.\n"));
if (((t->type != ENTIRE_DISK) && (t->type != SGI_VOLHDR))
&& (sgi_get_start_sector(cxt, i) < 1)) {
- read_chars(
+ read_chars(cxt,
_("It is highly recommended that the partition at offset 0\n"
"is of type \"SGI volhdr\", the IRIX system will rely on it to\n"
"retrieve from its directory standalone tools like sash and fx.\n"
SSWAP32(start / (cxt->geom.heads * cxt->geom.sectors));
sunlabel->partitions[i].num_sectors =
SSWAP32(stop - start);
- set_changed(i);
+ fdisk_label_set_changed(cxt->label, 1);
print_partition_size(cxt, i + 1, start, stop, sysid);
}
csum ^= *ush++;
sunlabel->cksum = csum;
- set_changed(0);
+ fdisk_label_set_changed(lb, 1);
}
lb->nparts_cur = partitions_in_use(lb);
sunlabel->cksum = csum;
}
- set_all_unchanged();
- set_changed(0);
+ fdisk_label_set_changed(lb, 1);
lb->nparts_cur = partitions_in_use(lb);
return 0;
p->flag ^= SSWAP16(mask);
- set_changed(i);
+ fdisk_label_set_changed(cxt->label, 1);
}
static void fetch_sun(struct fdisk_context *cxt,
tag->tag = SSWAP16(SUN_TAG_UNASSIGNED);
part->num_sectors = 0;
lb->nparts_cur = partitions_in_use(lb);
+ fdisk_label_set_changed(lb, 1);
return 0;
}
tag = &sunlabel->part_tags[i];
if (t->type == SUN_TAG_LINUX_SWAP && !part->start_cylinder) {
- read_chars(
+ read_chars(cxt,
_("It is highly recommended that the partition at offset 0\n"
"is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n"
"there may destroy your partition table and bootblock.\n"
gpt_recompute_crc(gpt->pheader, gpt->ents);
gpt_recompute_crc(gpt->bheader, gpt->ents);
lb->nparts_cur--;
+ fdisk_label_set_changed(lb, 1);
}
return 0;
else {
printf(_("Created partition %d\n"), partnum + 1);
lb->nparts_cur++;
+ fdisk_label_set_changed(lb, 1);
}
return 0;
uid->node[0], uid->node[1],
uid->node[2], uid->node[3],
uid->node[4], uid->node[5]);
+ fdisk_label_set_changed(lb, 1);
done:
return rc;
}
gpt_entry_set_type(&gpt->ents[i], &uuid);
gpt_recompute_crc(gpt->pheader, gpt->ents);
gpt_recompute_crc(gpt->bheader, gpt->ents);
+
+ fdisk_label_set_changed(lb, 1);
return 0;
}