Date: Fri, 25 Jun 2004 12:23:41 +0200 (CEST) From: Rene de Vries <rene@tunix.nl> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/68312: be able to create fdisk partions using similar syntax as disklabel/bsdlabel Message-ID: <200406251023.i5PANf2W063176@upsilix.tunix.nl> Resent-Message-ID: <200406251040.i5PAeJmE043099@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200406251023.i5PANf2W063176>