* [PATCH 00/13] sfdisk:
@ 2014-07-22 23:44 Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 01/13] sfdisk: remove bogus argc check Davidlohr Bueso
` (14 more replies)
0 siblings, 15 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
The sfdisk(8) program is the only one left to be rewritten to use the new libfdisk library.
To do so, however, there are first a series of cleanups that must be done in order to make
the effort easier, without introducing regressions or unexpected changes to users.
This patch is an initial attempt, and while there are plenty of leftover things to fix/cleanup,
I believe it's a pretty good start. While the set is fairly large, most of the patches are
rather straightforward -- specially patch 5, which is just an indentation change.
Thanks!
Davidlohr Bueso (13):
sfdisk: usage() can use noreturn attribute
sfdisk: remove bogus argc check
sfdisk: deprecate --linux option
sfdisk: remove dead code
sfdisk: remove 'short_opts' global variable
sfdisk: fix indentation
sfdisk: remove declaraion of 'partname()'
sfdisk: remove 'exit_status' global variable
sfdisk: move main function at the end of the file
fdisk: remove bugus space after header includes
sfdisk: update [embarrassingly] old man-page
sfdisk: rework option handling
sfdisk: fix --unhide segfault
disk-utils/fdisk.c | 2 -
disk-utils/sfdisk.8 | 4 +-
disk-utils/sfdisk.c | 4751 ++++++++++++++++++++++++++-------------------------
3 files changed, 2417 insertions(+), 2340 deletions(-)
--
1.8.1.4
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 01/13] sfdisk: remove bogus argc check
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
@ 2014-07-22 23:44 ` Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 02/13] sfdisk: deprecate --linux option Davidlohr Bueso
` (13 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
It makes no sense to check for argc < 1, remove this logic.
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
---
disk-utils/sfdisk.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index a54763d..9fc71b4 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -2552,8 +2552,6 @@ main(int argc, char **argv) {
textdomain(PACKAGE);
atexit(close_stdout);
- if (argc < 1)
- errx(EXIT_FAILURE, _("no command?"));
if (!strcmp(program_invocation_short_name, "activate"))
activate = 1; /* equivalent to `sfdisk -A' */
--
1.8.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 02/13] sfdisk: deprecate --linux option
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 01/13] sfdisk: remove bogus argc check Davidlohr Bueso
@ 2014-07-22 23:44 ` Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 03/13] sfdisk: remove dead code Davidlohr Bueso
` (12 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
Per sfdisk(8) manpage:
-L, --Linux
Do not complain about things irrelevant for Linux.
This doesn't make much sense for a program distributed by the
util-linux package. Mark deprecated, instead of removing, to
allow users to update theirs scripts, otherwise we can easily
break things. Now, using this option has no effect whatsoever
as it is the only behavior anyways.
Previously when sfdisk runs on Linux and the -L option is not
used, we can get some of the warnings from the additional checks:
$ sfdisk -V /dev/sda
sfdisk: Warning: partition 1 does not end at a cylinder boundary
sfdisk: Warning: partition 2 does not start at a cylinder boundary
/dev/sda: OK
With this patch output lines can change, ie:
$ sfdisk -V /dev/sda
/dev/sda: OK
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
---
disk-utils/sfdisk.8 | 2 +-
disk-utils/sfdisk.c | 77 +++--------------------------------------------------
2 files changed, 5 insertions(+), 74 deletions(-)
diff --git a/disk-utils/sfdisk.8 b/disk-utils/sfdisk.8
index 26065c2..1e84a11 100644
--- a/disk-utils/sfdisk.8
+++ b/disk-utils/sfdisk.8
@@ -301,7 +301,7 @@ Do what I say, even if it is stupid.
Suppress warning messages.
.TP
.BR \-L ", " \-\-Linux
-Do not complain about things irrelevant for Linux.
+Do not complain about things irrelevant for Linux. Deprecated.
.TP
.BR \-D ", " \-\-DOS
For DOS-compatibility: waste a little space.
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index 9fc71b4..6db9dfd 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -532,31 +532,6 @@ is_equal_chs(chs a, chs b) {
return (a.h == b.h && a.s == b.s && a.c == b.c);
}
-static int
-chs_ok(chs a, char *v, char *w) {
- longchs aa = chs_to_longchs(a);
- int ret = 1;
-
- if (is_equal_chs(a, zero_chs))
- return 1;
- if (B.heads && aa.h >= B.heads) {
- warnx(_("%s of partition %s has impossible value for head: "
- "%lu (should be in 0-%lu)"), w, v, aa.h, B.heads - 1);
- ret = 0;
- }
- if (B.sectors && (aa.s == 0 || aa.s > B.sectors)) {
- warnx(_("%s of partition %s has impossible value for sector: "
- "%lu (should be in 1-%lu)"), w, v, aa.s, B.sectors);
- ret = 0;
- }
- if (B.cylinders && aa.c >= B.cylinders) {
- warnx(_("%s of partition %s has impossible value for cylinders: "
- "%lu (should be in 0-%lu)"), w, v, aa.c, B.cylinders - 1);
- ret = 0;
- }
- return ret;
-}
-
/*
* D. About system Ids
*/
@@ -1266,39 +1241,6 @@ partitions_ok(int fd, struct disk_desc *z) {
for (p = partitions; p < partitions + 4; p++)
if (p->p.sys_type == EXTENDED_PARTITION)
ect++;
- if (ect > 1 && !Linux) {
- warnx(_("Among the primary partitions, at most one can be extended\n"
- " (although this is not a problem under Linux)"));
- return 0;
- }
- }
-
- /*
- * Do all partitions start at a cylinder boundary ?
- * (this is not required for Linux)
- * The first partition starts after MBR.
- * Logical partitions start slightly after the containing extended partn.
- */
- if (B.cylindersize && !Linux) {
- for (p = partitions; p < partitions + partno; p++)
- if (p->size) {
- if (p->start % B.cylindersize != 0
- && (!p->ep
- || p->start / B.cylindersize !=
- p->ep->start / B.cylindersize)
- && (p->p.start_sect >= B.cylindersize)) {
- warnx(_("Warning: partition %s does not start "
- "at a cylinder boundary"), PNO(p));
- if (specified_format == F_CYLINDER)
- return 0;
- }
- if ((p->start + p->size) % B.cylindersize) {
- warnx(_("Warning: partition %s does not end "
- "at a cylinder boundary"), PNO(p));
- if (specified_format == F_CYLINDER)
- return 0;
- }
- }
}
/* Usually, one can boot only from primary partitions. */
@@ -1339,8 +1281,7 @@ partitions_ok(int fd, struct disk_desc *z) {
b = p->p.begin_chs;
aa = chs_to_longchs(a);
bb = chs_to_longchs(b);
- if (!Linux && !chs_ok(b, PNO(p), _("start")))
- return 0;
+
if (a.s && !is_equal_chs(a, b))
warnx(_("partition %s: start: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)"),
PNO(p), aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
@@ -1348,8 +1289,7 @@ partitions_ok(int fd, struct disk_desc *z) {
b = p->p.end_chs;
aa = chs_to_longchs(a);
bb = chs_to_longchs(b);
- if (!Linux && !chs_ok(b, PNO(p), _("end")))
- return 0;
+
if (a.s && !is_equal_chs(a, b))
warnx(_("partition %s: end: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)"),
PNO(p), aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
@@ -1383,10 +1323,6 @@ extended_partition(char *dev, int fd, struct part_desc *ep, struct disk_desc *z)
"from %lld to %lld\n"
"(For listing purposes only. "
"Do not change its contents.)"), ep->start, start);
- } else if (!Linux) {
- warnx(_("Warning: extended partition does not start at a "
- "cylinder boundary.\n"
- "DOS and Linux will interpret the contents differently."));
}
}
@@ -2054,7 +1990,7 @@ read_line(int pno, struct part_desc *ep, char *dev, int interactive,
int fno, pct = pno % 4;
struct part_desc p, *orig;
unsigned long long ff, ff1, ul, ml, ml1, def;
- int format, lpno, is_extd;
+ int format = 0, lpno, is_extd;
if (eof || eob)
return -1;
@@ -2083,11 +2019,6 @@ read_line(int pno, struct part_desc *ep, char *dev, int interactive,
return -1;
}
- /* use specified format, but round to cylinders if F_MEGABYTE specified */
- format = 0;
- if (B.cylindersize && specified_format == F_MEGABYTE && !Linux)
- format = F_CYLINDER;
-
orig = (one_only ? &(oldp.partitions[pno]) : 0);
p = zero_part_desc;
@@ -2375,7 +2306,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
fputs(_(" -f, --force disable all consistency checking\n"
" --no-reread do not check whether the partition is in use\n"
" -q, --quiet suppress warning messages\n"
- " -L, --Linux do not complain about things irrelevant for Linux\n"), out);
+ " -L, --Linux do not complain about things irrelevant for Linux [deprecated]\n"), out);
fputs(_(" -g, --show-geometry print the kernel's idea of the geometry\n"
" -G, --show-pt-geometry print geometry guessed from the partition table\n"), out);
fputs(_(" -A, --activate[=<device>] activate the bootable flag\n"
--
1.8.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 03/13] sfdisk: remove dead code
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 01/13] sfdisk: remove bogus argc check Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 02/13] sfdisk: deprecate --linux option Davidlohr Bueso
@ 2014-07-22 23:44 ` Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 04/13] sfdisk: remove 'short_opts' global variable Davidlohr Bueso
` (11 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
---
disk-utils/sfdisk.c | 34 ++--------------------------------
1 file changed, 2 insertions(+), 32 deletions(-)
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index 6db9dfd..88f953d 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -436,18 +436,6 @@ get_cylindersize(char *dev, int fd, int silent) {
R.start);
exit(EXIT_FAILURE);
}
-#if 0
- if (R.heads && B.heads != R.heads)
- warnx(_("Warning: HDIO_GETGEO says that there are %lu heads"),
- R.heads);
- if (R.sectors && B.sectors != R.sectors)
- warnx(_("Warning: HDIO_GETGEO says that there are %lu sectors"),
- R.sectors);
- if (R.cylinders && B.cylinders != R.cylinders
- && B.cylinders < 65536 && R.cylinders < 65536)
- warnx(_("Warning: BLKGETSIZE/HDIO_GETGEO says that there are %lu cylinders"),
- R.cylinders);
-#endif
if (B.sectors > 63)
warnx(_("Warning: unlikely number of sectors (%lu) - usually at most 63\n"
@@ -515,18 +503,6 @@ ulong_to_chs(unsigned long sno, struct geometry G) {
return longchs_to_chs(ulong_to_longchs(sno, G), G);
}
-#if 0
-static unsigned long
-longchs_to_ulong(longchs aa, struct geometry G) {
- return (aa.c * G.cylindersize + aa.h * G.sectors + aa.s - 1);
-}
-
-static unsigned long
-chs_to_ulong(chs a, struct geometry G) {
- return longchs_to_ulong(chs_to_longchs(a), G);
-}
-#endif
-
static int
is_equal_chs(chs a, chs b) {
return (a.h == b.h && a.s == b.s && a.c == b.c);
@@ -1016,10 +992,6 @@ out_partition(char *dev, int format, struct part_desc *p,
out_rounddown(10, size, 1, 0);
break;
case F_BLOCK:
-#if 0
- printf("%8lu,%3lu ",
- p->sector / 2, ((p->sector & 1) ? 512 : 0) + p->offset);
-#endif
out_rounddown(8, start, 2, increment);
out_roundup(8, end, 2, increment);
out_rounddown(9, size, 2, 0);
@@ -1849,13 +1821,11 @@ first_free(int pno, int is_extended, struct part_desc *ep, int format,
else if (all_logicals_inside_outermost_extended)
pp = outer_extended_partition(ep);
}
-#if 0
- ff = pp ? (pp->start + unit - 1) / unit : 0;
-#else
+
/* rounding up wastes almost an entire cylinder - round down
and leave it to compute_start_sect() to fix the difference */
ff = pp ? pp->start / unit : 0;
-#endif
+
/* MBR and 1st sector of an extended partition are never free */
if (unit == 1)
ff++;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 04/13] sfdisk: remove 'short_opts' global variable
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
` (2 preceding siblings ...)
2014-07-22 23:44 ` [PATCH 03/13] sfdisk: remove dead code Davidlohr Bueso
@ 2014-07-22 23:44 ` Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 05/13] sfdisk: fix indentation Davidlohr Bueso
` (10 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
---
disk-utils/sfdisk.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index 88f953d..490492b 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -2319,8 +2319,6 @@ activate_usage(void) {
exit(EXIT_FAILURE);
}
-static const char short_opts[] = "cdfghilnqsu:vx1A::C:DGH:I:LN:O:RS:TU::V";
-
#define PRINT_ID 0400
#define CHANGE_ID 01000
@@ -2456,7 +2454,8 @@ main(int argc, char **argv) {
if (!strcmp(program_invocation_short_name, "activate"))
activate = 1; /* equivalent to `sfdisk -A' */
- while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "cdfghilnqsu:vx1A::C:DGH:I:LN:O:RS:TU::V",
+ long_opts, NULL)) != -1) {
switch (c) {
case 'f':
force = 1;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 05/13] sfdisk: fix indentation
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
` (3 preceding siblings ...)
2014-07-22 23:44 ` [PATCH 04/13] sfdisk: remove 'short_opts' global variable Davidlohr Bueso
@ 2014-07-22 23:44 ` Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 06/13] sfdisk: remove declaraion of 'partname()' Davidlohr Bueso
` (9 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
Re-writing a program requires reading a lot of the existing code.
Indent to 8 char columns to make it easier on developers working
on this effort. This is a large patch, but the contents are quite
trivial.
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
---
disk-utils/sfdisk.c | 4280 +++++++++++++++++++++++++--------------------------
1 file changed, 2140 insertions(+), 2140 deletions(-)
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index 490492b..af90c54 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -59,7 +59,7 @@ struct systypes {
};
static struct systypes i386_sys_types[] = {
- #include "pt-mbr-partnames.h"
+#include "pt-mbr-partnames.h"
};
static char *partname(char *dev, int pno, int lth);
@@ -106,21 +106,21 @@ char *restore_sector_file = NULL;
static int
sseek(char *dev, int fd, unsigned long s) {
- off_t in, out;
- in = ((off_t) s << 9);
+ off_t in, out;
+ in = ((off_t) s << 9);
- if ((out = lseek(fd, in, SEEK_SET)) != in) {
- warn(_("seek error on %s - cannot seek to %lu"), dev, s);
- return 0;
- }
+ if ((out = lseek(fd, in, SEEK_SET)) != in) {
+ warn(_("seek error on %s - cannot seek to %lu"), dev, s);
+ return 0;
+ }
- if (in != out) {
- warnx(_("seek error: wanted 0x%08x%08x, got 0x%08x%08x"),
- (unsigned int)(in >> 32), (unsigned int)(in & 0xffffffff),
- (unsigned int)(out >> 32), (unsigned int)(out & 0xffffffff));
- return 0;
- }
- return 1;
+ if (in != out) {
+ warnx(_("seek error: wanted 0x%08x%08x, got 0x%08x%08x"),
+ (unsigned int)(in >> 32), (unsigned int)(in & 0xffffffff),
+ (unsigned int)(out >> 32), (unsigned int)(out & 0xffffffff));
+ return 0;
+ }
+ return 1;
}
/*
@@ -132,209 +132,209 @@ sseek(char *dev, int fd, unsigned long s) {
* have to be modified and written back.
*/
struct sector {
- struct sector *next;
- unsigned long long sectornumber;
- int to_be_written;
- char data[512];
+ struct sector *next;
+ unsigned long long sectornumber;
+ int to_be_written;
+ char data[512];
} *sectorhead;
static void
free_sectors(void) {
- struct sector *s;
+ struct sector *s;
- while (sectorhead) {
- s = sectorhead;
- sectorhead = s->next;
- free(s);
- }
+ while (sectorhead) {
+ s = sectorhead;
+ sectorhead = s->next;
+ free(s);
+ }
}
static struct sector *
get_sector(char *dev, int fd, unsigned long long sno) {
- struct sector *s;
+ struct sector *s;
- for (s = sectorhead; s; s = s->next)
- if (s->sectornumber == sno)
- return s;
+ for (s = sectorhead; s; s = s->next)
+ if (s->sectornumber == sno)
+ return s;
- if (!sseek(dev, fd, sno))
- return 0;
+ if (!sseek(dev, fd, sno))
+ return 0;
- s = xmalloc(sizeof(struct sector));
+ s = xmalloc(sizeof(struct sector));
- if (read(fd, s->data, sizeof(s->data)) != sizeof(s->data)) {
- warn(_("read error on %s - cannot read sector %llu"), dev, sno);
- free(s);
- return 0;
- }
+ if (read(fd, s->data, sizeof(s->data)) != sizeof(s->data)) {
+ warn(_("read error on %s - cannot read sector %llu"), dev, sno);
+ free(s);
+ return 0;
+ }
- s->next = sectorhead;
- sectorhead = s;
- s->sectornumber = sno;
- s->to_be_written = 0;
+ s->next = sectorhead;
+ sectorhead = s;
+ s->sectornumber = sno;
+ s->to_be_written = 0;
- return s;
+ return s;
}
static int
msdos_signature(struct sector *s) {
- unsigned char *data = (unsigned char *)s->data;
- if (data[510] == 0x55 && data[511] == 0xaa)
- return 1;
- return 0;
+ unsigned char *data = (unsigned char *)s->data;
+ if (data[510] == 0x55 && data[511] == 0xaa)
+ return 1;
+ return 0;
}
static int
write_sectors(char *dev, int fd) {
- struct sector *s;
-
- for (s = sectorhead; s; s = s->next)
- if (s->to_be_written) {
- if (!sseek(dev, fd, s->sectornumber))
- return 0;
- if (write(fd, s->data, sizeof(s->data)) != sizeof(s->data)) {
- warn(_("write error on %s - cannot write sector %llu"),
- dev, s->sectornumber);
- return 0;
- }
- s->to_be_written = 0;
- }
- return 1;
+ struct sector *s;
+
+ for (s = sectorhead; s; s = s->next)
+ if (s->to_be_written) {
+ if (!sseek(dev, fd, s->sectornumber))
+ return 0;
+ if (write(fd, s->data, sizeof(s->data)) != sizeof(s->data)) {
+ warn(_("write error on %s - cannot write sector %llu"),
+ dev, s->sectornumber);
+ return 0;
+ }
+ s->to_be_written = 0;
+ }
+ return 1;
}
static void
ulong_to_chars(unsigned long u, char *uu) {
- int i;
+ int i;
- for (i = 0; i < 4; i++) {
- uu[i] = (u & 0xff);
- u >>= 8;
- }
+ for (i = 0; i < 4; i++) {
+ uu[i] = (u & 0xff);
+ u >>= 8;
+ }
}
static unsigned long
chars_to_ulong(unsigned char *uu) {
- int i;
- unsigned long u = 0;
+ int i;
+ unsigned long u = 0;
- for (i = 3; i >= 0; i--)
- u = (u << 8) | uu[i];
- return u;
+ for (i = 3; i >= 0; i--)
+ u = (u << 8) | uu[i];
+ return u;
}
static int
save_sectors(char *dev, int fdin) {
- struct sector *s;
- char ss[516];
- int fdout = -1;
-
- fdout = open(save_sector_file, O_WRONLY | O_CREAT, 0444);
- if (fdout < 0) {
- warn(_("cannot open partition sector save file (%s)"),
- save_sector_file);
- goto err;
- }
-
- for (s = sectorhead; s; s = s->next)
- if (s->to_be_written) {
- ulong_to_chars(s->sectornumber, ss);
- if (!sseek(dev, fdin, s->sectornumber))
- goto err;
- if (read(fdin, ss + 4, 512) != 512) {
- warn(_("read error on %s - cannot read sector %llu"),
- dev, s->sectornumber);
+ struct sector *s;
+ char ss[516];
+ int fdout = -1;
+
+ fdout = open(save_sector_file, O_WRONLY | O_CREAT, 0444);
+ if (fdout < 0) {
+ warn(_("cannot open partition sector save file (%s)"),
+ save_sector_file);
goto err;
- }
- if (write(fdout, ss, sizeof(ss)) != sizeof(ss)) {
- warn(_("write error on %s"), save_sector_file);
- goto err;
- }
}
- if (close_fd(fdout) != 0) {
- warn(_("write failed: %s"), save_sector_file);
- return 0;
- }
- return 1;
+ for (s = sectorhead; s; s = s->next)
+ if (s->to_be_written) {
+ ulong_to_chars(s->sectornumber, ss);
+ if (!sseek(dev, fdin, s->sectornumber))
+ goto err;
+ if (read(fdin, ss + 4, 512) != 512) {
+ warn(_("read error on %s - cannot read sector %llu"),
+ dev, s->sectornumber);
+ goto err;
+ }
+ if (write(fdout, ss, sizeof(ss)) != sizeof(ss)) {
+ warn(_("write error on %s"), save_sector_file);
+ goto err;
+ }
+ }
+
+ if (close_fd(fdout) != 0) {
+ warn(_("write failed: %s"), save_sector_file);
+ return 0;
+ }
+ return 1;
- err:
- if (fdout >= 0)
- if (close_fd(fdout) != 0)
- warn(_("write failed: %s"), save_sector_file);
- return 0;
+err:
+ if (fdout >= 0)
+ if (close_fd(fdout) != 0)
+ warn(_("write failed: %s"), save_sector_file);
+ return 0;
}
static int reread_disk_partition(char *dev, int fd);
static int
restore_sectors(char *dev) {
- int fdin = -1, fdout = -1;
- int ct;
- struct stat statbuf;
- char *ss0 = NULL, *ss;
- unsigned long sno;
-
- if (stat(restore_sector_file, &statbuf) < 0) {
- warn(_("cannot stat partition restore file (%s)"),
- restore_sector_file);
- goto err;
- }
- if (statbuf.st_size % 516) {
- warnx(_("partition restore file has wrong size - not restoring"));
- goto err;
- }
-
- ss0 = xmalloc(statbuf.st_size);
- ss = ss0;
-
- fdin = open(restore_sector_file, O_RDONLY);
- if (fdin < 0) {
- warn(_("cannot open partition restore file (%s)"),
- restore_sector_file);
- goto err;
- }
- if (read(fdin, ss, statbuf.st_size) != statbuf.st_size) {
- warn(_("error reading %s"), restore_sector_file);
- goto err;
- }
-
- fdout = open(dev, O_WRONLY);
- if (fdout < 0) {
- warn(_("cannot open device %s for writing"), dev);
- goto err;
- }
-
- ct = statbuf.st_size / 516;
- while (ct--) {
- sno = chars_to_ulong((unsigned char *)ss);
- if (!sseek(dev, fdout, sno))
- goto err;
- if (write(fdout, ss + 4, 512) != 512) {
- warn(_("error writing sector %lu on %s"), sno, dev);
- goto err;
- }
- ss += 516;
- }
- free(ss0);
- ss0 = NULL;
-
- if (!reread_disk_partition(dev, fdout)) /* closes fdout */
- goto err;
- close(fdin);
- if (close_fd(fdout) != 0) {
- warnx(_("write failed: %s"), dev);
- return 0;
- }
- return 1;
+ int fdin = -1, fdout = -1;
+ int ct;
+ struct stat statbuf;
+ char *ss0 = NULL, *ss;
+ unsigned long sno;
+
+ if (stat(restore_sector_file, &statbuf) < 0) {
+ warn(_("cannot stat partition restore file (%s)"),
+ restore_sector_file);
+ goto err;
+ }
+ if (statbuf.st_size % 516) {
+ warnx(_("partition restore file has wrong size - not restoring"));
+ goto err;
+ }
- err:
- free(ss0);
- if (fdin >= 0)
+ ss0 = xmalloc(statbuf.st_size);
+ ss = ss0;
+
+ fdin = open(restore_sector_file, O_RDONLY);
+ if (fdin < 0) {
+ warn(_("cannot open partition restore file (%s)"),
+ restore_sector_file);
+ goto err;
+ }
+ if (read(fdin, ss, statbuf.st_size) != statbuf.st_size) {
+ warn(_("error reading %s"), restore_sector_file);
+ goto err;
+ }
+
+ fdout = open(dev, O_WRONLY);
+ if (fdout < 0) {
+ warn(_("cannot open device %s for writing"), dev);
+ goto err;
+ }
+
+ ct = statbuf.st_size / 516;
+ while (ct--) {
+ sno = chars_to_ulong((unsigned char *)ss);
+ if (!sseek(dev, fdout, sno))
+ goto err;
+ if (write(fdout, ss + 4, 512) != 512) {
+ warn(_("error writing sector %lu on %s"), sno, dev);
+ goto err;
+ }
+ ss += 516;
+ }
+ free(ss0);
+ ss0 = NULL;
+
+ if (!reread_disk_partition(dev, fdout)) /* closes fdout */
+ goto err;
close(fdin);
- if (fdout >= 0)
- close(fdout);
+ if (close_fd(fdout) != 0) {
+ warnx(_("write failed: %s"), dev);
+ return 0;
+ }
+ return 1;
- return 0;
+err:
+ free(ss0);
+ if (fdin >= 0)
+ close(fdin);
+ if (fdout >= 0)
+ close(fdout);
+
+ return 0;
}
/*
@@ -362,150 +362,150 @@ restore_sectors(char *dev) {
* 0 means unspecified / unknown
*/
struct geometry {
- unsigned long long total_size; /* in sectors */
- unsigned long cylindersize; /* in sectors */
- unsigned long heads, sectors, cylinders;
- unsigned long start;
+ unsigned long long total_size; /* in sectors */
+ unsigned long cylindersize; /* in sectors */
+ unsigned long heads, sectors, cylinders;
+ unsigned long start;
} B, F, U;
static struct geometry
get_geometry(char *dev, int fd, int silent) {
- struct hd_geometry g;
- unsigned long cyls;
- unsigned long long sectors;
- struct geometry R;
+ struct hd_geometry g;
+ unsigned long cyls;
+ unsigned long long sectors;
+ struct geometry R;
#ifdef HDIO_GETGEO
- if (ioctl(fd, HDIO_GETGEO, &g))
+ if (ioctl(fd, HDIO_GETGEO, &g))
#endif
- {
- g.heads = g.sectors = g.cylinders = g.start = 0;
- if (!silent)
- warnx(_("Disk %s: cannot get geometry"), dev);
- }
-
- R.start = g.start;
- R.heads = g.heads;
- R.sectors = g.sectors;
- R.cylindersize = R.heads * R.sectors;
- R.cylinders = 0;
- R.total_size = 0;
-
- if (blkdev_get_sectors(fd, §ors) == -1) {
- /* maybe an ordinary file */
- struct stat s;
-
- if (fstat(fd, &s) == 0 && S_ISREG(s.st_mode))
- R.total_size = (s.st_size >> 9);
- else if (!silent)
- warnx(_("Disk %s: cannot get size"), dev);
- } else
- R.total_size = sectors;
-
- if (R.cylindersize && R.total_size) {
- sectors /= R.cylindersize;
- cyls = sectors;
- if (cyls != sectors)
- cyls = ~0;
- R.cylinders = cyls;
- }
-
- return R;
+ {
+ g.heads = g.sectors = g.cylinders = g.start = 0;
+ if (!silent)
+ warnx(_("Disk %s: cannot get geometry"), dev);
+ }
+
+ R.start = g.start;
+ R.heads = g.heads;
+ R.sectors = g.sectors;
+ R.cylindersize = R.heads * R.sectors;
+ R.cylinders = 0;
+ R.total_size = 0;
+
+ if (blkdev_get_sectors(fd, §ors) == -1) {
+ /* maybe an ordinary file */
+ struct stat s;
+
+ if (fstat(fd, &s) == 0 && S_ISREG(s.st_mode))
+ R.total_size = (s.st_size >> 9);
+ else if (!silent)
+ warnx(_("Disk %s: cannot get size"), dev);
+ } else
+ R.total_size = sectors;
+
+ if (R.cylindersize && R.total_size) {
+ sectors /= R.cylindersize;
+ cyls = sectors;
+ if (cyls != sectors)
+ cyls = ~0;
+ R.cylinders = cyls;
+ }
+
+ return R;
}
static void
get_cylindersize(char *dev, int fd, int silent) {
- struct geometry R;
+ struct geometry R;
- R = get_geometry(dev, fd, silent);
+ R = get_geometry(dev, fd, silent);
- B.heads = (U.heads ? U.heads : R.heads ? R.heads : 255);
- B.sectors = (U.sectors ? U.sectors : R.sectors ? R.sectors : 63);
- B.cylinders = (U.cylinders ? U.cylinders : R.cylinders);
+ B.heads = (U.heads ? U.heads : R.heads ? R.heads : 255);
+ B.sectors = (U.sectors ? U.sectors : R.sectors ? R.sectors : 63);
+ B.cylinders = (U.cylinders ? U.cylinders : R.cylinders);
- B.cylindersize = B.heads * B.sectors;
- B.total_size = R.total_size;
+ B.cylindersize = B.heads * B.sectors;
+ B.total_size = R.total_size;
- if (B.cylinders == 0 && B.cylindersize != 0)
- B.cylinders = B.total_size / B.cylindersize;
+ if (B.cylinders == 0 && B.cylindersize != 0)
+ B.cylinders = B.total_size / B.cylindersize;
- if (R.start && !force) {
- warnx(_("Warning: start=%lu - this looks like a partition rather than\n"
- "the entire disk. Using fdisk on it is probably meaningless.\n"
- "[Use the --force option if you really want this]"),
- R.start);
- exit(EXIT_FAILURE);
- }
+ if (R.start && !force) {
+ warnx(_("Warning: start=%lu - this looks like a partition rather than\n"
+ "the entire disk. Using fdisk on it is probably meaningless.\n"
+ "[Use the --force option if you really want this]"),
+ R.start);
+ exit(EXIT_FAILURE);
+ }
- if (B.sectors > 63)
- warnx(_("Warning: unlikely number of sectors (%lu) - usually at most 63\n"
- "This will give problems with all software that uses C/H/S addressing."),
- B.sectors);
- if (!silent)
- printf(_("\nDisk %s: %lu cylinders, %lu heads, %lu sectors/track\n"),
- dev, B.cylinders, B.heads, B.sectors);
+ if (B.sectors > 63)
+ warnx(_("Warning: unlikely number of sectors (%lu) - usually at most 63\n"
+ "This will give problems with all software that uses C/H/S addressing."),
+ B.sectors);
+ if (!silent)
+ printf(_("\nDisk %s: %lu cylinders, %lu heads, %lu sectors/track\n"),
+ dev, B.cylinders, B.heads, B.sectors);
}
typedef struct {
- unsigned char h, s, c;
+ unsigned char h, s, c;
} __attribute__ ((packed)) chs; /* has some c bits in s */
chs zero_chs = { 0, 0, 0 };
typedef struct {
- unsigned long h, s, c;
+ unsigned long h, s, c;
} longchs;
longchs zero_longchs;
static chs
longchs_to_chs(longchs aa, struct geometry G) {
- chs a;
-
- if (aa.h < 256 && aa.s < 64 && aa.c < 1024) {
- a.h = aa.h;
- a.s = aa.s | ((aa.c >> 2) & 0xc0);
- a.c = (aa.c & 0xff);
- } else if (G.heads && G.sectors) {
- a.h = G.heads - 1;
- a.s = G.sectors | 0xc0;
- a.c = 0xff;
- } else
- a = zero_chs;
- return a;
+ chs a;
+
+ if (aa.h < 256 && aa.s < 64 && aa.c < 1024) {
+ a.h = aa.h;
+ a.s = aa.s | ((aa.c >> 2) & 0xc0);
+ a.c = (aa.c & 0xff);
+ } else if (G.heads && G.sectors) {
+ a.h = G.heads - 1;
+ a.s = G.sectors | 0xc0;
+ a.c = 0xff;
+ } else
+ a = zero_chs;
+ return a;
}
static longchs
chs_to_longchs(chs a) {
- longchs aa;
+ longchs aa;
- aa.h = a.h;
- aa.s = (a.s & 0x3f);
- aa.c = (a.s & 0xc0);
- aa.c = (aa.c << 2) + a.c;
- return aa;
+ aa.h = a.h;
+ aa.s = (a.s & 0x3f);
+ aa.c = (a.s & 0xc0);
+ aa.c = (aa.c << 2) + a.c;
+ return aa;
}
static longchs
ulong_to_longchs(unsigned long sno, struct geometry G) {
- longchs aa;
+ longchs aa;
- if (G.heads && G.sectors && G.cylindersize) {
- aa.s = 1 + sno % G.sectors;
- aa.h = (sno / G.sectors) % G.heads;
- aa.c = sno / G.cylindersize;
- return aa;
- } else {
- return zero_longchs;
- }
+ if (G.heads && G.sectors && G.cylindersize) {
+ aa.s = 1 + sno % G.sectors;
+ aa.h = (sno / G.sectors) % G.heads;
+ aa.c = sno / G.cylindersize;
+ return aa;
+ } else {
+ return zero_longchs;
+ }
}
static chs
ulong_to_chs(unsigned long sno, struct geometry G) {
- return longchs_to_chs(ulong_to_longchs(sno, G), G);
+ return longchs_to_chs(ulong_to_longchs(sno, G), G);
}
static int
is_equal_chs(chs a, chs b) {
- return (a.h == b.h && a.s == b.s && a.c == b.c);
+ return (a.h == b.h && a.s == b.s && a.c == b.c);
}
/*
@@ -520,7 +520,7 @@ is_equal_chs(chs a, chs b) {
#define DM6_PARTITION 0x54
#define EZD_PARTITION 0x55
#define LINUX_SWAP 0x82
-#define LINUX_NATIVE 0x83
+#define LINUX_NATIVE 0x83
#define LINUX_EXTENDED 0x85
#define BSD_PARTITION 0xa5
#define NETBSD_PARTITION 0xa9
@@ -529,32 +529,32 @@ is_equal_chs(chs a, chs b) {
static const char *
sysname(unsigned char type) {
- struct systypes *s;
+ struct systypes *s;
- for (s = i386_sys_types; s->name; s++)
- if (s->type == type)
- return _(s->name);
- return _("Unknown");
+ for (s = i386_sys_types; s->name; s++)
+ if (s->type == type)
+ return _(s->name);
+ return _("Unknown");
}
static void
list_types(void) {
- struct systypes *s;
+ struct systypes *s;
- printf(_("Id Name\n\n"));
- for (s = i386_sys_types; s->name; s++)
- printf("%2x %s\n", s->type, _(s->name));
+ printf(_("Id Name\n\n"));
+ for (s = i386_sys_types; s->name; s++)
+ printf("%2x %s\n", s->type, _(s->name));
}
static int
is_extended(unsigned char type) {
- return (type == EXTENDED_PARTITION
- || type == LINUX_EXTENDED || type == WIN98_EXTENDED);
+ return (type == EXTENDED_PARTITION
+ || type == LINUX_EXTENDED || type == WIN98_EXTENDED);
}
static int
is_bsd(unsigned char type) {
- return (type == BSD_PARTITION || type == NETBSD_PARTITION);
+ return (type == BSD_PARTITION || type == NETBSD_PARTITION);
}
/*
@@ -564,64 +564,64 @@ is_bsd(unsigned char type) {
/* MS/DOS partition */
struct partition {
- unsigned char bootable; /* 0 or 0x80 */
- chs begin_chs;
- unsigned char sys_type;
- chs end_chs;
- unsigned int start_sect; /* starting sector counting from 0 */
- unsigned int nr_sects; /* nr of sectors in partition */
+ unsigned char bootable; /* 0 or 0x80 */
+ chs begin_chs;
+ unsigned char sys_type;
+ chs end_chs;
+ unsigned int start_sect; /* starting sector counting from 0 */
+ unsigned int nr_sects; /* nr of sectors in partition */
} __attribute__ ((packed));
/* Unfortunately, partitions are not aligned, and non-Intel machines
are unhappy with non-aligned integers. So, we need a copy by hand. */
static int
copy_to_int(unsigned char *cp) {
- unsigned int m;
+ unsigned int m;
- m = *cp++;
- m += (*cp++ << 8);
- m += (*cp++ << 16);
- m += (*cp++ << 24);
- return m;
+ m = *cp++;
+ m += (*cp++ << 8);
+ m += (*cp++ << 16);
+ m += (*cp++ << 24);
+ return m;
}
static void
copy_from_int(int m, char *cp) {
- *cp++ = (m & 0xff);
- m >>= 8;
- *cp++ = (m & 0xff);
- m >>= 8;
- *cp++ = (m & 0xff);
- m >>= 8;
- *cp++ = (m & 0xff);
+ *cp++ = (m & 0xff);
+ m >>= 8;
+ *cp++ = (m & 0xff);
+ m >>= 8;
+ *cp++ = (m & 0xff);
+ m >>= 8;
+ *cp++ = (m & 0xff);
}
static void
copy_to_part(char *cp, struct partition *p) {
- p->bootable = *cp++;
- p->begin_chs.h = *cp++;
- p->begin_chs.s = *cp++;
- p->begin_chs.c = *cp++;
- p->sys_type = *cp++;
- p->end_chs.h = *cp++;
- p->end_chs.s = *cp++;
- p->end_chs.c = *cp++;
- p->start_sect = copy_to_int((unsigned char *)cp);
- p->nr_sects = copy_to_int((unsigned char *)cp + 4);
+ p->bootable = *cp++;
+ p->begin_chs.h = *cp++;
+ p->begin_chs.s = *cp++;
+ p->begin_chs.c = *cp++;
+ p->sys_type = *cp++;
+ p->end_chs.h = *cp++;
+ p->end_chs.s = *cp++;
+ p->end_chs.c = *cp++;
+ p->start_sect = copy_to_int((unsigned char *)cp);
+ p->nr_sects = copy_to_int((unsigned char *)cp + 4);
}
static void
copy_from_part(struct partition *p, char *cp) {
- *cp++ = p->bootable;
- *cp++ = p->begin_chs.h;
- *cp++ = p->begin_chs.s;
- *cp++ = p->begin_chs.c;
- *cp++ = p->sys_type;
- *cp++ = p->end_chs.h;
- *cp++ = p->end_chs.s;
- *cp++ = p->end_chs.c;
- copy_from_int(p->start_sect, cp);
- copy_from_int(p->nr_sects, cp + 4);
+ *cp++ = p->bootable;
+ *cp++ = p->begin_chs.h;
+ *cp++ = p->begin_chs.s;
+ *cp++ = p->begin_chs.c;
+ *cp++ = p->sys_type;
+ *cp++ = p->end_chs.h;
+ *cp++ = p->end_chs.s;
+ *cp++ = p->end_chs.c;
+ copy_from_int(p->start_sect, cp);
+ copy_from_int(p->nr_sects, cp + 4);
}
/* Roughly speaking, Linux doesn't use any of the above fields except
@@ -631,132 +631,132 @@ copy_from_part(struct partition *p, char *cp) {
for equality with EXTENDED_PARTITION (and these Disk Manager types). */
struct part_desc {
- unsigned long long start;
- unsigned long long size;
- unsigned long long sector, offset; /* disk location of this info */
- struct partition p;
- struct part_desc *ep; /* extended partition containing this one */
- int ptype;
+ unsigned long long start;
+ unsigned long long size;
+ unsigned long long sector, offset; /* disk location of this info */
+ struct partition p;
+ struct part_desc *ep; /* extended partition containing this one */
+ int ptype;
#define DOS_TYPE 0
#define BSD_TYPE 1
} zero_part_desc;
static struct part_desc *
outer_extended_partition(struct part_desc *p) {
- while (p->ep)
- p = p->ep;
- return p;
+ while (p->ep)
+ p = p->ep;
+ return p;
}
static int
is_parent(struct part_desc *pp, struct part_desc *p) {
- while (p) {
- if (pp == p)
- return 1;
- p = p->ep;
- }
- return 0;
+ while (p) {
+ if (pp == p)
+ return 1;
+ p = p->ep;
+ }
+ return 0;
}
struct disk_desc {
- struct part_desc partitions[512];
- int partno;
+ struct part_desc partitions[512];
+ int partno;
} oldp, newp;
/* determine where on the disk this information goes */
static void
add_sector_and_offset(struct disk_desc *z) {
- int pno;
- struct part_desc *p;
+ int pno;
+ struct part_desc *p;
- for (pno = 0; pno < z->partno; pno++) {
- p = &(z->partitions[pno]);
- p->offset = 0x1be + (pno % 4) * sizeof(struct partition);
- p->sector = (p->ep ? p->ep->start : 0);
- }
+ for (pno = 0; pno < z->partno; pno++) {
+ p = &(z->partitions[pno]);
+ p->offset = 0x1be + (pno % 4) * sizeof(struct partition);
+ p->sector = (p->ep ? p->ep->start : 0);
+ }
}
/* tell the kernel to reread the partition tables */
static int
reread_ioctl(int fd) {
#ifdef BLKRRPART
- if (ioctl(fd, BLKRRPART))
+ if (ioctl(fd, BLKRRPART))
#else
- errno = ENOSYS;
+ errno = ENOSYS;
#endif
- {
- /* perror might change errno */
- int err = errno;
+ {
+ /* perror might change errno */
+ int err = errno;
- warn("BLKRRPART");
+ warn("BLKRRPART");
- /* 2.6.8 returns EIO for a zero table */
- if (err == EBUSY)
- return -1;
- }
- return 0;
+ /* 2.6.8 returns EIO for a zero table */
+ if (err == EBUSY)
+ return -1;
+ }
+ return 0;
}
/* reread after writing */
static int
reread_disk_partition(char *dev, int fd) {
- fflush(stdout);
- sync();
-
- if (is_blkdev(fd)) {
- printf(_("Re-reading the partition table ...\n"));
- if (reread_ioctl(fd) ) {
- warnx(_("The command to re-read the partition table failed.\n"
- "Run partprobe(8), kpartx(8) or reboot your system now,\n"
- "before using mkfs"));
- return 0;
+ fflush(stdout);
+ sync();
+
+ if (is_blkdev(fd)) {
+ printf(_("Re-reading the partition table ...\n"));
+ if (reread_ioctl(fd) ) {
+ warnx(_("The command to re-read the partition table failed.\n"
+ "Run partprobe(8), kpartx(8) or reboot your system now,\n"
+ "before using mkfs"));
+ return 0;
+ }
}
- }
- if (close_fd(fd) != 0) {
- warn(_("Error closing %s"), dev);
- return 0;
- }
- printf("\n");
+ if (close_fd(fd) != 0) {
+ warn(_("Error closing %s"), dev);
+ return 0;
+ }
+ printf("\n");
- return 1;
+ return 1;
}
/* find Linux name of this partition, assuming that it will have a name */
static int
index_to_linux(int pno, struct disk_desc *z) {
- int i, ct = 1;
- struct part_desc *p = &(z->partitions[0]);
- for (i = 0; i < pno; i++, p++)
- if (i < 4 || (p->size > 0 && !is_extended(p->p.sys_type)))
- ct++;
- return ct;
+ int i, ct = 1;
+ struct part_desc *p = &(z->partitions[0]);
+ for (i = 0; i < pno; i++, p++)
+ if (i < 4 || (p->size > 0 && !is_extended(p->p.sys_type)))
+ ct++;
+ return ct;
}
static int
linux_to_index(int lpno, struct disk_desc *z) {
- int i, ct = 0;
- struct part_desc *p = &(z->partitions[0]);
- for (i = 0; i < z->partno && ct < lpno; i++, p++)
- if ((i < 4 || (p->size > 0 && !is_extended(p->p.sys_type)))
- && ++ct == lpno)
- return i;
- return -1;
+ int i, ct = 0;
+ struct part_desc *p = &(z->partitions[0]);
+ for (i = 0; i < z->partno && ct < lpno; i++, p++)
+ if ((i < 4 || (p->size > 0 && !is_extended(p->p.sys_type)))
+ && ++ct == lpno)
+ return i;
+ return -1;
}
static int
asc_to_index(char *pnam, struct disk_desc *z) {
- int pnum, pno;
+ int pnum, pno;
- if (*pnam == '#') {
- pno = atoi(pnam + 1);
- } else {
- pnum = atoi(pnam);
- pno = linux_to_index(pnum, z);
- }
- if (!(pno >= 0 && pno < z->partno))
- errx(EXIT_FAILURE, _("%s: no such partition\n"), pnam);
- return pno;
+ if (*pnam == '#') {
+ pno = atoi(pnam + 1);
+ } else {
+ pnum = atoi(pnam);
+ pno = linux_to_index(pnum, z);
+ }
+ if (!(pno >= 0 && pno < z->partno))
+ errx(EXIT_FAILURE, _("%s: no such partition\n"), pnam);
+ return pno;
}
/*
@@ -776,573 +776,573 @@ int increment = 0;
static void
set_format(char c) {
- switch (c) {
- default:
- warnx(_("unrecognized format - using sectors"));
- /* fallthrough */
- case 'S':
- specified_format = F_SECTOR;
- break;
- case 'B':
- specified_format = F_BLOCK;
- break;
- case 'C':
- specified_format = F_CYLINDER;
- break;
- case 'M':
- specified_format = F_MEGABYTE;
- break;
- }
+ switch (c) {
+ default:
+ warnx(_("unrecognized format - using sectors"));
+ /* fallthrough */
+ case 'S':
+ specified_format = F_SECTOR;
+ break;
+ case 'B':
+ specified_format = F_BLOCK;
+ break;
+ case 'C':
+ specified_format = F_CYLINDER;
+ break;
+ case 'M':
+ specified_format = F_MEGABYTE;
+ break;
+ }
}
static unsigned long
unitsize(int format) {
- default_format = (B.cylindersize ? F_CYLINDER : F_MEGABYTE);
- if (!format && !(format = specified_format))
- format = default_format;
-
- switch (format) {
- default:
- case F_CYLINDER:
- if (B.cylindersize)
- return B.cylindersize;
- /* fallthrough */
- case F_SECTOR:
- return 1;
- case F_BLOCK:
- return 2;
- case F_MEGABYTE:
- return 2048;
- }
+ default_format = (B.cylindersize ? F_CYLINDER : F_MEGABYTE);
+ if (!format && !(format = specified_format))
+ format = default_format;
+
+ switch (format) {
+ default:
+ case F_CYLINDER:
+ if (B.cylindersize)
+ return B.cylindersize;
+ /* fallthrough */
+ case F_SECTOR:
+ return 1;
+ case F_BLOCK:
+ return 2;
+ case F_MEGABYTE:
+ return 2048;
+ }
}
static unsigned long long
get_disksize(int format) {
- if (B.total_size && leave_last)
- /* don't use last cylinder (--leave-last option) */
- return (B.total_size - B.cylindersize) / unitsize(format);
+ if (B.total_size && leave_last)
+ /* don't use last cylinder (--leave-last option) */
+ return (B.total_size - B.cylindersize) / unitsize(format);
- return B.total_size / unitsize(format);
+ return B.total_size / unitsize(format);
}
static void
out_partition_header(char *dev, int format, struct geometry G) {
- if (dump) {
- printf("# partition table of %s\n", dev);
- printf("unit: sectors\n\n");
- return;
- }
-
- default_format = (G.cylindersize ? F_CYLINDER : F_MEGABYTE);
- if (!format && !(format = specified_format))
- format = default_format;
-
- switch (format) {
- default:
- warnx(_("unimplemented format - using %s"),
- G.cylindersize ? _("cylinders") : _("sectors"));
- /* fallthrough */
- case F_CYLINDER:
- if (G.cylindersize) {
- printf(_("Units: cylinders of %lu bytes, blocks of 1024 bytes"
- ", counting from %d\n\n"), G.cylindersize << 9, increment);
- printf(_(" Device Boot Start End #cyls #blocks Id System\n"));
- break;
- }
- /* fall through */
- case F_SECTOR:
- printf(_("Units: sectors of 512 bytes, counting from %d\n\n"),
- increment);
- printf(_(" Device Boot Start End #sectors Id System\n"));
- break;
- case F_BLOCK:
- printf(_("Units: blocks of 1024 bytes, counting from %d\n\n"),
- increment);
- printf(_(" Device Boot Start End #blocks Id System\n"));
- break;
- case F_MEGABYTE:
- printf(_("Units: 1MiB = 1024*1024 bytes, blocks of 1024 bytes"
- ", counting from %d\n\n"), increment);
- printf(_(" Device Boot Start End MiB #blocks Id System\n"));
- break;
- }
+ if (dump) {
+ printf("# partition table of %s\n", dev);
+ printf("unit: sectors\n\n");
+ return;
+ }
+
+ default_format = (G.cylindersize ? F_CYLINDER : F_MEGABYTE);
+ if (!format && !(format = specified_format))
+ format = default_format;
+
+ switch (format) {
+ default:
+ warnx(_("unimplemented format - using %s"),
+ G.cylindersize ? _("cylinders") : _("sectors"));
+ /* fallthrough */
+ case F_CYLINDER:
+ if (G.cylindersize) {
+ printf(_("Units: cylinders of %lu bytes, blocks of 1024 bytes"
+ ", counting from %d\n\n"), G.cylindersize << 9, increment);
+ printf(_(" Device Boot Start End #cyls #blocks Id System\n"));
+ break;
+ }
+ /* fall through */
+ case F_SECTOR:
+ printf(_("Units: sectors of 512 bytes, counting from %d\n\n"),
+ increment);
+ printf(_(" Device Boot Start End #sectors Id System\n"));
+ break;
+ case F_BLOCK:
+ printf(_("Units: blocks of 1024 bytes, counting from %d\n\n"),
+ increment);
+ printf(_(" Device Boot Start End #blocks Id System\n"));
+ break;
+ case F_MEGABYTE:
+ printf(_("Units: 1MiB = 1024*1024 bytes, blocks of 1024 bytes"
+ ", counting from %d\n\n"), increment);
+ printf(_(" Device Boot Start End MiB #blocks Id System\n"));
+ break;
+ }
}
static void
out_rounddown(int width, unsigned long long n, unsigned long unit, int inc) {
- printf("%*llu", width, inc + n / unit);
- if (unit != 1)
- putchar((n % unit) ? '+' : ' ');
- putchar(' ');
+ printf("%*llu", width, inc + n / unit);
+ if (unit != 1)
+ putchar((n % unit) ? '+' : ' ');
+ putchar(' ');
}
static void
out_roundup(int width, unsigned long long n, unsigned long unit, int inc) {
- if (n == (unsigned long long)(-1))
- printf("%*s", width, "-");
- else
- printf("%*llu", width, inc + n / unit);
- if (unit != 1)
- putchar(((n + 1) % unit) ? '-' : ' ');
- putchar(' ');
+ if (n == (unsigned long long)(-1))
+ printf("%*s", width, "-");
+ else
+ printf("%*llu", width, inc + n / unit);
+ if (unit != 1)
+ putchar(((n + 1) % unit) ? '-' : ' ');
+ putchar(' ');
}
static void
out_roundup_size(int width, unsigned long long n, unsigned long unit) {
- printf("%*llu", width, (n + unit - 1) / unit);
- if (unit != 1)
- putchar((n % unit) ? '-' : ' ');
- putchar(' ');
+ printf("%*llu", width, (n + unit - 1) / unit);
+ if (unit != 1)
+ putchar((n % unit) ? '-' : ' ');
+ putchar(' ');
}
static struct geometry
get_fdisk_geometry_one(struct part_desc *p) {
- struct geometry G;
- chs b = p->p.end_chs;
- longchs bb = chs_to_longchs(b);
+ struct geometry G;
+ chs b = p->p.end_chs;
+ longchs bb = chs_to_longchs(b);
- memset(&G, 0, sizeof(struct geometry));
- G.heads = bb.h + 1;
- G.sectors = bb.s;
- G.cylindersize = G.heads * G.sectors;
- return G;
+ memset(&G, 0, sizeof(struct geometry));
+ G.heads = bb.h + 1;
+ G.sectors = bb.s;
+ G.cylindersize = G.heads * G.sectors;
+ return G;
}
static int
get_fdisk_geometry(struct disk_desc *z) {
- struct part_desc *p;
- int pno, agree;
- struct geometry G0, G;
-
- memset(&G0, 0, sizeof(struct geometry));
- agree = 0;
- for (pno = 0; pno < z->partno; pno++) {
- p = &(z->partitions[pno]);
- if (p->size != 0 && p->p.sys_type != 0) {
- G = get_fdisk_geometry_one(p);
- if (!G0.heads) {
- G0 = G;
- agree = 1;
- } else if (G.heads != G0.heads || G.sectors != G0.sectors) {
- agree = 0;
- break;
- }
+ struct part_desc *p;
+ int pno, agree;
+ struct geometry G0, G;
+
+ memset(&G0, 0, sizeof(struct geometry));
+ agree = 0;
+ for (pno = 0; pno < z->partno; pno++) {
+ p = &(z->partitions[pno]);
+ if (p->size != 0 && p->p.sys_type != 0) {
+ G = get_fdisk_geometry_one(p);
+ if (!G0.heads) {
+ G0 = G;
+ agree = 1;
+ } else if (G.heads != G0.heads || G.sectors != G0.sectors) {
+ agree = 0;
+ break;
+ }
+ }
}
- }
- F = (agree ? G0 : B);
- return (F.sectors != B.sectors || F.heads != B.heads);
+ F = (agree ? G0 : B);
+ return (F.sectors != B.sectors || F.heads != B.heads);
}
static void
out_partition(char *dev, int format, struct part_desc *p,
struct disk_desc *z, struct geometry G) {
- unsigned long long start, end, size;
- int pno, lpno;
-
- if (!format && !(format = specified_format))
- format = default_format;
-
- pno = p - &(z->partitions[0]); /* our index */
- lpno = index_to_linux(pno, z); /* name of next one that has a name */
- if (pno == linux_to_index(lpno, z)) /* was that us? */
- printf("%s", partname(dev, lpno, 10)); /* yes */
- else if (show_extended)
- printf(" - ");
- else
- return;
- putchar(dump ? ':' : ' ');
-
- start = p->start;
- end = p->start + p->size - 1;
- size = p->size;
-
- if (dump) {
- printf(" start=%9llu", start);
- printf(", size=%9llu", size);
+ unsigned long long start, end, size;
+ int pno, lpno;
+
+ if (!format && !(format = specified_format))
+ format = default_format;
+
+ pno = p - &(z->partitions[0]); /* our index */
+ lpno = index_to_linux(pno, z); /* name of next one that has a name */
+ if (pno == linux_to_index(lpno, z)) /* was that us? */
+ printf("%s", partname(dev, lpno, 10)); /* yes */
+ else if (show_extended)
+ printf(" - ");
+ else
+ return;
+ putchar(dump ? ':' : ' ');
+
+ start = p->start;
+ end = p->start + p->size - 1;
+ size = p->size;
+
+ if (dump) {
+ printf(" start=%9llu", start);
+ printf(", size=%9llu", size);
+ if (p->ptype == DOS_TYPE) {
+ printf(", Id=%2x", p->p.sys_type);
+ if (p->p.bootable == 0x80)
+ printf(", bootable");
+ }
+ printf("\n");
+ return;
+ }
+
+ if (p->ptype != DOS_TYPE || p->p.bootable == 0)
+ printf(" ");
+ else if (p->p.bootable == 0x80)
+ printf(" * ");
+ else
+ printf(" ? "); /* garbage */
+
+ switch (format) {
+ case F_CYLINDER:
+ if (G.cylindersize) {
+ out_rounddown(6, start, G.cylindersize, increment);
+ out_roundup(6, end, G.cylindersize, increment);
+ out_roundup_size(6, size, G.cylindersize);
+ out_rounddown(9, size, 2, 0);
+ break;
+ }
+ /* fall through */
+ default:
+ case F_SECTOR:
+ out_rounddown(9, start, 1, increment);
+ out_roundup(9, end, 1, increment);
+ out_rounddown(10, size, 1, 0);
+ break;
+ case F_BLOCK:
+ out_rounddown(8, start, 2, increment);
+ out_roundup(8, end, 2, increment);
+ out_rounddown(9, size, 2, 0);
+ break;
+ case F_MEGABYTE:
+ out_rounddown(5, start, 2048, increment);
+ out_roundup(5, end, 2048, increment);
+ out_roundup_size(5, size, 2048);
+ out_rounddown(9, size, 2, 0);
+ break;
+ }
if (p->ptype == DOS_TYPE) {
- printf(", Id=%2x", p->p.sys_type);
- if (p->p.bootable == 0x80)
- printf(", bootable");
+ printf(" %2x %s\n", p->p.sys_type, sysname(p->p.sys_type));
+ } else {
+ printf("\n");
+ }
+
+ /* Is chs as we expect? */
+ if (!quiet && p->ptype == DOS_TYPE) {
+ chs a, b;
+ longchs aa, bb;
+ a = (size ? ulong_to_chs(start, G) : zero_chs);
+ b = p->p.begin_chs;
+ aa = chs_to_longchs(a);
+ bb = chs_to_longchs(b);
+ if (a.s && !is_equal_chs(a, b))
+ printf(_("\t\tstart: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)\n"),
+ aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
+ a = (size ? ulong_to_chs(end, G) : zero_chs);
+ b = p->p.end_chs;
+ aa = chs_to_longchs(a);
+ bb = chs_to_longchs(b);
+ if (a.s && !is_equal_chs(a, b))
+ printf(_("\t\tend: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)\n"),
+ aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
+ if (G.cylinders && G.cylinders < 1024 && bb.c > G.cylinders)
+ printf(_("partition ends on cylinder %ld, beyond the end of the disk\n"),
+ bb.c);
}
- printf("\n");
- return;
- }
-
- if (p->ptype != DOS_TYPE || p->p.bootable == 0)
- printf(" ");
- else if (p->p.bootable == 0x80)
- printf(" * ");
- else
- printf(" ? "); /* garbage */
-
- switch (format) {
- case F_CYLINDER:
- if (G.cylindersize) {
- out_rounddown(6, start, G.cylindersize, increment);
- out_roundup(6, end, G.cylindersize, increment);
- out_roundup_size(6, size, G.cylindersize);
- out_rounddown(9, size, 2, 0);
- break;
- }
- /* fall through */
- default:
- case F_SECTOR:
- out_rounddown(9, start, 1, increment);
- out_roundup(9, end, 1, increment);
- out_rounddown(10, size, 1, 0);
- break;
- case F_BLOCK:
- out_rounddown(8, start, 2, increment);
- out_roundup(8, end, 2, increment);
- out_rounddown(9, size, 2, 0);
- break;
- case F_MEGABYTE:
- out_rounddown(5, start, 2048, increment);
- out_roundup(5, end, 2048, increment);
- out_roundup_size(5, size, 2048);
- out_rounddown(9, size, 2, 0);
- break;
- }
- if (p->ptype == DOS_TYPE) {
- printf(" %2x %s\n", p->p.sys_type, sysname(p->p.sys_type));
- } else {
- printf("\n");
- }
-
- /* Is chs as we expect? */
- if (!quiet && p->ptype == DOS_TYPE) {
- chs a, b;
- longchs aa, bb;
- a = (size ? ulong_to_chs(start, G) : zero_chs);
- b = p->p.begin_chs;
- aa = chs_to_longchs(a);
- bb = chs_to_longchs(b);
- if (a.s && !is_equal_chs(a, b))
- printf(_("\t\tstart: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)\n"),
- aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
- a = (size ? ulong_to_chs(end, G) : zero_chs);
- b = p->p.end_chs;
- aa = chs_to_longchs(a);
- bb = chs_to_longchs(b);
- if (a.s && !is_equal_chs(a, b))
- printf(_("\t\tend: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)\n"),
- aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
- if (G.cylinders && G.cylinders < 1024 && bb.c > G.cylinders)
- printf(_("partition ends on cylinder %ld, beyond the end of the disk\n"),
- bb.c);
- }
}
static void
out_partitions(char *dev, struct disk_desc *z) {
- int pno, format = 0;
+ int pno, format = 0;
- if (z->partno == 0) {
- if (!opt_list)
- warnx(_("No partitions found"));
- } else {
- if (get_fdisk_geometry(z) && !dump) {
- warnx(_("Warning: The partition table looks like it was made\n"
- " for C/H/S=*/%ld/%ld (instead of %ld/%ld/%ld).\n"
- "For this listing I'll assume that geometry."),
- F.heads, F.sectors, B.cylinders, B.heads, B.sectors);
- }
+ if (z->partno == 0) {
+ if (!opt_list)
+ warnx(_("No partitions found"));
+ } else {
+ if (get_fdisk_geometry(z) && !dump) {
+ warnx(_("Warning: The partition table looks like it was made\n"
+ " for C/H/S=*/%ld/%ld (instead of %ld/%ld/%ld).\n"
+ "For this listing I'll assume that geometry."),
+ F.heads, F.sectors, B.cylinders, B.heads, B.sectors);
+ }
- out_partition_header(dev, format, F);
- for (pno = 0; pno < z->partno; pno++) {
- out_partition(dev, format, &(z->partitions[pno]), z, F);
- if (show_extended && pno % 4 == 3)
- printf("\n");
+ out_partition_header(dev, format, F);
+ for (pno = 0; pno < z->partno; pno++) {
+ out_partition(dev, format, &(z->partitions[pno]), z, F);
+ if (show_extended && pno % 4 == 3)
+ printf("\n");
+ }
}
- }
}
static int
disj(struct part_desc *p, struct part_desc *q) {
- return ((p->start + p->size <= q->start)
- || (is_extended(p->p.sys_type)
- && q->start + q->size <= p->start + p->size));
+ return ((p->start + p->size <= q->start)
+ || (is_extended(p->p.sys_type)
+ && q->start + q->size <= p->start + p->size));
}
static char *
pnumber(struct part_desc *p, struct disk_desc *z) {
- static char buf[20];
- int this, next;
- struct part_desc *p0 = &(z->partitions[0]);
+ static char buf[20];
+ int this, next;
+ struct part_desc *p0 = &(z->partitions[0]);
- this = index_to_linux(p - p0, z);
- next = index_to_linux(p - p0 + 1, z);
+ this = index_to_linux(p - p0, z);
+ next = index_to_linux(p - p0 + 1, z);
- if (next > this)
- sprintf(buf, "%d", this);
- else
- sprintf(buf, "[%d]", this);
- return buf;
+ if (next > this)
+ sprintf(buf, "%d", this);
+ else
+ sprintf(buf, "[%d]", this);
+ return buf;
}
static int
partitions_ok(int fd, struct disk_desc *z) {
- struct part_desc *partitions = &(z->partitions[0]), *p, *q;
- int partno = z->partno;
- int sector_size;
+ struct part_desc *partitions = &(z->partitions[0]), *p, *q;
+ int partno = z->partno;
+ int sector_size;
#define PNO(p) pnumber(p, z)
- /* Have at least 4 partitions been defined? */
- if (partno < 4) {
- if (!partno)
- errx(EXIT_FAILURE, _("no partition table present."));
- else
- errx(EXIT_FAILURE, _("strange, only %d partitions defined."), partno);
- return 0;
- }
-
- /* Are the partitions of size 0 marked empty?
- And do they have start = 0? And bootable = 0? */
- for (p = partitions; p - partitions < partno; p++)
- if (p->size == 0) {
- if (p->p.sys_type != EMPTY_PARTITION)
- warnx(_("Warning: partition %s has size 0 but is not marked Empty"),
- PNO(p));
- else if (p->p.bootable != 0)
- warnx(_("Warning: partition %s has size 0 and is bootable"),
- PNO(p));
- else if (p->p.start_sect != 0)
- warnx(_("Warning: partition %s has size 0 and nonzero start"),
- PNO(p));
- /* all this is probably harmless, no error return */
- }
-
- /* Are the logical partitions contained in their extended partitions? */
- for (p = partitions + 4; p < partitions + partno; p++)
- if (p->ptype == DOS_TYPE)
- if (p->size && !is_extended(p->p.sys_type)) {
- q = p->ep;
- if (p->start < q->start
- || p->start + p->size > q->start + q->size) {
- warnx(_("Warning: partition %s is not contained in "
- "partition %s"), PNO(p), PNO(q));
- return 0;
+ /* Have at least 4 partitions been defined? */
+ if (partno < 4) {
+ if (!partno)
+ errx(EXIT_FAILURE, _("no partition table present."));
+ else
+ errx(EXIT_FAILURE, _("strange, only %d partitions defined."), partno);
+ return 0;
+ }
+
+ /* Are the partitions of size 0 marked empty?
+ And do they have start = 0? And bootable = 0? */
+ for (p = partitions; p - partitions < partno; p++)
+ if (p->size == 0) {
+ if (p->p.sys_type != EMPTY_PARTITION)
+ warnx(_("Warning: partition %s has size 0 but is not marked Empty"),
+ PNO(p));
+ else if (p->p.bootable != 0)
+ warnx(_("Warning: partition %s has size 0 and is bootable"),
+ PNO(p));
+ else if (p->p.start_sect != 0)
+ warnx(_("Warning: partition %s has size 0 and nonzero start"),
+ PNO(p));
+ /* all this is probably harmless, no error return */
}
- }
-
- /* Are the data partitions mutually disjoint? */
- for (p = partitions; p < partitions + partno; p++)
- if (p->size && !is_extended(p->p.sys_type))
- for (q = p + 1; q < partitions + partno; q++)
- if (q->size && !is_extended(q->p.sys_type))
- if (!((p->start > q->start) ? disj(q, p) : disj(p, q))) {
- warnx(_("Warning: partitions %s and %s overlap"),
- PNO(p), PNO(q));
- return 0;
- }
-
- /* Are the data partitions and the extended partition
- table sectors disjoint? */
- for (p = partitions; p < partitions + partno; p++)
- if (p->size && !is_extended(p->p.sys_type))
- for (q = partitions; q < partitions + partno; q++)
- if (is_extended(q->p.sys_type))
- if (p->start <= q->start && p->start + p->size > q->start) {
- warnx(_("Warning: partition %s contains part of "
- "the partition table (sector %llu),\n"
- "and will destroy it when filled"),
- PNO(p), q->start);
- return 0;
- }
- /* Do they start past zero and end before end-of-disk? */
- {
- unsigned long long ds = get_disksize(F_SECTOR);
+ /* Are the logical partitions contained in their extended partitions? */
+ for (p = partitions + 4; p < partitions + partno; p++)
+ if (p->ptype == DOS_TYPE)
+ if (p->size && !is_extended(p->p.sys_type)) {
+ q = p->ep;
+ if (p->start < q->start
+ || p->start + p->size > q->start + q->size) {
+ warnx(_("Warning: partition %s is not contained in "
+ "partition %s"), PNO(p), PNO(q));
+ return 0;
+ }
+ }
+
+ /* Are the data partitions mutually disjoint? */
for (p = partitions; p < partitions + partno; p++)
- if (p->size) {
- if (p->start == 0) {
- warnx(_("Warning: partition %s starts at sector 0"),
- PNO(p));
- return 0;
- }
- if (p->size && p->start + p->size > ds) {
- warnx(_("Warning: partition %s extends past end of disk"),
- PNO(p));
- return 0;
+ if (p->size && !is_extended(p->p.sys_type))
+ for (q = p + 1; q < partitions + partno; q++)
+ if (q->size && !is_extended(q->p.sys_type))
+ if (!((p->start > q->start) ? disj(q, p) : disj(p, q))) {
+ warnx(_("Warning: partitions %s and %s overlap"),
+ PNO(p), PNO(q));
+ return 0;
+ }
+
+ /* Are the data partitions and the extended partition
+ table sectors disjoint? */
+ for (p = partitions; p < partitions + partno; p++)
+ if (p->size && !is_extended(p->p.sys_type))
+ for (q = partitions; q < partitions + partno; q++)
+ if (is_extended(q->p.sys_type))
+ if (p->start <= q->start && p->start + p->size > q->start) {
+ warnx(_("Warning: partition %s contains part of "
+ "the partition table (sector %llu),\n"
+ "and will destroy it when filled"),
+ PNO(p), q->start);
+ return 0;
+ }
+
+ /* Do they start past zero and end before end-of-disk? */
+ {
+ unsigned long long ds = get_disksize(F_SECTOR);
+ for (p = partitions; p < partitions + partno; p++)
+ if (p->size) {
+ if (p->start == 0) {
+ warnx(_("Warning: partition %s starts at sector 0"),
+ PNO(p));
+ return 0;
+ }
+ if (p->size && p->start + p->size > ds) {
+ warnx(_("Warning: partition %s extends past end of disk"),
+ PNO(p));
+ return 0;
+ }
+ }
+ }
+
+ if (blkdev_get_sector_size(fd, §or_size) == -1)
+ sector_size = DEFAULT_SECTOR_SIZE;
+
+ /* Is the size of partitions less than 2^32 sectors limit? */
+ for (p = partitions; p < partitions + partno; p++)
+ if (p->size > UINT_MAX) {
+ unsigned long long bytes = p->size * sector_size;
+ int giga = bytes / 1000000000;
+ int hectogiga = (giga + 50) / 100;
+ warnx(_("Warning: partition %s has size %d.%d TB (%llu bytes),\n"
+ "which is larger than the %llu bytes limit imposed\n"
+ "by the DOS partition table for %d-byte sectors"),
+ PNO(p), hectogiga / 10, hectogiga % 10,
+ bytes,
+ (unsigned long long) UINT_MAX * sector_size,
+ sector_size);
+ return 0;
}
- }
- }
-
- if (blkdev_get_sector_size(fd, §or_size) == -1)
- sector_size = DEFAULT_SECTOR_SIZE;
-
- /* Is the size of partitions less than 2^32 sectors limit? */
- for (p = partitions; p < partitions + partno; p++)
- if (p->size > UINT_MAX) {
- unsigned long long bytes = p->size * sector_size;
- int giga = bytes / 1000000000;
- int hectogiga = (giga + 50) / 100;
- warnx(_("Warning: partition %s has size %d.%d TB (%llu bytes),\n"
- "which is larger than the %llu bytes limit imposed\n"
- "by the DOS partition table for %d-byte sectors"),
- PNO(p), hectogiga / 10, hectogiga % 10,
- bytes,
- (unsigned long long) UINT_MAX * sector_size,
- sector_size);
- return 0;
- }
-
- /* Do the partitions start below the 2^32 sectors limit? */
- for (p = partitions; p < partitions + partno; p++)
- if (p->start > UINT_MAX) {
- unsigned long long bytes = p->start * sector_size;
- int giga = bytes / 1000000000;
- int hectogiga = (giga + 50) / 100;
- warnx(_("Warning: partition %s starts at sector %llu (%d.%d TB for %d-byte sectors),\n"
- "which exceeds the DOS partition table limit of %llu sectors"),
- PNO(p),
- p->start,
- hectogiga / 10,
- hectogiga % 10,
- sector_size,
- (unsigned long long) UINT_MAX);
- return 0;
- }
-
- /* At most one chain of DOS extended partitions ? */
- /* It seems that the OS/2 fdisk has the additional requirement
- that the extended partition must be the fourth one */
- {
- int ect = 0;
- for (p = partitions; p < partitions + 4; p++)
- if (p->p.sys_type == EXTENDED_PARTITION)
- ect++;
- }
-
- /* Usually, one can boot only from primary partitions. */
- /* In fact, from a unique one only. */
- /* do not warn about bootable extended partitions -
- often LILO is there */
- {
- int pno = -1;
+
+ /* Do the partitions start below the 2^32 sectors limit? */
for (p = partitions; p < partitions + partno; p++)
- if (p->p.bootable) {
- if (pno == -1)
- pno = p - partitions;
- else if (p - partitions < 4) {
- warnx(_("Warning: more than one primary partition is marked "
- "bootable (active)\n"
- "This does not matter for LILO, but the DOS MBR will "
- "not boot this disk."));
- break;
+ if (p->start > UINT_MAX) {
+ unsigned long long bytes = p->start * sector_size;
+ int giga = bytes / 1000000000;
+ int hectogiga = (giga + 50) / 100;
+ warnx(_("Warning: partition %s starts at sector %llu (%d.%d TB for %d-byte sectors),\n"
+ "which exceeds the DOS partition table limit of %llu sectors"),
+ PNO(p),
+ p->start,
+ hectogiga / 10,
+ hectogiga % 10,
+ sector_size,
+ (unsigned long long) UINT_MAX);
+ return 0;
}
- if (p - partitions >= 4) {
- warnx(_("Warning: usually one can boot from primary partitions "
- "only\nLILO disregards the `bootable' flag."));
- break;
+
+ /* At most one chain of DOS extended partitions ? */
+ /* It seems that the OS/2 fdisk has the additional requirement
+ that the extended partition must be the fourth one */
+ {
+ int ect = 0;
+ for (p = partitions; p < partitions + 4; p++)
+ if (p->p.sys_type == EXTENDED_PARTITION)
+ ect++;
+ }
+
+ /* Usually, one can boot only from primary partitions. */
+ /* In fact, from a unique one only. */
+ /* do not warn about bootable extended partitions -
+ often LILO is there */
+ {
+ int pno = -1;
+ for (p = partitions; p < partitions + partno; p++)
+ if (p->p.bootable) {
+ if (pno == -1)
+ pno = p - partitions;
+ else if (p - partitions < 4) {
+ warnx(_("Warning: more than one primary partition is marked "
+ "bootable (active)\n"
+ "This does not matter for LILO, but the DOS MBR will "
+ "not boot this disk."));
+ break;
+ }
+ if (p - partitions >= 4) {
+ warnx(_("Warning: usually one can boot from primary partitions "
+ "only\nLILO disregards the `bootable' flag."));
+ break;
+ }
+ }
+ if (pno == -1 || pno >= 4)
+ warnx(_("Warning: no primary partition is marked bootable (active)\n"
+ "This does not matter for LILO, but the DOS MBR will "
+ "not boot this disk."));
+ }
+
+ /* Is chs as we expect? */
+ for (p = partitions; p < partitions + partno; p++)
+ if (p->ptype == DOS_TYPE) {
+ chs a, b;
+ longchs aa, bb;
+ a = p->size ? ulong_to_chs(p->start, B) : zero_chs;
+ b = p->p.begin_chs;
+ aa = chs_to_longchs(a);
+ bb = chs_to_longchs(b);
+
+ if (a.s && !is_equal_chs(a, b))
+ warnx(_("partition %s: start: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)"),
+ PNO(p), aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
+ a = p->size ? ulong_to_chs(p->start + p->size - 1, B) : zero_chs;
+ b = p->p.end_chs;
+ aa = chs_to_longchs(a);
+ bb = chs_to_longchs(b);
+
+ if (a.s && !is_equal_chs(a, b))
+ warnx(_("partition %s: end: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)"),
+ PNO(p), aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
+ if (B.cylinders && B.cylinders < 1024 && bb.c > B.cylinders)
+ warnx(_("partition %s ends on cylinder %ld, beyond the end of the disk"),
+ PNO(p), bb.c);
}
- }
- if (pno == -1 || pno >= 4)
- warnx(_("Warning: no primary partition is marked bootable (active)\n"
- "This does not matter for LILO, but the DOS MBR will "
- "not boot this disk."));
- }
-
- /* Is chs as we expect? */
- for (p = partitions; p < partitions + partno; p++)
- if (p->ptype == DOS_TYPE) {
- chs a, b;
- longchs aa, bb;
- a = p->size ? ulong_to_chs(p->start, B) : zero_chs;
- b = p->p.begin_chs;
- aa = chs_to_longchs(a);
- bb = chs_to_longchs(b);
-
- if (a.s && !is_equal_chs(a, b))
- warnx(_("partition %s: start: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)"),
- PNO(p), aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
- a = p->size ? ulong_to_chs(p->start + p->size - 1, B) : zero_chs;
- b = p->p.end_chs;
- aa = chs_to_longchs(a);
- bb = chs_to_longchs(b);
-
- if (a.s && !is_equal_chs(a, b))
- warnx(_("partition %s: end: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)"),
- PNO(p), aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
- if (B.cylinders && B.cylinders < 1024 && bb.c > B.cylinders)
- warnx(_("partition %s ends on cylinder %ld, beyond the end of the disk"),
- PNO(p), bb.c);
- }
-
- return 1;
+
+ return 1;
#undef PNO
}
static void
extended_partition(char *dev, int fd, struct part_desc *ep, struct disk_desc *z) {
- char *cp;
- struct sector *s;
- unsigned long long start, here, next;
- int i, moretodo = 1;
- struct partition p;
- struct part_desc *partitions = &(z->partitions[0]);
- size_t pno = z->partno;
-
- here = start = ep->start;
-
- if (B.cylindersize && start % B.cylindersize) {
- /* This is BAD */
- if (DOS_extended) {
- here = start -= (start % B.cylindersize);
- warnx(_("Warning: shifted start of the extd partition "
- "from %lld to %lld\n"
- "(For listing purposes only. "
- "Do not change its contents.)"), ep->start, start);
- }
- }
-
- while (moretodo) {
- moretodo = 0;
-
- if (!(s = get_sector(dev, fd, here)))
- break;
-
- if (!msdos_signature(s)) {
- warnx(_("ERROR: sector %llu does not have an msdos signature"),
- s->sectornumber);
- break;
+ char *cp;
+ struct sector *s;
+ unsigned long long start, here, next;
+ int i, moretodo = 1;
+ struct partition p;
+ struct part_desc *partitions = &(z->partitions[0]);
+ size_t pno = z->partno;
+
+ here = start = ep->start;
+
+ if (B.cylindersize && start % B.cylindersize) {
+ /* This is BAD */
+ if (DOS_extended) {
+ here = start -= (start % B.cylindersize);
+ warnx(_("Warning: shifted start of the extd partition "
+ "from %lld to %lld\n"
+ "(For listing purposes only. "
+ "Do not change its contents.)"), ep->start, start);
+ }
}
- cp = s->data + 0x1be;
- if (pno + 4 >= ARRAY_SIZE(z->partitions)) {
- warnx(_("too many partitions - ignoring those past nr (%zu)"),
- pno - 1);
- break;
- }
+ while (moretodo) {
+ moretodo = 0;
- next = 0;
+ if (!(s = get_sector(dev, fd, here)))
+ break;
- for (i = 0; i < 4; i++, cp += sizeof(struct partition)) {
- partitions[pno].sector = here;
- partitions[pno].offset = cp - s->data;
- partitions[pno].ep = ep;
- copy_to_part(cp, &p);
- if (is_extended(p.sys_type)) {
- partitions[pno].start = start + p.start_sect;
- if (next)
- warnx(_("tree of partitions?"));
- else
- next = partitions[pno].start; /* follow `upper' branch */
- moretodo = 1;
- } else {
- partitions[pno].start = here + p.start_sect;
- }
- partitions[pno].size = p.nr_sects;
- partitions[pno].ptype = DOS_TYPE;
- partitions[pno].p = p;
- pno++;
+ if (!msdos_signature(s)) {
+ warnx(_("ERROR: sector %llu does not have an msdos signature"),
+ s->sectornumber);
+ break;
+ }
+ cp = s->data + 0x1be;
+
+ if (pno + 4 >= ARRAY_SIZE(z->partitions)) {
+ warnx(_("too many partitions - ignoring those past nr (%zu)"),
+ pno - 1);
+ break;
+ }
+
+ next = 0;
+
+ for (i = 0; i < 4; i++, cp += sizeof(struct partition)) {
+ partitions[pno].sector = here;
+ partitions[pno].offset = cp - s->data;
+ partitions[pno].ep = ep;
+ copy_to_part(cp, &p);
+ if (is_extended(p.sys_type)) {
+ partitions[pno].start = start + p.start_sect;
+ if (next)
+ warnx(_("tree of partitions?"));
+ else
+ next = partitions[pno].start; /* follow `upper' branch */
+ moretodo = 1;
+ } else {
+ partitions[pno].start = here + p.start_sect;
+ }
+ partitions[pno].size = p.nr_sects;
+ partitions[pno].ptype = DOS_TYPE;
+ partitions[pno].p = p;
+ pno++;
+ }
+ here = next;
}
- here = next;
- }
- z->partno = pno;
+ z->partno = pno;
}
#define BSD_DISKMAGIC (0x82564557UL)
@@ -1352,145 +1352,145 @@ typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
struct bsd_disklabel {
- u32 d_magic;
- char d_junk1[4];
- char d_typename[16];
- char d_packname[16];
- char d_junk2[92];
- u32 d_magic2;
- char d_junk3[2];
- u16 d_npartitions; /* number of partitions in following */
- char d_junk4[8];
- struct bsd_partition { /* the partition table */
- u32 p_size; /* number of sectors in partition */
- u32 p_offset; /* starting sector */
- u32 p_fsize; /* filesystem basic fragment size */
- u8 p_fstype; /* filesystem type, see below */
- u8 p_frag; /* filesystem fragments per block */
- u16 p_cpg; /* filesystem cylinders per group */
- } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */
+ u32 d_magic;
+ char d_junk1[4];
+ char d_typename[16];
+ char d_packname[16];
+ char d_junk2[92];
+ u32 d_magic2;
+ char d_junk3[2];
+ u16 d_npartitions; /* number of partitions in following */
+ char d_junk4[8];
+ struct bsd_partition { /* the partition table */
+ u32 p_size; /* number of sectors in partition */
+ u32 p_offset; /* starting sector */
+ u32 p_fsize; /* filesystem basic fragment size */
+ u8 p_fstype; /* filesystem type, see below */
+ u8 p_frag; /* filesystem fragments per block */
+ u16 p_cpg; /* filesystem cylinders per group */
+ } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */
};
static void
bsd_partition(char *dev, int fd, struct part_desc *ep, struct disk_desc *z) {
- struct bsd_disklabel *l;
- struct bsd_partition *bp, *bp0;
- unsigned long long start = ep->start;
- struct sector *s;
- struct part_desc *partitions = &(z->partitions[0]);
- size_t pno = z->partno;
-
- if (!(s = get_sector(dev, fd, start + 1)))
- return;
- l = (struct bsd_disklabel *)(s->data);
- if (l->d_magic != BSD_DISKMAGIC || l->d_magic2 != BSD_DISKMAGIC)
- return;
-
- bp = bp0 = &l->d_partitions[0];
- while (bp - bp0 < BSD_MAXPARTITIONS && bp - bp0 < l->d_npartitions) {
- if (pno + 1 >= ARRAY_SIZE(z->partitions)) {
- warnx(_("too many partitions - ignoring those "
- "past nr (%zu)"), pno - 1);
- break;
- }
- if (bp->p_fstype != BSD_FS_UNUSED) {
- partitions[pno].start = bp->p_offset;
- partitions[pno].size = bp->p_size;
- partitions[pno].sector = start + 1;
- partitions[pno].offset = (char *)bp - (char *)bp0;
- partitions[pno].ep = 0;
- partitions[pno].ptype = BSD_TYPE;
- pno++;
- }
- bp++;
- }
- z->partno = pno;
+ struct bsd_disklabel *l;
+ struct bsd_partition *bp, *bp0;
+ unsigned long long start = ep->start;
+ struct sector *s;
+ struct part_desc *partitions = &(z->partitions[0]);
+ size_t pno = z->partno;
+
+ if (!(s = get_sector(dev, fd, start + 1)))
+ return;
+ l = (struct bsd_disklabel *)(s->data);
+ if (l->d_magic != BSD_DISKMAGIC || l->d_magic2 != BSD_DISKMAGIC)
+ return;
+
+ bp = bp0 = &l->d_partitions[0];
+ while (bp - bp0 < BSD_MAXPARTITIONS && bp - bp0 < l->d_npartitions) {
+ if (pno + 1 >= ARRAY_SIZE(z->partitions)) {
+ warnx(_("too many partitions - ignoring those "
+ "past nr (%zu)"), pno - 1);
+ break;
+ }
+ if (bp->p_fstype != BSD_FS_UNUSED) {
+ partitions[pno].start = bp->p_offset;
+ partitions[pno].size = bp->p_size;
+ partitions[pno].sector = start + 1;
+ partitions[pno].offset = (char *)bp - (char *)bp0;
+ partitions[pno].ep = 0;
+ partitions[pno].ptype = BSD_TYPE;
+ pno++;
+ }
+ bp++;
+ }
+ z->partno = pno;
}
static int
msdos_partition(char *dev, int fd, unsigned long start, struct disk_desc *z) {
- int i;
- char *cp;
- struct partition pt;
- struct sector *s;
- struct part_desc *partitions = &(z->partitions[0]);
- int pno;
- int bsd_later = 1;
- unsigned short sig, magic;
+ int i;
+ char *cp;
+ struct partition pt;
+ struct sector *s;
+ struct part_desc *partitions = &(z->partitions[0]);
+ int pno;
+ int bsd_later = 1;
+ unsigned short sig, magic;
#ifdef __linux__
- bsd_later = (get_linux_version() >= KERNEL_VERSION(2, 3, 40));
+ bsd_later = (get_linux_version() >= KERNEL_VERSION(2, 3, 40));
#endif
- if (!(s = get_sector(dev, fd, start)))
- return 0;
+ if (!(s = get_sector(dev, fd, start)))
+ return 0;
- if (!msdos_signature(s))
- return 0;
+ if (!msdos_signature(s))
+ return 0;
- cp = s->data + 0x1be;
- copy_to_part(cp, &pt);
+ cp = s->data + 0x1be;
+ copy_to_part(cp, &pt);
- /* If I am not mistaken, recent kernels will hide this from us,
- so we will never actually see traces of a Disk Manager */
- if (pt.sys_type == DM6_PARTITION
- || pt.sys_type == EZD_PARTITION
- || pt.sys_type == DM6_AUX1PARTITION
- || pt.sys_type == DM6_AUX3PARTITION) {
- warnx(_("detected Disk Manager - unable to handle that"));
- return 0;
- }
+ /* If I am not mistaken, recent kernels will hide this from us,
+ so we will never actually see traces of a Disk Manager */
+ if (pt.sys_type == DM6_PARTITION
+ || pt.sys_type == EZD_PARTITION
+ || pt.sys_type == DM6_AUX1PARTITION
+ || pt.sys_type == DM6_AUX3PARTITION) {
+ warnx(_("detected Disk Manager - unable to handle that"));
+ return 0;
+ }
- memcpy(&sig, s->data + 2, sizeof(sig));
- if (sig <= 0x1ae) {
- memcpy(&magic, s->data + sig, sizeof(magic));
- if (magic == 0x55aa && (1 & *(unsigned char *)(s->data + sig + 2))) {
- warnx(_("DM6 signature found - giving up"));
- return 0;
+ memcpy(&sig, s->data + 2, sizeof(sig));
+ if (sig <= 0x1ae) {
+ memcpy(&magic, s->data + sig, sizeof(magic));
+ if (magic == 0x55aa && (1 & *(unsigned char *)(s->data + sig + 2))) {
+ warnx(_("DM6 signature found - giving up"));
+ return 0;
+ }
}
- }
- for (pno = 0; pno < 4; pno++, cp += sizeof(struct partition)) {
- partitions[pno].sector = start;
- partitions[pno].offset = cp - s->data;
- copy_to_part(cp, &pt);
- partitions[pno].start = start + pt.start_sect;
- partitions[pno].size = pt.nr_sects;
- partitions[pno].ep = 0;
- partitions[pno].p = pt;
- }
-
- z->partno = pno;
-
- for (i = 0; i < 4; i++) {
- if (is_extended(partitions[i].p.sys_type)) {
- if (!partitions[i].size) {
- warnx(_("strange..., an extended partition of size 0?"));
- continue;
- }
- extended_partition(dev, fd, &partitions[i], z);
- }
- if (!bsd_later && is_bsd(partitions[i].p.sys_type)) {
- if (!partitions[i].size) {
- warnx(_("strange..., a BSD partition of size 0?"));
- continue;
- }
- bsd_partition(dev, fd, &partitions[i], z);
- }
- }
-
- if (bsd_later) {
+ for (pno = 0; pno < 4; pno++, cp += sizeof(struct partition)) {
+ partitions[pno].sector = start;
+ partitions[pno].offset = cp - s->data;
+ copy_to_part(cp, &pt);
+ partitions[pno].start = start + pt.start_sect;
+ partitions[pno].size = pt.nr_sects;
+ partitions[pno].ep = 0;
+ partitions[pno].p = pt;
+ }
+
+ z->partno = pno;
+
for (i = 0; i < 4; i++) {
- if (is_bsd(partitions[i].p.sys_type)) {
- if (!partitions[i].size) {
- warnx(_("strange..., a BSD partition of size 0?"));
- continue;
+ if (is_extended(partitions[i].p.sys_type)) {
+ if (!partitions[i].size) {
+ warnx(_("strange..., an extended partition of size 0?"));
+ continue;
+ }
+ extended_partition(dev, fd, &partitions[i], z);
+ }
+ if (!bsd_later && is_bsd(partitions[i].p.sys_type)) {
+ if (!partitions[i].size) {
+ warnx(_("strange..., a BSD partition of size 0?"));
+ continue;
+ }
+ bsd_partition(dev, fd, &partitions[i], z);
}
- bsd_partition(dev, fd, &partitions[i], z);
- }
}
- }
- return 1;
+ if (bsd_later) {
+ for (i = 0; i < 4; i++) {
+ if (is_bsd(partitions[i].p.sys_type)) {
+ if (!partitions[i].size) {
+ warnx(_("strange..., a BSD partition of size 0?"));
+ continue;
+ }
+ bsd_partition(dev, fd, &partitions[i], z);
+ }
+ }
+ }
+
+ return 1;
}
static int
@@ -1498,7 +1498,7 @@ osf_partition(char *dev __attribute__ ((__unused__)),
int fd __attribute__ ((__unused__)),
unsigned long start __attribute__ ((__unused__)),
struct disk_desc *z __attribute__ ((__unused__))) {
- return 0;
+ return 0;
}
static int
@@ -1506,7 +1506,7 @@ sun_partition(char *dev __attribute__ ((__unused__)),
int fd __attribute__ ((__unused__)),
unsigned long start __attribute__ ((__unused__)),
struct disk_desc *z __attribute__ ((__unused__))) {
- return 0;
+ return 0;
}
static int
@@ -1514,60 +1514,60 @@ amiga_partition(char *dev __attribute__ ((__unused__)),
int fd __attribute__ ((__unused__)),
unsigned long start __attribute__ ((__unused__)),
struct disk_desc *z __attribute__ ((__unused__))) {
- return 0;
+ return 0;
}
static void
get_partitions(char *dev, int fd, struct disk_desc *z) {
- z->partno = 0;
-
- if (!msdos_partition(dev, fd, 0, z)
- && !osf_partition(dev, fd, 0, z)
- && !sun_partition(dev, fd, 0, z)
- && !amiga_partition(dev, fd, 0, z)) {
- if (!opt_list)
- warnx(_(" %s: unrecognized partition table type"), dev);
- return;
- }
+ z->partno = 0;
+
+ if (!msdos_partition(dev, fd, 0, z)
+ && !osf_partition(dev, fd, 0, z)
+ && !sun_partition(dev, fd, 0, z)
+ && !amiga_partition(dev, fd, 0, z)) {
+ if (!opt_list)
+ warnx(_(" %s: unrecognized partition table type"), dev);
+ return;
+ }
}
static int
write_partitions(char *dev, int fd, struct disk_desc *z) {
- struct sector *s;
- struct part_desc *partitions = &(z->partitions[0]), *p;
- int pno = z->partno;
-
- if (no_write) {
- warnx(_("-n flag was given: Nothing changed"));
- exit(EXIT_SUCCESS);
- }
-
- for (p = partitions; p < partitions + pno; p++) {
- s = get_sector(dev, fd, p->sector);
- if (!s)
- return 0;
- s->to_be_written = 1;
- if (p->ptype == DOS_TYPE) {
- copy_from_part(&(p->p), s->data + p->offset);
- s->data[510] = 0x55;
- s->data[511] = (unsigned char)0xaa;
- }
- }
- if (save_sector_file) {
- if (!save_sectors(dev, fd)) {
- errx(EXIT_FAILURE, _("Failed saving the old sectors - aborting\n"));
- return 0;
- }
- }
- if (!write_sectors(dev, fd)) {
- warnx(_("Failed writing the partition on %s"), dev);
- return 0;
- }
- if (fsync(fd)) {
- warn(_("Failed writing the partition on %s"), dev);
- return 0;
- }
- return 1;
+ struct sector *s;
+ struct part_desc *partitions = &(z->partitions[0]), *p;
+ int pno = z->partno;
+
+ if (no_write) {
+ warnx(_("-n flag was given: Nothing changed"));
+ exit(EXIT_SUCCESS);
+ }
+
+ for (p = partitions; p < partitions + pno; p++) {
+ s = get_sector(dev, fd, p->sector);
+ if (!s)
+ return 0;
+ s->to_be_written = 1;
+ if (p->ptype == DOS_TYPE) {
+ copy_from_part(&(p->p), s->data + p->offset);
+ s->data[510] = 0x55;
+ s->data[511] = (unsigned char)0xaa;
+ }
+ }
+ if (save_sector_file) {
+ if (!save_sectors(dev, fd)) {
+ errx(EXIT_FAILURE, _("Failed saving the old sectors - aborting\n"));
+ return 0;
+ }
+ }
+ if (!write_sectors(dev, fd)) {
+ warnx(_("Failed writing the partition on %s"), dev);
+ return 0;
+ }
+ if (fsync(fd)) {
+ warn(_("Failed writing the partition on %s"), dev);
+ return 0;
+ }
+ return 1;
}
/*
@@ -1597,21 +1597,21 @@ write_partitions(char *dev, int fd, struct disk_desc *z) {
int eof, eob;
struct dumpfld {
- int fldno;
- char *fldname;
- int is_bool;
+ int fldno;
+ char *fldname;
+ int is_bool;
} dumpflds[] = {
- {
- 0, "start", 0}, {
- 1, "size", 0}, {
- 2, "Id", 0}, {
- 3, "bootable", 1}, {
- 4, "bh", 0}, {
- 5, "bs", 0}, {
- 6, "bc", 0}, {
- 7, "eh", 0}, {
- 8, "es", 0}, {
- 9, "ec", 0}
+ {
+ 0, "start", 0}, {
+ 1, "size", 0}, {
+ 2, "Id", 0}, {
+ 3, "bootable", 1}, {
+ 4, "bh", 0}, {
+ 5, "bs", 0}, {
+ 6, "bc", 0}, {
+ 7, "eh", 0}, {
+ 8, "es", 0}, {
+ 9, "ec", 0}
};
/*
@@ -1625,128 +1625,128 @@ struct dumpfld {
static int
read_stdin(char **fields, char *line, int fieldssize, int linesize) {
- char *lp, *ip;
- int c, fno;
-
- /* boolean true and empty string at start */
- line[0] = '*';
- line[1] = 0;
- for (fno = 0; fno < fieldssize; fno++)
- fields[fno] = line + 1;
- fno = 0;
-
- /* read a line from stdin */
- lp = fgets(line + 2, linesize - 2, stdin);
- if (lp == NULL) {
- eof = 1;
- return RD_EOF;
- }
- if (!(lp = strchr(lp, '\n')))
- errx(EXIT_FAILURE, _("long or incomplete input line - quitting"));
- *lp = 0;
-
- /* remove comments, if any */
- if ((lp = strchr(line + 2, '#')) != 0)
+ char *lp, *ip;
+ int c, fno;
+
+ /* boolean true and empty string at start */
+ line[0] = '*';
+ line[1] = 0;
+ for (fno = 0; fno < fieldssize; fno++)
+ fields[fno] = line + 1;
+ fno = 0;
+
+ /* read a line from stdin */
+ lp = fgets(line + 2, linesize - 2, stdin);
+ if (lp == NULL) {
+ eof = 1;
+ return RD_EOF;
+ }
+ if (!(lp = strchr(lp, '\n')))
+ errx(EXIT_FAILURE, _("long or incomplete input line - quitting"));
*lp = 0;
- /* recognize a few commands - to be expanded */
- if (!strcmp(line + 2, "unit: sectors")) {
- specified_format = F_SECTOR;
- return RD_CMD;
- }
-
- /* dump style? - then bad input is fatal */
- if ((ip = strchr(line + 2, ':')) != 0) {
- struct dumpfld *d;
-
- nxtfld:
- ip++;
- while (isspace(*ip))
- ip++;
- if (*ip == 0)
- return fno;
- for (d = dumpflds; (size_t) (d - dumpflds) < ARRAY_SIZE(dumpflds); d++) {
- if (!strncmp(ip, d->fldname, strlen(d->fldname))) {
- ip += strlen(d->fldname);
+ /* remove comments, if any */
+ if ((lp = strchr(line + 2, '#')) != 0)
+ *lp = 0;
+
+ /* recognize a few commands - to be expanded */
+ if (!strcmp(line + 2, "unit: sectors")) {
+ specified_format = F_SECTOR;
+ return RD_CMD;
+ }
+
+ /* dump style? - then bad input is fatal */
+ if ((ip = strchr(line + 2, ':')) != 0) {
+ struct dumpfld *d;
+
+ nxtfld:
+ ip++;
while (isspace(*ip))
- ip++;
- if (d->is_bool)
- fields[d->fldno] = line;
- else if (*ip == '=') {
- while (isspace(*++ip)) ;
- fields[d->fldno] = ip;
- while (isalnum(*ip)) /* 0x07FF */
ip++;
- } else
- errx(EXIT_FAILURE, _("input error: `=' expected after %s field"),
- d->fldname);
- if (fno <= d->fldno)
- fno = d->fldno + 1;
if (*ip == 0)
- return fno;
- if (*ip != ',' && *ip != ';')
- errx(EXIT_FAILURE, _("input error: unexpected character %c after %s field"),
- *ip, d->fldname);
- *ip = 0;
- goto nxtfld;
- }
- }
- errx(EXIT_FAILURE, _("unrecognized input: %s"), ip);
- }
-
- /* split line into fields */
- lp = ip = line + 2;
- fields[fno++] = lp;
- while ((c = *ip++) != 0) {
- if (!lp[-1] && (c == '\t' || c == ' ')) ;
- else if (c == '\t' || c == ' ' || c == ',' || c == ';') {
- *lp++ = 0;
- if (fno < fieldssize)
- fields[fno++] = lp;
- continue;
- } else
- *lp++ = c;
- }
+ return fno;
+ for (d = dumpflds; (size_t) (d - dumpflds) < ARRAY_SIZE(dumpflds); d++) {
+ if (!strncmp(ip, d->fldname, strlen(d->fldname))) {
+ ip += strlen(d->fldname);
+ while (isspace(*ip))
+ ip++;
+ if (d->is_bool)
+ fields[d->fldno] = line;
+ else if (*ip == '=') {
+ while (isspace(*++ip)) ;
+ fields[d->fldno] = ip;
+ while (isalnum(*ip)) /* 0x07FF */
+ ip++;
+ } else
+ errx(EXIT_FAILURE, _("input error: `=' expected after %s field"),
+ d->fldname);
+ if (fno <= d->fldno)
+ fno = d->fldno + 1;
+ if (*ip == 0)
+ return fno;
+ if (*ip != ',' && *ip != ';')
+ errx(EXIT_FAILURE, _("input error: unexpected character %c after %s field"),
+ *ip, d->fldname);
+ *ip = 0;
+ goto nxtfld;
+ }
+ }
+ errx(EXIT_FAILURE, _("unrecognized input: %s"), ip);
+ }
- if (lp == fields[fno - 1])
- fno--;
- return fno;
+ /* split line into fields */
+ lp = ip = line + 2;
+ fields[fno++] = lp;
+ while ((c = *ip++) != 0) {
+ if (!lp[-1] && (c == '\t' || c == ' ')) ;
+ else if (c == '\t' || c == ' ' || c == ',' || c == ';') {
+ *lp++ = 0;
+ if (fno < fieldssize)
+ fields[fno++] = lp;
+ continue;
+ } else
+ *lp++ = c;
+ }
+
+ if (lp == fields[fno - 1])
+ fno--;
+ return fno;
}
/* read a number, use default if absent */
/* a sign gives an offset from the default */
static int
get_ul(char *u, unsigned long *up, unsigned long def, int base) {
- char *nu;
- int sign = 0;
- unsigned long val;
-
- if (*u == '+') {
- sign = 1;
- u++;
- } else if (*u == '-') {
- sign = -1;
- u++;
- }
- if (*u) {
- errno = 0;
- val = strtoul(u, &nu, base);
- if (errno == ERANGE) {
- warnx(_("number too big"));
- return -1;
- }
- if (*nu) {
- warnx(_("trailing junk after number"));
- return -1;
- }
- if (sign == 1)
- val = def + val;
- else if (sign == -1)
- val = def - val;
- *up = val;
- } else
- *up = def;
- return 0;
+ char *nu;
+ int sign = 0;
+ unsigned long val;
+
+ if (*u == '+') {
+ sign = 1;
+ u++;
+ } else if (*u == '-') {
+ sign = -1;
+ u++;
+ }
+ if (*u) {
+ errno = 0;
+ val = strtoul(u, &nu, base);
+ if (errno == ERANGE) {
+ warnx(_("number too big"));
+ return -1;
+ }
+ if (*nu) {
+ warnx(_("trailing junk after number"));
+ return -1;
+ }
+ if (sign == 1)
+ val = def + val;
+ else if (sign == -1)
+ val = def - val;
+ *up = val;
+ } else
+ *up = def;
+ return 0;
}
@@ -1754,36 +1754,36 @@ get_ul(char *u, unsigned long *up, unsigned long def, int base) {
/* a sign gives an offset from the default */
static int
get_ull(char *u, unsigned long long *up, unsigned long long def, int base) {
- char *nu;
- int sign = 0;
- unsigned long long val;
-
- if (*u == '+') {
- sign = 1;
- u++;
- } else if (*u == '-') {
- sign = -1;
- u++;
- }
- if (*u) {
- errno = 0;
- val = strtoull(u, &nu, base);
- if (errno == ERANGE) {
- warnx(_("number too big"));
- return -1;
- }
- if (*nu) {
- warnx(_("trailing junk after number"));
- return -1;
- }
- if (sign == 1)
- val = def + val;
- else if (sign == -1)
- val = def - val;
- *up = val;
- } else
- *up = def;
- return 0;
+ char *nu;
+ int sign = 0;
+ unsigned long long val;
+
+ if (*u == '+') {
+ sign = 1;
+ u++;
+ } else if (*u == '-') {
+ sign = -1;
+ u++;
+ }
+ if (*u) {
+ errno = 0;
+ val = strtoull(u, &nu, base);
+ if (errno == ERANGE) {
+ warnx(_("number too big"));
+ return -1;
+ }
+ if (*nu) {
+ warnx(_("trailing junk after number"));
+ return -1;
+ }
+ if (sign == 1)
+ val = def + val;
+ else if (sign == -1)
+ val = def - val;
+ *up = val;
+ } else
+ *up = def;
+ return 0;
}
@@ -1791,12 +1791,12 @@ get_ull(char *u, unsigned long long *up, unsigned long long def, int base) {
as nested boxes, and as a chain. Sometimes the partitions
must be given in order. Sometimes all logical partitions
must lie inside the outermost extended partition.
-NESTED: every partition is contained in the surrounding partitions
+ NESTED: every partition is contained in the surrounding partitions
and is disjoint from all others.
-CHAINED: every data partition is contained in the surrounding partitions
+ CHAINED: every data partition is contained in the surrounding partitions
and disjoint from all others, but extended partitions may lie outside
(insofar as allowed by all_logicals_inside_outermost_extended).
-ONESECTOR: all data partitions are mutually disjoint; extended partitions
+ ONESECTOR: all data partitions are mutually disjoint; extended partitions
each use one sector only (except perhaps for the outermost one).
*/
int partitions_in_order = 0;
@@ -1807,70 +1807,70 @@ enum { NESTED, CHAINED, ONESECTOR } boxes = NESTED;
static unsigned long long
first_free(int pno, int is_extended, struct part_desc *ep, int format,
unsigned long long mid, struct disk_desc *z) {
- unsigned long long ff, fff;
- unsigned long unit = unitsize(format);
- struct part_desc *partitions = &(z->partitions[0]), *pp = 0;
-
- /* if containing ep undefined, look at its container */
- if (ep && ep->p.sys_type == EMPTY_PARTITION)
- ep = ep->ep;
-
- if (ep) {
- if (boxes == NESTED || (boxes == CHAINED && !is_extended))
- pp = ep;
- else if (all_logicals_inside_outermost_extended)
- pp = outer_extended_partition(ep);
- }
-
- /* rounding up wastes almost an entire cylinder - round down
- and leave it to compute_start_sect() to fix the difference */
- ff = pp ? pp->start / unit : 0;
-
- /* MBR and 1st sector of an extended partition are never free */
- if (unit == 1)
- ff++;
+ unsigned long long ff, fff;
+ unsigned long unit = unitsize(format);
+ struct part_desc *partitions = &(z->partitions[0]), *pp = 0;
+
+ /* if containing ep undefined, look at its container */
+ if (ep && ep->p.sys_type == EMPTY_PARTITION)
+ ep = ep->ep;
+
+ if (ep) {
+ if (boxes == NESTED || (boxes == CHAINED && !is_extended))
+ pp = ep;
+ else if (all_logicals_inside_outermost_extended)
+ pp = outer_extended_partition(ep);
+ }
- again:
- for (pp = partitions; pp < partitions + pno; pp++) {
- if (!is_parent(pp, ep) && pp->size > 0) {
- if ((partitions_in_order || pp->start / unit <= ff
- || (mid && pp->start / unit <= mid))
- && (fff = (pp->start + pp->size + unit - 1) / unit) > ff) {
- ff = fff;
- goto again;
- }
+ /* rounding up wastes almost an entire cylinder - round down
+ and leave it to compute_start_sect() to fix the difference */
+ ff = pp ? pp->start / unit : 0;
+
+ /* MBR and 1st sector of an extended partition are never free */
+ if (unit == 1)
+ ff++;
+
+again:
+ for (pp = partitions; pp < partitions + pno; pp++) {
+ if (!is_parent(pp, ep) && pp->size > 0) {
+ if ((partitions_in_order || pp->start / unit <= ff
+ || (mid && pp->start / unit <= mid))
+ && (fff = (pp->start + pp->size + unit - 1) / unit) > ff) {
+ ff = fff;
+ goto again;
+ }
+ }
}
- }
- return ff;
+ return ff;
}
/* find the default value for <size> - assuming entire units */
static unsigned long long
max_length(int pno, int is_extended, struct part_desc *ep, int format,
unsigned long long start, struct disk_desc *z) {
- unsigned long long fu;
- unsigned long unit = unitsize(format);
- struct part_desc *partitions = &(z->partitions[0]), *pp = 0;
-
- /* if containing ep undefined, look at its container */
- if (ep && ep->p.sys_type == EMPTY_PARTITION)
- ep = ep->ep;
-
- if (ep) {
- if (boxes == NESTED || (boxes == CHAINED && !is_extended))
- pp = ep;
- else if (all_logicals_inside_outermost_extended)
- pp = outer_extended_partition(ep);
- }
- fu = pp ? (pp->start + pp->size) / unit : get_disksize(format);
+ unsigned long long fu;
+ unsigned long unit = unitsize(format);
+ struct part_desc *partitions = &(z->partitions[0]), *pp = 0;
+
+ /* if containing ep undefined, look at its container */
+ if (ep && ep->p.sys_type == EMPTY_PARTITION)
+ ep = ep->ep;
+
+ if (ep) {
+ if (boxes == NESTED || (boxes == CHAINED && !is_extended))
+ pp = ep;
+ else if (all_logicals_inside_outermost_extended)
+ pp = outer_extended_partition(ep);
+ }
+ fu = pp ? (pp->start + pp->size) / unit : get_disksize(format);
- for (pp = partitions; pp < partitions + pno; pp++)
- if (!is_parent(pp, ep) && pp->size > 0
- && pp->start / unit >= start && pp->start / unit < fu)
- fu = pp->start / unit;
+ for (pp = partitions; pp < partitions + pno; pp++)
+ if (!is_parent(pp, ep) && pp->size > 0
+ && pp->start / unit >= start && pp->start / unit < fu)
+ fu = pp->start / unit;
- return (fu > start) ? fu - start : 0;
+ return (fu > start) ? fu - start : 0;
}
/* compute starting sector of a partition inside an extended one */
@@ -1878,278 +1878,278 @@ max_length(int pno, int is_extended, struct part_desc *ep, int format,
/* ep is 0 or points to surrounding extended partition */
static int
compute_start_sect(struct part_desc *p, struct part_desc *ep) {
- unsigned long long base;
- int inc = (DOS && B.sectors) ? B.sectors : 1;
- long long delta;
-
- if (ep && p->start + p->size >= ep->start + 1)
- delta = p->start - ep->start - inc;
- else if (p->start == 0 && p->size > 0)
- delta = -inc;
- else
- delta = 0;
-
- if (delta < 0) {
- unsigned long long old_size = p->size;
- p->start -= delta;
- p->size += delta;
- if (is_extended(p->p.sys_type) && boxes == ONESECTOR)
- p->size = inc;
- else if ((long long) old_size <= -delta) {
- warnx(_("no room for partition descriptor"));
- return 0;
- }
- }
- base = (!ep ? 0
- : (is_extended(p->p.sys_type) ?
- outer_extended_partition(ep) : ep)->start);
- p->ep = ep;
- if (p->p.sys_type == EMPTY_PARTITION && p->size == 0) {
- p->p.start_sect = 0;
- p->p.begin_chs = zero_chs;
- p->p.end_chs = zero_chs;
- } else {
- p->p.start_sect = p->start - base;
- p->p.begin_chs = ulong_to_chs(p->start, B);
- p->p.end_chs = ulong_to_chs(p->start + p->size - 1, B);
- }
- p->p.nr_sects = p->size;
- return 1;
+ unsigned long long base;
+ int inc = (DOS && B.sectors) ? B.sectors : 1;
+ long long delta;
+
+ if (ep && p->start + p->size >= ep->start + 1)
+ delta = p->start - ep->start - inc;
+ else if (p->start == 0 && p->size > 0)
+ delta = -inc;
+ else
+ delta = 0;
+
+ if (delta < 0) {
+ unsigned long long old_size = p->size;
+ p->start -= delta;
+ p->size += delta;
+ if (is_extended(p->p.sys_type) && boxes == ONESECTOR)
+ p->size = inc;
+ else if ((long long) old_size <= -delta) {
+ warnx(_("no room for partition descriptor"));
+ return 0;
+ }
+ }
+ base = (!ep ? 0
+ : (is_extended(p->p.sys_type) ?
+ outer_extended_partition(ep) : ep)->start);
+ p->ep = ep;
+ if (p->p.sys_type == EMPTY_PARTITION && p->size == 0) {
+ p->p.start_sect = 0;
+ p->p.begin_chs = zero_chs;
+ p->p.end_chs = zero_chs;
+ } else {
+ p->p.start_sect = p->start - base;
+ p->p.begin_chs = ulong_to_chs(p->start, B);
+ p->p.end_chs = ulong_to_chs(p->start + p->size - 1, B);
+ }
+ p->p.nr_sects = p->size;
+ return 1;
}
/* build the extended partition surrounding a given logical partition */
static int
build_surrounding_extended(struct part_desc *p, struct part_desc *ep,
struct disk_desc *z) {
- int inc = (DOS && B.sectors) ? B.sectors : 1;
- int format = F_SECTOR;
- struct part_desc *p0 = &(z->partitions[0]), *eep = ep->ep;
-
- if (boxes == NESTED) {
- ep->start = first_free(ep - p0, 1, eep, format, p->start, z);
- ep->size = max_length(ep - p0, 1, eep, format, ep->start, z);
- if (ep->start > p->start || ep->start + ep->size < p->start + p->size) {
- warnx(_("cannot build surrounding extended partition"));
- return 0;
- }
- } else {
- ep->start = p->start;
- if (boxes == CHAINED)
- ep->size = p->size;
- else
- ep->size = inc;
- }
-
- ep->p.nr_sects = ep->size;
- ep->p.bootable = 0;
- ep->p.sys_type = EXTENDED_PARTITION;
- if (!compute_start_sect(ep, eep) || !compute_start_sect(p, ep)) {
- ep->p.sys_type = EMPTY_PARTITION;
- ep->size = 0;
- return 0;
- }
+ int inc = (DOS && B.sectors) ? B.sectors : 1;
+ int format = F_SECTOR;
+ struct part_desc *p0 = &(z->partitions[0]), *eep = ep->ep;
+
+ if (boxes == NESTED) {
+ ep->start = first_free(ep - p0, 1, eep, format, p->start, z);
+ ep->size = max_length(ep - p0, 1, eep, format, ep->start, z);
+ if (ep->start > p->start || ep->start + ep->size < p->start + p->size) {
+ warnx(_("cannot build surrounding extended partition"));
+ return 0;
+ }
+ } else {
+ ep->start = p->start;
+ if (boxes == CHAINED)
+ ep->size = p->size;
+ else
+ ep->size = inc;
+ }
+
+ ep->p.nr_sects = ep->size;
+ ep->p.bootable = 0;
+ ep->p.sys_type = EXTENDED_PARTITION;
+ if (!compute_start_sect(ep, eep) || !compute_start_sect(p, ep)) {
+ ep->p.sys_type = EMPTY_PARTITION;
+ ep->size = 0;
+ return 0;
+ }
- return 1;
+ return 1;
}
static int
read_line(int pno, struct part_desc *ep, char *dev, int interactive,
struct disk_desc *z) {
- char line[1000];
- char *fields[11];
- int fno, pct = pno % 4;
- struct part_desc p, *orig;
- unsigned long long ff, ff1, ul, ml, ml1, def;
- int format = 0, lpno, is_extd;
-
- if (eof || eob)
- return -1;
+ char line[1000];
+ char *fields[11];
+ int fno, pct = pno % 4;
+ struct part_desc p, *orig;
+ unsigned long long ff, ff1, ul, ml, ml1, def;
+ int format = 0, lpno, is_extd;
- lpno = index_to_linux(pno, z);
+ if (eof || eob)
+ return -1;
- if (interactive) {
- if (pct == 0 && (show_extended || pno == 0))
- putchar('\n');
- warnx("%s:", partname(dev, lpno, 10));
- }
+ lpno = index_to_linux(pno, z);
- /* read input line - skip blank lines when reading from a file */
- do {
- fno = read_stdin(fields, line, ARRAY_SIZE(fields), ARRAY_SIZE(line));
- } while (fno == RD_CMD || (fno == 0 && !interactive));
- if (fno == RD_EOF) {
- return -1;
- } else if (fno > 10 && *(fields[10]) != 0) {
- warnx(_("too many input fields"));
- return 0;
- }
+ if (interactive) {
+ if (pct == 0 && (show_extended || pno == 0))
+ putchar('\n');
+ warnx("%s:", partname(dev, lpno, 10));
+ }
- if (fno == 1 && !strcmp(fields[0], ".")) {
- eob = 1;
- return -1;
- }
+ /* read input line - skip blank lines when reading from a file */
+ do {
+ fno = read_stdin(fields, line, ARRAY_SIZE(fields), ARRAY_SIZE(line));
+ } while (fno == RD_CMD || (fno == 0 && !interactive));
+ if (fno == RD_EOF) {
+ return -1;
+ } else if (fno > 10 && *(fields[10]) != 0) {
+ warnx(_("too many input fields"));
+ return 0;
+ }
- orig = (one_only ? &(oldp.partitions[pno]) : 0);
+ if (fno == 1 && !strcmp(fields[0], ".")) {
+ eob = 1;
+ return -1;
+ }
- p = zero_part_desc;
- p.ep = ep;
+ orig = (one_only ? &(oldp.partitions[pno]) : 0);
+
+ p = zero_part_desc;
+ p.ep = ep;
+
+ /* first read the type - we need to know whether it is extended */
+ /* stop reading when input blank (defaults) and all is full */
+ is_extd = 0;
+ if (fno == 0) { /* empty line */
+ if (orig && is_extended(orig->p.sys_type))
+ is_extd = 1;
+ ff = first_free(pno, is_extd, ep, format, 0, z);
+ ml = max_length(pno, is_extd, ep, format, ff, z);
+ if (ml == 0 && is_extd == 0) {
+ is_extd = 1;
+ ff = first_free(pno, is_extd, ep, format, 0, z);
+ ml = max_length(pno, is_extd, ep, format, ff, z);
+ }
+ if (ml == 0 && pno >= 4) {
+ /* no free blocks left - don't read any further */
+ warnx(_("No room for more"));
+ return -1;
+ }
+ }
+ if (fno < 3 || !*(fields[2]))
+ ul = orig ? orig->p.sys_type :
+ (is_extd || (pno > 3 && pct == 1 && show_extended))
+ ? EXTENDED_PARTITION : LINUX_NATIVE;
+ else if (!strcmp(fields[2], "L"))
+ ul = LINUX_NATIVE;
+ else if (!strcmp(fields[2], "S"))
+ ul = LINUX_SWAP;
+ else if (!strcmp(fields[2], "E"))
+ ul = EXTENDED_PARTITION;
+ else if (!strcmp(fields[2], "X"))
+ ul = LINUX_EXTENDED;
+ else if (get_ull(fields[2], &ul, LINUX_NATIVE, 16))
+ return 0;
+ if (ul > 255) {
+ warnx(_("Illegal type"));
+ return 0;
+ }
+ p.p.sys_type = ul;
+ is_extd = is_extended(ul);
- /* first read the type - we need to know whether it is extended */
- /* stop reading when input blank (defaults) and all is full */
- is_extd = 0;
- if (fno == 0) { /* empty line */
- if (orig && is_extended(orig->p.sys_type))
- is_extd = 1;
+ /* find start */
ff = first_free(pno, is_extd, ep, format, 0, z);
- ml = max_length(pno, is_extd, ep, format, ff, z);
- if (ml == 0 && is_extd == 0) {
- is_extd = 1;
- ff = first_free(pno, is_extd, ep, format, 0, z);
- ml = max_length(pno, is_extd, ep, format, ff, z);
- }
- if (ml == 0 && pno >= 4) {
- /* no free blocks left - don't read any further */
- warnx(_("No room for more"));
- return -1;
- }
- }
- if (fno < 3 || !*(fields[2]))
- ul = orig ? orig->p.sys_type :
- (is_extd || (pno > 3 && pct == 1 && show_extended))
- ? EXTENDED_PARTITION : LINUX_NATIVE;
- else if (!strcmp(fields[2], "L"))
- ul = LINUX_NATIVE;
- else if (!strcmp(fields[2], "S"))
- ul = LINUX_SWAP;
- else if (!strcmp(fields[2], "E"))
- ul = EXTENDED_PARTITION;
- else if (!strcmp(fields[2], "X"))
- ul = LINUX_EXTENDED;
- else if (get_ull(fields[2], &ul, LINUX_NATIVE, 16))
- return 0;
- if (ul > 255) {
- warnx(_("Illegal type"));
- return 0;
- }
- p.p.sys_type = ul;
- is_extd = is_extended(ul);
-
- /* find start */
- ff = first_free(pno, is_extd, ep, format, 0, z);
- ff1 = ff * unitsize(format);
- def = orig ? orig->start : (pno > 4 && pct > 1) ? 0 : ff1;
- if (fno < 1 || !*(fields[0]))
- p.start = def;
- else {
- if (get_ull(fields[0], &ul, def / unitsize(0), 0))
- return 0;
- p.start = ul * unitsize(0);
- p.start -= (p.start % unitsize(format));
- }
-
- /* find length */
- ml = max_length(pno, is_extd, ep, format, p.start / unitsize(format), z);
- ml1 = ml * unitsize(format);
- def = orig ? orig->size : (pno > 4 && pct > 1) ? 0 : ml1;
- if (fno < 2 || !*(fields[1]))
- p.size = def;
- else if (!strcmp(fields[1], "+"))
- p.size = ml1;
- else {
- if (get_ull(fields[1], &ul, def / unitsize(0), 0))
- return 0;
- p.size = ul * unitsize(0) + unitsize(format) - 1;
- p.size -= (p.size % unitsize(format));
- }
- if (p.size > ml1) {
- warnx(_("Warning: given size (%llu) exceeds max allowable size (%llu)"),
- (p.size + unitsize(0) - 1) / unitsize(0), ml1 / unitsize(0));
- if (!force)
- return 0;
- }
- if (p.size == 0 && pno >= 4 && (fno < 2 || !*(fields[1]))) {
- warnx(_("Warning: empty partition"));
- if (!force)
- return 0;
- }
- p.p.nr_sects = p.size;
-
- if (p.size == 0 && !orig) {
+ ff1 = ff * unitsize(format);
+ def = orig ? orig->start : (pno > 4 && pct > 1) ? 0 : ff1;
if (fno < 1 || !*(fields[0]))
- p.start = 0;
- if (fno < 3 || !*(fields[2]))
- p.p.sys_type = EMPTY_PARTITION;
- }
-
- if (p.start < ff1 && p.size > 0) {
- warnx(_("Warning: bad partition start (earliest %llu)"),
- (ff1 + unitsize(0) - 1) / unitsize(0));
- if (!force)
- return 0;
- }
-
- if (fno < 4 || !*(fields[3]))
- ul = (orig ? orig->p.bootable : 0);
- else if (!strcmp(fields[3], "-"))
- ul = 0;
- else if (!strcmp(fields[3], "*") || !strcmp(fields[3], "+"))
- ul = 0x80;
- else {
- warnx(_("unrecognized bootable flag - choose - or *"));
- return 0;
- }
- p.p.bootable = ul;
+ p.start = def;
+ else {
+ if (get_ull(fields[0], &ul, def / unitsize(0), 0))
+ return 0;
+ p.start = ul * unitsize(0);
+ p.start -= (p.start % unitsize(format));
+ }
- if (ep && ep->p.sys_type == EMPTY_PARTITION) {
- if (!build_surrounding_extended(&p, ep, z))
- return 0;
- } else if (!compute_start_sect(&p, ep))
- return 0;
+ /* find length */
+ ml = max_length(pno, is_extd, ep, format, p.start / unitsize(format), z);
+ ml1 = ml * unitsize(format);
+ def = orig ? orig->size : (pno > 4 && pct > 1) ? 0 : ml1;
+ if (fno < 2 || !*(fields[1]))
+ p.size = def;
+ else if (!strcmp(fields[1], "+"))
+ p.size = ml1;
+ else {
+ if (get_ull(fields[1], &ul, def / unitsize(0), 0))
+ return 0;
+ p.size = ul * unitsize(0) + unitsize(format) - 1;
+ p.size -= (p.size % unitsize(format));
+ }
+ if (p.size > ml1) {
+ warnx(_("Warning: given size (%llu) exceeds max allowable size (%llu)"),
+ (p.size + unitsize(0) - 1) / unitsize(0), ml1 / unitsize(0));
+ if (!force)
+ return 0;
+ }
+ if (p.size == 0 && pno >= 4 && (fno < 2 || !*(fields[1]))) {
+ warnx(_("Warning: empty partition"));
+ if (!force)
+ return 0;
+ }
+ p.p.nr_sects = p.size;
- {
- longchs aa = chs_to_longchs(p.p.begin_chs), bb;
-
- if (fno < 5) {
- bb = aa;
- } else if (fno < 7) {
- warnx(_("partial c,h,s specification?"));
- return 0;
- } else if (get_ul(fields[4], &bb.c, aa.c, 0) ||
- get_ul(fields[5], &bb.h, aa.h, 0) ||
- get_ul(fields[6], &bb.s, aa.s, 0))
- return 0;
- p.p.begin_chs = longchs_to_chs(bb, B);
- }
- {
- longchs aa = chs_to_longchs(p.p.end_chs), bb;
-
- if (fno < 8) {
- bb = aa;
- } else if (fno < 10) {
- warnx(_("partial c,h,s specification?"));
- return 0;
- } else if (get_ul(fields[7], &bb.c, aa.c, 0) ||
- get_ul(fields[8], &bb.h, aa.h, 0) ||
- get_ul(fields[9], &bb.s, aa.s, 0))
- return 0;
- p.p.end_chs = longchs_to_chs(bb, B);
- }
-
- if (pno > 3 && p.size && show_extended && p.p.sys_type != EMPTY_PARTITION
- && (is_extended(p.p.sys_type) != (pct == 1))) {
- warnx(_("Extended partition not where expected"));
- if (!force)
- return 0;
- }
-
- z->partitions[pno] = p;
- if (pno >= z->partno)
- z->partno += 4; /* reqd for out_partition() */
-
- if (interactive)
- out_partition(dev, 0, &(z->partitions[pno]), z, B);
-
- return 1;
+ if (p.size == 0 && !orig) {
+ if (fno < 1 || !*(fields[0]))
+ p.start = 0;
+ if (fno < 3 || !*(fields[2]))
+ p.p.sys_type = EMPTY_PARTITION;
+ }
+
+ if (p.start < ff1 && p.size > 0) {
+ warnx(_("Warning: bad partition start (earliest %llu)"),
+ (ff1 + unitsize(0) - 1) / unitsize(0));
+ if (!force)
+ return 0;
+ }
+
+ if (fno < 4 || !*(fields[3]))
+ ul = (orig ? orig->p.bootable : 0);
+ else if (!strcmp(fields[3], "-"))
+ ul = 0;
+ else if (!strcmp(fields[3], "*") || !strcmp(fields[3], "+"))
+ ul = 0x80;
+ else {
+ warnx(_("unrecognized bootable flag - choose - or *"));
+ return 0;
+ }
+ p.p.bootable = ul;
+
+ if (ep && ep->p.sys_type == EMPTY_PARTITION) {
+ if (!build_surrounding_extended(&p, ep, z))
+ return 0;
+ } else if (!compute_start_sect(&p, ep))
+ return 0;
+
+ {
+ longchs aa = chs_to_longchs(p.p.begin_chs), bb;
+
+ if (fno < 5) {
+ bb = aa;
+ } else if (fno < 7) {
+ warnx(_("partial c,h,s specification?"));
+ return 0;
+ } else if (get_ul(fields[4], &bb.c, aa.c, 0) ||
+ get_ul(fields[5], &bb.h, aa.h, 0) ||
+ get_ul(fields[6], &bb.s, aa.s, 0))
+ return 0;
+ p.p.begin_chs = longchs_to_chs(bb, B);
+ }
+ {
+ longchs aa = chs_to_longchs(p.p.end_chs), bb;
+
+ if (fno < 8) {
+ bb = aa;
+ } else if (fno < 10) {
+ warnx(_("partial c,h,s specification?"));
+ return 0;
+ } else if (get_ul(fields[7], &bb.c, aa.c, 0) ||
+ get_ul(fields[8], &bb.h, aa.h, 0) ||
+ get_ul(fields[9], &bb.s, aa.s, 0))
+ return 0;
+ p.p.end_chs = longchs_to_chs(bb, B);
+ }
+
+ if (pno > 3 && p.size && show_extended && p.p.sys_type != EMPTY_PARTITION
+ && (is_extended(p.p.sys_type) != (pct == 1))) {
+ warnx(_("Extended partition not where expected"));
+ if (!force)
+ return 0;
+ }
+
+ z->partitions[pno] = p;
+ if (pno >= z->partno)
+ z->partno += 4; /* reqd for out_partition() */
+
+ if (interactive)
+ out_partition(dev, 0, &(z->partitions[pno]), z, B);
+
+ return 1;
}
/* ep either points to the extended partition to contain this one,
@@ -2157,87 +2157,87 @@ read_line(int pno, struct part_desc *ep, char *dev, int interactive,
static int
read_partition(char *dev, int interactive, int pno, struct part_desc *ep,
struct disk_desc *z) {
- struct part_desc *p = &(z->partitions[pno]);
- int i;
-
- if (one_only) {
- *p = oldp.partitions[pno];
- if (one_only_pno != pno)
- goto ret;
- } else if (!show_extended && pno > 4 && pno % 4)
- goto ret;
-
- while (!(i = read_line(pno, ep, dev, interactive, z)))
- if (!interactive)
- errx(EXIT_FAILURE, _("bad input"));
- if (i < 0) {
- p->ep = ep;
- return 0;
- }
+ struct part_desc *p = &(z->partitions[pno]);
+ int i;
+
+ if (one_only) {
+ *p = oldp.partitions[pno];
+ if (one_only_pno != pno)
+ goto ret;
+ } else if (!show_extended && pno > 4 && pno % 4)
+ goto ret;
+
+ while (!(i = read_line(pno, ep, dev, interactive, z)))
+ if (!interactive)
+ errx(EXIT_FAILURE, _("bad input"));
+ if (i < 0) {
+ p->ep = ep;
+ return 0;
+ }
- ret:
- p->ep = ep;
- if (pno >= z->partno)
- z->partno += 4;
- return 1;
+ret:
+ p->ep = ep;
+ if (pno >= z->partno)
+ z->partno += 4;
+ return 1;
}
static void
read_partition_chain(char *dev, int interactive, struct part_desc *ep,
struct disk_desc *z) {
- int i;
- size_t base;
-
- eob = 0;
- while (1) {
- base = z->partno;
- if (base + 4 > ARRAY_SIZE(z->partitions)) {
- warnx(_("too many partitions"));
- break;
- }
- for (i = 0; i < 4; i++)
- if (!read_partition(dev, interactive, base + i, ep, z))
- return;
- for (i = 0; i < 4; i++) {
- ep = &(z->partitions[base + i]);
- if (is_extended(ep->p.sys_type) && ep->size)
- break;
- }
- if (i == 4) {
- /* nothing found - maybe an empty partition is going
- to be extended */
- if (one_only || show_extended)
- break;
- ep = &(z->partitions[base + 1]);
- if (ep->size || ep->p.sys_type != EMPTY_PARTITION)
- break;
+ int i;
+ size_t base;
+
+ eob = 0;
+ while (1) {
+ base = z->partno;
+ if (base + 4 > ARRAY_SIZE(z->partitions)) {
+ warnx(_("too many partitions"));
+ break;
+ }
+ for (i = 0; i < 4; i++)
+ if (!read_partition(dev, interactive, base + i, ep, z))
+ return;
+ for (i = 0; i < 4; i++) {
+ ep = &(z->partitions[base + i]);
+ if (is_extended(ep->p.sys_type) && ep->size)
+ break;
+ }
+ if (i == 4) {
+ /* nothing found - maybe an empty partition is going
+ to be extended */
+ if (one_only || show_extended)
+ break;
+ ep = &(z->partitions[base + 1]);
+ if (ep->size || ep->p.sys_type != EMPTY_PARTITION)
+ break;
+ }
}
- }
}
static void
read_input(char *dev, int interactive, struct disk_desc *z) {
- size_t i;
- struct part_desc *partitions = &(z->partitions[0]), *ep;
+ size_t i;
+ struct part_desc *partitions = &(z->partitions[0]), *ep;
- for (i = 0; i < ARRAY_SIZE(z->partitions); i++)
- partitions[i] = zero_part_desc;
- z->partno = 0;
+ for (i = 0; i < ARRAY_SIZE(z->partitions); i++)
+ partitions[i] = zero_part_desc;
+ z->partno = 0;
- if (interactive)
- warnx(_("Input in the following format; absent fields get a default value.\n"
- "<start> <size> <type [E,S,L,X,hex]> <bootable [-,*]> <c,h,s> <c,h,s>\n"
- "Usually you only need to specify <start> and <size> (and perhaps <type>)."));
- eof = 0;
+ if (interactive)
+ warnx(_("Input in the following format; absent fields get a default value.\n"
+ "<start> <size> <type [E,S,L,X,hex]> <bootable [-,*]> <c,h,s> <c,h,s>\n"
+ "Usually you only need to specify <start> and <size> (and perhaps <type>)."));
+ eof = 0;
- for (i = 0; i < 4; i++)
- read_partition(dev, interactive, i, 0, z);
- for (i = 0; i < 4; i++) {
- ep = partitions + i;
- if (is_extended(ep->p.sys_type) && ep->size)
- read_partition_chain(dev, interactive, ep, z);
- }
- add_sector_and_offset(z);
+ for (i = 0; i < 4; i++)
+ read_partition(dev, interactive, i, 0, z);
+ for (i = 0; i < 4; i++) {
+ ep = partitions + i;
+ if (is_extended(ep->p.sys_type) && ep->size)
+ read_partition_chain(dev, interactive, ep, z);
+ }
+ add_sector_and_offset(z);
}
/*
@@ -2304,75 +2304,75 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
static void
activate_usage(void) {
- char *p;
- if (!strcmp(program_invocation_short_name, "activate"))
- p = " ";
- else
- p = " --activate=";
- fputs(USAGE_HEADER, stderr);
- fputs(USAGE_SEPARATOR, stderr);
- fprintf(stderr, _(" %s%sdevice list active partitions on device\n"),
- program_invocation_short_name, p);
- fprintf(stderr, _(" %s%sdevice n1 n2 ... activate partitions n1 ..., inactivate the rest\n"),
- program_invocation_short_name, p);
- fprintf(stderr, USAGE_MAN_TAIL("sfdisk(8)"));
- exit(EXIT_FAILURE);
+ char *p;
+ if (!strcmp(program_invocation_short_name, "activate"))
+ p = " ";
+ else
+ p = " --activate=";
+ fputs(USAGE_HEADER, stderr);
+ fputs(USAGE_SEPARATOR, stderr);
+ fprintf(stderr, _(" %s%sdevice list active partitions on device\n"),
+ program_invocation_short_name, p);
+ fprintf(stderr, _(" %s%sdevice n1 n2 ... activate partitions n1 ..., inactivate the rest\n"),
+ program_invocation_short_name, p);
+ fprintf(stderr, USAGE_MAN_TAIL("sfdisk(8)"));
+ exit(EXIT_FAILURE);
}
#define PRINT_ID 0400
#define CHANGE_ID 01000
enum {
- OPT_NO_REREAD = CHAR_MAX + 1,
- OPT_LEAVE_LAST,
- OPT_IN_ORDER,
- OPT_NOT_IN_ORDER,
- OPT_INSIDE_OUTER,
- OPT_NOT_INSIDE_OUTER,
- OPT_NESTED,
- OPT_CHAINED,
- OPT_ONESECTOR
+ OPT_NO_REREAD = CHAR_MAX + 1,
+ OPT_LEAVE_LAST,
+ OPT_IN_ORDER,
+ OPT_NOT_IN_ORDER,
+ OPT_INSIDE_OUTER,
+ OPT_NOT_INSIDE_OUTER,
+ OPT_NESTED,
+ OPT_CHAINED,
+ OPT_ONESECTOR
};
static const struct option long_opts[] = {
- { "change-id", no_argument, NULL, 'c' + CHANGE_ID },
- { "print-id", no_argument, NULL, 'c' + PRINT_ID },
- { "id", no_argument, NULL, 'c' },
- { "dump", no_argument, NULL, 'd' },
- { "force", no_argument, NULL, 'f' },
- { "show-geometry", no_argument, NULL, 'g' },
- { "help", no_argument, NULL, 'h' },
- { "increment", no_argument, NULL, 'i' },
- { "list", no_argument, NULL, 'l' },
- { "quiet", no_argument, NULL, 'q' },
- { "show-size", no_argument, NULL, 's' },
- { "unit", required_argument, NULL, 'u' },
- { "version", no_argument, NULL, 'v' },
- { "show-extended", no_argument, NULL, 'x' },
- { "one-only", no_argument, NULL, '1' },
- { "cylinders", required_argument, NULL, 'C' },
- { "heads", required_argument, NULL, 'H' },
- { "sectors", required_argument, NULL, 'S' },
- { "show-pt-geometry", no_argument, NULL, 'G' },
- { "activate", optional_argument, NULL, 'A' },
- { "DOS", no_argument, NULL, 'D' },
- { "DOS-extended", no_argument, NULL, 'E' },
- { "Linux", no_argument, NULL, 'L' },
- { "re-read", no_argument, NULL, 'R' },
- { "list-types", no_argument, NULL, 'T' },
- { "unhide", optional_argument, NULL, 'U' },
- { "no-reread", no_argument, NULL, OPT_NO_REREAD },
- { "IBM", no_argument, NULL, OPT_LEAVE_LAST },
- { "leave-last", no_argument, NULL, OPT_LEAVE_LAST },
+ { "change-id", no_argument, NULL, 'c' + CHANGE_ID },
+ { "print-id", no_argument, NULL, 'c' + PRINT_ID },
+ { "id", no_argument, NULL, 'c' },
+ { "dump", no_argument, NULL, 'd' },
+ { "force", no_argument, NULL, 'f' },
+ { "show-geometry", no_argument, NULL, 'g' },
+ { "help", no_argument, NULL, 'h' },
+ { "increment", no_argument, NULL, 'i' },
+ { "list", no_argument, NULL, 'l' },
+ { "quiet", no_argument, NULL, 'q' },
+ { "show-size", no_argument, NULL, 's' },
+ { "unit", required_argument, NULL, 'u' },
+ { "version", no_argument, NULL, 'v' },
+ { "show-extended", no_argument, NULL, 'x' },
+ { "one-only", no_argument, NULL, '1' },
+ { "cylinders", required_argument, NULL, 'C' },
+ { "heads", required_argument, NULL, 'H' },
+ { "sectors", required_argument, NULL, 'S' },
+ { "show-pt-geometry", no_argument, NULL, 'G' },
+ { "activate", optional_argument, NULL, 'A' },
+ { "DOS", no_argument, NULL, 'D' },
+ { "DOS-extended", no_argument, NULL, 'E' },
+ { "Linux", no_argument, NULL, 'L' },
+ { "re-read", no_argument, NULL, 'R' },
+ { "list-types", no_argument, NULL, 'T' },
+ { "unhide", optional_argument, NULL, 'U' },
+ { "no-reread", no_argument, NULL, OPT_NO_REREAD },
+ { "IBM", no_argument, NULL, OPT_LEAVE_LAST },
+ { "leave-last", no_argument, NULL, OPT_LEAVE_LAST },
/* dangerous flags - not all completely implemented */
- { "in-order", no_argument, NULL, OPT_IN_ORDER },
- { "not-in-order", no_argument, NULL, OPT_NOT_IN_ORDER },
- { "inside-outer", no_argument, NULL, OPT_INSIDE_OUTER },
- { "not-inside-outer", no_argument, NULL, OPT_NOT_INSIDE_OUTER },
- { "nested", no_argument, NULL, OPT_NESTED },
- { "chained", no_argument, NULL, OPT_CHAINED },
- { "onesector", no_argument, NULL, OPT_ONESECTOR },
- { NULL, 0, NULL, 0 }
+ { "in-order", no_argument, NULL, OPT_IN_ORDER },
+ { "not-in-order", no_argument, NULL, OPT_NOT_IN_ORDER },
+ { "inside-outer", no_argument, NULL, OPT_INSIDE_OUTER },
+ { "not-inside-outer", no_argument, NULL, OPT_NOT_INSIDE_OUTER },
+ { "nested", no_argument, NULL, OPT_NESTED },
+ { "chained", no_argument, NULL, OPT_CHAINED },
+ { "onesector", no_argument, NULL, OPT_ONESECTOR },
+ { NULL, 0, NULL, 0 }
};
static int is_ide_cdrom_or_tape(char *device)
@@ -2434,238 +2434,238 @@ unsigned long long total_size;
int
main(int argc, char **argv) {
- int c;
- char *dev;
- int opt_size = 0;
- int opt_out_geom = 0;
- int opt_out_pt_geom = 0;
- int opt_reread = 0;
- int activate = 0;
- int do_id = 0;
- int unhide = 0;
- char *activatearg = 0;
- char *unhidearg = 0;
-
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
- atexit(close_stdout);
-
- if (!strcmp(program_invocation_short_name, "activate"))
- activate = 1; /* equivalent to `sfdisk -A' */
-
- while ((c = getopt_long(argc, argv, "cdfghilnqsu:vx1A::C:DGH:I:LN:O:RS:TU::V",
- long_opts, NULL)) != -1) {
- switch (c) {
- case 'f':
- force = 1;
- break; /* does not imply quiet */
- case 'g':
- opt_out_geom = 1;
- break;
- case 'G':
- opt_out_pt_geom = 1;
- break;
- case 'i':
- increment = 1;
- break;
- case 'c':
- case 'c' + PRINT_ID:
- case 'c' + CHANGE_ID:
- do_id = c;
- break;
- case 'd':
- dump = 1; /* fall through */
- case 'l':
- opt_list = 1;
- break;
- case 'n':
- no_write = 1;
- break;
- case 'q':
- quiet = 1;
- break;
- case 's':
- opt_size = 1;
- break;
- case 'u':
- set_format(*optarg);
- break;
- case 'v':
- printf(UTIL_LINUX_VERSION);
- return EXIT_SUCCESS;
- case 'h':
- usage(stdout);
- case 'x':
- show_extended = 1;
- break;
- case 'A':
- activatearg = optarg;
- activate = 1;
- break;
- case 'C':
- U.cylinders = strtoul_or_err(optarg, _("invalid cylinders argument"));
- break;
- case 'D':
- DOS = 1;
- break;
- case 'E':
- DOS_extended = 1;
- break;
- case 'H':
- U.heads = strtoul_or_err(optarg, _("invalid heads argument"));
- break;
- case 'L':
- Linux = 1;
- break;
- case 'N':
- one_only = strtol_or_err(optarg, _("invalid number of partitions argument"));
- break;
- case 'I':
- restore_sector_file = optarg;
- break;
- case 'O':
- save_sector_file = optarg;
- break;
- case 'R':
- opt_reread = 1;
- break;
- case 'S':
- U.sectors = strtoul_or_err(optarg, _("invalid sectors argument"));
- break;
- case 'T':
- list_types();
- return EXIT_SUCCESS;
- case 'U':
- unhidearg = optarg;
- unhide = 1;
- break;
- case 'V':
- verify = 1;
- break;
- default:
- usage(stderr);
-
- /* dangerous flags */
- case OPT_IN_ORDER:
- partitions_in_order = 1;
- break;
- case OPT_NOT_IN_ORDER:
- partitions_in_order = 0;
- break;
- case OPT_INSIDE_OUTER:
- all_logicals_inside_outermost_extended = 1;
- break;
- case OPT_NOT_INSIDE_OUTER:
- all_logicals_inside_outermost_extended = 0;
- break;
- case OPT_NESTED:
- boxes = NESTED;
- break;
- case OPT_CHAINED:
- boxes = CHAINED;
- break;
- case OPT_ONESECTOR:
- boxes = ONESECTOR;
- break;
-
- /* more flags */
- case OPT_NO_REREAD:
- no_reread = 1;
- break;
- case OPT_LEAVE_LAST:
- leave_last = 1;
- break;
- }
- }
-
- if (optind == argc &&
- (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify)) {
- FILE *procf;
-
- /* try all known devices */
- total_size = 0;
-
- procf = fopen(_PATH_PROC_PARTITIONS, "r");
- if (!procf)
- fprintf(stderr, _("cannot open %s\n"), _PATH_PROC_PARTITIONS);
- else {
- while ((dev = nextproc(procf)) != NULL) {
- if (!is_ide_cdrom_or_tape(dev)) {
- if (opt_out_geom)
- do_geom(dev, 1);
- if (opt_out_pt_geom)
- do_pt_geom(dev, 1);
- if (opt_size)
- do_size(dev, 1);
- if (opt_list || verify)
- do_list(dev, 1);
+ int c;
+ char *dev;
+ int opt_size = 0;
+ int opt_out_geom = 0;
+ int opt_out_pt_geom = 0;
+ int opt_reread = 0;
+ int activate = 0;
+ int do_id = 0;
+ int unhide = 0;
+ char *activatearg = 0;
+ char *unhidearg = 0;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+ atexit(close_stdout);
+
+ if (!strcmp(program_invocation_short_name, "activate"))
+ activate = 1; /* equivalent to `sfdisk -A' */
+
+ while ((c = getopt_long(argc, argv, "cdfghilnqsu:vx1A::C:DGH:I:LN:O:RS:TU::V",
+ long_opts, NULL)) != -1) {
+ switch (c) {
+ case 'f':
+ force = 1;
+ break; /* does not imply quiet */
+ case 'g':
+ opt_out_geom = 1;
+ break;
+ case 'G':
+ opt_out_pt_geom = 1;
+ break;
+ case 'i':
+ increment = 1;
+ break;
+ case 'c':
+ case 'c' + PRINT_ID:
+ case 'c' + CHANGE_ID:
+ do_id = c;
+ break;
+ case 'd':
+ dump = 1; /* fall through */
+ case 'l':
+ opt_list = 1;
+ break;
+ case 'n':
+ no_write = 1;
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ case 's':
+ opt_size = 1;
+ break;
+ case 'u':
+ set_format(*optarg);
+ break;
+ case 'v':
+ printf(UTIL_LINUX_VERSION);
+ return EXIT_SUCCESS;
+ case 'h':
+ usage(stdout);
+ case 'x':
+ show_extended = 1;
+ break;
+ case 'A':
+ activatearg = optarg;
+ activate = 1;
+ break;
+ case 'C':
+ U.cylinders = strtoul_or_err(optarg, _("invalid cylinders argument"));
+ break;
+ case 'D':
+ DOS = 1;
+ break;
+ case 'E':
+ DOS_extended = 1;
+ break;
+ case 'H':
+ U.heads = strtoul_or_err(optarg, _("invalid heads argument"));
+ break;
+ case 'L':
+ Linux = 1;
+ break;
+ case 'N':
+ one_only = strtol_or_err(optarg, _("invalid number of partitions argument"));
+ break;
+ case 'I':
+ restore_sector_file = optarg;
+ break;
+ case 'O':
+ save_sector_file = optarg;
+ break;
+ case 'R':
+ opt_reread = 1;
+ break;
+ case 'S':
+ U.sectors = strtoul_or_err(optarg, _("invalid sectors argument"));
+ break;
+ case 'T':
+ list_types();
+ return EXIT_SUCCESS;
+ case 'U':
+ unhidearg = optarg;
+ unhide = 1;
+ break;
+ case 'V':
+ verify = 1;
+ break;
+ default:
+ usage(stderr);
+
+ /* dangerous flags */
+ case OPT_IN_ORDER:
+ partitions_in_order = 1;
+ break;
+ case OPT_NOT_IN_ORDER:
+ partitions_in_order = 0;
+ break;
+ case OPT_INSIDE_OUTER:
+ all_logicals_inside_outermost_extended = 1;
+ break;
+ case OPT_NOT_INSIDE_OUTER:
+ all_logicals_inside_outermost_extended = 0;
+ break;
+ case OPT_NESTED:
+ boxes = NESTED;
+ break;
+ case OPT_CHAINED:
+ boxes = CHAINED;
+ break;
+ case OPT_ONESECTOR:
+ boxes = ONESECTOR;
+ break;
+
+ /* more flags */
+ case OPT_NO_REREAD:
+ no_reread = 1;
+ break;
+ case OPT_LEAVE_LAST:
+ leave_last = 1;
+ break;
}
- free(dev);
- }
- fclose(procf);
}
- if (opt_size)
- printf(_("total: %llu blocks\n"), total_size);
+ if (optind == argc &&
+ (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify)) {
+ FILE *procf;
+
+ /* try all known devices */
+ total_size = 0;
+
+ procf = fopen(_PATH_PROC_PARTITIONS, "r");
+ if (!procf)
+ fprintf(stderr, _("cannot open %s\n"), _PATH_PROC_PARTITIONS);
+ else {
+ while ((dev = nextproc(procf)) != NULL) {
+ if (!is_ide_cdrom_or_tape(dev)) {
+ if (opt_out_geom)
+ do_geom(dev, 1);
+ if (opt_out_pt_geom)
+ do_pt_geom(dev, 1);
+ if (opt_size)
+ do_size(dev, 1);
+ if (opt_list || verify)
+ do_list(dev, 1);
+ }
+ free(dev);
+ }
+ fclose(procf);
+ }
- return exit_status;
- }
+ if (opt_size)
+ printf(_("total: %llu blocks\n"), total_size);
- if (optind == argc) {
- if (activate)
- activate_usage();
- else
- usage(stderr);
- }
-
- if (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify) {
- while (optind < argc) {
- if (opt_out_geom)
- do_geom(argv[optind], 0);
- if (opt_out_pt_geom)
- do_pt_geom(argv[optind], 0);
- if (opt_size)
- do_size(argv[optind], 0);
- if (opt_list || verify)
- do_list(argv[optind], 0);
- optind++;
+ return exit_status;
}
- return exit_status;
- }
- if (activate) {
- do_activate(argv + optind, argc - optind, activatearg);
- return exit_status;
- }
- if (unhide) {
- do_unhide(argv + optind, argc - optind, unhidearg);
- return exit_status;
- }
- if (do_id) {
- if ((do_id & PRINT_ID) != 0 && optind != argc - 2)
- errx(EXIT_FAILURE, _("usage: sfdisk --print-id device partition-number"));
- else if ((do_id & CHANGE_ID) != 0 && optind != argc - 3)
- errx(EXIT_FAILURE, _("usage: sfdisk --change-id device partition-number Id"));
- else if (optind != argc - 3 && optind != argc - 2)
- errx(EXIT_FAILURE, _("usage: sfdisk --id device partition-number [Id]"));
- do_change_id(argv[optind], argv[optind + 1],
- (optind == argc - 2) ? 0 : argv[optind + 2]);
- return exit_status;
- }
+ if (optind == argc) {
+ if (activate)
+ activate_usage();
+ else
+ usage(stderr);
+ }
+
+ if (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify) {
+ while (optind < argc) {
+ if (opt_out_geom)
+ do_geom(argv[optind], 0);
+ if (opt_out_pt_geom)
+ do_pt_geom(argv[optind], 0);
+ if (opt_size)
+ do_size(argv[optind], 0);
+ if (opt_list || verify)
+ do_list(argv[optind], 0);
+ optind++;
+ }
+ return exit_status;
+ }
- if (optind != argc - 1)
- errx(EXIT_FAILURE, _("can specify only one device (except with -l or -s)"));
- dev = argv[optind];
+ if (activate) {
+ do_activate(argv + optind, argc - optind, activatearg);
+ return exit_status;
+ }
+ if (unhide) {
+ do_unhide(argv + optind, argc - optind, unhidearg);
+ return exit_status;
+ }
+ if (do_id) {
+ if ((do_id & PRINT_ID) != 0 && optind != argc - 2)
+ errx(EXIT_FAILURE, _("usage: sfdisk --print-id device partition-number"));
+ else if ((do_id & CHANGE_ID) != 0 && optind != argc - 3)
+ errx(EXIT_FAILURE, _("usage: sfdisk --change-id device partition-number Id"));
+ else if (optind != argc - 3 && optind != argc - 2)
+ errx(EXIT_FAILURE, _("usage: sfdisk --id device partition-number [Id]"));
+ do_change_id(argv[optind], argv[optind + 1],
+ (optind == argc - 2) ? 0 : argv[optind + 2]);
+ return exit_status;
+ }
- if (opt_reread)
- do_reread(dev);
- else if (restore_sector_file)
- restore_sectors(dev);
- else
- do_fdisk(dev);
+ if (optind != argc - 1)
+ errx(EXIT_FAILURE, _("can specify only one device (except with -l or -s)"));
+ dev = argv[optind];
- return exit_status;
+ if (opt_reread)
+ do_reread(dev);
+ else if (restore_sector_file)
+ restore_sectors(dev);
+ else
+ do_fdisk(dev);
+
+ return exit_status;
}
/*
@@ -2674,127 +2674,127 @@ main(int argc, char **argv) {
static int
my_open(char *dev, int rw, int silent) {
- int fd, mode;
+ int fd, mode;
- mode = (rw ? O_RDWR : O_RDONLY);
- fd = open(dev, mode);
- if (fd < 0 && !silent) {
- if (rw)
- err(EXIT_FAILURE, _("cannot open %s read-write"), dev);
- else
- err(EXIT_FAILURE, _("cannot open %s for reading"), dev);
- }
- return fd;
+ mode = (rw ? O_RDWR : O_RDONLY);
+ fd = open(dev, mode);
+ if (fd < 0 && !silent) {
+ if (rw)
+ err(EXIT_FAILURE, _("cannot open %s read-write"), dev);
+ else
+ err(EXIT_FAILURE, _("cannot open %s for reading"), dev);
+ }
+ return fd;
}
static void
do_list(char *dev, int silent) {
- int fd;
- struct disk_desc *z;
+ int fd;
+ struct disk_desc *z;
- fd = my_open(dev, 0, silent);
- if (fd < 0)
- return;
+ fd = my_open(dev, 0, silent);
+ if (fd < 0)
+ return;
- z = &oldp;
+ z = &oldp;
- free_sectors();
- get_cylindersize(dev, fd, dump ? 1 : opt_list ? 0 : 1);
- get_partitions(dev, fd, z);
+ free_sectors();
+ get_cylindersize(dev, fd, dump ? 1 : opt_list ? 0 : 1);
+ get_partitions(dev, fd, z);
- if (opt_list)
- out_partitions(dev, z);
+ if (opt_list)
+ out_partitions(dev, z);
- if (verify) {
- if (partitions_ok(fd, z))
- printf(_("%s: OK"), dev);
- else
- exit_status = 1;
- }
+ if (verify) {
+ if (partitions_ok(fd, z))
+ printf(_("%s: OK"), dev);
+ else
+ exit_status = 1;
+ }
- close(fd);
+ close(fd);
}
static void
do_geom(char *dev, int silent) {
- int fd;
- struct geometry R;
+ int fd;
+ struct geometry R;
- fd = my_open(dev, 0, silent);
- if (fd < 0)
- return;
+ fd = my_open(dev, 0, silent);
+ if (fd < 0)
+ return;
- R = get_geometry(dev, fd, silent);
- if (R.cylinders)
- printf(_("%s: %ld cylinders, %ld heads, %ld sectors/track\n"),
- dev, R.cylinders, R.heads, R.sectors);
+ R = get_geometry(dev, fd, silent);
+ if (R.cylinders)
+ printf(_("%s: %ld cylinders, %ld heads, %ld sectors/track\n"),
+ dev, R.cylinders, R.heads, R.sectors);
- close(fd);
+ close(fd);
}
static void
do_pt_geom(char *dev, int silent) {
- int fd;
- struct disk_desc *z;
- struct geometry R;
+ int fd;
+ struct disk_desc *z;
+ struct geometry R;
- fd = my_open(dev, 0, silent);
- if (fd < 0)
- return;
+ fd = my_open(dev, 0, silent);
+ if (fd < 0)
+ return;
- z = &oldp;
+ z = &oldp;
- free_sectors();
- get_cylindersize(dev, fd, 1);
- get_partitions(dev, fd, z);
+ free_sectors();
+ get_cylindersize(dev, fd, 1);
+ get_partitions(dev, fd, z);
- R = B;
+ R = B;
- if (z->partno != 0 && get_fdisk_geometry(z)) {
- R.heads = F.heads;
- R.sectors = F.sectors;
- R.cylindersize = R.heads * R.sectors;
- R.cylinders = (R.cylindersize == 0) ? 0 : R.total_size / R.cylindersize;
- }
+ if (z->partno != 0 && get_fdisk_geometry(z)) {
+ R.heads = F.heads;
+ R.sectors = F.sectors;
+ R.cylindersize = R.heads * R.sectors;
+ R.cylinders = (R.cylindersize == 0) ? 0 : R.total_size / R.cylindersize;
+ }
- if (R.cylinders)
- printf(_("%s: %ld cylinders, %ld heads, %ld sectors/track\n"),
- dev, R.cylinders, R.heads, R.sectors);
+ if (R.cylinders)
+ printf(_("%s: %ld cylinders, %ld heads, %ld sectors/track\n"),
+ dev, R.cylinders, R.heads, R.sectors);
- close(fd);
+ close(fd);
}
/* for compatibility with earlier fdisk: provide option -s */
static void
do_size(char *dev, int silent) {
- int fd;
- unsigned long long size;
+ int fd;
+ unsigned long long size;
- fd = my_open(dev, 0, silent);
- if (fd < 0)
- return;
+ fd = my_open(dev, 0, silent);
+ if (fd < 0)
+ return;
- if (blkdev_get_sectors(fd, &size) == -1) {
- if (!silent)
- err(EXIT_FAILURE, _("Cannot get size of %s"), dev);
- goto done;
- }
+ if (blkdev_get_sectors(fd, &size) == -1) {
+ if (!silent)
+ err(EXIT_FAILURE, _("Cannot get size of %s"), dev);
+ goto done;
+ }
- size /= 2; /* convert sectors to blocks */
+ size /= 2; /* convert sectors to blocks */
- /* a CDROM drive without mounted CD yields MAXINT */
- if (silent && size == ((1 << 30) - 1))
- goto done;
+ /* a CDROM drive without mounted CD yields MAXINT */
+ if (silent && size == ((1 << 30) - 1))
+ goto done;
- if (silent)
- printf("%s: %9llu\n", dev, size);
- else
- printf("%llu\n", size);
+ if (silent)
+ printf("%s: %9llu\n", dev, size);
+ else
+ printf("%llu\n", size);
- total_size += size;
+ total_size += size;
done:
- close(fd);
+ close(fd);
}
/*
@@ -2823,90 +2823,90 @@ done:
*/
static void
set_active(struct disk_desc *z, char *pnam) {
- int pno;
+ int pno;
- pno = asc_to_index(pnam, z);
- if (z->partitions[pno].ptype == DOS_TYPE)
- z->partitions[pno].p.bootable = 0x80;
+ pno = asc_to_index(pnam, z);
+ if (z->partitions[pno].ptype == DOS_TYPE)
+ z->partitions[pno].p.bootable = 0x80;
}
static void
do_activate(char **av, int ac, char *arg) {
- char *dev = av[0];
- int fd;
- int rw, i, pno, lpno;
- struct disk_desc *z;
-
- z = &oldp;
-
- rw = (!no_write && (arg || ac > 1));
- fd = my_open(dev, rw, 0);
-
- free_sectors();
- get_cylindersize(dev, fd, 1);
- get_partitions(dev, fd, z);
-
- if (!arg && ac == 1) {
- /* list active partitions */
- for (pno = 0; pno < z->partno; pno++) {
- if (z->partitions[pno].p.bootable) {
- lpno = index_to_linux(pno, z);
- if (pno == linux_to_index(lpno, z))
- printf("%s\n", partname(dev, lpno, 0));
+ char *dev = av[0];
+ int fd;
+ int rw, i, pno, lpno;
+ struct disk_desc *z;
+
+ z = &oldp;
+
+ rw = (!no_write && (arg || ac > 1));
+ fd = my_open(dev, rw, 0);
+
+ free_sectors();
+ get_cylindersize(dev, fd, 1);
+ get_partitions(dev, fd, z);
+
+ if (!arg && ac == 1) {
+ /* list active partitions */
+ for (pno = 0; pno < z->partno; pno++) {
+ if (z->partitions[pno].p.bootable) {
+ lpno = index_to_linux(pno, z);
+ if (pno == linux_to_index(lpno, z))
+ printf("%s\n", partname(dev, lpno, 0));
+ else
+ printf("%s#%d\n", dev, pno);
+ if (z->partitions[pno].p.bootable != 0x80)
+ warnx(_("bad active byte: 0x%x instead of 0x80"),
+ z->partitions[pno].p.bootable);
+ }
+ }
+ } else {
+ /* clear `active byte' everywhere */
+ for (pno = 0; pno < z->partno; pno++)
+ if (z->partitions[pno].ptype == DOS_TYPE)
+ z->partitions[pno].p.bootable = 0;
+
+ /* then set where desired */
+ if (ac == 1)
+ set_active(z, arg);
else
- printf("%s#%d\n", dev, pno);
- if (z->partitions[pno].p.bootable != 0x80)
- warnx(_("bad active byte: 0x%x instead of 0x80"),
- z->partitions[pno].p.bootable);
- }
- }
- } else {
- /* clear `active byte' everywhere */
- for (pno = 0; pno < z->partno; pno++)
- if (z->partitions[pno].ptype == DOS_TYPE)
- z->partitions[pno].p.bootable = 0;
-
- /* then set where desired */
- if (ac == 1)
- set_active(z, arg);
- else
- for (i = 1; i < ac; i++)
- set_active(z, av[i]);
+ for (i = 1; i < ac; i++)
+ set_active(z, av[i]);
- /* then write to disk */
- if (write_partitions(dev, fd, z))
- warnx(_("Done"));
- else
- exit_status = 1;
- }
- i = 0;
- for (pno = 0; pno < z->partno && pno < 4; pno++)
- if (z->partitions[pno].p.bootable)
- i++;
- if (i != 1)
- warnx(_("You have %d active primary partitions. This does not matter for LILO,\n"
- "but the DOS MBR will only boot a disk with 1 active partition."),
- i);
-
- if (close_fd(fd) != 0) {
- warnx(_("write failed"));
- exit_status = 1;
- }
+ /* then write to disk */
+ if (write_partitions(dev, fd, z))
+ warnx(_("Done"));
+ else
+ exit_status = 1;
+ }
+ i = 0;
+ for (pno = 0; pno < z->partno && pno < 4; pno++)
+ if (z->partitions[pno].p.bootable)
+ i++;
+ if (i != 1)
+ warnx(_("You have %d active primary partitions. This does not matter for LILO,\n"
+ "but the DOS MBR will only boot a disk with 1 active partition."),
+ i);
+
+ if (close_fd(fd) != 0) {
+ warnx(_("write failed"));
+ exit_status = 1;
+ }
}
static void
set_unhidden(struct disk_desc *z, char *pnam) {
- int pno;
- unsigned char id;
-
- pno = asc_to_index(pnam, z);
- id = z->partitions[pno].p.sys_type;
- if (id == 0x11 || id == 0x14 || id == 0x16 || id == 0x17 ||
- id == 0x17 || id == 0x1b || id == 0x1c || id == 0x1e)
- id -= 0x10;
- else
- errx(EXIT_FAILURE, _("partition %s has id %x and is not hidden"), pnam, id);
- z->partitions[pno].p.sys_type = id;
+ int pno;
+ unsigned char id;
+
+ pno = asc_to_index(pnam, z);
+ id = z->partitions[pno].p.sys_type;
+ if (id == 0x11 || id == 0x14 || id == 0x16 || id == 0x17 ||
+ id == 0x17 || id == 0x1b || id == 0x1c || id == 0x1e)
+ id -= 0x10;
+ else
+ errx(EXIT_FAILURE, _("partition %s has id %x and is not hidden"), pnam, id);
+ z->partitions[pno].p.sys_type = id;
}
/*
@@ -2914,86 +2914,86 @@ set_unhidden(struct disk_desc *z, char *pnam) {
*/
static void
do_unhide(char **av, int ac, char *arg) {
- char *dev = av[0];
- int fd, rw, i;
- struct disk_desc *z;
+ char *dev = av[0];
+ int fd, rw, i;
+ struct disk_desc *z;
- z = &oldp;
+ z = &oldp;
- rw = !no_write;
- fd = my_open(dev, rw, 0);
+ rw = !no_write;
+ fd = my_open(dev, rw, 0);
- free_sectors();
- get_cylindersize(dev, fd, 1);
- get_partitions(dev, fd, z);
+ free_sectors();
+ get_cylindersize(dev, fd, 1);
+ get_partitions(dev, fd, z);
- /* unhide where desired */
- if (ac == 1)
- set_unhidden(z, arg);
- else
- for (i = 1; i < ac; i++)
- set_unhidden(z, av[i]);
+ /* unhide where desired */
+ if (ac == 1)
+ set_unhidden(z, arg);
+ else
+ for (i = 1; i < ac; i++)
+ set_unhidden(z, av[i]);
- /* then write to disk */
- if (write_partitions(dev, fd, z))
- warn(_("Done"));
- else
- exit_status = 1;
+ /* then write to disk */
+ if (write_partitions(dev, fd, z))
+ warn(_("Done"));
+ else
+ exit_status = 1;
- if (close_fd(fd) != 0) {
- warn(_("write failed"));
- exit_status = 1;
- }
+ if (close_fd(fd) != 0) {
+ warn(_("write failed"));
+ exit_status = 1;
+ }
}
static void
do_change_id(char *dev, char *pnam, char *id) {
- int fd, rw, pno;
- struct disk_desc *z;
- unsigned long i;
-
- z = &oldp;
-
- rw = !no_write;
- fd = my_open(dev, rw, 0);
-
- free_sectors();
- get_cylindersize(dev, fd, 1);
- get_partitions(dev, fd, z);
-
- pno = asc_to_index(pnam, z);
- if (id == 0) {
- printf("%x\n", z->partitions[pno].p.sys_type);
- goto done;
- }
- i = strtoul(id, NULL, 16);
- if (i > 255)
- errx(EXIT_FAILURE, _("Bad Id %lx"), i);
- z->partitions[pno].p.sys_type = i;
-
- if (write_partitions(dev, fd, z))
- warnx(_("Done"));
- else
- exit_status = 1;
+ int fd, rw, pno;
+ struct disk_desc *z;
+ unsigned long i;
+
+ z = &oldp;
+
+ rw = !no_write;
+ fd = my_open(dev, rw, 0);
+
+ free_sectors();
+ get_cylindersize(dev, fd, 1);
+ get_partitions(dev, fd, z);
+
+ pno = asc_to_index(pnam, z);
+ if (id == 0) {
+ printf("%x\n", z->partitions[pno].p.sys_type);
+ goto done;
+ }
+ i = strtoul(id, NULL, 16);
+ if (i > 255)
+ errx(EXIT_FAILURE, _("Bad Id %lx"), i);
+ z->partitions[pno].p.sys_type = i;
+
+ if (write_partitions(dev, fd, z))
+ warnx(_("Done"));
+ else
+ exit_status = 1;
done:
- if (close_fd(fd) != 0) {
- warnx(_("write failed"));
- exit_status = 1;
- }
+ if (close_fd(fd) != 0) {
+ warnx(_("write failed"));
+ exit_status = 1;
+ }
}
static void
do_reread(char *dev) {
- int fd;
+ int fd;
- fd = my_open(dev, 0, 0);
- if (reread_ioctl(fd)) {
- warnx(_("This disk is currently in use."));
- exit(EXIT_FAILURE);
- }
+ fd = my_open(dev, 0, 0);
+ if (reread_ioctl(fd)) {
+ warnx(_("This disk is currently in use."));
+ exit(EXIT_FAILURE);
+ }
- close(fd);
+ close(fd);
}
/*
@@ -3002,97 +3002,97 @@ do_reread(char *dev) {
static void
do_fdisk(char *dev) {
- int fd;
- char answer[32];
- struct stat statbuf;
- int interactive = isatty(0);
- struct disk_desc *z;
-
- if (stat(dev, &statbuf) < 0)
- err(EXIT_FAILURE, _("Fatal error: cannot find %s"), dev);
- if (!S_ISBLK(statbuf.st_mode)) {
- warnx(_("Warning: %s is not a block device"), dev);
- no_reread = 1;
- }
- fd = my_open(dev, !no_write, 0);
-
- if (!no_write && !no_reread) {
- warnx(_("Checking that no-one is using this disk right now ..."));
- if (reread_ioctl(fd)) {
- warnx(_("\nThis disk is currently in use - repartitioning is probably a bad idea.\n"
- "Umount all file systems, and swapoff all swap partitions on this disk.\n"
- "Use the --no-reread flag to suppress this check."));
- if (!force)
- errx(EXIT_FAILURE, _("Use the --force flag to overrule all checks."));
- } else
- warnx(_("OK"));
- }
+ int fd;
+ char answer[32];
+ struct stat statbuf;
+ int interactive = isatty(0);
+ struct disk_desc *z;
+
+ if (stat(dev, &statbuf) < 0)
+ err(EXIT_FAILURE, _("Fatal error: cannot find %s"), dev);
+ if (!S_ISBLK(statbuf.st_mode)) {
+ warnx(_("Warning: %s is not a block device"), dev);
+ no_reread = 1;
+ }
+ fd = my_open(dev, !no_write, 0);
+
+ if (!no_write && !no_reread) {
+ warnx(_("Checking that no-one is using this disk right now ..."));
+ if (reread_ioctl(fd)) {
+ warnx(_("\nThis disk is currently in use - repartitioning is probably a bad idea.\n"
+ "Umount all file systems, and swapoff all swap partitions on this disk.\n"
+ "Use the --no-reread flag to suppress this check."));
+ if (!force)
+ errx(EXIT_FAILURE, _("Use the --force flag to overrule all checks."));
+ } else
+ warnx(_("OK"));
+ }
- z = &oldp;
+ z = &oldp;
- free_sectors();
- get_cylindersize(dev, fd, 0);
- get_partitions(dev, fd, z);
+ free_sectors();
+ get_cylindersize(dev, fd, 0);
+ get_partitions(dev, fd, z);
- printf(_("Old situation:\n"));
- out_partitions(dev, z);
+ printf(_("Old situation:\n"));
+ out_partitions(dev, z);
- if (one_only && (one_only_pno = linux_to_index(one_only, z)) < 0)
- errx(EXIT_FAILURE, _("Partition %d does not exist, cannot change it"), one_only);
+ if (one_only && (one_only_pno = linux_to_index(one_only, z)) < 0)
+ errx(EXIT_FAILURE, _("Partition %d does not exist, cannot change it"), one_only);
- z = &newp;
+ z = &newp;
- while (1) {
+ while (1) {
- read_input(dev, interactive, z);
+ read_input(dev, interactive, z);
- printf(_("New situation:\n"));
- out_partitions(dev, z);
+ printf(_("New situation:\n"));
+ out_partitions(dev, z);
- if (!partitions_ok(fd, z) && !force) {
- if (!interactive)
- errx(EXIT_FAILURE, _("I don't like these partitions - nothing changed.\n"
- "(If you really want this, use the --force option.)"));
- else
- warnx(_("I don't like this - probably you should answer No"));
+ if (!partitions_ok(fd, z) && !force) {
+ if (!interactive)
+ errx(EXIT_FAILURE, _("I don't like these partitions - nothing changed.\n"
+ "(If you really want this, use the --force option.)"));
+ else
+ warnx(_("I don't like this - probably you should answer No"));
+ }
+ if (interactive) {
+ ask:
+ if (no_write)
+ /* TRANSLATORS: sfdisk uses rpmatch which means the answers y and n
+ * should be translated, but that is not the case with q answer. */
+ printf(_("Are you satisfied with this? [ynq] "));
+ else
+ printf(_("Do you want to write this to disk? [ynq] "));
+ ignore_result( fgets(answer, sizeof(answer), stdin) );
+ if (answer[0] == 'q' || answer[0] == 'Q') {
+ errx(EXIT_FAILURE, _("Quitting - nothing changed"));
+ } else if (rpmatch(answer) == 0) {
+ continue;
+ } else if (rpmatch(answer) == 1) {
+ break;
+ } else {
+ printf(_("Please answer one of y,n,q\n"));
+ goto ask;
+ }
+ } else
+ break;
}
- if (interactive) {
- ask:
- if (no_write)
- /* TRANSLATORS: sfdisk uses rpmatch which means the answers y and n
- * should be translated, but that is not the case with q answer. */
- printf(_("Are you satisfied with this? [ynq] "));
- else
- printf(_("Do you want to write this to disk? [ynq] "));
- ignore_result( fgets(answer, sizeof(answer), stdin) );
- if (answer[0] == 'q' || answer[0] == 'Q') {
- errx(EXIT_FAILURE, _("Quitting - nothing changed"));
- } else if (rpmatch(answer) == 0) {
- continue;
- } else if (rpmatch(answer) == 1) {
- break;
- } else {
- printf(_("Please answer one of y,n,q\n"));
- goto ask;
- }
- } else
- break;
- }
- if (write_partitions(dev, fd, z))
- printf(_("Successfully wrote the new partition table\n\n"));
- else
- exit_status = 1;
+ if (write_partitions(dev, fd, z))
+ printf(_("Successfully wrote the new partition table\n\n"));
+ else
+ exit_status = 1;
- if (!reread_disk_partition(dev, fd)) { /* close fd on success */
- close(fd);
- exit_status = 1;
- }
- warnx(_("If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)\n"
- "to zero the first 512 bytes: dd if=/dev/zero of=/dev/foo7 bs=512 count=1\n"
- "(See fdisk(8).)"));
+ if (!reread_disk_partition(dev, fd)) { /* close fd on success */
+ close(fd);
+ exit_status = 1;
+ }
+ warnx(_("If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)\n"
+ "to zero the first 512 bytes: dd if=/dev/zero of=/dev/foo7 bs=512 count=1\n"
+ "(See fdisk(8).)"));
- sync(); /* superstition */
+ sync(); /* superstition */
}
@@ -3121,8 +3121,8 @@ static char *partname(char *dev, int pno, int lth)
/* udev names partitions by appending -partN
e.g. ata-SAMSUNG_SV8004H_0357J1FT712448-part1 */
if ((strncmp(dev, _PATH_DEV_BYID, strlen(_PATH_DEV_BYID)) == 0) ||
- strncmp(dev, _PATH_DEV_BYPATH, strlen(_PATH_DEV_BYPATH)) == 0) {
- p = "-part";
+ strncmp(dev, _PATH_DEV_BYPATH, strlen(_PATH_DEV_BYPATH)) == 0) {
+ p = "-part";
}
wp = strlen(p);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 06/13] sfdisk: remove declaraion of 'partname()'
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
` (4 preceding siblings ...)
2014-07-22 23:44 ` [PATCH 05/13] sfdisk: fix indentation Davidlohr Bueso
@ 2014-07-22 23:44 ` Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 07/13] sfdisk: remove 'exit_status' global variable Davidlohr Bueso
` (8 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
---
disk-utils/sfdisk.c | 84 +++++++++++++++++++++++++----------------------------
1 file changed, 40 insertions(+), 44 deletions(-)
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index af90c54..96f4d82 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -62,8 +62,6 @@ static struct systypes i386_sys_types[] = {
#include "pt-mbr-partnames.h"
};
-static char *partname(char *dev, int pno, int lth);
-
/*
* Table of contents:
* A. About seeking
@@ -95,6 +93,46 @@ char *save_sector_file = NULL;
char *restore_sector_file = NULL;
/*
+ * return partition name - uses static storage unless buf is supplied
+ */
+static char *partname(char *dev, int pno, int lth)
+{
+ static char bufp[PATH_MAX];
+ char *p;
+ int w, wp;
+
+ w = strlen(dev);
+ p = "";
+
+ if (isdigit(dev[w-1]))
+ p = "p";
+
+ /* devfs kludge - note: fdisk partition names are not supposed
+ to equal kernel names, so there is no reason to do this */
+ if (strcmp (dev + w - 4, "disc") == 0) {
+ w -= 4;
+ p = "part";
+ }
+
+ /* udev names partitions by appending -partN
+ e.g. ata-SAMSUNG_SV8004H_0357J1FT712448-part1 */
+ if ((strncmp(dev, _PATH_DEV_BYID, strlen(_PATH_DEV_BYID)) == 0) ||
+ strncmp(dev, _PATH_DEV_BYPATH, strlen(_PATH_DEV_BYPATH)) == 0) {
+ p = "-part";
+ }
+
+ wp = strlen(p);
+
+ if (lth) {
+ snprintf(bufp, sizeof(bufp), "%*.*s%s%-2u",
+ lth-wp-2, w, dev, p, pno);
+ } else {
+ snprintf(bufp, sizeof(bufp), "%.*s%s%-2u", w, dev, p, pno);
+ }
+ return bufp;
+}
+
+/*
* A. About seeking
*/
@@ -3094,45 +3132,3 @@ do_fdisk(char *dev) {
sync(); /* superstition */
}
-
-
-/*
- * return partition name - uses static storage unless buf is supplied
- */
-static char *partname(char *dev, int pno, int lth)
-{
- static char bufp[PATH_MAX];
- char *p;
- int w, wp;
-
- w = strlen(dev);
- p = "";
-
- if (isdigit(dev[w-1]))
- p = "p";
-
- /* devfs kludge - note: fdisk partition names are not supposed
- to equal kernel names, so there is no reason to do this */
- if (strcmp (dev + w - 4, "disc") == 0) {
- w -= 4;
- p = "part";
- }
-
- /* udev names partitions by appending -partN
- e.g. ata-SAMSUNG_SV8004H_0357J1FT712448-part1 */
- if ((strncmp(dev, _PATH_DEV_BYID, strlen(_PATH_DEV_BYID)) == 0) ||
- strncmp(dev, _PATH_DEV_BYPATH, strlen(_PATH_DEV_BYPATH)) == 0) {
- p = "-part";
- }
-
- wp = strlen(p);
-
- if (lth) {
- snprintf(bufp, sizeof(bufp), "%*.*s%s%-2u",
- lth-wp-2, w, dev, p, pno);
- } else {
- snprintf(bufp, sizeof(bufp), "%.*s%s%-2u", w, dev, p, pno);
- }
- return bufp;
-}
-
--
1.8.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 07/13] sfdisk: remove 'exit_status' global variable
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
` (5 preceding siblings ...)
2014-07-22 23:44 ` [PATCH 06/13] sfdisk: remove declaraion of 'partname()' Davidlohr Bueso
@ 2014-07-22 23:44 ` Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 08/13] sfdisk: move main function at the end of the file Davidlohr Bueso
` (7 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
This variable determines the overall exit code sfdisk(8) uses, from
main(). Simplify this atrocity by returning the value from the callers
that modify it to 1, including: do_list, do_activate, do_unhide,
do_change_id and do_fork.
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
---
disk-utils/sfdisk.c | 97 +++++++++++++++++++++++++++--------------------------
1 file changed, 49 insertions(+), 48 deletions(-)
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index 96f4d82..7e0b081 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -74,7 +74,6 @@ static struct systypes i386_sys_types[] = {
* H. Listing the current situation
* I. Writing the new situation
*/
-int exit_status = 0;
int force = 0; /* 1: do what I say, even if it is stupid ... */
int quiet = 0; /* 1: suppress all warnings */
@@ -2458,21 +2457,21 @@ static char *nextproc(FILE *f)
return NULL;
}
-static void do_list(char *dev, int silent);
+static int do_list(char *dev, int silent);
static void do_size(char *dev, int silent);
static void do_geom(char *dev, int silent);
static void do_pt_geom(char *dev, int silent);
-static void do_fdisk(char *dev);
+static int do_fdisk(char *dev);
static void do_reread(char *dev);
-static void do_change_id(char *dev, char *part, char *id);
-static void do_unhide(char **av, int ac, char *arg);
-static void do_activate(char **av, int ac, char *arg);
+static int do_change_id(char *dev, char *part, char *id);
+static int do_unhide(char **av, int ac, char *arg);
+static int do_activate(char **av, int ac, char *arg);
unsigned long long total_size;
-int
-main(int argc, char **argv) {
- int c;
+int main(int argc, char **argv)
+{
+ int c, ret = 0;
char *dev;
int opt_size = 0;
int opt_out_geom = 0;
@@ -2637,7 +2636,7 @@ main(int argc, char **argv) {
if (opt_size)
do_size(dev, 1);
if (opt_list || verify)
- do_list(dev, 1);
+ ret = do_list(dev, 1);
}
free(dev);
}
@@ -2647,7 +2646,7 @@ main(int argc, char **argv) {
if (opt_size)
printf(_("total: %llu blocks\n"), total_size);
- return exit_status;
+ goto done;
}
if (optind == argc) {
@@ -2666,19 +2665,17 @@ main(int argc, char **argv) {
if (opt_size)
do_size(argv[optind], 0);
if (opt_list || verify)
- do_list(argv[optind], 0);
+ ret = do_list(argv[optind], 0);
optind++;
}
- return exit_status;
+ goto done;
}
if (activate) {
- do_activate(argv + optind, argc - optind, activatearg);
- return exit_status;
+ return do_activate(argv + optind, argc - optind, activatearg);
}
if (unhide) {
- do_unhide(argv + optind, argc - optind, unhidearg);
- return exit_status;
+ return do_unhide(argv + optind, argc - optind, unhidearg);
}
if (do_id) {
if ((do_id & PRINT_ID) != 0 && optind != argc - 2)
@@ -2687,9 +2684,8 @@ main(int argc, char **argv) {
errx(EXIT_FAILURE, _("usage: sfdisk --change-id device partition-number Id"));
else if (optind != argc - 3 && optind != argc - 2)
errx(EXIT_FAILURE, _("usage: sfdisk --id device partition-number [Id]"));
- do_change_id(argv[optind], argv[optind + 1],
- (optind == argc - 2) ? 0 : argv[optind + 2]);
- return exit_status;
+ return do_change_id(argv[optind], argv[optind + 1],
+ (optind == argc - 2) ? 0 : argv[optind + 2]);
}
if (optind != argc - 1)
@@ -2701,9 +2697,9 @@ main(int argc, char **argv) {
else if (restore_sector_file)
restore_sectors(dev);
else
- do_fdisk(dev);
-
- return exit_status;
+ ret = do_fdisk(dev);
+done:
+ return ret;
}
/*
@@ -2725,14 +2721,14 @@ my_open(char *dev, int rw, int silent) {
return fd;
}
-static void
-do_list(char *dev, int silent) {
- int fd;
+static int do_list(char *dev, int silent)
+{
+ int fd, ret = 0;
struct disk_desc *z;
fd = my_open(dev, 0, silent);
if (fd < 0)
- return;
+ return ret;
z = &oldp;
@@ -2747,10 +2743,11 @@ do_list(char *dev, int silent) {
if (partitions_ok(fd, z))
printf(_("%s: OK"), dev);
else
- exit_status = 1;
+ ret = 1;
}
close(fd);
+ return ret;
}
static void
@@ -2868,10 +2865,10 @@ set_active(struct disk_desc *z, char *pnam) {
z->partitions[pno].p.bootable = 0x80;
}
-static void
-do_activate(char **av, int ac, char *arg) {
+static int do_activate(char **av, int ac, char *arg)
+{
char *dev = av[0];
- int fd;
+ int fd, ret = 0;
int rw, i, pno, lpno;
struct disk_desc *z;
@@ -2915,7 +2912,7 @@ do_activate(char **av, int ac, char *arg) {
if (write_partitions(dev, fd, z))
warnx(_("Done"));
else
- exit_status = 1;
+ ret = 1;
}
i = 0;
for (pno = 0; pno < z->partno && pno < 4; pno++)
@@ -2928,8 +2925,9 @@ do_activate(char **av, int ac, char *arg) {
if (close_fd(fd) != 0) {
warnx(_("write failed"));
- exit_status = 1;
+ ret = 1;
}
+ return ret;
}
static void
@@ -2950,10 +2948,10 @@ set_unhidden(struct disk_desc *z, char *pnam) {
/*
* maybe remove and make part of --change-id
*/
-static void
-do_unhide(char **av, int ac, char *arg) {
+static int do_unhide(char **av, int ac, char *arg)
+{
char *dev = av[0];
- int fd, rw, i;
+ int fd, rw, i, ret = 0;
struct disk_desc *z;
z = &oldp;
@@ -2976,17 +2974,18 @@ do_unhide(char **av, int ac, char *arg) {
if (write_partitions(dev, fd, z))
warn(_("Done"));
else
- exit_status = 1;
+ ret = 1;
if (close_fd(fd) != 0) {
warn(_("write failed"));
- exit_status = 1;
+ ret = 1;
}
+ return ret;
}
-static void
-do_change_id(char *dev, char *pnam, char *id) {
- int fd, rw, pno;
+static int do_change_id(char *dev, char *pnam, char *id)
+{
+ int fd, rw, pno, ret = 0;
struct disk_desc *z;
unsigned long i;
@@ -3012,13 +3011,14 @@ do_change_id(char *dev, char *pnam, char *id) {
if (write_partitions(dev, fd, z))
warnx(_("Done"));
else
- exit_status = 1;
+ ret = 1;
done:
if (close_fd(fd) != 0) {
warnx(_("write failed"));
- exit_status = 1;
+ ret = 1;
}
+ return ret;
}
static void
@@ -3038,9 +3038,9 @@ do_reread(char *dev) {
* I. Writing the new situation
*/
-static void
-do_fdisk(char *dev) {
- int fd;
+static int do_fdisk(char *dev)
+{
+ int fd, ret = 0;
char answer[32];
struct stat statbuf;
int interactive = isatty(0);
@@ -3120,15 +3120,16 @@ do_fdisk(char *dev) {
if (write_partitions(dev, fd, z))
printf(_("Successfully wrote the new partition table\n\n"));
else
- exit_status = 1;
+ ret = 1;
if (!reread_disk_partition(dev, fd)) { /* close fd on success */
close(fd);
- exit_status = 1;
+ ret = 1;
}
warnx(_("If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)\n"
"to zero the first 512 bytes: dd if=/dev/zero of=/dev/foo7 bs=512 count=1\n"
"(See fdisk(8).)"));
sync(); /* superstition */
+ return ret;
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 08/13] sfdisk: move main function at the end of the file
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
` (6 preceding siblings ...)
2014-07-22 23:44 ` [PATCH 07/13] sfdisk: remove 'exit_status' global variable Davidlohr Bueso
@ 2014-07-22 23:44 ` Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 09/13] fdisk: remove bugus space after header includes Davidlohr Bueso
` (6 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
By doing so, we can remove do_*() function prototypes.
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
---
disk-utils/sfdisk.c | 476 +++++++++++++++++++++++++---------------------------
1 file changed, 233 insertions(+), 243 deletions(-)
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index 7e0b081..a097c6e 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -2457,251 +2457,8 @@ static char *nextproc(FILE *f)
return NULL;
}
-static int do_list(char *dev, int silent);
-static void do_size(char *dev, int silent);
-static void do_geom(char *dev, int silent);
-static void do_pt_geom(char *dev, int silent);
-static int do_fdisk(char *dev);
-static void do_reread(char *dev);
-static int do_change_id(char *dev, char *part, char *id);
-static int do_unhide(char **av, int ac, char *arg);
-static int do_activate(char **av, int ac, char *arg);
-
unsigned long long total_size;
-int main(int argc, char **argv)
-{
- int c, ret = 0;
- char *dev;
- int opt_size = 0;
- int opt_out_geom = 0;
- int opt_out_pt_geom = 0;
- int opt_reread = 0;
- int activate = 0;
- int do_id = 0;
- int unhide = 0;
- char *activatearg = 0;
- char *unhidearg = 0;
-
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
- atexit(close_stdout);
-
- if (!strcmp(program_invocation_short_name, "activate"))
- activate = 1; /* equivalent to `sfdisk -A' */
-
- while ((c = getopt_long(argc, argv, "cdfghilnqsu:vx1A::C:DGH:I:LN:O:RS:TU::V",
- long_opts, NULL)) != -1) {
- switch (c) {
- case 'f':
- force = 1;
- break; /* does not imply quiet */
- case 'g':
- opt_out_geom = 1;
- break;
- case 'G':
- opt_out_pt_geom = 1;
- break;
- case 'i':
- increment = 1;
- break;
- case 'c':
- case 'c' + PRINT_ID:
- case 'c' + CHANGE_ID:
- do_id = c;
- break;
- case 'd':
- dump = 1; /* fall through */
- case 'l':
- opt_list = 1;
- break;
- case 'n':
- no_write = 1;
- break;
- case 'q':
- quiet = 1;
- break;
- case 's':
- opt_size = 1;
- break;
- case 'u':
- set_format(*optarg);
- break;
- case 'v':
- printf(UTIL_LINUX_VERSION);
- return EXIT_SUCCESS;
- case 'h':
- usage(stdout);
- case 'x':
- show_extended = 1;
- break;
- case 'A':
- activatearg = optarg;
- activate = 1;
- break;
- case 'C':
- U.cylinders = strtoul_or_err(optarg, _("invalid cylinders argument"));
- break;
- case 'D':
- DOS = 1;
- break;
- case 'E':
- DOS_extended = 1;
- break;
- case 'H':
- U.heads = strtoul_or_err(optarg, _("invalid heads argument"));
- break;
- case 'L':
- Linux = 1;
- break;
- case 'N':
- one_only = strtol_or_err(optarg, _("invalid number of partitions argument"));
- break;
- case 'I':
- restore_sector_file = optarg;
- break;
- case 'O':
- save_sector_file = optarg;
- break;
- case 'R':
- opt_reread = 1;
- break;
- case 'S':
- U.sectors = strtoul_or_err(optarg, _("invalid sectors argument"));
- break;
- case 'T':
- list_types();
- return EXIT_SUCCESS;
- case 'U':
- unhidearg = optarg;
- unhide = 1;
- break;
- case 'V':
- verify = 1;
- break;
- default:
- usage(stderr);
-
- /* dangerous flags */
- case OPT_IN_ORDER:
- partitions_in_order = 1;
- break;
- case OPT_NOT_IN_ORDER:
- partitions_in_order = 0;
- break;
- case OPT_INSIDE_OUTER:
- all_logicals_inside_outermost_extended = 1;
- break;
- case OPT_NOT_INSIDE_OUTER:
- all_logicals_inside_outermost_extended = 0;
- break;
- case OPT_NESTED:
- boxes = NESTED;
- break;
- case OPT_CHAINED:
- boxes = CHAINED;
- break;
- case OPT_ONESECTOR:
- boxes = ONESECTOR;
- break;
-
- /* more flags */
- case OPT_NO_REREAD:
- no_reread = 1;
- break;
- case OPT_LEAVE_LAST:
- leave_last = 1;
- break;
- }
- }
-
- if (optind == argc &&
- (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify)) {
- FILE *procf;
-
- /* try all known devices */
- total_size = 0;
-
- procf = fopen(_PATH_PROC_PARTITIONS, "r");
- if (!procf)
- fprintf(stderr, _("cannot open %s\n"), _PATH_PROC_PARTITIONS);
- else {
- while ((dev = nextproc(procf)) != NULL) {
- if (!is_ide_cdrom_or_tape(dev)) {
- if (opt_out_geom)
- do_geom(dev, 1);
- if (opt_out_pt_geom)
- do_pt_geom(dev, 1);
- if (opt_size)
- do_size(dev, 1);
- if (opt_list || verify)
- ret = do_list(dev, 1);
- }
- free(dev);
- }
- fclose(procf);
- }
-
- if (opt_size)
- printf(_("total: %llu blocks\n"), total_size);
-
- goto done;
- }
-
- if (optind == argc) {
- if (activate)
- activate_usage();
- else
- usage(stderr);
- }
-
- if (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify) {
- while (optind < argc) {
- if (opt_out_geom)
- do_geom(argv[optind], 0);
- if (opt_out_pt_geom)
- do_pt_geom(argv[optind], 0);
- if (opt_size)
- do_size(argv[optind], 0);
- if (opt_list || verify)
- ret = do_list(argv[optind], 0);
- optind++;
- }
- goto done;
- }
-
- if (activate) {
- return do_activate(argv + optind, argc - optind, activatearg);
- }
- if (unhide) {
- return do_unhide(argv + optind, argc - optind, unhidearg);
- }
- if (do_id) {
- if ((do_id & PRINT_ID) != 0 && optind != argc - 2)
- errx(EXIT_FAILURE, _("usage: sfdisk --print-id device partition-number"));
- else if ((do_id & CHANGE_ID) != 0 && optind != argc - 3)
- errx(EXIT_FAILURE, _("usage: sfdisk --change-id device partition-number Id"));
- else if (optind != argc - 3 && optind != argc - 2)
- errx(EXIT_FAILURE, _("usage: sfdisk --id device partition-number [Id]"));
- return do_change_id(argv[optind], argv[optind + 1],
- (optind == argc - 2) ? 0 : argv[optind + 2]);
- }
-
- if (optind != argc - 1)
- errx(EXIT_FAILURE, _("can specify only one device (except with -l or -s)"));
- dev = argv[optind];
-
- if (opt_reread)
- do_reread(dev);
- else if (restore_sector_file)
- restore_sectors(dev);
- else
- ret = do_fdisk(dev);
-done:
- return ret;
-}
-
/*
* H. Listing the current situation
*/
@@ -3133,3 +2890,236 @@ static int do_fdisk(char *dev)
sync(); /* superstition */
return ret;
}
+
+int main(int argc, char **argv)
+{
+ int c, ret = 0;
+ char *dev;
+ int opt_size = 0;
+ int opt_out_geom = 0;
+ int opt_out_pt_geom = 0;
+ int opt_reread = 0;
+ int activate = 0;
+ int do_id = 0;
+ int unhide = 0;
+ char *activatearg = 0;
+ char *unhidearg = 0;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+ atexit(close_stdout);
+
+ if (!strcmp(program_invocation_short_name, "activate"))
+ activate = 1; /* equivalent to `sfdisk -A' */
+
+ while ((c = getopt_long(argc, argv, "cdfghilnqsu:vx1A::C:DGH:I:LN:O:RS:TU::V",
+ long_opts, NULL)) != -1) {
+ switch (c) {
+ case 'f':
+ force = 1;
+ break; /* does not imply quiet */
+ case 'g':
+ opt_out_geom = 1;
+ break;
+ case 'G':
+ opt_out_pt_geom = 1;
+ break;
+ case 'i':
+ increment = 1;
+ break;
+ case 'c':
+ case 'c' + PRINT_ID:
+ case 'c' + CHANGE_ID:
+ do_id = c;
+ break;
+ case 'd':
+ dump = 1; /* fall through */
+ case 'l':
+ opt_list = 1;
+ break;
+ case 'n':
+ no_write = 1;
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ case 's':
+ opt_size = 1;
+ break;
+ case 'u':
+ set_format(*optarg);
+ break;
+ case 'v':
+ printf(UTIL_LINUX_VERSION);
+ return EXIT_SUCCESS;
+ case 'h':
+ usage(stdout);
+ case 'x':
+ show_extended = 1;
+ break;
+ case 'A':
+ activatearg = optarg;
+ activate = 1;
+ break;
+ case 'C':
+ U.cylinders = strtoul_or_err(optarg, _("invalid cylinders argument"));
+ break;
+ case 'D':
+ DOS = 1;
+ break;
+ case 'E':
+ DOS_extended = 1;
+ break;
+ case 'H':
+ U.heads = strtoul_or_err(optarg, _("invalid heads argument"));
+ break;
+ case 'L':
+ Linux = 1;
+ break;
+ case 'N':
+ one_only = strtol_or_err(optarg, _("invalid number of partitions argument"));
+ break;
+ case 'I':
+ restore_sector_file = optarg;
+ break;
+ case 'O':
+ save_sector_file = optarg;
+ break;
+ case 'R':
+ opt_reread = 1;
+ break;
+ case 'S':
+ U.sectors = strtoul_or_err(optarg, _("invalid sectors argument"));
+ break;
+ case 'T':
+ list_types();
+ return EXIT_SUCCESS;
+ case 'U':
+ unhidearg = optarg;
+ unhide = 1;
+ break;
+ case 'V':
+ verify = 1;
+ break;
+ default:
+ usage(stderr);
+
+ /* dangerous flags */
+ case OPT_IN_ORDER:
+ partitions_in_order = 1;
+ break;
+ case OPT_NOT_IN_ORDER:
+ partitions_in_order = 0;
+ break;
+ case OPT_INSIDE_OUTER:
+ all_logicals_inside_outermost_extended = 1;
+ break;
+ case OPT_NOT_INSIDE_OUTER:
+ all_logicals_inside_outermost_extended = 0;
+ break;
+ case OPT_NESTED:
+ boxes = NESTED;
+ break;
+ case OPT_CHAINED:
+ boxes = CHAINED;
+ break;
+ case OPT_ONESECTOR:
+ boxes = ONESECTOR;
+ break;
+
+ /* more flags */
+ case OPT_NO_REREAD:
+ no_reread = 1;
+ break;
+ case OPT_LEAVE_LAST:
+ leave_last = 1;
+ break;
+ }
+ }
+
+ if (optind == argc &&
+ (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify)) {
+ FILE *procf;
+
+ /* try all known devices */
+ total_size = 0;
+
+ procf = fopen(_PATH_PROC_PARTITIONS, "r");
+ if (!procf)
+ fprintf(stderr, _("cannot open %s\n"), _PATH_PROC_PARTITIONS);
+ else {
+ while ((dev = nextproc(procf)) != NULL) {
+ if (!is_ide_cdrom_or_tape(dev)) {
+ if (opt_out_geom)
+ do_geom(dev, 1);
+ if (opt_out_pt_geom)
+ do_pt_geom(dev, 1);
+ if (opt_size)
+ do_size(dev, 1);
+ if (opt_list || verify)
+ ret = do_list(dev, 1);
+ }
+ free(dev);
+ }
+ fclose(procf);
+ }
+
+ if (opt_size)
+ printf(_("total: %llu blocks\n"), total_size);
+
+ goto done;
+ }
+
+ if (optind == argc) {
+ if (activate)
+ activate_usage();
+ else
+ usage(stderr);
+ }
+
+ if (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify) {
+ while (optind < argc) {
+ if (opt_out_geom)
+ do_geom(argv[optind], 0);
+ if (opt_out_pt_geom)
+ do_pt_geom(argv[optind], 0);
+ if (opt_size)
+ do_size(argv[optind], 0);
+ if (opt_list || verify)
+ ret = do_list(argv[optind], 0);
+ optind++;
+ }
+ goto done;
+ }
+
+ if (activate) {
+ return do_activate(argv + optind, argc - optind, activatearg);
+ }
+ if (unhide) {
+ return do_unhide(argv + optind, argc - optind, unhidearg);
+ }
+ if (do_id) {
+ if ((do_id & PRINT_ID) != 0 && optind != argc - 2)
+ errx(EXIT_FAILURE, _("usage: sfdisk --print-id device partition-number"));
+ else if ((do_id & CHANGE_ID) != 0 && optind != argc - 3)
+ errx(EXIT_FAILURE, _("usage: sfdisk --change-id device partition-number Id"));
+ else if (optind != argc - 3 && optind != argc - 2)
+ errx(EXIT_FAILURE, _("usage: sfdisk --id device partition-number [Id]"));
+ return do_change_id(argv[optind], argv[optind + 1],
+ (optind == argc - 2) ? 0 : argv[optind + 2]);
+ }
+
+ if (optind != argc - 1)
+ errx(EXIT_FAILURE, _("can specify only one device (except with -l or -s)"));
+ dev = argv[optind];
+
+ if (opt_reread)
+ do_reread(dev);
+ else if (restore_sector_file)
+ restore_sectors(dev);
+ else
+ ret = do_fdisk(dev);
+done:
+ return ret;
+}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 09/13] fdisk: remove bugus space after header includes
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
` (7 preceding siblings ...)
2014-07-22 23:44 ` [PATCH 08/13] sfdisk: move main function at the end of the file Davidlohr Bueso
@ 2014-07-22 23:44 ` Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 10/13] sfdisk: update [embarrassingly] old man-page Davidlohr Bueso
` (5 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
---
disk-utils/fdisk.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/disk-utils/fdisk.c b/disk-utils/fdisk.c
index e9b4fec..abb64a3 100644
--- a/disk-utils/fdisk.c
+++ b/disk-utils/fdisk.c
@@ -45,8 +45,6 @@
# include <linux/blkpg.h>
#endif
-
-
int get_user_reply(struct fdisk_context *cxt, const char *prompt,
char *buf, size_t bufsz)
{
--
1.8.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 10/13] sfdisk: update [embarrassingly] old man-page
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
` (8 preceding siblings ...)
2014-07-22 23:44 ` [PATCH 09/13] fdisk: remove bugus space after header includes Davidlohr Bueso
@ 2014-07-22 23:44 ` Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 11/13] sfdisk: rework option handling Davidlohr Bueso
` (4 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
... sheeeeesh. A little dignity, please.
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
---
disk-utils/sfdisk.8 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/disk-utils/sfdisk.8 b/disk-utils/sfdisk.8
index 1e84a11..d9d9b3e 100644
--- a/disk-utils/sfdisk.8
+++ b/disk-utils/sfdisk.8
@@ -402,7 +402,7 @@ that are going to be overwritten to
.I file
(where hopefully
.I file
-resides on another block device, or on a floppy).
+resides on another block device).
.TP
.BI \-I " file"
After destroying your filesystems with an unfortunate
--
1.8.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 11/13] sfdisk: rework option handling
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
` (9 preceding siblings ...)
2014-07-22 23:44 ` [PATCH 10/13] sfdisk: update [embarrassingly] old man-page Davidlohr Bueso
@ 2014-07-22 23:44 ` Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 12/13] sfdisk: fix --unhide segfault Davidlohr Bueso
` (3 subsequent siblings)
14 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
One of the biggest characteristics of sfdisk is that it has an enormous amount
of argument options. While the manpage classifies this has a bug, it does
have its place, ie: user or (more likely) sysadmin scripts. Any reworking effort
must maintain 100% backward compatibility, otherwise we can make users unhappy.
With that in mind, this patch proposes a fundamental general structuring of
the program's UI. Just as cfdisk has ncurses and fdisk has those crazy character
based menus, sfdisk uses the command line arguments as the main way of interaction.
Specifically, there are 4 main types of options that will define the overall
program logic -- each of these types are completely independent and keep a very
particular order. It introduces a simple static 'struct sfdisk_option' type as a
table that maps to the group-specific callback if enabled by the user.
A few observations:
* While this idea guarantees backward compatibility, it is possible for the
implementation to be missing a few corner cases. This patch is pretty well
tested, but still lacks 100% automation. So more testing is definitely
welcome!
* For now, have a global array of options. However, as the sfdisk context
begins to be built, this array can be moved inside and have direct control
over it.
While I doubt that there will ever be a need, adding a new group of options is
quite trivial, as it is to change the internal interfaces (sfdisk_option_*).
This last one will be more important as code matures.
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
---
disk-utils/sfdisk.c | 435 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 315 insertions(+), 120 deletions(-)
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index a097c6e..86ed112 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -40,6 +40,7 @@
#include <sys/stat.h>
#include <sys/utsname.h>
#include <limits.h>
+#include <assert.h>
#include "c.h"
#include "nls.h"
@@ -53,6 +54,9 @@
#include "strutils.h"
#include "sysfs.h"
+#define PRINT_ID 0400
+#define CHANGE_ID 01000
+
struct systypes {
unsigned char type;
char *name;
@@ -63,6 +67,200 @@ static struct systypes i386_sys_types[] = {
};
/*
+ * sfdisk program command line handling internal API.
+ */
+enum {
+ /*
+ * There are 4 independent, mutually exclusive types,
+ * or groups, of options throughout sfdisk.
+ *
+ * Keep this particular order to maintain backward
+ * option preference compatibility. Consider each group
+ * call completely isolated to one another. Otherwise
+ * existing scripts can be broken, ie:
+ *
+ * sfdisk -s -V /dev/sda
+ * sfdisk -G -g -s /dev/sda
+ */
+ SFDISK_OPT_OUT_GEOM = 0, /* list kernel's idea of the geometry */
+ SFDISK_OPT_OUT_PT_GEOM, /* list the geometry by looking at the pt */
+ SFDISK_OPT_SIZE, /* list size of the partition */
+ SFDISK_OPT_LIST, /* list partitions of a device */
+ SFDISK_OPT_VERIFY, /* check that listed partition is reasonable */
+#define SFDISK_OPT_GROUP1 SFDISK_OPT_VERIFY
+
+ SFDISK_OPT_ACTIVATE, /* mark the indicated partitions active, the rest inactive */
+ SFDISK_OPT_UNHIDE, /* mark various Microsoft partitions unhidden */
+#define SFDISK_OPT_GROUP2 SFDISK_OPT_UNHIDE
+
+ SFDISK_OPT_CHANGE_ID, /* print or change partition IDs to a given value */
+#define SFDISK_OPT_GROUP3 SFDISK_OPT_CHANGE_ID
+
+ SFDISK_OPT_REREAD, /* make the kernel re-read the partition table (BLKRRPART ioctl) */
+ SFDISK_OPT_RESTORE_SCT, /* restore filesystem/disk state backed-up by -O option */
+#define SFDISK_OPT_GROUP4 SFDISK_OPT_RESTORE_SCT
+
+ N_SFDISK_OPTS,
+};
+
+struct sfdisk_option {
+ int active;
+
+ /*
+ * Different different families of callbacks,
+ * depending on the passed options. For each callback
+ * type, there is a sfdisk_option_do_cb<N>() which
+ * should be called only after successfully calling
+ * sfdisk_option_is_cb<N>().
+ */
+ int (*callback1)(char *, int, unsigned long long *);
+ int (*callback2)(char **, int, char *);
+ int (*callback3)(char *, char *, char *);
+ int (*callback4)(char *);
+};
+
+/* the different callbacks */
+static int do_geom(char *dev, int silent,
+ unsigned long long *dummy __attribute__((__unused__)));
+static int do_pt_geom(char *dev, int silent,
+ unsigned long long *dummy __attribute__((__unused__)));
+static int do_size(char *dev, int silent, unsigned long long *total_size);
+static int do_verify(char *dev, int silent,
+ unsigned long long *dummy __attribute__((__unused__)));
+static int do_list(char *dev, int silent, unsigned long long *dummy __attribute__((__unused__)));
+static int do_activate(char **av, int ac, char *arg);
+static int do_unhide(char **av, int ac, char *arg);
+static int do_change_id(char *dev, char *pnam, char *id);
+static int do_reread(char *dev);
+static int do_restore_sectors(char *dev);
+
+static struct sfdisk_option opts[N_SFDISK_OPTS] = {
+ /* first group of options */
+ [SFDISK_OPT_OUT_GEOM] = { 0, do_geom, NULL, NULL },
+ [SFDISK_OPT_OUT_PT_GEOM] = { 0, do_pt_geom, NULL, NULL },
+ [SFDISK_OPT_SIZE] = { 0, do_size, NULL, NULL },
+ [SFDISK_OPT_VERIFY] = { 0, do_verify, NULL, NULL },
+ [SFDISK_OPT_LIST] = { 0, do_list, NULL, NULL },
+ /* second group of options */
+ [SFDISK_OPT_ACTIVATE] = { 0, NULL, do_activate, NULL },
+ [SFDISK_OPT_UNHIDE] = { 0, NULL, do_unhide, NULL },
+ /* Third group of options */
+ [SFDISK_OPT_CHANGE_ID] = { 0, NULL, NULL, do_change_id, NULL},
+ /* fourth group of options */
+ [SFDISK_OPT_REREAD] = { 0, NULL, NULL, NULL, do_reread },
+ [SFDISK_OPT_RESTORE_SCT] = { 0, NULL, NULL, NULL, do_restore_sectors },
+};
+
+static inline void sfdisk_option_checks(void)
+{
+ assert(N_SFDISK_OPTS - 1 == SFDISK_OPT_RESTORE_SCT);
+ assert((SFDISK_OPT_GROUP1 < SFDISK_OPT_GROUP2) &&
+ (SFDISK_OPT_GROUP3 < SFDISK_OPT_GROUP4));
+}
+
+/* TYPE 1 option calls */
+static inline int sfdisk_option_is_cb1(struct sfdisk_option *opts)
+{
+ int i;
+
+ for (i = 0; i <= SFDISK_OPT_GROUP1; i++)
+ if (opts[i].active)
+ return 1;
+ return 0;
+}
+
+static int sfdisk_option_do_cb1(struct sfdisk_option *opts, char *dev,
+ int silent, unsigned long long *arg)
+{
+ int i, ret = 0;
+
+ for (i = 0; i <= SFDISK_OPT_GROUP1; i++)
+ if (opts[i].active)
+ ret = opts[i].callback1(dev, silent, arg);
+ return ret;
+}
+/* TYPE 2 option calls */
+static inline int sfdisk_option_is_cb2(struct sfdisk_option *opts)
+{
+ int i;
+
+ for (i = SFDISK_OPT_GROUP1; i <= SFDISK_OPT_GROUP2; i++)
+ if (opts[i].active)
+ return 1;
+ return 0;
+}
+
+static int sfdisk_option_do_cb2(struct sfdisk_option *opts, char **av,
+ int ac, char *arg)
+{
+ int i;
+
+ for (i = SFDISK_OPT_GROUP1; i <= SFDISK_OPT_GROUP2; i++) {
+ if (!opts[i].active)
+ continue;
+
+ return opts[i].callback2(av, ac, arg);
+ }
+ return 0; /* should never occur */
+}
+/* TYPE 3 option calls */
+static inline int sfdisk_option_is_cb3(struct sfdisk_option *opts)
+{
+ int i;
+
+ for (i = SFDISK_OPT_GROUP2; i <= SFDISK_OPT_GROUP3; i++)
+ if (opts[i].active)
+ return 1;
+ return 0;
+}
+
+static int sfdisk_option_do_cb3(struct sfdisk_option *opts,
+ int optind, int argc,
+ char *dev, char *pnam, char *id)
+{
+ int i;
+
+ for (i = SFDISK_OPT_GROUP2; i <= SFDISK_OPT_GROUP3; i++) {
+ int do_id = opts[SFDISK_OPT_CHANGE_ID].active;
+
+ if (!opts[i].active)
+ continue;
+
+ if (i == SFDISK_OPT_CHANGE_ID && do_id) {
+ if ((do_id & PRINT_ID) != 0 && optind != argc - 2)
+ errx(EXIT_FAILURE, _("usage: sfdisk --print-id device partition-number"));
+ else if ((do_id & CHANGE_ID) != 0 && optind != argc - 3)
+ errx(EXIT_FAILURE, _("usage: sfdisk --change-id device partition-number Id"));
+ else if (optind != argc - 3 && optind != argc - 2)
+ errx(EXIT_FAILURE, _("usage: sfdisk --id device partition-number [Id]"));
+ }
+ return opts[i].callback3(dev, pnam, id);
+ }
+ return 0; /* should never occur */
+}
+/* TYPE 4 option calls */
+static inline int sfdisk_option_is_cb4(struct sfdisk_option *opts)
+{
+ int i;
+
+ for (i = SFDISK_OPT_GROUP3; i <= SFDISK_OPT_GROUP4; i++)
+ if (opts[i].active)
+ return 1;
+ return 0;
+}
+
+static int sfdisk_option_do_cb4(struct sfdisk_option *opts, char *dev)
+
+{
+ int i;
+
+ for (i = SFDISK_OPT_GROUP3; i <= SFDISK_OPT_GROUP4; i++)
+ if (opts[i].active)
+ return opts[i].callback4(dev);
+ return 0;
+}
+
+/*
* Table of contents:
* A. About seeking
* B. About sectors
@@ -79,15 +277,12 @@ int force = 0; /* 1: do what I say, even if it is stupid ... */
int quiet = 0; /* 1: suppress all warnings */
/* IA-64 gcc spec file currently does -DLinux... */
#undef Linux
-int Linux = 0; /* 1: suppress warnings irrelevant for Linux */
int DOS = 0; /* 1: shift extended partitions by #sectors, not 1 */
int DOS_extended = 0; /* 1: use starting cylinder boundary of extd partn */
int dump = 0; /* 1: list in a format suitable for later input */
-int verify = 0; /* 1: check that listed partition is reasonable */
int no_write = 0; /* 1: do not actually write to disk */
int no_reread = 0; /* 1: skip the BLKRRPART ioctl test at startup */
int leave_last = 0; /* 1: don't allocate the last cylinder */
-int opt_list = 0;
char *save_sector_file = NULL;
char *restore_sector_file = NULL;
@@ -303,8 +498,8 @@ err:
static int reread_disk_partition(char *dev, int fd);
-static int
-restore_sectors(char *dev) {
+static int do_restore_sectors(char *dev)
+{
int fdin = -1, fdout = -1;
int ct;
struct stat statbuf;
@@ -450,8 +645,8 @@ get_geometry(char *dev, int fd, int silent) {
return R;
}
-static void
-get_cylindersize(char *dev, int fd, int silent) {
+static void get_cylindersize(char *dev, int fd, int silent)
+{
struct geometry R;
R = get_geometry(dev, fd, silent);
@@ -1070,14 +1265,17 @@ out_partition(char *dev, int format, struct part_desc *p,
}
}
-static void
-out_partitions(char *dev, struct disk_desc *z) {
+static void out_partitions(char *dev, struct disk_desc *z)
+{
int pno, format = 0;
if (z->partno == 0) {
+ int opt_list = opts[SFDISK_OPT_LIST].active;
+
if (!opt_list)
warnx(_("No partitions found"));
} else {
+
if (get_fdisk_geometry(z) && !dump) {
warnx(_("Warning: The partition table looks like it was made\n"
" for C/H/S=*/%ld/%ld (instead of %ld/%ld/%ld).\n"
@@ -1554,8 +1752,10 @@ amiga_partition(char *dev __attribute__ ((__unused__)),
return 0;
}
-static void
-get_partitions(char *dev, int fd, struct disk_desc *z) {
+static void get_partitions(char *dev, int fd, struct disk_desc *z)
+{
+ int opt_list = opts[SFDISK_OPT_LIST].active;
+
z->partno = 0;
if (!msdos_partition(dev, fd, 0, z)
@@ -2339,13 +2539,15 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}
-static void
-activate_usage(void) {
+static void activate_usage(void)
+{
char *p;
+
if (!strcmp(program_invocation_short_name, "activate"))
p = " ";
else
p = " --activate=";
+
fputs(USAGE_HEADER, stderr);
fputs(USAGE_SEPARATOR, stderr);
fprintf(stderr, _(" %s%sdevice list active partitions on device\n"),
@@ -2356,9 +2558,6 @@ activate_usage(void) {
exit(EXIT_FAILURE);
}
-#define PRINT_ID 0400
-#define CHANGE_ID 01000
-
enum {
OPT_NO_REREAD = CHAR_MAX + 1,
OPT_LEAVE_LAST,
@@ -2457,14 +2656,12 @@ static char *nextproc(FILE *f)
return NULL;
}
-unsigned long long total_size;
-
/*
* H. Listing the current situation
*/
-static int
-my_open(char *dev, int rw, int silent) {
+static int my_open(char *dev, int rw, int silent)
+{
int fd, mode;
mode = (rw ? O_RDWR : O_RDONLY);
@@ -2478,7 +2675,8 @@ my_open(char *dev, int rw, int silent) {
return fd;
}
-static int do_list(char *dev, int silent)
+static int do_list(char *dev, int silent,
+ unsigned long long *dummy __attribute__((__unused__)))
{
int fd, ret = 0;
struct disk_desc *z;
@@ -2490,31 +2688,51 @@ static int do_list(char *dev, int silent)
z = &oldp;
free_sectors();
- get_cylindersize(dev, fd, dump ? 1 : opt_list ? 0 : 1);
+ get_cylindersize(dev, fd, dump ? 1 : 0);
get_partitions(dev, fd, z);
- if (opt_list)
- out_partitions(dev, z);
+ out_partitions(dev, z);
- if (verify) {
- if (partitions_ok(fd, z))
- printf(_("%s: OK"), dev);
- else
- ret = 1;
- }
+ close(fd);
+ return ret;
+}
+
+static int do_verify(char *dev, int silent,
+ unsigned long long *dummy __attribute__((__unused__)))
+{
+ int fd, ret = 0, opt_list = opts[SFDISK_OPT_LIST].active;
+ struct disk_desc *z;
+
+ fd = my_open(dev, 0, silent);
+ if (fd < 0)
+ return ret;
+
+ z = &oldp;
+
+ free_sectors();
+ get_cylindersize(dev, fd, dump ? 1 :
+ (opt_list && opts[SFDISK_OPT_SIZE].active) ? 0 : 1);
+ get_partitions(dev, fd, z);
+
+ if (partitions_ok(fd, z))
+ printf(_("%s: OK"), dev);
+ else
+ ret = 1;
close(fd);
return ret;
}
-static void
-do_geom(char *dev, int silent) {
+static int do_geom(char *dev, int silent,
+ unsigned long long *dummy __attribute__((__unused__)))
+
+{
int fd;
struct geometry R;
fd = my_open(dev, 0, silent);
if (fd < 0)
- return;
+ return 0;
R = get_geometry(dev, fd, silent);
if (R.cylinders)
@@ -2522,17 +2740,19 @@ do_geom(char *dev, int silent) {
dev, R.cylinders, R.heads, R.sectors);
close(fd);
+ return 0;
}
-static void
-do_pt_geom(char *dev, int silent) {
+static int do_pt_geom(char *dev, int silent,
+ unsigned long long *dummy __attribute__((__unused__)))
+{
int fd;
struct disk_desc *z;
struct geometry R;
fd = my_open(dev, 0, silent);
if (fd < 0)
- return;
+ return 0;
z = &oldp;
@@ -2554,17 +2774,18 @@ do_pt_geom(char *dev, int silent) {
dev, R.cylinders, R.heads, R.sectors);
close(fd);
+ return 0;
}
/* for compatibility with earlier fdisk: provide option -s */
-static void
-do_size(char *dev, int silent) {
+static int do_size(char *dev, int silent, unsigned long long *total_size)
+{
int fd;
unsigned long long size;
fd = my_open(dev, 0, silent);
if (fd < 0)
- return;
+ return 0;
if (blkdev_get_sectors(fd, &size) == -1) {
if (!silent)
@@ -2583,10 +2804,11 @@ do_size(char *dev, int silent) {
else
printf("%llu\n", size);
- total_size += size;
+ *total_size += size;
done:
close(fd);
+ return size;
}
/*
@@ -2778,8 +3000,8 @@ done:
return ret;
}
-static void
-do_reread(char *dev) {
+static int do_reread(char *dev)
+{
int fd;
fd = my_open(dev, 0, 0);
@@ -2789,6 +3011,7 @@ do_reread(char *dev) {
}
close(fd);
+ return 0;
}
/*
@@ -2893,25 +3116,19 @@ static int do_fdisk(char *dev)
int main(int argc, char **argv)
{
- int c, ret = 0;
- char *dev;
- int opt_size = 0;
- int opt_out_geom = 0;
- int opt_out_pt_geom = 0;
- int opt_reread = 0;
- int activate = 0;
- int do_id = 0;
- int unhide = 0;
- char *activatearg = 0;
- char *unhidearg = 0;
+ int c, err = 0;
+ char *dev, *args = NULL;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
atexit(close_stdout);
+ /* simple option size/order sanity check */
+ sfdisk_option_checks();
+
if (!strcmp(program_invocation_short_name, "activate"))
- activate = 1; /* equivalent to `sfdisk -A' */
+ opts[SFDISK_OPT_ACTIVATE].active = 1; /* equivalent to `sfdisk -A' */
while ((c = getopt_long(argc, argv, "cdfghilnqsu:vx1A::C:DGH:I:LN:O:RS:TU::V",
long_opts, NULL)) != -1) {
@@ -2920,10 +3137,10 @@ int main(int argc, char **argv)
force = 1;
break; /* does not imply quiet */
case 'g':
- opt_out_geom = 1;
+ opts[SFDISK_OPT_OUT_GEOM].active = 1;
break;
case 'G':
- opt_out_pt_geom = 1;
+ opts[SFDISK_OPT_OUT_PT_GEOM].active = 1;
break;
case 'i':
increment = 1;
@@ -2931,12 +3148,12 @@ int main(int argc, char **argv)
case 'c':
case 'c' + PRINT_ID:
case 'c' + CHANGE_ID:
- do_id = c;
+ opts[SFDISK_OPT_CHANGE_ID].active = c;
break;
case 'd':
dump = 1; /* fall through */
case 'l':
- opt_list = 1;
+ opts[SFDISK_OPT_LIST].active = 1;
break;
case 'n':
no_write = 1;
@@ -2945,7 +3162,7 @@ int main(int argc, char **argv)
quiet = 1;
break;
case 's':
- opt_size = 1;
+ opts[SFDISK_OPT_SIZE].active = 1;
break;
case 'u':
set_format(*optarg);
@@ -2959,8 +3176,8 @@ int main(int argc, char **argv)
show_extended = 1;
break;
case 'A':
- activatearg = optarg;
- activate = 1;
+ args = optarg;
+ opts[SFDISK_OPT_ACTIVATE].active = 1;
break;
case 'C':
U.cylinders = strtoul_or_err(optarg, _("invalid cylinders argument"));
@@ -2975,19 +3192,19 @@ int main(int argc, char **argv)
U.heads = strtoul_or_err(optarg, _("invalid heads argument"));
break;
case 'L':
- Linux = 1;
break;
case 'N':
one_only = strtol_or_err(optarg, _("invalid number of partitions argument"));
break;
case 'I':
restore_sector_file = optarg;
+ opts[SFDISK_OPT_RESTORE_SCT].active = 1;
break;
case 'O':
save_sector_file = optarg;
break;
case 'R':
- opt_reread = 1;
+ opts[SFDISK_OPT_REREAD].active = 1;
break;
case 'S':
U.sectors = strtoul_or_err(optarg, _("invalid sectors argument"));
@@ -2996,11 +3213,11 @@ int main(int argc, char **argv)
list_types();
return EXIT_SUCCESS;
case 'U':
- unhidearg = optarg;
- unhide = 1;
+ args = optarg;
+ opts[SFDISK_OPT_UNHIDE].active = 1;
break;
case 'V':
- verify = 1;
+ opts[SFDISK_OPT_VERIFY].active = 1;
break;
default:
usage(stderr);
@@ -3038,88 +3255,66 @@ int main(int argc, char **argv)
}
}
- if (optind == argc &&
- (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify)) {
+ if ((optind == argc) && sfdisk_option_is_cb1(opts)) { /* ie: sfdisk -V */
FILE *procf;
-
- /* try all known devices */
- total_size = 0;
+ unsigned long long total_size = 0; /* try all known devices */
procf = fopen(_PATH_PROC_PARTITIONS, "r");
if (!procf)
fprintf(stderr, _("cannot open %s\n"), _PATH_PROC_PARTITIONS);
else {
- while ((dev = nextproc(procf)) != NULL) {
- if (!is_ide_cdrom_or_tape(dev)) {
- if (opt_out_geom)
- do_geom(dev, 1);
- if (opt_out_pt_geom)
- do_pt_geom(dev, 1);
- if (opt_size)
- do_size(dev, 1);
- if (opt_list || verify)
- ret = do_list(dev, 1);
- }
+ while ((dev = nextproc(procf))) {
+ if (!is_ide_cdrom_or_tape(dev))
+ err = sfdisk_option_do_cb1(opts, dev, 1, &total_size);
free(dev);
}
fclose(procf);
}
- if (opt_size)
- printf(_("total: %llu blocks\n"), total_size);
-
+ if (opts[SFDISK_OPT_SIZE].active)
+ printf(_("total: %llu blocks\n"), total_size);
goto done;
}
- if (optind == argc) {
- if (activate)
+ if (optind == argc) { /* ie: sfdisk -A */
+ if (opts[SFDISK_OPT_ACTIVATE].active)
activate_usage();
else
usage(stderr);
+ /* neither usage-family functions returns to the caller */
}
- if (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify) {
- while (optind < argc) {
- if (opt_out_geom)
- do_geom(argv[optind], 0);
- if (opt_out_pt_geom)
- do_pt_geom(argv[optind], 0);
- if (opt_size)
- do_size(argv[optind], 0);
- if (opt_list || verify)
- ret = do_list(argv[optind], 0);
- optind++;
- }
+ if (sfdisk_option_is_cb1(opts)) {
+ unsigned long long dummy = 0;
+
+ while (optind < argc)
+ err = sfdisk_option_do_cb1(opts, argv[optind++], 0, &dummy);
goto done;
}
- if (activate) {
- return do_activate(argv + optind, argc - optind, activatearg);
- }
- if (unhide) {
- return do_unhide(argv + optind, argc - optind, unhidearg);
+ if (sfdisk_option_is_cb2(opts)) { /* ie: sfdisk -A /dev/sda */
+ err = sfdisk_option_do_cb2(opts, argv + optind, argc - optind, args);
+ goto done;
}
- if (do_id) {
- if ((do_id & PRINT_ID) != 0 && optind != argc - 2)
- errx(EXIT_FAILURE, _("usage: sfdisk --print-id device partition-number"));
- else if ((do_id & CHANGE_ID) != 0 && optind != argc - 3)
- errx(EXIT_FAILURE, _("usage: sfdisk --change-id device partition-number Id"));
- else if (optind != argc - 3 && optind != argc - 2)
- errx(EXIT_FAILURE, _("usage: sfdisk --id device partition-number [Id]"));
- return do_change_id(argv[optind], argv[optind + 1],
- (optind == argc - 2) ? 0 : argv[optind + 2]);
+
+ if (sfdisk_option_is_cb3(opts)) { /* ie: sfdisk -c /dev/sda */
+ err = sfdisk_option_do_cb3(opts, optind, argc,
+ argv[optind], argv[optind + 1],
+ (optind == argc - 2) ? 0 : argv[optind + 2]);
+ goto done;
}
if (optind != argc - 1)
errx(EXIT_FAILURE, _("can specify only one device (except with -l or -s)"));
dev = argv[optind];
- if (opt_reread)
- do_reread(dev);
- else if (restore_sector_file)
- restore_sectors(dev);
- else
- ret = do_fdisk(dev);
+ if (sfdisk_option_is_cb4(opts)) { /* ie: sfdisk -R /dev/sda */
+ err = sfdisk_option_do_cb4(opts, dev);
+ goto done;
+ }
+
+ /* ok ok, do the rest */
+ err = do_fdisk(dev);
done:
- return ret;
+ return err ? EXIT_FAILURE : EXIT_SUCCESS;
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 12/13] sfdisk: fix --unhide segfault
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
` (10 preceding siblings ...)
2014-07-22 23:44 ` [PATCH 11/13] sfdisk: rework option handling Davidlohr Bueso
@ 2014-07-22 23:44 ` Davidlohr Bueso
2014-07-26 4:22 ` Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 13/13] sfdisk: activate_usage() can use noreturn attribute Signed-off-by: Davidlohr Bueso <davidlohr@hp.com> Davidlohr Bueso
` (2 subsequent siblings)
14 siblings, 1 reply; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
There's currently a NULL ptr dereference bug when calling asc_to_index()
via set_unhidden(). Fix this bug by checking the optarg value for null.
This is similar to how other options handle such calls.
Before:
Segmentation fault (core dumped)
After:
sfdisk: Done: Success
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
---
disk-utils/sfdisk.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index 86ed112..f730504 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -2909,12 +2909,13 @@ static int do_activate(char **av, int ac, char *arg)
return ret;
}
-static void
-set_unhidden(struct disk_desc *z, char *pnam) {
+static void set_unhidden(struct disk_desc *z, char *pnam)
+{
int pno;
unsigned char id;
pno = asc_to_index(pnam, z);
+ printf("\t%s\n", pnam);
id = z->partitions[pno].p.sys_type;
if (id == 0x11 || id == 0x14 || id == 0x16 || id == 0x17 ||
id == 0x17 || id == 0x1b || id == 0x1c || id == 0x1e)
@@ -2943,7 +2944,7 @@ static int do_unhide(char **av, int ac, char *arg)
get_partitions(dev, fd, z);
/* unhide where desired */
- if (ac == 1)
+ if (ac == 1 && arg)
set_unhidden(z, arg);
else
for (i = 1; i < ac; i++)
--
1.8.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 13/13] sfdisk: activate_usage() can use noreturn attribute Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
` (11 preceding siblings ...)
2014-07-22 23:44 ` [PATCH 12/13] sfdisk: fix --unhide segfault Davidlohr Bueso
@ 2014-07-22 23:44 ` Davidlohr Bueso
2014-07-22 23:46 ` [PATCH 00/13] sfdisk: Davidlohr Bueso
2014-07-23 6:54 ` Karel Zak
14 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:44 UTC (permalink / raw)
To: kzak; +Cc: davidlohr, aswin, util-linux
---
disk-utils/sfdisk.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index f730504..6fbbb73 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -2539,7 +2539,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}
-static void activate_usage(void)
+static void __attribute__ ((__noreturn__)) activate_usage(void)
{
char *p;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 00/13] sfdisk:
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
` (12 preceding siblings ...)
2014-07-22 23:44 ` [PATCH 13/13] sfdisk: activate_usage() can use noreturn attribute Signed-off-by: Davidlohr Bueso <davidlohr@hp.com> Davidlohr Bueso
@ 2014-07-22 23:46 ` Davidlohr Bueso
2014-07-23 6:54 ` Karel Zak
14 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-22 23:46 UTC (permalink / raw)
To: kzak; +Cc: aswin, util-linux
Oops, subject should have been "sfdisk: cleanups part1"
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 00/13] sfdisk:
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
` (13 preceding siblings ...)
2014-07-22 23:46 ` [PATCH 00/13] sfdisk: Davidlohr Bueso
@ 2014-07-23 6:54 ` Karel Zak
14 siblings, 0 replies; 17+ messages in thread
From: Karel Zak @ 2014-07-23 6:54 UTC (permalink / raw)
To: Davidlohr Bueso; +Cc: aswin, util-linux
On Tue, Jul 22, 2014 at 04:44:44PM -0700, Davidlohr Bueso wrote:
> The sfdisk(8) program is the only one left to be rewritten to use the new libfdisk library.
Note that I'd like to move all core sfdisk functionality to libfdisk,
to make it possible to save / load partitioning scripts in all fdisk
applications (fdisk and cfdisk).
> disk-utils/fdisk.c | 2 -
> disk-utils/sfdisk.8 | 4 +-
> disk-utils/sfdisk.c | 4751 ++++++++++++++++++++++++++-------------------------
> 3 files changed, 2417 insertions(+), 2340 deletions(-)
OK, I'll apply this later this week. Thanks.
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 12/13] sfdisk: fix --unhide segfault
2014-07-22 23:44 ` [PATCH 12/13] sfdisk: fix --unhide segfault Davidlohr Bueso
@ 2014-07-26 4:22 ` Davidlohr Bueso
0 siblings, 0 replies; 17+ messages in thread
From: Davidlohr Bueso @ 2014-07-26 4:22 UTC (permalink / raw)
To: kzak; +Cc: aswin, util-linux
On Tue, 2014-07-22 at 16:44 -0700, Davidlohr Bueso wrote:
> There's currently a NULL ptr dereference bug when calling asc_to_index()
> via set_unhidden(). Fix this bug by checking the optarg value for null.
> This is similar to how other options handle such calls.
>
> Before:
> Segmentation fault (core dumped)
>
> After:
> sfdisk: Done: Success
>
> Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
> ---
> disk-utils/sfdisk.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
> index 86ed112..f730504 100644
> --- a/disk-utils/sfdisk.c
> +++ b/disk-utils/sfdisk.c
> @@ -2909,12 +2909,13 @@ static int do_activate(char **av, int ac, char *arg)
> return ret;
> }
>
> -static void
> -set_unhidden(struct disk_desc *z, char *pnam) {
> +static void set_unhidden(struct disk_desc *z, char *pnam)
> +{
> int pno;
> unsigned char id;
>
> pno = asc_to_index(pnam, z);
> + printf("\t%s\n", pnam);
err, sorry... forgot to delete that one.
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2014-07-26 4:22 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-22 23:44 [PATCH 00/13] sfdisk: Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 01/13] sfdisk: remove bogus argc check Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 02/13] sfdisk: deprecate --linux option Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 03/13] sfdisk: remove dead code Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 04/13] sfdisk: remove 'short_opts' global variable Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 05/13] sfdisk: fix indentation Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 06/13] sfdisk: remove declaraion of 'partname()' Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 07/13] sfdisk: remove 'exit_status' global variable Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 08/13] sfdisk: move main function at the end of the file Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 09/13] fdisk: remove bugus space after header includes Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 10/13] sfdisk: update [embarrassingly] old man-page Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 11/13] sfdisk: rework option handling Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 12/13] sfdisk: fix --unhide segfault Davidlohr Bueso
2014-07-26 4:22 ` Davidlohr Bueso
2014-07-22 23:44 ` [PATCH 13/13] sfdisk: activate_usage() can use noreturn attribute Signed-off-by: Davidlohr Bueso <davidlohr@hp.com> Davidlohr Bueso
2014-07-22 23:46 ` [PATCH 00/13] sfdisk: Davidlohr Bueso
2014-07-23 6:54 ` Karel Zak
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).