- usage fresh bb_getopt_ulflags for ls -- very size reduce.
- small indent corrections
- remove unecessary malloc and free
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 75d7b1f..ac2557a 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -83,15 +83,15 @@
 
 /* 51306 lrwxrwxrwx  1 root     root         2 May 11 01:43 /bin/view -> vi* */
 /* what file information will be listed */
-#define LIST_INO		(1U<<0)
-#define LIST_BLOCKS		(1U<<1)
+#define LIST_INO	(1U<<0)
+#define LIST_BLOCKS	(1U<<1)
 #define LIST_MODEBITS	(1U<<2)
-#define LIST_NLINKS		(1U<<3)
+#define LIST_NLINKS	(1U<<3)
 #define LIST_ID_NAME	(1U<<4)
 #define LIST_ID_NUMERIC	(1U<<5)
 #define LIST_CONTEXT	(1U<<6)
-#define LIST_SIZE		(1U<<7)
-#define LIST_DEV		(1U<<8)
+#define LIST_SIZE	(1U<<7)
+#define LIST_DEV	(1U<<8)
 #define LIST_DATE_TIME	(1U<<9)
 #define LIST_FULLTIME	(1U<<10)
 #define LIST_FILENAME	(1U<<11)
@@ -103,22 +103,22 @@
 
 /* what files will be displayed */
 /* TODO -- We may be able to make DISP_NORMAL 0 to save a bit slot. */
-#define DISP_NORMAL		(1U<<14)	/* show normal filenames */
+#define DISP_NORMAL	(1U<<14)	/* show normal filenames */
 #define DISP_DIRNAME	(1U<<15)	/* 2 or more items? label directories */
-#define DISP_HIDDEN		(1U<<16)	/* show filenames starting with .  */
-#define DISP_DOT		(1U<<17)	/* show . and .. */
-#define DISP_NOLIST		(1U<<18)	/* show directory as itself, not contents */
+#define DISP_HIDDEN	(1U<<16)	/* show filenames starting with .  */
+#define DISP_DOT	(1U<<17)	/* show . and .. */
+#define DISP_NOLIST	(1U<<18)	/* show directory as itself, not contents */
 #define DISP_RECURSIVE	(1U<<19)	/* show directory and everything below it */
-#define DISP_ROWS		(1U<<20)	/* print across rows */
+#define DISP_ROWS	(1U<<20)	/* print across rows */
 
 #define DISP_MASK       (((DISP_ROWS << 1) - 1) & ~(DISP_NORMAL - 1))
 
 #ifdef CONFIG_FEATURE_LS_SORTFILES
 /* how will the files be sorted */
-#define SORT_ORDER_FORWARD   0			/* sort in reverse order */
+#define SORT_ORDER_FORWARD   0		/* sort in reverse order */
 #define SORT_ORDER_REVERSE   (1U<<27)	/* sort in reverse order */
 
-#define SORT_NAME      0			/* sort by file name */
+#define SORT_NAME      0		/* sort by file name */
 #define SORT_SIZE      (1U<<28)		/* sort by file size */
 #define SORT_ATIME     (2U<<28)		/* sort by last access time */
 #define SORT_CTIME     (3U<<28)		/* sort by last change time */
@@ -170,25 +170,25 @@
 
 /* long option entry used only for --color, which has no short option
  * equivalent.  */
-static int got_color_opt;
 static struct option ls_color_opt[] =
 {
-        {"color", optional_argument, &got_color_opt, 1},
+	{"color", optional_argument, NULL, 1},
         {NULL, 0, NULL, 0}
 };
 
 #define COLOR(mode)	("\000\043\043\043\042\000\043\043"\
-					"\000\000\044\000\043\000\000\040" [TYPEINDEX(mode)])
+			 "\000\000\044\000\043\000\000\040" [TYPEINDEX(mode)])
 #define ATTR(mode)	("\00\00\01\00\01\00\01\00"\
-					"\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)])
+			 "\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)])
 #endif
 
 /*
  * a directory entry and its stat info are stored here
  */
 struct dnode {			/* the basic node */
-	char *name;			/* the dir entry name */
+	char *name;		/* the dir entry name */
 	char *fullname;		/* the dir entry name */
+	int   allocated;
 	struct stat dstat;	/* the file stat info */
 #ifdef CONFIG_SELINUX
 	security_context_t sid;
@@ -235,8 +235,7 @@
 		}
 #endif
 		  rc = stat(fullname, &dstat);
-		if(rc)
-		{
+		if(rc) {
 			bb_perror_msg("%s", fullname);
 			status = EXIT_FAILURE;
 			return 0;
@@ -251,8 +250,7 @@
 		}
 #endif
 		rc = lstat(fullname, &dstat);
-		if(rc)
-		{
+		if(rc) {
 			bb_perror_msg("%s", fullname);
 			status = EXIT_FAILURE;
 			return 0;
@@ -320,11 +318,10 @@
 	dirs = 0;
 	for (i = 0; i < nfiles; i++) {
 		if (S_ISDIR(dn[i]->dstat.st_mode)
-			&& (notsubdirs
-				|| ((dn[i]->name[0] != '.')
-					|| (dn[i]->name[1]
+			&& (notsubdirs || 
+			((dn[i]->name[0] != '.') || (dn[i]->name[1]
 						&& ((dn[i]->name[1] != '.')
-							|| dn[i]->name[2])))))
+						|| dn[i]->name[2])))))
 			dirs++;
 	}
 	return (dirs);
@@ -352,8 +349,7 @@
 	if (num < 1)
 		return (NULL);
 
-	p = (struct dnode **) xcalloc((size_t) num,
-								  (size_t) (sizeof(struct dnode *)));
+	p = (struct dnode **) xcalloc((size_t) num, (size_t) (sizeof(struct dnode *)));
 	return (p);
 }
 
@@ -367,7 +363,8 @@
 
 	cur = dnp[0];
 	while (cur != NULL) {
-		free(cur->fullname);	/* free the filename */
+		if(cur->allocated)
+			free(cur->fullname);	/* free the filename */
 		next = cur->next;
 		free(cur);		/* free the dnode */
 		cur = next;
@@ -622,6 +619,7 @@
 		cur = my_stat(fullname, strrchr(fullname, '/') + 1);
 		if (!cur)
 			continue;
+		cur->allocated = 1;
 		cur->next = dn;
 		dn = cur;
 		nfiles++;
@@ -756,7 +754,7 @@
 				  safe_strncpy(context, dn->sid, len);
 				  freecon(dn->sid);
 				}else {
-				  safe_strncpy(context, "unknown",8);
+				  safe_strncpy(context, "unknown", 8);
 				}
 				printf("%-32s ", context);
 				column += MAX(33, len);
@@ -952,6 +950,9 @@
 #ifdef CONFIG_SELINUX
 	LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */
 #endif
+#ifdef CONFIG_FEATURE_AUTOWIDTH
+       0, 0,                    /* T, w - ignored */
+#endif
 	(1U<<31)
 };
 
@@ -977,6 +978,9 @@
 	char *tabstops_str = NULL;
 	char *terminal_width_str = NULL;
 #endif
+#ifdef CONFIG_FEATURE_LS_COLOR
+	char *color_opt;
+#endif
 
 	all_fmt = LIST_SHORT | DISP_NORMAL | STYLE_AUTO
 #ifdef CONFIG_FEATURE_LS_TIMESTAMPS
@@ -1000,7 +1004,11 @@
 
 	/* process options */
 #ifdef CONFIG_FEATURE_AUTOWIDTH
-	opt = bb_getopt_ulflags(argc, argv, ls_options, &tabstops_str, &terminal_width_str);
+	opt = bb_getopt_ulflags(argc, argv, ls_options, &tabstops_str, &terminal_width_str
+#ifdef CONFIG_FEATURE_LS_COLOR
+		, &color_opt
+#endif
+		);
 	if (tabstops_str) {
 		tabstops = atoi(tabstops_str);
 	}
@@ -1008,11 +1016,16 @@
 		terminal_width = atoi(terminal_width_str);
 	}
 #else
-	opt = bb_getopt_ulflags(argc, argv, ls_options);
+	opt = bb_getopt_ulflags(argc, argv, ls_options
+#ifdef CONFIG_FEATURE_LS_COLOR
+		, &color_opt
+#endif
+		);
 #endif
 	for (i = 0; opt_flags[i] != (1U<<31); i++) {
 		if (opt & (1 << i)) {
 			unsigned int flags = opt_flags[i];
+			
 			if (flags & LIST_MASK_TRIGGER) {
 				all_fmt &= ~LIST_MASK;
 			}
@@ -1045,51 +1058,28 @@
 	}
 
 #ifdef CONFIG_FEATURE_LS_COLOR
-	if (got_color_opt) {
-		/* there is no way for bb_getopt_ulflags() to
-		 * return us the argument string for long options
-		 * which don't have a short option equivalent.
-		 * all we can find out is that the option was
-		 * present, and we have to rescan to find the
-		 * argument string.
-		 */
-		got_color_opt=0;
-		optind = 1;
-		while ((i = getopt_long (argc, argv, ls_options,
-			    ls_color_opt, NULL)) >= 0) {
-			if (i != 0) continue;
-			if (got_color_opt) {
-				if (!optarg || strcmp("always", optarg) == 0)
-					show_color = 1;
-				else if (strcmp("never", optarg) == 0)
-					show_color = 0;
-				else if (strcmp("auto", optarg) == 0 &&
-						isatty(STDOUT_FILENO))
-					show_color = 1;
+	{
+		/* find color bit value - last position for short getopt */
 
-				/* don't break; want to a) pick up repeated
-				 * --color options, and b) leave optind
-				 * set correctly when we're done.
-				 */
-				got_color_opt = 0;
-			}
-		}
 #if CONFIG_FEATURE_LS_COLOR_IS_DEFAULT
-	} else {
-		/* if no option set by user, then this config option
-		 * forces "auto", which is what busybox 1.00 and previous
-		 * did.  however, provide one more "out" for users that
-		 * don't want color:  if LS_COLOR is set, and is null or
-		 * "none" -- then default coloring to "off".
-		 */
 		char *p;
+
 		if ((p = getenv ("LS_COLORS")) != NULL && 
 			(*p == '\0' || (strcmp(p, "none") == 0))) {
-		    	show_color = 0;
+			;
 		} else if (isatty(STDOUT_FILENO)) {
 		    	show_color = 1;
 		}
 #endif
+
+		if((opt & (1 << i))) {  /* next flag after short options */
+			if (color_opt == NULL || strcmp("always", color_opt) == 0)
+				show_color = 1;
+			else if (color_opt != NULL && strcmp("never", color_opt) == 0)
+				show_color = 0;
+			else if (color_opt != NULL && strcmp("auto", color_opt) == 0 && isatty(STDOUT_FILENO))
+				show_color = 1;
+		}
 	}
 #endif
 
@@ -1129,14 +1119,12 @@
 	 */
 	ac = argc - optind;	/* how many cmd line args are left */
 	if (ac < 1) {
-		av = (char **) xcalloc((size_t) 1, (size_t) (sizeof(char *)));
-		av[0] = bb_xstrdup(".");
+		static const char * const dotdir[] = { "." };
+
+		av = (char **) dotdir;
 		ac = 1;
 	} else {
-		av = (char **) xcalloc((size_t) ac, (size_t) (sizeof(char *)));
-		for (oi = 0; oi < ac; oi++) {
-			av[oi] = argv[optind++];	/* copy pointer to real cmd line arg */
-		}
+		av = argv + optind;
 	}
 
 	/* now, everything is in the av array */
@@ -1146,11 +1134,10 @@
 	/* stuff the command line file names into an dnode array */
 	dn = NULL;
 	for (oi = 0; oi < ac; oi++) {
-		char *fullname = bb_xstrdup(av[oi]);
-
-		cur = my_stat(fullname, fullname);
+		cur = my_stat(av[oi], av[oi]);
 		if (!cur)
 			continue;
+		cur->allocated = 0;
 		cur->next = dn;
 		dn = cur;
 		nfiles++;