(LOGIN_NAME_MAX): Define if not already defined.
[platform/upstream/coreutils.git] / src / ls.c
1 /* `dir', `vdir' and `ls' directory listing programs for GNU.
2    Copyright (C) 85, 88, 90, 91, 1995-2002 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 /* If ls_mode is LS_MULTI_COL,
19    the multi-column format is the default regardless
20    of the type of output device.
21    This is for the `dir' program.
22
23    If ls_mode is LS_LONG_FORMAT,
24    the long format is the default regardless of the
25    type of output device.
26    This is for the `vdir' program.
27
28    If ls_mode is LS_LS,
29    the output format depends on whether the output
30    device is a terminal.
31    This is for the `ls' program. */
32
33 /* Written by Richard Stallman and David MacKenzie.  */
34
35 /* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
36    Flaherty <dennisf@denix.elk.miles.com> based on original patches by
37    Greg Lee <lee@uhunix.uhcc.hawaii.edu>.  */
38
39 #ifdef _AIX
40  #pragma alloca
41 #endif
42
43 #include <config.h>
44 #include <sys/types.h>
45
46 #if HAVE_INTTYPES_H
47 # include <inttypes.h>
48 #endif
49
50 #if HAVE_TERMIOS_H
51 # include <termios.h>
52 #endif
53
54 #ifdef GWINSZ_IN_SYS_IOCTL
55 # include <sys/ioctl.h>
56 #endif
57
58 #ifdef WINSIZE_IN_PTEM
59 # include <sys/stream.h>
60 # include <sys/ptem.h>
61 #endif
62
63 #include <stdio.h>
64 #include <assert.h>
65 #include <setjmp.h>
66 #include <grp.h>
67 #include <pwd.h>
68 #include <getopt.h>
69
70 /* Get MB_CUR_MAX.  */
71 #if HAVE_STDLIB_H
72 # include <stdlib.h>
73 #endif
74
75 /* Get mbstate_t, mbrtowc(), mbsinit(), wcwidth().  */
76 #if HAVE_WCHAR_H
77 # include <wchar.h>
78 #endif
79
80 /* Get iswprint().  */
81 #if HAVE_WCTYPE_H
82 # include <wctype.h>
83 #endif
84 #if !defined iswprint && !HAVE_ISWPRINT
85 # define iswprint(wc) 1
86 #endif
87
88 #ifndef HAVE_DECL_WCWIDTH
89 "this configure-time declaration test was not run"
90 #endif
91 #if !HAVE_DECL_WCWIDTH
92 int wcwidth ();
93 #endif
94
95 /* If wcwidth() doesn't exist, assume all printable characters have
96    width 1.  */
97 #ifndef wcwidth
98 # if !HAVE_WCWIDTH
99 #  define wcwidth(wc) ((wc) == 0 ? 0 : iswprint (wc) ? 1 : -1)
100 # endif
101 #endif
102
103 #include "system.h"
104 #include <fnmatch.h>
105
106 #include "acl.h"
107 #include "argmatch.h"
108 #include "dirname.h"
109 #include "dirfd.h"
110 #include "error.h"
111 #include "hard-locale.h"
112 #include "hash.h"
113 #include "human.h"
114 #include "filemode.h"
115 #include "ls.h"
116 #include "mbswidth.h"
117 #include "obstack.h"
118 #include "path-concat.h"
119 #include "quote.h"
120 #include "quotearg.h"
121 #include "same.h"
122 #include "strverscmp.h"
123 #include "xstrtol.h"
124 #include "xreadlink.h"
125
126 #define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \
127                       : (ls_mode == LS_MULTI_COL \
128                          ? "dir" : "vdir"))
129
130 #define AUTHORS N_ ("Richard Stallman and David MacKenzie")
131
132 #define obstack_chunk_alloc malloc
133 #define obstack_chunk_free free
134
135 /* Return an int indicating the result of comparing two integers.
136    Subtracting doesn't always work, due to overflow.  */
137 #define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b))
138
139 /* The field width for inode numbers.  On some hosts inode numbers are
140    64 bits, so columns won't line up exactly when a huge inode number
141    is encountered, but in practice 7 digits is usually enough.  */
142 #ifndef INODE_DIGITS
143 # define INODE_DIGITS 7
144 #endif
145
146 #ifdef S_ISLNK
147 # define HAVE_SYMLINKS 1
148 #else
149 # define HAVE_SYMLINKS 0
150 #endif
151
152 /* Arrange to make lstat calls go through the wrapper function
153    on systems with an lstat function that does not dereference symlinks
154    that are specified with a trailing slash.  */
155 #if ! LSTAT_FOLLOWS_SLASHED_SYMLINK
156 int rpl_lstat PARAMS((const char *, struct stat *));
157 # undef lstat
158 # define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
159 #endif
160
161 #if HAVE_STRUCT_DIRENT_D_TYPE && defined DTTOIF
162 # define DT_INIT(Val) = Val
163 #else
164 # define DT_INIT(Val) /* empty */
165 #endif
166
167 #ifdef ST_MTIM_NSEC
168 # define TIMESPEC_NS(timespec) ((timespec).ST_MTIM_NSEC)
169 #else
170 # define TIMESPEC_NS(timespec) 0
171 #endif
172
173 #if ! HAVE_STRUCT_STAT_ST_AUTHOR
174 # define st_author st_uid
175 #endif
176
177 /* Cray/Unicos DMF: use the file's migrated, not real, status */
178 #if HAVE_ST_DM_MODE
179 # define ST_DM_MODE(Stat_buf) ((Stat_buf).st_dm_mode)
180 #else
181 # define ST_DM_MODE(Stat_buf) ((Stat_buf).st_mode)
182 #endif
183
184 #ifndef LOGIN_NAME_MAX
185 # if _POSIX_LOGIN_NAME_MAX
186 #  define LOGIN_NAME_MAX _POSIX_LOGIN_NAME_MAX
187 # else
188 #  define LOGIN_NAME_MAX 17
189 # endif
190 #endif
191
192 /* The maximum length of a string representation of a user or group ID,
193    not counting any terminating NUL byte.  */
194 #define ID_LENGTH_MAX \
195   MAX (LOGIN_NAME_MAX - 1, LONGEST_HUMAN_READABLE)
196
197 enum filetype
198   {
199     unknown DT_INIT (DT_UNKNOWN),
200     fifo DT_INIT (DT_FIFO),
201     chardev DT_INIT (DT_CHR),
202     directory DT_INIT (DT_DIR),
203     blockdev DT_INIT (DT_BLK),
204     normal DT_INIT (DT_REG),
205     symbolic_link DT_INIT (DT_LNK),
206     sock DT_INIT (DT_SOCK),
207     arg_directory DT_INIT (2 * (DT_UNKNOWN | DT_FIFO | DT_CHR | DT_DIR | DT_BLK
208                                 | DT_REG | DT_LNK | DT_SOCK))
209   };
210
211 struct fileinfo
212   {
213     /* The file name. */
214     char *name;
215
216     struct stat stat;
217
218     /* For symbolic link, name of the file linked to, otherwise zero. */
219     char *linkname;
220
221     /* For symbolic link and long listing, st_mode of file linked to, otherwise
222        zero. */
223     mode_t linkmode;
224
225     /* For symbolic link and color printing, 1 if linked-to file
226        exists, otherwise 0.  */
227     int linkok;
228
229     enum filetype filetype;
230
231 #if HAVE_ACL
232     /* For long listings, true if the file has an access control list.  */
233     bool have_acl;
234 #endif
235   };
236
237 #if HAVE_ACL
238 # define FILE_HAS_ACL(F) ((F)->have_acl)
239 #else
240 # define FILE_HAS_ACL(F) 0
241 #endif
242
243 #define LEN_STR_PAIR(s) sizeof (s) - 1, s
244
245 /* Null is a valid character in a color indicator (think about Epson
246    printers, for example) so we have to use a length/buffer string
247    type.  */
248
249 struct bin_str
250   {
251     int len;                    /* Number of bytes */
252     const char *string;         /* Pointer to the same */
253   };
254
255 #ifndef STDC_HEADERS
256 time_t time ();
257 #endif
258
259 size_t nstrftime PARAMS ((char *, size_t, char const *,
260                           struct tm const *, int, int));
261 char *getgroup ();
262 char *getuser ();
263
264 static size_t quote_name PARAMS ((FILE *out, const char *name,
265                                   struct quoting_options const *options));
266 static char *make_link_path PARAMS ((const char *path, const char *linkname));
267 static int decode_switches PARAMS ((int argc, char **argv));
268 static int file_interesting PARAMS ((const struct dirent *next));
269 static uintmax_t gobble_file PARAMS ((const char *name, enum filetype type,
270                                       int explicit_arg, const char *dirname));
271 static void print_color_indicator PARAMS ((const char *name, mode_t mode,
272                                            int linkok));
273 static void put_indicator PARAMS ((const struct bin_str *ind));
274 static int length_of_file_name_and_frills PARAMS ((const struct fileinfo *f));
275 static void add_ignore_pattern PARAMS ((const char *pattern));
276 static void attach PARAMS ((char *dest, const char *dirname, const char *name));
277 static void clear_files PARAMS ((void));
278 static void extract_dirs_from_files PARAMS ((const char *dirname,
279                                              int ignore_dot_and_dot_dot));
280 static void get_link_name PARAMS ((const char *filename, struct fileinfo *f));
281 static void indent PARAMS ((int from, int to));
282 static void init_column_info PARAMS ((void));
283 static void print_current_files PARAMS ((void));
284 static void print_dir PARAMS ((const char *name, const char *realname));
285 static void print_file_name_and_frills PARAMS ((const struct fileinfo *f));
286 static void print_horizontal PARAMS ((void));
287 static void print_long_format PARAMS ((const struct fileinfo *f));
288 static void print_many_per_line PARAMS ((void));
289 static void print_name_with_quoting PARAMS ((const char *p, mode_t mode,
290                                              int linkok,
291                                              struct obstack *stack));
292 static void prep_non_filename_text PARAMS ((void));
293 static void print_type_indicator PARAMS ((mode_t mode));
294 static void print_with_commas PARAMS ((void));
295 static void queue_directory PARAMS ((const char *name, const char *realname));
296 static void sort_files PARAMS ((void));
297 static void parse_ls_color PARAMS ((void));
298 void usage PARAMS ((int status));
299
300 /* The name the program was run with, stripped of any leading path. */
301 char *program_name;
302
303 /* Initial size of hash table.
304    Most hierarchies are likely to be shallower than this.  */
305 #define INITIAL_TABLE_SIZE 30
306
307 /* The set of `active' directories, from the current command-line argument
308    to the level in the hierarchy at which files are being listed.
309    A directory is represented by its device and inode numbers.
310    A directory is added to this set when ls begins listing it or its
311    entries, and it is removed from the set just after ls has finished
312    processing it.  This set is used solely to detect loops, e.g., with
313    mkdir loop; cd loop; ln -s ../loop sub; ls -RL  */
314 static Hash_table *active_dir_set;
315
316 #define LOOP_DETECT (!!active_dir_set)
317
318 /* An entry in the active_dir_set.  */
319 struct dev_ino
320 {
321   dev_t st_dev;
322   ino_t st_ino;
323 };
324
325 /* The table of files in the current directory:
326
327    `files' points to a vector of `struct fileinfo', one per file.
328    `nfiles' is the number of elements space has been allocated for.
329    `files_index' is the number actually in use.  */
330
331 /* Address of block containing the files that are described.  */
332 static struct fileinfo *files;  /* FIXME: rename this to e.g. cwd_file */
333
334 /* Length of block that `files' points to, measured in files.  */
335 static int nfiles;  /* FIXME: rename this to e.g. cwd_n_alloc */
336
337 /* Index of first unused in `files'.  */
338 static int files_index;  /* FIXME: rename this to e.g. cwd_n_used */
339
340 /* When nonzero, in a color listing, color each symlink name according to the
341    type of file it points to.  Otherwise, color them according to the `ln'
342    directive in LS_COLORS.  Dangling (orphan) symlinks are treated specially,
343    regardless.  This is set when `ln=target' appears in LS_COLORS.  */
344
345 static int color_symlink_as_referent;
346
347 /* mode of appropriate file for colorization */
348 #define FILE_OR_LINK_MODE(File) \
349     ((color_symlink_as_referent && (File)->linkok) \
350      ? (File)->linkmode : (File)->stat.st_mode)
351
352
353 /* Record of one pending directory waiting to be listed.  */
354
355 struct pending
356   {
357     char *name;
358     /* If the directory is actually the file pointed to by a symbolic link we
359        were told to list, `realname' will contain the name of the symbolic
360        link, otherwise zero. */
361     char *realname;
362     struct pending *next;
363   };
364
365 static struct pending *pending_dirs;
366
367 /* Current time in seconds and nanoseconds since 1970, updated as
368    needed when deciding whether a file is recent.  */
369
370 static time_t current_time = TYPE_MINIMUM (time_t);
371 static int current_time_ns = -1;
372
373 /* The number of digits to use for block sizes.
374    4, or more if needed for bigger numbers.  */
375
376 static int block_size_size;
377
378 /* Option flags */
379
380 /* long_format for lots of info, one per line.
381    one_per_line for just names, one per line.
382    many_per_line for just names, many per line, sorted vertically.
383    horizontal for just names, many per line, sorted horizontally.
384    with_commas for just names, many per line, separated by commas.
385
386    -l (and other options that imply -l), -1, -C, -x and -m control
387    this parameter.  */
388
389 enum format
390   {
391     long_format,                /* -l and other options that imply -l */
392     one_per_line,               /* -1 */
393     many_per_line,              /* -C */
394     horizontal,                 /* -x */
395     with_commas                 /* -m */
396   };
397
398 static enum format format;
399
400 /* `full-iso' uses full ISO-style dates and times.  `iso' uses shorter
401    ISO-style time stamps.  `locale' uses locale-dependent time stamps.
402    `posix-iso' uses traditional POSIX-locale-style dates where
403    POSIX requires it, ISO-style dates otherwise.  */
404 enum time_style
405   {
406     full_iso_time_style,        /* --time-style=full-iso */
407     iso_time_style,             /* --time-style=iso */
408     locale_time_style,          /* --time-style=locale */
409     posix_iso_time_style        /* --time-style=posix-iso (default) */
410   };
411
412 static char const *const time_style_args[] =
413 {
414   "full-iso", "iso", "locale", "posix-iso", 0
415 };
416
417 static enum time_style const time_style_types[] =
418 {
419   full_iso_time_style, iso_time_style,
420   locale_time_style, posix_iso_time_style, 0
421 };
422
423 /* Type of time to print or sort by.  Controlled by -c and -u.  */
424
425 enum time_type
426   {
427     time_mtime,                 /* default */
428     time_ctime,                 /* -c */
429     time_atime                  /* -u */
430   };
431
432 static enum time_type time_type;
433
434 /* The file characteristic to sort by.  Controlled by -t, -S, -U, -X, -v. */
435
436 enum sort_type
437   {
438     sort_none,                  /* -U */
439     sort_name,                  /* default */
440     sort_extension,             /* -X */
441     sort_time,                  /* -t */
442     sort_size,                  /* -S */
443     sort_version                /* -v */
444   };
445
446 static enum sort_type sort_type;
447
448 /* Direction of sort.
449    0 means highest first if numeric,
450    lowest first if alphabetic;
451    these are the defaults.
452    1 means the opposite order in each case.  -r  */
453
454 static int sort_reverse;
455
456 /* Nonzero means to display owner information.  -g turns this off.  */
457
458 static int print_owner = 1;
459
460 /* Nonzero means to display author information.  */
461
462 static bool print_author;
463
464 /* Nonzero means to display group information.  -G and -o turn this off.  */
465
466 static int print_group = 1;
467
468 /* Nonzero means print the user and group id's as numbers rather
469    than as names.  -n  */
470
471 static int numeric_ids;
472
473 /* Nonzero means mention the size in blocks of each file.  -s  */
474
475 static int print_block_size;
476
477 /* If positive, the units to use when printing sizes;
478    if negative, the human-readable base.  */
479 static int output_block_size;
480
481 /* Precede each line of long output (per file) with a string like `m,n:'
482    where M is the number of characters after the `:' and before the
483    filename and N is the length of the filename.  Using this format,
484    Emacs' dired mode starts up twice as fast, and can handle all
485    strange characters in file names.  */
486 static int dired;
487
488 /* `none' means don't mention the type of files.
489    `classify' means mention file types and mark executables.
490    `file_type' means mention only file types.
491
492    Controlled by -F, -p, and --indicator-style.  */
493
494 enum indicator_style
495   {
496     none,       /*     --indicator-style=none */
497     classify,   /* -F, --indicator-style=classify */
498     file_type   /* -p, --indicator-style=file-type */
499   };
500
501 static enum indicator_style indicator_style;
502
503 /* Names of indicator styles.  */
504 static char const *const indicator_style_args[] =
505 {
506   "none", "classify", "file-type", 0
507 };
508
509 static enum indicator_style const indicator_style_types[]=
510 {
511   none, classify, file_type
512 };
513
514 /* Nonzero means use colors to mark types.  Also define the different
515    colors as well as the stuff for the LS_COLORS environment variable.
516    The LS_COLORS variable is now in a termcap-like format.  */
517
518 static int print_with_color;
519
520 enum color_type
521   {
522     color_never,                /* 0: default or --color=never */
523     color_always,               /* 1: --color=always */
524     color_if_tty                /* 2: --color=tty */
525   };
526
527 enum Dereference_symlink
528   {
529     DEREF_UNDEFINED = 1,
530     DEREF_NEVER,
531     DEREF_COMMAND_LINE_ARGUMENTS,       /* -H */
532     DEREF_ALWAYS                        /* -L */
533   };
534
535 enum indicator_no
536   {
537     C_LEFT, C_RIGHT, C_END, C_NORM, C_FILE, C_DIR, C_LINK, C_FIFO, C_SOCK,
538     C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR
539   };
540
541 static const char *const indicator_name[]=
542   {
543     "lc", "rc", "ec", "no", "fi", "di", "ln", "pi", "so",
544     "bd", "cd", "mi", "or", "ex", "do", NULL
545   };
546
547 struct color_ext_type
548   {
549     struct bin_str ext;         /* The extension we're looking for */
550     struct bin_str seq;         /* The sequence to output when we do */
551     struct color_ext_type *next;        /* Next in list */
552   };
553
554 static struct bin_str color_indicator[] =
555   {
556     { LEN_STR_PAIR ("\033[") },         /* lc: Left of color sequence */
557     { LEN_STR_PAIR ("m") },             /* rc: Right of color sequence */
558     { 0, NULL },                        /* ec: End color (replaces lc+no+rc) */
559     { LEN_STR_PAIR ("0") },             /* no: Normal */
560     { LEN_STR_PAIR ("0") },             /* fi: File: default */
561     { LEN_STR_PAIR ("01;34") },         /* di: Directory: bright blue */
562     { LEN_STR_PAIR ("01;36") },         /* ln: Symlink: bright cyan */
563     { LEN_STR_PAIR ("33") },            /* pi: Pipe: yellow/brown */
564     { LEN_STR_PAIR ("01;35") },         /* so: Socket: bright magenta */
565     { LEN_STR_PAIR ("01;33") },         /* bd: Block device: bright yellow */
566     { LEN_STR_PAIR ("01;33") },         /* cd: Char device: bright yellow */
567     { 0, NULL },                        /* mi: Missing file: undefined */
568     { 0, NULL },                        /* or: Orphanned symlink: undefined */
569     { LEN_STR_PAIR ("01;32") },         /* ex: Executable: bright green */
570     { LEN_STR_PAIR ("01;35") }          /* do: Door: bright magenta */
571   };
572
573 /* FIXME: comment  */
574 static struct color_ext_type *color_ext_list = NULL;
575
576 /* Buffer for color sequences */
577 static char *color_buf;
578
579 /* Nonzero means to check for orphaned symbolic link, for displaying
580    colors.  */
581
582 static int check_symlink_color;
583
584 /* Nonzero means mention the inode number of each file.  -i  */
585
586 static int print_inode;
587
588 /* What to do with symbolic links.  Affected by -d, -F, -H, -l (and
589    other options that imply -l), and -L.  */
590
591 static enum Dereference_symlink dereference;
592
593 /* Nonzero means when a directory is found, display info on its
594    contents.  -R  */
595
596 static int recursive;
597
598 /* Nonzero means when an argument is a directory name, display info
599    on it itself.  -d  */
600
601 static int immediate_dirs;
602
603 /* Nonzero means don't omit files whose names start with `.'.  -A */
604
605 static int all_files;
606
607 /* Nonzero means don't omit files `.' and `..'
608    This flag implies `all_files'.  -a  */
609
610 static int really_all_files;
611
612 /* A linked list of shell-style globbing patterns.  If a non-argument
613    file name matches any of these patterns, it is omitted.
614    Controlled by -I.  Multiple -I options accumulate.
615    The -B option adds `*~' and `.*~' to this list.  */
616
617 struct ignore_pattern
618   {
619     const char *pattern;
620     struct ignore_pattern *next;
621   };
622
623 static struct ignore_pattern *ignore_patterns;
624
625 /* Nonzero means output nongraphic chars in file names as `?'.
626    (-q, --hide-control-chars)
627    qmark_funny_chars and the quoting style (-Q, --quoting-style=WORD) are
628    independent.  The algorithm is: first, obey the quoting style to get a
629    string representing the file name;  then, if qmark_funny_chars is set,
630    replace all nonprintable chars in that string with `?'.  It's necessary
631    to replace nonprintable chars even in quoted strings, because we don't
632    want to mess up the terminal if control chars get sent to it, and some
633    quoting methods pass through control chars as-is.  */
634 static int qmark_funny_chars;
635
636 /* Quoting options for file and dir name output.  */
637
638 static struct quoting_options *filename_quoting_options;
639 static struct quoting_options *dirname_quoting_options;
640
641 /* The number of chars per hardware tab stop.  Setting this to zero
642    inhibits the use of TAB characters for separating columns.  -T */
643 static int tabsize;
644
645 /* Nonzero means we are listing the working directory because no
646    non-option arguments were given. */
647
648 static int dir_defaulted;
649
650 /* Nonzero means print each directory name before listing it. */
651
652 static int print_dir_name;
653
654 /* The line length to use for breaking lines in many-per-line format.
655    Can be set with -w.  */
656
657 static int line_length;
658
659 /* If nonzero, the file listing format requires that stat be called on
660    each file. */
661
662 static int format_needs_stat;
663
664 /* Similar to `format_needs_stat', but set if only the file type is
665    needed.  */
666
667 static int format_needs_type;
668
669 /* strftime formats for non-recent and recent files, respectively, in
670    -l output.  */
671
672 static char const *long_time_format[2] =
673   {
674     /* strftime format for non-recent files (older than 6 months), in
675        -l output when --time-style=locale is specified.  This should
676        contain the year, month and day (at least), in an order that is
677        understood by people in your locale's territory.
678        Please try to keep the number of used screen columns small,
679        because many people work in windows with only 80 columns.  But
680        make this as wide as the other string below, for recent files.  */
681     N_("%b %e  %Y"),
682     /* strftime format for recent files (younger than 6 months), in
683        -l output when --time-style=locale is specified.  This should
684        contain the month, day and time (at least), in an order that is
685        understood by people in your locale's territory.
686        Please try to keep the number of used screen columns small,
687        because many people work in windows with only 80 columns.  But
688        make this as wide as the other string above, for non-recent files.  */
689     N_("%b %e %H:%M")
690   };
691
692 /* The exit status to use if we don't get any fatal errors. */
693
694 static int exit_status;
695
696 /* For long options that have no equivalent short option, use a
697    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
698 enum
699 {
700   AUTHOR_OPTION = CHAR_MAX + 1,
701   BLOCK_SIZE_OPTION,
702   COLOR_OPTION,
703   FORMAT_OPTION,
704   FULL_TIME_OPTION,
705   INDICATOR_STYLE_OPTION,
706   QUOTING_STYLE_OPTION,
707   SHOW_CONTROL_CHARS_OPTION,
708   SI_OPTION,
709   SORT_OPTION,
710   TIME_OPTION,
711   TIME_STYLE_OPTION
712 };
713
714 static struct option const long_options[] =
715 {
716   {"all", no_argument, 0, 'a'},
717   {"escape", no_argument, 0, 'b'},
718   {"directory", no_argument, 0, 'd'},
719   {"dired", no_argument, 0, 'D'},
720   {"full-time", no_argument, 0, FULL_TIME_OPTION},
721   {"human-readable", no_argument, 0, 'h'},
722   {"inode", no_argument, 0, 'i'},
723   {"kilobytes", no_argument, 0, 'k'}, /* long form is obsolescent */
724   {"numeric-uid-gid", no_argument, 0, 'n'},
725   {"no-group", no_argument, 0, 'G'},
726   {"hide-control-chars", no_argument, 0, 'q'},
727   {"reverse", no_argument, 0, 'r'},
728   {"size", no_argument, 0, 's'},
729   {"width", required_argument, 0, 'w'},
730   {"almost-all", no_argument, 0, 'A'},
731   {"ignore-backups", no_argument, 0, 'B'},
732   {"classify", no_argument, 0, 'F'},
733   {"file-type", no_argument, 0, 'p'},
734   {"si", no_argument, 0, SI_OPTION},
735   {"dereference-command-line", no_argument, 0, 'H'},
736   {"ignore", required_argument, 0, 'I'},
737   {"indicator-style", required_argument, 0, INDICATOR_STYLE_OPTION},
738   {"dereference", no_argument, 0, 'L'},
739   {"literal", no_argument, 0, 'N'},
740   {"quote-name", no_argument, 0, 'Q'},
741   {"quoting-style", required_argument, 0, QUOTING_STYLE_OPTION},
742   {"recursive", no_argument, 0, 'R'},
743   {"format", required_argument, 0, FORMAT_OPTION},
744   {"show-control-chars", no_argument, 0, SHOW_CONTROL_CHARS_OPTION},
745   {"sort", required_argument, 0, SORT_OPTION},
746   {"tabsize", required_argument, 0, 'T'},
747   {"time", required_argument, 0, TIME_OPTION},
748   {"time-style", required_argument, 0, TIME_STYLE_OPTION},
749   {"color", optional_argument, 0, COLOR_OPTION},
750   {"block-size", required_argument, 0, BLOCK_SIZE_OPTION},
751   {"author", no_argument, 0, AUTHOR_OPTION},
752   {GETOPT_HELP_OPTION_DECL},
753   {GETOPT_VERSION_OPTION_DECL},
754   {NULL, 0, NULL, 0}
755 };
756
757 static char const *const format_args[] =
758 {
759   "verbose", "long", "commas", "horizontal", "across",
760   "vertical", "single-column", 0
761 };
762
763 static enum format const format_types[] =
764 {
765   long_format, long_format, with_commas, horizontal, horizontal,
766   many_per_line, one_per_line
767 };
768
769 static char const *const sort_args[] =
770 {
771   "none", "time", "size", "extension", "version", 0
772 };
773
774 static enum sort_type const sort_types[] =
775 {
776   sort_none, sort_time, sort_size, sort_extension, sort_version
777 };
778
779 static char const *const time_args[] =
780 {
781   "atime", "access", "use", "ctime", "status", 0
782 };
783
784 static enum time_type const time_types[] =
785 {
786   time_atime, time_atime, time_atime, time_ctime, time_ctime
787 };
788
789 static char const *const color_args[] =
790 {
791   /* force and none are for compatibility with another color-ls version */
792   "always", "yes", "force",
793   "never", "no", "none",
794   "auto", "tty", "if-tty", 0
795 };
796
797 static enum color_type const color_types[] =
798 {
799   color_always, color_always, color_always,
800   color_never, color_never, color_never,
801   color_if_tty, color_if_tty, color_if_tty
802 };
803
804 /* Information about filling a column.  */
805 struct column_info
806 {
807   int valid_len;
808   int line_len;
809   int *col_arr;
810 };
811
812 /* Array with information about column filledness.  */
813 static struct column_info *column_info;
814
815 /* Maximum number of columns ever possible for this display.  */
816 static int max_idx;
817
818 /* The minimum width of a colum is 3: 1 character for the name and 2
819    for the separating white space.  */
820 #define MIN_COLUMN_WIDTH        3
821
822
823 /* This zero-based index is used solely with the --dired option.
824    When that option is in effect, this counter is incremented for each
825    character of output generated by this program so that the beginning
826    and ending indices (in that output) of every file name can be recorded
827    and later output themselves.  */
828 static size_t dired_pos;
829
830 #define DIRED_PUTCHAR(c) do {putchar ((c)); ++dired_pos;} while (0)
831
832 /* Write S to STREAM and increment DIRED_POS by S_LEN.  */
833 #define DIRED_FPUTS(s, stream, s_len) \
834     do {fputs ((s), (stream)); dired_pos += s_len;} while (0)
835
836 /* Like DIRED_FPUTS, but for use when S is a literal string.  */
837 #define DIRED_FPUTS_LITERAL(s, stream) \
838     do {fputs ((s), (stream)); dired_pos += sizeof((s)) - 1;} while (0)
839
840 #define DIRED_INDENT()                                                  \
841     do                                                                  \
842       {                                                                 \
843         /* FIXME: remove the `&& format == long_format' clause.  */     \
844         if (dired && format == long_format)                             \
845           DIRED_FPUTS_LITERAL ("  ", stdout);                           \
846       }                                                                 \
847     while (0)
848
849 /* With --dired, store pairs of beginning and ending indices of filenames.  */
850 static struct obstack dired_obstack;
851
852 /* With --dired, store pairs of beginning and ending indices of any
853    directory names that appear as headers (just before `total' line)
854    for lists of directory entries.  Such directory names are seen when
855    listing hierarchies using -R and when a directory is listed with at
856    least one other command line argument.  */
857 static struct obstack subdired_obstack;
858
859 /* Save the current index on the specified obstack, OBS.  */
860 #define PUSH_CURRENT_DIRED_POS(obs)                                     \
861   do                                                                    \
862     {                                                                   \
863       /* FIXME: remove the `&& format == long_format' clause.  */       \
864       if (dired && format == long_format)                               \
865         obstack_grow ((obs), &dired_pos, sizeof (dired_pos));           \
866     }                                                                   \
867   while (0)
868
869 /* With -R, this stack is used to help detect directory cycles.
870    The device/inode pairs on this stack mirror the pairs in the
871    active_dir_set hash table.  */
872 static struct obstack dev_ino_obstack;
873
874 /* Push a pair onto the device/inode stack.  */
875 #define DEV_INO_PUSH(Dev, Ino)                                          \
876   do                                                                    \
877     {                                                                   \
878       struct dev_ino *di;                                               \
879       obstack_blank (&dev_ino_obstack, sizeof (struct dev_ino));        \
880       di = -1 + (struct dev_ino *) obstack_next_free (&dev_ino_obstack); \
881       di->st_dev = (Dev);                                               \
882       di->st_ino = (Ino);                                               \
883     }                                                                   \
884   while (0)
885
886 /* Pop a dev/ino struct off the global dev_ino_obstack
887    and return that struct.  */
888 static struct dev_ino
889 dev_ino_pop (void)
890 {
891   assert (sizeof (struct dev_ino) <= obstack_object_size (&dev_ino_obstack));
892   obstack_blank (&dev_ino_obstack, -(int) (sizeof (struct dev_ino)));
893   return *(struct dev_ino*) obstack_next_free (&dev_ino_obstack);
894 }
895
896 #define ASSERT_MATCHING_DEV_INO(Name, Di)       \
897   do                                            \
898     {                                           \
899       struct stat sb;                           \
900       assert (Name);                            \
901       assert (0 <= stat (Name, &sb));           \
902       assert (sb.st_dev == Di.st_dev);          \
903       assert (sb.st_ino == Di.st_ino);          \
904     }                                           \
905   while (0)
906
907
908 /* Write to standard output PREFIX, followed by the quoting style and
909    a space-separated list of the integers stored in OS all on one line.  */
910
911 static void
912 dired_dump_obstack (const char *prefix, struct obstack *os)
913 {
914   int n_pos;
915
916   n_pos = obstack_object_size (os) / sizeof (dired_pos);
917   if (n_pos > 0)
918     {
919       int i;
920       size_t *pos;
921
922       pos = (size_t *) obstack_finish (os);
923       fputs (prefix, stdout);
924       for (i = 0; i < n_pos; i++)
925         printf (" %lu", (unsigned long) pos[i]);
926       fputs ("\n", stdout);
927     }
928 }
929
930 static unsigned int
931 dev_ino_hash (void const *x, unsigned int table_size)
932 {
933   struct dev_ino const *p = x;
934   return (uintmax_t) p->st_ino % table_size;
935 }
936
937 static bool
938 dev_ino_compare (void const *x, void const *y)
939 {
940   struct dev_ino const *a = x;
941   struct dev_ino const *b = y;
942   return SAME_INODE (*a, *b) ? true : false;
943 }
944
945 static void
946 dev_ino_free (void *x)
947 {
948   free (x);
949 }
950
951 /* Add the device/inode pair (P->st_dev/P->st_ino) to the set of
952    active directories.  Return nonzero if there is already a matching
953    entry in the table.  Otherwise, return zero.  */
954
955 static int
956 visit_dir (dev_t dev, ino_t ino)
957 {
958   struct dev_ino *ent;
959   struct dev_ino *ent_from_table;
960   int found_match;
961
962   ent = XMALLOC (struct dev_ino, 1);
963   ent->st_ino = ino;
964   ent->st_dev = dev;
965
966   /* Attempt to insert this entry into the table.  */
967   ent_from_table = hash_insert (active_dir_set, ent);
968
969   if (ent_from_table == NULL)
970     {
971       /* Insertion failed due to lack of memory.  */
972       xalloc_die ();
973     }
974
975   found_match = (ent_from_table != ent);
976
977   if (found_match)
978     {
979       /* ent was not inserted, so free it.  */
980       free (ent);
981     }
982
983   return found_match;
984 }
985
986 static void
987 free_pending_ent (struct pending *p)
988 {
989   if (p->name)
990     free (p->name);
991   if (p->realname)
992     free (p->realname);
993   free (p);
994 }
995
996 int
997 main (int argc, char **argv)
998 {
999   register int i;
1000   register struct pending *thispend;
1001   unsigned int n_files;
1002
1003   program_name = argv[0];
1004   setlocale (LC_ALL, "");
1005   bindtextdomain (PACKAGE, LOCALEDIR);
1006   textdomain (PACKAGE);
1007
1008   atexit (close_stdout);
1009
1010 #define N_ENTRIES(Array) (sizeof Array / sizeof *(Array))
1011   assert (N_ENTRIES (color_indicator) + 1 == N_ENTRIES (indicator_name));
1012
1013   exit_status = 0;
1014   dir_defaulted = 1;
1015   print_dir_name = 1;
1016   pending_dirs = 0;
1017
1018   i = decode_switches (argc, argv);
1019
1020   if (print_with_color)
1021     parse_ls_color ();
1022
1023   /* Test print_with_color again, because the call to parse_ls_color
1024      may have just reset it -- e.g., if LS_COLORS is invalid.  */
1025   if (print_with_color)
1026     {
1027       prep_non_filename_text ();
1028       /* Avoid following symbolic links when possible.  */
1029       if (color_indicator[C_ORPHAN].string != NULL
1030           || (color_indicator[C_MISSING].string != NULL
1031               && format == long_format))
1032         check_symlink_color = 1;
1033     }
1034
1035   if (dereference == DEREF_UNDEFINED)
1036     dereference = ((immediate_dirs
1037                     || indicator_style == classify
1038                     || format == long_format)
1039                    ? DEREF_NEVER
1040                    : DEREF_COMMAND_LINE_ARGUMENTS);
1041
1042   /* When using -R, initialize a data structure we'll use to
1043      detect any directory cycles.  */
1044   if (recursive)
1045     {
1046       active_dir_set = hash_initialize (INITIAL_TABLE_SIZE, NULL,
1047                                         dev_ino_hash,
1048                                         dev_ino_compare,
1049                                         dev_ino_free);
1050       if (active_dir_set == NULL)
1051         xalloc_die ();
1052
1053       obstack_init (&dev_ino_obstack);
1054     }
1055
1056   format_needs_stat = sort_type == sort_time || sort_type == sort_size
1057     || format == long_format
1058     || dereference == DEREF_ALWAYS
1059     || recursive || print_block_size || print_inode;
1060   format_needs_type = (format_needs_stat == 0
1061                        && (print_with_color || indicator_style != none));
1062
1063   if (dired && format == long_format)
1064     {
1065       obstack_init (&dired_obstack);
1066       obstack_init (&subdired_obstack);
1067     }
1068
1069   nfiles = 100;
1070   files = XMALLOC (struct fileinfo, nfiles);
1071   files_index = 0;
1072
1073   clear_files ();
1074
1075   n_files = argc - i;
1076   if (0 < n_files)
1077     dir_defaulted = 0;
1078
1079   for (; i < argc; i++)
1080     {
1081       gobble_file (argv[i], unknown, 1, "");
1082     }
1083
1084   if (dir_defaulted)
1085     {
1086       if (immediate_dirs)
1087         gobble_file (".", directory, 1, "");
1088       else
1089         queue_directory (".", 0);
1090     }
1091
1092   if (files_index)
1093     {
1094       sort_files ();
1095       if (!immediate_dirs)
1096         extract_dirs_from_files ("", 0);
1097       /* `files_index' might be zero now.  */
1098     }
1099
1100   /* In the following if/else blocks, it is sufficient to test `pending_dirs'
1101      (and not pending_dirs->name) because there may be no markers in the queue
1102      at this point.  A marker may be enqueued when extract_dirs_from_files is
1103      called with a non-empty string or via print_dir.  */
1104   if (files_index)
1105     {
1106       print_current_files ();
1107       if (pending_dirs)
1108         DIRED_PUTCHAR ('\n');
1109     }
1110   else if (n_files <= 1 && pending_dirs && pending_dirs->next == 0)
1111     print_dir_name = 0;
1112
1113   while (pending_dirs)
1114     {
1115       thispend = pending_dirs;
1116       pending_dirs = pending_dirs->next;
1117
1118       if (LOOP_DETECT)
1119         {
1120           if (thispend->name == NULL)
1121             {
1122               /* thispend->name == NULL means this is a marker entry
1123                  indicating we've finished processing the directory.
1124                  Use its dev/ino numbers to remove the corresponding
1125                  entry from the active_dir_set hash table.  */
1126               struct dev_ino di = dev_ino_pop ();
1127               struct dev_ino *found = hash_delete (active_dir_set, &di);
1128               /* ASSERT_MATCHING_DEV_INO (thispend->realname, di); */
1129               assert (found);
1130               dev_ino_free (found);
1131               free_pending_ent (thispend);
1132               continue;
1133             }
1134         }
1135
1136       print_dir (thispend->name, thispend->realname);
1137
1138       free_pending_ent (thispend);
1139       print_dir_name = 1;
1140     }
1141
1142   if (dired && format == long_format)
1143     {
1144       /* No need to free these since we're about to exit.  */
1145       dired_dump_obstack ("//DIRED//", &dired_obstack);
1146       dired_dump_obstack ("//SUBDIRED//", &subdired_obstack);
1147       printf ("//DIRED-OPTIONS// --quoting-style=%s\n",
1148               quoting_style_args[get_quoting_style (filename_quoting_options)]);
1149     }
1150
1151   /* Restore default color before exiting */
1152   if (print_with_color)
1153     {
1154       put_indicator (&color_indicator[C_LEFT]);
1155       put_indicator (&color_indicator[C_RIGHT]);
1156     }
1157
1158   if (LOOP_DETECT)
1159     {
1160       assert (hash_get_n_entries (active_dir_set) == 0);
1161       hash_free (active_dir_set);
1162     }
1163
1164   exit (exit_status);
1165 }
1166
1167 /* Set all the option flags according to the switches specified.
1168    Return the index of the first non-option argument.  */
1169
1170 static int
1171 decode_switches (int argc, char **argv)
1172 {
1173   int c;
1174   char *time_style_option = 0;
1175
1176   /* Record whether there is an option specifying sort type.  */
1177   int sort_type_specified = 0;
1178
1179   qmark_funny_chars = 0;
1180
1181   /* initialize all switches to default settings */
1182
1183   switch (ls_mode)
1184     {
1185     case LS_MULTI_COL:
1186       /* This is for the `dir' program.  */
1187       format = many_per_line;
1188       set_quoting_style (NULL, escape_quoting_style);
1189       break;
1190
1191     case LS_LONG_FORMAT:
1192       /* This is for the `vdir' program.  */
1193       format = long_format;
1194       set_quoting_style (NULL, escape_quoting_style);
1195       break;
1196
1197     case LS_LS:
1198       /* This is for the `ls' program.  */
1199       if (isatty (STDOUT_FILENO))
1200         {
1201           format = many_per_line;
1202           /* See description of qmark_funny_chars, above.  */
1203           qmark_funny_chars = 1;
1204         }
1205       else
1206         {
1207           format = one_per_line;
1208           qmark_funny_chars = 0;
1209         }
1210       break;
1211
1212     default:
1213       abort ();
1214     }
1215
1216   time_type = time_mtime;
1217   sort_type = sort_name;
1218   sort_reverse = 0;
1219   numeric_ids = 0;
1220   print_block_size = 0;
1221   indicator_style = none;
1222   print_inode = 0;
1223   dereference = DEREF_UNDEFINED;
1224   recursive = 0;
1225   immediate_dirs = 0;
1226   all_files = 0;
1227   really_all_files = 0;
1228   ignore_patterns = 0;
1229
1230   /* FIXME: put this in a function.  */
1231   {
1232     char const *q_style = getenv ("QUOTING_STYLE");
1233     if (q_style)
1234       {
1235         int i = ARGCASEMATCH (q_style, quoting_style_args, quoting_style_vals);
1236         if (0 <= i)
1237           set_quoting_style (NULL, quoting_style_vals[i]);
1238         else
1239           error (0, 0,
1240          _("ignoring invalid value of environment variable QUOTING_STYLE: %s"),
1241                  quotearg (q_style));
1242       }
1243   }
1244
1245   human_block_size (getenv ("LS_BLOCK_SIZE"), 0, &output_block_size);
1246
1247   line_length = 80;
1248   {
1249     char const *p = getenv ("COLUMNS");
1250     if (p && *p)
1251       {
1252         long int tmp_long;
1253         if (xstrtol (p, NULL, 0, &tmp_long, NULL) == LONGINT_OK
1254             && 0 < tmp_long && tmp_long <= INT_MAX)
1255           {
1256             line_length = (int) tmp_long;
1257           }
1258         else
1259           {
1260             error (0, 0,
1261                _("ignoring invalid width in environment variable COLUMNS: %s"),
1262                    quotearg (p));
1263           }
1264       }
1265   }
1266
1267 #ifdef TIOCGWINSZ
1268   {
1269     struct winsize ws;
1270
1271     if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 && ws.ws_col != 0)
1272       line_length = ws.ws_col;
1273   }
1274 #endif
1275
1276   /* Using the TABSIZE environment variable is not POSIX-approved.
1277      Ignore it when POSIXLY_CORRECT is set.  */
1278   {
1279     char const *p;
1280     tabsize = 8;
1281     if (!getenv ("POSIXLY_CORRECT") && (p = getenv ("TABSIZE")))
1282       {
1283         long int tmp_long;
1284         if (xstrtol (p, NULL, 0, &tmp_long, NULL) == LONGINT_OK
1285             && 0 <= tmp_long && tmp_long <= INT_MAX)
1286           {
1287             tabsize = (int) tmp_long;
1288           }
1289         else
1290           {
1291             error (0, 0,
1292              _("ignoring invalid tab size in environment variable TABSIZE: %s"),
1293                    quotearg (p));
1294           }
1295       }
1296   }
1297
1298   while ((c = getopt_long (argc, argv,
1299                            "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UX1",
1300                            long_options, NULL)) != -1)
1301     {
1302       switch (c)
1303         {
1304         case 0:
1305           break;
1306
1307         case 'a':
1308           all_files = 1;
1309           really_all_files = 1;
1310           break;
1311
1312         case 'b':
1313           set_quoting_style (NULL, escape_quoting_style);
1314           break;
1315
1316         case 'c':
1317           time_type = time_ctime;
1318           break;
1319
1320         case 'd':
1321           immediate_dirs = 1;
1322           break;
1323
1324         case 'f':
1325           /* Same as enabling -a -U and disabling -l -s.  */
1326           all_files = 1;
1327           really_all_files = 1;
1328           sort_type = sort_none;
1329           sort_type_specified = 1;
1330           /* disable -l */
1331           if (format == long_format)
1332             format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line);
1333           print_block_size = 0; /* disable -s */
1334           print_with_color = 0; /* disable --color */
1335           break;
1336
1337         case 'g':
1338           format = long_format;
1339           print_owner = 0;
1340           break;
1341
1342         case 'h':
1343           output_block_size = -1024;
1344           break;
1345
1346         case 'i':
1347           print_inode = 1;
1348           break;
1349
1350         case 'k':
1351           output_block_size = 1024;
1352           break;
1353
1354         case 'l':
1355           format = long_format;
1356           break;
1357
1358         case 'm':
1359           format = with_commas;
1360           break;
1361
1362         case 'n':
1363           numeric_ids = 1;
1364           format = long_format;
1365           break;
1366
1367         case 'o':  /* Just like -l, but don't display group info.  */
1368           format = long_format;
1369           print_group = 0;
1370           break;
1371
1372         case 'p':
1373           indicator_style = file_type;
1374           break;
1375
1376         case 'q':
1377           qmark_funny_chars = 1;
1378           break;
1379
1380         case 'r':
1381           sort_reverse = 1;
1382           break;
1383
1384         case 's':
1385           print_block_size = 1;
1386           break;
1387
1388         case 't':
1389           sort_type = sort_time;
1390           sort_type_specified = 1;
1391           break;
1392
1393         case 'u':
1394           time_type = time_atime;
1395           break;
1396
1397         case 'v':
1398           sort_type = sort_version;
1399           sort_type_specified = 1;
1400           break;
1401
1402         case 'w':
1403           {
1404             long int tmp_long;
1405             if (xstrtol (optarg, NULL, 0, &tmp_long, NULL) != LONGINT_OK
1406                 || tmp_long <= 0 || tmp_long > INT_MAX)
1407               error (EXIT_FAILURE, 0, _("invalid line width: %s"),
1408                      quotearg (optarg));
1409             line_length = (int) tmp_long;
1410             break;
1411           }
1412
1413         case 'x':
1414           format = horizontal;
1415           break;
1416
1417         case 'A':
1418           really_all_files = 0;
1419           all_files = 1;
1420           break;
1421
1422         case 'B':
1423           add_ignore_pattern ("*~");
1424           add_ignore_pattern (".*~");
1425           break;
1426
1427         case 'C':
1428           format = many_per_line;
1429           break;
1430
1431         case 'D':
1432           dired = 1;
1433           break;
1434
1435         case 'F':
1436           indicator_style = classify;
1437           break;
1438
1439         case 'G':               /* inhibit display of group info */
1440           print_group = 0;
1441           break;
1442
1443         case 'H':
1444           dereference = DEREF_COMMAND_LINE_ARGUMENTS;
1445           break;
1446
1447         case 'I':
1448           add_ignore_pattern (optarg);
1449           break;
1450
1451         case 'L':
1452           dereference = DEREF_ALWAYS;
1453           break;
1454
1455         case 'N':
1456           set_quoting_style (NULL, literal_quoting_style);
1457           break;
1458
1459         case 'Q':
1460           set_quoting_style (NULL, c_quoting_style);
1461           break;
1462
1463         case 'R':
1464           recursive = 1;
1465           break;
1466
1467         case 'S':
1468           sort_type = sort_size;
1469           sort_type_specified = 1;
1470           break;
1471
1472         case 'T':
1473           {
1474             long int tmp_long;
1475             if (xstrtol (optarg, NULL, 0, &tmp_long, NULL) != LONGINT_OK
1476                 || tmp_long < 0 || tmp_long > INT_MAX)
1477               error (EXIT_FAILURE, 0, _("invalid tab size: %s"),
1478                      quotearg (optarg));
1479             tabsize = (int) tmp_long;
1480             break;
1481           }
1482
1483         case 'U':
1484           sort_type = sort_none;
1485           sort_type_specified = 1;
1486           break;
1487
1488         case 'X':
1489           sort_type = sort_extension;
1490           sort_type_specified = 1;
1491           break;
1492
1493         case '1':
1494           /* -1 has no effect after -l.  */
1495           if (format != long_format)
1496             format = one_per_line;
1497           break;
1498
1499         case AUTHOR_OPTION:
1500           print_author = true;
1501           break;
1502
1503         case SORT_OPTION:
1504           sort_type = XARGMATCH ("--sort", optarg, sort_args, sort_types);
1505           sort_type_specified = 1;
1506           break;
1507
1508         case TIME_OPTION:
1509           time_type = XARGMATCH ("--time", optarg, time_args, time_types);
1510           break;
1511
1512         case FORMAT_OPTION:
1513           format = XARGMATCH ("--format", optarg, format_args, format_types);
1514           break;
1515
1516         case FULL_TIME_OPTION:
1517           format = long_format;
1518           time_style_option = "full-iso";
1519           break;
1520
1521         case COLOR_OPTION:
1522           {
1523             int i;
1524             if (optarg)
1525               i = XARGMATCH ("--color", optarg, color_args, color_types);
1526             else
1527               /* Using --color with no argument is equivalent to using
1528                  --color=always.  */
1529               i = color_always;
1530
1531             print_with_color = (i == color_always
1532                                 || (i == color_if_tty
1533                                     && isatty (STDOUT_FILENO)));
1534
1535             if (print_with_color)
1536               {
1537                 /* Don't use TAB characters in output.  Some terminal
1538                    emulators can't handle the combination of tabs and
1539                    color codes on the same line.  */
1540                 tabsize = 0;
1541               }
1542             break;
1543           }
1544
1545         case INDICATOR_STYLE_OPTION:
1546           indicator_style = XARGMATCH ("--indicator-style", optarg,
1547                                        indicator_style_args,
1548                                        indicator_style_types);
1549           break;
1550
1551         case QUOTING_STYLE_OPTION:
1552           set_quoting_style (NULL,
1553                              XARGMATCH ("--quoting-style", optarg,
1554                                         quoting_style_args,
1555                                         quoting_style_vals));
1556           break;
1557
1558         case TIME_STYLE_OPTION:
1559           time_style_option = optarg;
1560           break;
1561
1562         case SHOW_CONTROL_CHARS_OPTION:
1563           qmark_funny_chars = 0;
1564           break;
1565
1566         case BLOCK_SIZE_OPTION:
1567           human_block_size (optarg, 1, &output_block_size);
1568           break;
1569
1570         case SI_OPTION:
1571           output_block_size = -1000;
1572           break;
1573
1574         case_GETOPT_HELP_CHAR;
1575
1576         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1577
1578         default:
1579           usage (EXIT_FAILURE);
1580         }
1581     }
1582
1583   filename_quoting_options = clone_quoting_options (NULL);
1584   if (get_quoting_style (filename_quoting_options) == escape_quoting_style)
1585     set_char_quoting (filename_quoting_options, ' ', 1);
1586   if (indicator_style != none)
1587     {
1588       char const *p;
1589       for (p = "*=@|" + (int) indicator_style - 1;  *p;  p++)
1590         set_char_quoting (filename_quoting_options, *p, 1);
1591     }
1592
1593   dirname_quoting_options = clone_quoting_options (NULL);
1594   set_char_quoting (dirname_quoting_options, ':', 1);
1595
1596   /* If -c or -u is specified and not -l (or any other option that implies -l),
1597      and no sort-type was specified, then sort by the ctime (-c) or atime (-u).
1598      The behavior of ls when using either -c or -u but with neither -l nor -t
1599      appears to be unspecified by POSIX.  So, with GNU ls, `-u' alone means
1600      sort by atime (this is the one that's not specified by the POSIX spec),
1601      -lu means show atime and sort by name, -lut means show atime and sort
1602      by atime.  */
1603
1604   if ((time_type == time_ctime || time_type == time_atime)
1605       && !sort_type_specified && format != long_format)
1606     {
1607       sort_type = sort_time;
1608     }
1609
1610   if (format == long_format)
1611     {
1612       if (! time_style_option)
1613         time_style_option = getenv ("TIME_STYLE");
1614
1615       if (time_style_option && *time_style_option == '+')
1616         {
1617           char *p0 = time_style_option + 1;
1618           char *p1 = strchr (p0, '\n');
1619           if (! p1)
1620             p1 = p0;
1621           else
1622             {
1623               if (strchr (p1 + 1, '\n'))
1624                 error (EXIT_FAILURE, 0, _("invalid time style format %s"),
1625                        quote (p0));
1626               *p1++ = '\0';
1627             }
1628           long_time_format[0] = p0;
1629           long_time_format[1] = p1;
1630         }
1631       else
1632         switch (time_style_option
1633                 ? XARGMATCH ("time style", time_style_option,
1634                              time_style_args,
1635                              time_style_types)
1636                 : posix_iso_time_style)
1637           {
1638           case full_iso_time_style:
1639             long_time_format[0] = long_time_format[1] =
1640               "%Y-%m-%d %H:%M:%S.%N %z";
1641             break;
1642
1643           case posix_iso_time_style:
1644             if (! hard_locale (LC_TIME))
1645               break;
1646             /* Fall through.  */
1647           case iso_time_style:
1648             long_time_format[0] = "%Y-%m-%d ";
1649             long_time_format[1] = "%m-%d %H:%M";
1650             break;
1651
1652           case locale_time_style:
1653             if (hard_locale (LC_TIME))
1654               {
1655                 unsigned int i;
1656                 for (i = 0; i < 2; i++)
1657                   long_time_format[i] =
1658                     dcgettext (NULL, long_time_format[i], LC_TIME);
1659               }
1660           }
1661     }
1662
1663   return optind;
1664 }
1665
1666 /* Parse a string as part of the LS_COLORS variable; this may involve
1667    decoding all kinds of escape characters.  If equals_end is set an
1668    unescaped equal sign ends the string, otherwise only a : or \0
1669    does.  Returns the number of characters output, or -1 on failure.
1670
1671    The resulting string is *not* null-terminated, but may contain
1672    embedded nulls.
1673
1674    Note that both dest and src are char **; on return they point to
1675    the first free byte after the array and the character that ended
1676    the input string, respectively.  */
1677
1678 static int
1679 get_funky_string (char **dest, const char **src, int equals_end)
1680 {
1681   int num;                      /* For numerical codes */
1682   int count;                    /* Something to count with */
1683   enum {
1684     ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR
1685   } state;
1686   const char *p;
1687   char *q;
1688
1689   p = *src;                     /* We don't want to double-indirect */
1690   q = *dest;                    /* the whole darn time.  */
1691
1692   count = 0;                    /* No characters counted in yet.  */
1693   num = 0;
1694
1695   state = ST_GND;               /* Start in ground state.  */
1696   while (state < ST_END)
1697     {
1698       switch (state)
1699         {
1700         case ST_GND:            /* Ground state (no escapes) */
1701           switch (*p)
1702             {
1703             case ':':
1704             case '\0':
1705               state = ST_END;   /* End of string */
1706               break;
1707             case '\\':
1708               state = ST_BACKSLASH; /* Backslash scape sequence */
1709               ++p;
1710               break;
1711             case '^':
1712               state = ST_CARET; /* Caret escape */
1713               ++p;
1714               break;
1715             case '=':
1716               if (equals_end)
1717                 {
1718                   state = ST_END; /* End */
1719                   break;
1720                 }
1721               /* else fall through */
1722             default:
1723               *(q++) = *(p++);
1724               ++count;
1725               break;
1726             }
1727           break;
1728
1729         case ST_BACKSLASH:      /* Backslash escaped character */
1730           switch (*p)
1731             {
1732             case '0':
1733             case '1':
1734             case '2':
1735             case '3':
1736             case '4':
1737             case '5':
1738             case '6':
1739             case '7':
1740               state = ST_OCTAL; /* Octal sequence */
1741               num = *p - '0';
1742               break;
1743             case 'x':
1744             case 'X':
1745               state = ST_HEX;   /* Hex sequence */
1746               num = 0;
1747               break;
1748             case 'a':           /* Bell */
1749               num = 7;          /* Not all C compilers know what \a means */
1750               break;
1751             case 'b':           /* Backspace */
1752               num = '\b';
1753               break;
1754             case 'e':           /* Escape */
1755               num = 27;
1756               break;
1757             case 'f':           /* Form feed */
1758               num = '\f';
1759               break;
1760             case 'n':           /* Newline */
1761               num = '\n';
1762               break;
1763             case 'r':           /* Carriage return */
1764               num = '\r';
1765               break;
1766             case 't':           /* Tab */
1767               num = '\t';
1768               break;
1769             case 'v':           /* Vtab */
1770               num = '\v';
1771               break;
1772             case '?':           /* Delete */
1773               num = 127;
1774               break;
1775             case '_':           /* Space */
1776               num = ' ';
1777               break;
1778             case '\0':          /* End of string */
1779               state = ST_ERROR; /* Error! */
1780               break;
1781             default:            /* Escaped character like \ ^ : = */
1782               num = *p;
1783               break;
1784             }
1785           if (state == ST_BACKSLASH)
1786             {
1787               *(q++) = num;
1788               ++count;
1789               state = ST_GND;
1790             }
1791           ++p;
1792           break;
1793
1794         case ST_OCTAL:          /* Octal sequence */
1795           if (*p < '0' || *p > '7')
1796             {
1797               *(q++) = num;
1798               ++count;
1799               state = ST_GND;
1800             }
1801           else
1802             num = (num << 3) + (*(p++) - '0');
1803           break;
1804
1805         case ST_HEX:            /* Hex sequence */
1806           switch (*p)
1807             {
1808             case '0':
1809             case '1':
1810             case '2':
1811             case '3':
1812             case '4':
1813             case '5':
1814             case '6':
1815             case '7':
1816             case '8':
1817             case '9':
1818               num = (num << 4) + (*(p++) - '0');
1819               break;
1820             case 'a':
1821             case 'b':
1822             case 'c':
1823             case 'd':
1824             case 'e':
1825             case 'f':
1826               num = (num << 4) + (*(p++) - 'a') + 10;
1827               break;
1828             case 'A':
1829             case 'B':
1830             case 'C':
1831             case 'D':
1832             case 'E':
1833             case 'F':
1834               num = (num << 4) + (*(p++) - 'A') + 10;
1835               break;
1836             default:
1837               *(q++) = num;
1838               ++count;
1839               state = ST_GND;
1840               break;
1841             }
1842           break;
1843
1844         case ST_CARET:          /* Caret escape */
1845           state = ST_GND;       /* Should be the next state... */
1846           if (*p >= '@' && *p <= '~')
1847             {
1848               *(q++) = *(p++) & 037;
1849               ++count;
1850             }
1851           else if (*p == '?')
1852             {
1853               *(q++) = 127;
1854               ++count;
1855             }
1856           else
1857             state = ST_ERROR;
1858           break;
1859
1860         default:
1861           abort ();
1862         }
1863     }
1864
1865   *dest = q;
1866   *src = p;
1867
1868   return state == ST_ERROR ? -1 : count;
1869 }
1870
1871 static void
1872 parse_ls_color (void)
1873 {
1874   const char *p;                /* Pointer to character being parsed */
1875   char *buf;                    /* color_buf buffer pointer */
1876   int state;                    /* State of parser */
1877   int ind_no;                   /* Indicator number */
1878   char label[3];                /* Indicator label */
1879   struct color_ext_type *ext;   /* Extension we are working on */
1880
1881   if ((p = getenv ("LS_COLORS")) == NULL || *p == '\0')
1882     return;
1883
1884   ext = NULL;
1885   strcpy (label, "??");
1886
1887   /* This is an overly conservative estimate, but any possible
1888      LS_COLORS string will *not* generate a color_buf longer than
1889      itself, so it is a safe way of allocating a buffer in
1890      advance.  */
1891   buf = color_buf = xstrdup (p);
1892
1893   state = 1;
1894   while (state > 0)
1895     {
1896       switch (state)
1897         {
1898         case 1:         /* First label character */
1899           switch (*p)
1900             {
1901             case ':':
1902               ++p;
1903               break;
1904
1905             case '*':
1906               /* Allocate new extension block and add to head of
1907                  linked list (this way a later definition will
1908                  override an earlier one, which can be useful for
1909                  having terminal-specific defs override global).  */
1910
1911               ext = XMALLOC (struct color_ext_type, 1);
1912               ext->next = color_ext_list;
1913               color_ext_list = ext;
1914
1915               ++p;
1916               ext->ext.string = buf;
1917
1918               state = (ext->ext.len =
1919                        get_funky_string (&buf, &p, 1)) < 0 ? -1 : 4;
1920               break;
1921
1922             case '\0':
1923               state = 0;        /* Done! */
1924               break;
1925
1926             default:    /* Assume it is file type label */
1927               label[0] = *(p++);
1928               state = 2;
1929               break;
1930             }
1931           break;
1932
1933         case 2:         /* Second label character */
1934           if (*p)
1935             {
1936               label[1] = *(p++);
1937               state = 3;
1938             }
1939           else
1940             state = -1; /* Error */
1941           break;
1942
1943         case 3:         /* Equal sign after indicator label */
1944           state = -1;   /* Assume failure... */
1945           if (*(p++) == '=')/* It *should* be... */
1946             {
1947               for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no)
1948                 {
1949                   if (STREQ (label, indicator_name[ind_no]))
1950                     {
1951                       color_indicator[ind_no].string = buf;
1952                       state = ((color_indicator[ind_no].len =
1953                                 get_funky_string (&buf, &p, 0)) < 0 ? -1 : 1);
1954                       break;
1955                     }
1956                 }
1957               if (state == -1)
1958                 error (0, 0, _("unrecognized prefix: %s"), quotearg (label));
1959             }
1960          break;
1961
1962         case 4:         /* Equal sign after *.ext */
1963           if (*(p++) == '=')
1964             {
1965               ext->seq.string = buf;
1966               state = (ext->seq.len =
1967                        get_funky_string (&buf, &p, 0)) < 0 ? -1 : 1;
1968             }
1969           else
1970             state = -1;
1971           break;
1972         }
1973     }
1974
1975   if (state < 0)
1976     {
1977       struct color_ext_type *e;
1978       struct color_ext_type *e2;
1979
1980       error (0, 0,
1981              _("unparsable value for LS_COLORS environment variable"));
1982       free (color_buf);
1983       for (e = color_ext_list; e != NULL; /* empty */)
1984         {
1985           e2 = e;
1986           e = e->next;
1987           free (e2);
1988         }
1989       print_with_color = 0;
1990     }
1991
1992   if (color_indicator[C_LINK].len == 6
1993       && !strncmp (color_indicator[C_LINK].string, "target", 6))
1994     color_symlink_as_referent = 1;
1995 }
1996
1997 /* Request that the directory named NAME have its contents listed later.
1998    If REALNAME is nonzero, it will be used instead of NAME when the
1999    directory name is printed.  This allows symbolic links to directories
2000    to be treated as regular directories but still be listed under their
2001    real names.  NAME == NULL is used to insert a marker entry for the
2002    directory named in REALNAME.
2003    If F is non-NULL, we use its dev/ino information to save
2004    a call to stat -- when doing a recursive (-R) traversal.  */
2005
2006 static void
2007 queue_directory (const char *name, const char *realname)
2008 {
2009   struct pending *new;
2010
2011   new = XMALLOC (struct pending, 1);
2012   new->realname = realname ? xstrdup (realname) : NULL;
2013   new->name = name ? xstrdup (name) : NULL;
2014   new->next = pending_dirs;
2015   pending_dirs = new;
2016 }
2017
2018 /* Read directory `name', and list the files in it.
2019    If `realname' is nonzero, print its name instead of `name';
2020    this is used for symbolic links to directories. */
2021
2022 static void
2023 print_dir (const char *name, const char *realname)
2024 {
2025   register DIR *reading;
2026   register struct dirent *next;
2027   register uintmax_t total_blocks = 0;
2028   static int first = 1;
2029
2030   errno = 0;
2031   reading = opendir (name);
2032   if (!reading)
2033     {
2034       error (0, errno, "%s", quotearg_colon (name));
2035       exit_status = 1;
2036       return;
2037     }
2038
2039   if (LOOP_DETECT)
2040     {
2041       struct stat dir_stat;
2042       int fd = dirfd (reading);
2043
2044       /* If dirfd failed, endure the overhead of using stat.  */
2045       if ((0 <= fd
2046            ? fstat (fd, &dir_stat)
2047            : stat (name, &dir_stat)) < 0)
2048         {
2049           error (0, errno, _("cannot determine device and inode of %s"),
2050                  quotearg_colon (name));
2051           exit_status = 1;
2052           return;
2053         }
2054
2055       /* If we've already visited this dev/inode pair, warn that
2056          we've found a loop, and do not process this directory.  */
2057       if (visit_dir (dir_stat.st_dev, dir_stat.st_ino))
2058         {
2059           error (0, 0, _("not listing already-listed directory: %s"),
2060                  quotearg_colon (name));
2061           return;
2062         }
2063
2064       DEV_INO_PUSH (dir_stat.st_dev, dir_stat.st_ino);
2065     }
2066
2067   /* Read the directory entries, and insert the subfiles into the `files'
2068      table.  */
2069
2070   clear_files ();
2071
2072   while ((next = readdir (reading)) != NULL)
2073     if (file_interesting (next))
2074       {
2075         enum filetype type = unknown;
2076
2077 #if HAVE_STRUCT_DIRENT_D_TYPE
2078         if (next->d_type == DT_DIR || next->d_type == DT_CHR
2079             || next->d_type == DT_BLK || next->d_type == DT_SOCK
2080             || next->d_type == DT_FIFO)
2081           type = next->d_type;
2082 #endif
2083         total_blocks += gobble_file (next->d_name, type, 0, name);
2084       }
2085
2086   if (CLOSEDIR (reading))
2087     {
2088       error (0, errno, "%s", quotearg_colon (name));
2089       exit_status = 1;
2090       /* Don't return; print whatever we got. */
2091     }
2092
2093   /* Sort the directory contents.  */
2094   sort_files ();
2095
2096   /* If any member files are subdirectories, perhaps they should have their
2097      contents listed rather than being mentioned here as files.  */
2098
2099   if (recursive)
2100     extract_dirs_from_files (name, 1);
2101
2102   if (recursive || print_dir_name)
2103     {
2104       if (!first)
2105         DIRED_PUTCHAR ('\n');
2106       first = 0;
2107       DIRED_INDENT ();
2108       PUSH_CURRENT_DIRED_POS (&subdired_obstack);
2109       dired_pos += quote_name (stdout, realname ? realname : name,
2110                                dirname_quoting_options);
2111       PUSH_CURRENT_DIRED_POS (&subdired_obstack);
2112       DIRED_FPUTS_LITERAL (":\n", stdout);
2113     }
2114
2115   if (format == long_format || print_block_size)
2116     {
2117       const char *p;
2118       char buf[LONGEST_HUMAN_READABLE + 1];
2119
2120       DIRED_INDENT ();
2121       p = _("total");
2122       DIRED_FPUTS (p, stdout, strlen (p));
2123       DIRED_PUTCHAR (' ');
2124       p = human_readable_inexact (total_blocks, buf, ST_NBLOCKSIZE,
2125                                   output_block_size, human_ceiling);
2126       DIRED_FPUTS (p, stdout, strlen (p));
2127       DIRED_PUTCHAR ('\n');
2128     }
2129
2130   if (files_index)
2131     print_current_files ();
2132 }
2133
2134 /* Add `pattern' to the list of patterns for which files that match are
2135    not listed.  */
2136
2137 static void
2138 add_ignore_pattern (const char *pattern)
2139 {
2140   register struct ignore_pattern *ignore;
2141
2142   ignore = XMALLOC (struct ignore_pattern, 1);
2143   ignore->pattern = pattern;
2144   /* Add it to the head of the linked list. */
2145   ignore->next = ignore_patterns;
2146   ignore_patterns = ignore;
2147 }
2148
2149 /* Return nonzero if the file in `next' should be listed. */
2150
2151 static int
2152 file_interesting (const struct dirent *next)
2153 {
2154   register struct ignore_pattern *ignore;
2155
2156   for (ignore = ignore_patterns; ignore; ignore = ignore->next)
2157     if (fnmatch (ignore->pattern, next->d_name, FNM_PERIOD) == 0)
2158       return 0;
2159
2160   if (really_all_files
2161       || next->d_name[0] != '.'
2162       || (all_files
2163           && next->d_name[1] != '\0'
2164           && (next->d_name[1] != '.' || next->d_name[2] != '\0')))
2165     return 1;
2166
2167   return 0;
2168 }
2169
2170 /* Enter and remove entries in the table `files'.  */
2171
2172 /* Empty the table of files. */
2173
2174 static void
2175 clear_files (void)
2176 {
2177   register int i;
2178
2179   for (i = 0; i < files_index; i++)
2180     {
2181       free (files[i].name);
2182       if (files[i].linkname)
2183         free (files[i].linkname);
2184     }
2185
2186   files_index = 0;
2187   block_size_size = 4;
2188 }
2189
2190 /* Add a file to the current table of files.
2191    Verify that the file exists, and print an error message if it does not.
2192    Return the number of blocks that the file occupies.  */
2193
2194 static uintmax_t
2195 gobble_file (const char *name, enum filetype type, int explicit_arg,
2196              const char *dirname)
2197 {
2198   register uintmax_t blocks;
2199   register char *path;
2200
2201   if (files_index == nfiles)
2202     {
2203       nfiles *= 2;
2204       files = XREALLOC (files, struct fileinfo, nfiles);
2205     }
2206
2207   files[files_index].linkname = 0;
2208   files[files_index].linkmode = 0;
2209   files[files_index].linkok = 0;
2210
2211   /* FIXME: this use of ls: `mkdir a; touch a/{b,c,d}; ls -R a'
2212      shouldn't require that ls stat b, c, and d -- at least
2213      not on systems with usable d_type.  The problem is that
2214      format_needs_stat is set, because of the -R.  */
2215   if (explicit_arg || format_needs_stat
2216       || (format_needs_type && type == unknown))
2217     {
2218       /* `path' is the absolute pathname of this file. */
2219       int val;
2220
2221       if (name[0] == '/' || dirname[0] == 0)
2222         path = (char *) name;
2223       else
2224         {
2225           path = (char *) alloca (strlen (name) + strlen (dirname) + 2);
2226           attach (path, dirname, name);
2227         }
2228
2229       val = (DEREF_ALWAYS <= dereference + explicit_arg
2230              ? stat (path, &files[files_index].stat)
2231              : lstat (path, &files[files_index].stat));
2232
2233       if (val < 0)
2234         {
2235           error (0, errno, "%s", quotearg_colon (path));
2236           exit_status = 1;
2237           return 0;
2238         }
2239
2240 #if HAVE_ACL
2241       if (format == long_format)
2242         {
2243           int n = file_has_acl (path, &files[files_index].stat);
2244           files[files_index].have_acl = (0 < n);
2245           if (n < 0)
2246             error (0, errno, "%s", quotearg_colon (path));
2247         }
2248 #endif
2249
2250       if (S_ISLNK (files[files_index].stat.st_mode)
2251           && (format == long_format || check_symlink_color))
2252         {
2253           char *linkpath;
2254           struct stat linkstats;
2255
2256           get_link_name (path, &files[files_index]);
2257           linkpath = make_link_path (path, files[files_index].linkname);
2258
2259           /* Avoid following symbolic links when possible, ie, when
2260              they won't be traced and when no indicator is needed. */
2261           if (linkpath
2262               && (indicator_style != none || check_symlink_color)
2263               && stat (linkpath, &linkstats) == 0)
2264             {
2265               files[files_index].linkok = 1;
2266
2267               /* Symbolic links to directories that are mentioned on the
2268                  command line are automatically traced if not being
2269                  listed as files.  */
2270               if (explicit_arg && format != long_format
2271                   && S_ISDIR (linkstats.st_mode))
2272                 {
2273                   /* Substitute the linked-to directory's name, but
2274                      save the real name in `linkname' for printing.  */
2275                   if (!immediate_dirs)
2276                     {
2277                       const char *tempname = name;
2278                       name = linkpath;
2279                       linkpath = files[files_index].linkname;
2280                       files[files_index].linkname = (char *) tempname;
2281                     }
2282                   files[files_index].stat = linkstats;
2283                 }
2284               else
2285                 {
2286                   /* Get the linked-to file's mode for the filetype indicator
2287                      in long listings.  */
2288                   files[files_index].linkmode = linkstats.st_mode;
2289                   files[files_index].linkok = 1;
2290                 }
2291             }
2292           if (linkpath)
2293             free (linkpath);
2294         }
2295
2296       if (S_ISLNK (files[files_index].stat.st_mode))
2297         files[files_index].filetype = symbolic_link;
2298       else if (S_ISDIR (files[files_index].stat.st_mode))
2299         {
2300           if (explicit_arg && !immediate_dirs)
2301             files[files_index].filetype = arg_directory;
2302           else
2303             files[files_index].filetype = directory;
2304         }
2305       else
2306         files[files_index].filetype = normal;
2307
2308       blocks = ST_NBLOCKS (files[files_index].stat);
2309       {
2310         char buf[LONGEST_HUMAN_READABLE + 1];
2311         int len = strlen (human_readable_inexact (blocks, buf, ST_NBLOCKSIZE,
2312                                                   output_block_size,
2313                                                   human_ceiling));
2314         if (block_size_size < len)
2315           block_size_size = len < 7 ? len : 7;
2316       }
2317     }
2318   else
2319     {
2320       files[files_index].filetype = type;
2321 #if HAVE_STRUCT_DIRENT_D_TYPE
2322       files[files_index].stat.st_mode = DTTOIF (type);
2323 #endif
2324       blocks = 0;
2325     }
2326
2327   files[files_index].name = xstrdup (name);
2328   files_index++;
2329
2330   return blocks;
2331 }
2332
2333 #if HAVE_SYMLINKS
2334
2335 /* Put the name of the file that `filename' is a symbolic link to
2336    into the `linkname' field of `f'. */
2337
2338 static void
2339 get_link_name (const char *filename, struct fileinfo *f)
2340 {
2341   f->linkname = xreadlink (filename);
2342   if (f->linkname == NULL)
2343     {
2344       error (0, errno, _("cannot read symbolic link %s"),
2345              quotearg_colon (filename));
2346       exit_status = 1;
2347     }
2348 }
2349
2350 /* If `linkname' is a relative path and `path' contains one or more
2351    leading directories, return `linkname' with those directories
2352    prepended; otherwise, return a copy of `linkname'.
2353    If `linkname' is zero, return zero. */
2354
2355 static char *
2356 make_link_path (const char *path, const char *linkname)
2357 {
2358   char *linkbuf;
2359   size_t bufsiz;
2360
2361   if (linkname == 0)
2362     return 0;
2363
2364   if (*linkname == '/')
2365     return xstrdup (linkname);
2366
2367   /* The link is to a relative path.  Prepend any leading path
2368      in `path' to the link name. */
2369   linkbuf = strrchr (path, '/');
2370   if (linkbuf == 0)
2371     return xstrdup (linkname);
2372
2373   bufsiz = linkbuf - path + 1;
2374   linkbuf = xmalloc (bufsiz + strlen (linkname) + 1);
2375   strncpy (linkbuf, path, bufsiz);
2376   strcpy (linkbuf + bufsiz, linkname);
2377   return linkbuf;
2378 }
2379 #endif
2380
2381 /* Return nonzero if base_name (NAME) ends in `.' or `..'
2382    This is so we don't try to recurse on `././././. ...' */
2383
2384 static int
2385 basename_is_dot_or_dotdot (const char *name)
2386 {
2387   char const *base = base_name (name);
2388   return DOT_OR_DOTDOT (base);
2389 }
2390
2391 /* Remove any entries from `files' that are for directories,
2392    and queue them to be listed as directories instead.
2393    `dirname' is the prefix to prepend to each dirname
2394    to make it correct relative to ls's working dir.
2395    If IGNORE_DOT_AND_DOT_DOT is nonzero don't treat `.' and `..' as dirs.
2396    This is desirable when processing directories recursively.  */
2397
2398 static void
2399 extract_dirs_from_files (const char *dirname, int ignore_dot_and_dot_dot)
2400 {
2401   register int i, j;
2402
2403   if (*dirname && LOOP_DETECT)
2404     {
2405       /* Insert a marker entry first.  When we dequeue this marker entry,
2406          we'll know that DIRNAME has been processed and may be removed
2407          from the set of active directories.  */
2408       queue_directory (NULL, dirname);
2409     }
2410
2411   /* Queue the directories last one first, because queueing reverses the
2412      order.  */
2413   for (i = files_index - 1; i >= 0; i--)
2414     if ((files[i].filetype == directory || files[i].filetype == arg_directory)
2415         && (!ignore_dot_and_dot_dot
2416             || !basename_is_dot_or_dotdot (files[i].name)))
2417       {
2418         if (files[i].name[0] == '/' || dirname[0] == 0)
2419           {
2420             queue_directory (files[i].name, files[i].linkname);
2421           }
2422         else
2423           {
2424             char *path = path_concat (dirname, files[i].name, NULL);
2425             queue_directory (path, files[i].linkname);
2426             free (path);
2427           }
2428         if (files[i].filetype == arg_directory)
2429           free (files[i].name);
2430       }
2431
2432   /* Now delete the directories from the table, compacting all the remaining
2433      entries.  */
2434
2435   for (i = 0, j = 0; i < files_index; i++)
2436     if (files[i].filetype != arg_directory)
2437       files[j++] = files[i];
2438   files_index = j;
2439 }
2440
2441 /* Use strcoll to compare strings in this locale.  If an error occurs,
2442    report an error and longjmp to failed_strcoll.  */
2443
2444 static jmp_buf failed_strcoll;
2445
2446 static int
2447 xstrcoll (char const *a, char const *b)
2448 {
2449   int diff;
2450   errno = 0;
2451   diff = strcoll (a, b);
2452   if (errno)
2453     {
2454       error (0, errno, _("cannot compare file names %s and %s"),
2455              quote_n (0, a), quote_n (1, b));
2456       exit_status = 1;
2457       longjmp (failed_strcoll, 1);
2458     }
2459   return diff;
2460 }
2461
2462 /* Comparison routines for sorting the files. */
2463
2464 typedef void const *V;
2465
2466 static inline int
2467 cmp_ctime (struct fileinfo const *a, struct fileinfo const *b,
2468            int (*cmp) PARAMS ((char const *, char const *)))
2469 {
2470   int diff = CTIME_CMP (b->stat, a->stat);
2471   return diff ? diff : cmp (a->name, b->name);
2472 }
2473 static int compare_ctime (V a, V b) { return cmp_ctime (a, b, xstrcoll); }
2474 static int compstr_ctime (V a, V b) { return cmp_ctime (a, b, strcmp); }
2475 static int rev_cmp_ctime (V a, V b) { return compare_ctime (b, a); }
2476 static int rev_str_ctime (V a, V b) { return compstr_ctime (b, a); }
2477
2478 static inline int
2479 cmp_mtime (struct fileinfo const *a, struct fileinfo const *b,
2480            int (*cmp) PARAMS((char const *, char const *)))
2481 {
2482   int diff = MTIME_CMP (b->stat, a->stat);
2483   return diff ? diff : cmp (a->name, b->name);
2484 }
2485 static int compare_mtime (V a, V b) { return cmp_mtime (a, b, xstrcoll); }
2486 static int compstr_mtime (V a, V b) { return cmp_mtime (a, b, strcmp); }
2487 static int rev_cmp_mtime (V a, V b) { return compare_mtime (b, a); }
2488 static int rev_str_mtime (V a, V b) { return compstr_mtime (b, a); }
2489
2490 static inline int
2491 cmp_atime (struct fileinfo const *a, struct fileinfo const *b,
2492            int (*cmp) PARAMS ((char const *, char const *)))
2493 {
2494   int diff = ATIME_CMP (b->stat, a->stat);
2495   return diff ? diff : cmp (a->name, b->name);
2496 }
2497 static int compare_atime (V a, V b) { return cmp_atime (a, b, xstrcoll); }
2498 static int compstr_atime (V a, V b) { return cmp_atime (a, b, strcmp); }
2499 static int rev_cmp_atime (V a, V b) { return compare_atime (b, a); }
2500 static int rev_str_atime (V a, V b) { return compstr_atime (b, a); }
2501
2502 static inline int
2503 cmp_size (struct fileinfo const *a, struct fileinfo const *b,
2504           int (*cmp) PARAMS ((char const *, char const *)))
2505 {
2506   int diff = longdiff (b->stat.st_size, a->stat.st_size);
2507   return diff ? diff : cmp (a->name, b->name);
2508 }
2509 static int compare_size (V a, V b) { return cmp_size (a, b, xstrcoll); }
2510 static int compstr_size (V a, V b) { return cmp_size (a, b, strcmp); }
2511 static int rev_cmp_size (V a, V b) { return compare_size (b, a); }
2512 static int rev_str_size (V a, V b) { return compstr_size (b, a); }
2513
2514 static inline int
2515 cmp_version (struct fileinfo const *a, struct fileinfo const *b)
2516 {
2517   return strverscmp (a->name, b->name);
2518 }
2519 static int compare_version (V a, V b) { return cmp_version (a, b); }
2520 static int rev_cmp_version (V a, V b) { return compare_version (b, a); }
2521
2522 static inline int
2523 cmp_name (struct fileinfo const *a, struct fileinfo const *b,
2524           int (*cmp) PARAMS ((char const *, char const *)))
2525 {
2526   return cmp (a->name, b->name);
2527 }
2528 static int compare_name (V a, V b) { return cmp_name (a, b, xstrcoll); }
2529 static int compstr_name (V a, V b) { return cmp_name (a, b, strcmp); }
2530 static int rev_cmp_name (V a, V b) { return compare_name (b, a); }
2531 static int rev_str_name (V a, V b) { return compstr_name (b, a); }
2532
2533 /* Compare file extensions.  Files with no extension are `smallest'.
2534    If extensions are the same, compare by filenames instead. */
2535
2536 static inline int
2537 cmp_extension (struct fileinfo const *a, struct fileinfo const *b,
2538                int (*cmp) PARAMS ((char const *, char const *)))
2539 {
2540   char const *base1 = strrchr (a->name, '.');
2541   char const *base2 = strrchr (b->name, '.');
2542   int diff = cmp (base1 ? base1 : "", base2 ? base2 : "");
2543   return diff ? diff : cmp (a->name, b->name);
2544 }
2545 static int compare_extension (V a, V b) { return cmp_extension (a, b, xstrcoll); }
2546 static int compstr_extension (V a, V b) { return cmp_extension (a, b, strcmp); }
2547 static int rev_cmp_extension (V a, V b) { return compare_extension (b, a); }
2548 static int rev_str_extension (V a, V b) { return compstr_extension (b, a); }
2549
2550 /* Sort the files now in the table.  */
2551
2552 static void
2553 sort_files (void)
2554 {
2555   int (*func) PARAMS ((V, V));
2556
2557   switch (sort_type)
2558     {
2559     case sort_none:
2560       return;
2561     case sort_time:
2562       switch (time_type)
2563         {
2564         case time_ctime:
2565           func = sort_reverse ? rev_cmp_ctime : compare_ctime;
2566           break;
2567         case time_mtime:
2568           func = sort_reverse ? rev_cmp_mtime : compare_mtime;
2569           break;
2570         case time_atime:
2571           func = sort_reverse ? rev_cmp_atime : compare_atime;
2572           break;
2573         default:
2574           abort ();
2575         }
2576       break;
2577     case sort_name:
2578       func = sort_reverse ? rev_cmp_name : compare_name;
2579       break;
2580     case sort_extension:
2581       func = sort_reverse ? rev_cmp_extension : compare_extension;
2582       break;
2583     case sort_size:
2584       func = sort_reverse ? rev_cmp_size : compare_size;
2585       break;
2586     case sort_version:
2587       func = sort_reverse ? rev_cmp_version : compare_version;
2588       break;
2589     default:
2590       abort ();
2591     }
2592
2593   /* Try strcoll.  If it fails, fall back on strcmp.  We can't safely
2594      ignore strcoll failures, as a failing strcoll might be a
2595      comparison function that is not a total order, and if we ignored
2596      the failure this might cause qsort to dump core.  */
2597
2598   if (setjmp (failed_strcoll))
2599     {
2600       switch (sort_type)
2601         {
2602         case sort_time:
2603           switch (time_type)
2604             {
2605             case time_ctime:
2606               func = sort_reverse ? rev_str_ctime : compstr_ctime;
2607               break;
2608             case time_mtime:
2609               func = sort_reverse ? rev_str_mtime : compstr_mtime;
2610               break;
2611             case time_atime:
2612               func = sort_reverse ? rev_str_atime : compstr_atime;
2613               break;
2614             default:
2615               abort ();
2616             }
2617           break;
2618         case sort_name:
2619           func = sort_reverse ? rev_str_name : compstr_name;
2620           break;
2621         case sort_extension:
2622           func = sort_reverse ? rev_str_extension : compstr_extension;
2623           break;
2624         case sort_size:
2625           func = sort_reverse ? rev_str_size : compstr_size;
2626           break;
2627         default:
2628           abort ();
2629         }
2630     }
2631
2632   qsort (files, files_index, sizeof (struct fileinfo), func);
2633 }
2634
2635 /* List all the files now in the table.  */
2636
2637 static void
2638 print_current_files (void)
2639 {
2640   register int i;
2641
2642   switch (format)
2643     {
2644     case one_per_line:
2645       for (i = 0; i < files_index; i++)
2646         {
2647           print_file_name_and_frills (files + i);
2648           putchar ('\n');
2649         }
2650       break;
2651
2652     case many_per_line:
2653       init_column_info ();
2654       print_many_per_line ();
2655       break;
2656
2657     case horizontal:
2658       init_column_info ();
2659       print_horizontal ();
2660       break;
2661
2662     case with_commas:
2663       print_with_commas ();
2664       break;
2665
2666     case long_format:
2667       for (i = 0; i < files_index; i++)
2668         {
2669           print_long_format (files + i);
2670           DIRED_PUTCHAR ('\n');
2671         }
2672       break;
2673     }
2674 }
2675
2676 /* Return the expected number of columns in a long-format time stamp,
2677    or zero if it cannot be calculated.  */
2678
2679 static int
2680 long_time_expected_width (void)
2681 {
2682   static int width = -1;
2683
2684   if (width < 0)
2685     {
2686       time_t epoch = 0;
2687       struct tm const *tm = localtime (&epoch);
2688       char const *fmt = long_time_format[0];
2689       char initbuf[100];
2690       char *buf = initbuf;
2691       size_t bufsize = sizeof initbuf;
2692       size_t len;
2693
2694       for (;;)
2695         {
2696           *buf = '\1';
2697           len = nstrftime (buf, bufsize, fmt, tm, 0, 0);
2698           if (len || ! *buf)
2699             break;
2700           buf = alloca (bufsize *= 2);
2701         }
2702
2703       width = mbsnwidth (buf, len, 0);
2704       if (width < 0)
2705         width = 0;
2706     }
2707
2708   return width;
2709 }
2710
2711 /* Get the current time.  */
2712
2713 static void
2714 get_current_time (void)
2715 {
2716 #if HAVE_CLOCK_GETTIME && defined CLOCK_REALTIME
2717   {
2718     struct timespec timespec;
2719     if (clock_gettime (CLOCK_REALTIME, &timespec) == 0)
2720       {
2721         current_time = timespec.tv_sec;
2722         current_time_ns = timespec.tv_nsec;
2723         return;
2724       }
2725   }
2726 #endif
2727
2728   /* The clock does not have nanosecond resolution, so get the maximum
2729      possible value for the current time that is consistent with the
2730      reported clock.  That way, files are not considered to be in the
2731      future merely because their time stamps have higher resolution
2732      than the clock resolution.  */
2733
2734 #if HAVE_GETTIMEOFDAY
2735   {
2736     struct timeval timeval;
2737     if (gettimeofday (&timeval, NULL) == 0)
2738       {
2739         current_time = timeval.tv_sec;
2740         current_time_ns = timeval.tv_usec * 1000 + 999;
2741         return;
2742       }
2743   }
2744 #endif
2745
2746   current_time = time (NULL);
2747   current_time_ns = 999999999;
2748 }
2749
2750 /* Format into BUFFER the name or id of the user with id U.  Return
2751    the length of the formatted buffer, not counting the terminating
2752    null.  */
2753
2754 static size_t
2755 format_user (char *buffer, uid_t u)
2756 {
2757   char const *name = (numeric_ids ? NULL : getuser (u));
2758   if (name)
2759     sprintf (buffer, "%-8s ", name);
2760   else
2761     sprintf (buffer, "%-8lu ", (unsigned long) u);
2762   return strlen (buffer);
2763 }
2764
2765 /* Print information about F in long format.  */
2766
2767 static void
2768 print_long_format (const struct fileinfo *f)
2769 {
2770   char modebuf[12];
2771   char init_bigbuf
2772     [LONGEST_HUMAN_READABLE + 1         /* inode */
2773      + LONGEST_HUMAN_READABLE + 1       /* size in blocks */
2774      + sizeof (modebuf) - 1 + 1         /* mode string */
2775      + LONGEST_HUMAN_READABLE + 1       /* st_nlink */
2776      + ID_LENGTH_MAX + 1                /* owner name */
2777      + ID_LENGTH_MAX + 1                /* group name */
2778      + ID_LENGTH_MAX + 1                /* author name */
2779      + LONGEST_HUMAN_READABLE + 1       /* major device number */
2780      + LONGEST_HUMAN_READABLE + 1       /* minor device number */
2781      + 35 + 1   /* usual length of time/date -- may be longer; see below */
2782      ];
2783   char *buf = init_bigbuf;
2784   size_t bufsize = sizeof (init_bigbuf);
2785   size_t s;
2786   char *p;
2787   time_t when;
2788   int when_ns IF_LINT (= 0);
2789   struct tm *when_local;
2790
2791   /* Compute mode string.  On most systems, it's based on st_mode.
2792      On systems with migration (via the stat.st_dm_mode field), use
2793      the file's migrated status.  */
2794   mode_string (ST_DM_MODE (f->stat), modebuf);
2795
2796   modebuf[10] = (FILE_HAS_ACL (f) ? '+' : ' ');
2797   modebuf[11] = '\0';
2798
2799   switch (time_type)
2800     {
2801     case time_ctime:
2802       when = f->stat.st_ctime;
2803       when_ns = TIMESPEC_NS (f->stat.st_ctim);
2804       break;
2805     case time_mtime:
2806       when = f->stat.st_mtime;
2807       when_ns = TIMESPEC_NS (f->stat.st_mtim);
2808       break;
2809     case time_atime:
2810       when = f->stat.st_atime;
2811       when_ns = TIMESPEC_NS (f->stat.st_atim);
2812       break;
2813     }
2814
2815   p = buf;
2816
2817   if (print_inode)
2818     {
2819       char hbuf[LONGEST_HUMAN_READABLE + 1];
2820       sprintf (p, "%*s ", INODE_DIGITS,
2821                human_readable ((uintmax_t) f->stat.st_ino, hbuf, 1, 1));
2822       p += strlen (p);
2823     }
2824
2825   if (print_block_size)
2826     {
2827       char hbuf[LONGEST_HUMAN_READABLE + 1];
2828       sprintf (p, "%*s ", block_size_size,
2829                human_readable_inexact ((uintmax_t) ST_NBLOCKS (f->stat), hbuf,
2830                                        ST_NBLOCKSIZE, output_block_size,
2831                                        human_ceiling));
2832       p += strlen (p);
2833     }
2834
2835   /* The last byte of the mode string is the POSIX
2836      "optional alternate access method flag".  */
2837   sprintf (p, "%s %3lu ", modebuf, (unsigned long) f->stat.st_nlink);
2838   p += strlen (p);
2839
2840   if (print_owner)
2841     p += format_user (p, f->stat.st_uid);
2842
2843   if (print_group)
2844     {
2845       char const *group_name = (numeric_ids ? NULL : getgroup (f->stat.st_gid));
2846       if (group_name)
2847         sprintf (p, "%-8s ", group_name);
2848       else
2849         sprintf (p, "%-8lu ", (unsigned long) f->stat.st_gid);
2850       p += strlen (p);
2851     }
2852
2853   if (print_author)
2854     p += format_user (p, f->stat.st_author);
2855
2856   if (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode))
2857     sprintf (p, "%3lu, %3lu ",
2858              (unsigned long) major (f->stat.st_rdev),
2859              (unsigned long) minor (f->stat.st_rdev));
2860   else
2861     {
2862       char hbuf[LONGEST_HUMAN_READABLE + 1];
2863       uintmax_t size = f->stat.st_size;
2864
2865       /* POSIX requires that the size be printed without a sign, even
2866          when negative.  Assume the typical case where negative sizes
2867          are actually positive values that have wrapped around.  */
2868       size += (f->stat.st_size < 0) * ((uintmax_t) OFF_T_MAX - OFF_T_MIN + 1);
2869
2870       sprintf (p, "%8s ",
2871                human_readable (size, hbuf, 1,
2872                                output_block_size < 0 ? output_block_size : 1));
2873     }
2874
2875   p += strlen (p);
2876
2877   if ((when_local = localtime (&when)))
2878     {
2879       time_t six_months_ago;
2880       int recent;
2881       char const *fmt;
2882
2883       /* If the file appears to be in the future, update the current
2884          time, in case the file happens to have been modified since
2885          the last time we checked the clock.  */
2886       if (current_time < when
2887           || (current_time == when && current_time_ns < when_ns))
2888         {
2889           /* Note that get_current_time calls gettimeofday which, on some non-
2890              compliant systems, clobbers the buffer used for localtime's result.
2891              But it's ok here, because we use a gettimeofday wrapper that
2892              saves and restores the buffer around the gettimeofday call.  */
2893           get_current_time ();
2894         }
2895
2896       /* Consider a time to be recent if it is within the past six
2897          months.  A Gregorian year has 365.2425 * 24 * 60 * 60 ==
2898          31556952 seconds on the average.  Write this value as an
2899          integer constant to avoid floating point hassles.  */
2900       six_months_ago = current_time - 31556952 / 2;
2901       recent = (six_months_ago <= when
2902                 && (when < current_time
2903                     || (when == current_time && when_ns <= current_time_ns)));
2904       fmt = long_time_format[recent];
2905
2906       for (;;)
2907         {
2908           char *newbuf;
2909           *p = '\1';
2910           s = nstrftime (p, buf + bufsize - p - 1, fmt,
2911                          when_local, 0, when_ns);
2912           if (s || ! *p)
2913             break;
2914           newbuf = alloca (bufsize *= 2);
2915           memcpy (newbuf, buf, p - buf);
2916           p = newbuf + (p - buf);
2917           buf = newbuf;
2918         }
2919
2920       p += s;
2921       *p++ = ' ';
2922
2923       /* NUL-terminate the string -- fputs (via DIRED_FPUTS) requires it.  */
2924       *p = '\0';
2925     }
2926   else
2927     {
2928       /* The time cannot be represented as a local time;
2929          print it as a huge integer number of seconds.  */
2930       char hbuf[LONGEST_HUMAN_READABLE + 1];
2931       int width = long_time_expected_width ();
2932
2933       if (when < 0)
2934         {
2935           const char *num = human_readable (- (uintmax_t) when, hbuf, 1, 1);
2936           int sign_width = width - strlen (num);
2937           sprintf (p, "%*s%s ", sign_width < 0 ? 0 : sign_width, "-", num);
2938         }
2939       else
2940         sprintf (p, "%*s ", width,
2941                  human_readable ((uintmax_t) when, hbuf, 1, 1));
2942
2943       p += strlen (p);
2944     }
2945
2946   DIRED_INDENT ();
2947   DIRED_FPUTS (buf, stdout, p - buf);
2948   print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok,
2949                            &dired_obstack);
2950
2951   if (f->filetype == symbolic_link)
2952     {
2953       if (f->linkname)
2954         {
2955           DIRED_FPUTS_LITERAL (" -> ", stdout);
2956           print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1,
2957                                    NULL);
2958           if (indicator_style != none)
2959             print_type_indicator (f->linkmode);
2960         }
2961     }
2962   else if (indicator_style != none)
2963     print_type_indicator (f->stat.st_mode);
2964 }
2965
2966 /* Output to OUT a quoted representation of the file name NAME,
2967    using OPTIONS to control quoting.  Produce no output if OUT is NULL.
2968    Return the number of screen columns occupied by NAME's quoted
2969    representation.  */
2970
2971 static size_t
2972 quote_name (FILE *out, const char *name, struct quoting_options const *options)
2973 {
2974   char smallbuf[BUFSIZ];
2975   size_t len = quotearg_buffer (smallbuf, sizeof smallbuf, name, -1, options);
2976   char *buf;
2977   int displayed_width;
2978
2979   if (len < sizeof smallbuf)
2980     buf = smallbuf;
2981   else
2982     {
2983       buf = (char *) alloca (len + 1);
2984       quotearg_buffer (buf, len + 1, name, -1, options);
2985     }
2986
2987   if (qmark_funny_chars)
2988     {
2989 #if HAVE_MBRTOWC
2990       if (MB_CUR_MAX > 1)
2991         {
2992           char const *p = buf;
2993           char const *plimit = buf + len;
2994           char *q = buf;
2995           displayed_width = 0;
2996
2997           while (p < plimit)
2998             switch (*p)
2999               {
3000                 case ' ': case '!': case '"': case '#': case '%':
3001                 case '&': case '\'': case '(': case ')': case '*':
3002                 case '+': case ',': case '-': case '.': case '/':
3003                 case '0': case '1': case '2': case '3': case '4':
3004                 case '5': case '6': case '7': case '8': case '9':
3005                 case ':': case ';': case '<': case '=': case '>':
3006                 case '?':
3007                 case 'A': case 'B': case 'C': case 'D': case 'E':
3008                 case 'F': case 'G': case 'H': case 'I': case 'J':
3009                 case 'K': case 'L': case 'M': case 'N': case 'O':
3010                 case 'P': case 'Q': case 'R': case 'S': case 'T':
3011                 case 'U': case 'V': case 'W': case 'X': case 'Y':
3012                 case 'Z':
3013                 case '[': case '\\': case ']': case '^': case '_':
3014                 case 'a': case 'b': case 'c': case 'd': case 'e':
3015                 case 'f': case 'g': case 'h': case 'i': case 'j':
3016                 case 'k': case 'l': case 'm': case 'n': case 'o':
3017                 case 'p': case 'q': case 'r': case 's': case 't':
3018                 case 'u': case 'v': case 'w': case 'x': case 'y':
3019                 case 'z': case '{': case '|': case '}': case '~':
3020                   /* These characters are printable ASCII characters.  */
3021                   *q++ = *p++;
3022                   displayed_width += 1;
3023                   break;
3024                 default:
3025                   /* If we have a multibyte sequence, copy it until we
3026                      reach its end, replacing each non-printable multibyte
3027                      character with a single question mark.  */
3028                   {
3029                     mbstate_t mbstate;
3030                     memset (&mbstate, 0, sizeof mbstate);
3031                     do
3032                       {
3033                         wchar_t wc;
3034                         size_t bytes;
3035                         int w;
3036
3037                         bytes = mbrtowc (&wc, p, plimit - p, &mbstate);
3038
3039                         if (bytes == (size_t) -1)
3040                           {
3041                             /* An invalid multibyte sequence was
3042                                encountered.  Skip one input byte, and
3043                                put a question mark.  */
3044                             p++;
3045                             *q++ = '?';
3046                             displayed_width += 1;
3047                             break;
3048                           }
3049
3050                         if (bytes == (size_t) -2)
3051                           {
3052                             /* An incomplete multibyte character
3053                                at the end.  Replace it entirely with
3054                                a question mark.  */
3055                             p = plimit;
3056                             *q++ = '?';
3057                             displayed_width += 1;
3058                             break;
3059                           }
3060
3061                         if (bytes == 0)
3062                           /* A null wide character was encountered.  */
3063                           bytes = 1;
3064
3065                         w = wcwidth (wc);
3066                         if (w >= 0)
3067                           {
3068                             /* A printable multibyte character.
3069                                Keep it.  */
3070                             for (; bytes > 0; --bytes)
3071                               *q++ = *p++;
3072                             displayed_width += w;
3073                           }
3074                         else
3075                           {
3076                             /* An unprintable multibyte character.
3077                                Replace it entirely with a question
3078                                mark.  */
3079                             p += bytes;
3080                             *q++ = '?';
3081                             displayed_width += 1;
3082                           }
3083                       }
3084                     while (! mbsinit (&mbstate));
3085                   }
3086                   break;
3087               }
3088
3089           /* The buffer may have shrunk.  */
3090           len = q - buf;
3091         }
3092       else
3093 #endif
3094         {
3095           char *p = buf;
3096           char const *plimit = buf + len;
3097
3098           while (p < plimit)
3099             {
3100               if (! ISPRINT ((unsigned char) *p))
3101                 *p = '?';
3102               p++;
3103             }
3104           displayed_width = len;
3105         }
3106     }
3107   else
3108     {
3109       /* Assume unprintable characters have a displayed_width of 1.  */
3110 #if HAVE_MBRTOWC
3111       if (MB_CUR_MAX > 1)
3112         displayed_width = mbsnwidth (buf, len, 0);
3113       else
3114 #endif
3115         displayed_width = len;
3116     }
3117
3118   if (out != NULL)
3119     fwrite (buf, 1, len, out);
3120   return displayed_width;
3121 }
3122
3123 static void
3124 print_name_with_quoting (const char *p, mode_t mode, int linkok,
3125                          struct obstack *stack)
3126 {
3127   if (print_with_color)
3128     print_color_indicator (p, mode, linkok);
3129
3130   if (stack)
3131     PUSH_CURRENT_DIRED_POS (stack);
3132
3133   dired_pos += quote_name (stdout, p, filename_quoting_options);
3134
3135   if (stack)
3136     PUSH_CURRENT_DIRED_POS (stack);
3137
3138   if (print_with_color)
3139     prep_non_filename_text ();
3140 }
3141
3142 static void
3143 prep_non_filename_text (void)
3144 {
3145   if (color_indicator[C_END].string != NULL)
3146     put_indicator (&color_indicator[C_END]);
3147   else
3148     {
3149       put_indicator (&color_indicator[C_LEFT]);
3150       put_indicator (&color_indicator[C_NORM]);
3151       put_indicator (&color_indicator[C_RIGHT]);
3152     }
3153 }
3154
3155 /* Print the file name of `f' with appropriate quoting.
3156    Also print file size, inode number, and filetype indicator character,
3157    as requested by switches.  */
3158
3159 static void
3160 print_file_name_and_frills (const struct fileinfo *f)
3161 {
3162   char buf[LONGEST_HUMAN_READABLE + 1];
3163
3164   if (print_inode)
3165     printf ("%*s ", INODE_DIGITS,
3166             human_readable ((uintmax_t) f->stat.st_ino, buf, 1, 1));
3167
3168   if (print_block_size)
3169     printf ("%*s ", block_size_size,
3170             human_readable_inexact ((uintmax_t) ST_NBLOCKS (f->stat), buf,
3171                                     ST_NBLOCKSIZE, output_block_size,
3172                                     human_ceiling));
3173
3174   print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok, NULL);
3175
3176   if (indicator_style != none)
3177     print_type_indicator (f->stat.st_mode);
3178 }
3179
3180 static void
3181 print_type_indicator (mode_t mode)
3182 {
3183   int c;
3184
3185   if (S_ISREG (mode))
3186     {
3187       if (indicator_style == classify && (mode & S_IXUGO))
3188         c ='*';
3189       else
3190         c = 0;
3191     }
3192   else
3193     {
3194       if (S_ISDIR (mode))
3195         c = '/';
3196       else if (S_ISLNK (mode))
3197         c = '@';
3198       else if (S_ISFIFO (mode))
3199         c = '|';
3200       else if (S_ISSOCK (mode))
3201         c = '=';
3202       else if (S_ISDOOR (mode))
3203         c = '>';
3204       else
3205         c = 0;
3206     }
3207
3208   if (c)
3209     DIRED_PUTCHAR (c);
3210 }
3211
3212 static void
3213 print_color_indicator (const char *name, mode_t mode, int linkok)
3214 {
3215   int type = C_FILE;
3216   struct color_ext_type *ext;   /* Color extension */
3217   size_t len;                   /* Length of name */
3218
3219   /* Is this a nonexistent file?  If so, linkok == -1.  */
3220
3221   if (linkok == -1 && color_indicator[C_MISSING].string != NULL)
3222     {
3223       ext = NULL;
3224       type = C_MISSING;
3225     }
3226   else
3227     {
3228       if (S_ISDIR (mode))
3229         type = C_DIR;
3230       else if (S_ISLNK (mode))
3231         type = ((!linkok && color_indicator[C_ORPHAN].string)
3232                 ? C_ORPHAN : C_LINK);
3233       else if (S_ISFIFO (mode))
3234         type = C_FIFO;
3235       else if (S_ISSOCK (mode))
3236         type = C_SOCK;
3237       else if (S_ISBLK (mode))
3238         type = C_BLK;
3239       else if (S_ISCHR (mode))
3240         type = C_CHR;
3241       else if (S_ISDOOR (mode))
3242         type = C_DOOR;
3243
3244       if (type == C_FILE && (mode & S_IXUGO) != 0)
3245         type = C_EXEC;
3246
3247       /* Check the file's suffix only if still classified as C_FILE.  */
3248       ext = NULL;
3249       if (type == C_FILE)
3250         {
3251           /* Test if NAME has a recognized suffix.  */
3252
3253           len = strlen (name);
3254           name += len;          /* Pointer to final \0.  */
3255           for (ext = color_ext_list; ext != NULL; ext = ext->next)
3256             {
3257               if ((size_t) ext->ext.len <= len
3258                   && strncmp (name - ext->ext.len, ext->ext.string,
3259                               ext->ext.len) == 0)
3260                 break;
3261             }
3262         }
3263     }
3264
3265   put_indicator (&color_indicator[C_LEFT]);
3266   put_indicator (ext ? &(ext->seq) : &color_indicator[type]);
3267   put_indicator (&color_indicator[C_RIGHT]);
3268 }
3269
3270 /* Output a color indicator (which may contain nulls).  */
3271 static void
3272 put_indicator (const struct bin_str *ind)
3273 {
3274   register int i;
3275   register const char *p;
3276
3277   p = ind->string;
3278
3279   for (i = ind->len; i > 0; --i)
3280     putchar (*(p++));
3281 }
3282
3283 static int
3284 length_of_file_name_and_frills (const struct fileinfo *f)
3285 {
3286   register int len = 0;
3287
3288   if (print_inode)
3289     len += INODE_DIGITS + 1;
3290
3291   if (print_block_size)
3292     len += 1 + block_size_size;
3293
3294   len += quote_name (NULL, f->name, filename_quoting_options);
3295
3296   if (indicator_style != none)
3297     {
3298       mode_t filetype = f->stat.st_mode;
3299
3300       if (S_ISREG (filetype))
3301         {
3302           if (indicator_style == classify
3303               && (f->stat.st_mode & S_IXUGO))
3304             len += 1;
3305         }
3306       else if (S_ISDIR (filetype)
3307                || S_ISLNK (filetype)
3308                || S_ISFIFO (filetype)
3309                || S_ISSOCK (filetype)
3310                || S_ISDOOR (filetype)
3311                )
3312         len += 1;
3313     }
3314
3315   return len;
3316 }
3317
3318 static void
3319 print_many_per_line (void)
3320 {
3321   struct column_info *line_fmt;
3322   int filesno;                  /* Index into files. */
3323   int row;                      /* Current row. */
3324   int max_name_length;          /* Length of longest file name + frills. */
3325   int name_length;              /* Length of each file name + frills. */
3326   int pos;                      /* Current character column. */
3327   int cols;                     /* Number of files across. */
3328   int rows;                     /* Maximum number of files down. */
3329   int max_cols;
3330
3331   /* Normally the maximum number of columns is determined by the
3332      screen width.  But if few files are available this might limit it
3333      as well.  */
3334   max_cols = max_idx > files_index ? files_index : max_idx;
3335
3336   /* Compute the maximum number of possible columns.  */
3337   for (filesno = 0; filesno < files_index; ++filesno)
3338     {
3339       int i;
3340
3341       name_length = length_of_file_name_and_frills (files + filesno);
3342
3343       for (i = 0; i < max_cols; ++i)
3344         {
3345           if (column_info[i].valid_len)
3346             {
3347               int idx = filesno / ((files_index + i) / (i + 1));
3348               int real_length = name_length + (idx == i ? 0 : 2);
3349
3350               if (real_length > column_info[i].col_arr[idx])
3351                 {
3352                   column_info[i].line_len += (real_length
3353                                            - column_info[i].col_arr[idx]);
3354                   column_info[i].col_arr[idx] = real_length;
3355                   column_info[i].valid_len = column_info[i].line_len < line_length;
3356                 }
3357             }
3358         }
3359     }
3360
3361   /* Find maximum allowed columns.  */
3362   for (cols = max_cols; cols > 1; --cols)
3363     {
3364       if (column_info[cols - 1].valid_len)
3365         break;
3366     }
3367
3368   line_fmt = &column_info[cols - 1];
3369
3370   /* Calculate the number of rows that will be in each column except possibly
3371      for a short column on the right. */
3372   rows = files_index / cols + (files_index % cols != 0);
3373
3374   for (row = 0; row < rows; row++)
3375     {
3376       int col = 0;
3377       filesno = row;
3378       pos = 0;
3379       /* Print the next row.  */
3380       while (1)
3381         {
3382           print_file_name_and_frills (files + filesno);
3383           name_length = length_of_file_name_and_frills (files + filesno);
3384           max_name_length = line_fmt->col_arr[col++];
3385
3386           filesno += rows;
3387           if (filesno >= files_index)
3388             break;
3389
3390           indent (pos + name_length, pos + max_name_length);
3391           pos += max_name_length;
3392         }
3393       putchar ('\n');
3394     }
3395 }
3396
3397 static void
3398 print_horizontal (void)
3399 {
3400   struct column_info *line_fmt;
3401   int filesno;
3402   int max_name_length;
3403   int name_length;
3404   int cols;
3405   int pos;
3406   int max_cols;
3407
3408   /* Normally the maximum number of columns is determined by the
3409      screen width.  But if few files are available this might limit it
3410      as well.  */
3411   max_cols = max_idx > files_index ? files_index : max_idx;
3412
3413   /* Compute the maximum file name length.  */
3414   max_name_length = 0;
3415   for (filesno = 0; filesno < files_index; ++filesno)
3416     {
3417       int i;
3418
3419       name_length = length_of_file_name_and_frills (files + filesno);
3420
3421       for (i = 0; i < max_cols; ++i)
3422         {
3423           if (column_info[i].valid_len)
3424             {
3425               int idx = filesno % (i + 1);
3426               int real_length = name_length + (idx == i ? 0 : 2);
3427
3428               if (real_length > column_info[i].col_arr[idx])
3429                 {
3430                   column_info[i].line_len += (real_length
3431                                            - column_info[i].col_arr[idx]);
3432                   column_info[i].col_arr[idx] = real_length;
3433                   column_info[i].valid_len = column_info[i].line_len < line_length;
3434                 }
3435             }
3436         }
3437     }
3438
3439   /* Find maximum allowed columns.  */
3440   for (cols = max_cols; cols > 1; --cols)
3441     {
3442       if (column_info[cols - 1].valid_len)
3443         break;
3444     }
3445
3446   line_fmt = &column_info[cols - 1];
3447
3448   pos = 0;
3449
3450   /* Print first entry.  */
3451   print_file_name_and_frills (files);
3452   name_length = length_of_file_name_and_frills (files);
3453   max_name_length = line_fmt->col_arr[0];
3454
3455   /* Now the rest.  */
3456   for (filesno = 1; filesno < files_index; ++filesno)
3457     {
3458       int col = filesno % cols;
3459
3460       if (col == 0)
3461         {
3462           putchar ('\n');
3463           pos = 0;
3464         }
3465       else
3466         {
3467           indent (pos + name_length, pos + max_name_length);
3468           pos += max_name_length;
3469         }
3470
3471       print_file_name_and_frills (files + filesno);
3472
3473       name_length = length_of_file_name_and_frills (files + filesno);
3474       max_name_length = line_fmt->col_arr[col];
3475     }
3476   putchar ('\n');
3477 }
3478
3479 static void
3480 print_with_commas (void)
3481 {
3482   int filesno;
3483   int pos, old_pos;
3484
3485   pos = 0;
3486
3487   for (filesno = 0; filesno < files_index; filesno++)
3488     {
3489       old_pos = pos;
3490
3491       pos += length_of_file_name_and_frills (files + filesno);
3492       if (filesno + 1 < files_index)
3493         pos += 2;               /* For the comma and space */
3494
3495       if (old_pos != 0 && pos >= line_length)
3496         {
3497           putchar ('\n');
3498           pos -= old_pos;
3499         }
3500
3501       print_file_name_and_frills (files + filesno);
3502       if (filesno + 1 < files_index)
3503         {
3504           putchar (',');
3505           putchar (' ');
3506         }
3507     }
3508   putchar ('\n');
3509 }
3510
3511 /* Assuming cursor is at position FROM, indent up to position TO.
3512    Use a TAB character instead of two or more spaces whenever possible.  */
3513
3514 static void
3515 indent (int from, int to)
3516 {
3517   while (from < to)
3518     {
3519       if (tabsize > 0 && to / tabsize > (from + 1) / tabsize)
3520         {
3521           putchar ('\t');
3522           from += tabsize - from % tabsize;
3523         }
3524       else
3525         {
3526           putchar (' ');
3527           from++;
3528         }
3529     }
3530 }
3531
3532 /* Put DIRNAME/NAME into DEST, handling `.' and `/' properly. */
3533 /* FIXME: maybe remove this function someday.  See about using a
3534    non-malloc'ing version of path_concat.  */
3535
3536 static void
3537 attach (char *dest, const char *dirname, const char *name)
3538 {
3539   const char *dirnamep = dirname;
3540
3541   /* Copy dirname if it is not ".". */
3542   if (dirname[0] != '.' || dirname[1] != 0)
3543     {
3544       while (*dirnamep)
3545         *dest++ = *dirnamep++;
3546       /* Add '/' if `dirname' doesn't already end with it. */
3547       if (dirnamep > dirname && dirnamep[-1] != '/')
3548         *dest++ = '/';
3549     }
3550   while (*name)
3551     *dest++ = *name++;
3552   *dest = 0;
3553 }
3554
3555 static void
3556 init_column_info (void)
3557 {
3558   int i;
3559   int allocate = 0;
3560
3561   max_idx = line_length / MIN_COLUMN_WIDTH;
3562   if (max_idx == 0)
3563     max_idx = 1;
3564
3565   if (column_info == NULL)
3566     {
3567       column_info = XMALLOC (struct column_info, max_idx);
3568       allocate = 1;
3569     }
3570
3571   for (i = 0; i < max_idx; ++i)
3572     {
3573       int j;
3574
3575       column_info[i].valid_len = 1;
3576       column_info[i].line_len = (i + 1) * MIN_COLUMN_WIDTH;
3577
3578       if (allocate)
3579         column_info[i].col_arr = XMALLOC (int, i + 1);
3580
3581       for (j = 0; j <= i; ++j)
3582         column_info[i].col_arr[j] = MIN_COLUMN_WIDTH;
3583     }
3584 }
3585
3586 void
3587 usage (int status)
3588 {
3589   if (status != 0)
3590     fprintf (stderr, _("Try `%s --help' for more information.\n"),
3591              program_name);
3592   else
3593     {
3594       printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);
3595       fputs (_("\
3596 List information about the FILEs (the current directory by default).\n\
3597 Sort entries alphabetically if none of -cftuSUX nor --sort.\n\
3598 \n\
3599 "), stdout);
3600       fputs (_("\
3601 Mandatory arguments to long options are mandatory for short options too.\n\
3602 "), stdout);
3603       fputs (_("\
3604   -a, --all                  do not hide entries starting with .\n\
3605   -A, --almost-all           do not list implied . and ..\n\
3606       --author               print the author of each file\n\
3607   -b, --escape               print octal escapes for nongraphic characters\n\
3608 "), stdout);
3609       fputs (_("\
3610       --block-size=SIZE      use SIZE-byte blocks\n\
3611   -B, --ignore-backups       do not list implied entries ending with ~\n\
3612   -c                         with -lt: sort by, and show, ctime (time of last\n\
3613                                modification of file status information)\n\
3614                                with -l: show ctime and sort by name\n\
3615                                otherwise: sort by ctime\n\
3616 "), stdout);
3617       fputs (_("\
3618   -C                         list entries by columns\n\
3619       --color[=WHEN]         control whether color is used to distinguish file\n\
3620                                types.  WHEN may be `never', `always', or `auto'\n\
3621   -d, --directory            list directory entries instead of contents\n\
3622   -D, --dired                generate output designed for Emacs' dired mode\n\
3623 "), stdout);
3624       fputs (_("\
3625   -f                         do not sort, enable -aU, disable -lst\n\
3626   -F, --classify             append indicator (one of */=@|) to entries\n\
3627       --format=WORD          across -x, commas -m, horizontal -x, long -l,\n\
3628                                single-column -1, verbose -l, vertical -C\n\
3629       --full-time            like -l --time-style=full-iso\n\
3630 "), stdout);
3631       fputs (_("\
3632   -g                         like -l, but do not list owner\n\
3633   -G, --no-group             inhibit display of group information\n\
3634   -h, --human-readable  print sizes in human readable format (e.g., 1K 234M 2G)\n\
3635       --si                   likewise, but use powers of 1000 not 1024\n\
3636   -H, --dereference-command-line  follow symbolic links on the command line\n\
3637 "), stdout);
3638       fputs (_("\
3639       --indicator-style=WORD append indicator with style WORD to entry names:\n\
3640                                none (default), classify (-F), file-type (-p)\n\
3641   -i, --inode                print index number of each file\n\
3642   -I, --ignore=PATTERN       do not list implied entries matching shell PATTERN\n\
3643   -k                         like --block-size=1K\n\
3644 "), stdout);
3645       fputs (_("\
3646   -l                         use a long listing format\n\
3647   -L, --dereference          when showing file information for a symbolic\n\
3648                                link, show information for the file the link\n\
3649                                references rather than for the link itself\n\
3650   -m                         fill width with a comma separated list of entries\n\
3651 "), stdout);
3652       fputs (_("\
3653   -n, --numeric-uid-gid      like -l, but list numeric UIDs and GIDs\n\
3654   -N, --literal              print raw entry names (don't treat e.g. control\n\
3655                                characters specially)\n\
3656   -o                         like -l, but do not list group information\n\
3657   -p, --file-type            append indicator (one of /=@|) to entries\n\
3658 "), stdout);
3659       fputs (_("\
3660   -q, --hide-control-chars   print ? instead of non graphic characters\n\
3661       --show-control-chars   show non graphic characters as-is (default\n\
3662                              unless program is `ls' and output is a terminal)\n\
3663   -Q, --quote-name           enclose entry names in double quotes\n\
3664       --quoting-style=WORD   use quoting style WORD for entry names:\n\
3665                                literal, locale, shell, shell-always, c, escape\n\
3666 "), stdout);
3667       fputs (_("\
3668   -r, --reverse              reverse order while sorting\n\
3669   -R, --recursive            list subdirectories recursively\n\
3670   -s, --size                 print size of each file, in blocks\n\
3671 "), stdout);
3672       fputs (_("\
3673   -S                         sort by file size\n\
3674       --sort=WORD            extension -X, none -U, size -S, time -t,\n\
3675                                version -v\n\
3676                              status -c, time -t, atime -u, access -u, use -u\n\
3677       --time=WORD            show time as WORD instead of modification time:\n\
3678                                atime, access, use, ctime or status; use\n\
3679                                specified time as sort key if --sort=time\n\
3680 "), stdout);
3681       fputs (_("\
3682       --time-style=WORD      show times using style WORD:\n\
3683                                full-iso, iso, locale, posix-iso, +FORMAT\n\
3684                              FORMAT is interpreted like `date'; if FORMAT is\n\
3685                              FORMAT1<newline>FORMAT2, FORMAT1 applies to\n\
3686                              non-recent files and FORMAT2 to recent files\n\
3687   -t                         sort by modification time\n\
3688   -T, --tabsize=COLS         assume tab stops at each COLS instead of 8\n\
3689 "), stdout);
3690       fputs (_("\
3691   -u                         with -lt: sort by, and show, access time\n\
3692                                with -l: show access time and sort by name\n\
3693                                otherwise: sort by access time\n\
3694   -U                         do not sort; list entries in directory order\n\
3695   -v                         sort by version\n\
3696 "), stdout);
3697       fputs (_("\
3698   -w, --width=COLS           assume screen width instead of current value\n\
3699   -x                         list entries by lines instead of by columns\n\
3700   -X                         sort alphabetically by entry extension\n\
3701   -1                         list one file per line\n\
3702 "), stdout);
3703       fputs (HELP_OPTION_DESCRIPTION, stdout);
3704       fputs (VERSION_OPTION_DESCRIPTION, stdout);
3705       fputs (_("\n\
3706 SIZE may be (or may be an integer optionally followed by) one of following:\n\
3707 kB 1000, K 1024, MB 1,000,000, M 1,048,576, and so on for G, T, P, E, Z, Y.\n\
3708 "), stdout);
3709       fputs (_("\
3710 \n\
3711 By default, color is not used to distinguish types of files.  That is\n\
3712 equivalent to using --color=none.  Using the --color option without the\n\
3713 optional WHEN argument is equivalent to using --color=always.  With\n\
3714 --color=auto, color codes are output only if standard output is connected\n\
3715 to a terminal (tty).\n\
3716 "), stdout);
3717       puts (_("\nReport bugs to <bug-fileutils@gnu.org>."));
3718     }
3719   exit (status);
3720 }