bin/68312: be able to create fdisk partions using similar syntax as
disklabel/bsdlabel
Rene de Vries
rene at tunix.nl
Fri Jun 25 10:41:38 GMT 2004
>Number: 68312
>Category: bin
>Synopsis: be able to create fdisk partions using similar syntax as disklabel/bsdlabel
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Fri Jun 25 10:40:19 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: Rene de Vries
>Release: FreeBSD 4.8 i386
>Organization:
Tunix Internet Security & Training
>Environment:
System: FreeBSD upsilix.tunix.nl 4.8 FreeBSD 4.8-RELEASE-p16 #7: Wed Mar 3 15:00:31 CET 2004 rene at upsilix.tunix.nl:/usr/obj/usr/src/sys/UPSILIX i386
>Description:
Added some cleverness to the 'p' command while parsing a
fdisk partition description file.
Sizes can now also be given in '10M', '20G', etc and wildcards
can be used to assume sensible defaults.
Example:
/tmp/fdisk.in:
p 1 165 * 10G
p 2 165 * 20G
p 3 165 * *
fdisk -f /tmp/fdisk.in /dev/ad2
>How-To-Repeat:
>Fix:
Index: sbin/i386/fdisk/fdisk.c
===================================================================
RCS file: sbin/i386/fdisk/fdisk.c,v
retrieving revision 1.1.1.4
retrieving revision 1.2
diff -u -r1.1.1.4 -r1.2
--- sbin/i386/fdisk/fdisk.c 2002/08/28 08:57:58 1.1.1.4
+++ sbin/i386/fdisk/fdisk.c 2003/07/22 15:43:21 1.2
@@ -113,6 +113,7 @@
struct arg {
char argtype;
int arg_val;
+ char *arg_str;
} args[MAX_ARGS];
} CMD;
@@ -1013,6 +1014,10 @@
while (1)
{
while (isspace(*cp)) ++cp;
+ if (*cp == '\0')
+ {
+ break; /* eol */
+ }
if (*cp == '#')
{
break; /* found comment */
@@ -1021,16 +1026,21 @@
{
command->args[command->n_args].argtype = *cp++;
}
- if (!isdigit(*cp))
- {
- break; /* assume end of line */
- }
end = NULL;
command->args[command->n_args].arg_val = strtol(cp, &end, 0);
- if (cp == end)
+ if ((cp == end) || (!isspace(*end) && (*end != '\0')))
{
- break; /* couldn't parse number */
+ char ch;
+ end = cp;
+ while (!isspace(*end) && *end != '\0') ++end;
+ ch = *end; *end = '\0';
+ command->args[command->n_args].arg_str = strdup(cp);
+ *end = ch;
}
+ else
+ {
+ command->args[command->n_args].arg_str = NULL;
+ }
cp = end;
command->n_args++;
}
@@ -1174,8 +1184,96 @@
partp = ((struct dos_partition *) &mboot.parts) + partition - 1;
bzero((char *)partp, sizeof (struct dos_partition));
partp->dp_typ = command->args[1].arg_val;
- partp->dp_start = command->args[2].arg_val;
- partp->dp_size = command->args[3].arg_val;
+ if (command->args[2].arg_str != NULL)
+ {
+ if (strcmp(command->args[2].arg_str, "*") == 0)
+ {
+ int i;
+ partp->dp_start = dos_sectors;
+ for (i = 1; i < partition; i++)
+ {
+ struct dos_partition *prev_partp;
+ prev_partp = ((struct dos_partition *) &mboot.parts) + i - 1;
+ if (prev_partp->dp_typ != 0)
+ {
+ partp->dp_start = prev_partp->dp_start + prev_partp->dp_size;
+ }
+ }
+ if (partp->dp_start % dos_sectors != 0)
+ {
+ prev_head_boundary = partp->dp_start / dos_sectors * dos_sectors;
+ partp->dp_start = prev_head_boundary + dos_sectors;
+ }
+ }
+ else
+ {
+ warnx("ERROR line %d: unexpected start: \'%s\'",
+ current_line_number, command->args[2].arg_str);
+ break;
+ }
+ }
+ else
+ {
+ partp->dp_start = command->args[2].arg_val;
+ }
+
+ if (command->args[3].arg_str != NULL)
+ {
+ if (strcmp(command->args[3].arg_str, "*") == 0)
+ {
+ partp->dp_size =
+ ((disksecs / dos_cylsecs) * dos_cylsecs) -
+ partp->dp_start;
+ }
+ else
+ {
+ char *end;
+ unsigned long val;
+ val = strtol(command->args[3].arg_str, &end, 0);
+ if (command->args[3].arg_str == end) {
+ warnx("ERROR line %d: unexpected size: \'%s\'",
+ current_line_number, command->args[3].arg_str);
+ break;
+ }
+ if (*end != '\0') {
+ if (*end == 'K')
+ {
+ val *= (1024UL / secsize);
+ }
+ else if (*end == 'M')
+ {
+ val *= (unsigned long)(1024 * 1024 / secsize);
+ }
+ else if (*end == 'G')
+ {
+ val *= (unsigned long)(1024 * 1024 * 1024 / secsize);
+ }
+ else
+ {
+ warnx("ERROR line %d: unexpected modifier: %c (K/M/G)",
+ current_line_number, *end);
+ break;
+ }
+ }
+ else
+ {
+ warnx("ERROR line %d: unexpected size: %s",
+ current_line_number, command->args[3].arg_str);
+ break;
+ }
+ partp->dp_size = val;
+ }
+ prev_cyl_boundary =
+ ((partp->dp_start + partp->dp_size) / dos_cylsecs) * dos_cylsecs;
+ if (prev_cyl_boundary > partp->dp_start)
+ {
+ partp->dp_size = prev_cyl_boundary - partp->dp_start;
+ }
+ }
+ else
+ {
+ partp->dp_size = command->args[3].arg_val;
+ }
max_end = partp->dp_start + partp->dp_size;
if (partp->dp_typ == 0)
@@ -1189,6 +1287,15 @@
bzero((char *)partp, sizeof (struct dos_partition));
status = 1;
break;
+ }
+
+ if (v_flag)
+ {
+ printf("p%d type=%d start=%lu size=%lu\n",
+ partition,
+ partp->dp_typ,
+ partp->dp_start,
+ partp->dp_size);
}
/*
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list