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