Teach newfs(8) to understand size modifiers for all options taking

size or size-like argument. I.e. "-s 32k" instead of "-s 32768".
Size parsing function has been shamelessly stolen from the truncate(1).
I'm sure many sysadmins out there will appreciate this small
improvement.

MFC after:	1 week
This commit is contained in:
Maxim Sobolev 2010-03-03 02:05:09 +00:00
parent 07ce8d9b43
commit 83b5ab2770
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=204615

View file

@ -117,6 +117,7 @@ static void getfssize(intmax_t *, const char *p, intmax_t, intmax_t);
static struct disklabel *getdisklabel(char *s);
static void rewritelabel(char *s, struct disklabel *lp);
static void usage(void);
static int parselength(const char *ls, int *sz);
ufs2_daddr_t part_ofs; /* partition offset in blocks, used with files */
@ -129,7 +130,7 @@ main(int argc, char *argv[])
struct stat st;
char *cp, *special;
intmax_t reserved;
int ch, i;
int ch, i, rval;
off_t mediasize;
char part_name; /* partition name, default to full disk */
@ -169,7 +170,8 @@ main(int argc, char *argv[])
Rflag = 1;
break;
case 'S':
if ((sectorsize = atoi(optarg)) <= 0)
rval = parselength(optarg, &sectorsize);
if (rval < 0 || sectorsize <= 0)
errx(1, "%s: bad sector size", optarg);
break;
case 'T':
@ -182,12 +184,17 @@ main(int argc, char *argv[])
Xflag++;
break;
case 'a':
if ((maxcontig = atoi(optarg)) <= 0)
rval = parselength(optarg, &maxcontig);
if (rval < 0 || maxcontig <= 0)
errx(1, "%s: bad maximum contiguous blocks",
optarg);
break;
case 'b':
if ((bsize = atoi(optarg)) < MINBSIZE)
rval = parselength(optarg, &bsize);
if (rval < 0)
errx(1, "%s: bad block size",
optarg);
if (bsize < MINBSIZE)
errx(1, "%s: block size too small, min is %d",
optarg, MINBSIZE);
if (bsize > MAXBSIZE)
@ -195,33 +202,40 @@ main(int argc, char *argv[])
optarg, MAXBSIZE);
break;
case 'c':
if ((maxblkspercg = atoi(optarg)) <= 0)
rval = parselength(optarg, &maxblkspercg);
if (rval < 0 || maxblkspercg <= 0)
errx(1, "%s: bad blocks per cylinder group",
optarg);
break;
case 'd':
if ((maxbsize = atoi(optarg)) < MINBSIZE)
rval = parselength(optarg, &maxbsize);
if (rval < 0 || maxbsize < MINBSIZE)
errx(1, "%s: bad extent block size", optarg);
break;
case 'e':
if ((maxbpg = atoi(optarg)) <= 0)
rval = parselength(optarg, &maxbpg);
if (rval < 0 || maxbpg <= 0)
errx(1, "%s: bad blocks per file in a cylinder group",
optarg);
break;
case 'f':
if ((fsize = atoi(optarg)) <= 0)
rval = parselength(optarg, &fsize);
if (rval < 0 || fsize <= 0)
errx(1, "%s: bad fragment size", optarg);
break;
case 'g':
if ((avgfilesize = atoi(optarg)) <= 0)
rval = parselength(optarg, &avgfilesize);
if (rval < 0 || avgfilesize <= 0)
errx(1, "%s: bad average file size", optarg);
break;
case 'h':
if ((avgfilesperdir = atoi(optarg)) <= 0)
rval = parselength(optarg, &avgfilesperdir);
if (rval < 0 || avgfilesperdir <= 0)
errx(1, "%s: bad average files per dir", optarg);
break;
case 'i':
if ((density = atoi(optarg)) <= 0)
rval = parselength(optarg, &density);
if (rval < 0 || density <= 0)
errx(1, "%s: bad bytes per inode", optarg);
break;
case 'l':
@ -481,3 +495,62 @@ usage()
fprintf(stderr, "\t-s file system size (sectors)\n");
exit(1);
}
/*
* Return the numeric value of a string given in the form [+-][0-9]+[GMKT]
* or -1 on format error or overflow.
*/
static int
parselength(const char *ls, int *sz)
{
off_t length, oflow;
int lsign;
length = 0;
lsign = 1;
switch (*ls) {
case '-':
lsign = -1;
case '+':
ls++;
}
#define ASSIGN_CHK_OFLOW(x, y) if (x < y) return -1; y = x
/*
* Calculate the value of the decimal digit string, failing
* on overflow.
*/
while (isdigit(*ls)) {
oflow = length * 10 + *ls++ - '0';
ASSIGN_CHK_OFLOW(oflow, length);
}
switch (*ls) {
case 'T':
case 't':
oflow = length * 1024;
ASSIGN_CHK_OFLOW(oflow, length);
case 'G':
case 'g':
oflow = length * 1024;
ASSIGN_CHK_OFLOW(oflow, length);
case 'M':
case 'm':
oflow = length * 1024;
ASSIGN_CHK_OFLOW(oflow, length);
case 'K':
case 'k':
if (ls[1] != '\0')
return -1;
oflow = length * 1024;
ASSIGN_CHK_OFLOW(oflow, length);
case '\0':
break;
default:
return -1;
}
*sz = length * lsign;
return 0;
}