-#define FMT_AUTO 0
-#define FMT_LONG 1 /* one record per line, extended info */
-#define FMT_SINGLE 2 /* one record per line */
-#define FMT_ROWS 3 /* print across rows */
-#define FMT_COLUMNS 3 /* fill columns (same, since we don't sort) */
-
-#define TIME_MOD 0
-#define TIME_CHANGE 1
-#define TIME_ACCESS 2
-
-#define DISP_FTYPE 1 /* show character for file type */
-#define DISP_EXEC 2 /* show '*' if regular executable file */
-#define DISP_HIDDEN 4 /* show files starting . (except . and ..) */
-#define DISP_DOT 8 /* show . and .. */
-#define DISP_NUMERIC 16 /* numeric uid and gid */
-#define DISP_FULLTIME 32 /* show extended time display */
-#define DIR_NOLIST 64 /* show directory as itself, not contents */
-#define DISP_DIRNAME 128 /* show directory name (for internal use) */
-#define DIR_RECURSE 256 /* -R (not yet implemented) */
-
-static unsigned char display_fmt = FMT_AUTO;
-static unsigned short opts = 0;
-static unsigned short column = 0;
-
-#ifdef FEATURE_AUTOWIDTH
-static unsigned short terminal_width = 0, column_width = 0;
-#else
-#define terminal_width TERMINAL_WIDTH
-#define column_width COLUMN_WIDTH
+/* what is the overall style of the listing */
+enum {
+ STYLE_AUTO = 0,
+ STYLE_LONG = 1, /* one record per line, extended info */
+ STYLE_SINGLE = 2, /* one record per line */
+ STYLE_COLUMNS = 3 /* fill columns */
+};
+
+/* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */
+/* what file information will be listed */
+#define LIST_INO (1<<0)
+#define LIST_BLOCKS (1<<1)
+#define LIST_MODEBITS (1<<2)
+#define LIST_NLINKS (1<<3)
+#define LIST_ID_NAME (1<<4)
+#define LIST_ID_NUMERIC (1<<5)
+#define LIST_SIZE (1<<6)
+#define LIST_DEV (1<<7)
+#define LIST_DATE_TIME (1<<8)
+#define LIST_FULLTIME (1<<9)
+#define LIST_FILENAME (1<<10)
+#define LIST_SYMLINK (1<<11)
+#define LIST_FILETYPE (1<<12)
+#define LIST_EXEC (1<<13)
+
+/* what files will be displayed */
+#define DISP_NORMAL (0) /* show normal filenames */
+#define DISP_DIRNAME (1<<0) /* 2 or more items? label directories */
+#define DISP_HIDDEN (1<<1) /* show filenames starting with . */
+#define DISP_DOT (1<<2) /* show . and .. */
+#define DISP_NOLIST (1<<3) /* show directory as itself, not contents */
+#define DISP_RECURSIVE (1<<4) /* show directory and everything below it */
+#define DISP_ROWS (1<<5) /* print across rows */
+
+#ifdef CONFIG_FEATURE_LS_SORTFILES
+/* how will the files be sorted */
+static const int SORT_FORWARD = 0; /* sort in reverse order */
+static const int SORT_REVERSE = 1; /* sort in reverse order */
+static const int SORT_NAME = 2; /* sort by file name */
+static const int SORT_SIZE = 3; /* sort by file size */
+static const int SORT_ATIME = 4; /* sort by last access time */
+static const int SORT_CTIME = 5; /* sort by last change time */
+static const int SORT_MTIME = 6; /* sort by last modification time */
+static const int SORT_VERSION = 7; /* sort by version */
+static const int SORT_EXT = 8; /* sort by file name extension */
+static const int SORT_DIR = 9; /* sort by file or directory */
+#endif
+
+#ifdef CONFIG_FEATURE_LS_TIMESTAMPS
+/* which of the three times will be used */
+static const int TIME_MOD = 0;
+static const int TIME_CHANGE = 1;
+static const int TIME_ACCESS = 2;
+#endif
+
+#define LIST_SHORT (LIST_FILENAME)
+#define LIST_ISHORT (LIST_INO | LIST_FILENAME)
+#define LIST_LONG (LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \
+ LIST_DATE_TIME | LIST_FILENAME | LIST_SYMLINK)
+#define LIST_ILONG (LIST_INO | LIST_LONG)
+
+static const int SPLIT_DIR = 0;
+static const int SPLIT_FILE = 1;
+static const int SPLIT_SUBDIR = 2;
+
+#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f)
+#define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)])
+
+#if defined(CONFIG_FEATURE_LS_FILETYPES) || defined(CONFIG_FEATURE_LS_COLOR)
+# define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)])
+#endif
+
+/* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */
+#ifdef CONFIG_FEATURE_LS_COLOR
+static int show_color = 0;
+
+#define COLOR(mode) ("\000\043\043\043\042\000\043\043"\
+ "\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)])
+#endif
+
+/*
+ * a directory entry and its stat info are stored here
+ */
+struct dnode { /* the basic node */
+ char *name; /* the dir entry name */
+ char *fullname; /* the dir entry name */
+ struct stat dstat; /* the file stat info */
+ struct dnode *next; /* point at the next node */
+};
+typedef struct dnode dnode_t;
+
+static struct dnode **list_dir(const char *);
+static struct dnode **dnalloc(int);
+static int list_single(struct dnode *);
+
+static unsigned int disp_opts;
+static unsigned int style_fmt;
+static unsigned int list_fmt;
+
+#ifdef CONFIG_FEATURE_LS_SORTFILES
+static unsigned int sort_opts;
+static unsigned int sort_order;
+#endif
+#ifdef CONFIG_FEATURE_LS_TIMESTAMPS
+static unsigned int time_fmt;
+#endif
+#ifdef CONFIG_FEATURE_LS_FOLLOWLINKS
+static unsigned int follow_links = FALSE;