(SA_NOCLDSTOP): Define to 0 if not defined.
[platform/upstream/coreutils.git] / src / ls.c
1 /* `dir', `vdir' and `ls' directory listing programs for GNU.
2    Copyright (C) 85, 88, 90, 91, 1995-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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 /* If ls_mode is LS_MULTI_COL,
19    the multi-column format is the default regardless
20    of the type of output device.
21    This is for the `dir' program.
22
23    If ls_mode is LS_LONG_FORMAT,
24    the long format is the default regardless of the
25    type of output device.
26    This is for the `vdir' program.
27
28    If ls_mode is LS_LS,
29    the output format depends on whether the output
30    device is a terminal.
31    This is for the `ls' program.  */
32
33 /* Written by Richard Stallman and David MacKenzie.  */
34
35 /* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
36    Flaherty <dennisf@denix.elk.miles.com> based on original patches by
37    Greg Lee <lee@uhunix.uhcc.hawaii.edu>.  */
38
39 #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 "hard-locale.h"
112 #include "hash.h"
113 #include "human.h"
114 #include "filemode.h"
115 #include "inttostr.h"
116 #include "ls.h"
117 #include "mbswidth.h"
118 #include "obstack.h"
119 #include "path-concat.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_path (const char *path, const char *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 the program was run with, stripped of any leading path.  */
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    `classify' means mention file types and mark executables.
467    `file_type' means mention only file types.
468
469    Controlled by -F, -p, and --indicator-style.  */
470
471 enum indicator_style
472   {
473     none,       /*     --indicator-style=none */
474     classify,   /* -F, --indicator-style=classify */
475     file_type   /* -p, --indicator-style=file-type */
476   };
477
478 static enum indicator_style indicator_style;
479
480 /* Names of indicator styles.  */
481 static char const *const indicator_style_args[] =
482 {
483   "none", "classify", "file-type", NULL
484 };
485
486 static enum indicator_style const indicator_style_types[]=
487 {
488   none, classify, file_type
489 };
490
491 /* True means use colors to mark types.  Also define the different
492    colors as well as the stuff for the LS_COLORS environment variable.
493    The LS_COLORS variable is now in a termcap-like format.  */
494
495 static bool print_with_color;
496
497 enum color_type
498   {
499     color_never,                /* 0: default or --color=never */
500     color_always,               /* 1: --color=always */
501     color_if_tty                /* 2: --color=tty */
502   };
503
504 enum Dereference_symlink
505   {
506     DEREF_UNDEFINED = 1,
507     DEREF_NEVER,
508     DEREF_COMMAND_LINE_ARGUMENTS,       /* -H */
509     DEREF_COMMAND_LINE_SYMLINK_TO_DIR,  /* the default, in certain cases */
510     DEREF_ALWAYS                        /* -L */
511   };
512
513 enum indicator_no
514   {
515     C_LEFT, C_RIGHT, C_END, C_NORM, C_FILE, C_DIR, C_LINK, C_FIFO, C_SOCK,
516     C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR
517   };
518
519 static const char *const indicator_name[]=
520   {
521     "lc", "rc", "ec", "no", "fi", "di", "ln", "pi", "so",
522     "bd", "cd", "mi", "or", "ex", "do", NULL
523   };
524
525 struct color_ext_type
526   {
527     struct bin_str ext;         /* The extension we're looking for */
528     struct bin_str seq;         /* The sequence to output when we do */
529     struct color_ext_type *next;        /* Next in list */
530   };
531
532 static struct bin_str color_indicator[] =
533   {
534     { LEN_STR_PAIR ("\033[") },         /* lc: Left of color sequence */
535     { LEN_STR_PAIR ("m") },             /* rc: Right of color sequence */
536     { 0, NULL },                        /* ec: End color (replaces lc+no+rc) */
537     { LEN_STR_PAIR ("0") },             /* no: Normal */
538     { LEN_STR_PAIR ("0") },             /* fi: File: default */
539     { LEN_STR_PAIR ("01;34") },         /* di: Directory: bright blue */
540     { LEN_STR_PAIR ("01;36") },         /* ln: Symlink: bright cyan */
541     { LEN_STR_PAIR ("33") },            /* pi: Pipe: yellow/brown */
542     { LEN_STR_PAIR ("01;35") },         /* so: Socket: bright magenta */
543     { LEN_STR_PAIR ("01;33") },         /* bd: Block device: bright yellow */
544     { LEN_STR_PAIR ("01;33") },         /* cd: Char device: bright yellow */
545     { 0, NULL },                        /* mi: Missing file: undefined */
546     { 0, NULL },                        /* or: Orphaned symlink: undefined */
547     { LEN_STR_PAIR ("01;32") },         /* ex: Executable: bright green */
548     { LEN_STR_PAIR ("01;35") }          /* do: Door: bright magenta */
549   };
550
551 /* FIXME: comment  */
552 static struct color_ext_type *color_ext_list = NULL;
553
554 /* Buffer for color sequences */
555 static char *color_buf;
556
557 /* True means to check for orphaned symbolic link, for displaying
558    colors.  */
559
560 static bool check_symlink_color;
561
562 /* True means mention the inode number of each file.  -i  */
563
564 static bool print_inode;
565
566 /* What to do with symbolic links.  Affected by -d, -F, -H, -l (and
567    other options that imply -l), and -L.  */
568
569 static enum Dereference_symlink dereference;
570
571 /* True means when a directory is found, display info on its
572    contents.  -R  */
573
574 static bool recursive;
575
576 /* True means when an argument is a directory name, display info
577    on it itself.  -d  */
578
579 static bool immediate_dirs;
580
581 /* Which files to ignore.  */
582
583 static enum
584 {
585   /* Ignore files whose names start with `.', and files specified by
586      --hide and --ignore.  */
587   IGNORE_DEFAULT,
588
589   /* Ignore `.', `..', and files specified by --ignore.  */
590   IGNORE_DOT_AND_DOTDOT,
591
592   /* Ignore only files specified by --ignore.  */
593   IGNORE_MINIMAL
594 } ignore_mode;
595
596 /* A linked list of shell-style globbing patterns.  If a non-argument
597    file name matches any of these patterns, it is ignored.
598    Controlled by -I.  Multiple -I options accumulate.
599    The -B option adds `*~' and `.*~' to this list.  */
600
601 struct ignore_pattern
602   {
603     const char *pattern;
604     struct ignore_pattern *next;
605   };
606
607 static struct ignore_pattern *ignore_patterns;
608
609 /* Similar to IGNORE_PATTERNS, except that -a or -A causes this
610    variable itself to be ignored.  */
611 static struct ignore_pattern *hide_patterns;
612
613 /* True means output nongraphic chars in file names as `?'.
614    (-q, --hide-control-chars)
615    qmark_funny_chars and the quoting style (-Q, --quoting-style=WORD) are
616    independent.  The algorithm is: first, obey the quoting style to get a
617    string representing the file name;  then, if qmark_funny_chars is set,
618    replace all nonprintable chars in that string with `?'.  It's necessary
619    to replace nonprintable chars even in quoted strings, because we don't
620    want to mess up the terminal if control chars get sent to it, and some
621    quoting methods pass through control chars as-is.  */
622 static bool qmark_funny_chars;
623
624 /* Quoting options for file and dir name output.  */
625
626 static struct quoting_options *filename_quoting_options;
627 static struct quoting_options *dirname_quoting_options;
628
629 /* The number of chars per hardware tab stop.  Setting this to zero
630    inhibits the use of TAB characters for separating columns.  -T */
631 static size_t tabsize;
632
633 /* True means print each directory name before listing it.  */
634
635 static bool print_dir_name;
636
637 /* The line length to use for breaking lines in many-per-line format.
638    Can be set with -w.  */
639
640 static size_t line_length;
641
642 /* If true, the file listing format requires that stat be called on
643    each file.  */
644
645 static bool format_needs_stat;
646
647 /* Similar to `format_needs_stat', but set if only the file type is
648    needed.  */
649
650 static bool format_needs_type;
651
652 /* An arbitrary limit on the number of bytes in a printed time stamp.
653    This is set to a relatively small value to avoid the need to worry
654    about denial-of-service attacks on servers that run "ls" on behalf
655    of remote clients.  1000 bytes should be enough for any practical
656    time stamp format.  */
657
658 enum { TIME_STAMP_LEN_MAXIMUM = MAX (1000, INT_STRLEN_BOUND (time_t)) };
659
660 /* strftime formats for non-recent and recent files, respectively, in
661    -l output.  */
662
663 static char const *long_time_format[2] =
664   {
665     /* strftime format for non-recent files (older than 6 months), in
666        -l output when --time-style=locale is specified.  This should
667        contain the year, month and day (at least), in an order that is
668        understood by people in your locale's territory.
669        Please try to keep the number of used screen columns small,
670        because many people work in windows with only 80 columns.  But
671        make this as wide as the other string below, for recent files.  */
672     N_("%b %e  %Y"),
673     /* strftime format for recent files (younger than 6 months), in
674        -l output when --time-style=locale is specified.  This should
675        contain the month, day and time (at least), in an order that is
676        understood by people in your locale's territory.
677        Please try to keep the number of used screen columns small,
678        because many people work in windows with only 80 columns.  But
679        make this as wide as the other string above, for non-recent files.  */
680     N_("%b %e %H:%M")
681   };
682
683 /* The set of signals that are caught.  */
684
685 static sigset_t caught_signals;
686
687 /* If nonzero, the value of the pending fatal signal.  */
688
689 static sig_atomic_t volatile interrupt_signal;
690
691 /* A count of the number of pending stop signals that have been received.  */
692
693 static sig_atomic_t volatile stop_signal_count;
694
695 /* Desired exit status.  */
696
697 static int exit_status;
698
699 /* Exit statuses.  */
700 enum
701   {
702     /* "ls" had a minor problem (e.g., it could not stat a directory
703        entry).  */
704     LS_MINOR_PROBLEM = 1,
705
706     /* "ls" had more serious trouble.  */
707     LS_FAILURE = 2
708   };
709
710 /* For long options that have no equivalent short option, use a
711    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
712 enum
713 {
714   AUTHOR_OPTION = CHAR_MAX + 1,
715   BLOCK_SIZE_OPTION,
716   COLOR_OPTION,
717   DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION,
718   FORMAT_OPTION,
719   FULL_TIME_OPTION,
720   HIDE_OPTION,
721   INDICATOR_STYLE_OPTION,
722   QUOTING_STYLE_OPTION,
723   SHOW_CONTROL_CHARS_OPTION,
724   SI_OPTION,
725   SORT_OPTION,
726   TIME_OPTION,
727   TIME_STYLE_OPTION
728 };
729
730 static struct option const long_options[] =
731 {
732   {"all", no_argument, NULL, 'a'},
733   {"escape", no_argument, NULL, 'b'},
734   {"directory", no_argument, NULL, 'd'},
735   {"dired", no_argument, NULL, 'D'},
736   {"full-time", no_argument, NULL, FULL_TIME_OPTION},
737   {"human-readable", no_argument, NULL, 'h'},
738   {"inode", no_argument, NULL, 'i'},
739   {"kilobytes", no_argument, NULL, 'k'}, /* long form is obsolescent */
740   {"numeric-uid-gid", no_argument, NULL, 'n'},
741   {"no-group", no_argument, NULL, 'G'},
742   {"hide-control-chars", no_argument, NULL, 'q'},
743   {"reverse", no_argument, NULL, 'r'},
744   {"size", no_argument, NULL, 's'},
745   {"width", required_argument, NULL, 'w'},
746   {"almost-all", no_argument, NULL, 'A'},
747   {"ignore-backups", no_argument, NULL, 'B'},
748   {"classify", no_argument, NULL, 'F'},
749   {"file-type", no_argument, NULL, 'p'},
750   {"si", no_argument, NULL, SI_OPTION},
751   {"dereference-command-line", no_argument, NULL, 'H'},
752   {"dereference-command-line-symlink-to-dir", no_argument, NULL,
753    DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION},
754   {"hide", required_argument, NULL, HIDE_OPTION},
755   {"ignore", required_argument, NULL, 'I'},
756   {"indicator-style", required_argument, NULL, INDICATOR_STYLE_OPTION},
757   {"dereference", no_argument, NULL, 'L'},
758   {"literal", no_argument, NULL, 'N'},
759   {"quote-name", no_argument, NULL, 'Q'},
760   {"quoting-style", required_argument, NULL, QUOTING_STYLE_OPTION},
761   {"recursive", no_argument, NULL, 'R'},
762   {"format", required_argument, NULL, FORMAT_OPTION},
763   {"show-control-chars", no_argument, NULL, SHOW_CONTROL_CHARS_OPTION},
764   {"sort", required_argument, NULL, SORT_OPTION},
765   {"tabsize", required_argument, NULL, 'T'},
766   {"time", required_argument, NULL, TIME_OPTION},
767   {"time-style", required_argument, NULL, TIME_STYLE_OPTION},
768   {"color", optional_argument, NULL, COLOR_OPTION},
769   {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION},
770   {"author", no_argument, NULL, AUTHOR_OPTION},
771   {GETOPT_HELP_OPTION_DECL},
772   {GETOPT_VERSION_OPTION_DECL},
773   {NULL, 0, NULL, 0}
774 };
775
776 static char const *const format_args[] =
777 {
778   "verbose", "long", "commas", "horizontal", "across",
779   "vertical", "single-column", NULL
780 };
781
782 static enum format const format_types[] =
783 {
784   long_format, long_format, with_commas, horizontal, horizontal,
785   many_per_line, one_per_line
786 };
787
788 static char const *const sort_args[] =
789 {
790   "none", "time", "size", "extension", "version", NULL
791 };
792
793 static enum sort_type const sort_types[] =
794 {
795   sort_none, sort_time, sort_size, sort_extension, sort_version
796 };
797
798 static char const *const time_args[] =
799 {
800   "atime", "access", "use", "ctime", "status", NULL
801 };
802
803 static enum time_type const time_types[] =
804 {
805   time_atime, time_atime, time_atime, time_ctime, time_ctime
806 };
807
808 static char const *const color_args[] =
809 {
810   /* force and none are for compatibility with another color-ls version */
811   "always", "yes", "force",
812   "never", "no", "none",
813   "auto", "tty", "if-tty", NULL
814 };
815
816 static enum color_type const color_types[] =
817 {
818   color_always, color_always, color_always,
819   color_never, color_never, color_never,
820   color_if_tty, color_if_tty, color_if_tty
821 };
822
823 /* Information about filling a column.  */
824 struct column_info
825 {
826   bool valid_len;
827   size_t line_len;
828   size_t *col_arr;
829 };
830
831 /* Array with information about column filledness.  */
832 static struct column_info *column_info;
833
834 /* Maximum number of columns ever possible for this display.  */
835 static size_t max_idx;
836
837 /* The minimum width of a column is 3: 1 character for the name and 2
838    for the separating white space.  */
839 #define MIN_COLUMN_WIDTH        3
840
841
842 /* This zero-based index is used solely with the --dired option.
843    When that option is in effect, this counter is incremented for each
844    byte of output generated by this program so that the beginning
845    and ending indices (in that output) of every file name can be recorded
846    and later output themselves.  */
847 static size_t dired_pos;
848
849 #define DIRED_PUTCHAR(c) do {putchar ((c)); ++dired_pos;} while (0)
850
851 /* Write S to STREAM and increment DIRED_POS by S_LEN.  */
852 #define DIRED_FPUTS(s, stream, s_len) \
853     do {fputs ((s), (stream)); dired_pos += s_len;} while (0)
854
855 /* Like DIRED_FPUTS, but for use when S is a literal string.  */
856 #define DIRED_FPUTS_LITERAL(s, stream) \
857     do {fputs ((s), (stream)); dired_pos += sizeof((s)) - 1;} while (0)
858
859 #define DIRED_INDENT()                                                  \
860     do                                                                  \
861       {                                                                 \
862         if (dired)                                                      \
863           DIRED_FPUTS_LITERAL ("  ", stdout);                           \
864       }                                                                 \
865     while (0)
866
867 /* With --dired, store pairs of beginning and ending indices of filenames.  */
868 static struct obstack dired_obstack;
869
870 /* With --dired, store pairs of beginning and ending indices of any
871    directory names that appear as headers (just before `total' line)
872    for lists of directory entries.  Such directory names are seen when
873    listing hierarchies using -R and when a directory is listed with at
874    least one other command line argument.  */
875 static struct obstack subdired_obstack;
876
877 /* Save the current index on the specified obstack, OBS.  */
878 #define PUSH_CURRENT_DIRED_POS(obs)                                     \
879   do                                                                    \
880     {                                                                   \
881       if (dired)                                                        \
882         obstack_grow ((obs), &dired_pos, sizeof (dired_pos));           \
883     }                                                                   \
884   while (0)
885
886 /* With -R, this stack is used to help detect directory cycles.
887    The device/inode pairs on this stack mirror the pairs in the
888    active_dir_set hash table.  */
889 static struct obstack dev_ino_obstack;
890
891 /* Push a pair onto the device/inode stack.  */
892 #define DEV_INO_PUSH(Dev, Ino)                                          \
893   do                                                                    \
894     {                                                                   \
895       struct dev_ino *di;                                               \
896       obstack_blank (&dev_ino_obstack, sizeof (struct dev_ino));        \
897       di = -1 + (struct dev_ino *) obstack_next_free (&dev_ino_obstack); \
898       di->st_dev = (Dev);                                               \
899       di->st_ino = (Ino);                                               \
900     }                                                                   \
901   while (0)
902
903 /* Pop a dev/ino struct off the global dev_ino_obstack
904    and return that struct.  */
905 static struct dev_ino
906 dev_ino_pop (void)
907 {
908   assert (sizeof (struct dev_ino) <= obstack_object_size (&dev_ino_obstack));
909   obstack_blank (&dev_ino_obstack, -(int) (sizeof (struct dev_ino)));
910   return *(struct dev_ino*) obstack_next_free (&dev_ino_obstack);
911 }
912
913 #define ASSERT_MATCHING_DEV_INO(Name, Di)       \
914   do                                            \
915     {                                           \
916       struct stat sb;                           \
917       assert (Name);                            \
918       assert (0 <= stat (Name, &sb));           \
919       assert (sb.st_dev == Di.st_dev);          \
920       assert (sb.st_ino == Di.st_ino);          \
921     }                                           \
922   while (0)
923
924
925 /* Write to standard output PREFIX, followed by the quoting style and
926    a space-separated list of the integers stored in OS all on one line.  */
927
928 static void
929 dired_dump_obstack (const char *prefix, struct obstack *os)
930 {
931   size_t n_pos;
932
933   n_pos = obstack_object_size (os) / sizeof (dired_pos);
934   if (n_pos > 0)
935     {
936       size_t i;
937       size_t *pos;
938
939       pos = (size_t *) obstack_finish (os);
940       fputs (prefix, stdout);
941       for (i = 0; i < n_pos; i++)
942         printf (" %lu", (unsigned long int) pos[i]);
943       putchar ('\n');
944     }
945 }
946
947 static size_t
948 dev_ino_hash (void const *x, size_t table_size)
949 {
950   struct dev_ino const *p = x;
951   return (uintmax_t) p->st_ino % table_size;
952 }
953
954 static bool
955 dev_ino_compare (void const *x, void const *y)
956 {
957   struct dev_ino const *a = x;
958   struct dev_ino const *b = y;
959   return SAME_INODE (*a, *b) ? true : false;
960 }
961
962 static void
963 dev_ino_free (void *x)
964 {
965   free (x);
966 }
967
968 /* Add the device/inode pair (P->st_dev/P->st_ino) to the set of
969    active directories.  Return true if there is already a matching
970    entry in the table.  */
971
972 static bool
973 visit_dir (dev_t dev, ino_t ino)
974 {
975   struct dev_ino *ent;
976   struct dev_ino *ent_from_table;
977   bool found_match;
978
979   ent = xmalloc (sizeof *ent);
980   ent->st_ino = ino;
981   ent->st_dev = dev;
982
983   /* Attempt to insert this entry into the table.  */
984   ent_from_table = hash_insert (active_dir_set, ent);
985
986   if (ent_from_table == NULL)
987     {
988       /* Insertion failed due to lack of memory.  */
989       xalloc_die ();
990     }
991
992   found_match = (ent_from_table != ent);
993
994   if (found_match)
995     {
996       /* ent was not inserted, so free it.  */
997       free (ent);
998     }
999
1000   return found_match;
1001 }
1002
1003 static void
1004 free_pending_ent (struct pending *p)
1005 {
1006   if (p->name)
1007     free (p->name);
1008   if (p->realname)
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 = file_type;
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 (indicator_style != none)
1779     {
1780       char const *p;
1781       for (p = "*=@|" + indicator_style - 1;  *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       if (files[i].linkname)
2450         free (files[i].linkname);
2451     }
2452
2453   files_index = 0;
2454   inode_number_width = 0;
2455   block_size_width = 0;
2456   nlink_width = 0;
2457   owner_width = 0;
2458   group_width = 0;
2459   author_width = 0;
2460   major_device_number_width = 0;
2461   minor_device_number_width = 0;
2462   file_size_width = 0;
2463 }
2464
2465 /* Add a file to the current table of files.
2466    Verify that the file exists, and print an error message if it does not.
2467    Return the number of blocks that the file occupies.  */
2468
2469 static uintmax_t
2470 gobble_file (char const *name, enum filetype type, bool command_line_arg,
2471              char const *dirname)
2472 {
2473   uintmax_t blocks;
2474   char *path;
2475   struct fileinfo *f;
2476
2477   if (files_index == nfiles)
2478     {
2479       files = xnrealloc (files, nfiles, 2 * sizeof *files);
2480       nfiles *= 2;
2481     }
2482
2483   f = &files[files_index];
2484   f->linkname = NULL;
2485   f->linkmode = 0;
2486   f->linkok = false;
2487
2488   if (command_line_arg
2489       || format_needs_stat
2490       || (format_needs_type
2491           && (type == unknown
2492
2493               /* FIXME: remove this disjunct.
2494                  I don't think we care about symlinks here, but for now
2495                  this won't make a big performance difference.  */
2496               || type == symbolic_link
2497
2498               /* --indicator-style=classify (aka -F)
2499                  requires that we stat each regular file
2500                  to see if it's executable.  */
2501               || (type == normal && (indicator_style == classify
2502                                      /* This is so that --color ends up
2503                                         highlighting files with the executable
2504                                         bit set even when options like -F are
2505                                         not specified.  */
2506                                      || (print_with_color
2507                                          && is_colored (C_EXEC))
2508                                      )))))
2509
2510     {
2511       /* `path' is the absolute pathname of this file.  */
2512       int err;
2513
2514       if (name[0] == '/' || dirname[0] == 0)
2515         path = (char *) name;
2516       else
2517         {
2518           path = alloca (strlen (name) + strlen (dirname) + 2);
2519           attach (path, dirname, name);
2520         }
2521
2522       switch (dereference)
2523         {
2524         case DEREF_ALWAYS:
2525           err = stat (path, &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 (path, &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, PATH 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 (path, &f->stat);
2552           break;
2553         }
2554
2555       if (err < 0)
2556         {
2557           file_failure (command_line_arg, "%s", path);
2558           return 0;
2559         }
2560
2561 #if HAVE_ACL
2562       if (format == long_format)
2563         {
2564           int n = file_has_acl (path, &f->stat);
2565           f->have_acl = (0 < n);
2566           if (n < 0)
2567             error (0, errno, "%s", quotearg_colon (path));
2568         }
2569 #endif
2570
2571       if (S_ISLNK (f->stat.st_mode)
2572           && (format == long_format || check_symlink_color))
2573         {
2574           char *linkpath;
2575           struct stat linkstats;
2576
2577           get_link_name (path, f, command_line_arg);
2578           linkpath = make_link_path (path, 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 (linkpath
2583               && (indicator_style != none || check_symlink_color)
2584               && stat (linkpath, &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           if (linkpath)
2601             free (linkpath);
2602         }
2603
2604       if (S_ISLNK (f->stat.st_mode))
2605         f->filetype = symbolic_link;
2606       else if (S_ISDIR (f->stat.st_mode))
2607         {
2608           if (command_line_arg & !immediate_dirs)
2609             f->filetype = arg_directory;
2610           else
2611             f->filetype = directory;
2612         }
2613       else
2614         f->filetype = normal;
2615
2616       {
2617         char buf[INT_BUFSIZE_BOUND (uintmax_t)];
2618         int len = strlen (umaxtostr (f->stat.st_ino, buf));
2619         if (inode_number_width < len)
2620           inode_number_width = len;
2621       }
2622
2623       blocks = ST_NBLOCKS (f->stat);
2624       {
2625         char buf[LONGEST_HUMAN_READABLE + 1];
2626         int len = mbswidth (human_readable (blocks, buf, human_output_opts,
2627                                             ST_NBLOCKSIZE, output_block_size),
2628                             0);
2629         if (block_size_width < len)
2630           block_size_width = len;
2631       }
2632
2633       if (print_owner)
2634         {
2635           int len = format_user_width (f->stat.st_uid);
2636           if (owner_width < len)
2637             owner_width = len;
2638         }
2639
2640       if (print_group)
2641         {
2642           int len = format_group_width (f->stat.st_gid);
2643           if (group_width < len)
2644             group_width = len;
2645         }
2646
2647       if (print_author)
2648         {
2649           int len = format_user_width (f->stat.st_uid);
2650           if (author_width < len)
2651             author_width = len;
2652         }
2653
2654       {
2655         char buf[INT_BUFSIZE_BOUND (uintmax_t)];
2656         int len = strlen (umaxtostr (f->stat.st_nlink, buf));
2657         if (nlink_width < len)
2658           nlink_width = len;
2659       }
2660
2661       if (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode))
2662         {
2663           char buf[INT_BUFSIZE_BOUND (uintmax_t)];
2664           int len = strlen (umaxtostr (major (f->stat.st_rdev), buf));
2665           if (major_device_number_width < len)
2666             major_device_number_width = len;
2667           len = strlen (umaxtostr (minor (f->stat.st_rdev), buf));
2668           if (minor_device_number_width < len)
2669             minor_device_number_width = len;
2670           len = major_device_number_width + 2 + minor_device_number_width;
2671           if (file_size_width < len)
2672             file_size_width = len;
2673         }
2674       else
2675         {
2676           char buf[LONGEST_HUMAN_READABLE + 1];
2677           uintmax_t size = unsigned_file_size (f->stat.st_size);
2678           int len = mbswidth (human_readable (size, buf, human_output_opts,
2679                                               1, file_output_block_size),
2680                               0);
2681           if (file_size_width < len)
2682             file_size_width = len;
2683         }
2684     }
2685   else
2686     {
2687       f->filetype = type;
2688 #if HAVE_STRUCT_DIRENT_D_TYPE
2689       f->stat.st_mode = DTTOIF (type);
2690 #endif
2691       blocks = 0;
2692     }
2693
2694   f->name = xstrdup (name);
2695   files_index++;
2696
2697   return blocks;
2698 }
2699
2700 #ifdef S_ISLNK
2701
2702 /* Put the name of the file that FILENAME is a symbolic link to
2703    into the LINKNAME field of `f'.  COMMAND_LINE_ARG indicates whether
2704    FILENAME is a command-line argument.  */
2705
2706 static void
2707 get_link_name (char const *filename, struct fileinfo *f, bool command_line_arg)
2708 {
2709   f->linkname = xreadlink (filename, f->stat.st_size);
2710   if (f->linkname == NULL)
2711     file_failure (command_line_arg, _("cannot read symbolic link %s"),
2712                   filename);
2713 }
2714
2715 /* If `linkname' is a relative path and `path' contains one or more
2716    leading directories, return `linkname' with those directories
2717    prepended; otherwise, return a copy of `linkname'.
2718    If `linkname' is zero, return zero.  */
2719
2720 static char *
2721 make_link_path (const char *path, const char *linkname)
2722 {
2723   char *linkbuf;
2724   size_t bufsiz;
2725
2726   if (!linkname)
2727     return NULL;
2728
2729   if (*linkname == '/')
2730     return xstrdup (linkname);
2731
2732   /* The link is to a relative path.  Prepend any leading path
2733      in `path' to the link name.  */
2734   linkbuf = strrchr (path, '/');
2735   if (linkbuf == 0)
2736     return xstrdup (linkname);
2737
2738   bufsiz = linkbuf - path + 1;
2739   linkbuf = xmalloc (bufsiz + strlen (linkname) + 1);
2740   strncpy (linkbuf, path, bufsiz);
2741   strcpy (linkbuf + bufsiz, linkname);
2742   return linkbuf;
2743 }
2744 #endif
2745
2746 /* Return true if base_name (NAME) ends in `.' or `..'
2747    This is so we don't try to recurse on `././././. ...' */
2748
2749 static bool
2750 basename_is_dot_or_dotdot (const char *name)
2751 {
2752   char const *base = base_name (name);
2753   return DOT_OR_DOTDOT (base);
2754 }
2755
2756 /* Remove any entries from FILES that are for directories,
2757    and queue them to be listed as directories instead.
2758    DIRNAME is the prefix to prepend to each dirname
2759    to make it correct relative to ls's working dir;
2760    if it is null, no prefix is needed and "." and ".." should not be ignored.
2761    If COMMAND_LINE_ARG is true, this directory was mentioned at the top level,
2762    This is desirable when processing directories recursively.  */
2763
2764 static void
2765 extract_dirs_from_files (char const *dirname, bool command_line_arg)
2766 {
2767   size_t i;
2768   size_t j;
2769   bool ignore_dot_and_dot_dot = (dirname != NULL);
2770
2771   if (dirname && LOOP_DETECT)
2772     {
2773       /* Insert a marker entry first.  When we dequeue this marker entry,
2774          we'll know that DIRNAME has been processed and may be removed
2775          from the set of active directories.  */
2776       queue_directory (NULL, dirname, false);
2777     }
2778
2779   /* Queue the directories last one first, because queueing reverses the
2780      order.  */
2781   for (i = files_index; i-- != 0; )
2782     if ((files[i].filetype == directory || files[i].filetype == arg_directory)
2783         && (!ignore_dot_and_dot_dot
2784             || !basename_is_dot_or_dotdot (files[i].name)))
2785       {
2786         if (!dirname || files[i].name[0] == '/')
2787           {
2788             queue_directory (files[i].name, files[i].linkname,
2789                              command_line_arg);
2790           }
2791         else
2792           {
2793             char *path = path_concat (dirname, files[i].name, NULL);
2794             queue_directory (path, files[i].linkname, command_line_arg);
2795             free (path);
2796           }
2797         if (files[i].filetype == arg_directory)
2798           free (files[i].name);
2799       }
2800
2801   /* Now delete the directories from the table, compacting all the remaining
2802      entries.  */
2803
2804   for (i = 0, j = 0; i < files_index; i++)
2805     {
2806       if (files[i].filetype != arg_directory)
2807         {
2808           if (j < i)
2809             files[j] = files[i];
2810           ++j;
2811         }
2812     }
2813   files_index = j;
2814 }
2815
2816 /* Use strcoll to compare strings in this locale.  If an error occurs,
2817    report an error and longjmp to failed_strcoll.  */
2818
2819 static jmp_buf failed_strcoll;
2820
2821 static int
2822 xstrcoll (char const *a, char const *b)
2823 {
2824   int diff;
2825   errno = 0;
2826   diff = strcoll (a, b);
2827   if (errno)
2828     {
2829       error (0, errno, _("cannot compare file names %s and %s"),
2830              quote_n (0, a), quote_n (1, b));
2831       set_exit_status (false);
2832       longjmp (failed_strcoll, 1);
2833     }
2834   return diff;
2835 }
2836
2837 /* Comparison routines for sorting the files.  */
2838
2839 typedef void const *V;
2840
2841 static inline int
2842 cmp_ctime (struct fileinfo const *a, struct fileinfo const *b,
2843            int (*cmp) (char const *, char const *))
2844 {
2845   int diff = CTIME_CMP (b->stat, a->stat);
2846   return diff ? diff : cmp (a->name, b->name);
2847 }
2848 static int compare_ctime (V a, V b) { return cmp_ctime (a, b, xstrcoll); }
2849 static int compstr_ctime (V a, V b) { return cmp_ctime (a, b, strcmp); }
2850 static int rev_cmp_ctime (V a, V b) { return compare_ctime (b, a); }
2851 static int rev_str_ctime (V a, V b) { return compstr_ctime (b, a); }
2852
2853 static inline int
2854 cmp_mtime (struct fileinfo const *a, struct fileinfo const *b,
2855            int (*cmp) (char const *, char const *))
2856 {
2857   int diff = MTIME_CMP (b->stat, a->stat);
2858   return diff ? diff : cmp (a->name, b->name);
2859 }
2860 static int compare_mtime (V a, V b) { return cmp_mtime (a, b, xstrcoll); }
2861 static int compstr_mtime (V a, V b) { return cmp_mtime (a, b, strcmp); }
2862 static int rev_cmp_mtime (V a, V b) { return compare_mtime (b, a); }
2863 static int rev_str_mtime (V a, V b) { return compstr_mtime (b, a); }
2864
2865 static inline int
2866 cmp_atime (struct fileinfo const *a, struct fileinfo const *b,
2867            int (*cmp) (char const *, char const *))
2868 {
2869   int diff = ATIME_CMP (b->stat, a->stat);
2870   return diff ? diff : cmp (a->name, b->name);
2871 }
2872 static int compare_atime (V a, V b) { return cmp_atime (a, b, xstrcoll); }
2873 static int compstr_atime (V a, V b) { return cmp_atime (a, b, strcmp); }
2874 static int rev_cmp_atime (V a, V b) { return compare_atime (b, a); }
2875 static int rev_str_atime (V a, V b) { return compstr_atime (b, a); }
2876
2877 static inline int
2878 cmp_size (struct fileinfo const *a, struct fileinfo const *b,
2879           int (*cmp) (char const *, char const *))
2880 {
2881   int diff = longdiff (b->stat.st_size, a->stat.st_size);
2882   return diff ? diff : cmp (a->name, b->name);
2883 }
2884 static int compare_size (V a, V b) { return cmp_size (a, b, xstrcoll); }
2885 static int compstr_size (V a, V b) { return cmp_size (a, b, strcmp); }
2886 static int rev_cmp_size (V a, V b) { return compare_size (b, a); }
2887 static int rev_str_size (V a, V b) { return compstr_size (b, a); }
2888
2889 static inline int
2890 cmp_version (struct fileinfo const *a, struct fileinfo const *b)
2891 {
2892   return strverscmp (a->name, b->name);
2893 }
2894 static int compare_version (V a, V b) { return cmp_version (a, b); }
2895 static int rev_cmp_version (V a, V b) { return compare_version (b, a); }
2896
2897 static inline int
2898 cmp_name (struct fileinfo const *a, struct fileinfo const *b,
2899           int (*cmp) (char const *, char const *))
2900 {
2901   return cmp (a->name, b->name);
2902 }
2903 static int compare_name (V a, V b) { return cmp_name (a, b, xstrcoll); }
2904 static int compstr_name (V a, V b) { return cmp_name (a, b, strcmp); }
2905 static int rev_cmp_name (V a, V b) { return compare_name (b, a); }
2906 static int rev_str_name (V a, V b) { return compstr_name (b, a); }
2907
2908 /* Compare file extensions.  Files with no extension are `smallest'.
2909    If extensions are the same, compare by filenames instead.  */
2910
2911 static inline int
2912 cmp_extension (struct fileinfo const *a, struct fileinfo const *b,
2913                int (*cmp) (char const *, char const *))
2914 {
2915   char const *base1 = strrchr (a->name, '.');
2916   char const *base2 = strrchr (b->name, '.');
2917   int diff = cmp (base1 ? base1 : "", base2 ? base2 : "");
2918   return diff ? diff : cmp (a->name, b->name);
2919 }
2920 static int compare_extension (V a, V b) { return cmp_extension (a, b, xstrcoll); }
2921 static int compstr_extension (V a, V b) { return cmp_extension (a, b, strcmp); }
2922 static int rev_cmp_extension (V a, V b) { return compare_extension (b, a); }
2923 static int rev_str_extension (V a, V b) { return compstr_extension (b, a); }
2924
2925 /* Sort the files now in the table.  */
2926
2927 static void
2928 sort_files (void)
2929 {
2930   int (*func) (V, V);
2931
2932   /* Try strcoll.  If it fails, fall back on strcmp.  We can't safely
2933      ignore strcoll failures, as a failing strcoll might be a
2934      comparison function that is not a total order, and if we ignored
2935      the failure this might cause qsort to dump core.  */
2936
2937   if (! setjmp (failed_strcoll))
2938     {
2939       switch (sort_type)
2940         {
2941         case sort_none:
2942           return;
2943         case sort_time:
2944           switch (time_type)
2945             {
2946             case time_ctime:
2947               func = sort_reverse ? rev_cmp_ctime : compare_ctime;
2948               break;
2949             case time_mtime:
2950               func = sort_reverse ? rev_cmp_mtime : compare_mtime;
2951               break;
2952             case time_atime:
2953               func = sort_reverse ? rev_cmp_atime : compare_atime;
2954               break;
2955             default:
2956               abort ();
2957             }
2958           break;
2959         case sort_name:
2960           func = sort_reverse ? rev_cmp_name : compare_name;
2961           break;
2962         case sort_extension:
2963           func = sort_reverse ? rev_cmp_extension : compare_extension;
2964           break;
2965         case sort_size:
2966           func = sort_reverse ? rev_cmp_size : compare_size;
2967           break;
2968         case sort_version:
2969           func = sort_reverse ? rev_cmp_version : compare_version;
2970           break;
2971         default:
2972           abort ();
2973         }
2974     }
2975   else
2976     {
2977       switch (sort_type)
2978         {
2979         case sort_time:
2980           switch (time_type)
2981             {
2982             case time_ctime:
2983               func = sort_reverse ? rev_str_ctime : compstr_ctime;
2984               break;
2985             case time_mtime:
2986               func = sort_reverse ? rev_str_mtime : compstr_mtime;
2987               break;
2988             case time_atime:
2989               func = sort_reverse ? rev_str_atime : compstr_atime;
2990               break;
2991             default:
2992               abort ();
2993             }
2994           break;
2995         case sort_name:
2996           func = sort_reverse ? rev_str_name : compstr_name;
2997           break;
2998         case sort_extension:
2999           func = sort_reverse ? rev_str_extension : compstr_extension;
3000           break;
3001         case sort_size:
3002           func = sort_reverse ? rev_str_size : compstr_size;
3003           break;
3004         default:
3005           abort ();
3006         }
3007     }
3008
3009   qsort (files, files_index, sizeof (struct fileinfo), func);
3010 }
3011
3012 /* List all the files now in the table.  */
3013
3014 static void
3015 print_current_files (void)
3016 {
3017   size_t i;
3018
3019   switch (format)
3020     {
3021     case one_per_line:
3022       for (i = 0; i < files_index; i++)
3023         {
3024           print_file_name_and_frills (files + i);
3025           putchar ('\n');
3026         }
3027       break;
3028
3029     case many_per_line:
3030       print_many_per_line ();
3031       break;
3032
3033     case horizontal:
3034       print_horizontal ();
3035       break;
3036
3037     case with_commas:
3038       print_with_commas ();
3039       break;
3040
3041     case long_format:
3042       for (i = 0; i < files_index; i++)
3043         {
3044           print_long_format (files + i);
3045           DIRED_PUTCHAR ('\n');
3046         }
3047       break;
3048     }
3049 }
3050
3051 /* Return the expected number of columns in a long-format time stamp,
3052    or zero if it cannot be calculated.  */
3053
3054 static int
3055 long_time_expected_width (void)
3056 {
3057   static int width = -1;
3058
3059   if (width < 0)
3060     {
3061       time_t epoch = 0;
3062       struct tm const *tm = localtime (&epoch);
3063       char buf[TIME_STAMP_LEN_MAXIMUM + 1];
3064
3065       if (tm)
3066         {
3067           size_t len =
3068             nstrftime (buf, sizeof buf, long_time_format[0], tm, 0, 0);
3069           if (len != 0)
3070             width = mbsnwidth (buf, len, 0);
3071         }
3072
3073       if (width < 0)
3074         width = 0;
3075     }
3076
3077   return width;
3078 }
3079
3080 /* Get the current time.  */
3081
3082 static void
3083 get_current_time (void)
3084 {
3085 #if HAVE_CLOCK_GETTIME && defined CLOCK_REALTIME
3086   {
3087     struct timespec timespec;
3088     if (clock_gettime (CLOCK_REALTIME, &timespec) == 0)
3089       {
3090         current_time = timespec.tv_sec;
3091         current_time_ns = timespec.tv_nsec;
3092         return;
3093       }
3094   }
3095 #endif
3096
3097   /* The clock does not have nanosecond resolution, so get the maximum
3098      possible value for the current time that is consistent with the
3099      reported clock.  That way, files are not considered to be in the
3100      future merely because their time stamps have higher resolution
3101      than the clock resolution.  */
3102
3103 #if HAVE_GETTIMEOFDAY
3104   {
3105     struct timeval timeval;
3106     gettimeofday (&timeval, NULL);
3107     current_time = timeval.tv_sec;
3108     current_time_ns = timeval.tv_usec * 1000 + 999;
3109   }
3110 #else
3111   current_time = time (NULL);
3112   current_time_ns = 999999999;
3113 #endif
3114 }
3115
3116 /* Print the user or group name NAME, with numeric id ID, using a
3117    print width of WIDTH columns.  */
3118
3119 static void
3120 format_user_or_group (char const *name, unsigned long int id, int width)
3121 {
3122   size_t len;
3123
3124   if (name)
3125     {
3126       int width_gap = width - mbswidth (name, 0);
3127       int pad = MAX (0, width_gap);
3128       fputs (name, stdout);
3129       len = strlen (name) + pad;
3130
3131       do
3132         putchar (' ');
3133       while (pad--);
3134     }
3135   else
3136     {
3137       printf ("%*lu ", width, id);
3138       len = width;
3139     }
3140
3141   dired_pos += len + 1;
3142 }
3143
3144 /* Print the name or id of the user with id U, using a print width of
3145    WIDTH.  */
3146
3147 static void
3148 format_user (uid_t u, int width)
3149 {
3150   format_user_or_group (numeric_ids ? NULL : getuser (u), u, width);
3151 }
3152
3153 /* Likewise, for groups.  */
3154
3155 static void
3156 format_group (gid_t g, int width)
3157 {
3158   format_user_or_group (numeric_ids ? NULL : getgroup (g), g, width);
3159 }
3160
3161 /* Return the number of columns that format_user_or_group will print.  */
3162
3163 static int
3164 format_user_or_group_width (char const *name, unsigned long int id)
3165 {
3166   if (name)
3167     {
3168       int len = mbswidth (name, 0);
3169       return MAX (0, len);
3170     }
3171   else
3172     {
3173       char buf[INT_BUFSIZE_BOUND (unsigned long int)];
3174       sprintf (buf, "%lu", id);
3175       return strlen (buf);
3176     }
3177 }
3178
3179 /* Return the number of columns that format_user will print.  */
3180
3181 static int
3182 format_user_width (uid_t u)
3183 {
3184   return format_user_or_group_width (numeric_ids ? NULL : getuser (u), u);
3185 }
3186
3187 /* Likewise, for groups.  */
3188
3189 static int
3190 format_group_width (gid_t g)
3191 {
3192   return format_user_or_group_width (numeric_ids ? NULL : getgroup (g), g);
3193 }
3194
3195
3196 /* Print information about F in long format.  */
3197
3198 static void
3199 print_long_format (const struct fileinfo *f)
3200 {
3201   char modebuf[12];
3202   char buf
3203     [LONGEST_HUMAN_READABLE + 1         /* inode */
3204      + LONGEST_HUMAN_READABLE + 1       /* size in blocks */
3205      + sizeof (modebuf) - 1 + 1         /* mode string */
3206      + INT_BUFSIZE_BOUND (uintmax_t)    /* st_nlink */
3207      + LONGEST_HUMAN_READABLE + 2       /* major device number */
3208      + LONGEST_HUMAN_READABLE + 1       /* minor device number */
3209      + TIME_STAMP_LEN_MAXIMUM + 1       /* max length of time/date */
3210      ];
3211   size_t s;
3212   char *p;
3213   time_t when;
3214   int when_ns IF_LINT (= 0);
3215   struct tm *when_local;
3216
3217   /* Compute mode string.  On most systems, it's based on st_mode.
3218      On systems with migration (via the stat.st_dm_mode field), use
3219      the file's migrated status.  */
3220   mode_string (ST_DM_MODE (f->stat), modebuf);
3221
3222   modebuf[10] = (FILE_HAS_ACL (f) ? '+' : ' ');
3223   modebuf[11] = '\0';
3224
3225   switch (time_type)
3226     {
3227     case time_ctime:
3228       when = f->stat.st_ctime;
3229       when_ns = TIMESPEC_NS (f->stat.st_ctim);
3230       break;
3231     case time_mtime:
3232       when = f->stat.st_mtime;
3233       when_ns = TIMESPEC_NS (f->stat.st_mtim);
3234       break;
3235     case time_atime:
3236       when = f->stat.st_atime;
3237       when_ns = TIMESPEC_NS (f->stat.st_atim);
3238       break;
3239     }
3240
3241   p = buf;
3242
3243   if (print_inode)
3244     {
3245       char hbuf[INT_BUFSIZE_BOUND (uintmax_t)];
3246       sprintf (p, "%*s ", inode_number_width,
3247                umaxtostr (f->stat.st_ino, hbuf));
3248       p += inode_number_width + 1;
3249     }
3250
3251   if (print_block_size)
3252     {
3253       char hbuf[LONGEST_HUMAN_READABLE + 1];
3254       char const *blocks =
3255         human_readable (ST_NBLOCKS (f->stat), hbuf, human_output_opts,
3256                         ST_NBLOCKSIZE, output_block_size);
3257       int pad;
3258       for (pad = block_size_width - mbswidth (blocks, 0); 0 < pad; pad--)
3259         *p++ = ' ';
3260       while ((*p++ = *blocks++))
3261         continue;
3262       p[-1] = ' ';
3263     }
3264
3265   /* The last byte of the mode string is the POSIX
3266      "optional alternate access method flag".  */
3267   {
3268     char hbuf[INT_BUFSIZE_BOUND (uintmax_t)];
3269     sprintf (p, "%s %*s ", modebuf, nlink_width,
3270              umaxtostr (f->stat.st_nlink, hbuf));
3271   }
3272   p += sizeof modebuf + nlink_width + 1;
3273
3274   DIRED_INDENT ();
3275
3276   if (print_owner | print_group | print_author)
3277     {
3278       DIRED_FPUTS (buf, stdout, p - buf);
3279
3280       if (print_owner)
3281         format_user (f->stat.st_uid, owner_width);
3282
3283       if (print_group)
3284         format_group (f->stat.st_gid, group_width);
3285
3286       if (print_author)
3287         format_user (f->stat.st_author, author_width);
3288
3289       p = buf;
3290     }
3291
3292   if (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode))
3293     {
3294       char majorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
3295       char minorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
3296       int blanks_width = (file_size_width
3297                           - (major_device_number_width + 2
3298                              + minor_device_number_width));
3299       sprintf (p, "%*s, %*s ",
3300                major_device_number_width + MAX (0, blanks_width),
3301                umaxtostr (major (f->stat.st_rdev), majorbuf),
3302                minor_device_number_width,
3303                umaxtostr (minor (f->stat.st_rdev), minorbuf));
3304       p += file_size_width + 1;
3305     }
3306   else
3307     {
3308       char hbuf[LONGEST_HUMAN_READABLE + 1];
3309       char const *size =
3310         human_readable (unsigned_file_size (f->stat.st_size),
3311                         hbuf, human_output_opts, 1, file_output_block_size);
3312       int pad;
3313       for (pad = file_size_width - mbswidth (size, 0); 0 < pad; pad--)
3314         *p++ = ' ';
3315       while ((*p++ = *size++))
3316         continue;
3317       p[-1] = ' ';
3318     }
3319
3320   when_local = localtime (&when);
3321   s = 0;
3322   *p = '\1';
3323
3324   if (when_local)
3325     {
3326       time_t six_months_ago;
3327       bool recent;
3328       char const *fmt;
3329
3330       /* If the file appears to be in the future, update the current
3331          time, in case the file happens to have been modified since
3332          the last time we checked the clock.  */
3333       if (current_time < when
3334           || (current_time == when && current_time_ns < when_ns))
3335         {
3336           /* Note that get_current_time calls gettimeofday which, on some non-
3337              compliant systems, clobbers the buffer used for localtime's result.
3338              But it's ok here, because we use a gettimeofday wrapper that
3339              saves and restores the buffer around the gettimeofday call.  */
3340           get_current_time ();
3341         }
3342
3343       /* Consider a time to be recent if it is within the past six
3344          months.  A Gregorian year has 365.2425 * 24 * 60 * 60 ==
3345          31556952 seconds on the average.  Write this value as an
3346          integer constant to avoid floating point hassles.  */
3347       six_months_ago = current_time - 31556952 / 2;
3348       recent = (six_months_ago <= when
3349                 && (when < current_time
3350                     || (when == current_time && when_ns <= current_time_ns)));
3351       fmt = long_time_format[recent];
3352
3353       s = nstrftime (p, TIME_STAMP_LEN_MAXIMUM + 1, fmt,
3354                      when_local, 0, when_ns);
3355     }
3356
3357   if (s || !*p)
3358     {
3359       p += s;
3360       *p++ = ' ';
3361
3362       /* NUL-terminate the string -- fputs (via DIRED_FPUTS) requires it.  */
3363       *p = '\0';
3364     }
3365   else
3366     {
3367       /* The time cannot be converted using the desired format, so
3368          print it as a huge integer number of seconds.  */
3369       char hbuf[INT_BUFSIZE_BOUND (intmax_t)];
3370       sprintf (p, "%*s ", long_time_expected_width (),
3371                (TYPE_SIGNED (time_t)
3372                 ? imaxtostr (when, hbuf)
3373                 : umaxtostr (when, hbuf)));
3374       p += strlen (p);
3375     }
3376
3377   DIRED_FPUTS (buf, stdout, p - buf);
3378   print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok,
3379                            &dired_obstack);
3380
3381   if (f->filetype == symbolic_link)
3382     {
3383       if (f->linkname)
3384         {
3385           DIRED_FPUTS_LITERAL (" -> ", stdout);
3386           print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1,
3387                                    NULL);
3388           if (indicator_style != none)
3389             print_type_indicator (f->linkmode);
3390         }
3391     }
3392   else if (indicator_style != none)
3393     print_type_indicator (f->stat.st_mode);
3394 }
3395
3396 /* Output to OUT a quoted representation of the file name NAME,
3397    using OPTIONS to control quoting.  Produce no output if OUT is NULL.
3398    Store the number of screen columns occupied by NAME's quoted
3399    representation into WIDTH, if non-NULL.  Return the number of bytes
3400    produced.  */
3401
3402 static size_t
3403 quote_name (FILE *out, const char *name, struct quoting_options const *options,
3404             size_t *width)
3405 {
3406   char smallbuf[BUFSIZ];
3407   size_t len = quotearg_buffer (smallbuf, sizeof smallbuf, name, -1, options);
3408   char *buf;
3409   size_t displayed_width IF_LINT (= 0);
3410
3411   if (len < sizeof smallbuf)
3412     buf = smallbuf;
3413   else
3414     {
3415       buf = alloca (len + 1);
3416       quotearg_buffer (buf, len + 1, name, -1, options);
3417     }
3418
3419   if (qmark_funny_chars)
3420     {
3421 #if HAVE_MBRTOWC
3422       if (MB_CUR_MAX > 1)
3423         {
3424           char const *p = buf;
3425           char const *plimit = buf + len;
3426           char *q = buf;
3427           displayed_width = 0;
3428
3429           while (p < plimit)
3430             switch (*p)
3431               {
3432                 case ' ': case '!': case '"': case '#': case '%':
3433                 case '&': case '\'': case '(': case ')': case '*':
3434                 case '+': case ',': case '-': case '.': case '/':
3435                 case '0': case '1': case '2': case '3': case '4':
3436                 case '5': case '6': case '7': case '8': case '9':
3437                 case ':': case ';': case '<': case '=': case '>':
3438                 case '?':
3439                 case 'A': case 'B': case 'C': case 'D': case 'E':
3440                 case 'F': case 'G': case 'H': case 'I': case 'J':
3441                 case 'K': case 'L': case 'M': case 'N': case 'O':
3442                 case 'P': case 'Q': case 'R': case 'S': case 'T':
3443                 case 'U': case 'V': case 'W': case 'X': case 'Y':
3444                 case 'Z':
3445                 case '[': case '\\': case ']': case '^': case '_':
3446                 case 'a': case 'b': case 'c': case 'd': case 'e':
3447                 case 'f': case 'g': case 'h': case 'i': case 'j':
3448                 case 'k': case 'l': case 'm': case 'n': case 'o':
3449                 case 'p': case 'q': case 'r': case 's': case 't':
3450                 case 'u': case 'v': case 'w': case 'x': case 'y':
3451                 case 'z': case '{': case '|': case '}': case '~':
3452                   /* These characters are printable ASCII characters.  */
3453                   *q++ = *p++;
3454                   displayed_width += 1;
3455                   break;
3456                 default:
3457                   /* If we have a multibyte sequence, copy it until we
3458                      reach its end, replacing each non-printable multibyte
3459                      character with a single question mark.  */
3460                   {
3461                     mbstate_t mbstate;
3462                     memset (&mbstate, 0, sizeof mbstate);
3463                     do
3464                       {
3465                         wchar_t wc;
3466                         size_t bytes;
3467                         int w;
3468
3469                         bytes = mbrtowc (&wc, p, plimit - p, &mbstate);
3470
3471                         if (bytes == (size_t) -1)
3472                           {
3473                             /* An invalid multibyte sequence was
3474                                encountered.  Skip one input byte, and
3475                                put a question mark.  */
3476                             p++;
3477                             *q++ = '?';
3478                             displayed_width += 1;
3479                             break;
3480                           }
3481
3482                         if (bytes == (size_t) -2)
3483                           {
3484                             /* An incomplete multibyte character
3485                                at the end.  Replace it entirely with
3486                                a question mark.  */
3487                             p = plimit;
3488                             *q++ = '?';
3489                             displayed_width += 1;
3490                             break;
3491                           }
3492
3493                         if (bytes == 0)
3494                           /* A null wide character was encountered.  */
3495                           bytes = 1;
3496
3497                         w = wcwidth (wc);
3498                         if (w >= 0)
3499                           {
3500                             /* A printable multibyte character.
3501                                Keep it.  */
3502                             for (; bytes > 0; --bytes)
3503                               *q++ = *p++;
3504                             displayed_width += w;
3505                           }
3506                         else
3507                           {
3508                             /* An unprintable multibyte character.
3509                                Replace it entirely with a question
3510                                mark.  */
3511                             p += bytes;
3512                             *q++ = '?';
3513                             displayed_width += 1;
3514                           }
3515                       }
3516                     while (! mbsinit (&mbstate));
3517                   }
3518                   break;
3519               }
3520
3521           /* The buffer may have shrunk.  */
3522           len = q - buf;
3523         }
3524       else
3525 #endif
3526         {
3527           char *p = buf;
3528           char const *plimit = buf + len;
3529
3530           while (p < plimit)
3531             {
3532               if (! ISPRINT (to_uchar (*p)))
3533                 *p = '?';
3534               p++;
3535             }
3536           displayed_width = len;
3537         }
3538     }
3539   else if (width != NULL)
3540     {
3541 #if HAVE_MBRTOWC
3542       if (MB_CUR_MAX > 1)
3543         displayed_width = mbsnwidth (buf, len, 0);
3544       else
3545 #endif
3546         {
3547           char const *p = buf;
3548           char const *plimit = buf + len;
3549
3550           displayed_width = 0;
3551           while (p < plimit)
3552             {
3553               if (ISPRINT (to_uchar (*p)))
3554                 displayed_width++;
3555               p++;
3556             }
3557         }
3558     }
3559
3560   if (out != NULL)
3561     fwrite (buf, 1, len, out);
3562   if (width != NULL)
3563     *width = displayed_width;
3564   return len;
3565 }
3566
3567 static void
3568 print_name_with_quoting (const char *p, mode_t mode, int linkok,
3569                          struct obstack *stack)
3570 {
3571   if (print_with_color)
3572     print_color_indicator (p, mode, linkok);
3573
3574   if (stack)
3575     PUSH_CURRENT_DIRED_POS (stack);
3576
3577   dired_pos += quote_name (stdout, p, filename_quoting_options, NULL);
3578
3579   if (stack)
3580     PUSH_CURRENT_DIRED_POS (stack);
3581
3582   if (print_with_color)
3583     {
3584       process_signals ();
3585       prep_non_filename_text ();
3586     }
3587 }
3588
3589 static void
3590 prep_non_filename_text (void)
3591 {
3592   if (color_indicator[C_END].string != NULL)
3593     put_indicator (&color_indicator[C_END]);
3594   else
3595     {
3596       put_indicator (&color_indicator[C_LEFT]);
3597       put_indicator (&color_indicator[C_NORM]);
3598       put_indicator (&color_indicator[C_RIGHT]);
3599     }
3600 }
3601
3602 /* Print the file name of `f' with appropriate quoting.
3603    Also print file size, inode number, and filetype indicator character,
3604    as requested by switches.  */
3605
3606 static void
3607 print_file_name_and_frills (const struct fileinfo *f)
3608 {
3609   char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))];
3610
3611   if (print_inode)
3612     printf ("%*s ", format == with_commas ? 0 : inode_number_width,
3613             umaxtostr (f->stat.st_ino, buf));
3614
3615   if (print_block_size)
3616     printf ("%*s ", format == with_commas ? 0 : block_size_width,
3617             human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts,
3618                             ST_NBLOCKSIZE, output_block_size));
3619
3620   print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok, NULL);
3621
3622   if (indicator_style != none)
3623     print_type_indicator (f->stat.st_mode);
3624 }
3625
3626 static void
3627 print_type_indicator (mode_t mode)
3628 {
3629   char c;
3630
3631   if (S_ISREG (mode))
3632     {
3633       if (indicator_style == classify && (mode & S_IXUGO))
3634         c ='*';
3635       else
3636         c = 0;
3637     }
3638   else
3639     {
3640       if (S_ISDIR (mode))
3641         c = '/';
3642       else if (S_ISLNK (mode))
3643         c = '@';
3644       else if (S_ISFIFO (mode))
3645         c = '|';
3646       else if (S_ISSOCK (mode))
3647         c = '=';
3648       else if (S_ISDOOR (mode))
3649         c = '>';
3650       else
3651         c = 0;
3652     }
3653
3654   if (c)
3655     DIRED_PUTCHAR (c);
3656 }
3657
3658 static void
3659 print_color_indicator (const char *name, mode_t mode, int linkok)
3660 {
3661   int type = C_FILE;
3662   struct color_ext_type *ext;   /* Color extension */
3663   size_t len;                   /* Length of name */
3664
3665   /* Is this a nonexistent file?  If so, linkok == -1.  */
3666
3667   if (linkok == -1 && color_indicator[C_MISSING].string != NULL)
3668     {
3669       ext = NULL;
3670       type = C_MISSING;
3671     }
3672   else
3673     {
3674       if (S_ISDIR (mode))
3675         type = C_DIR;
3676       else if (S_ISLNK (mode))
3677         type = ((!linkok && color_indicator[C_ORPHAN].string)
3678                 ? C_ORPHAN : C_LINK);
3679       else if (S_ISFIFO (mode))
3680         type = C_FIFO;
3681       else if (S_ISSOCK (mode))
3682         type = C_SOCK;
3683       else if (S_ISBLK (mode))
3684         type = C_BLK;
3685       else if (S_ISCHR (mode))
3686         type = C_CHR;
3687       else if (S_ISDOOR (mode))
3688         type = C_DOOR;
3689
3690       if (type == C_FILE && (mode & S_IXUGO) != 0)
3691         type = C_EXEC;
3692
3693       /* Check the file's suffix only if still classified as C_FILE.  */
3694       ext = NULL;
3695       if (type == C_FILE)
3696         {
3697           /* Test if NAME has a recognized suffix.  */
3698
3699           len = strlen (name);
3700           name += len;          /* Pointer to final \0.  */
3701           for (ext = color_ext_list; ext != NULL; ext = ext->next)
3702             {
3703               if (ext->ext.len <= len
3704                   && strncmp (name - ext->ext.len, ext->ext.string,
3705                               ext->ext.len) == 0)
3706                 break;
3707             }
3708         }
3709     }
3710
3711   put_indicator (&color_indicator[C_LEFT]);
3712   put_indicator (ext ? &(ext->seq) : &color_indicator[type]);
3713   put_indicator (&color_indicator[C_RIGHT]);
3714 }
3715
3716 /* Output a color indicator (which may contain nulls).  */
3717 static void
3718 put_indicator (const struct bin_str *ind)
3719 {
3720   size_t i;
3721   const char *p;
3722
3723   p = ind->string;
3724
3725   for (i = ind->len; i != 0; --i)
3726     putchar (*(p++));
3727 }
3728
3729 static size_t
3730 length_of_file_name_and_frills (const struct fileinfo *f)
3731 {
3732   size_t len = 0;
3733   size_t name_width;
3734   char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))];
3735
3736   if (print_inode)
3737     len += 1 + (format == with_commas
3738                 ? strlen (umaxtostr (f->stat.st_ino, buf))
3739                 : inode_number_width);
3740
3741   if (print_block_size)
3742     len += 1 + (format == with_commas
3743                 ? strlen (human_readable (ST_NBLOCKS (f->stat), buf,
3744                                           human_output_opts, ST_NBLOCKSIZE,
3745                                           output_block_size))
3746                 : block_size_width);
3747
3748   quote_name (NULL, f->name, filename_quoting_options, &name_width);
3749   len += name_width;
3750
3751   if (indicator_style != none)
3752     {
3753       mode_t filetype = f->stat.st_mode;
3754
3755       if (S_ISREG (filetype))
3756         {
3757           if (indicator_style == classify
3758               && (f->stat.st_mode & S_IXUGO))
3759             len += 1;
3760         }
3761       else if (S_ISDIR (filetype)
3762                || S_ISLNK (filetype)
3763                || S_ISFIFO (filetype)
3764                || S_ISSOCK (filetype)
3765                || S_ISDOOR (filetype)
3766                )
3767         len += 1;
3768     }
3769
3770   return len;
3771 }
3772
3773 static void
3774 print_many_per_line (void)
3775 {
3776   size_t row;                   /* Current row.  */
3777   size_t cols = calculate_columns (true);
3778   struct column_info const *line_fmt = &column_info[cols - 1];
3779
3780   /* Calculate the number of rows that will be in each column except possibly
3781      for a short column on the right.  */
3782   size_t rows = files_index / cols + (files_index % cols != 0);
3783
3784   for (row = 0; row < rows; row++)
3785     {
3786       size_t col = 0;
3787       size_t filesno = row;
3788       size_t pos = 0;
3789
3790       /* Print the next row.  */
3791       while (1)
3792         {
3793           size_t name_length = length_of_file_name_and_frills (files + filesno);
3794           size_t max_name_length = line_fmt->col_arr[col++];
3795           print_file_name_and_frills (files + filesno);
3796
3797           filesno += rows;
3798           if (filesno >= files_index)
3799             break;
3800
3801           indent (pos + name_length, pos + max_name_length);
3802           pos += max_name_length;
3803         }
3804       putchar ('\n');
3805     }
3806 }
3807
3808 static void
3809 print_horizontal (void)
3810 {
3811   size_t filesno;
3812   size_t pos = 0;
3813   size_t cols = calculate_columns (false);
3814   struct column_info const *line_fmt = &column_info[cols - 1];
3815   size_t name_length = length_of_file_name_and_frills (files);
3816   size_t max_name_length = line_fmt->col_arr[0];
3817
3818   /* Print first entry.  */
3819   print_file_name_and_frills (files);
3820
3821   /* Now the rest.  */
3822   for (filesno = 1; filesno < files_index; ++filesno)
3823     {
3824       size_t col = filesno % cols;
3825
3826       if (col == 0)
3827         {
3828           putchar ('\n');
3829           pos = 0;
3830         }
3831       else
3832         {
3833           indent (pos + name_length, pos + max_name_length);
3834           pos += max_name_length;
3835         }
3836
3837       print_file_name_and_frills (files + filesno);
3838
3839       name_length = length_of_file_name_and_frills (files + filesno);
3840       max_name_length = line_fmt->col_arr[col];
3841     }
3842   putchar ('\n');
3843 }
3844
3845 static void
3846 print_with_commas (void)
3847 {
3848   size_t filesno;
3849   size_t pos = 0;
3850
3851   for (filesno = 0; filesno < files_index; filesno++)
3852     {
3853       size_t len = length_of_file_name_and_frills (files + filesno);
3854
3855       if (filesno != 0)
3856         {
3857           char separator;
3858
3859           if (pos + len + 2 < line_length)
3860             {
3861               pos += 2;
3862               separator = ' ';
3863             }
3864           else
3865             {
3866               pos = 0;
3867               separator = '\n';
3868             }
3869
3870           putchar (',');
3871           putchar (separator);
3872         }
3873
3874       print_file_name_and_frills (files + filesno);
3875       pos += len;
3876     }
3877   putchar ('\n');
3878 }
3879
3880 /* Assuming cursor is at position FROM, indent up to position TO.
3881    Use a TAB character instead of two or more spaces whenever possible.  */
3882
3883 static void
3884 indent (size_t from, size_t to)
3885 {
3886   while (from < to)
3887     {
3888       if (tabsize != 0 && to / tabsize > (from + 1) / tabsize)
3889         {
3890           putchar ('\t');
3891           from += tabsize - from % tabsize;
3892         }
3893       else
3894         {
3895           putchar (' ');
3896           from++;
3897         }
3898     }
3899 }
3900
3901 /* Put DIRNAME/NAME into DEST, handling `.' and `/' properly.  */
3902 /* FIXME: maybe remove this function someday.  See about using a
3903    non-malloc'ing version of path_concat.  */
3904
3905 static void
3906 attach (char *dest, const char *dirname, const char *name)
3907 {
3908   const char *dirnamep = dirname;
3909
3910   /* Copy dirname if it is not ".".  */
3911   if (dirname[0] != '.' || dirname[1] != 0)
3912     {
3913       while (*dirnamep)
3914         *dest++ = *dirnamep++;
3915       /* Add '/' if `dirname' doesn't already end with it.  */
3916       if (dirnamep > dirname && dirnamep[-1] != '/')
3917         *dest++ = '/';
3918     }
3919   while (*name)
3920     *dest++ = *name++;
3921   *dest = 0;
3922 }
3923
3924 /* Allocate enough column info suitable for the current number of
3925    files and display columns, and initialize the info to represent the
3926    narrowest possible columns.  */
3927
3928 static void
3929 init_column_info (void)
3930 {
3931   size_t i;
3932   size_t max_cols = MIN (max_idx, files_index);
3933
3934   /* Currently allocated columns in column_info.  */
3935   static size_t column_info_alloc;
3936
3937   if (column_info_alloc < max_cols)
3938     {
3939       size_t new_column_info_alloc;
3940       size_t *p;
3941
3942       if (max_cols < max_idx / 2)
3943         {
3944           /* The number of columns is far less than the display width
3945              allows.  Grow the allocation, but only so that it's
3946              double the current requirements.  If the display is
3947              extremely wide, this avoids allocating a lot of memory
3948              that is never needed.  */
3949           column_info = xnrealloc (column_info, max_cols,
3950                                    2 * sizeof *column_info);
3951           new_column_info_alloc = 2 * max_cols;
3952         }
3953       else
3954         {
3955           column_info = xnrealloc (column_info, max_idx, sizeof *column_info);
3956           new_column_info_alloc = max_idx;
3957         }
3958
3959       /* Allocate the new size_t objects by computing the triangle
3960          formula n * (n + 1) / 2, except that we don't need to
3961          allocate the part of the triangle that we've already
3962          allocated.  Check for address arithmetic overflow.  */
3963       {
3964         size_t column_info_growth = new_column_info_alloc - column_info_alloc;
3965         size_t s = column_info_alloc + 1 + new_column_info_alloc;
3966         size_t t = s * column_info_growth;
3967         if (s < new_column_info_alloc || t / column_info_growth != s)
3968           xalloc_die ();
3969         p = xnmalloc (t / 2, sizeof *p);
3970       }
3971
3972       /* Grow the triangle by parceling out the cells just allocated.  */
3973       for (i = column_info_alloc; i < new_column_info_alloc; i++)
3974         {
3975           column_info[i].col_arr = p;
3976           p += i + 1;
3977         }
3978
3979       column_info_alloc = new_column_info_alloc;
3980     }
3981
3982   for (i = 0; i < max_cols; ++i)
3983     {
3984       size_t j;
3985
3986       column_info[i].valid_len = true;
3987       column_info[i].line_len = (i + 1) * MIN_COLUMN_WIDTH;
3988       for (j = 0; j <= i; ++j)
3989         column_info[i].col_arr[j] = MIN_COLUMN_WIDTH;
3990     }
3991 }
3992
3993 /* Calculate the number of columns needed to represent the current set
3994    of files in the current display width.  */
3995
3996 static size_t
3997 calculate_columns (bool by_columns)
3998 {
3999   size_t filesno;               /* Index into files.  */
4000   size_t cols;                  /* Number of files across.  */
4001
4002   /* Normally the maximum number of columns is determined by the
4003      screen width.  But if few files are available this might limit it
4004      as well.  */
4005   size_t max_cols = MIN (max_idx, files_index);
4006
4007   init_column_info ();
4008
4009   /* Compute the maximum number of possible columns.  */
4010   for (filesno = 0; filesno < files_index; ++filesno)
4011     {
4012       size_t name_length = length_of_file_name_and_frills (files + filesno);
4013       size_t i;
4014
4015       for (i = 0; i < max_cols; ++i)
4016         {
4017           if (column_info[i].valid_len)
4018             {
4019               size_t idx = (by_columns
4020                             ? filesno / ((files_index + i) / (i + 1))
4021                             : filesno % (i + 1));
4022               size_t real_length = name_length + (idx == i ? 0 : 2);
4023
4024               if (column_info[i].col_arr[idx] < real_length)
4025                 {
4026                   column_info[i].line_len += (real_length
4027                                               - column_info[i].col_arr[idx]);
4028                   column_info[i].col_arr[idx] = real_length;
4029                   column_info[i].valid_len = (column_info[i].line_len
4030                                               < line_length);
4031                 }
4032             }
4033         }
4034     }
4035
4036   /* Find maximum allowed columns.  */
4037   for (cols = max_cols; 1 < cols; --cols)
4038     {
4039       if (column_info[cols - 1].valid_len)
4040         break;
4041     }
4042
4043   return cols;
4044 }
4045
4046 void
4047 usage (int status)
4048 {
4049   if (status != EXIT_SUCCESS)
4050     fprintf (stderr, _("Try `%s --help' for more information.\n"),
4051              program_name);
4052   else
4053     {
4054       printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);
4055       fputs (_("\
4056 List information about the FILEs (the current directory by default).\n\
4057 Sort entries alphabetically if none of -cftuSUX nor --sort.\n\
4058 \n\
4059 "), stdout);
4060       fputs (_("\
4061 Mandatory arguments to long options are mandatory for short options too.\n\
4062 "), stdout);
4063       fputs (_("\
4064   -a, --all                  do not ignore entries starting with .\n\
4065   -A, --almost-all           do not list implied . and ..\n\
4066       --author               with -l, print the author of each file\n\
4067   -b, --escape               print octal escapes for nongraphic characters\n\
4068 "), stdout);
4069       fputs (_("\
4070       --block-size=SIZE      use SIZE-byte blocks\n\
4071   -B, --ignore-backups       do not list implied entries ending with ~\n\
4072   -c                         with -lt: sort by, and show, ctime (time of last\n\
4073                                modification of file status information)\n\
4074                                with -l: show ctime and sort by name\n\
4075                                otherwise: sort by ctime\n\
4076 "), stdout);
4077       fputs (_("\
4078   -C                         list entries by columns\n\
4079       --color[=WHEN]         control whether color is used to distinguish file\n\
4080                                types.  WHEN may be `never', `always', or `auto'\n\
4081   -d, --directory            list directory entries instead of contents,\n\
4082                                and do not dereference symbolic links\n\
4083   -D, --dired                generate output designed for Emacs' dired mode\n\
4084 "), stdout);
4085       fputs (_("\
4086   -f                         do not sort, enable -aU, disable -lst\n\
4087   -F, --classify             append indicator (one of */=@|) to entries\n\
4088       --format=WORD          across -x, commas -m, horizontal -x, long -l,\n\
4089                                single-column -1, verbose -l, vertical -C\n\
4090       --full-time            like -l --time-style=full-iso\n\
4091 "), stdout);
4092       fputs (_("\
4093   -g                         like -l, but do not list owner\n\
4094   -G, --no-group             like -l, but do not list group\n\
4095   -h, --human-readable       with -l, print sizes in human readable format\n\
4096                                (e.g., 1K 234M 2G)\n\
4097       --si                   likewise, but use powers of 1000 not 1024\n\
4098   -H, --dereference-command-line\n\
4099                              follow symbolic links listed on the command line\n\
4100       --dereference-command-line-symlink-to-dir\n\
4101                              follow each command line symbolic link\n\
4102                              that points to a directory\n\
4103       --hide=PATTERN         do not list implied entries matching shell PATTERN\n\
4104                                (overridden by -a or -A)\n\
4105 "), stdout);
4106       fputs (_("\
4107       --indicator-style=WORD append indicator with style WORD to entry names:\n\
4108                                none (default), classify (-F), file-type (-p)\n\
4109   -i, --inode                with -l, print the index number of each file\n\
4110   -I, --ignore=PATTERN       do not list implied entries matching shell PATTERN\n\
4111   -k                         like --block-size=1K\n\
4112 "), stdout);
4113       fputs (_("\
4114   -l                         use a long listing format\n\
4115   -L, --dereference          when showing file information for a symbolic\n\
4116                                link, show information for the file the link\n\
4117                                references rather than for the link itself\n\
4118   -m                         fill width with a comma separated list of entries\n\
4119 "), stdout);
4120       fputs (_("\
4121   -n, --numeric-uid-gid      like -l, but list numeric UIDs and GIDs\n\
4122   -N, --literal              print raw entry names (don't treat e.g. control\n\
4123                                characters specially)\n\
4124   -o                         like -l, but do not list group information\n\
4125   -p, --file-type            append indicator (one of /=@|) to entries\n\
4126 "), stdout);
4127       fputs (_("\
4128   -q, --hide-control-chars   print ? instead of non graphic characters\n\
4129       --show-control-chars   show non graphic characters as-is (default\n\
4130                              unless program is `ls' and output is a terminal)\n\
4131   -Q, --quote-name           enclose entry names in double quotes\n\
4132       --quoting-style=WORD   use quoting style WORD for entry names:\n\
4133                                literal, locale, shell, shell-always, c, escape\n\
4134 "), stdout);
4135       fputs (_("\
4136   -r, --reverse              reverse order while sorting\n\
4137   -R, --recursive            list subdirectories recursively\n\
4138   -s, --size                 with -l, print size of each file, in blocks\n\
4139 "), stdout);
4140       fputs (_("\
4141   -S                         sort by file size\n\
4142       --sort=WORD            extension -X, none -U, size -S, time -t,\n\
4143                              version -v, status -c, time -t, atime -u,\n\
4144                              access -u, use -u\n\
4145       --time=WORD            with -l, show time as WORD instead of modification\n\
4146                              time: atime, access, use, ctime or status; use\n\
4147                              specified time as sort key if --sort=time\n\
4148 "), stdout);
4149       fputs (_("\
4150       --time-style=STYLE     with -l, show times using style STYLE:\n\
4151                              full-iso, long-iso, iso, locale, +FORMAT.\n\
4152                              FORMAT is interpreted like `date'; if FORMAT is\n\
4153                              FORMAT1<newline>FORMAT2, FORMAT1 applies to\n\
4154                              non-recent files and FORMAT2 to recent files;\n\
4155                              if STYLE is prefixed with `posix-', STYLE\n\
4156                              takes effect only outside the POSIX locale\n\
4157   -t                         sort by modification time\n\
4158   -T, --tabsize=COLS         assume tab stops at each COLS instead of 8\n\
4159 "), stdout);
4160       fputs (_("\
4161   -u                         with -lt: sort by, and show, access time\n\
4162                                with -l: show access time and sort by name\n\
4163                                otherwise: sort by access time\n\
4164   -U                         do not sort; list entries in directory order\n\
4165   -v                         sort by version\n\
4166 "), stdout);
4167       fputs (_("\
4168   -w, --width=COLS           assume screen width instead of current value\n\
4169   -x                         list entries by lines instead of by columns\n\
4170   -X                         sort alphabetically by entry extension\n\
4171   -1                         list one file per line\n\
4172 "), stdout);
4173       fputs (HELP_OPTION_DESCRIPTION, stdout);
4174       fputs (VERSION_OPTION_DESCRIPTION, stdout);
4175       fputs (_("\n\
4176 SIZE may be (or may be an integer optionally followed by) one of following:\n\
4177 kB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n\
4178 "), stdout);
4179       fputs (_("\
4180 \n\
4181 By default, color is not used to distinguish types of files.  That is\n\
4182 equivalent to using --color=none.  Using the --color option without the\n\
4183 optional WHEN argument is equivalent to using --color=always.  With\n\
4184 --color=auto, color codes are output only if standard output is connected\n\
4185 to a terminal (tty).  The environment variable LS_COLORS can influence the\n\
4186 colors, and can be set easily by the dircolors command.\n\
4187 "), stdout);
4188       fputs (_("\
4189 \n\
4190 Exit status is 0 if OK, 1 if minor problems, 2 if serious trouble.\n\
4191 "), stdout);
4192       printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
4193     }
4194   exit (status);
4195 }