* src/ls.c (usage): Describe exit statuses more concisely.
[coreutils/bo.git] / src / ls.c
blobe38a5fee54f4b91cee755aefc5372a470083c658
1 /* `dir', `vdir' and `ls' directory listing programs for GNU.
2 Copyright (C) 85, 88, 90, 91, 1995-2008 Free Software Foundation, Inc.
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 3 of the License, or
7 (at your option) any later version.
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.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* If ls_mode is LS_MULTI_COL,
18 the multi-column format is the default regardless
19 of the type of output device.
20 This is for the `dir' program.
22 If ls_mode is LS_LONG_FORMAT,
23 the long format is the default regardless of the
24 type of output device.
25 This is for the `vdir' program.
27 If ls_mode is LS_LS,
28 the output format depends on whether the output
29 device is a terminal.
30 This is for the `ls' program. */
32 /* Written by Richard Stallman and David MacKenzie. */
34 /* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
35 Flaherty <dennisf@denix.elk.miles.com> based on original patches by
36 Greg Lee <lee@uhunix.uhcc.hawaii.edu>. */
38 #include <config.h>
39 #include <sys/types.h>
41 #ifdef HAVE_CAP
42 # include <sys/capability.h>
43 #endif
45 #if HAVE_TERMIOS_H
46 # include <termios.h>
47 #endif
48 #if HAVE_STROPTS_H
49 # include <stropts.h>
50 #endif
51 #if HAVE_SYS_IOCTL_H
52 # include <sys/ioctl.h>
53 #endif
55 #ifdef WINSIZE_IN_PTEM
56 # include <sys/stream.h>
57 # include <sys/ptem.h>
58 #endif
60 #include <stdio.h>
61 #include <assert.h>
62 #include <setjmp.h>
63 #include <grp.h>
64 #include <pwd.h>
65 #include <getopt.h>
66 #include <signal.h>
67 #include <selinux/selinux.h>
68 #include <wchar.h>
70 /* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is
71 present. */
72 #ifndef SA_NOCLDSTOP
73 # define SA_NOCLDSTOP 0
74 # define sigprocmask(How, Set, Oset) /* empty */
75 # define sigset_t int
76 # if ! HAVE_SIGINTERRUPT
77 # define siginterrupt(sig, flag) /* empty */
78 # endif
79 #endif
80 #ifndef SA_RESTART
81 # define SA_RESTART 0
82 #endif
84 #include "system.h"
85 #include <fnmatch.h>
87 #include "acl.h"
88 #include "argmatch.h"
89 #include "dev-ino.h"
90 #include "error.h"
91 #include "filenamecat.h"
92 #include "hard-locale.h"
93 #include "hash.h"
94 #include "human.h"
95 #include "filemode.h"
96 #include "filevercmp.h"
97 #include "idcache.h"
98 #include "ls.h"
99 #include "mbswidth.h"
100 #include "mpsort.h"
101 #include "obstack.h"
102 #include "quote.h"
103 #include "quotearg.h"
104 #include "same.h"
105 #include "stat-time.h"
106 #include "strftime.h"
107 #include "xstrtol.h"
108 #include "areadlink.h"
110 #define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \
111 : (ls_mode == LS_MULTI_COL \
112 ? "dir" : "vdir"))
114 #define AUTHORS \
115 proper_name ("Richard M. Stallman"), \
116 proper_name ("David MacKenzie")
118 #define obstack_chunk_alloc malloc
119 #define obstack_chunk_free free
121 /* Return an int indicating the result of comparing two integers.
122 Subtracting doesn't always work, due to overflow. */
123 #define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b))
125 #if ! HAVE_STRUCT_STAT_ST_AUTHOR
126 # define st_author st_uid
127 #endif
129 enum filetype
131 unknown,
132 fifo,
133 chardev,
134 directory,
135 blockdev,
136 normal,
137 symbolic_link,
138 sock,
139 whiteout,
140 arg_directory
143 /* Display letters and indicators for each filetype.
144 Keep these in sync with enum filetype. */
145 static char const filetype_letter[] = "?pcdb-lswd";
147 /* Ensure that filetype and filetype_letter have the same
148 number of elements. */
149 verify (sizeof filetype_letter - 1 == arg_directory + 1);
151 #define FILETYPE_INDICATORS \
153 C_ORPHAN, C_FIFO, C_CHR, C_DIR, C_BLK, C_FILE, \
154 C_LINK, C_SOCK, C_FILE, C_DIR \
158 struct fileinfo
160 /* The file name. */
161 char *name;
163 /* For symbolic link, name of the file linked to, otherwise zero. */
164 char *linkname;
166 struct stat stat;
168 enum filetype filetype;
170 /* For symbolic link and long listing, st_mode of file linked to, otherwise
171 zero. */
172 mode_t linkmode;
174 /* SELinux security context. */
175 security_context_t scontext;
177 bool stat_ok;
179 /* For symbolic link and color printing, true if linked-to file
180 exists, otherwise false. */
181 bool linkok;
183 /* For long listings, true if the file has an access control list,
184 or an SELinux security context. */
185 bool have_acl;
188 #define LEN_STR_PAIR(s) sizeof (s) - 1, s
190 /* Null is a valid character in a color indicator (think about Epson
191 printers, for example) so we have to use a length/buffer string
192 type. */
194 struct bin_str
196 size_t len; /* Number of bytes */
197 const char *string; /* Pointer to the same */
200 #if ! HAVE_TCGETPGRP
201 # define tcgetpgrp(Fd) 0
202 #endif
204 static size_t quote_name (FILE *out, const char *name,
205 struct quoting_options const *options,
206 size_t *width);
207 static char *make_link_name (char const *name, char const *linkname);
208 static int decode_switches (int argc, char **argv);
209 static bool file_ignored (char const *name);
210 static uintmax_t gobble_file (char const *name, enum filetype type,
211 ino_t inode, bool command_line_arg,
212 char const *dirname);
213 static bool print_color_indicator (const char *name, mode_t mode, int linkok,
214 bool stat_ok, enum filetype type);
215 static void put_indicator (const struct bin_str *ind);
216 static void add_ignore_pattern (const char *pattern);
217 static void attach (char *dest, const char *dirname, const char *name);
218 static void clear_files (void);
219 static void extract_dirs_from_files (char const *dirname,
220 bool command_line_arg);
221 static void get_link_name (char const *filename, struct fileinfo *f,
222 bool command_line_arg);
223 static void indent (size_t from, size_t to);
224 static size_t calculate_columns (bool by_columns);
225 static void print_current_files (void);
226 static void print_dir (char const *name, char const *realname,
227 bool command_line_arg);
228 static void print_file_name_and_frills (const struct fileinfo *f);
229 static void print_horizontal (void);
230 static int format_user_width (uid_t u);
231 static int format_group_width (gid_t g);
232 static void print_long_format (const struct fileinfo *f);
233 static void print_many_per_line (void);
234 static void print_name_with_quoting (const char *p, mode_t mode,
235 int linkok, bool stat_ok,
236 enum filetype type,
237 struct obstack *stack);
238 static void prep_non_filename_text (void);
239 static void print_type_indicator (bool stat_ok, mode_t mode,
240 enum filetype type);
241 static void print_with_commas (void);
242 static void queue_directory (char const *name, char const *realname,
243 bool command_line_arg);
244 static void sort_files (void);
245 static void parse_ls_color (void);
246 void usage (int status);
248 /* Initial size of hash table.
249 Most hierarchies are likely to be shallower than this. */
250 #define INITIAL_TABLE_SIZE 30
252 /* The set of `active' directories, from the current command-line argument
253 to the level in the hierarchy at which files are being listed.
254 A directory is represented by its device and inode numbers (struct dev_ino).
255 A directory is added to this set when ls begins listing it or its
256 entries, and it is removed from the set just after ls has finished
257 processing it. This set is used solely to detect loops, e.g., with
258 mkdir loop; cd loop; ln -s ../loop sub; ls -RL */
259 static Hash_table *active_dir_set;
261 #define LOOP_DETECT (!!active_dir_set)
263 /* The table of files in the current directory:
265 `cwd_file' points to a vector of `struct fileinfo', one per file.
266 `cwd_n_alloc' is the number of elements space has been allocated for.
267 `cwd_n_used' is the number actually in use. */
269 /* Address of block containing the files that are described. */
270 static struct fileinfo *cwd_file;
272 /* Length of block that `cwd_file' points to, measured in files. */
273 static size_t cwd_n_alloc;
275 /* Index of first unused slot in `cwd_file'. */
276 static size_t cwd_n_used;
278 /* Vector of pointers to files, in proper sorted order, and the number
279 of entries allocated for it. */
280 static void **sorted_file;
281 static size_t sorted_file_alloc;
283 /* When true, in a color listing, color each symlink name according to the
284 type of file it points to. Otherwise, color them according to the `ln'
285 directive in LS_COLORS. Dangling (orphan) symlinks are treated specially,
286 regardless. This is set when `ln=target' appears in LS_COLORS. */
288 static bool color_symlink_as_referent;
290 /* mode of appropriate file for colorization */
291 #define FILE_OR_LINK_MODE(File) \
292 ((color_symlink_as_referent & (File)->linkok) \
293 ? (File)->linkmode : (File)->stat.st_mode)
296 /* Record of one pending directory waiting to be listed. */
298 struct pending
300 char *name;
301 /* If the directory is actually the file pointed to by a symbolic link we
302 were told to list, `realname' will contain the name of the symbolic
303 link, otherwise zero. */
304 char *realname;
305 bool command_line_arg;
306 struct pending *next;
309 static struct pending *pending_dirs;
311 /* Current time in seconds and nanoseconds since 1970, updated as
312 needed when deciding whether a file is recent. */
314 static struct timespec current_time;
316 static bool print_scontext;
317 static char UNKNOWN_SECURITY_CONTEXT[] = "?";
319 /* Whether any of the files has an ACL. This affects the width of the
320 mode column. */
322 static bool any_has_acl;
324 /* The number of columns to use for columns containing inode numbers,
325 block sizes, link counts, owners, groups, authors, major device
326 numbers, minor device numbers, and file sizes, respectively. */
328 static int inode_number_width;
329 static int block_size_width;
330 static int nlink_width;
331 static int scontext_width;
332 static int owner_width;
333 static int group_width;
334 static int author_width;
335 static int major_device_number_width;
336 static int minor_device_number_width;
337 static int file_size_width;
339 /* Option flags */
341 /* long_format for lots of info, one per line.
342 one_per_line for just names, one per line.
343 many_per_line for just names, many per line, sorted vertically.
344 horizontal for just names, many per line, sorted horizontally.
345 with_commas for just names, many per line, separated by commas.
347 -l (and other options that imply -l), -1, -C, -x and -m control
348 this parameter. */
350 enum format
352 long_format, /* -l and other options that imply -l */
353 one_per_line, /* -1 */
354 many_per_line, /* -C */
355 horizontal, /* -x */
356 with_commas /* -m */
359 static enum format format;
361 /* `full-iso' uses full ISO-style dates and times. `long-iso' uses longer
362 ISO-style time stamps, though shorter than `full-iso'. `iso' uses shorter
363 ISO-style time stamps. `locale' uses locale-dependent time stamps. */
364 enum time_style
366 full_iso_time_style, /* --time-style=full-iso */
367 long_iso_time_style, /* --time-style=long-iso */
368 iso_time_style, /* --time-style=iso */
369 locale_time_style /* --time-style=locale */
372 static char const *const time_style_args[] =
374 "full-iso", "long-iso", "iso", "locale", NULL
376 static enum time_style const time_style_types[] =
378 full_iso_time_style, long_iso_time_style, iso_time_style,
379 locale_time_style
381 ARGMATCH_VERIFY (time_style_args, time_style_types);
383 /* Type of time to print or sort by. Controlled by -c and -u.
384 The values of each item of this enum are important since they are
385 used as indices in the sort functions array (see sort_files()). */
387 enum time_type
389 time_mtime, /* default */
390 time_ctime, /* -c */
391 time_atime, /* -u */
392 time_numtypes /* the number of elements of this enum */
395 static enum time_type time_type;
397 /* The file characteristic to sort by. Controlled by -t, -S, -U, -X, -v.
398 The values of each item of this enum are important since they are
399 used as indices in the sort functions array (see sort_files()). */
401 enum sort_type
403 sort_none = -1, /* -U */
404 sort_name, /* default */
405 sort_extension, /* -X */
406 sort_size, /* -S */
407 sort_version, /* -v */
408 sort_time, /* -t */
409 sort_numtypes /* the number of elements of this enum */
412 static enum sort_type sort_type;
414 /* Direction of sort.
415 false means highest first if numeric,
416 lowest first if alphabetic;
417 these are the defaults.
418 true means the opposite order in each case. -r */
420 static bool sort_reverse;
422 /* True means to display owner information. -g turns this off. */
424 static bool print_owner = true;
426 /* True means to display author information. */
428 static bool print_author;
430 /* True means to display group information. -G and -o turn this off. */
432 static bool print_group = true;
434 /* True means print the user and group id's as numbers rather
435 than as names. -n */
437 static bool numeric_ids;
439 /* True means mention the size in blocks of each file. -s */
441 static bool print_block_size;
443 /* Human-readable options for output. */
444 static int human_output_opts;
446 /* The units to use when printing sizes other than file sizes. */
447 static uintmax_t output_block_size;
449 /* Likewise, but for file sizes. */
450 static uintmax_t file_output_block_size = 1;
452 /* Follow the output with a special string. Using this format,
453 Emacs' dired mode starts up twice as fast, and can handle all
454 strange characters in file names. */
455 static bool dired;
457 /* `none' means don't mention the type of files.
458 `slash' means mention directories only, with a '/'.
459 `file_type' means mention file types.
460 `classify' means mention file types and mark executables.
462 Controlled by -F, -p, and --indicator-style. */
464 enum indicator_style
466 none, /* --indicator-style=none */
467 slash, /* -p, --indicator-style=slash */
468 file_type, /* --indicator-style=file-type */
469 classify /* -F, --indicator-style=classify */
472 static enum indicator_style indicator_style;
474 /* Names of indicator styles. */
475 static char const *const indicator_style_args[] =
477 "none", "slash", "file-type", "classify", NULL
479 static enum indicator_style const indicator_style_types[] =
481 none, slash, file_type, classify
483 ARGMATCH_VERIFY (indicator_style_args, indicator_style_types);
485 /* True means use colors to mark types. Also define the different
486 colors as well as the stuff for the LS_COLORS environment variable.
487 The LS_COLORS variable is now in a termcap-like format. */
489 static bool print_with_color;
491 /* Whether we used any colors in the output so far. If so, we will
492 need to restore the default color later. If not, we will need to
493 call prep_non_filename_text before using color for the first time. */
495 static bool used_color = false;
497 enum color_type
499 color_never, /* 0: default or --color=never */
500 color_always, /* 1: --color=always */
501 color_if_tty /* 2: --color=tty */
504 enum Dereference_symlink
506 DEREF_UNDEFINED = 1,
507 DEREF_NEVER,
508 DEREF_COMMAND_LINE_ARGUMENTS, /* -H */
509 DEREF_COMMAND_LINE_SYMLINK_TO_DIR, /* the default, in certain cases */
510 DEREF_ALWAYS /* -L */
513 enum indicator_no
515 C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK,
516 C_FIFO, C_SOCK,
517 C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID,
518 C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP
521 static const char *const indicator_name[]=
523 "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so",
524 "bd", "cd", "mi", "or", "ex", "do", "su", "sg", "st",
525 "ow", "tw", "ca", NULL
528 struct color_ext_type
530 struct bin_str ext; /* The extension we're looking for */
531 struct bin_str seq; /* The sequence to output when we do */
532 struct color_ext_type *next; /* Next in list */
535 static struct bin_str color_indicator[] =
537 { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */
538 { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */
539 { 0, NULL }, /* ec: End color (replaces lc+no+rc) */
540 { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */
541 { 0, NULL }, /* no: Normal */
542 { 0, NULL }, /* fi: File: default */
543 { LEN_STR_PAIR ("01;34") }, /* di: Directory: bright blue */
544 { LEN_STR_PAIR ("01;36") }, /* ln: Symlink: bright cyan */
545 { LEN_STR_PAIR ("33") }, /* pi: Pipe: yellow/brown */
546 { LEN_STR_PAIR ("01;35") }, /* so: Socket: bright magenta */
547 { LEN_STR_PAIR ("01;33") }, /* bd: Block device: bright yellow */
548 { LEN_STR_PAIR ("01;33") }, /* cd: Char device: bright yellow */
549 { 0, NULL }, /* mi: Missing file: undefined */
550 { 0, NULL }, /* or: Orphaned symlink: undefined */
551 { LEN_STR_PAIR ("01;32") }, /* ex: Executable: bright green */
552 { LEN_STR_PAIR ("01;35") }, /* do: Door: bright magenta */
553 { LEN_STR_PAIR ("37;41") }, /* su: setuid: white on red */
554 { LEN_STR_PAIR ("30;43") }, /* sg: setgid: black on yellow */
555 { LEN_STR_PAIR ("37;44") }, /* st: sticky: black on blue */
556 { LEN_STR_PAIR ("34;42") }, /* ow: other-writable: blue on green */
557 { LEN_STR_PAIR ("30;42") }, /* tw: ow w/ sticky: black on green */
558 { LEN_STR_PAIR ("30;41") }, /* capability: black on red */
561 /* FIXME: comment */
562 static struct color_ext_type *color_ext_list = NULL;
564 /* Buffer for color sequences */
565 static char *color_buf;
567 /* True means to check for orphaned symbolic link, for displaying
568 colors. */
570 static bool check_symlink_color;
572 /* True means mention the inode number of each file. -i */
574 static bool print_inode;
576 /* What to do with symbolic links. Affected by -d, -F, -H, -l (and
577 other options that imply -l), and -L. */
579 static enum Dereference_symlink dereference;
581 /* True means when a directory is found, display info on its
582 contents. -R */
584 static bool recursive;
586 /* True means when an argument is a directory name, display info
587 on it itself. -d */
589 static bool immediate_dirs;
591 /* True means that directories are grouped before files. */
593 static bool directories_first;
595 /* Which files to ignore. */
597 static enum
599 /* Ignore files whose names start with `.', and files specified by
600 --hide and --ignore. */
601 IGNORE_DEFAULT,
603 /* Ignore `.', `..', and files specified by --ignore. */
604 IGNORE_DOT_AND_DOTDOT,
606 /* Ignore only files specified by --ignore. */
607 IGNORE_MINIMAL
608 } ignore_mode;
610 /* A linked list of shell-style globbing patterns. If a non-argument
611 file name matches any of these patterns, it is ignored.
612 Controlled by -I. Multiple -I options accumulate.
613 The -B option adds `*~' and `.*~' to this list. */
615 struct ignore_pattern
617 const char *pattern;
618 struct ignore_pattern *next;
621 static struct ignore_pattern *ignore_patterns;
623 /* Similar to IGNORE_PATTERNS, except that -a or -A causes this
624 variable itself to be ignored. */
625 static struct ignore_pattern *hide_patterns;
627 /* True means output nongraphic chars in file names as `?'.
628 (-q, --hide-control-chars)
629 qmark_funny_chars and the quoting style (-Q, --quoting-style=WORD) are
630 independent. The algorithm is: first, obey the quoting style to get a
631 string representing the file name; then, if qmark_funny_chars is set,
632 replace all nonprintable chars in that string with `?'. It's necessary
633 to replace nonprintable chars even in quoted strings, because we don't
634 want to mess up the terminal if control chars get sent to it, and some
635 quoting methods pass through control chars as-is. */
636 static bool qmark_funny_chars;
638 /* Quoting options for file and dir name output. */
640 static struct quoting_options *filename_quoting_options;
641 static struct quoting_options *dirname_quoting_options;
643 /* The number of chars per hardware tab stop. Setting this to zero
644 inhibits the use of TAB characters for separating columns. -T */
645 static size_t tabsize;
647 /* True means print each directory name before listing it. */
649 static bool print_dir_name;
651 /* The line length to use for breaking lines in many-per-line format.
652 Can be set with -w. */
654 static size_t line_length;
656 /* If true, the file listing format requires that stat be called on
657 each file. */
659 static bool format_needs_stat;
661 /* Similar to `format_needs_stat', but set if only the file type is
662 needed. */
664 static bool format_needs_type;
666 /* An arbitrary limit on the number of bytes in a printed time stamp.
667 This is set to a relatively small value to avoid the need to worry
668 about denial-of-service attacks on servers that run "ls" on behalf
669 of remote clients. 1000 bytes should be enough for any practical
670 time stamp format. */
672 enum { TIME_STAMP_LEN_MAXIMUM = MAX (1000, INT_STRLEN_BOUND (time_t)) };
674 /* strftime formats for non-recent and recent files, respectively, in
675 -l output. */
677 static char const *long_time_format[2] =
679 /* strftime format for non-recent files (older than 6 months), in
680 -l output. This should contain the year, month and day (at
681 least), in an order that is understood by people in your
682 locale's territory. Please try to keep the number of used
683 screen columns small, because many people work in windows with
684 only 80 columns. But make this as wide as the other string
685 below, for recent files. */
686 N_("%b %e %Y"),
687 /* strftime format for recent files (younger than 6 months), in -l
688 output. This should contain the month, day and time (at
689 least), in an order that is understood by people in your
690 locale's territory. Please try to keep the number of used
691 screen columns small, because many people work in windows with
692 only 80 columns. But make this as wide as the other string
693 above, for non-recent files. */
694 N_("%b %e %H:%M")
697 /* The set of signals that are caught. */
699 static sigset_t caught_signals;
701 /* If nonzero, the value of the pending fatal signal. */
703 static sig_atomic_t volatile interrupt_signal;
705 /* A count of the number of pending stop signals that have been received. */
707 static sig_atomic_t volatile stop_signal_count;
709 /* Desired exit status. */
711 static int exit_status;
713 /* Exit statuses. */
714 enum
716 /* "ls" had a minor problem. E.g., while processing a directory,
717 ls obtained the name of an entry via readdir, yet was later
718 unable to stat that name. This happens when listing a directory
719 in which entries are actively being removed or renamed. */
720 LS_MINOR_PROBLEM = 1,
722 /* "ls" had more serious trouble (e.g., memory exhausted, invalid
723 option or failure to stat a command line argument. */
724 LS_FAILURE = 2
727 /* For long options that have no equivalent short option, use a
728 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
729 enum
731 AUTHOR_OPTION = CHAR_MAX + 1,
732 BLOCK_SIZE_OPTION,
733 COLOR_OPTION,
734 DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION,
735 FILE_TYPE_INDICATOR_OPTION,
736 FORMAT_OPTION,
737 FULL_TIME_OPTION,
738 GROUP_DIRECTORIES_FIRST_OPTION,
739 HIDE_OPTION,
740 INDICATOR_STYLE_OPTION,
741 QUOTING_STYLE_OPTION,
742 SHOW_CONTROL_CHARS_OPTION,
743 SI_OPTION,
744 SORT_OPTION,
745 TIME_OPTION,
746 TIME_STYLE_OPTION
749 static struct option const long_options[] =
751 {"all", no_argument, NULL, 'a'},
752 {"escape", no_argument, NULL, 'b'},
753 {"directory", no_argument, NULL, 'd'},
754 {"dired", no_argument, NULL, 'D'},
755 {"full-time", no_argument, NULL, FULL_TIME_OPTION},
756 {"group-directories-first", no_argument, NULL,
757 GROUP_DIRECTORIES_FIRST_OPTION},
758 {"human-readable", no_argument, NULL, 'h'},
759 {"inode", no_argument, NULL, 'i'},
760 {"numeric-uid-gid", no_argument, NULL, 'n'},
761 {"no-group", no_argument, NULL, 'G'},
762 {"hide-control-chars", no_argument, NULL, 'q'},
763 {"reverse", no_argument, NULL, 'r'},
764 {"size", no_argument, NULL, 's'},
765 {"width", required_argument, NULL, 'w'},
766 {"almost-all", no_argument, NULL, 'A'},
767 {"ignore-backups", no_argument, NULL, 'B'},
768 {"classify", no_argument, NULL, 'F'},
769 {"file-type", no_argument, NULL, FILE_TYPE_INDICATOR_OPTION},
770 {"si", no_argument, NULL, SI_OPTION},
771 {"dereference-command-line", no_argument, NULL, 'H'},
772 {"dereference-command-line-symlink-to-dir", no_argument, NULL,
773 DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION},
774 {"hide", required_argument, NULL, HIDE_OPTION},
775 {"ignore", required_argument, NULL, 'I'},
776 {"indicator-style", required_argument, NULL, INDICATOR_STYLE_OPTION},
777 {"dereference", no_argument, NULL, 'L'},
778 {"literal", no_argument, NULL, 'N'},
779 {"quote-name", no_argument, NULL, 'Q'},
780 {"quoting-style", required_argument, NULL, QUOTING_STYLE_OPTION},
781 {"recursive", no_argument, NULL, 'R'},
782 {"format", required_argument, NULL, FORMAT_OPTION},
783 {"show-control-chars", no_argument, NULL, SHOW_CONTROL_CHARS_OPTION},
784 {"sort", required_argument, NULL, SORT_OPTION},
785 {"tabsize", required_argument, NULL, 'T'},
786 {"time", required_argument, NULL, TIME_OPTION},
787 {"time-style", required_argument, NULL, TIME_STYLE_OPTION},
788 {"color", optional_argument, NULL, COLOR_OPTION},
789 {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION},
790 {"context", no_argument, 0, 'Z'},
791 {"author", no_argument, NULL, AUTHOR_OPTION},
792 {GETOPT_HELP_OPTION_DECL},
793 {GETOPT_VERSION_OPTION_DECL},
794 {NULL, 0, NULL, 0}
797 static char const *const format_args[] =
799 "verbose", "long", "commas", "horizontal", "across",
800 "vertical", "single-column", NULL
802 static enum format const format_types[] =
804 long_format, long_format, with_commas, horizontal, horizontal,
805 many_per_line, one_per_line
807 ARGMATCH_VERIFY (format_args, format_types);
809 static char const *const sort_args[] =
811 "none", "time", "size", "extension", "version", NULL
813 static enum sort_type const sort_types[] =
815 sort_none, sort_time, sort_size, sort_extension, sort_version
817 ARGMATCH_VERIFY (sort_args, sort_types);
819 static char const *const time_args[] =
821 "atime", "access", "use", "ctime", "status", NULL
823 static enum time_type const time_types[] =
825 time_atime, time_atime, time_atime, time_ctime, time_ctime
827 ARGMATCH_VERIFY (time_args, time_types);
829 static char const *const color_args[] =
831 /* force and none are for compatibility with another color-ls version */
832 "always", "yes", "force",
833 "never", "no", "none",
834 "auto", "tty", "if-tty", NULL
836 static enum color_type const color_types[] =
838 color_always, color_always, color_always,
839 color_never, color_never, color_never,
840 color_if_tty, color_if_tty, color_if_tty
842 ARGMATCH_VERIFY (color_args, color_types);
844 /* Information about filling a column. */
845 struct column_info
847 bool valid_len;
848 size_t line_len;
849 size_t *col_arr;
852 /* Array with information about column filledness. */
853 static struct column_info *column_info;
855 /* Maximum number of columns ever possible for this display. */
856 static size_t max_idx;
858 /* The minimum width of a column is 3: 1 character for the name and 2
859 for the separating white space. */
860 #define MIN_COLUMN_WIDTH 3
863 /* This zero-based index is used solely with the --dired option.
864 When that option is in effect, this counter is incremented for each
865 byte of output generated by this program so that the beginning
866 and ending indices (in that output) of every file name can be recorded
867 and later output themselves. */
868 static size_t dired_pos;
870 #define DIRED_PUTCHAR(c) do {putchar ((c)); ++dired_pos;} while (0)
872 /* Write S to STREAM and increment DIRED_POS by S_LEN. */
873 #define DIRED_FPUTS(s, stream, s_len) \
874 do {fputs (s, stream); dired_pos += s_len;} while (0)
876 /* Like DIRED_FPUTS, but for use when S is a literal string. */
877 #define DIRED_FPUTS_LITERAL(s, stream) \
878 do {fputs (s, stream); dired_pos += sizeof (s) - 1;} while (0)
880 #define DIRED_INDENT() \
881 do \
883 if (dired) \
884 DIRED_FPUTS_LITERAL (" ", stdout); \
886 while (0)
888 /* With --dired, store pairs of beginning and ending indices of filenames. */
889 static struct obstack dired_obstack;
891 /* With --dired, store pairs of beginning and ending indices of any
892 directory names that appear as headers (just before `total' line)
893 for lists of directory entries. Such directory names are seen when
894 listing hierarchies using -R and when a directory is listed with at
895 least one other command line argument. */
896 static struct obstack subdired_obstack;
898 /* Save the current index on the specified obstack, OBS. */
899 #define PUSH_CURRENT_DIRED_POS(obs) \
900 do \
902 if (dired) \
903 obstack_grow (obs, &dired_pos, sizeof (dired_pos)); \
905 while (0)
907 /* With -R, this stack is used to help detect directory cycles.
908 The device/inode pairs on this stack mirror the pairs in the
909 active_dir_set hash table. */
910 static struct obstack dev_ino_obstack;
912 /* Push a pair onto the device/inode stack. */
913 #define DEV_INO_PUSH(Dev, Ino) \
914 do \
916 struct dev_ino *di; \
917 obstack_blank (&dev_ino_obstack, sizeof (struct dev_ino)); \
918 di = -1 + (struct dev_ino *) obstack_next_free (&dev_ino_obstack); \
919 di->st_dev = (Dev); \
920 di->st_ino = (Ino); \
922 while (0)
924 /* Pop a dev/ino struct off the global dev_ino_obstack
925 and return that struct. */
926 static struct dev_ino
927 dev_ino_pop (void)
929 assert (sizeof (struct dev_ino) <= obstack_object_size (&dev_ino_obstack));
930 obstack_blank (&dev_ino_obstack, -(int) (sizeof (struct dev_ino)));
931 return *(struct dev_ino *) obstack_next_free (&dev_ino_obstack);
934 #define ASSERT_MATCHING_DEV_INO(Name, Di) \
935 do \
937 struct stat sb; \
938 assert (Name); \
939 assert (0 <= stat (Name, &sb)); \
940 assert (sb.st_dev == Di.st_dev); \
941 assert (sb.st_ino == Di.st_ino); \
943 while (0)
946 /* Write to standard output PREFIX, followed by the quoting style and
947 a space-separated list of the integers stored in OS all on one line. */
949 static void
950 dired_dump_obstack (const char *prefix, struct obstack *os)
952 size_t n_pos;
954 n_pos = obstack_object_size (os) / sizeof (dired_pos);
955 if (n_pos > 0)
957 size_t i;
958 size_t *pos;
960 pos = (size_t *) obstack_finish (os);
961 fputs (prefix, stdout);
962 for (i = 0; i < n_pos; i++)
963 printf (" %lu", (unsigned long int) pos[i]);
964 putchar ('\n');
968 static size_t
969 dev_ino_hash (void const *x, size_t table_size)
971 struct dev_ino const *p = x;
972 return (uintmax_t) p->st_ino % table_size;
975 static bool
976 dev_ino_compare (void const *x, void const *y)
978 struct dev_ino const *a = x;
979 struct dev_ino const *b = y;
980 return SAME_INODE (*a, *b) ? true : false;
983 static void
984 dev_ino_free (void *x)
986 free (x);
989 /* Add the device/inode pair (P->st_dev/P->st_ino) to the set of
990 active directories. Return true if there is already a matching
991 entry in the table. */
993 static bool
994 visit_dir (dev_t dev, ino_t ino)
996 struct dev_ino *ent;
997 struct dev_ino *ent_from_table;
998 bool found_match;
1000 ent = xmalloc (sizeof *ent);
1001 ent->st_ino = ino;
1002 ent->st_dev = dev;
1004 /* Attempt to insert this entry into the table. */
1005 ent_from_table = hash_insert (active_dir_set, ent);
1007 if (ent_from_table == NULL)
1009 /* Insertion failed due to lack of memory. */
1010 xalloc_die ();
1013 found_match = (ent_from_table != ent);
1015 if (found_match)
1017 /* ent was not inserted, so free it. */
1018 free (ent);
1021 return found_match;
1024 static void
1025 free_pending_ent (struct pending *p)
1027 free (p->name);
1028 free (p->realname);
1029 free (p);
1032 static bool
1033 is_colored (enum indicator_no type)
1035 size_t len = color_indicator[type].len;
1036 char const *s = color_indicator[type].string;
1037 return ! (len == 0
1038 || (len == 1 && strncmp (s, "0", 1) == 0)
1039 || (len == 2 && strncmp (s, "00", 2) == 0));
1042 static void
1043 restore_default_color (void)
1045 put_indicator (&color_indicator[C_LEFT]);
1046 put_indicator (&color_indicator[C_RIGHT]);
1049 /* An ordinary signal was received; arrange for the program to exit. */
1051 static void
1052 sighandler (int sig)
1054 if (! SA_NOCLDSTOP)
1055 signal (sig, SIG_IGN);
1056 if (! interrupt_signal)
1057 interrupt_signal = sig;
1060 /* A SIGTSTP was received; arrange for the program to suspend itself. */
1062 static void
1063 stophandler (int sig)
1065 if (! SA_NOCLDSTOP)
1066 signal (sig, stophandler);
1067 if (! interrupt_signal)
1068 stop_signal_count++;
1071 /* Process any pending signals. If signals are caught, this function
1072 should be called periodically. Ideally there should never be an
1073 unbounded amount of time when signals are not being processed.
1074 Signal handling can restore the default colors, so callers must
1075 immediately change colors after invoking this function. */
1077 static void
1078 process_signals (void)
1080 while (interrupt_signal | stop_signal_count)
1082 int sig;
1083 int stops;
1084 sigset_t oldset;
1086 if (used_color)
1087 restore_default_color ();
1088 fflush (stdout);
1090 sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
1092 /* Reload interrupt_signal and stop_signal_count, in case a new
1093 signal was handled before sigprocmask took effect. */
1094 sig = interrupt_signal;
1095 stops = stop_signal_count;
1097 /* SIGTSTP is special, since the application can receive that signal
1098 more than once. In this case, don't set the signal handler to the
1099 default. Instead, just raise the uncatchable SIGSTOP. */
1100 if (stops)
1102 stop_signal_count = stops - 1;
1103 sig = SIGSTOP;
1105 else
1106 signal (sig, SIG_DFL);
1108 /* Exit or suspend the program. */
1109 raise (sig);
1110 sigprocmask (SIG_SETMASK, &oldset, NULL);
1112 /* If execution reaches here, then the program has been
1113 continued (after being suspended). */
1118 main (int argc, char **argv)
1120 int i;
1121 struct pending *thispend;
1122 int n_files;
1124 /* The signals that are trapped, and the number of such signals. */
1125 static int const sig[] =
1127 /* This one is handled specially. */
1128 SIGTSTP,
1130 /* The usual suspects. */
1131 SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM,
1132 #ifdef SIGPOLL
1133 SIGPOLL,
1134 #endif
1135 #ifdef SIGPROF
1136 SIGPROF,
1137 #endif
1138 #ifdef SIGVTALRM
1139 SIGVTALRM,
1140 #endif
1141 #ifdef SIGXCPU
1142 SIGXCPU,
1143 #endif
1144 #ifdef SIGXFSZ
1145 SIGXFSZ,
1146 #endif
1148 enum { nsigs = sizeof sig / sizeof sig[0] };
1150 #if ! SA_NOCLDSTOP
1151 bool caught_sig[nsigs];
1152 #endif
1154 initialize_main (&argc, &argv);
1155 set_program_name (argv[0]);
1156 setlocale (LC_ALL, "");
1157 bindtextdomain (PACKAGE, LOCALEDIR);
1158 textdomain (PACKAGE);
1160 initialize_exit_failure (LS_FAILURE);
1161 atexit (close_stdout);
1163 #define N_ENTRIES(Array) (sizeof Array / sizeof *(Array))
1164 assert (N_ENTRIES (color_indicator) + 1 == N_ENTRIES (indicator_name));
1166 exit_status = EXIT_SUCCESS;
1167 print_dir_name = true;
1168 pending_dirs = NULL;
1170 current_time.tv_sec = TYPE_MINIMUM (time_t);
1171 current_time.tv_nsec = -1;
1173 i = decode_switches (argc, argv);
1175 if (print_with_color)
1176 parse_ls_color ();
1178 /* Test print_with_color again, because the call to parse_ls_color
1179 may have just reset it -- e.g., if LS_COLORS is invalid. */
1180 if (print_with_color)
1182 /* Avoid following symbolic links when possible. */
1183 if (is_colored (C_ORPHAN)
1184 || (is_colored (C_EXEC) && color_symlink_as_referent)
1185 || (is_colored (C_MISSING) && format == long_format))
1186 check_symlink_color = true;
1188 /* If the standard output is a controlling terminal, watch out
1189 for signals, so that the colors can be restored to the
1190 default state if "ls" is suspended or interrupted. */
1192 if (0 <= tcgetpgrp (STDOUT_FILENO))
1194 int j;
1195 #if SA_NOCLDSTOP
1196 struct sigaction act;
1198 sigemptyset (&caught_signals);
1199 for (j = 0; j < nsigs; j++)
1201 sigaction (sig[j], NULL, &act);
1202 if (act.sa_handler != SIG_IGN)
1203 sigaddset (&caught_signals, sig[j]);
1206 act.sa_mask = caught_signals;
1207 act.sa_flags = SA_RESTART;
1209 for (j = 0; j < nsigs; j++)
1210 if (sigismember (&caught_signals, sig[j]))
1212 act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler;
1213 sigaction (sig[j], &act, NULL);
1215 #else
1216 for (j = 0; j < nsigs; j++)
1218 caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN);
1219 if (caught_sig[j])
1221 signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler);
1222 siginterrupt (sig[j], 0);
1225 #endif
1229 if (dereference == DEREF_UNDEFINED)
1230 dereference = ((immediate_dirs
1231 || indicator_style == classify
1232 || format == long_format)
1233 ? DEREF_NEVER
1234 : DEREF_COMMAND_LINE_SYMLINK_TO_DIR);
1236 /* When using -R, initialize a data structure we'll use to
1237 detect any directory cycles. */
1238 if (recursive)
1240 active_dir_set = hash_initialize (INITIAL_TABLE_SIZE, NULL,
1241 dev_ino_hash,
1242 dev_ino_compare,
1243 dev_ino_free);
1244 if (active_dir_set == NULL)
1245 xalloc_die ();
1247 obstack_init (&dev_ino_obstack);
1250 format_needs_stat = sort_type == sort_time || sort_type == sort_size
1251 || format == long_format
1252 || print_scontext
1253 || print_block_size;
1254 format_needs_type = (! format_needs_stat
1255 && (recursive
1256 || print_with_color
1257 || indicator_style != none
1258 || directories_first));
1260 if (dired)
1262 obstack_init (&dired_obstack);
1263 obstack_init (&subdired_obstack);
1266 cwd_n_alloc = 100;
1267 cwd_file = xnmalloc (cwd_n_alloc, sizeof *cwd_file);
1268 cwd_n_used = 0;
1270 clear_files ();
1272 n_files = argc - i;
1274 if (n_files <= 0)
1276 if (immediate_dirs)
1277 gobble_file (".", directory, NOT_AN_INODE_NUMBER, true, "");
1278 else
1279 queue_directory (".", NULL, true);
1281 else
1283 gobble_file (argv[i++], unknown, NOT_AN_INODE_NUMBER, true, "");
1284 while (i < argc);
1286 if (cwd_n_used)
1288 sort_files ();
1289 if (!immediate_dirs)
1290 extract_dirs_from_files (NULL, true);
1291 /* `cwd_n_used' might be zero now. */
1294 /* In the following if/else blocks, it is sufficient to test `pending_dirs'
1295 (and not pending_dirs->name) because there may be no markers in the queue
1296 at this point. A marker may be enqueued when extract_dirs_from_files is
1297 called with a non-empty string or via print_dir. */
1298 if (cwd_n_used)
1300 print_current_files ();
1301 if (pending_dirs)
1302 DIRED_PUTCHAR ('\n');
1304 else if (n_files <= 1 && pending_dirs && pending_dirs->next == 0)
1305 print_dir_name = false;
1307 while (pending_dirs)
1309 thispend = pending_dirs;
1310 pending_dirs = pending_dirs->next;
1312 if (LOOP_DETECT)
1314 if (thispend->name == NULL)
1316 /* thispend->name == NULL means this is a marker entry
1317 indicating we've finished processing the directory.
1318 Use its dev/ino numbers to remove the corresponding
1319 entry from the active_dir_set hash table. */
1320 struct dev_ino di = dev_ino_pop ();
1321 struct dev_ino *found = hash_delete (active_dir_set, &di);
1322 /* ASSERT_MATCHING_DEV_INO (thispend->realname, di); */
1323 assert (found);
1324 dev_ino_free (found);
1325 free_pending_ent (thispend);
1326 continue;
1330 print_dir (thispend->name, thispend->realname,
1331 thispend->command_line_arg);
1333 free_pending_ent (thispend);
1334 print_dir_name = true;
1337 if (print_with_color)
1339 int j;
1341 if (used_color)
1342 restore_default_color ();
1343 fflush (stdout);
1345 /* Restore the default signal handling. */
1346 #if SA_NOCLDSTOP
1347 for (j = 0; j < nsigs; j++)
1348 if (sigismember (&caught_signals, sig[j]))
1349 signal (sig[j], SIG_DFL);
1350 #else
1351 for (j = 0; j < nsigs; j++)
1352 if (caught_sig[j])
1353 signal (sig[j], SIG_DFL);
1354 #endif
1356 /* Act on any signals that arrived before the default was restored.
1357 This can process signals out of order, but there doesn't seem to
1358 be an easy way to do them in order, and the order isn't that
1359 important anyway. */
1360 for (j = stop_signal_count; j; j--)
1361 raise (SIGSTOP);
1362 j = interrupt_signal;
1363 if (j)
1364 raise (j);
1367 if (dired)
1369 /* No need to free these since we're about to exit. */
1370 dired_dump_obstack ("//DIRED//", &dired_obstack);
1371 dired_dump_obstack ("//SUBDIRED//", &subdired_obstack);
1372 printf ("//DIRED-OPTIONS// --quoting-style=%s\n",
1373 quoting_style_args[get_quoting_style (filename_quoting_options)]);
1376 if (LOOP_DETECT)
1378 assert (hash_get_n_entries (active_dir_set) == 0);
1379 hash_free (active_dir_set);
1382 exit (exit_status);
1385 /* Set all the option flags according to the switches specified.
1386 Return the index of the first non-option argument. */
1388 static int
1389 decode_switches (int argc, char **argv)
1391 char *time_style_option = NULL;
1393 /* Record whether there is an option specifying sort type. */
1394 bool sort_type_specified = false;
1396 qmark_funny_chars = false;
1398 /* initialize all switches to default settings */
1400 switch (ls_mode)
1402 case LS_MULTI_COL:
1403 /* This is for the `dir' program. */
1404 format = many_per_line;
1405 set_quoting_style (NULL, escape_quoting_style);
1406 break;
1408 case LS_LONG_FORMAT:
1409 /* This is for the `vdir' program. */
1410 format = long_format;
1411 set_quoting_style (NULL, escape_quoting_style);
1412 break;
1414 case LS_LS:
1415 /* This is for the `ls' program. */
1416 if (isatty (STDOUT_FILENO))
1418 format = many_per_line;
1419 /* See description of qmark_funny_chars, above. */
1420 qmark_funny_chars = true;
1422 else
1424 format = one_per_line;
1425 qmark_funny_chars = false;
1427 break;
1429 default:
1430 abort ();
1433 time_type = time_mtime;
1434 sort_type = sort_name;
1435 sort_reverse = false;
1436 numeric_ids = false;
1437 print_block_size = false;
1438 indicator_style = none;
1439 print_inode = false;
1440 dereference = DEREF_UNDEFINED;
1441 recursive = false;
1442 immediate_dirs = false;
1443 ignore_mode = IGNORE_DEFAULT;
1444 ignore_patterns = NULL;
1445 hide_patterns = NULL;
1446 print_scontext = false;
1448 /* FIXME: put this in a function. */
1450 char const *q_style = getenv ("QUOTING_STYLE");
1451 if (q_style)
1453 int i = ARGMATCH (q_style, quoting_style_args, quoting_style_vals);
1454 if (0 <= i)
1455 set_quoting_style (NULL, quoting_style_vals[i]);
1456 else
1457 error (0, 0,
1458 _("ignoring invalid value of environment variable QUOTING_STYLE: %s"),
1459 quotearg (q_style));
1464 char const *ls_block_size = getenv ("LS_BLOCK_SIZE");
1465 human_options (ls_block_size,
1466 &human_output_opts, &output_block_size);
1467 if (ls_block_size || getenv ("BLOCK_SIZE"))
1468 file_output_block_size = output_block_size;
1471 line_length = 80;
1473 char const *p = getenv ("COLUMNS");
1474 if (p && *p)
1476 unsigned long int tmp_ulong;
1477 if (xstrtoul (p, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK
1478 && 0 < tmp_ulong && tmp_ulong <= SIZE_MAX)
1480 line_length = tmp_ulong;
1482 else
1484 error (0, 0,
1485 _("ignoring invalid width in environment variable COLUMNS: %s"),
1486 quotearg (p));
1491 #ifdef TIOCGWINSZ
1493 struct winsize ws;
1495 if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1
1496 && 0 < ws.ws_col && ws.ws_col == (size_t) ws.ws_col)
1497 line_length = ws.ws_col;
1499 #endif
1502 char const *p = getenv ("TABSIZE");
1503 tabsize = 8;
1504 if (p)
1506 unsigned long int tmp_ulong;
1507 if (xstrtoul (p, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK
1508 && tmp_ulong <= SIZE_MAX)
1510 tabsize = tmp_ulong;
1512 else
1514 error (0, 0,
1515 _("ignoring invalid tab size in environment variable TABSIZE: %s"),
1516 quotearg (p));
1521 for (;;)
1523 int oi = -1;
1524 int c = getopt_long (argc, argv,
1525 "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1",
1526 long_options, &oi);
1527 if (c == -1)
1528 break;
1530 switch (c)
1532 case 'a':
1533 ignore_mode = IGNORE_MINIMAL;
1534 break;
1536 case 'b':
1537 set_quoting_style (NULL, escape_quoting_style);
1538 break;
1540 case 'c':
1541 time_type = time_ctime;
1542 break;
1544 case 'd':
1545 immediate_dirs = true;
1546 break;
1548 case 'f':
1549 /* Same as enabling -a -U and disabling -l -s. */
1550 ignore_mode = IGNORE_MINIMAL;
1551 sort_type = sort_none;
1552 sort_type_specified = true;
1553 /* disable -l */
1554 if (format == long_format)
1555 format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line);
1556 print_block_size = false; /* disable -s */
1557 print_with_color = false; /* disable --color */
1558 break;
1560 case FILE_TYPE_INDICATOR_OPTION: /* --file-type */
1561 indicator_style = file_type;
1562 break;
1564 case 'g':
1565 format = long_format;
1566 print_owner = false;
1567 break;
1569 case 'h':
1570 human_output_opts = human_autoscale | human_SI | human_base_1024;
1571 file_output_block_size = output_block_size = 1;
1572 break;
1574 case 'i':
1575 print_inode = true;
1576 break;
1578 case 'k':
1579 human_output_opts = 0;
1580 file_output_block_size = output_block_size = 1024;
1581 break;
1583 case 'l':
1584 format = long_format;
1585 break;
1587 case 'm':
1588 format = with_commas;
1589 break;
1591 case 'n':
1592 numeric_ids = true;
1593 format = long_format;
1594 break;
1596 case 'o': /* Just like -l, but don't display group info. */
1597 format = long_format;
1598 print_group = false;
1599 break;
1601 case 'p':
1602 indicator_style = slash;
1603 break;
1605 case 'q':
1606 qmark_funny_chars = true;
1607 break;
1609 case 'r':
1610 sort_reverse = true;
1611 break;
1613 case 's':
1614 print_block_size = true;
1615 break;
1617 case 't':
1618 sort_type = sort_time;
1619 sort_type_specified = true;
1620 break;
1622 case 'u':
1623 time_type = time_atime;
1624 break;
1626 case 'v':
1627 sort_type = sort_version;
1628 sort_type_specified = true;
1629 break;
1631 case 'w':
1633 unsigned long int tmp_ulong;
1634 if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK
1635 || ! (0 < tmp_ulong && tmp_ulong <= SIZE_MAX))
1636 error (LS_FAILURE, 0, _("invalid line width: %s"),
1637 quotearg (optarg));
1638 line_length = tmp_ulong;
1639 break;
1642 case 'x':
1643 format = horizontal;
1644 break;
1646 case 'A':
1647 if (ignore_mode == IGNORE_DEFAULT)
1648 ignore_mode = IGNORE_DOT_AND_DOTDOT;
1649 break;
1651 case 'B':
1652 add_ignore_pattern ("*~");
1653 add_ignore_pattern (".*~");
1654 break;
1656 case 'C':
1657 format = many_per_line;
1658 break;
1660 case 'D':
1661 dired = true;
1662 break;
1664 case 'F':
1665 indicator_style = classify;
1666 break;
1668 case 'G': /* inhibit display of group info */
1669 print_group = false;
1670 break;
1672 case 'H':
1673 dereference = DEREF_COMMAND_LINE_ARGUMENTS;
1674 break;
1676 case DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION:
1677 dereference = DEREF_COMMAND_LINE_SYMLINK_TO_DIR;
1678 break;
1680 case 'I':
1681 add_ignore_pattern (optarg);
1682 break;
1684 case 'L':
1685 dereference = DEREF_ALWAYS;
1686 break;
1688 case 'N':
1689 set_quoting_style (NULL, literal_quoting_style);
1690 break;
1692 case 'Q':
1693 set_quoting_style (NULL, c_quoting_style);
1694 break;
1696 case 'R':
1697 recursive = true;
1698 break;
1700 case 'S':
1701 sort_type = sort_size;
1702 sort_type_specified = true;
1703 break;
1705 case 'T':
1707 unsigned long int tmp_ulong;
1708 if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK
1709 || SIZE_MAX < tmp_ulong)
1710 error (LS_FAILURE, 0, _("invalid tab size: %s"),
1711 quotearg (optarg));
1712 tabsize = tmp_ulong;
1713 break;
1716 case 'U':
1717 sort_type = sort_none;
1718 sort_type_specified = true;
1719 break;
1721 case 'X':
1722 sort_type = sort_extension;
1723 sort_type_specified = true;
1724 break;
1726 case '1':
1727 /* -1 has no effect after -l. */
1728 if (format != long_format)
1729 format = one_per_line;
1730 break;
1732 case AUTHOR_OPTION:
1733 print_author = true;
1734 break;
1736 case HIDE_OPTION:
1738 struct ignore_pattern *hide = xmalloc (sizeof *hide);
1739 hide->pattern = optarg;
1740 hide->next = hide_patterns;
1741 hide_patterns = hide;
1743 break;
1745 case SORT_OPTION:
1746 sort_type = XARGMATCH ("--sort", optarg, sort_args, sort_types);
1747 sort_type_specified = true;
1748 break;
1750 case GROUP_DIRECTORIES_FIRST_OPTION:
1751 directories_first = true;
1752 break;
1754 case TIME_OPTION:
1755 time_type = XARGMATCH ("--time", optarg, time_args, time_types);
1756 break;
1758 case FORMAT_OPTION:
1759 format = XARGMATCH ("--format", optarg, format_args, format_types);
1760 break;
1762 case FULL_TIME_OPTION:
1763 format = long_format;
1764 time_style_option = "full-iso";
1765 break;
1767 case COLOR_OPTION:
1769 int i;
1770 if (optarg)
1771 i = XARGMATCH ("--color", optarg, color_args, color_types);
1772 else
1773 /* Using --color with no argument is equivalent to using
1774 --color=always. */
1775 i = color_always;
1777 print_with_color = (i == color_always
1778 || (i == color_if_tty
1779 && isatty (STDOUT_FILENO)));
1781 if (print_with_color)
1783 /* Don't use TAB characters in output. Some terminal
1784 emulators can't handle the combination of tabs and
1785 color codes on the same line. */
1786 tabsize = 0;
1788 break;
1791 case INDICATOR_STYLE_OPTION:
1792 indicator_style = XARGMATCH ("--indicator-style", optarg,
1793 indicator_style_args,
1794 indicator_style_types);
1795 break;
1797 case QUOTING_STYLE_OPTION:
1798 set_quoting_style (NULL,
1799 XARGMATCH ("--quoting-style", optarg,
1800 quoting_style_args,
1801 quoting_style_vals));
1802 break;
1804 case TIME_STYLE_OPTION:
1805 time_style_option = optarg;
1806 break;
1808 case SHOW_CONTROL_CHARS_OPTION:
1809 qmark_funny_chars = false;
1810 break;
1812 case BLOCK_SIZE_OPTION:
1814 enum strtol_error e = human_options (optarg, &human_output_opts,
1815 &output_block_size);
1816 if (e != LONGINT_OK)
1817 xstrtol_fatal (e, oi, 0, long_options, optarg);
1818 file_output_block_size = output_block_size;
1820 break;
1822 case SI_OPTION:
1823 human_output_opts = human_autoscale | human_SI;
1824 file_output_block_size = output_block_size = 1;
1825 break;
1827 case 'Z':
1828 print_scontext = true;
1829 break;
1831 case_GETOPT_HELP_CHAR;
1833 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1835 default:
1836 usage (LS_FAILURE);
1840 max_idx = MAX (1, line_length / MIN_COLUMN_WIDTH);
1842 filename_quoting_options = clone_quoting_options (NULL);
1843 if (get_quoting_style (filename_quoting_options) == escape_quoting_style)
1844 set_char_quoting (filename_quoting_options, ' ', 1);
1845 if (file_type <= indicator_style)
1847 char const *p;
1848 for (p = "*=>@|" + indicator_style - file_type; *p; p++)
1849 set_char_quoting (filename_quoting_options, *p, 1);
1852 dirname_quoting_options = clone_quoting_options (NULL);
1853 set_char_quoting (dirname_quoting_options, ':', 1);
1855 /* --dired is meaningful only with --format=long (-l).
1856 Otherwise, ignore it. FIXME: warn about this?
1857 Alternatively, make --dired imply --format=long? */
1858 if (dired && format != long_format)
1859 dired = false;
1861 /* If -c or -u is specified and not -l (or any other option that implies -l),
1862 and no sort-type was specified, then sort by the ctime (-c) or atime (-u).
1863 The behavior of ls when using either -c or -u but with neither -l nor -t
1864 appears to be unspecified by POSIX. So, with GNU ls, `-u' alone means
1865 sort by atime (this is the one that's not specified by the POSIX spec),
1866 -lu means show atime and sort by name, -lut means show atime and sort
1867 by atime. */
1869 if ((time_type == time_ctime || time_type == time_atime)
1870 && !sort_type_specified && format != long_format)
1872 sort_type = sort_time;
1875 if (format == long_format)
1877 char *style = time_style_option;
1878 static char const posix_prefix[] = "posix-";
1880 if (! style)
1881 if (! (style = getenv ("TIME_STYLE")))
1882 style = "locale";
1884 while (strncmp (style, posix_prefix, sizeof posix_prefix - 1) == 0)
1886 if (! hard_locale (LC_TIME))
1887 return optind;
1888 style += sizeof posix_prefix - 1;
1891 if (*style == '+')
1893 char *p0 = style + 1;
1894 char *p1 = strchr (p0, '\n');
1895 if (! p1)
1896 p1 = p0;
1897 else
1899 if (strchr (p1 + 1, '\n'))
1900 error (LS_FAILURE, 0, _("invalid time style format %s"),
1901 quote (p0));
1902 *p1++ = '\0';
1904 long_time_format[0] = p0;
1905 long_time_format[1] = p1;
1907 else
1908 switch (XARGMATCH ("time style", style,
1909 time_style_args,
1910 time_style_types))
1912 case full_iso_time_style:
1913 long_time_format[0] = long_time_format[1] =
1914 "%Y-%m-%d %H:%M:%S.%N %z";
1915 break;
1917 case long_iso_time_style:
1918 case_long_iso_time_style:
1919 long_time_format[0] = long_time_format[1] = "%Y-%m-%d %H:%M";
1920 break;
1922 case iso_time_style:
1923 long_time_format[0] = "%Y-%m-%d ";
1924 long_time_format[1] = "%m-%d %H:%M";
1925 break;
1927 case locale_time_style:
1928 if (hard_locale (LC_TIME))
1930 /* Ensure that the locale has translations for both
1931 formats. If not, fall back on long-iso format. */
1932 int i;
1933 for (i = 0; i < 2; i++)
1935 char const *locale_format =
1936 dcgettext (NULL, long_time_format[i], LC_TIME);
1937 if (locale_format == long_time_format[i])
1938 goto case_long_iso_time_style;
1939 long_time_format[i] = locale_format;
1945 return optind;
1948 /* Parse a string as part of the LS_COLORS variable; this may involve
1949 decoding all kinds of escape characters. If equals_end is set an
1950 unescaped equal sign ends the string, otherwise only a : or \0
1951 does. Set *OUTPUT_COUNT to the number of bytes output. Return
1952 true if successful.
1954 The resulting string is *not* null-terminated, but may contain
1955 embedded nulls.
1957 Note that both dest and src are char **; on return they point to
1958 the first free byte after the array and the character that ended
1959 the input string, respectively. */
1961 static bool
1962 get_funky_string (char **dest, const char **src, bool equals_end,
1963 size_t *output_count)
1965 char num; /* For numerical codes */
1966 size_t count; /* Something to count with */
1967 enum {
1968 ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR
1969 } state;
1970 const char *p;
1971 char *q;
1973 p = *src; /* We don't want to double-indirect */
1974 q = *dest; /* the whole darn time. */
1976 count = 0; /* No characters counted in yet. */
1977 num = 0;
1979 state = ST_GND; /* Start in ground state. */
1980 while (state < ST_END)
1982 switch (state)
1984 case ST_GND: /* Ground state (no escapes) */
1985 switch (*p)
1987 case ':':
1988 case '\0':
1989 state = ST_END; /* End of string */
1990 break;
1991 case '\\':
1992 state = ST_BACKSLASH; /* Backslash scape sequence */
1993 ++p;
1994 break;
1995 case '^':
1996 state = ST_CARET; /* Caret escape */
1997 ++p;
1998 break;
1999 case '=':
2000 if (equals_end)
2002 state = ST_END; /* End */
2003 break;
2005 /* else fall through */
2006 default:
2007 *(q++) = *(p++);
2008 ++count;
2009 break;
2011 break;
2013 case ST_BACKSLASH: /* Backslash escaped character */
2014 switch (*p)
2016 case '0':
2017 case '1':
2018 case '2':
2019 case '3':
2020 case '4':
2021 case '5':
2022 case '6':
2023 case '7':
2024 state = ST_OCTAL; /* Octal sequence */
2025 num = *p - '0';
2026 break;
2027 case 'x':
2028 case 'X':
2029 state = ST_HEX; /* Hex sequence */
2030 num = 0;
2031 break;
2032 case 'a': /* Bell */
2033 num = '\a';
2034 break;
2035 case 'b': /* Backspace */
2036 num = '\b';
2037 break;
2038 case 'e': /* Escape */
2039 num = 27;
2040 break;
2041 case 'f': /* Form feed */
2042 num = '\f';
2043 break;
2044 case 'n': /* Newline */
2045 num = '\n';
2046 break;
2047 case 'r': /* Carriage return */
2048 num = '\r';
2049 break;
2050 case 't': /* Tab */
2051 num = '\t';
2052 break;
2053 case 'v': /* Vtab */
2054 num = '\v';
2055 break;
2056 case '?': /* Delete */
2057 num = 127;
2058 break;
2059 case '_': /* Space */
2060 num = ' ';
2061 break;
2062 case '\0': /* End of string */
2063 state = ST_ERROR; /* Error! */
2064 break;
2065 default: /* Escaped character like \ ^ : = */
2066 num = *p;
2067 break;
2069 if (state == ST_BACKSLASH)
2071 *(q++) = num;
2072 ++count;
2073 state = ST_GND;
2075 ++p;
2076 break;
2078 case ST_OCTAL: /* Octal sequence */
2079 if (*p < '0' || *p > '7')
2081 *(q++) = num;
2082 ++count;
2083 state = ST_GND;
2085 else
2086 num = (num << 3) + (*(p++) - '0');
2087 break;
2089 case ST_HEX: /* Hex sequence */
2090 switch (*p)
2092 case '0':
2093 case '1':
2094 case '2':
2095 case '3':
2096 case '4':
2097 case '5':
2098 case '6':
2099 case '7':
2100 case '8':
2101 case '9':
2102 num = (num << 4) + (*(p++) - '0');
2103 break;
2104 case 'a':
2105 case 'b':
2106 case 'c':
2107 case 'd':
2108 case 'e':
2109 case 'f':
2110 num = (num << 4) + (*(p++) - 'a') + 10;
2111 break;
2112 case 'A':
2113 case 'B':
2114 case 'C':
2115 case 'D':
2116 case 'E':
2117 case 'F':
2118 num = (num << 4) + (*(p++) - 'A') + 10;
2119 break;
2120 default:
2121 *(q++) = num;
2122 ++count;
2123 state = ST_GND;
2124 break;
2126 break;
2128 case ST_CARET: /* Caret escape */
2129 state = ST_GND; /* Should be the next state... */
2130 if (*p >= '@' && *p <= '~')
2132 *(q++) = *(p++) & 037;
2133 ++count;
2135 else if (*p == '?')
2137 *(q++) = 127;
2138 ++count;
2140 else
2141 state = ST_ERROR;
2142 break;
2144 default:
2145 abort ();
2149 *dest = q;
2150 *src = p;
2151 *output_count = count;
2153 return state != ST_ERROR;
2156 static void
2157 parse_ls_color (void)
2159 const char *p; /* Pointer to character being parsed */
2160 char *buf; /* color_buf buffer pointer */
2161 int state; /* State of parser */
2162 int ind_no; /* Indicator number */
2163 char label[3]; /* Indicator label */
2164 struct color_ext_type *ext; /* Extension we are working on */
2166 if ((p = getenv ("LS_COLORS")) == NULL || *p == '\0')
2167 return;
2169 ext = NULL;
2170 strcpy (label, "??");
2172 /* This is an overly conservative estimate, but any possible
2173 LS_COLORS string will *not* generate a color_buf longer than
2174 itself, so it is a safe way of allocating a buffer in
2175 advance. */
2176 buf = color_buf = xstrdup (p);
2178 state = 1;
2179 while (state > 0)
2181 switch (state)
2183 case 1: /* First label character */
2184 switch (*p)
2186 case ':':
2187 ++p;
2188 break;
2190 case '*':
2191 /* Allocate new extension block and add to head of
2192 linked list (this way a later definition will
2193 override an earlier one, which can be useful for
2194 having terminal-specific defs override global). */
2196 ext = xmalloc (sizeof *ext);
2197 ext->next = color_ext_list;
2198 color_ext_list = ext;
2200 ++p;
2201 ext->ext.string = buf;
2203 state = (get_funky_string (&buf, &p, true, &ext->ext.len)
2204 ? 4 : -1);
2205 break;
2207 case '\0':
2208 state = 0; /* Done! */
2209 break;
2211 default: /* Assume it is file type label */
2212 label[0] = *(p++);
2213 state = 2;
2214 break;
2216 break;
2218 case 2: /* Second label character */
2219 if (*p)
2221 label[1] = *(p++);
2222 state = 3;
2224 else
2225 state = -1; /* Error */
2226 break;
2228 case 3: /* Equal sign after indicator label */
2229 state = -1; /* Assume failure... */
2230 if (*(p++) == '=')/* It *should* be... */
2232 for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no)
2234 if (STREQ (label, indicator_name[ind_no]))
2236 color_indicator[ind_no].string = buf;
2237 state = (get_funky_string (&buf, &p, false,
2238 &color_indicator[ind_no].len)
2239 ? 1 : -1);
2240 break;
2243 if (state == -1)
2244 error (0, 0, _("unrecognized prefix: %s"), quotearg (label));
2246 break;
2248 case 4: /* Equal sign after *.ext */
2249 if (*(p++) == '=')
2251 ext->seq.string = buf;
2252 state = (get_funky_string (&buf, &p, false, &ext->seq.len)
2253 ? 1 : -1);
2255 else
2256 state = -1;
2257 break;
2261 if (state < 0)
2263 struct color_ext_type *e;
2264 struct color_ext_type *e2;
2266 error (0, 0,
2267 _("unparsable value for LS_COLORS environment variable"));
2268 free (color_buf);
2269 for (e = color_ext_list; e != NULL; /* empty */)
2271 e2 = e;
2272 e = e->next;
2273 free (e2);
2275 print_with_color = false;
2278 if (color_indicator[C_LINK].len == 6
2279 && !strncmp (color_indicator[C_LINK].string, "target", 6))
2280 color_symlink_as_referent = true;
2283 /* Set the exit status to report a failure. If SERIOUS, it is a
2284 serious failure; otherwise, it is merely a minor problem. */
2286 static void
2287 set_exit_status (bool serious)
2289 if (serious)
2290 exit_status = LS_FAILURE;
2291 else if (exit_status == EXIT_SUCCESS)
2292 exit_status = LS_MINOR_PROBLEM;
2295 /* Assuming a failure is serious if SERIOUS, use the printf-style
2296 MESSAGE to report the failure to access a file named FILE. Assume
2297 errno is set appropriately for the failure. */
2299 static void
2300 file_failure (bool serious, char const *message, char const *file)
2302 error (0, errno, message, quotearg_colon (file));
2303 set_exit_status (serious);
2306 /* Request that the directory named NAME have its contents listed later.
2307 If REALNAME is nonzero, it will be used instead of NAME when the
2308 directory name is printed. This allows symbolic links to directories
2309 to be treated as regular directories but still be listed under their
2310 real names. NAME == NULL is used to insert a marker entry for the
2311 directory named in REALNAME.
2312 If NAME is non-NULL, we use its dev/ino information to save
2313 a call to stat -- when doing a recursive (-R) traversal.
2314 COMMAND_LINE_ARG means this directory was mentioned on the command line. */
2316 static void
2317 queue_directory (char const *name, char const *realname, bool command_line_arg)
2319 struct pending *new = xmalloc (sizeof *new);
2320 new->realname = realname ? xstrdup (realname) : NULL;
2321 new->name = name ? xstrdup (name) : NULL;
2322 new->command_line_arg = command_line_arg;
2323 new->next = pending_dirs;
2324 pending_dirs = new;
2327 /* Read directory NAME, and list the files in it.
2328 If REALNAME is nonzero, print its name instead of NAME;
2329 this is used for symbolic links to directories.
2330 COMMAND_LINE_ARG means this directory was mentioned on the command line. */
2332 static void
2333 print_dir (char const *name, char const *realname, bool command_line_arg)
2335 DIR *dirp;
2336 struct dirent *next;
2337 uintmax_t total_blocks = 0;
2338 static bool first = true;
2340 errno = 0;
2341 dirp = opendir (name);
2342 if (!dirp)
2344 file_failure (command_line_arg, _("cannot open directory %s"), name);
2345 return;
2348 if (LOOP_DETECT)
2350 struct stat dir_stat;
2351 int fd = dirfd (dirp);
2353 /* If dirfd failed, endure the overhead of using stat. */
2354 if ((0 <= fd
2355 ? fstat (fd, &dir_stat)
2356 : stat (name, &dir_stat)) < 0)
2358 file_failure (command_line_arg,
2359 _("cannot determine device and inode of %s"), name);
2360 closedir (dirp);
2361 return;
2364 /* If we've already visited this dev/inode pair, warn that
2365 we've found a loop, and do not process this directory. */
2366 if (visit_dir (dir_stat.st_dev, dir_stat.st_ino))
2368 error (0, 0, _("%s: not listing already-listed directory"),
2369 quotearg_colon (name));
2370 closedir (dirp);
2371 return;
2374 DEV_INO_PUSH (dir_stat.st_dev, dir_stat.st_ino);
2377 /* Read the directory entries, and insert the subfiles into the `cwd_file'
2378 table. */
2380 clear_files ();
2382 while (1)
2384 /* Set errno to zero so we can distinguish between a readdir failure
2385 and when readdir simply finds that there are no more entries. */
2386 errno = 0;
2387 next = readdir (dirp);
2388 if (next)
2390 if (! file_ignored (next->d_name))
2392 enum filetype type = unknown;
2394 #if HAVE_STRUCT_DIRENT_D_TYPE
2395 switch (next->d_type)
2397 case DT_BLK: type = blockdev; break;
2398 case DT_CHR: type = chardev; break;
2399 case DT_DIR: type = directory; break;
2400 case DT_FIFO: type = fifo; break;
2401 case DT_LNK: type = symbolic_link; break;
2402 case DT_REG: type = normal; break;
2403 case DT_SOCK: type = sock; break;
2404 # ifdef DT_WHT
2405 case DT_WHT: type = whiteout; break;
2406 # endif
2408 #endif
2409 total_blocks += gobble_file (next->d_name, type, D_INO (next),
2410 false, name);
2412 /* In this narrow case, print out each name right away, so
2413 ls uses constant memory while processing the entries of
2414 this directory. Useful when there are many (millions)
2415 of entries in a directory. */
2416 if (format == one_per_line && sort_type == sort_none)
2418 /* We must call sort_files in spite of
2419 "sort_type == sort_none" for its initialization
2420 of the sorted_file vector. */
2421 sort_files ();
2422 print_current_files ();
2423 clear_files ();
2427 else if (errno != 0)
2429 file_failure (command_line_arg, _("reading directory %s"), name);
2430 if (errno != EOVERFLOW)
2431 break;
2433 else
2434 break;
2437 if (closedir (dirp) != 0)
2439 file_failure (command_line_arg, _("closing directory %s"), name);
2440 /* Don't return; print whatever we got. */
2443 /* Sort the directory contents. */
2444 sort_files ();
2446 /* If any member files are subdirectories, perhaps they should have their
2447 contents listed rather than being mentioned here as files. */
2449 if (recursive)
2450 extract_dirs_from_files (name, command_line_arg);
2452 if (recursive | print_dir_name)
2454 if (!first)
2455 DIRED_PUTCHAR ('\n');
2456 first = false;
2457 DIRED_INDENT ();
2458 PUSH_CURRENT_DIRED_POS (&subdired_obstack);
2459 dired_pos += quote_name (stdout, realname ? realname : name,
2460 dirname_quoting_options, NULL);
2461 PUSH_CURRENT_DIRED_POS (&subdired_obstack);
2462 DIRED_FPUTS_LITERAL (":\n", stdout);
2465 if (format == long_format || print_block_size)
2467 const char *p;
2468 char buf[LONGEST_HUMAN_READABLE + 1];
2470 DIRED_INDENT ();
2471 p = _("total");
2472 DIRED_FPUTS (p, stdout, strlen (p));
2473 DIRED_PUTCHAR (' ');
2474 p = human_readable (total_blocks, buf, human_output_opts,
2475 ST_NBLOCKSIZE, output_block_size);
2476 DIRED_FPUTS (p, stdout, strlen (p));
2477 DIRED_PUTCHAR ('\n');
2480 if (cwd_n_used)
2481 print_current_files ();
2484 /* Add `pattern' to the list of patterns for which files that match are
2485 not listed. */
2487 static void
2488 add_ignore_pattern (const char *pattern)
2490 struct ignore_pattern *ignore;
2492 ignore = xmalloc (sizeof *ignore);
2493 ignore->pattern = pattern;
2494 /* Add it to the head of the linked list. */
2495 ignore->next = ignore_patterns;
2496 ignore_patterns = ignore;
2499 /* Return true if one of the PATTERNS matches FILE. */
2501 static bool
2502 patterns_match (struct ignore_pattern const *patterns, char const *file)
2504 struct ignore_pattern const *p;
2505 for (p = patterns; p; p = p->next)
2506 if (fnmatch (p->pattern, file, FNM_PERIOD) == 0)
2507 return true;
2508 return false;
2511 /* Return true if FILE should be ignored. */
2513 static bool
2514 file_ignored (char const *name)
2516 return ((ignore_mode != IGNORE_MINIMAL
2517 && name[0] == '.'
2518 && (ignore_mode == IGNORE_DEFAULT || ! name[1 + (name[1] == '.')]))
2519 || (ignore_mode == IGNORE_DEFAULT
2520 && patterns_match (hide_patterns, name))
2521 || patterns_match (ignore_patterns, name));
2524 /* POSIX requires that a file size be printed without a sign, even
2525 when negative. Assume the typical case where negative sizes are
2526 actually positive values that have wrapped around. */
2528 static uintmax_t
2529 unsigned_file_size (off_t size)
2531 return size + (size < 0) * ((uintmax_t) OFF_T_MAX - OFF_T_MIN + 1);
2534 /* Enter and remove entries in the table `cwd_file'. */
2536 /* Empty the table of files. */
2538 static void
2539 clear_files (void)
2541 size_t i;
2543 for (i = 0; i < cwd_n_used; i++)
2545 struct fileinfo *f = sorted_file[i];
2546 free (f->name);
2547 free (f->linkname);
2548 if (f->scontext != UNKNOWN_SECURITY_CONTEXT)
2549 freecon (f->scontext);
2552 cwd_n_used = 0;
2553 any_has_acl = false;
2554 inode_number_width = 0;
2555 block_size_width = 0;
2556 nlink_width = 0;
2557 owner_width = 0;
2558 group_width = 0;
2559 author_width = 0;
2560 scontext_width = 0;
2561 major_device_number_width = 0;
2562 minor_device_number_width = 0;
2563 file_size_width = 0;
2566 /* Add a file to the current table of files.
2567 Verify that the file exists, and print an error message if it does not.
2568 Return the number of blocks that the file occupies. */
2570 static uintmax_t
2571 gobble_file (char const *name, enum filetype type, ino_t inode,
2572 bool command_line_arg, char const *dirname)
2574 uintmax_t blocks = 0;
2575 struct fileinfo *f;
2577 /* An inode value prior to gobble_file necessarily came from readdir,
2578 which is not used for command line arguments. */
2579 assert (! command_line_arg || inode == NOT_AN_INODE_NUMBER);
2581 if (cwd_n_used == cwd_n_alloc)
2583 cwd_file = xnrealloc (cwd_file, cwd_n_alloc, 2 * sizeof *cwd_file);
2584 cwd_n_alloc *= 2;
2587 f = &cwd_file[cwd_n_used];
2588 memset (f, '\0', sizeof *f);
2589 f->stat.st_ino = inode;
2590 f->filetype = type;
2592 if (command_line_arg
2593 || format_needs_stat
2594 /* When coloring a directory (we may know the type from
2595 direct.d_type), we have to stat it in order to indicate
2596 sticky and/or other-writable attributes. */
2597 || (type == directory && print_with_color)
2598 /* When dereferencing symlinks, the inode and type must come from
2599 stat, but readdir provides the inode and type of lstat. */
2600 || ((print_inode || format_needs_type)
2601 && (type == symbolic_link || type == unknown)
2602 && (dereference == DEREF_ALWAYS
2603 || (command_line_arg && dereference != DEREF_NEVER)
2604 || color_symlink_as_referent || check_symlink_color))
2605 /* Command line dereferences are already taken care of by the above
2606 assertion that the inode number is not yet known. */
2607 || (print_inode && inode == NOT_AN_INODE_NUMBER)
2608 || (format_needs_type
2609 && (type == unknown || command_line_arg
2610 /* --indicator-style=classify (aka -F)
2611 requires that we stat each regular file
2612 to see if it's executable. */
2613 || (type == normal && (indicator_style == classify
2614 /* This is so that --color ends up
2615 highlighting files with the executable
2616 bit set even when options like -F are
2617 not specified. */
2618 || (print_with_color
2619 && is_colored (C_EXEC))
2620 )))))
2623 /* Absolute name of this file. */
2624 char *absolute_name;
2625 bool do_deref;
2626 int err;
2628 if (name[0] == '/' || dirname[0] == 0)
2629 absolute_name = (char *) name;
2630 else
2632 absolute_name = alloca (strlen (name) + strlen (dirname) + 2);
2633 attach (absolute_name, dirname, name);
2636 switch (dereference)
2638 case DEREF_ALWAYS:
2639 err = stat (absolute_name, &f->stat);
2640 do_deref = true;
2641 break;
2643 case DEREF_COMMAND_LINE_ARGUMENTS:
2644 case DEREF_COMMAND_LINE_SYMLINK_TO_DIR:
2645 if (command_line_arg)
2647 bool need_lstat;
2648 err = stat (absolute_name, &f->stat);
2649 do_deref = true;
2651 if (dereference == DEREF_COMMAND_LINE_ARGUMENTS)
2652 break;
2654 need_lstat = (err < 0
2655 ? errno == ENOENT
2656 : ! S_ISDIR (f->stat.st_mode));
2657 if (!need_lstat)
2658 break;
2660 /* stat failed because of ENOENT, maybe indicating a dangling
2661 symlink. Or stat succeeded, ABSOLUTE_NAME does not refer to a
2662 directory, and --dereference-command-line-symlink-to-dir is
2663 in effect. Fall through so that we call lstat instead. */
2666 default: /* DEREF_NEVER */
2667 err = lstat (absolute_name, &f->stat);
2668 do_deref = false;
2669 break;
2672 if (err != 0)
2674 /* Failure to stat a command line argument leads to
2675 an exit status of 2. For other files, stat failure
2676 provokes an exit status of 1. */
2677 file_failure (command_line_arg,
2678 _("cannot access %s"), absolute_name);
2679 if (command_line_arg)
2680 return 0;
2682 f->name = xstrdup (name);
2683 cwd_n_used++;
2685 return 0;
2688 f->stat_ok = true;
2690 if (format == long_format || print_scontext)
2692 bool have_acl = false;
2693 int attr_len = (do_deref
2694 ? getfilecon (absolute_name, &f->scontext)
2695 : lgetfilecon (absolute_name, &f->scontext));
2696 err = (attr_len < 0);
2698 /* Contrary to its documented API, getfilecon may return 0,
2699 yet set f->scontext to NULL (on at least Debian's libselinux1
2700 2.0.15-2+b1), so work around that bug.
2701 FIXME: remove this work-around in 2011, or whenever affected
2702 versions of libselinux are long gone. */
2703 if (attr_len == 0)
2705 err = 0;
2706 f->scontext = xstrdup ("unlabeled");
2709 if (err == 0)
2710 have_acl = ! STREQ ("unlabeled", f->scontext);
2711 else
2713 f->scontext = UNKNOWN_SECURITY_CONTEXT;
2715 /* When requesting security context information, don't make
2716 ls fail just because the file (even a command line argument)
2717 isn't on the right type of file system. I.e., a getfilecon
2718 failure isn't in the same class as a stat failure. */
2719 if (errno == ENOTSUP || errno == EOPNOTSUPP || errno == ENODATA)
2720 err = 0;
2723 if (err == 0 && ! have_acl && format == long_format)
2725 int n = file_has_acl (absolute_name, &f->stat);
2726 err = (n < 0);
2727 have_acl = (0 < n);
2730 f->have_acl = have_acl;
2731 any_has_acl |= have_acl;
2733 if (err)
2734 error (0, errno, "%s", quotearg_colon (absolute_name));
2737 if (S_ISLNK (f->stat.st_mode)
2738 && (format == long_format || check_symlink_color))
2740 char *linkname;
2741 struct stat linkstats;
2743 get_link_name (absolute_name, f, command_line_arg);
2744 linkname = make_link_name (absolute_name, f->linkname);
2746 /* Avoid following symbolic links when possible, ie, when
2747 they won't be traced and when no indicator is needed. */
2748 if (linkname
2749 && (file_type <= indicator_style || check_symlink_color)
2750 && stat (linkname, &linkstats) == 0)
2752 f->linkok = true;
2754 /* Symbolic links to directories that are mentioned on the
2755 command line are automatically traced if not being
2756 listed as files. */
2757 if (!command_line_arg || format == long_format
2758 || !S_ISDIR (linkstats.st_mode))
2760 /* Get the linked-to file's mode for the filetype indicator
2761 in long listings. */
2762 f->linkmode = linkstats.st_mode;
2765 free (linkname);
2768 /* When not distinguishing types of symlinks, pretend we know that
2769 it is stat'able, so that it will be colored as a regular symlink,
2770 and not as an orphan. */
2771 if (S_ISLNK (f->stat.st_mode) && !check_symlink_color)
2772 f->linkok = true;
2774 if (S_ISLNK (f->stat.st_mode))
2775 f->filetype = symbolic_link;
2776 else if (S_ISDIR (f->stat.st_mode))
2778 if (command_line_arg & !immediate_dirs)
2779 f->filetype = arg_directory;
2780 else
2781 f->filetype = directory;
2783 else
2784 f->filetype = normal;
2786 blocks = ST_NBLOCKS (f->stat);
2787 if (format == long_format || print_block_size)
2789 char buf[LONGEST_HUMAN_READABLE + 1];
2790 int len = mbswidth (human_readable (blocks, buf, human_output_opts,
2791 ST_NBLOCKSIZE, output_block_size),
2793 if (block_size_width < len)
2794 block_size_width = len;
2797 if (format == long_format)
2799 if (print_owner)
2801 int len = format_user_width (f->stat.st_uid);
2802 if (owner_width < len)
2803 owner_width = len;
2806 if (print_group)
2808 int len = format_group_width (f->stat.st_gid);
2809 if (group_width < len)
2810 group_width = len;
2813 if (print_author)
2815 int len = format_user_width (f->stat.st_author);
2816 if (author_width < len)
2817 author_width = len;
2821 if (print_scontext)
2823 int len = strlen (f->scontext);
2824 if (scontext_width < len)
2825 scontext_width = len;
2828 if (format == long_format)
2830 char b[INT_BUFSIZE_BOUND (uintmax_t)];
2831 int b_len = strlen (umaxtostr (f->stat.st_nlink, b));
2832 if (nlink_width < b_len)
2833 nlink_width = b_len;
2835 if (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode))
2837 char buf[INT_BUFSIZE_BOUND (uintmax_t)];
2838 int len = strlen (umaxtostr (major (f->stat.st_rdev), buf));
2839 if (major_device_number_width < len)
2840 major_device_number_width = len;
2841 len = strlen (umaxtostr (minor (f->stat.st_rdev), buf));
2842 if (minor_device_number_width < len)
2843 minor_device_number_width = len;
2844 len = major_device_number_width + 2 + minor_device_number_width;
2845 if (file_size_width < len)
2846 file_size_width = len;
2848 else
2850 char buf[LONGEST_HUMAN_READABLE + 1];
2851 uintmax_t size = unsigned_file_size (f->stat.st_size);
2852 int len = mbswidth (human_readable (size, buf, human_output_opts,
2853 1, file_output_block_size),
2855 if (file_size_width < len)
2856 file_size_width = len;
2861 if (print_inode)
2863 char buf[INT_BUFSIZE_BOUND (uintmax_t)];
2864 int len = strlen (umaxtostr (f->stat.st_ino, buf));
2865 if (inode_number_width < len)
2866 inode_number_width = len;
2869 f->name = xstrdup (name);
2870 cwd_n_used++;
2872 return blocks;
2875 /* Return true if F refers to a directory. */
2876 static bool
2877 is_directory (const struct fileinfo *f)
2879 return f->filetype == directory || f->filetype == arg_directory;
2882 /* Put the name of the file that FILENAME is a symbolic link to
2883 into the LINKNAME field of `f'. COMMAND_LINE_ARG indicates whether
2884 FILENAME is a command-line argument. */
2886 static void
2887 get_link_name (char const *filename, struct fileinfo *f, bool command_line_arg)
2889 f->linkname = areadlink_with_size (filename, f->stat.st_size);
2890 if (f->linkname == NULL)
2891 file_failure (command_line_arg, _("cannot read symbolic link %s"),
2892 filename);
2895 /* If `linkname' is a relative name and `name' contains one or more
2896 leading directories, return `linkname' with those directories
2897 prepended; otherwise, return a copy of `linkname'.
2898 If `linkname' is zero, return zero. */
2900 static char *
2901 make_link_name (char const *name, char const *linkname)
2903 char *linkbuf;
2904 size_t bufsiz;
2906 if (!linkname)
2907 return NULL;
2909 if (*linkname == '/')
2910 return xstrdup (linkname);
2912 /* The link is to a relative name. Prepend any leading directory
2913 in `name' to the link name. */
2914 linkbuf = strrchr (name, '/');
2915 if (linkbuf == 0)
2916 return xstrdup (linkname);
2918 bufsiz = linkbuf - name + 1;
2919 linkbuf = xmalloc (bufsiz + strlen (linkname) + 1);
2920 strncpy (linkbuf, name, bufsiz);
2921 strcpy (linkbuf + bufsiz, linkname);
2922 return linkbuf;
2925 /* Return true if the last component of NAME is `.' or `..'
2926 This is so we don't try to recurse on `././././. ...' */
2928 static bool
2929 basename_is_dot_or_dotdot (const char *name)
2931 char const *base = last_component (name);
2932 return dot_or_dotdot (base);
2935 /* Remove any entries from CWD_FILE that are for directories,
2936 and queue them to be listed as directories instead.
2937 DIRNAME is the prefix to prepend to each dirname
2938 to make it correct relative to ls's working dir;
2939 if it is null, no prefix is needed and "." and ".." should not be ignored.
2940 If COMMAND_LINE_ARG is true, this directory was mentioned at the top level,
2941 This is desirable when processing directories recursively. */
2943 static void
2944 extract_dirs_from_files (char const *dirname, bool command_line_arg)
2946 size_t i;
2947 size_t j;
2948 bool ignore_dot_and_dot_dot = (dirname != NULL);
2950 if (dirname && LOOP_DETECT)
2952 /* Insert a marker entry first. When we dequeue this marker entry,
2953 we'll know that DIRNAME has been processed and may be removed
2954 from the set of active directories. */
2955 queue_directory (NULL, dirname, false);
2958 /* Queue the directories last one first, because queueing reverses the
2959 order. */
2960 for (i = cwd_n_used; i-- != 0; )
2962 struct fileinfo *f = sorted_file[i];
2964 if (is_directory (f)
2965 && (! ignore_dot_and_dot_dot
2966 || ! basename_is_dot_or_dotdot (f->name)))
2968 if (!dirname || f->name[0] == '/')
2969 queue_directory (f->name, f->linkname, command_line_arg);
2970 else
2972 char *name = file_name_concat (dirname, f->name, NULL);
2973 queue_directory (name, f->linkname, command_line_arg);
2974 free (name);
2976 if (f->filetype == arg_directory)
2977 free (f->name);
2981 /* Now delete the directories from the table, compacting all the remaining
2982 entries. */
2984 for (i = 0, j = 0; i < cwd_n_used; i++)
2986 struct fileinfo *f = sorted_file[i];
2987 sorted_file[j] = f;
2988 j += (f->filetype != arg_directory);
2990 cwd_n_used = j;
2993 /* Use strcoll to compare strings in this locale. If an error occurs,
2994 report an error and longjmp to failed_strcoll. */
2996 static jmp_buf failed_strcoll;
2998 static int
2999 xstrcoll (char const *a, char const *b)
3001 int diff;
3002 errno = 0;
3003 diff = strcoll (a, b);
3004 if (errno)
3006 error (0, errno, _("cannot compare file names %s and %s"),
3007 quote_n (0, a), quote_n (1, b));
3008 set_exit_status (false);
3009 longjmp (failed_strcoll, 1);
3011 return diff;
3014 /* Comparison routines for sorting the files. */
3016 typedef void const *V;
3017 typedef int (*qsortFunc)(V a, V b);
3019 /* Used below in DEFINE_SORT_FUNCTIONS for _df_ sort function variants.
3020 The do { ... } while(0) makes it possible to use the macro more like
3021 a statement, without violating C89 rules: */
3022 #define DIRFIRST_CHECK(a, b) \
3023 do \
3025 bool a_is_dir = is_directory ((struct fileinfo const *) a); \
3026 bool b_is_dir = is_directory ((struct fileinfo const *) b); \
3027 if (a_is_dir && !b_is_dir) \
3028 return -1; /* a goes before b */ \
3029 if (!a_is_dir && b_is_dir) \
3030 return 1; /* b goes before a */ \
3032 while (0)
3034 /* Define the 8 different sort function variants required for each sortkey.
3035 KEY_NAME is a token describing the sort key, e.g., ctime, atime, size.
3036 KEY_CMP_FUNC is a function to compare records based on that key, e.g.,
3037 ctime_cmp, atime_cmp, size_cmp. Append KEY_NAME to the string,
3038 '[rev_][x]str{cmp|coll}[_df]_', to create each function name. */
3039 #define DEFINE_SORT_FUNCTIONS(key_name, key_cmp_func) \
3040 /* direct, non-dirfirst versions */ \
3041 static int xstrcoll_##key_name (V a, V b) \
3042 { return key_cmp_func (a, b, xstrcoll); } \
3043 static int strcmp_##key_name (V a, V b) \
3044 { return key_cmp_func (a, b, strcmp); } \
3046 /* reverse, non-dirfirst versions */ \
3047 static int rev_xstrcoll_##key_name (V a, V b) \
3048 { return key_cmp_func (b, a, xstrcoll); } \
3049 static int rev_strcmp_##key_name (V a, V b) \
3050 { return key_cmp_func (b, a, strcmp); } \
3052 /* direct, dirfirst versions */ \
3053 static int xstrcoll_df_##key_name (V a, V b) \
3054 { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, xstrcoll); } \
3055 static int strcmp_df_##key_name (V a, V b) \
3056 { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, strcmp); } \
3058 /* reverse, dirfirst versions */ \
3059 static int rev_xstrcoll_df_##key_name (V a, V b) \
3060 { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, xstrcoll); } \
3061 static int rev_strcmp_df_##key_name (V a, V b) \
3062 { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, strcmp); }
3064 static inline int
3065 cmp_ctime (struct fileinfo const *a, struct fileinfo const *b,
3066 int (*cmp) (char const *, char const *))
3068 int diff = timespec_cmp (get_stat_ctime (&b->stat),
3069 get_stat_ctime (&a->stat));
3070 return diff ? diff : cmp (a->name, b->name);
3073 static inline int
3074 cmp_mtime (struct fileinfo const *a, struct fileinfo const *b,
3075 int (*cmp) (char const *, char const *))
3077 int diff = timespec_cmp (get_stat_mtime (&b->stat),
3078 get_stat_mtime (&a->stat));
3079 return diff ? diff : cmp (a->name, b->name);
3082 static inline int
3083 cmp_atime (struct fileinfo const *a, struct fileinfo const *b,
3084 int (*cmp) (char const *, char const *))
3086 int diff = timespec_cmp (get_stat_atime (&b->stat),
3087 get_stat_atime (&a->stat));
3088 return diff ? diff : cmp (a->name, b->name);
3091 static inline int
3092 cmp_size (struct fileinfo const *a, struct fileinfo const *b,
3093 int (*cmp) (char const *, char const *))
3095 int diff = longdiff (b->stat.st_size, a->stat.st_size);
3096 return diff ? diff : cmp (a->name, b->name);
3099 static inline int
3100 cmp_name (struct fileinfo const *a, struct fileinfo const *b,
3101 int (*cmp) (char const *, char const *))
3103 return cmp (a->name, b->name);
3106 /* Compare file extensions. Files with no extension are `smallest'.
3107 If extensions are the same, compare by filenames instead. */
3109 static inline int
3110 cmp_extension (struct fileinfo const *a, struct fileinfo const *b,
3111 int (*cmp) (char const *, char const *))
3113 char const *base1 = strrchr (a->name, '.');
3114 char const *base2 = strrchr (b->name, '.');
3115 int diff = cmp (base1 ? base1 : "", base2 ? base2 : "");
3116 return diff ? diff : cmp (a->name, b->name);
3119 DEFINE_SORT_FUNCTIONS (ctime, cmp_ctime)
3120 DEFINE_SORT_FUNCTIONS (mtime, cmp_mtime)
3121 DEFINE_SORT_FUNCTIONS (atime, cmp_atime)
3122 DEFINE_SORT_FUNCTIONS (size, cmp_size)
3123 DEFINE_SORT_FUNCTIONS (name, cmp_name)
3124 DEFINE_SORT_FUNCTIONS (extension, cmp_extension)
3126 /* Compare file versions.
3127 Unlike all other compare functions above, cmp_version depends only
3128 on filevercmp, which does not fail (even for locale reasons), and does not
3129 need a secondary sort key. See lib/filevercmp.h for function description.
3131 All the other sort options, in fact, need xstrcoll and strcmp variants,
3132 because they all use a string comparison (either as the primary or secondary
3133 sort key), and xstrcoll has the ability to do a longjmp if strcoll fails for
3134 locale reasons. Last, strverscmp is ALWAYS available in coreutils,
3135 thanks to the gnulib library. */
3136 static inline int
3137 cmp_version (struct fileinfo const *a, struct fileinfo const *b)
3139 return filevercmp (a->name, b->name);
3142 static int xstrcoll_version (V a, V b)
3143 { return cmp_version (a, b); }
3144 static int rev_xstrcoll_version (V a, V b)
3145 { return cmp_version (b, a); }
3146 static int xstrcoll_df_version (V a, V b)
3147 { DIRFIRST_CHECK (a, b); return cmp_version (a, b); }
3148 static int rev_xstrcoll_df_version (V a, V b)
3149 { DIRFIRST_CHECK (a, b); return cmp_version (b, a); }
3152 /* We have 2^3 different variants for each sortkey function
3153 (for 3 independent sort modes).
3154 The function pointers stored in this array must be dereferenced as:
3156 sort_variants[sort_key][use_strcmp][reverse][dirs_first]
3158 Note that the order in which sortkeys are listed in the function pointer
3159 array below is defined by the order of the elements in the time_type and
3160 sort_type enums! */
3162 #define LIST_SORTFUNCTION_VARIANTS(key_name) \
3165 { xstrcoll_##key_name, xstrcoll_df_##key_name }, \
3166 { rev_xstrcoll_##key_name, rev_xstrcoll_df_##key_name }, \
3167 }, \
3169 { strcmp_##key_name, strcmp_df_##key_name }, \
3170 { rev_strcmp_##key_name, rev_strcmp_df_##key_name }, \
3174 static qsortFunc const sort_functions[][2][2][2] =
3176 LIST_SORTFUNCTION_VARIANTS (name),
3177 LIST_SORTFUNCTION_VARIANTS (extension),
3178 LIST_SORTFUNCTION_VARIANTS (size),
3182 { xstrcoll_version, xstrcoll_df_version },
3183 { rev_xstrcoll_version, rev_xstrcoll_df_version },
3186 /* We use NULL for the strcmp variants of version comparison
3187 since as explained in cmp_version definition, version comparison
3188 does not rely on xstrcoll, so it will never longjmp, and never
3189 need to try the strcmp fallback. */
3191 { NULL, NULL },
3192 { NULL, NULL },
3196 /* last are time sort functions */
3197 LIST_SORTFUNCTION_VARIANTS (mtime),
3198 LIST_SORTFUNCTION_VARIANTS (ctime),
3199 LIST_SORTFUNCTION_VARIANTS (atime)
3202 /* The number of sortkeys is calculated as
3203 the number of elements in the sort_type enum (i.e. sort_numtypes) +
3204 the number of elements in the time_type enum (i.e. time_numtypes) - 1
3205 This is because when sort_type==sort_time, we have up to
3206 time_numtypes possible sortkeys.
3208 This line verifies at compile-time that the array of sort functions has been
3209 initialized for all possible sortkeys. */
3210 verify (ARRAY_CARDINALITY (sort_functions)
3211 == sort_numtypes + time_numtypes - 1 );
3213 /* Set up SORTED_FILE to point to the in-use entries in CWD_FILE, in order. */
3215 static void
3216 initialize_ordering_vector (void)
3218 size_t i;
3219 for (i = 0; i < cwd_n_used; i++)
3220 sorted_file[i] = &cwd_file[i];
3223 /* Sort the files now in the table. */
3225 static void
3226 sort_files (void)
3228 bool use_strcmp;
3230 if (sorted_file_alloc < cwd_n_used + cwd_n_used / 2)
3232 free (sorted_file);
3233 sorted_file = xnmalloc (cwd_n_used, 3 * sizeof *sorted_file);
3234 sorted_file_alloc = 3 * cwd_n_used;
3237 initialize_ordering_vector ();
3239 if (sort_type == sort_none)
3240 return;
3242 /* Try strcoll. If it fails, fall back on strcmp. We can't safely
3243 ignore strcoll failures, as a failing strcoll might be a
3244 comparison function that is not a total order, and if we ignored
3245 the failure this might cause qsort to dump core. */
3247 if (! setjmp (failed_strcoll))
3248 use_strcmp = false; /* strcoll() succeeded */
3249 else
3251 use_strcmp = true;
3252 assert (sort_type != sort_version);
3253 initialize_ordering_vector ();
3256 /* When sort_type == sort_time, use time_type as subindex. */
3257 mpsort ((void const **) sorted_file, cwd_n_used,
3258 sort_functions[sort_type + (sort_type == sort_time ? time_type : 0)]
3259 [use_strcmp][sort_reverse]
3260 [directories_first]);
3263 /* List all the files now in the table. */
3265 static void
3266 print_current_files (void)
3268 size_t i;
3270 switch (format)
3272 case one_per_line:
3273 for (i = 0; i < cwd_n_used; i++)
3275 print_file_name_and_frills (sorted_file[i]);
3276 putchar ('\n');
3278 break;
3280 case many_per_line:
3281 print_many_per_line ();
3282 break;
3284 case horizontal:
3285 print_horizontal ();
3286 break;
3288 case with_commas:
3289 print_with_commas ();
3290 break;
3292 case long_format:
3293 for (i = 0; i < cwd_n_used; i++)
3295 print_long_format (sorted_file[i]);
3296 DIRED_PUTCHAR ('\n');
3298 break;
3302 /* Return the expected number of columns in a long-format time stamp,
3303 or zero if it cannot be calculated. */
3305 static int
3306 long_time_expected_width (void)
3308 static int width = -1;
3310 if (width < 0)
3312 time_t epoch = 0;
3313 struct tm const *tm = localtime (&epoch);
3314 char buf[TIME_STAMP_LEN_MAXIMUM + 1];
3316 /* In case you're wondering if localtime can fail with an input time_t
3317 value of 0, let's just say it's very unlikely, but not inconceivable.
3318 The TZ environment variable would have to specify a time zone that
3319 is 2**31-1900 years or more ahead of UTC. This could happen only on
3320 a 64-bit system that blindly accepts e.g., TZ=UTC+20000000000000.
3321 However, this is not possible with Solaris 10 or glibc-2.3.5, since
3322 their implementations limit the offset to 167:59 and 24:00, resp. */
3323 if (tm)
3325 size_t len =
3326 nstrftime (buf, sizeof buf, long_time_format[0], tm, 0, 0);
3327 if (len != 0)
3328 width = mbsnwidth (buf, len, 0);
3331 if (width < 0)
3332 width = 0;
3335 return width;
3338 /* Print the user or group name NAME, with numeric id ID, using a
3339 print width of WIDTH columns. */
3341 static void
3342 format_user_or_group (char const *name, unsigned long int id, int width)
3344 size_t len;
3346 if (name)
3348 int width_gap = width - mbswidth (name, 0);
3349 int pad = MAX (0, width_gap);
3350 fputs (name, stdout);
3351 len = strlen (name) + pad;
3354 putchar (' ');
3355 while (pad--);
3357 else
3359 printf ("%*lu ", width, id);
3360 len = width;
3363 dired_pos += len + 1;
3366 /* Print the name or id of the user with id U, using a print width of
3367 WIDTH. */
3369 static void
3370 format_user (uid_t u, int width, bool stat_ok)
3372 format_user_or_group (! stat_ok ? "?" :
3373 (numeric_ids ? NULL : getuser (u)), u, width);
3376 /* Likewise, for groups. */
3378 static void
3379 format_group (gid_t g, int width, bool stat_ok)
3381 format_user_or_group (! stat_ok ? "?" :
3382 (numeric_ids ? NULL : getgroup (g)), g, width);
3385 /* Return the number of columns that format_user_or_group will print. */
3387 static int
3388 format_user_or_group_width (char const *name, unsigned long int id)
3390 if (name)
3392 int len = mbswidth (name, 0);
3393 return MAX (0, len);
3395 else
3397 char buf[INT_BUFSIZE_BOUND (unsigned long int)];
3398 sprintf (buf, "%lu", id);
3399 return strlen (buf);
3403 /* Return the number of columns that format_user will print. */
3405 static int
3406 format_user_width (uid_t u)
3408 return format_user_or_group_width (numeric_ids ? NULL : getuser (u), u);
3411 /* Likewise, for groups. */
3413 static int
3414 format_group_width (gid_t g)
3416 return format_user_or_group_width (numeric_ids ? NULL : getgroup (g), g);
3420 /* Print information about F in long format. */
3422 static void
3423 print_long_format (const struct fileinfo *f)
3425 char modebuf[12];
3426 char buf
3427 [LONGEST_HUMAN_READABLE + 1 /* inode */
3428 + LONGEST_HUMAN_READABLE + 1 /* size in blocks */
3429 + sizeof (modebuf) - 1 + 1 /* mode string */
3430 + INT_BUFSIZE_BOUND (uintmax_t) /* st_nlink */
3431 + LONGEST_HUMAN_READABLE + 2 /* major device number */
3432 + LONGEST_HUMAN_READABLE + 1 /* minor device number */
3433 + TIME_STAMP_LEN_MAXIMUM + 1 /* max length of time/date */
3435 size_t s;
3436 char *p;
3437 struct timespec when_timespec;
3438 struct tm *when_local;
3440 /* Compute the mode string, except remove the trailing space if no
3441 file in this directory has an ACL or SELinux security context. */
3442 if (f->stat_ok)
3443 filemodestring (&f->stat, modebuf);
3444 else
3446 modebuf[0] = filetype_letter[f->filetype];
3447 memset (modebuf + 1, '?', 10);
3448 modebuf[11] = '\0';
3450 if (! any_has_acl)
3451 modebuf[10] = '\0';
3452 else if (f->have_acl)
3453 modebuf[10] = '+';
3455 switch (time_type)
3457 case time_ctime:
3458 when_timespec = get_stat_ctime (&f->stat);
3459 break;
3460 case time_mtime:
3461 when_timespec = get_stat_mtime (&f->stat);
3462 break;
3463 case time_atime:
3464 when_timespec = get_stat_atime (&f->stat);
3465 break;
3466 default:
3467 abort ();
3470 p = buf;
3472 if (print_inode)
3474 char hbuf[INT_BUFSIZE_BOUND (uintmax_t)];
3475 sprintf (p, "%*s ", inode_number_width,
3476 (f->stat.st_ino == NOT_AN_INODE_NUMBER
3477 ? "?"
3478 : umaxtostr (f->stat.st_ino, hbuf)));
3479 /* Increment by strlen (p) here, rather than by inode_number_width + 1.
3480 The latter is wrong when inode_number_width is zero. */
3481 p += strlen (p);
3484 if (print_block_size)
3486 char hbuf[LONGEST_HUMAN_READABLE + 1];
3487 char const *blocks =
3488 (! f->stat_ok
3489 ? "?"
3490 : human_readable (ST_NBLOCKS (f->stat), hbuf, human_output_opts,
3491 ST_NBLOCKSIZE, output_block_size));
3492 int pad;
3493 for (pad = block_size_width - mbswidth (blocks, 0); 0 < pad; pad--)
3494 *p++ = ' ';
3495 while ((*p++ = *blocks++))
3496 continue;
3497 p[-1] = ' ';
3500 /* The last byte of the mode string is the POSIX
3501 "optional alternate access method flag". */
3503 char hbuf[INT_BUFSIZE_BOUND (uintmax_t)];
3504 sprintf (p, "%s %*s ", modebuf, nlink_width,
3505 ! f->stat_ok ? "?" : umaxtostr (f->stat.st_nlink, hbuf));
3507 /* Increment by strlen (p) here, rather than by, e.g.,
3508 sizeof modebuf - 2 + any_has_acl + 1 + nlink_width + 1.
3509 The latter is wrong when nlink_width is zero. */
3510 p += strlen (p);
3512 DIRED_INDENT ();
3514 if (print_owner | print_group | print_author | print_scontext)
3516 DIRED_FPUTS (buf, stdout, p - buf);
3518 if (print_owner)
3519 format_user (f->stat.st_uid, owner_width, f->stat_ok);
3521 if (print_group)
3522 format_group (f->stat.st_gid, group_width, f->stat_ok);
3524 if (print_author)
3525 format_user (f->stat.st_author, author_width, f->stat_ok);
3527 if (print_scontext)
3528 format_user_or_group (f->scontext, 0, scontext_width);
3530 p = buf;
3533 if (f->stat_ok
3534 && (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode)))
3536 char majorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
3537 char minorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
3538 int blanks_width = (file_size_width
3539 - (major_device_number_width + 2
3540 + minor_device_number_width));
3541 sprintf (p, "%*s, %*s ",
3542 major_device_number_width + MAX (0, blanks_width),
3543 umaxtostr (major (f->stat.st_rdev), majorbuf),
3544 minor_device_number_width,
3545 umaxtostr (minor (f->stat.st_rdev), minorbuf));
3546 p += file_size_width + 1;
3548 else
3550 char hbuf[LONGEST_HUMAN_READABLE + 1];
3551 char const *size =
3552 (! f->stat_ok
3553 ? "?"
3554 : human_readable (unsigned_file_size (f->stat.st_size),
3555 hbuf, human_output_opts, 1, file_output_block_size));
3556 int pad;
3557 for (pad = file_size_width - mbswidth (size, 0); 0 < pad; pad--)
3558 *p++ = ' ';
3559 while ((*p++ = *size++))
3560 continue;
3561 p[-1] = ' ';
3564 when_local = localtime (&when_timespec.tv_sec);
3565 s = 0;
3566 *p = '\1';
3568 if (f->stat_ok && when_local)
3570 struct timespec six_months_ago;
3571 bool recent;
3572 char const *fmt;
3574 /* If the file appears to be in the future, update the current
3575 time, in case the file happens to have been modified since
3576 the last time we checked the clock. */
3577 if (timespec_cmp (current_time, when_timespec) < 0)
3579 /* Note that gettime may call gettimeofday which, on some non-
3580 compliant systems, clobbers the buffer used for localtime's result.
3581 But it's ok here, because we use a gettimeofday wrapper that
3582 saves and restores the buffer around the gettimeofday call. */
3583 gettime (&current_time);
3586 /* Consider a time to be recent if it is within the past six
3587 months. A Gregorian year has 365.2425 * 24 * 60 * 60 ==
3588 31556952 seconds on the average. Write this value as an
3589 integer constant to avoid floating point hassles. */
3590 six_months_ago.tv_sec = current_time.tv_sec - 31556952 / 2;
3591 six_months_ago.tv_nsec = current_time.tv_nsec;
3593 recent = (timespec_cmp (six_months_ago, when_timespec) < 0
3594 && (timespec_cmp (when_timespec, current_time) < 0));
3595 fmt = long_time_format[recent];
3597 /* We assume here that all time zones are offset from UTC by a
3598 whole number of seconds. */
3599 s = nstrftime (p, TIME_STAMP_LEN_MAXIMUM + 1, fmt,
3600 when_local, 0, when_timespec.tv_nsec);
3603 if (s || !*p)
3605 p += s;
3606 *p++ = ' ';
3608 /* NUL-terminate the string -- fputs (via DIRED_FPUTS) requires it. */
3609 *p = '\0';
3611 else
3613 /* The time cannot be converted using the desired format, so
3614 print it as a huge integer number of seconds. */
3615 char hbuf[INT_BUFSIZE_BOUND (intmax_t)];
3616 sprintf (p, "%*s ", long_time_expected_width (),
3617 (! f->stat_ok
3618 ? "?"
3619 : timetostr (when_timespec.tv_sec, hbuf)));
3620 /* FIXME: (maybe) We discarded when_timespec.tv_nsec. */
3621 p += strlen (p);
3624 DIRED_FPUTS (buf, stdout, p - buf);
3625 print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok,
3626 f->stat_ok, f->filetype, &dired_obstack);
3628 if (f->filetype == symbolic_link)
3630 if (f->linkname)
3632 DIRED_FPUTS_LITERAL (" -> ", stdout);
3633 print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1,
3634 f->stat_ok, f->filetype, NULL);
3635 if (indicator_style != none)
3636 print_type_indicator (true, f->linkmode, unknown);
3639 else if (indicator_style != none)
3640 print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
3643 /* Output to OUT a quoted representation of the file name NAME,
3644 using OPTIONS to control quoting. Produce no output if OUT is NULL.
3645 Store the number of screen columns occupied by NAME's quoted
3646 representation into WIDTH, if non-NULL. Return the number of bytes
3647 produced. */
3649 static size_t
3650 quote_name (FILE *out, const char *name, struct quoting_options const *options,
3651 size_t *width)
3653 char smallbuf[BUFSIZ];
3654 size_t len = quotearg_buffer (smallbuf, sizeof smallbuf, name, -1, options);
3655 char *buf;
3656 size_t displayed_width IF_LINT (= 0);
3658 if (len < sizeof smallbuf)
3659 buf = smallbuf;
3660 else
3662 buf = alloca (len + 1);
3663 quotearg_buffer (buf, len + 1, name, -1, options);
3666 if (qmark_funny_chars)
3668 #if HAVE_MBRTOWC
3669 if (MB_CUR_MAX > 1)
3671 char const *p = buf;
3672 char const *plimit = buf + len;
3673 char *q = buf;
3674 displayed_width = 0;
3676 while (p < plimit)
3677 switch (*p)
3679 case ' ': case '!': case '"': case '#': case '%':
3680 case '&': case '\'': case '(': case ')': case '*':
3681 case '+': case ',': case '-': case '.': case '/':
3682 case '0': case '1': case '2': case '3': case '4':
3683 case '5': case '6': case '7': case '8': case '9':
3684 case ':': case ';': case '<': case '=': case '>':
3685 case '?':
3686 case 'A': case 'B': case 'C': case 'D': case 'E':
3687 case 'F': case 'G': case 'H': case 'I': case 'J':
3688 case 'K': case 'L': case 'M': case 'N': case 'O':
3689 case 'P': case 'Q': case 'R': case 'S': case 'T':
3690 case 'U': case 'V': case 'W': case 'X': case 'Y':
3691 case 'Z':
3692 case '[': case '\\': case ']': case '^': case '_':
3693 case 'a': case 'b': case 'c': case 'd': case 'e':
3694 case 'f': case 'g': case 'h': case 'i': case 'j':
3695 case 'k': case 'l': case 'm': case 'n': case 'o':
3696 case 'p': case 'q': case 'r': case 's': case 't':
3697 case 'u': case 'v': case 'w': case 'x': case 'y':
3698 case 'z': case '{': case '|': case '}': case '~':
3699 /* These characters are printable ASCII characters. */
3700 *q++ = *p++;
3701 displayed_width += 1;
3702 break;
3703 default:
3704 /* If we have a multibyte sequence, copy it until we
3705 reach its end, replacing each non-printable multibyte
3706 character with a single question mark. */
3708 mbstate_t mbstate = { 0, };
3711 wchar_t wc;
3712 size_t bytes;
3713 int w;
3715 bytes = mbrtowc (&wc, p, plimit - p, &mbstate);
3717 if (bytes == (size_t) -1)
3719 /* An invalid multibyte sequence was
3720 encountered. Skip one input byte, and
3721 put a question mark. */
3722 p++;
3723 *q++ = '?';
3724 displayed_width += 1;
3725 break;
3728 if (bytes == (size_t) -2)
3730 /* An incomplete multibyte character
3731 at the end. Replace it entirely with
3732 a question mark. */
3733 p = plimit;
3734 *q++ = '?';
3735 displayed_width += 1;
3736 break;
3739 if (bytes == 0)
3740 /* A null wide character was encountered. */
3741 bytes = 1;
3743 w = wcwidth (wc);
3744 if (w >= 0)
3746 /* A printable multibyte character.
3747 Keep it. */
3748 for (; bytes > 0; --bytes)
3749 *q++ = *p++;
3750 displayed_width += w;
3752 else
3754 /* An unprintable multibyte character.
3755 Replace it entirely with a question
3756 mark. */
3757 p += bytes;
3758 *q++ = '?';
3759 displayed_width += 1;
3762 while (! mbsinit (&mbstate));
3764 break;
3767 /* The buffer may have shrunk. */
3768 len = q - buf;
3770 else
3771 #endif
3773 char *p = buf;
3774 char const *plimit = buf + len;
3776 while (p < plimit)
3778 if (! isprint (to_uchar (*p)))
3779 *p = '?';
3780 p++;
3782 displayed_width = len;
3785 else if (width != NULL)
3787 #if HAVE_MBRTOWC
3788 if (MB_CUR_MAX > 1)
3789 displayed_width = mbsnwidth (buf, len, 0);
3790 else
3791 #endif
3793 char const *p = buf;
3794 char const *plimit = buf + len;
3796 displayed_width = 0;
3797 while (p < plimit)
3799 if (isprint (to_uchar (*p)))
3800 displayed_width++;
3801 p++;
3806 if (out != NULL)
3807 fwrite (buf, 1, len, out);
3808 if (width != NULL)
3809 *width = displayed_width;
3810 return len;
3813 static void
3814 print_name_with_quoting (const char *p, mode_t mode, int linkok,
3815 bool stat_ok, enum filetype type,
3816 struct obstack *stack)
3818 bool used_color_this_time
3819 = (print_with_color
3820 && print_color_indicator (p, mode, linkok, stat_ok, type));
3822 if (stack)
3823 PUSH_CURRENT_DIRED_POS (stack);
3825 dired_pos += quote_name (stdout, p, filename_quoting_options, NULL);
3827 if (stack)
3828 PUSH_CURRENT_DIRED_POS (stack);
3830 if (used_color_this_time)
3832 process_signals ();
3833 prep_non_filename_text ();
3837 static void
3838 prep_non_filename_text (void)
3840 if (color_indicator[C_END].string != NULL)
3841 put_indicator (&color_indicator[C_END]);
3842 else
3844 put_indicator (&color_indicator[C_LEFT]);
3845 put_indicator (&color_indicator[C_RESET]);
3846 put_indicator (&color_indicator[C_RIGHT]);
3850 /* Print the file name of `f' with appropriate quoting.
3851 Also print file size, inode number, and filetype indicator character,
3852 as requested by switches. */
3854 static void
3855 print_file_name_and_frills (const struct fileinfo *f)
3857 char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))];
3859 if (print_inode)
3860 printf ("%*s ", format == with_commas ? 0 : inode_number_width,
3861 umaxtostr (f->stat.st_ino, buf));
3863 if (print_block_size)
3864 printf ("%*s ", format == with_commas ? 0 : block_size_width,
3865 human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts,
3866 ST_NBLOCKSIZE, output_block_size));
3868 if (print_scontext)
3869 printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext);
3871 print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok,
3872 f->stat_ok, f->filetype, NULL);
3874 if (indicator_style != none)
3875 print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
3878 /* Given these arguments describing a file, return the single-byte
3879 type indicator, or 0. */
3880 static char
3881 get_type_indicator (bool stat_ok, mode_t mode, enum filetype type)
3883 char c;
3885 if (stat_ok ? S_ISREG (mode) : type == normal)
3887 if (stat_ok && indicator_style == classify && (mode & S_IXUGO))
3888 c = '*';
3889 else
3890 c = 0;
3892 else
3894 if (stat_ok ? S_ISDIR (mode) : type == directory || type == arg_directory)
3895 c = '/';
3896 else if (indicator_style == slash)
3897 c = 0;
3898 else if (stat_ok ? S_ISLNK (mode) : type == symbolic_link)
3899 c = '@';
3900 else if (stat_ok ? S_ISFIFO (mode) : type == fifo)
3901 c = '|';
3902 else if (stat_ok ? S_ISSOCK (mode) : type == sock)
3903 c = '=';
3904 else if (stat_ok && S_ISDOOR (mode))
3905 c = '>';
3906 else
3907 c = 0;
3909 return c;
3912 static void
3913 print_type_indicator (bool stat_ok, mode_t mode, enum filetype type)
3915 char c = get_type_indicator (stat_ok, mode, type);
3916 if (c)
3917 DIRED_PUTCHAR (c);
3920 #ifdef HAVE_CAP
3921 /* Return true if NAME has a capability (see linux/capability.h) */
3922 static bool
3923 has_capability (char const *name)
3925 char *result;
3926 bool has_cap;
3928 cap_t cap_d = cap_get_file (name);
3929 if (cap_d == NULL)
3930 return false;
3932 result = cap_to_text (cap_d, NULL);
3933 cap_free (cap_d);
3934 if (!result)
3935 return false;
3937 /* check if human-readable capability string is empty */
3938 has_cap = !!*result;
3940 cap_free (result);
3941 return has_cap;
3943 #else
3944 static bool
3945 has_capability (char const *name ATTRIBUTE_UNUSED)
3947 return false;
3949 #endif
3951 /* Returns whether any color sequence was printed. */
3952 static bool
3953 print_color_indicator (const char *name, mode_t mode, int linkok,
3954 bool stat_ok, enum filetype filetype)
3956 int type;
3957 struct color_ext_type *ext; /* Color extension */
3958 size_t len; /* Length of name */
3960 /* Is this a nonexistent file? If so, linkok == -1. */
3962 if (linkok == -1 && color_indicator[C_MISSING].string != NULL)
3963 type = C_MISSING;
3964 else if (! stat_ok)
3966 static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS;
3967 type = filetype_indicator[filetype];
3969 else
3971 if (S_ISREG (mode))
3973 type = C_FILE;
3974 if ((mode & S_ISUID) != 0)
3975 type = C_SETUID;
3976 else if ((mode & S_ISGID) != 0)
3977 type = C_SETGID;
3978 else if (is_colored (C_CAP) && has_capability (name))
3979 type = C_CAP;
3980 else if ((mode & S_IXUGO) != 0)
3981 type = C_EXEC;
3983 else if (S_ISDIR (mode))
3985 if ((mode & S_ISVTX) && (mode & S_IWOTH))
3986 type = C_STICKY_OTHER_WRITABLE;
3987 else if ((mode & S_IWOTH) != 0)
3988 type = C_OTHER_WRITABLE;
3989 else if ((mode & S_ISVTX) != 0)
3990 type = C_STICKY;
3991 else
3992 type = C_DIR;
3994 else if (S_ISLNK (mode))
3995 type = ((!linkok && color_indicator[C_ORPHAN].string)
3996 ? C_ORPHAN : C_LINK);
3997 else if (S_ISFIFO (mode))
3998 type = C_FIFO;
3999 else if (S_ISSOCK (mode))
4000 type = C_SOCK;
4001 else if (S_ISBLK (mode))
4002 type = C_BLK;
4003 else if (S_ISCHR (mode))
4004 type = C_CHR;
4005 else if (S_ISDOOR (mode))
4006 type = C_DOOR;
4007 else
4009 /* Classify a file of some other type as C_ORPHAN. */
4010 type = C_ORPHAN;
4014 /* Check the file's suffix only if still classified as C_FILE. */
4015 ext = NULL;
4016 if (type == C_FILE)
4018 /* Test if NAME has a recognized suffix. */
4020 len = strlen (name);
4021 name += len; /* Pointer to final \0. */
4022 for (ext = color_ext_list; ext != NULL; ext = ext->next)
4024 if (ext->ext.len <= len
4025 && strncmp (name - ext->ext.len, ext->ext.string,
4026 ext->ext.len) == 0)
4027 break;
4032 const struct bin_str *const s
4033 = ext ? &(ext->seq) : &color_indicator[type];
4034 if (s->string != NULL)
4036 put_indicator (&color_indicator[C_LEFT]);
4037 put_indicator (s);
4038 put_indicator (&color_indicator[C_RIGHT]);
4039 return true;
4041 else
4042 return false;
4046 /* Output a color indicator (which may contain nulls). */
4047 static void
4048 put_indicator (const struct bin_str *ind)
4050 if (! used_color)
4052 used_color = true;
4053 prep_non_filename_text ();
4056 fwrite (ind->string, ind->len, 1, stdout);
4059 static size_t
4060 length_of_file_name_and_frills (const struct fileinfo *f)
4062 size_t len = 0;
4063 size_t name_width;
4064 char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))];
4066 if (print_inode)
4067 len += 1 + (format == with_commas
4068 ? strlen (umaxtostr (f->stat.st_ino, buf))
4069 : inode_number_width);
4071 if (print_block_size)
4072 len += 1 + (format == with_commas
4073 ? strlen (human_readable (ST_NBLOCKS (f->stat), buf,
4074 human_output_opts, ST_NBLOCKSIZE,
4075 output_block_size))
4076 : block_size_width);
4078 if (print_scontext)
4079 len += 1 + (format == with_commas ? strlen (f->scontext) : scontext_width);
4081 quote_name (NULL, f->name, filename_quoting_options, &name_width);
4082 len += name_width;
4084 if (indicator_style != none)
4086 char c = get_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
4087 len += (c != 0);
4090 return len;
4093 static void
4094 print_many_per_line (void)
4096 size_t row; /* Current row. */
4097 size_t cols = calculate_columns (true);
4098 struct column_info const *line_fmt = &column_info[cols - 1];
4100 /* Calculate the number of rows that will be in each column except possibly
4101 for a short column on the right. */
4102 size_t rows = cwd_n_used / cols + (cwd_n_used % cols != 0);
4104 for (row = 0; row < rows; row++)
4106 size_t col = 0;
4107 size_t filesno = row;
4108 size_t pos = 0;
4110 /* Print the next row. */
4111 while (1)
4113 struct fileinfo const *f = sorted_file[filesno];
4114 size_t name_length = length_of_file_name_and_frills (f);
4115 size_t max_name_length = line_fmt->col_arr[col++];
4116 print_file_name_and_frills (f);
4118 filesno += rows;
4119 if (filesno >= cwd_n_used)
4120 break;
4122 indent (pos + name_length, pos + max_name_length);
4123 pos += max_name_length;
4125 putchar ('\n');
4129 static void
4130 print_horizontal (void)
4132 size_t filesno;
4133 size_t pos = 0;
4134 size_t cols = calculate_columns (false);
4135 struct column_info const *line_fmt = &column_info[cols - 1];
4136 struct fileinfo const *f = sorted_file[0];
4137 size_t name_length = length_of_file_name_and_frills (f);
4138 size_t max_name_length = line_fmt->col_arr[0];
4140 /* Print first entry. */
4141 print_file_name_and_frills (f);
4143 /* Now the rest. */
4144 for (filesno = 1; filesno < cwd_n_used; ++filesno)
4146 size_t col = filesno % cols;
4148 if (col == 0)
4150 putchar ('\n');
4151 pos = 0;
4153 else
4155 indent (pos + name_length, pos + max_name_length);
4156 pos += max_name_length;
4159 f = sorted_file[filesno];
4160 print_file_name_and_frills (f);
4162 name_length = length_of_file_name_and_frills (f);
4163 max_name_length = line_fmt->col_arr[col];
4165 putchar ('\n');
4168 static void
4169 print_with_commas (void)
4171 size_t filesno;
4172 size_t pos = 0;
4174 for (filesno = 0; filesno < cwd_n_used; filesno++)
4176 struct fileinfo const *f = sorted_file[filesno];
4177 size_t len = length_of_file_name_and_frills (f);
4179 if (filesno != 0)
4181 char separator;
4183 if (pos + len + 2 < line_length)
4185 pos += 2;
4186 separator = ' ';
4188 else
4190 pos = 0;
4191 separator = '\n';
4194 putchar (',');
4195 putchar (separator);
4198 print_file_name_and_frills (f);
4199 pos += len;
4201 putchar ('\n');
4204 /* Assuming cursor is at position FROM, indent up to position TO.
4205 Use a TAB character instead of two or more spaces whenever possible. */
4207 static void
4208 indent (size_t from, size_t to)
4210 while (from < to)
4212 if (tabsize != 0 && to / tabsize > (from + 1) / tabsize)
4214 putchar ('\t');
4215 from += tabsize - from % tabsize;
4217 else
4219 putchar (' ');
4220 from++;
4225 /* Put DIRNAME/NAME into DEST, handling `.' and `/' properly. */
4226 /* FIXME: maybe remove this function someday. See about using a
4227 non-malloc'ing version of file_name_concat. */
4229 static void
4230 attach (char *dest, const char *dirname, const char *name)
4232 const char *dirnamep = dirname;
4234 /* Copy dirname if it is not ".". */
4235 if (dirname[0] != '.' || dirname[1] != 0)
4237 while (*dirnamep)
4238 *dest++ = *dirnamep++;
4239 /* Add '/' if `dirname' doesn't already end with it. */
4240 if (dirnamep > dirname && dirnamep[-1] != '/')
4241 *dest++ = '/';
4243 while (*name)
4244 *dest++ = *name++;
4245 *dest = 0;
4248 /* Allocate enough column info suitable for the current number of
4249 files and display columns, and initialize the info to represent the
4250 narrowest possible columns. */
4252 static void
4253 init_column_info (void)
4255 size_t i;
4256 size_t max_cols = MIN (max_idx, cwd_n_used);
4258 /* Currently allocated columns in column_info. */
4259 static size_t column_info_alloc;
4261 if (column_info_alloc < max_cols)
4263 size_t new_column_info_alloc;
4264 size_t *p;
4266 if (max_cols < max_idx / 2)
4268 /* The number of columns is far less than the display width
4269 allows. Grow the allocation, but only so that it's
4270 double the current requirements. If the display is
4271 extremely wide, this avoids allocating a lot of memory
4272 that is never needed. */
4273 column_info = xnrealloc (column_info, max_cols,
4274 2 * sizeof *column_info);
4275 new_column_info_alloc = 2 * max_cols;
4277 else
4279 column_info = xnrealloc (column_info, max_idx, sizeof *column_info);
4280 new_column_info_alloc = max_idx;
4283 /* Allocate the new size_t objects by computing the triangle
4284 formula n * (n + 1) / 2, except that we don't need to
4285 allocate the part of the triangle that we've already
4286 allocated. Check for address arithmetic overflow. */
4288 size_t column_info_growth = new_column_info_alloc - column_info_alloc;
4289 size_t s = column_info_alloc + 1 + new_column_info_alloc;
4290 size_t t = s * column_info_growth;
4291 if (s < new_column_info_alloc || t / column_info_growth != s)
4292 xalloc_die ();
4293 p = xnmalloc (t / 2, sizeof *p);
4296 /* Grow the triangle by parceling out the cells just allocated. */
4297 for (i = column_info_alloc; i < new_column_info_alloc; i++)
4299 column_info[i].col_arr = p;
4300 p += i + 1;
4303 column_info_alloc = new_column_info_alloc;
4306 for (i = 0; i < max_cols; ++i)
4308 size_t j;
4310 column_info[i].valid_len = true;
4311 column_info[i].line_len = (i + 1) * MIN_COLUMN_WIDTH;
4312 for (j = 0; j <= i; ++j)
4313 column_info[i].col_arr[j] = MIN_COLUMN_WIDTH;
4317 /* Calculate the number of columns needed to represent the current set
4318 of files in the current display width. */
4320 static size_t
4321 calculate_columns (bool by_columns)
4323 size_t filesno; /* Index into cwd_file. */
4324 size_t cols; /* Number of files across. */
4326 /* Normally the maximum number of columns is determined by the
4327 screen width. But if few files are available this might limit it
4328 as well. */
4329 size_t max_cols = MIN (max_idx, cwd_n_used);
4331 init_column_info ();
4333 /* Compute the maximum number of possible columns. */
4334 for (filesno = 0; filesno < cwd_n_used; ++filesno)
4336 struct fileinfo const *f = sorted_file[filesno];
4337 size_t name_length = length_of_file_name_and_frills (f);
4338 size_t i;
4340 for (i = 0; i < max_cols; ++i)
4342 if (column_info[i].valid_len)
4344 size_t idx = (by_columns
4345 ? filesno / ((cwd_n_used + i) / (i + 1))
4346 : filesno % (i + 1));
4347 size_t real_length = name_length + (idx == i ? 0 : 2);
4349 if (column_info[i].col_arr[idx] < real_length)
4351 column_info[i].line_len += (real_length
4352 - column_info[i].col_arr[idx]);
4353 column_info[i].col_arr[idx] = real_length;
4354 column_info[i].valid_len = (column_info[i].line_len
4355 < line_length);
4361 /* Find maximum allowed columns. */
4362 for (cols = max_cols; 1 < cols; --cols)
4364 if (column_info[cols - 1].valid_len)
4365 break;
4368 return cols;
4371 void
4372 usage (int status)
4374 if (status != EXIT_SUCCESS)
4375 fprintf (stderr, _("Try `%s --help' for more information.\n"),
4376 program_name);
4377 else
4379 printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);
4380 fputs (_("\
4381 List information about the FILEs (the current directory by default).\n\
4382 Sort entries alphabetically if none of -cftuvSUX nor --sort.\n\
4384 "), stdout);
4385 fputs (_("\
4386 Mandatory arguments to long options are mandatory for short options too.\n\
4387 "), stdout);
4388 fputs (_("\
4389 -a, --all do not ignore entries starting with .\n\
4390 -A, --almost-all do not list implied . and ..\n\
4391 --author with -l, print the author of each file\n\
4392 -b, --escape print octal escapes for nongraphic characters\n\
4393 "), stdout);
4394 fputs (_("\
4395 --block-size=SIZE use SIZE-byte blocks\n\
4396 -B, --ignore-backups do not list implied entries ending with ~\n\
4397 -c with -lt: sort by, and show, ctime (time of last\n\
4398 modification of file status information)\n\
4399 with -l: show ctime and sort by name\n\
4400 otherwise: sort by ctime\n\
4401 "), stdout);
4402 fputs (_("\
4403 -C list entries by columns\n\
4404 --color[=WHEN] control whether color is used to distinguish file\n\
4405 types. WHEN may be `never', `always', or `auto'\n\
4406 -d, --directory list directory entries instead of contents,\n\
4407 and do not dereference symbolic links\n\
4408 -D, --dired generate output designed for Emacs' dired mode\n\
4409 "), stdout);
4410 fputs (_("\
4411 -f do not sort, enable -aU, disable -ls --color\n\
4412 -F, --classify append indicator (one of */=>@|) to entries\n\
4413 --file-type likewise, except do not append `*'\n\
4414 --format=WORD across -x, commas -m, horizontal -x, long -l,\n\
4415 single-column -1, verbose -l, vertical -C\n\
4416 --full-time like -l --time-style=full-iso\n\
4417 "), stdout);
4418 fputs (_("\
4419 -g like -l, but do not list owner\n\
4420 "), stdout);
4421 fputs (_("\
4422 --group-directories-first\n\
4423 group directories before files.\n\
4424 augment with a --sort option, but any\n\
4425 use of --sort=none (-U) disables grouping\n\
4426 "), stdout);
4427 fputs (_("\
4428 -G, --no-group in a long listing, don't print group names\n\
4429 -h, --human-readable with -l, print sizes in human readable format\n\
4430 (e.g., 1K 234M 2G)\n\
4431 --si likewise, but use powers of 1000 not 1024\n\
4432 "), stdout);
4433 fputs (_("\
4434 -H, --dereference-command-line\n\
4435 follow symbolic links listed on the command line\n\
4436 --dereference-command-line-symlink-to-dir\n\
4437 follow each command line symbolic link\n\
4438 that points to a directory\n\
4439 --hide=PATTERN do not list implied entries matching shell PATTERN\n\
4440 (overridden by -a or -A)\n\
4441 "), stdout);
4442 fputs (_("\
4443 --indicator-style=WORD append indicator with style WORD to entry names:\n\
4444 none (default), slash (-p),\n\
4445 file-type (--file-type), classify (-F)\n\
4446 -i, --inode print the index number of each file\n\
4447 -I, --ignore=PATTERN do not list implied entries matching shell PATTERN\n\
4448 -k like --block-size=1K\n\
4449 "), stdout);
4450 fputs (_("\
4451 -l use a long listing format\n\
4452 -L, --dereference when showing file information for a symbolic\n\
4453 link, show information for the file the link\n\
4454 references rather than for the link itself\n\
4455 -m fill width with a comma separated list of entries\n\
4456 "), stdout);
4457 fputs (_("\
4458 -n, --numeric-uid-gid like -l, but list numeric user and group IDs\n\
4459 -N, --literal print raw entry names (don't treat e.g. control\n\
4460 characters specially)\n\
4461 -o like -l, but do not list group information\n\
4462 -p, --indicator-style=slash\n\
4463 append / indicator to directories\n\
4464 "), stdout);
4465 fputs (_("\
4466 -q, --hide-control-chars print ? instead of non graphic characters\n\
4467 --show-control-chars show non graphic characters as-is (default\n\
4468 unless program is `ls' and output is a terminal)\n\
4469 -Q, --quote-name enclose entry names in double quotes\n\
4470 --quoting-style=WORD use quoting style WORD for entry names:\n\
4471 literal, locale, shell, shell-always, c, escape\n\
4472 "), stdout);
4473 fputs (_("\
4474 -r, --reverse reverse order while sorting\n\
4475 -R, --recursive list subdirectories recursively\n\
4476 -s, --size print the size of each file, in blocks\n\
4477 "), stdout);
4478 fputs (_("\
4479 -S sort by file size\n\
4480 --sort=WORD sort by WORD instead of name: none -U,\n\
4481 extension -X, size -S, time -t, version -v\n\
4482 --time=WORD with -l, show time as WORD instead of modification\n\
4483 time: atime -u, access -u, use -u, ctime -c,\n\
4484 or status -c; use specified time as sort key\n\
4485 if --sort=time\n\
4486 "), stdout);
4487 fputs (_("\
4488 --time-style=STYLE with -l, show times using style STYLE:\n\
4489 full-iso, long-iso, iso, locale, +FORMAT.\n\
4490 FORMAT is interpreted like `date'; if FORMAT is\n\
4491 FORMAT1<newline>FORMAT2, FORMAT1 applies to\n\
4492 non-recent files and FORMAT2 to recent files;\n\
4493 if STYLE is prefixed with `posix-', STYLE\n\
4494 takes effect only outside the POSIX locale\n\
4495 "), stdout);
4496 fputs (_("\
4497 -t sort by modification time\n\
4498 -T, --tabsize=COLS assume tab stops at each COLS instead of 8\n\
4499 "), stdout);
4500 fputs (_("\
4501 -u with -lt: sort by, and show, access time\n\
4502 with -l: show access time and sort by name\n\
4503 otherwise: sort by access time\n\
4504 -U do not sort; list entries in directory order\n\
4505 -v sort by version\n\
4506 "), stdout);
4507 fputs (_("\
4508 -w, --width=COLS assume screen width instead of current value\n\
4509 -x list entries by lines instead of by columns\n\
4510 -X sort alphabetically by entry extension\n\
4511 -Z, --context print any SELinux security context of each file\n\
4512 -1 list one file per line\n\
4513 "), stdout);
4514 fputs (HELP_OPTION_DESCRIPTION, stdout);
4515 fputs (VERSION_OPTION_DESCRIPTION, stdout);
4516 fputs (_("\n\
4517 SIZE may be (or may be an integer optionally followed by) one of following:\n\
4518 kB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n\
4519 "), stdout);
4520 fputs (_("\
4522 By default, color is not used to distinguish types of files. That is\n\
4523 equivalent to using --color=none. Using the --color option without the\n\
4524 optional WHEN argument is equivalent to using --color=always. With\n\
4525 --color=auto, color codes are output only if standard output is connected\n\
4526 to a terminal (tty). The environment variable LS_COLORS can influence the\n\
4527 colors, and can be set easily by the dircolors command.\n\
4528 "), stdout);
4529 fputs (_("\
4531 Exit status:\n\
4532 0 if OK,\n\
4533 1 if minor problems (e.g., cannot access subdirectory),\n\
4534 2 if serious trouble (e.g., cannot access command-line argument).\n\
4535 "), stdout);
4536 emit_bug_reporting_address ();
4538 exit (status);