summaryrefslogtreecommitdiffstats
path: root/sbin/bsdlabel/bsdlabel.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/bsdlabel/bsdlabel.c')
-rw-r--r--sbin/bsdlabel/bsdlabel.c263
1 files changed, 134 insertions, 129 deletions
diff --git a/sbin/bsdlabel/bsdlabel.c b/sbin/bsdlabel/bsdlabel.c
index becc280..45964b6 100644
--- a/sbin/bsdlabel/bsdlabel.c
+++ b/sbin/bsdlabel/bsdlabel.c
@@ -116,6 +116,7 @@ int editit(void);
char *skip(char *);
char *word(char *);
int getasciilabel(FILE *, struct disklabel *);
+int getasciipartspec(char *, struct disklabel *, int, int);
int checklabel(struct disklabel *);
void setbootflag(struct disklabel *);
void Warning(const char *, ...) __printflike(1, 2);
@@ -929,7 +930,6 @@ getasciilabel(FILE *f, struct disklabel *lp)
{
char *cp;
const char **cpp;
- struct partition *pp;
unsigned int part;
char *tp, line[BUFSIZ];
int v, lineno = 0, errors = 0;
@@ -958,7 +958,7 @@ getasciilabel(FILE *f, struct disklabel *lp)
for (; cpp < &dktypenames[DKMAXTYPES]; cpp++)
if (*cpp && streq(*cpp, tp)) {
lp->d_type = cpp - dktypenames;
- goto next;
+ continue;
}
v = atoi(tp);
if ((unsigned)v >= DKMAXTYPES)
@@ -1135,35 +1135,51 @@ getasciilabel(FILE *f, struct disklabel *lp)
continue;
}
/* the ':' was removed above */
- if ('a' <= *cp && *cp <= MAX_PART && cp[1] == '\0') {
- part = *cp - 'a';
- if (part >= lp->d_npartitions) {
- fprintf(stderr,
- "line %d: partition name out of range a-%c: %s\n",
- lineno, 'a' + lp->d_npartitions - 1, cp);
- errors++;
- continue;
- }
- pp = &lp->d_partitions[part];
- part_set[part] = 1;
-#define NXTNUM(n) { \
+ if (*cp < 'a' || *cp > MAX_PART || cp[1] != '\0') {
+ fprintf(stderr,
+ "line %d: %s: Unknown disklabel field\n", lineno,
+ cp);
+ errors++;
+ continue;
+ }
+
+ /* Process a partition specification line. */
+ part = *cp - 'a';
+ if (part >= lp->d_npartitions) {
+ fprintf(stderr,
+ "line %d: partition name out of range a-%c: %s\n",
+ lineno, 'a' + lp->d_npartitions - 1, cp);
+ errors++;
+ continue;
+ }
+ part_set[part] = 1;
+
+ if (getasciipartspec(tp, lp, part, lineno) != 0) {
+ errors++;
+ break;
+ }
+ }
+ errors += checklabel(lp);
+ return (errors == 0);
+}
+
+#define NXTNUM(n) do { \
if (tp == NULL) { \
fprintf(stderr, "line %d: too few numeric fields\n", lineno); \
- errors++; \
- break; \
+ return (1); \
} else { \
cp = tp, tp = word(cp); \
if (tp == NULL) \
tp = cp; \
(n) = atoi(cp); \
} \
- }
+} while (0)
+
/* retain 1 character following number */
-#define NXTWORD(w,n) { \
+#define NXTWORD(w,n) do { \
if (tp == NULL) { \
fprintf(stderr, "line %d: too few numeric fields\n", lineno); \
- errors++; \
- break; \
+ return (1); \
} else { \
char *tmp; \
cp = tp, tp = word(cp); \
@@ -1172,120 +1188,109 @@ getasciilabel(FILE *f, struct disklabel *lp)
(n) = strtol(cp,&tmp,10); \
if (tmp) (w) = *tmp; \
} \
- }
- v = 0;
- NXTWORD(part_size_type[part],v);
- if (v < 0 || (v == 0 && part_size_type[part] != '*')) {
- fprintf(stderr,
- "line %d: %s: bad partition size\n",
- lineno, cp);
- errors++;
- break;
- } else {
- pp->p_size = v;
+} while (0)
- v = 0;
- NXTWORD(part_offset_type[part],v);
- if (v < 0 || (v == 0 &&
- part_offset_type[part] != '*' &&
- part_offset_type[part] != '\0')) {
- fprintf(stderr,
- "line %d: %s: bad partition offset\n",
- lineno, cp);
- errors++;
- break;
- } else {
- pp->p_offset = v;
- cp = tp, tp = word(cp);
- cpp = fstypenames;
- for (; cpp < &fstypenames[FSMAXTYPES]; cpp++)
- if (*cpp && streq(*cpp, cp)) {
- pp->p_fstype = cpp -
- fstypenames;
- goto gottype;
- }
- if (isdigit(*cp))
- v = atoi(cp);
- else
- v = FSMAXTYPES;
- if ((unsigned)v >= FSMAXTYPES) {
- fprintf(stderr,
- "line %d: Warning, unknown "
- "filesystem type %s\n",
- lineno, cp);
- v = FS_UNUSED;
- }
- pp->p_fstype = v;
- gottype:;
- /*
- * Note: NXTNUM will break us out of the
- * switch only!
- */
- switch (pp->p_fstype) {
- case FS_UNUSED:
- /*
- * allow us to accept defaults for
- * fsize/frag/cpg
- */
- if (tp) {
- NXTNUM(pp->p_fsize);
- if (pp->p_fsize == 0)
- break;
- NXTNUM(v);
- pp->p_frag = v / pp->p_fsize;
- }
- /* else default to 0's */
- break;
-
- /* These happen to be the same */
- case FS_BSDFFS:
- case FS_BSDLFS:
- if (tp) {
- NXTNUM(pp->p_fsize);
- if (pp->p_fsize == 0)
- break;
- NXTNUM(v);
- pp->p_frag = v / pp->p_fsize;
- NXTNUM(pp->p_cpg);
- } else {
- /*
- * FIX! poor attempt at
- * adaptive
- */
- /* 1 GB */
- if (pp->p_size < 1*1024*1024*1024/lp->d_secsize) {
-/* FIX! These are too low, but are traditional */
- pp->p_fsize = DEFAULT_NEWFS_BLOCK;
- pp->p_frag = (unsigned char) DEFAULT_NEWFS_FRAG;
- pp->p_cpg = DEFAULT_NEWFS_CPG;
- } else {
- pp->p_fsize = BIG_NEWFS_BLOCK;
- pp->p_frag = (unsigned char) BIG_NEWFS_FRAG;
- pp->p_cpg = BIG_NEWFS_CPG;
- }
- }
- break;
- default:
- break;
- }
+/*
+ * Read a partition line into partition `part' in the specified disklabel.
+ * Return 0 on success, 1 on failure.
+ */
+int
+getasciipartspec(char *tp, struct disklabel *lp, int part, int lineno)
+{
+ struct partition *pp;
+ char *cp;
+ const char **cpp;
+ int v;
- /*
- * note: we may not have
- * gotten all the entries for
- * the fs though if we didn't,
- * errors will be set.
- */
- }
+ pp = &lp->d_partitions[part];
+ cp = NULL;
+
+ v = 0;
+ NXTWORD(part_size_type[part],v);
+ if (v < 0 || (v == 0 && part_size_type[part] != '*')) {
+ fprintf(stderr, "line %d: %s: bad partition size\n", lineno,
+ cp);
+ return (1);
+ }
+ pp->p_size = v;
+
+ v = 0;
+ NXTWORD(part_offset_type[part],v);
+ if (v < 0 || (v == 0 && part_offset_type[part] != '*' &&
+ part_offset_type[part] != '\0')) {
+ fprintf(stderr, "line %d: %s: bad partition offset\n", lineno,
+ cp);
+ return (1);
+ }
+ pp->p_offset = v;
+ cp = tp, tp = word(cp);
+ for (cpp = fstypenames; cpp < &fstypenames[FSMAXTYPES]; cpp++)
+ if (*cpp && streq(*cpp, cp))
+ break;
+ if (*cpp != NULL) {
+ pp->p_fstype = cpp - fstypenames;
+ } else {
+ if (isdigit(*cp))
+ v = atoi(cp);
+ else
+ v = FSMAXTYPES;
+ if ((unsigned)v >= FSMAXTYPES) {
+ fprintf(stderr,
+ "line %d: Warning, unknown filesystem type %s\n",
+ lineno, cp);
+ v = FS_UNUSED;
+ }
+ pp->p_fstype = v;
+ }
+
+ switch (pp->p_fstype) {
+ case FS_UNUSED:
+ /*
+ * allow us to accept defaults for
+ * fsize/frag/cpg
+ */
+ if (tp) {
+ NXTNUM(pp->p_fsize);
+ if (pp->p_fsize == 0)
+ break;
+ NXTNUM(v);
+ pp->p_frag = v / pp->p_fsize;
+ }
+ /* else default to 0's */
+ break;
+
+ /* These happen to be the same */
+ case FS_BSDFFS:
+ case FS_BSDLFS:
+ if (tp) {
+ NXTNUM(pp->p_fsize);
+ if (pp->p_fsize == 0)
+ break;
+ NXTNUM(v);
+ pp->p_frag = v / pp->p_fsize;
+ NXTNUM(pp->p_cpg);
+ } else {
+ /*
+ * FIX! poor attempt at adaptive
+ */
+ /* 1 GB */
+ if (pp->p_size < 1024*1024*1024 / lp->d_secsize) {
+ /*
+ * FIX! These are too low, but are traditional
+ */
+ pp->p_fsize = DEFAULT_NEWFS_BLOCK;
+ pp->p_frag = (unsigned char) DEFAULT_NEWFS_FRAG;
+ pp->p_cpg = DEFAULT_NEWFS_CPG;
+ } else {
+ pp->p_fsize = BIG_NEWFS_BLOCK;
+ pp->p_frag = (unsigned char) BIG_NEWFS_FRAG;
+ pp->p_cpg = BIG_NEWFS_CPG;
}
- continue;
}
- fprintf(stderr, "line %d: %s: Unknown disklabel field\n",
- lineno, cp);
- errors++;
- next:;
+ default:
+ break;
}
- errors += checklabel(lp);
- return (errors == 0);
+ return (0);
}
/*
OpenPOWER on IntegriCloud