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