Subject: bin/36827: makefs arg order matters
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <prlw1@cam.ac.uk>
List: netbsd-bugs
Date: 08/24/2007 10:40:00
>Number:         36827
>Category:       bin
>Synopsis:       Order of -t and -o arguments matters to makefs
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Aug 24 10:40:00 +0000 2007
>Originator:     Patrick Welche
>Release:        NetBSD 4.99.29
>Organization:
	
>Environment:
NetBSD-current/i386 but shouldn't matter
>Description:
From makefs(8)

     makefs [-x] [-B byte-order] [-b free-blocks] [-d debug-mask]
            [-F specfile] [-f free-files] [-M minimum-size] [-m maximum-size]
            [-N userdb-dir] [-o fs-options] [-S sector-size] [-s image-size]
            [-t fs-type] image-file directory

So if you follow the above and fill in the arguments, you might do

% makefs -o rockridge -t cd9660 cd1.fs cd1
makefs: Option `rockridge' doesn't contain a value
usage: makefs [-t fs-type] [-o fs-options] [-d debug-mask] [-B endian]
        [-S sector-size] [-M minimum-size] [-m maximum-size] [-s image-size]
        [-b free-blocks] [-f free-files] [-F mtree-specfile] [-x]
        [-N userdb-dir] image-file directory

If you set a breakpoint in cd9660_parse_opts, you will be surprised that it
doesn't get called.

Reversing the order of the arguments

% makefs -t cd9660 -o rockridge cd1.fs cd1

works as expected.
>How-To-Repeat:
	
>Fix:
Index: makefs.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/makefs/makefs.c,v
retrieving revision 1.26
diff -u -r1.26 makefs.c
--- makefs.c	22 Oct 2006 21:11:56 -0000	1.26
+++ makefs.c	24 Aug 2007 10:34:04 -0000
@@ -91,7 +91,7 @@
 	fsinfo_t	 fsoptions;
 	fsnode		*root;
 	int	 	 ch, len;
-	char		*specfile;
+	char		*specfile, *fsoptions_str=NULL;
 
 	setprogname(argv[0]);
 
@@ -190,17 +190,8 @@
 			break;
 			
 		case 'o':
-		{
-			char *p;
-
-			while ((p = strsep(&optarg, ",")) != NULL) {
-				if (*p == '\0')
-					errx(1, "Empty option");
-				if (! fstype->parse_options(p, &fsoptions))
-					usage();
-			}
+			fsoptions_str = optarg;
 			break;
-		}
 
 		case 's':
 			fsoptions.minsize = fsoptions.maxsize =
@@ -234,17 +225,29 @@
 
 		}
 	}
+	argc -= optind;
+	argv += optind;
+
+	if (argc != 2)
+		usage();
+
+	if (fsoptions_str != NULL) {
+		char *p;
+
+		while ((p = strsep(&fsoptions_str, ",")) != NULL) {
+			if (*p == '\0')
+				errx(1, "Empty option");
+			if (! fstype->parse_options(p, &fsoptions))
+				usage();
+		}
+	}
+
 	if (debug) {
 		printf("debug mask: 0x%08x\n", debug);
 		printf("start time: %ld.%ld, %s",
 		    (long)start_time.tv_sec, (long)start_time.tv_nsec,
 		    ctime(&start_time.tv_sec));
 	}
-	argc -= optind;
-	argv += optind;
-
-	if (argc != 2)
-		usage();
 
 	/* -x must be accompanied by -F */
 	if (fsoptions.onlyspec != 0 && specfile == NULL)

>Unformatted: