1 /* 'dir', 'vdir' and 'ls' directory listing programs for GNU.
2 Copyright (C) 1985-2018 Free Software Foundation, Inc.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
16
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.
21
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.
26
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. */
31
32 /* Written by Richard Stallman and David MacKenzie. */
33
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>. */
37
38 #include <config.h>
39 #include <sys/types.h>
40
41 #include <termios.h>
42 #if HAVE_STROPTS_H
43 # include <stropts.h>
44 #endif
45 #include <sys/ioctl.h>
46
47 #ifdef WINSIZE_IN_PTEM
48 # include <sys/stream.h>
49 # include <sys/ptem.h>
50 #endif
51
52 #include <stdio.h>
53 #include <assert.h>
54 #include <setjmp.h>
55 #include <pwd.h>
56 #include <getopt.h>
57 #include <signal.h>
58 #include <selinux/selinux.h>
59 #include <wchar.h>
60
61 #if HAVE_LANGINFO_CODESET
62 # include <langinfo.h>
63 #endif
64
65 /* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is
66 present. */
67 #ifndef SA_NOCLDSTOP
68 # define SA_NOCLDSTOP 0
69 # define sigprocmask(How, Set, Oset) /* empty */
70 # define sigset_t int
71 # if ! HAVE_SIGINTERRUPT
72 # define siginterrupt(sig, flag) /* empty */
73 # endif
74 #endif
75
76 /* NonStop circa 2011 lacks both SA_RESTART and siginterrupt, so don't
77 restart syscalls after a signal handler fires. This may cause
78 colors to get messed up on the screen if 'ls' is interrupted, but
79 that's the best we can do on such a platform. */
80 #ifndef SA_RESTART
81 # define SA_RESTART 0
82 #endif
83
84 #include "system.h"
85 #include <fnmatch.h>
86
87 #include "acl.h"
88 #include "argmatch.h"
89 #include "c-strcase.h"
90 #include "dev-ino.h"
91 #include "die.h"
92 #include "error.h"
93 #include "filenamecat.h"
94 #include "hard-locale.h"
95 #include "hash.h"
96 #include "human.h"
97 #include "filemode.h"
98 #include "filevercmp.h"
99 #include "idcache.h"
100 #include "ls.h"
101 #include "mbswidth.h"
102 #include "mpsort.h"
103 #include "obstack.h"
104 #include "quote.h"
105 #include "smack.h"
106 #include "stat-size.h"
107 #include "stat-time.h"
108 #include "strftime.h"
109 #include "xdectoint.h"
110 #include "xstrtol.h"
111 #include "areadlink.h"
112 #include "mbsalign.h"
113 #include "dircolors.h"
114 #include "xgethostname.h"
115 #include "c-ctype.h"
116 #include "canonicalize.h"
117
118 /* Include <sys/capability.h> last to avoid a clash of <sys/types.h>
119 include guards with some premature versions of libcap.
120 For more details, see <https://bugzilla.redhat.com/483548>. */
121 #ifdef HAVE_CAP
122 # include <sys/capability.h>
123 #endif
124
125 #define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \
126 : (ls_mode == LS_MULTI_COL \
127 ? "dir" : "vdir"))
128
129 #define AUTHORS \
130 proper_name ("Richard M. Stallman"), \
131 proper_name ("David MacKenzie")
132
133 #define obstack_chunk_alloc malloc
134 #define obstack_chunk_free free
135
136 /* Return an int indicating the result of comparing two integers.
137 Subtracting doesn't always work, due to overflow. */
138 #define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b))
139
140 /* Unix-based readdir implementations have historically returned a dirent.d_ino
141 value that is sometimes not equal to the stat-obtained st_ino value for
142 that same entry. This error occurs for a readdir entry that refers
143 to a mount point. readdir's error is to return the inode number of
144 the underlying directory -- one that typically cannot be stat'ed, as
145 long as a file system is mounted on that directory. RELIABLE_D_INO
146 encapsulates whether we can use the more efficient approach of relying
147 on readdir-supplied d_ino values, or whether we must incur the cost of
148 calling stat or lstat to obtain each guaranteed-valid inode number. */
149
150 #ifndef READDIR_LIES_ABOUT_MOUNTPOINT_D_INO
151 # define READDIR_LIES_ABOUT_MOUNTPOINT_D_INO 1
152 #endif
153
154 #if READDIR_LIES_ABOUT_MOUNTPOINT_D_INO
155 # define RELIABLE_D_INO(dp) NOT_AN_INODE_NUMBER
156 #else
157 # define RELIABLE_D_INO(dp) D_INO (dp)
158 #endif
159
160 #if ! HAVE_STRUCT_STAT_ST_AUTHOR
161 # define st_author st_uid
162 #endif
163
164 enum filetype
165 {
166 unknown,
167 fifo,
168 chardev,
169 directory,
170 blockdev,
171 normal,
172 symbolic_link,
173 sock,
174 whiteout,
175 arg_directory
176 };
177
178 /* Display letters and indicators for each filetype.
179 Keep these in sync with enum filetype. */
180 static char const filetype_letter[] = "?pcdb-lswd";
181
182 /* Ensure that filetype and filetype_letter have the same
183 number of elements. */
184 verify (sizeof filetype_letter - 1 == arg_directory + 1);
185
186 #define FILETYPE_INDICATORS \
187 { \
188 C_ORPHAN, C_FIFO, C_CHR, C_DIR, C_BLK, C_FILE, \
189 C_LINK, C_SOCK, C_FILE, C_DIR \
190 }
191
192 enum acl_type
193 {
194 ACL_T_NONE,
195 ACL_T_LSM_CONTEXT_ONLY,
196 ACL_T_YES
197 };
198
199 struct fileinfo
200 {
201 /* The file name. */
202 char *name;
203
204 /* For symbolic link, name of the file linked to, otherwise zero. */
205 char *linkname;
206
207 /* For terminal hyperlinks. */
208 char *absolute_name;
209
210 struct stat stat;
211
212 enum filetype filetype;
213
214 /* For symbolic link and long listing, st_mode of file linked to, otherwise
215 zero. */
216 mode_t linkmode;
217
218 /* security context. */
219 char *scontext;
220
221 bool stat_ok;
222
223 /* For symbolic link and color printing, true if linked-to file
224 exists, otherwise false. */
225 bool linkok;
226
227 /* For long listings, true if the file has an access control list,
228 or a security context. */
229 enum acl_type acl_type;
230
231 /* For color listings, true if a regular file has capability info. */
232 bool has_capability;
233
234 /* Whether file name needs quoting. tri-state with -1 == unknown. */
235 int quoted;
236 };
237
238 #define LEN_STR_PAIR(s) sizeof (s) - 1, s
239
240 /* Null is a valid character in a color indicator (think about Epson
241 printers, for example) so we have to use a length/buffer string
242 type. */
243
244 struct bin_str
245 {
246 size_t len; /* Number of bytes */
247 const char *string; /* Pointer to the same */
248 };
249
250 #if ! HAVE_TCGETPGRP
251 # define tcgetpgrp(Fd) 0
252 #endif
253
254 static size_t quote_name (char const *name,
255 struct quoting_options const *options,
256 int needs_general_quoting,
257 const struct bin_str *color,
258 bool allow_pad, struct obstack *stack,
259 char const *absolute_name);
260 static size_t quote_name_buf (char **inbuf, size_t bufsize, char *name,
261 struct quoting_options const *options,
262 int needs_general_quoting, size_t *width,
263 bool *pad);
264 static char *make_link_name (char const *name, char const *linkname);
265 static int decode_switches (int argc, char **argv);
266 static bool file_ignored (char const *name);
267 static uintmax_t gobble_file (char const *name, enum filetype type,
268 ino_t inode, bool command_line_arg,
269 char const *dirname);
270 static const struct bin_str * get_color_indicator (const struct fileinfo *f,
271 bool symlink_target);
272 static bool print_color_indicator (const struct bin_str *ind);
273 static void put_indicator (const struct bin_str *ind);
274 static void add_ignore_pattern (const char *pattern);
275 static void attach (char *dest, const char *dirname, const char *name);
276 static void clear_files (void);
277 static void extract_dirs_from_files (char const *dirname,
278 bool command_line_arg);
279 static void get_link_name (char const *filename, struct fileinfo *f,
280 bool command_line_arg);
281 static void indent (size_t from, size_t to);
282 static size_t calculate_columns (bool by_columns);
283 static void print_current_files (void);
284 static void print_dir (char const *name, char const *realname,
285 bool command_line_arg);
286 static size_t print_file_name_and_frills (const struct fileinfo *f,
287 size_t start_col);
288 static void print_horizontal (void);
289 static int format_user_width (uid_t u);
290 static int format_group_width (gid_t g);
291 static void print_long_format (const struct fileinfo *f);
292 static void print_many_per_line (void);
293 static size_t print_name_with_quoting (const struct fileinfo *f,
294 bool symlink_target,
295 struct obstack *stack,
296 size_t start_col);
297 static void prep_non_filename_text (void);
298 static bool print_type_indicator (bool stat_ok, mode_t mode,
299 enum filetype type);
300 static void print_with_separator (char sep);
301 static void queue_directory (char const *name, char const *realname,
302 bool command_line_arg);
303 static void sort_files (void);
304 static void parse_ls_color (void);
305
306 static void getenv_quoting_style (void);
307
308 /* Initial size of hash table.
309 Most hierarchies are likely to be shallower than this. */
310 #define INITIAL_TABLE_SIZE 30
311
312 /* The set of 'active' directories, from the current command-line argument
313 to the level in the hierarchy at which files are being listed.
314 A directory is represented by its device and inode numbers (struct dev_ino).
315 A directory is added to this set when ls begins listing it or its
316 entries, and it is removed from the set just after ls has finished
317 processing it. This set is used solely to detect loops, e.g., with
318 mkdir loop; cd loop; ln -s ../loop sub; ls -RL */
319 static Hash_table *active_dir_set;
320
321 #define LOOP_DETECT (!!active_dir_set)
322
323 /* The table of files in the current directory:
324
325 'cwd_file' points to a vector of 'struct fileinfo', one per file.
326 'cwd_n_alloc' is the number of elements space has been allocated for.
327 'cwd_n_used' is the number actually in use. */
328
329 /* Address of block containing the files that are described. */
330 static struct fileinfo *cwd_file;
331
332 /* Length of block that 'cwd_file' points to, measured in files. */
333 static size_t cwd_n_alloc;
334
335 /* Index of first unused slot in 'cwd_file'. */
336 static size_t cwd_n_used;
337
338 /* Whether files needs may need padding due to quoting. */
339 static bool cwd_some_quoted;
340
341 /* Whether quoting style _may_ add outer quotes,
342 and whether aligning those is useful. */
343 static bool align_variable_outer_quotes;
344
345 /* Vector of pointers to files, in proper sorted order, and the number
346 of entries allocated for it. */
347 static void **sorted_file;
348 static size_t sorted_file_alloc;
349
350 /* When true, in a color listing, color each symlink name according to the
351 type of file it points to. Otherwise, color them according to the 'ln'
352 directive in LS_COLORS. Dangling (orphan) symlinks are treated specially,
353 regardless. This is set when 'ln=target' appears in LS_COLORS. */
354
355 static bool color_symlink_as_referent;
356
357 static char const *hostname;
358
359 /* mode of appropriate file for colorization */
360 #define FILE_OR_LINK_MODE(File) \
361 ((color_symlink_as_referent && (File)->linkok) \
362 ? (File)->linkmode : (File)->stat.st_mode)
363
364
365 /* Record of one pending directory waiting to be listed. */
366
367 struct pending
368 {
369 char *name;
370 /* If the directory is actually the file pointed to by a symbolic link we
371 were told to list, 'realname' will contain the name of the symbolic
372 link, otherwise zero. */
373 char *realname;
374 bool command_line_arg;
375 struct pending *next;
376 };
377
378 static struct pending *pending_dirs;
379
380 /* Current time in seconds and nanoseconds since 1970, updated as
381 needed when deciding whether a file is recent. */
382
383 static struct timespec current_time;
384
385 static bool print_scontext;
386 static char UNKNOWN_SECURITY_CONTEXT[] = "?";
387
388 /* Whether any of the files has an ACL. This affects the width of the
389 mode column. */
390
391 static bool any_has_acl;
392
393 /* The number of columns to use for columns containing inode numbers,
394 block sizes, link counts, owners, groups, authors, major device
395 numbers, minor device numbers, and file sizes, respectively. */
396
397 static int inode_number_width;
398 static int block_size_width;
399 static int nlink_width;
400 static int scontext_width;
401 static int owner_width;
402 static int group_width;
403 static int author_width;
404 static int major_device_number_width;
405 static int minor_device_number_width;
406 static int file_size_width;
407
408 /* Option flags */
409
410 /* long_format for lots of info, one per line.
411 one_per_line for just names, one per line.
412 many_per_line for just names, many per line, sorted vertically.
413 horizontal for just names, many per line, sorted horizontally.
414 with_commas for just names, many per line, separated by commas.
415
416 -l (and other options that imply -l), -1, -C, -x and -m control
417 this parameter. */
418
419 enum format
420 {
421 long_format, /* -l and other options that imply -l */
422 one_per_line, /* -1 */
423 many_per_line, /* -C */
424 horizontal, /* -x */
425 with_commas /* -m */
426 };
427
428 static enum format format;
429
430 /* 'full-iso' uses full ISO-style dates and times. 'long-iso' uses longer
431 ISO-style timestamps, though shorter than 'full-iso'. 'iso' uses shorter
432 ISO-style timestamps. 'locale' uses locale-dependent timestamps. */
433 enum time_style
434 {
435 full_iso_time_style, /* --time-style=full-iso */
436 long_iso_time_style, /* --time-style=long-iso */
437 iso_time_style, /* --time-style=iso */
438 locale_time_style /* --time-style=locale */
439 };
440
441 static char const *const time_style_args[] =
442 {
443 "full-iso", "long-iso", "iso", "locale", NULL
444 };
445 static enum time_style const time_style_types[] =
446 {
447 full_iso_time_style, long_iso_time_style, iso_time_style,
448 locale_time_style
449 };
450 ARGMATCH_VERIFY (time_style_args, time_style_types);
451
452 /* Type of time to print or sort by. Controlled by -c and -u.
453 The values of each item of this enum are important since they are
454 used as indices in the sort functions array (see sort_files()). */
455
456 enum time_type
457 {
458 time_mtime, /* default */
459 time_ctime, /* -c */
460 time_atime, /* -u */
461 time_numtypes /* the number of elements of this enum */
462 };
463
464 static enum time_type time_type;
465
466 /* The file characteristic to sort by. Controlled by -t, -S, -U, -X, -v.
467 The values of each item of this enum are important since they are
468 used as indices in the sort functions array (see sort_files()). */
469
470 enum sort_type
471 {
472 sort_none = -1, /* -U */
473 sort_name, /* default */
474 sort_extension, /* -X */
475 sort_size, /* -S */
476 sort_version, /* -v */
477 sort_time, /* -t */
478 sort_numtypes /* the number of elements of this enum */
479 };
480
481 static enum sort_type sort_type;
482
483 /* Direction of sort.
484 false means highest first if numeric,
485 lowest first if alphabetic;
486 these are the defaults.
487 true means the opposite order in each case. -r */
488
489 static bool sort_reverse;
490
491 /* True means to display owner information. -g turns this off. */
492
493 static bool print_owner = true;
494
495 /* True means to display author information. */
496
497 static bool print_author;
498
499 /* True means to display group information. -G and -o turn this off. */
500
501 static bool print_group = true;
502
503 /* True means print the user and group id's as numbers rather
504 than as names. -n */
505
506 static bool numeric_ids;
507
508 /* True means mention the size in blocks of each file. -s */
509
510 static bool print_block_size;
511
512 /* Human-readable options for output, when printing block counts. */
513 static int human_output_opts;
514
515 /* The units to use when printing block counts. */
516 static uintmax_t output_block_size;
517
518 /* Likewise, but for file sizes. */
519 static int file_human_output_opts;
520 static uintmax_t file_output_block_size = 1;
521
522 /* Follow the output with a special string. Using this format,
523 Emacs' dired mode starts up twice as fast, and can handle all
524 strange characters in file names. */
525 static bool dired;
526
527 /* 'none' means don't mention the type of files.
528 'slash' means mention directories only, with a '/'.
529 'file_type' means mention file types.
530 'classify' means mention file types and mark executables.
531
532 Controlled by -F, -p, and --indicator-style. */
533
534 enum indicator_style
535 {
536 none, /* --indicator-style=none */
537 slash, /* -p, --indicator-style=slash */
538 file_type, /* --indicator-style=file-type */
539 classify /* -F, --indicator-style=classify */
540 };
541
542 static enum indicator_style indicator_style;
543
544 /* Names of indicator styles. */
545 static char const *const indicator_style_args[] =
546 {
547 "none", "slash", "file-type", "classify", NULL
548 };
549 static enum indicator_style const indicator_style_types[] =
550 {
551 none, slash, file_type, classify
552 };
553 ARGMATCH_VERIFY (indicator_style_args, indicator_style_types);
554
555 /* True means use colors to mark types. Also define the different
556 colors as well as the stuff for the LS_COLORS environment variable.
557 The LS_COLORS variable is now in a termcap-like format. */
558
559 static bool print_with_color;
560
561 static bool print_hyperlink;
562
563 /* Whether we used any colors in the output so far. If so, we will
564 need to restore the default color later. If not, we will need to
565 call prep_non_filename_text before using color for the first time. */
566
567 static bool used_color = false;
568
569 enum when_type
570 {
571 when_never, /* 0: default or --color=never */
572 when_always, /* 1: --color=always */
573 when_if_tty /* 2: --color=tty */
574 };
575
576 enum Dereference_symlink
577 {
578 DEREF_UNDEFINED = 1,
579 DEREF_NEVER,
580 DEREF_COMMAND_LINE_ARGUMENTS, /* -H */
581 DEREF_COMMAND_LINE_SYMLINK_TO_DIR, /* the default, in certain cases */
582 DEREF_ALWAYS /* -L */
583 };
584
585 enum indicator_no
586 {
587 C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK,
588 C_FIFO, C_SOCK,
589 C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID,
590 C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP, C_MULTIHARDLINK,
591 C_CLR_TO_EOL
592 };
593
594 static const char *const indicator_name[]=
595 {
596 "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so",
597 "bd", "cd", "mi", "or", "ex", "do", "su", "sg", "st",
598 "ow", "tw", "ca", "mh", "cl", NULL
599 };
600
601 struct color_ext_type
602 {
603 struct bin_str ext; /* The extension we're looking for */
604 struct bin_str seq; /* The sequence to output when we do */
605 struct color_ext_type *next; /* Next in list */
606 };
607
608 static struct bin_str color_indicator[] =
609 {
610 { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */
611 { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */
612 { 0, NULL }, /* ec: End color (replaces lc+rs+rc) */
613 { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */
614 { 0, NULL }, /* no: Normal */
615 { 0, NULL }, /* fi: File: default */
616 { LEN_STR_PAIR ("01;34") }, /* di: Directory: bright blue */
617 { LEN_STR_PAIR ("01;36") }, /* ln: Symlink: bright cyan */
618 { LEN_STR_PAIR ("33") }, /* pi: Pipe: yellow/brown */
619 { LEN_STR_PAIR ("01;35") }, /* so: Socket: bright magenta */
620 { LEN_STR_PAIR ("01;33") }, /* bd: Block device: bright yellow */
621 { LEN_STR_PAIR ("01;33") }, /* cd: Char device: bright yellow */
622 { 0, NULL }, /* mi: Missing file: undefined */
623 { 0, NULL }, /* or: Orphaned symlink: undefined */
624 { LEN_STR_PAIR ("01;32") }, /* ex: Executable: bright green */
625 { LEN_STR_PAIR ("01;35") }, /* do: Door: bright magenta */
626 { LEN_STR_PAIR ("37;41") }, /* su: setuid: white on red */
627 { LEN_STR_PAIR ("30;43") }, /* sg: setgid: black on yellow */
628 { LEN_STR_PAIR ("37;44") }, /* st: sticky: black on blue */
629 { LEN_STR_PAIR ("34;42") }, /* ow: other-writable: blue on green */
630 { LEN_STR_PAIR ("30;42") }, /* tw: ow w/ sticky: black on green */
631 { LEN_STR_PAIR ("30;41") }, /* ca: black on red */
632 { 0, NULL }, /* mh: disabled by default */
633 { LEN_STR_PAIR ("\033[K") }, /* cl: clear to end of line */
634 };
635
636 /* FIXME: comment */
637 static struct color_ext_type *color_ext_list = NULL;
638
639 /* Buffer for color sequences */
640 static char *color_buf;
641
642 /* True means to check for orphaned symbolic link, for displaying
643 colors. */
644
645 static bool check_symlink_color;
646
647 /* True means mention the inode number of each file. -i */
648
649 static bool print_inode;
650
651 /* What to do with symbolic links. Affected by -d, -F, -H, -l (and
652 other options that imply -l), and -L. */
653
654 static enum Dereference_symlink dereference;
655
656 /* True means when a directory is found, display info on its
657 contents. -R */
658
659 static bool recursive;
660
661 /* True means when an argument is a directory name, display info
662 on it itself. -d */
663
664 static bool immediate_dirs;
665
666 /* True means that directories are grouped before files. */
667
668 static bool directories_first;
669
670 /* Which files to ignore. */
671
672 static enum
673 {
674 /* Ignore files whose names start with '.', and files specified by
675 --hide and --ignore. */
676 IGNORE_DEFAULT,
677
678 /* Ignore '.', '..', and files specified by --ignore. */
679 IGNORE_DOT_AND_DOTDOT,
680
681 /* Ignore only files specified by --ignore. */
682 IGNORE_MINIMAL
683 } ignore_mode;
684
685 /* A linked list of shell-style globbing patterns. If a non-argument
686 file name matches any of these patterns, it is ignored.
687 Controlled by -I. Multiple -I options accumulate.
688 The -B option adds '*~' and '.*~' to this list. */
689
690 struct ignore_pattern
691 {
692 const char *pattern;
693 struct ignore_pattern *next;
694 };
695
696 static struct ignore_pattern *ignore_patterns;
697
698 /* Similar to IGNORE_PATTERNS, except that -a or -A causes this
699 variable itself to be ignored. */
700 static struct ignore_pattern *hide_patterns;
701
702 /* True means output nongraphic chars in file names as '?'.
703 (-q, --hide-control-chars)
704 qmark_funny_chars and the quoting style (-Q, --quoting-style=WORD) are
705 independent. The algorithm is: first, obey the quoting style to get a
706 string representing the file name; then, if qmark_funny_chars is set,
707 replace all nonprintable chars in that string with '?'. It's necessary
708 to replace nonprintable chars even in quoted strings, because we don't
709 want to mess up the terminal if control chars get sent to it, and some
710 quoting methods pass through control chars as-is. */
711 static bool qmark_funny_chars;
712
713 /* Quoting options for file and dir name output. */
714
715 static struct quoting_options *filename_quoting_options;
716 static struct quoting_options *dirname_quoting_options;
717
718 /* The number of chars per hardware tab stop. Setting this to zero
719 inhibits the use of TAB characters for separating columns. -T */
720 static size_t tabsize;
721
722 /* True means print each directory name before listing it. */
723
724 static bool print_dir_name;
725
726 /* The line length to use for breaking lines in many-per-line format.
727 Can be set with -w. */
728
729 static size_t line_length;
730
731 /* The local time zone rules, as per the TZ environment variable. */
732
733 static timezone_t localtz;
734
735 /* If true, the file listing format requires that stat be called on
736 each file. */
737
738 static bool format_needs_stat;
739
740 /* Similar to 'format_needs_stat', but set if only the file type is
741 needed. */
742
743 static bool format_needs_type;
744
745 /* An arbitrary limit on the number of bytes in a printed timestamp.
746 This is set to a relatively small value to avoid the need to worry
747 about denial-of-service attacks on servers that run "ls" on behalf
748 of remote clients. 1000 bytes should be enough for any practical
749 timestamp format. */
750
751 enum { TIME_STAMP_LEN_MAXIMUM = MAX (1000, INT_STRLEN_BOUND (time_t)) };
752
753 /* strftime formats for non-recent and recent files, respectively, in
754 -l output. */
755
756 static char const *long_time_format[2] =
757 {
758 /* strftime format for non-recent files (older than 6 months), in
759 -l output. This should contain the year, month and day (at
760 least), in an order that is understood by people in your
761 locale's territory. Please try to keep the number of used
762 screen columns small, because many people work in windows with
763 only 80 columns. But make this as wide as the other string
764 below, for recent files. */
765 /* TRANSLATORS: ls output needs to be aligned for ease of reading,
766 so be wary of using variable width fields from the locale.
767 Note %b is handled specially by ls and aligned correctly.
768 Note also that specifying a width as in %5b is erroneous as strftime
769 will count bytes rather than characters in multibyte locales. */
770 N_("%b %e %Y"),
771 /* strftime format for recent files (younger than 6 months), in -l
772 output. This should contain the month, day and time (at
773 least), in an order that is understood by people in your
774 locale's territory. Please try to keep the number of used
775 screen columns small, because many people work in windows with
776 only 80 columns. But make this as wide as the other string
777 above, for non-recent files. */
778 /* TRANSLATORS: ls output needs to be aligned for ease of reading,
779 so be wary of using variable width fields from the locale.
780 Note %b is handled specially by ls and aligned correctly.
781 Note also that specifying a width as in %5b is erroneous as strftime
782 will count bytes rather than characters in multibyte locales. */
783 N_("%b %e %H:%M")
784 };
785
786 /* The set of signals that are caught. */
787
788 static sigset_t caught_signals;
789
790 /* If nonzero, the value of the pending fatal signal. */
791
792 static sig_atomic_t volatile interrupt_signal;
793
794 /* A count of the number of pending stop signals that have been received. */
795
796 static sig_atomic_t volatile stop_signal_count;
797
798 /* Desired exit status. */
799
800 static int exit_status;
801
802 /* Exit statuses. */
803 enum
804 {
805 /* "ls" had a minor problem. E.g., while processing a directory,
806 ls obtained the name of an entry via readdir, yet was later
807 unable to stat that name. This happens when listing a directory
808 in which entries are actively being removed or renamed. */
809 LS_MINOR_PROBLEM = 1,
810
811 /* "ls" had more serious trouble (e.g., memory exhausted, invalid
812 option or failure to stat a command line argument. */
813 LS_FAILURE = 2
814 };
815
816 /* For long options that have no equivalent short option, use a
817 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
818 enum
819 {
820 AUTHOR_OPTION = CHAR_MAX + 1,
821 BLOCK_SIZE_OPTION,
822 COLOR_OPTION,
823 DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION,
824 FILE_TYPE_INDICATOR_OPTION,
825 FORMAT_OPTION,
826 FULL_TIME_OPTION,
827 GROUP_DIRECTORIES_FIRST_OPTION,
828 HIDE_OPTION,
829 HYPERLINK_OPTION,
830 INDICATOR_STYLE_OPTION,
831 QUOTING_STYLE_OPTION,
832 SHOW_CONTROL_CHARS_OPTION,
833 SI_OPTION,
834 SORT_OPTION,
835 TIME_OPTION,
836 TIME_STYLE_OPTION
837 };
838
839 static struct option const long_options[] =
840 {
841 {"all", no_argument, NULL, 'a'},
842 {"escape", no_argument, NULL, 'b'},
843 {"directory", no_argument, NULL, 'd'},
844 {"dired", no_argument, NULL, 'D'},
845 {"full-time", no_argument, NULL, FULL_TIME_OPTION},
846 {"group-directories-first", no_argument, NULL,
847 GROUP_DIRECTORIES_FIRST_OPTION},
848 {"human-readable", no_argument, NULL, 'h'},
849 {"inode", no_argument, NULL, 'i'},
850 {"kibibytes", no_argument, NULL, 'k'},
851 {"numeric-uid-gid", no_argument, NULL, 'n'},
852 {"no-group", no_argument, NULL, 'G'},
853 {"hide-control-chars", no_argument, NULL, 'q'},
854 {"reverse", no_argument, NULL, 'r'},
855 {"size", no_argument, NULL, 's'},
856 {"width", required_argument, NULL, 'w'},
857 {"almost-all", no_argument, NULL, 'A'},
858 {"ignore-backups", no_argument, NULL, 'B'},
859 {"classify", no_argument, NULL, 'F'},
860 {"file-type", no_argument, NULL, FILE_TYPE_INDICATOR_OPTION},
861 {"si", no_argument, NULL, SI_OPTION},
862 {"dereference-command-line", no_argument, NULL, 'H'},
863 {"dereference-command-line-symlink-to-dir", no_argument, NULL,
864 DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION},
865 {"hide", required_argument, NULL, HIDE_OPTION},
866 {"ignore", required_argument, NULL, 'I'},
867 {"indicator-style", required_argument, NULL, INDICATOR_STYLE_OPTION},
868 {"dereference", no_argument, NULL, 'L'},
869 {"literal", no_argument, NULL, 'N'},
870 {"quote-name", no_argument, NULL, 'Q'},
871 {"quoting-style", required_argument, NULL, QUOTING_STYLE_OPTION},
872 {"recursive", no_argument, NULL, 'R'},
873 {"format", required_argument, NULL, FORMAT_OPTION},
874 {"show-control-chars", no_argument, NULL, SHOW_CONTROL_CHARS_OPTION},
875 {"sort", required_argument, NULL, SORT_OPTION},
876 {"tabsize", required_argument, NULL, 'T'},
877 {"time", required_argument, NULL, TIME_OPTION},
878 {"time-style", required_argument, NULL, TIME_STYLE_OPTION},
879 {"color", optional_argument, NULL, COLOR_OPTION},
880 {"hyperlink", optional_argument, NULL, HYPERLINK_OPTION},
881 {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION},
882 {"context", no_argument, 0, 'Z'},
883 {"author", no_argument, NULL, AUTHOR_OPTION},
884 {GETOPT_HELP_OPTION_DECL},
885 {GETOPT_VERSION_OPTION_DECL},
886 {NULL, 0, NULL, 0}
887 };
888
889 static char const *const format_args[] =
890 {
891 "verbose", "long", "commas", "horizontal", "across",
892 "vertical", "single-column", NULL
893 };
894 static enum format const format_types[] =
895 {
896 long_format, long_format, with_commas, horizontal, horizontal,
897 many_per_line, one_per_line
898 };
899 ARGMATCH_VERIFY (format_args, format_types);
900
901 static char const *const sort_args[] =
902 {
903 "none", "time", "size", "extension", "version", NULL
904 };
905 static enum sort_type const sort_types[] =
906 {
907 sort_none, sort_time, sort_size, sort_extension, sort_version
908 };
909 ARGMATCH_VERIFY (sort_args, sort_types);
910
911 static char const *const time_args[] =
912 {
913 "atime", "access", "use", "ctime", "status", NULL
914 };
915 static enum time_type const time_types[] =
916 {
917 time_atime, time_atime, time_atime, time_ctime, time_ctime
918 };
919 ARGMATCH_VERIFY (time_args, time_types);
920
921 static char const *const when_args[] =
922 {
923 /* force and none are for compatibility with another color-ls version */
924 "always", "yes", "force",
925 "never", "no", "none",
926 "auto", "tty", "if-tty", NULL
927 };
928 static enum when_type const when_types[] =
929 {
930 when_always, when_always, when_always,
931 when_never, when_never, when_never,
932 when_if_tty, when_if_tty, when_if_tty
933 };
934 ARGMATCH_VERIFY (when_args, when_types);
935
936 /* Information about filling a column. */
937 struct column_info
938 {
939 bool valid_len;
940 size_t line_len;
941 size_t *col_arr;
942 };
943
944 /* Array with information about column filledness. */
945 static struct column_info *column_info;
946
947 /* Maximum number of columns ever possible for this display. */
948 static size_t max_idx;
949
950 /* The minimum width of a column is 3: 1 character for the name and 2
951 for the separating white space. */
952 #define MIN_COLUMN_WIDTH 3
953
954
955 /* This zero-based index is used solely with the --dired option.
956 When that option is in effect, this counter is incremented for each
957 byte of output generated by this program so that the beginning
958 and ending indices (in that output) of every file name can be recorded
959 and later output themselves. */
960 static size_t dired_pos;
961
962 #define DIRED_PUTCHAR(c) do {putchar ((c)); ++dired_pos;} while (0)
963
964 /* Write S to STREAM and increment DIRED_POS by S_LEN. */
965 #define DIRED_FPUTS(s, stream, s_len) \
966 do {fputs (s, stream); dired_pos += s_len;} while (0)
967
968 /* Like DIRED_FPUTS, but for use when S is a literal string. */
969 #define DIRED_FPUTS_LITERAL(s, stream) \
970 do {fputs (s, stream); dired_pos += sizeof (s) - 1;} while (0)
971
972 #define DIRED_INDENT() \
973 do \
974 { \
975 if (dired) \
976 DIRED_FPUTS_LITERAL (" ", stdout); \
977 } \
978 while (0)
979
980 /* With --dired, store pairs of beginning and ending indices of file names. */
981 static struct obstack dired_obstack;
982
983 /* With --dired, store pairs of beginning and ending indices of any
984 directory names that appear as headers (just before 'total' line)
985 for lists of directory entries. Such directory names are seen when
986 listing hierarchies using -R and when a directory is listed with at
987 least one other command line argument. */
988 static struct obstack subdired_obstack;
989
990 /* Save the current index on the specified obstack, OBS. */
991 #define PUSH_CURRENT_DIRED_POS(obs) \
992 do \
993 { \
994 if (dired) \
995 obstack_grow (obs, &dired_pos, sizeof (dired_pos)); \
996 } \
997 while (0)
998
999 /* With -R, this stack is used to help detect directory cycles.
1000 The device/inode pairs on this stack mirror the pairs in the
1001 active_dir_set hash table. */
1002 static struct obstack dev_ino_obstack;
1003
1004 /* Push a pair onto the device/inode stack. */
1005 static void
dev_ino_push(dev_t dev,ino_t ino)1006 dev_ino_push (dev_t dev, ino_t ino)
1007 {
1008 void *vdi;
1009 struct dev_ino *di;
1010 int dev_ino_size = sizeof *di;
1011 obstack_blank (&dev_ino_obstack, dev_ino_size);
1012 vdi = obstack_next_free (&dev_ino_obstack);
1013 di = vdi;
1014 di--;
1015 di->st_dev = dev;
1016 di->st_ino = ino;
1017 }
1018
1019 /* Pop a dev/ino struct off the global dev_ino_obstack
1020 and return that struct. */
1021 static struct dev_ino
dev_ino_pop(void)1022 dev_ino_pop (void)
1023 {
1024 void *vdi;
1025 struct dev_ino *di;
1026 int dev_ino_size = sizeof *di;
1027 assert (dev_ino_size <= obstack_object_size (&dev_ino_obstack));
1028 obstack_blank_fast (&dev_ino_obstack, -dev_ino_size);
1029 vdi = obstack_next_free (&dev_ino_obstack);
1030 di = vdi;
1031 return *di;
1032 }
1033
1034 /* Note the use commented out below:
1035 #define ASSERT_MATCHING_DEV_INO(Name, Di) \
1036 do \
1037 { \
1038 struct stat sb; \
1039 assert (Name); \
1040 assert (0 <= stat (Name, &sb)); \
1041 assert (sb.st_dev == Di.st_dev); \
1042 assert (sb.st_ino == Di.st_ino); \
1043 } \
1044 while (0)
1045 */
1046
1047 /* Write to standard output PREFIX, followed by the quoting style and
1048 a space-separated list of the integers stored in OS all on one line. */
1049
1050 static void
dired_dump_obstack(const char * prefix,struct obstack * os)1051 dired_dump_obstack (const char *prefix, struct obstack *os)
1052 {
1053 size_t n_pos;
1054
1055 n_pos = obstack_object_size (os) / sizeof (dired_pos);
1056 if (n_pos > 0)
1057 {
1058 size_t *pos = (size_t *) obstack_finish (os);
1059 fputs (prefix, stdout);
1060 for (size_t i = 0; i < n_pos; i++)
1061 printf (" %lu", (unsigned long int) pos[i]);
1062 putchar ('\n');
1063 }
1064 }
1065
1066 /* Return the address of the first plain %b spec in FMT, or NULL if
1067 there is no such spec. %5b etc. do not match, so that user
1068 widths/flags are honored. */
1069
1070 static char const * _GL_ATTRIBUTE_PURE
first_percent_b(char const * fmt)1071 first_percent_b (char const *fmt)
1072 {
1073 for (; *fmt; fmt++)
1074 if (fmt[0] == '%')
1075 switch (fmt[1])
1076 {
1077 case 'b': return fmt;
1078 case '%': fmt++; break;
1079 }
1080 return NULL;
1081 }
1082
1083 static char RFC3986[256];
1084 static void
file_escape_init(void)1085 file_escape_init (void)
1086 {
1087 for (int i = 0; i < 256; i++)
1088 RFC3986[i] |= c_isalnum (i) || i == '~' || i == '-' || i == '.' || i == '_';
1089 }
1090
1091 /* Read the abbreviated month names from the locale, to align them
1092 and to determine the max width of the field and to truncate names
1093 greater than our max allowed.
1094 Note even though this handles multibyte locales correctly
1095 it's not restricted to them as single byte locales can have
1096 variable width abbreviated months and also precomputing/caching
1097 the names was seen to increase the performance of ls significantly. */
1098
1099 /* max number of display cells to use.
1100 As of 2018 the abmon for Arabic has entries with width 12.
1101 It doesn't make much sense to support wider than this
1102 and locales should aim for abmon entries of width <= 5. */
1103 enum { MAX_MON_WIDTH = 12 };
1104 /* abformat[RECENT][MON] is the format to use for timestamps with
1105 recentness RECENT and month MON. */
1106 enum { ABFORMAT_SIZE = 128 };
1107 static char abformat[2][12][ABFORMAT_SIZE];
1108 /* True if precomputed formats should be used. This can be false if
1109 nl_langinfo fails, if a format or month abbreviation is unusually
1110 long, or if a month abbreviation contains '%'. */
1111 static bool use_abformat;
1112
1113 /* Store into ABMON the abbreviated month names, suitably aligned.
1114 Return true if successful. */
1115
1116 static bool
abmon_init(char abmon[12][ABFORMAT_SIZE])1117 abmon_init (char abmon[12][ABFORMAT_SIZE])
1118 {
1119 #ifndef HAVE_NL_LANGINFO
1120 return false;
1121 #else
1122 size_t required_mon_width = MAX_MON_WIDTH;
1123 size_t curr_max_width;
1124 do
1125 {
1126 curr_max_width = required_mon_width;
1127 required_mon_width = 0;
1128 for (int i = 0; i < 12; i++)
1129 {
1130 size_t width = curr_max_width;
1131 char const *abbr = nl_langinfo (ABMON_1 + i);
1132 if (strchr (abbr, '%'))
1133 return false;
1134 size_t req = mbsalign (abbr, abmon[i], ABFORMAT_SIZE,
1135 &width, MBS_ALIGN_LEFT, 0);
1136 if (! (req < ABFORMAT_SIZE))
1137 return false;
1138 required_mon_width = MAX (required_mon_width, width);
1139 }
1140 }
1141 while (curr_max_width > required_mon_width);
1142
1143 return true;
1144 #endif
1145 }
1146
1147 /* Initialize ABFORMAT and USE_ABFORMAT. */
1148
1149 static void
abformat_init(void)1150 abformat_init (void)
1151 {
1152 char const *pb[2];
1153 for (int recent = 0; recent < 2; recent++)
1154 pb[recent] = first_percent_b (long_time_format[recent]);
1155 if (! (pb[0] || pb[1]))
1156 return;
1157
1158 char abmon[12][ABFORMAT_SIZE];
1159 if (! abmon_init (abmon))
1160 return;
1161
1162 for (int recent = 0; recent < 2; recent++)
1163 {
1164 char const *fmt = long_time_format[recent];
1165 for (int i = 0; i < 12; i++)
1166 {
1167 char *nfmt = abformat[recent][i];
1168 int nbytes;
1169
1170 if (! pb[recent])
1171 nbytes = snprintf (nfmt, ABFORMAT_SIZE, "%s", fmt);
1172 else
1173 {
1174 if (! (pb[recent] - fmt <= MIN (ABFORMAT_SIZE, INT_MAX)))
1175 return;
1176 int prefix_len = pb[recent] - fmt;
1177 nbytes = snprintf (nfmt, ABFORMAT_SIZE, "%.*s%s%s",
1178 prefix_len, fmt, abmon[i], pb[recent] + 2);
1179 }
1180
1181 if (! (0 <= nbytes && nbytes < ABFORMAT_SIZE))
1182 return;
1183 }
1184 }
1185
1186 use_abformat = true;
1187 }
1188
1189 static size_t
dev_ino_hash(void const * x,size_t table_size)1190 dev_ino_hash (void const *x, size_t table_size)
1191 {
1192 struct dev_ino const *p = x;
1193 return (uintmax_t) p->st_ino % table_size;
1194 }
1195
1196 static bool
dev_ino_compare(void const * x,void const * y)1197 dev_ino_compare (void const *x, void const *y)
1198 {
1199 struct dev_ino const *a = x;
1200 struct dev_ino const *b = y;
1201 return SAME_INODE (*a, *b) ? true : false;
1202 }
1203
1204 static void
dev_ino_free(void * x)1205 dev_ino_free (void *x)
1206 {
1207 free (x);
1208 }
1209
1210 /* Add the device/inode pair (P->st_dev/P->st_ino) to the set of
1211 active directories. Return true if there is already a matching
1212 entry in the table. */
1213
1214 static bool
visit_dir(dev_t dev,ino_t ino)1215 visit_dir (dev_t dev, ino_t ino)
1216 {
1217 struct dev_ino *ent;
1218 struct dev_ino *ent_from_table;
1219 bool found_match;
1220
1221 ent = xmalloc (sizeof *ent);
1222 ent->st_ino = ino;
1223 ent->st_dev = dev;
1224
1225 /* Attempt to insert this entry into the table. */
1226 ent_from_table = hash_insert (active_dir_set, ent);
1227
1228 if (ent_from_table == NULL)
1229 {
1230 /* Insertion failed due to lack of memory. */
1231 xalloc_die ();
1232 }
1233
1234 found_match = (ent_from_table != ent);
1235
1236 if (found_match)
1237 {
1238 /* ent was not inserted, so free it. */
1239 free (ent);
1240 }
1241
1242 return found_match;
1243 }
1244
1245 static void
free_pending_ent(struct pending * p)1246 free_pending_ent (struct pending *p)
1247 {
1248 free (p->name);
1249 free (p->realname);
1250 free (p);
1251 }
1252
1253 static bool
is_colored(enum indicator_no type)1254 is_colored (enum indicator_no type)
1255 {
1256 size_t len = color_indicator[type].len;
1257 char const *s = color_indicator[type].string;
1258 return ! (len == 0
1259 || (len == 1 && STRNCMP_LIT (s, "0") == 0)
1260 || (len == 2 && STRNCMP_LIT (s, "00") == 0));
1261 }
1262
1263 static void
restore_default_color(void)1264 restore_default_color (void)
1265 {
1266 put_indicator (&color_indicator[C_LEFT]);
1267 put_indicator (&color_indicator[C_RIGHT]);
1268 }
1269
1270 static void
set_normal_color(void)1271 set_normal_color (void)
1272 {
1273 if (print_with_color && is_colored (C_NORM))
1274 {
1275 put_indicator (&color_indicator[C_LEFT]);
1276 put_indicator (&color_indicator[C_NORM]);
1277 put_indicator (&color_indicator[C_RIGHT]);
1278 }
1279 }
1280
1281 /* An ordinary signal was received; arrange for the program to exit. */
1282
1283 static void
sighandler(int sig)1284 sighandler (int sig)
1285 {
1286 if (! SA_NOCLDSTOP)
1287 signal (sig, SIG_IGN);
1288 if (! interrupt_signal)
1289 interrupt_signal = sig;
1290 }
1291
1292 /* A SIGTSTP was received; arrange for the program to suspend itself. */
1293
1294 static void
stophandler(int sig)1295 stophandler (int sig)
1296 {
1297 if (! SA_NOCLDSTOP)
1298 signal (sig, stophandler);
1299 if (! interrupt_signal)
1300 stop_signal_count++;
1301 }
1302
1303 /* Process any pending signals. If signals are caught, this function
1304 should be called periodically. Ideally there should never be an
1305 unbounded amount of time when signals are not being processed.
1306 Signal handling can restore the default colors, so callers must
1307 immediately change colors after invoking this function. */
1308
1309 static void
process_signals(void)1310 process_signals (void)
1311 {
1312 while (interrupt_signal || stop_signal_count)
1313 {
1314 int sig;
1315 int stops;
1316 sigset_t oldset;
1317
1318 if (used_color)
1319 restore_default_color ();
1320 fflush (stdout);
1321
1322 sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
1323
1324 /* Reload interrupt_signal and stop_signal_count, in case a new
1325 signal was handled before sigprocmask took effect. */
1326 sig = interrupt_signal;
1327 stops = stop_signal_count;
1328
1329 /* SIGTSTP is special, since the application can receive that signal
1330 more than once. In this case, don't set the signal handler to the
1331 default. Instead, just raise the uncatchable SIGSTOP. */
1332 if (stops)
1333 {
1334 stop_signal_count = stops - 1;
1335 sig = SIGSTOP;
1336 }
1337 else
1338 signal (sig, SIG_DFL);
1339
1340 /* Exit or suspend the program. */
1341 raise (sig);
1342 sigprocmask (SIG_SETMASK, &oldset, NULL);
1343
1344 /* If execution reaches here, then the program has been
1345 continued (after being suspended). */
1346 }
1347 }
1348
1349 /* Setup signal handlers if INIT is true,
1350 otherwise restore to the default. */
1351
1352 static void
signal_setup(bool init)1353 signal_setup (bool init)
1354 {
1355 /* The signals that are trapped, and the number of such signals. */
1356 static int const sig[] =
1357 {
1358 /* This one is handled specially. */
1359 SIGTSTP,
1360
1361 /* The usual suspects. */
1362 SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM,
1363 #ifdef SIGPOLL
1364 SIGPOLL,
1365 #endif
1366 #ifdef SIGPROF
1367 SIGPROF,
1368 #endif
1369 #ifdef SIGVTALRM
1370 SIGVTALRM,
1371 #endif
1372 #ifdef SIGXCPU
1373 SIGXCPU,
1374 #endif
1375 #ifdef SIGXFSZ
1376 SIGXFSZ,
1377 #endif
1378 };
1379 enum { nsigs = ARRAY_CARDINALITY (sig) };
1380
1381 #if ! SA_NOCLDSTOP
1382 static bool caught_sig[nsigs];
1383 #endif
1384
1385 int j;
1386
1387 if (init)
1388 {
1389 #if SA_NOCLDSTOP
1390 struct sigaction act;
1391
1392 sigemptyset (&caught_signals);
1393 for (j = 0; j < nsigs; j++)
1394 {
1395 sigaction (sig[j], NULL, &act);
1396 if (act.sa_handler != SIG_IGN)
1397 sigaddset (&caught_signals, sig[j]);
1398 }
1399
1400 act.sa_mask = caught_signals;
1401 act.sa_flags = SA_RESTART;
1402
1403 for (j = 0; j < nsigs; j++)
1404 if (sigismember (&caught_signals, sig[j]))
1405 {
1406 act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler;
1407 sigaction (sig[j], &act, NULL);
1408 }
1409 #else
1410 for (j = 0; j < nsigs; j++)
1411 {
1412 caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN);
1413 if (caught_sig[j])
1414 {
1415 signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler);
1416 siginterrupt (sig[j], 0);
1417 }
1418 }
1419 #endif
1420 }
1421 else /* restore. */
1422 {
1423 #if SA_NOCLDSTOP
1424 for (j = 0; j < nsigs; j++)
1425 if (sigismember (&caught_signals, sig[j]))
1426 signal (sig[j], SIG_DFL);
1427 #else
1428 for (j = 0; j < nsigs; j++)
1429 if (caught_sig[j])
1430 signal (sig[j], SIG_DFL);
1431 #endif
1432 }
1433 }
1434
1435 static inline void
signal_init(void)1436 signal_init (void)
1437 {
1438 signal_setup (true);
1439 }
1440
1441 static inline void
signal_restore(void)1442 signal_restore (void)
1443 {
1444 signal_setup (false);
1445 }
1446
1447 int
main(int argc,char ** argv)1448 main (int argc, char **argv)
1449 {
1450 int i;
1451 struct pending *thispend;
1452 int n_files;
1453
1454 initialize_main (&argc, &argv);
1455 set_program_name (argv[0]);
1456 setlocale (LC_ALL, "");
1457 bindtextdomain (PACKAGE, LOCALEDIR);
1458 textdomain (PACKAGE);
1459
1460 initialize_exit_failure (LS_FAILURE);
1461 atexit (close_stdout);
1462
1463 assert (ARRAY_CARDINALITY (color_indicator) + 1
1464 == ARRAY_CARDINALITY (indicator_name));
1465
1466 exit_status = EXIT_SUCCESS;
1467 print_dir_name = true;
1468 pending_dirs = NULL;
1469
1470 current_time.tv_sec = TYPE_MINIMUM (time_t);
1471 current_time.tv_nsec = -1;
1472
1473 i = decode_switches (argc, argv);
1474
1475 if (print_with_color)
1476 parse_ls_color ();
1477
1478 /* Test print_with_color again, because the call to parse_ls_color
1479 may have just reset it -- e.g., if LS_COLORS is invalid. */
1480 if (print_with_color)
1481 {
1482 /* Avoid following symbolic links when possible. */
1483 if (is_colored (C_ORPHAN)
1484 || (is_colored (C_EXEC) && color_symlink_as_referent)
1485 || (is_colored (C_MISSING) && format == long_format))
1486 check_symlink_color = true;
1487 }
1488
1489 if (dereference == DEREF_UNDEFINED)
1490 dereference = ((immediate_dirs
1491 || indicator_style == classify
1492 || format == long_format)
1493 ? DEREF_NEVER
1494 : DEREF_COMMAND_LINE_SYMLINK_TO_DIR);
1495
1496 /* When using -R, initialize a data structure we'll use to
1497 detect any directory cycles. */
1498 if (recursive)
1499 {
1500 active_dir_set = hash_initialize (INITIAL_TABLE_SIZE, NULL,
1501 dev_ino_hash,
1502 dev_ino_compare,
1503 dev_ino_free);
1504 if (active_dir_set == NULL)
1505 xalloc_die ();
1506
1507 obstack_init (&dev_ino_obstack);
1508 }
1509
1510 localtz = tzalloc (getenv ("TZ"));
1511
1512 format_needs_stat = sort_type == sort_time || sort_type == sort_size
1513 || format == long_format
1514 || print_scontext
1515 || print_block_size;
1516 format_needs_type = (! format_needs_stat
1517 && (recursive
1518 || print_with_color
1519 || indicator_style != none
1520 || directories_first));
1521
1522 if (dired)
1523 {
1524 obstack_init (&dired_obstack);
1525 obstack_init (&subdired_obstack);
1526 }
1527
1528 if (print_hyperlink)
1529 {
1530 file_escape_init ();
1531
1532 hostname = xgethostname ();
1533 /* The hostname is generally ignored,
1534 so ignore failures obtaining it. */
1535 if (! hostname)
1536 hostname = "";
1537 }
1538
1539 cwd_n_alloc = 100;
1540 cwd_file = xnmalloc (cwd_n_alloc, sizeof *cwd_file);
1541 cwd_n_used = 0;
1542
1543 clear_files ();
1544
1545 n_files = argc - i;
1546
1547 if (n_files <= 0)
1548 {
1549 if (immediate_dirs)
1550 gobble_file (".", directory, NOT_AN_INODE_NUMBER, true, "");
1551 else
1552 queue_directory (".", NULL, true);
1553 }
1554 else
1555 do
1556 gobble_file (argv[i++], unknown, NOT_AN_INODE_NUMBER, true, "");
1557 while (i < argc);
1558
1559 if (cwd_n_used)
1560 {
1561 sort_files ();
1562 if (!immediate_dirs)
1563 extract_dirs_from_files (NULL, true);
1564 /* 'cwd_n_used' might be zero now. */
1565 }
1566
1567 /* In the following if/else blocks, it is sufficient to test 'pending_dirs'
1568 (and not pending_dirs->name) because there may be no markers in the queue
1569 at this point. A marker may be enqueued when extract_dirs_from_files is
1570 called with a non-empty string or via print_dir. */
1571 if (cwd_n_used)
1572 {
1573 print_current_files ();
1574 if (pending_dirs)
1575 DIRED_PUTCHAR ('\n');
1576 }
1577 else if (n_files <= 1 && pending_dirs && pending_dirs->next == 0)
1578 print_dir_name = false;
1579
1580 while (pending_dirs)
1581 {
1582 thispend = pending_dirs;
1583 pending_dirs = pending_dirs->next;
1584
1585 if (LOOP_DETECT)
1586 {
1587 if (thispend->name == NULL)
1588 {
1589 /* thispend->name == NULL means this is a marker entry
1590 indicating we've finished processing the directory.
1591 Use its dev/ino numbers to remove the corresponding
1592 entry from the active_dir_set hash table. */
1593 struct dev_ino di = dev_ino_pop ();
1594 struct dev_ino *found = hash_delete (active_dir_set, &di);
1595 /* ASSERT_MATCHING_DEV_INO (thispend->realname, di); */
1596 assert (found);
1597 dev_ino_free (found);
1598 free_pending_ent (thispend);
1599 continue;
1600 }
1601 }
1602
1603 print_dir (thispend->name, thispend->realname,
1604 thispend->command_line_arg);
1605
1606 free_pending_ent (thispend);
1607 print_dir_name = true;
1608 }
1609
1610 if (print_with_color && used_color)
1611 {
1612 int j;
1613
1614 /* Skip the restore when it would be a no-op, i.e.,
1615 when left is "\033[" and right is "m". */
1616 if (!(color_indicator[C_LEFT].len == 2
1617 && memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0
1618 && color_indicator[C_RIGHT].len == 1
1619 && color_indicator[C_RIGHT].string[0] == 'm'))
1620 restore_default_color ();
1621
1622 fflush (stdout);
1623
1624 signal_restore ();
1625
1626 /* Act on any signals that arrived before the default was restored.
1627 This can process signals out of order, but there doesn't seem to
1628 be an easy way to do them in order, and the order isn't that
1629 important anyway. */
1630 for (j = stop_signal_count; j; j--)
1631 raise (SIGSTOP);
1632 j = interrupt_signal;
1633 if (j)
1634 raise (j);
1635 }
1636
1637 if (dired)
1638 {
1639 /* No need to free these since we're about to exit. */
1640 dired_dump_obstack ("//DIRED//", &dired_obstack);
1641 dired_dump_obstack ("//SUBDIRED//", &subdired_obstack);
1642 printf ("//DIRED-OPTIONS// --quoting-style=%s\n",
1643 quoting_style_args[get_quoting_style (filename_quoting_options)]);
1644 }
1645
1646 if (LOOP_DETECT)
1647 {
1648 assert (hash_get_n_entries (active_dir_set) == 0);
1649 hash_free (active_dir_set);
1650 }
1651
1652 return exit_status;
1653 }
1654
1655 /* Set the line length to the value given by SPEC. Return true if
1656 successful. 0 means no limit on line length. */
1657
1658 static bool
set_line_length(char const * spec)1659 set_line_length (char const *spec)
1660 {
1661 uintmax_t val;
1662
1663 /* Treat too-large values as if they were SIZE_MAX, which is
1664 effectively infinity. */
1665 switch (xstrtoumax (spec, NULL, 0, &val, ""))
1666 {
1667 case LONGINT_OK:
1668 line_length = MIN (val, SIZE_MAX);
1669 return true;
1670
1671 case LONGINT_OVERFLOW:
1672 line_length = SIZE_MAX;
1673 return true;
1674
1675 default:
1676 return false;
1677 }
1678 }
1679
1680 /* Set all the option flags according to the switches specified.
1681 Return the index of the first non-option argument. */
1682
1683 static int
decode_switches(int argc,char ** argv)1684 decode_switches (int argc, char **argv)
1685 {
1686 char *time_style_option = NULL;
1687
1688 bool sort_type_specified = false;
1689 bool kibibytes_specified = false;
1690
1691 qmark_funny_chars = false;
1692
1693 /* initialize all switches to default settings */
1694
1695 switch (ls_mode)
1696 {
1697 case LS_MULTI_COL:
1698 /* This is for the 'dir' program. */
1699 format = many_per_line;
1700 set_quoting_style (NULL, escape_quoting_style);
1701 break;
1702
1703 case LS_LONG_FORMAT:
1704 /* This is for the 'vdir' program. */
1705 format = long_format;
1706 set_quoting_style (NULL, escape_quoting_style);
1707 break;
1708
1709 case LS_LS:
1710 /* This is for the 'ls' program. */
1711 if (isatty (STDOUT_FILENO))
1712 {
1713 format = many_per_line;
1714 set_quoting_style (NULL, shell_escape_quoting_style);
1715 /* See description of qmark_funny_chars, above. */
1716 qmark_funny_chars = true;
1717 }
1718 else
1719 {
1720 format = one_per_line;
1721 qmark_funny_chars = false;
1722 }
1723 break;
1724
1725 default:
1726 abort ();
1727 }
1728
1729 time_type = time_mtime;
1730 sort_type = sort_name;
1731 sort_reverse = false;
1732 numeric_ids = false;
1733 print_block_size = false;
1734 indicator_style = none;
1735 print_inode = false;
1736 dereference = DEREF_UNDEFINED;
1737 recursive = false;
1738 immediate_dirs = false;
1739 ignore_mode = IGNORE_DEFAULT;
1740 ignore_patterns = NULL;
1741 hide_patterns = NULL;
1742 print_scontext = false;
1743
1744 getenv_quoting_style ();
1745
1746 line_length = 80;
1747 {
1748 char const *p = getenv ("COLUMNS");
1749 if (p && *p && ! set_line_length (p))
1750 error (0, 0,
1751 _("ignoring invalid width in environment variable COLUMNS: %s"),
1752 quote (p));
1753 }
1754
1755 #ifdef TIOCGWINSZ
1756 {
1757 struct winsize ws;
1758
1759 if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1
1760 && 0 < ws.ws_col && ws.ws_col == (size_t) ws.ws_col)
1761 line_length = ws.ws_col;
1762 }
1763 #endif
1764
1765 {
1766 char const *p = getenv ("TABSIZE");
1767 tabsize = 8;
1768 if (p)
1769 {
1770 unsigned long int tmp_ulong;
1771 if (xstrtoul (p, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK
1772 && tmp_ulong <= SIZE_MAX)
1773 {
1774 tabsize = tmp_ulong;
1775 }
1776 else
1777 {
1778 error (0, 0,
1779 _("ignoring invalid tab size in environment variable TABSIZE: %s"),
1780 quote (p));
1781 }
1782 }
1783 }
1784
1785 while (true)
1786 {
1787 int oi = -1;
1788 int c = getopt_long (argc, argv,
1789 "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1",
1790 long_options, &oi);
1791 if (c == -1)
1792 break;
1793
1794 switch (c)
1795 {
1796 case 'a':
1797 ignore_mode = IGNORE_MINIMAL;
1798 break;
1799
1800 case 'b':
1801 set_quoting_style (NULL, escape_quoting_style);
1802 break;
1803
1804 case 'c':
1805 time_type = time_ctime;
1806 break;
1807
1808 case 'd':
1809 immediate_dirs = true;
1810 break;
1811
1812 case 'f':
1813 /* Same as enabling -a -U and disabling -l -s. */
1814 ignore_mode = IGNORE_MINIMAL;
1815 sort_type = sort_none;
1816 sort_type_specified = true;
1817 /* disable -l */
1818 if (format == long_format)
1819 format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line);
1820 print_block_size = false; /* disable -s */
1821 print_with_color = false; /* disable --color */
1822 print_hyperlink = false; /* disable --hyperlink */
1823 break;
1824
1825 case FILE_TYPE_INDICATOR_OPTION: /* --file-type */
1826 indicator_style = file_type;
1827 break;
1828
1829 case 'g':
1830 format = long_format;
1831 print_owner = false;
1832 break;
1833
1834 case 'h':
1835 file_human_output_opts = human_output_opts =
1836 human_autoscale | human_SI | human_base_1024;
1837 file_output_block_size = output_block_size = 1;
1838 break;
1839
1840 case 'i':
1841 print_inode = true;
1842 break;
1843
1844 case 'k':
1845 kibibytes_specified = true;
1846 break;
1847
1848 case 'l':
1849 format = long_format;
1850 break;
1851
1852 case 'm':
1853 format = with_commas;
1854 break;
1855
1856 case 'n':
1857 numeric_ids = true;
1858 format = long_format;
1859 break;
1860
1861 case 'o': /* Just like -l, but don't display group info. */
1862 format = long_format;
1863 print_group = false;
1864 break;
1865
1866 case 'p':
1867 indicator_style = slash;
1868 break;
1869
1870 case 'q':
1871 qmark_funny_chars = true;
1872 break;
1873
1874 case 'r':
1875 sort_reverse = true;
1876 break;
1877
1878 case 's':
1879 print_block_size = true;
1880 break;
1881
1882 case 't':
1883 sort_type = sort_time;
1884 sort_type_specified = true;
1885 break;
1886
1887 case 'u':
1888 time_type = time_atime;
1889 break;
1890
1891 case 'v':
1892 sort_type = sort_version;
1893 sort_type_specified = true;
1894 break;
1895
1896 case 'w':
1897 if (! set_line_length (optarg))
1898 die (LS_FAILURE, 0, "%s: %s", _("invalid line width"),
1899 quote (optarg));
1900 break;
1901
1902 case 'x':
1903 format = horizontal;
1904 break;
1905
1906 case 'A':
1907 ignore_mode = IGNORE_DOT_AND_DOTDOT;
1908 break;
1909
1910 case 'B':
1911 add_ignore_pattern ("*~");
1912 add_ignore_pattern (".*~");
1913 break;
1914
1915 case 'C':
1916 format = many_per_line;
1917 break;
1918
1919 case 'D':
1920 dired = true;
1921 break;
1922
1923 case 'F':
1924 indicator_style = classify;
1925 break;
1926
1927 case 'G': /* inhibit display of group info */
1928 print_group = false;
1929 break;
1930
1931 case 'H':
1932 dereference = DEREF_COMMAND_LINE_ARGUMENTS;
1933 break;
1934
1935 case DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION:
1936 dereference = DEREF_COMMAND_LINE_SYMLINK_TO_DIR;
1937 break;
1938
1939 case 'I':
1940 add_ignore_pattern (optarg);
1941 break;
1942
1943 case 'L':
1944 dereference = DEREF_ALWAYS;
1945 break;
1946
1947 case 'N':
1948 set_quoting_style (NULL, literal_quoting_style);
1949 break;
1950
1951 case 'Q':
1952 set_quoting_style (NULL, c_quoting_style);
1953 break;
1954
1955 case 'R':
1956 recursive = true;
1957 break;
1958
1959 case 'S':
1960 sort_type = sort_size;
1961 sort_type_specified = true;
1962 break;
1963
1964 case 'T':
1965 tabsize = xnumtoumax (optarg, 0, 0, SIZE_MAX, "",
1966 _("invalid tab size"), LS_FAILURE);
1967 break;
1968
1969 case 'U':
1970 sort_type = sort_none;
1971 sort_type_specified = true;
1972 break;
1973
1974 case 'X':
1975 sort_type = sort_extension;
1976 sort_type_specified = true;
1977 break;
1978
1979 case '1':
1980 /* -1 has no effect after -l. */
1981 if (format != long_format)
1982 format = one_per_line;
1983 break;
1984
1985 case AUTHOR_OPTION:
1986 print_author = true;
1987 break;
1988
1989 case HIDE_OPTION:
1990 {
1991 struct ignore_pattern *hide = xmalloc (sizeof *hide);
1992 hide->pattern = optarg;
1993 hide->next = hide_patterns;
1994 hide_patterns = hide;
1995 }
1996 break;
1997
1998 case SORT_OPTION:
1999 sort_type = XARGMATCH ("--sort", optarg, sort_args, sort_types);
2000 sort_type_specified = true;
2001 break;
2002
2003 case GROUP_DIRECTORIES_FIRST_OPTION:
2004 directories_first = true;
2005 break;
2006
2007 case TIME_OPTION:
2008 time_type = XARGMATCH ("--time", optarg, time_args, time_types);
2009 break;
2010
2011 case FORMAT_OPTION:
2012 format = XARGMATCH ("--format", optarg, format_args, format_types);
2013 break;
2014
2015 case FULL_TIME_OPTION:
2016 format = long_format;
2017 time_style_option = bad_cast ("full-iso");
2018 break;
2019
2020 case COLOR_OPTION:
2021 {
2022 int i;
2023 if (optarg)
2024 i = XARGMATCH ("--color", optarg, when_args, when_types);
2025 else
2026 /* Using --color with no argument is equivalent to using
2027 --color=always. */
2028 i = when_always;
2029
2030 print_with_color = (i == when_always
2031 || (i == when_if_tty
2032 && isatty (STDOUT_FILENO)));
2033
2034 if (print_with_color)
2035 {
2036 /* Don't use TAB characters in output. Some terminal
2037 emulators can't handle the combination of tabs and
2038 color codes on the same line. */
2039 tabsize = 0;
2040 }
2041 break;
2042 }
2043
2044 case HYPERLINK_OPTION:
2045 {
2046 int i;
2047 if (optarg)
2048 i = XARGMATCH ("--hyperlink", optarg, when_args, when_types);
2049 else
2050 /* Using --hyperlink with no argument is equivalent to using
2051 --hyperlink=always. */
2052 i = when_always;
2053
2054 print_hyperlink = (i == when_always
2055 || (i == when_if_tty
2056 && isatty (STDOUT_FILENO)));
2057 break;
2058 }
2059
2060 case INDICATOR_STYLE_OPTION:
2061 indicator_style = XARGMATCH ("--indicator-style", optarg,
2062 indicator_style_args,
2063 indicator_style_types);
2064 break;
2065
2066 case QUOTING_STYLE_OPTION:
2067 set_quoting_style (NULL,
2068 XARGMATCH ("--quoting-style", optarg,
2069 quoting_style_args,
2070 quoting_style_vals));
2071 break;
2072
2073 case TIME_STYLE_OPTION:
2074 time_style_option = optarg;
2075 break;
2076
2077 case SHOW_CONTROL_CHARS_OPTION:
2078 qmark_funny_chars = false;
2079 break;
2080
2081 case BLOCK_SIZE_OPTION:
2082 {
2083 enum strtol_error e = human_options (optarg, &human_output_opts,
2084 &output_block_size);
2085 if (e != LONGINT_OK)
2086 xstrtol_fatal (e, oi, 0, long_options, optarg);
2087 file_human_output_opts = human_output_opts;
2088 file_output_block_size = output_block_size;
2089 }
2090 break;
2091
2092 case SI_OPTION:
2093 file_human_output_opts = human_output_opts =
2094 human_autoscale | human_SI;
2095 file_output_block_size = output_block_size = 1;
2096 break;
2097
2098 case 'Z':
2099 print_scontext = true;
2100 break;
2101
2102 case_GETOPT_HELP_CHAR;
2103
2104 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
2105
2106 default:
2107 usage (LS_FAILURE);
2108 }
2109 }
2110
2111 if (! output_block_size)
2112 {
2113 char const *ls_block_size = getenv ("LS_BLOCK_SIZE");
2114 human_options (ls_block_size,
2115 &human_output_opts, &output_block_size);
2116 if (ls_block_size || getenv ("BLOCK_SIZE"))
2117 {
2118 file_human_output_opts = human_output_opts;
2119 file_output_block_size = output_block_size;
2120 }
2121 if (kibibytes_specified)
2122 {
2123 human_output_opts = 0;
2124 output_block_size = 1024;
2125 }
2126 }
2127
2128 /* Determine the max possible number of display columns. */
2129 max_idx = line_length / MIN_COLUMN_WIDTH;
2130 /* Account for first display column not having a separator,
2131 or line_lengths shorter than MIN_COLUMN_WIDTH. */
2132 max_idx += line_length % MIN_COLUMN_WIDTH != 0;
2133
2134 enum quoting_style qs = get_quoting_style (NULL);
2135 align_variable_outer_quotes = format != with_commas
2136 && format != one_per_line
2137 && (line_length || format == long_format)
2138 && (qs == shell_quoting_style
2139 || qs == shell_escape_quoting_style
2140 || qs == c_maybe_quoting_style);
2141 filename_quoting_options = clone_quoting_options (NULL);
2142 if (qs == escape_quoting_style)
2143 set_char_quoting (filename_quoting_options, ' ', 1);
2144 if (file_type <= indicator_style)
2145 {
2146 char const *p;
2147 for (p = &"*=>@|"[indicator_style - file_type]; *p; p++)
2148 set_char_quoting (filename_quoting_options, *p, 1);
2149 }
2150
2151 dirname_quoting_options = clone_quoting_options (NULL);
2152 set_char_quoting (dirname_quoting_options, ':', 1);
2153
2154 /* --dired is meaningful only with --format=long (-l).
2155 Otherwise, ignore it. FIXME: warn about this?
2156 Alternatively, make --dired imply --format=long? */
2157 if (dired && (format != long_format || print_hyperlink))
2158 dired = false;
2159
2160 /* If -c or -u is specified and not -l (or any other option that implies -l),
2161 and no sort-type was specified, then sort by the ctime (-c) or atime (-u).
2162 The behavior of ls when using either -c or -u but with neither -l nor -t
2163 appears to be unspecified by POSIX. So, with GNU ls, '-u' alone means
2164 sort by atime (this is the one that's not specified by the POSIX spec),
2165 -lu means show atime and sort by name, -lut means show atime and sort
2166 by atime. */
2167
2168 if ((time_type == time_ctime || time_type == time_atime)
2169 && !sort_type_specified && format != long_format)
2170 {
2171 sort_type = sort_time;
2172 }
2173
2174 if (format == long_format)
2175 {
2176 char *style = time_style_option;
2177 static char const posix_prefix[] = "posix-";
2178
2179 if (! style)
2180 if (! (style = getenv ("TIME_STYLE")))
2181 style = bad_cast ("locale");
2182
2183 while (STREQ_LEN (style, posix_prefix, sizeof posix_prefix - 1))
2184 {
2185 if (! hard_locale (LC_TIME))
2186 return optind;
2187 style += sizeof posix_prefix - 1;
2188 }
2189
2190 if (*style == '+')
2191 {
2192 char *p0 = style + 1;
2193 char *p1 = strchr (p0, '\n');
2194 if (! p1)
2195 p1 = p0;
2196 else
2197 {
2198 if (strchr (p1 + 1, '\n'))
2199 die (LS_FAILURE, 0, _("invalid time style format %s"),
2200 quote (p0));
2201 *p1++ = '\0';
2202 }
2203 long_time_format[0] = p0;
2204 long_time_format[1] = p1;
2205 }
2206 else
2207 {
2208 ptrdiff_t res = argmatch (style, time_style_args,
2209 (char const *) time_style_types,
2210 sizeof (*time_style_types));
2211 if (res < 0)
2212 {
2213 /* This whole block used to be a simple use of XARGMATCH.
2214 but that didn't print the "posix-"-prefixed variants or
2215 the "+"-prefixed format string option upon failure. */
2216 argmatch_invalid ("time style", style, res);
2217
2218 /* The following is a manual expansion of argmatch_valid,
2219 but with the added "+ ..." description and the [posix-]
2220 prefixes prepended. Note that this simplification works
2221 only because all four existing time_style_types values
2222 are distinct. */
2223 fputs (_("Valid arguments are:\n"), stderr);
2224 char const *const *p = time_style_args;
2225 while (*p)
2226 fprintf (stderr, " - [posix-]%s\n", *p++);
2227 fputs (_(" - +FORMAT (e.g., +%H:%M) for a 'date'-style"
2228 " format\n"), stderr);
2229 usage (LS_FAILURE);
2230 }
2231 switch (res)
2232 {
2233 case full_iso_time_style:
2234 long_time_format[0] = long_time_format[1] =
2235 "%Y-%m-%d %H:%M:%S.%N %z";
2236 break;
2237
2238 case long_iso_time_style:
2239 long_time_format[0] = long_time_format[1] = "%Y-%m-%d %H:%M";
2240 break;
2241
2242 case iso_time_style:
2243 long_time_format[0] = "%Y-%m-%d ";
2244 long_time_format[1] = "%m-%d %H:%M";
2245 break;
2246
2247 case locale_time_style:
2248 if (hard_locale (LC_TIME))
2249 {
2250 for (int i = 0; i < 2; i++)
2251 long_time_format[i] =
2252 dcgettext (NULL, long_time_format[i], LC_TIME);
2253 }
2254 }
2255 }
2256
2257 abformat_init ();
2258 }
2259
2260 return optind;
2261 }
2262
2263 /* Parse a string as part of the LS_COLORS variable; this may involve
2264 decoding all kinds of escape characters. If equals_end is set an
2265 unescaped equal sign ends the string, otherwise only a : or \0
2266 does. Set *OUTPUT_COUNT to the number of bytes output. Return
2267 true if successful.
2268
2269 The resulting string is *not* null-terminated, but may contain
2270 embedded nulls.
2271
2272 Note that both dest and src are char **; on return they point to
2273 the first free byte after the array and the character that ended
2274 the input string, respectively. */
2275
2276 static bool
get_funky_string(char ** dest,const char ** src,bool equals_end,size_t * output_count)2277 get_funky_string (char **dest, const char **src, bool equals_end,
2278 size_t *output_count)
2279 {
2280 char num; /* For numerical codes */
2281 size_t count; /* Something to count with */
2282 enum {
2283 ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR
2284 } state;
2285 const char *p;
2286 char *q;
2287
2288 p = *src; /* We don't want to double-indirect */
2289 q = *dest; /* the whole darn time. */
2290
2291 count = 0; /* No characters counted in yet. */
2292 num = 0;
2293
2294 state = ST_GND; /* Start in ground state. */
2295 while (state < ST_END)
2296 {
2297 switch (state)
2298 {
2299 case ST_GND: /* Ground state (no escapes) */
2300 switch (*p)
2301 {
2302 case ':':
2303 case '\0':
2304 state = ST_END; /* End of string */
2305 break;
2306 case '\\':
2307 state = ST_BACKSLASH; /* Backslash escape sequence */
2308 ++p;
2309 break;
2310 case '^':
2311 state = ST_CARET; /* Caret escape */
2312 ++p;
2313 break;
2314 case '=':
2315 if (equals_end)
2316 {
2317 state = ST_END; /* End */
2318 break;
2319 }
2320 FALLTHROUGH;
2321 default:
2322 *(q++) = *(p++);
2323 ++count;
2324 break;
2325 }
2326 break;
2327
2328 case ST_BACKSLASH: /* Backslash escaped character */
2329 switch (*p)
2330 {
2331 case '0':
2332 case '1':
2333 case '2':
2334 case '3':
2335 case '4':
2336 case '5':
2337 case '6':
2338 case '7':
2339 state = ST_OCTAL; /* Octal sequence */
2340 num = *p - '0';
2341 break;
2342 case 'x':
2343 case 'X':
2344 state = ST_HEX; /* Hex sequence */
2345 num = 0;
2346 break;
2347 case 'a': /* Bell */
2348 num = '\a';
2349 break;
2350 case 'b': /* Backspace */
2351 num = '\b';
2352 break;
2353 case 'e': /* Escape */
2354 num = 27;
2355 break;
2356 case 'f': /* Form feed */
2357 num = '\f';
2358 break;
2359 case 'n': /* Newline */
2360 num = '\n';
2361 break;
2362 case 'r': /* Carriage return */
2363 num = '\r';
2364 break;
2365 case 't': /* Tab */
2366 num = '\t';
2367 break;
2368 case 'v': /* Vtab */
2369 num = '\v';
2370 break;
2371 case '?': /* Delete */
2372 num = 127;
2373 break;
2374 case '_': /* Space */
2375 num = ' ';
2376 break;
2377 case '\0': /* End of string */
2378 state = ST_ERROR; /* Error! */
2379 break;
2380 default: /* Escaped character like \ ^ : = */
2381 num = *p;
2382 break;
2383 }
2384 if (state == ST_BACKSLASH)
2385 {
2386 *(q++) = num;
2387 ++count;
2388 state = ST_GND;
2389 }
2390 ++p;
2391 break;
2392
2393 case ST_OCTAL: /* Octal sequence */
2394 if (*p < '0' || *p > '7')
2395 {
2396 *(q++) = num;
2397 ++count;
2398 state = ST_GND;
2399 }
2400 else
2401 num = (num << 3) + (*(p++) - '0');
2402 break;
2403
2404 case ST_HEX: /* Hex sequence */
2405 switch (*p)
2406 {
2407 case '0':
2408 case '1':
2409 case '2':
2410 case '3':
2411 case '4':
2412 case '5':
2413 case '6':
2414 case '7':
2415 case '8':
2416 case '9':
2417 num = (num << 4) + (*(p++) - '0');
2418 break;
2419 case 'a':
2420 case 'b':
2421 case 'c':
2422 case 'd':
2423 case 'e':
2424 case 'f':
2425 num = (num << 4) + (*(p++) - 'a') + 10;
2426 break;
2427 case 'A':
2428 case 'B':
2429 case 'C':
2430 case 'D':
2431 case 'E':
2432 case 'F':
2433 num = (num << 4) + (*(p++) - 'A') + 10;
2434 break;
2435 default:
2436 *(q++) = num;
2437 ++count;
2438 state = ST_GND;
2439 break;
2440 }
2441 break;
2442
2443 case ST_CARET: /* Caret escape */
2444 state = ST_GND; /* Should be the next state... */
2445 if (*p >= '@' && *p <= '~')
2446 {
2447 *(q++) = *(p++) & 037;
2448 ++count;
2449 }
2450 else if (*p == '?')
2451 {
2452 *(q++) = 127;
2453 ++count;
2454 }
2455 else
2456 state = ST_ERROR;
2457 break;
2458
2459 default:
2460 abort ();
2461 }
2462 }
2463
2464 *dest = q;
2465 *src = p;
2466 *output_count = count;
2467
2468 return state != ST_ERROR;
2469 }
2470
2471 enum parse_state
2472 {
2473 PS_START = 1,
2474 PS_2,
2475 PS_3,
2476 PS_4,
2477 PS_DONE,
2478 PS_FAIL
2479 };
2480
2481
2482 /* Check if the content of TERM is a valid name in dircolors. */
2483
2484 static bool
known_term_type(void)2485 known_term_type (void)
2486 {
2487 char const *term = getenv ("TERM");
2488 if (! term || ! *term)
2489 return false;
2490
2491 char const *line = G_line;
2492 while (line - G_line < sizeof (G_line))
2493 {
2494 if (STRNCMP_LIT (line, "TERM ") == 0)
2495 {
2496 if (fnmatch (line + 5, term, 0) == 0)
2497 return true;
2498 }
2499 line += strlen (line) + 1;
2500 }
2501
2502 return false;
2503 }
2504
2505 static void
parse_ls_color(void)2506 parse_ls_color (void)
2507 {
2508 const char *p; /* Pointer to character being parsed */
2509 char *buf; /* color_buf buffer pointer */
2510 int ind_no; /* Indicator number */
2511 char label[3]; /* Indicator label */
2512 struct color_ext_type *ext; /* Extension we are working on */
2513
2514 if ((p = getenv ("LS_COLORS")) == NULL || *p == '\0')
2515 {
2516 /* LS_COLORS takes precedence, but if that's not set then
2517 honor the COLORTERM and TERM env variables so that
2518 we only go with the internal ANSI color codes if the
2519 former is non empty or the latter is set to a known value. */
2520 char const *colorterm = getenv ("COLORTERM");
2521 if (! (colorterm && *colorterm) && ! known_term_type ())
2522 print_with_color = false;
2523 return;
2524 }
2525
2526 ext = NULL;
2527 strcpy (label, "??");
2528
2529 /* This is an overly conservative estimate, but any possible
2530 LS_COLORS string will *not* generate a color_buf longer than
2531 itself, so it is a safe way of allocating a buffer in
2532 advance. */
2533 buf = color_buf = xstrdup (p);
2534
2535 enum parse_state state = PS_START;
2536 while (true)
2537 {
2538 switch (state)
2539 {
2540 case PS_START: /* First label character */
2541 switch (*p)
2542 {
2543 case ':':
2544 ++p;
2545 break;
2546
2547 case '*':
2548 /* Allocate new extension block and add to head of
2549 linked list (this way a later definition will
2550 override an earlier one, which can be useful for
2551 having terminal-specific defs override global). */
2552
2553 ext = xmalloc (sizeof *ext);
2554 ext->next = color_ext_list;
2555 color_ext_list = ext;
2556
2557 ++p;
2558 ext->ext.string = buf;
2559
2560 state = (get_funky_string (&buf, &p, true, &ext->ext.len)
2561 ? PS_4 : PS_FAIL);
2562 break;
2563
2564 case '\0':
2565 state = PS_DONE; /* Done! */
2566 goto done;
2567
2568 default: /* Assume it is file type label */
2569 label[0] = *(p++);
2570 state = PS_2;
2571 break;
2572 }
2573 break;
2574
2575 case PS_2: /* Second label character */
2576 if (*p)
2577 {
2578 label[1] = *(p++);
2579 state = PS_3;
2580 }
2581 else
2582 state = PS_FAIL; /* Error */
2583 break;
2584
2585 case PS_3: /* Equal sign after indicator label */
2586 state = PS_FAIL; /* Assume failure... */
2587 if (*(p++) == '=')/* It *should* be... */
2588 {
2589 for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no)
2590 {
2591 if (STREQ (label, indicator_name[ind_no]))
2592 {
2593 color_indicator[ind_no].string = buf;
2594 state = (get_funky_string (&buf, &p, false,
2595 &color_indicator[ind_no].len)
2596 ? PS_START : PS_FAIL);
2597 break;
2598 }
2599 }
2600 if (state == PS_FAIL)
2601 error (0, 0, _("unrecognized prefix: %s"), quote (label));
2602 }
2603 break;
2604
2605 case PS_4: /* Equal sign after *.ext */
2606 if (*(p++) == '=')
2607 {
2608 ext->seq.string = buf;
2609 state = (get_funky_string (&buf, &p, false, &ext->seq.len)
2610 ? PS_START : PS_FAIL);
2611 }
2612 else
2613 state = PS_FAIL;
2614 break;
2615
2616 case PS_FAIL:
2617 goto done;
2618
2619 default:
2620 abort ();
2621 }
2622 }
2623 done:
2624
2625 if (state == PS_FAIL)
2626 {
2627 struct color_ext_type *e;
2628 struct color_ext_type *e2;
2629
2630 error (0, 0,
2631 _("unparsable value for LS_COLORS environment variable"));
2632 free (color_buf);
2633 for (e = color_ext_list; e != NULL; /* empty */)
2634 {
2635 e2 = e;
2636 e = e->next;
2637 free (e2);
2638 }
2639 print_with_color = false;
2640 }
2641
2642 if (color_indicator[C_LINK].len == 6
2643 && !STRNCMP_LIT (color_indicator[C_LINK].string, "target"))
2644 color_symlink_as_referent = true;
2645 }
2646
2647 /* Set the quoting style default if the environment variable
2648 QUOTING_STYLE is set. */
2649
2650 static void
getenv_quoting_style(void)2651 getenv_quoting_style (void)
2652 {
2653 char const *q_style = getenv ("QUOTING_STYLE");
2654 if (q_style)
2655 {
2656 int i = ARGMATCH (q_style, quoting_style_args, quoting_style_vals);
2657 if (0 <= i)
2658 set_quoting_style (NULL, quoting_style_vals[i]);
2659 else
2660 error (0, 0,
2661 _("ignoring invalid value of environment variable QUOTING_STYLE: %s"),
2662 quote (q_style));
2663 }
2664 }
2665
2666 /* Set the exit status to report a failure. If SERIOUS, it is a
2667 serious failure; otherwise, it is merely a minor problem. */
2668
2669 static void
set_exit_status(bool serious)2670 set_exit_status (bool serious)
2671 {
2672 if (serious)
2673 exit_status = LS_FAILURE;
2674 else if (exit_status == EXIT_SUCCESS)
2675 exit_status = LS_MINOR_PROBLEM;
2676 }
2677
2678 /* Assuming a failure is serious if SERIOUS, use the printf-style
2679 MESSAGE to report the failure to access a file named FILE. Assume
2680 errno is set appropriately for the failure. */
2681
2682 static void
file_failure(bool serious,char const * message,char const * file)2683 file_failure (bool serious, char const *message, char const *file)
2684 {
2685 error (0, errno, message, quoteaf (file));
2686 set_exit_status (serious);
2687 }
2688
2689 /* Request that the directory named NAME have its contents listed later.
2690 If REALNAME is nonzero, it will be used instead of NAME when the
2691 directory name is printed. This allows symbolic links to directories
2692 to be treated as regular directories but still be listed under their
2693 real names. NAME == NULL is used to insert a marker entry for the
2694 directory named in REALNAME.
2695 If NAME is non-NULL, we use its dev/ino information to save
2696 a call to stat -- when doing a recursive (-R) traversal.
2697 COMMAND_LINE_ARG means this directory was mentioned on the command line. */
2698
2699 static void
queue_directory(char const * name,char const * realname,bool command_line_arg)2700 queue_directory (char const *name, char const *realname, bool command_line_arg)
2701 {
2702 struct pending *new = xmalloc (sizeof *new);
2703 new->realname = realname ? xstrdup (realname) : NULL;
2704 new->name = name ? xstrdup (name) : NULL;
2705 new->command_line_arg = command_line_arg;
2706 new->next = pending_dirs;
2707 pending_dirs = new;
2708 }
2709
2710 /* Read directory NAME, and list the files in it.
2711 If REALNAME is nonzero, print its name instead of NAME;
2712 this is used for symbolic links to directories.
2713 COMMAND_LINE_ARG means this directory was mentioned on the command line. */
2714
2715 static void
print_dir(char const * name,char const * realname,bool command_line_arg)2716 print_dir (char const *name, char const *realname, bool command_line_arg)
2717 {
2718 DIR *dirp;
2719 struct dirent *next;
2720 uintmax_t total_blocks = 0;
2721 static bool first = true;
2722
2723 errno = 0;
2724 dirp = opendir (name);
2725 if (!dirp)
2726 {
2727 file_failure (command_line_arg, _("cannot open directory %s"), name);
2728 return;
2729 }
2730
2731 if (LOOP_DETECT)
2732 {
2733 struct stat dir_stat;
2734 int fd = dirfd (dirp);
2735
2736 /* If dirfd failed, endure the overhead of using stat. */
2737 if ((0 <= fd
2738 ? fstat (fd, &dir_stat)
2739 : stat (name, &dir_stat)) < 0)
2740 {
2741 file_failure (command_line_arg,
2742 _("cannot determine device and inode of %s"), name);
2743 closedir (dirp);
2744 return;
2745 }
2746
2747 /* If we've already visited this dev/inode pair, warn that
2748 we've found a loop, and do not process this directory. */
2749 if (visit_dir (dir_stat.st_dev, dir_stat.st_ino))
2750 {
2751 error (0, 0, _("%s: not listing already-listed directory"),
2752 quotef (name));
2753 closedir (dirp);
2754 set_exit_status (true);
2755 return;
2756 }
2757
2758 dev_ino_push (dir_stat.st_dev, dir_stat.st_ino);
2759 }
2760
2761 clear_files ();
2762
2763 if (recursive || print_dir_name)
2764 {
2765 if (!first)
2766 DIRED_PUTCHAR ('\n');
2767 first = false;
2768 DIRED_INDENT ();
2769
2770 char *absolute_name = NULL;
2771 if (print_hyperlink)
2772 {
2773 absolute_name = canonicalize_filename_mode (name, CAN_MISSING);
2774 if (! absolute_name)
2775 file_failure (command_line_arg,
2776 _("error canonicalizing %s"), name);
2777 }
2778 quote_name (realname ? realname : name, dirname_quoting_options, -1,
2779 NULL, true, &subdired_obstack, absolute_name);
2780
2781 free (absolute_name);
2782
2783 DIRED_FPUTS_LITERAL (":\n", stdout);
2784 }
2785
2786 /* Read the directory entries, and insert the subfiles into the 'cwd_file'
2787 table. */
2788
2789 while (1)
2790 {
2791 /* Set errno to zero so we can distinguish between a readdir failure
2792 and when readdir simply finds that there are no more entries. */
2793 errno = 0;
2794 next = readdir (dirp);
2795 if (next)
2796 {
2797 if (! file_ignored (next->d_name))
2798 {
2799 enum filetype type = unknown;
2800
2801 #if HAVE_STRUCT_DIRENT_D_TYPE
2802 switch (next->d_type)
2803 {
2804 case DT_BLK: type = blockdev; break;
2805 case DT_CHR: type = chardev; break;
2806 case DT_DIR: type = directory; break;
2807 case DT_FIFO: type = fifo; break;
2808 case DT_LNK: type = symbolic_link; break;
2809 case DT_REG: type = normal; break;
2810 case DT_SOCK: type = sock; break;
2811 # ifdef DT_WHT
2812 case DT_WHT: type = whiteout; break;
2813 # endif
2814 }
2815 #endif
2816 total_blocks += gobble_file (next->d_name, type,
2817 RELIABLE_D_INO (next),
2818 false, name);
2819
2820 /* In this narrow case, print out each name right away, so
2821 ls uses constant memory while processing the entries of
2822 this directory. Useful when there are many (millions)
2823 of entries in a directory. */
2824 if (format == one_per_line && sort_type == sort_none
2825 && !print_block_size && !recursive)
2826 {
2827 /* We must call sort_files in spite of
2828 "sort_type == sort_none" for its initialization
2829 of the sorted_file vector. */
2830 sort_files ();
2831 print_current_files ();
2832 clear_files ();
2833 }
2834 }
2835 }
2836 else if (errno != 0)
2837 {
2838 file_failure (command_line_arg, _("reading directory %s"), name);
2839 if (errno != EOVERFLOW)
2840 break;
2841 }
2842 else
2843 break;
2844
2845 /* When processing a very large directory, and since we've inhibited
2846 interrupts, this loop would take so long that ls would be annoyingly
2847 uninterruptible. This ensures that it handles signals promptly. */
2848 process_signals ();
2849 }
2850
2851 if (closedir (dirp) != 0)
2852 {
2853 file_failure (command_line_arg, _("closing directory %s"), name);
2854 /* Don't return; print whatever we got. */
2855 }
2856
2857 /* Sort the directory contents. */
2858 sort_files ();
2859
2860 /* If any member files are subdirectories, perhaps they should have their
2861 contents listed rather than being mentioned here as files. */
2862
2863 if (recursive)
2864 extract_dirs_from_files (name, false);
2865
2866 if (format == long_format || print_block_size)
2867 {
2868 const char *p;
2869 char buf[LONGEST_HUMAN_READABLE + 1];
2870
2871 DIRED_INDENT ();
2872 p = _("total");
2873 DIRED_FPUTS (p, stdout, strlen (p));
2874 DIRED_PUTCHAR (' ');
2875 p = human_readable (total_blocks, buf, human_output_opts,
2876 ST_NBLOCKSIZE, output_block_size);
2877 DIRED_FPUTS (p, stdout, strlen (p));
2878 DIRED_PUTCHAR ('\n');
2879 }
2880
2881 if (cwd_n_used)
2882 print_current_files ();
2883 }
2884
2885 /* Add 'pattern' to the list of patterns for which files that match are
2886 not listed. */
2887
2888 static void
add_ignore_pattern(const char * pattern)2889 add_ignore_pattern (const char *pattern)
2890 {
2891 struct ignore_pattern *ignore;
2892
2893 ignore = xmalloc (sizeof *ignore);
2894 ignore->pattern = pattern;
2895 /* Add it to the head of the linked list. */
2896 ignore->next = ignore_patterns;
2897 ignore_patterns = ignore;
2898 }
2899
2900 /* Return true if one of the PATTERNS matches FILE. */
2901
2902 static bool
patterns_match(struct ignore_pattern const * patterns,char const * file)2903 patterns_match (struct ignore_pattern const *patterns, char const *file)
2904 {
2905 struct ignore_pattern const *p;
2906 for (p = patterns; p; p = p->next)
2907 if (fnmatch (p->pattern, file, FNM_PERIOD) == 0)
2908 return true;
2909 return false;
2910 }
2911
2912 /* Return true if FILE should be ignored. */
2913
2914 static bool
file_ignored(char const * name)2915 file_ignored (char const *name)
2916 {
2917 return ((ignore_mode != IGNORE_MINIMAL
2918 && name[0] == '.'
2919 && (ignore_mode == IGNORE_DEFAULT || ! name[1 + (name[1] == '.')]))
2920 || (ignore_mode == IGNORE_DEFAULT
2921 && patterns_match (hide_patterns, name))
2922 || patterns_match (ignore_patterns, name));
2923 }
2924
2925 /* POSIX requires that a file size be printed without a sign, even
2926 when negative. Assume the typical case where negative sizes are
2927 actually positive values that have wrapped around. */
2928
2929 static uintmax_t
unsigned_file_size(off_t size)2930 unsigned_file_size (off_t size)
2931 {
2932 return size + (size < 0) * ((uintmax_t) OFF_T_MAX - OFF_T_MIN + 1);
2933 }
2934
2935 #ifdef HAVE_CAP
2936 /* Return true if NAME has a capability (see linux/capability.h) */
2937 static bool
has_capability(char const * name)2938 has_capability (char const *name)
2939 {
2940 char *result;
2941 bool has_cap;
2942
2943 cap_t cap_d = cap_get_file (name);
2944 if (cap_d == NULL)
2945 return false;
2946
2947 result = cap_to_text (cap_d, NULL);
2948 cap_free (cap_d);
2949 if (!result)
2950 return false;
2951
2952 /* check if human-readable capability string is empty */
2953 has_cap = !!*result;
2954
2955 cap_free (result);
2956 return has_cap;
2957 }
2958 #else
2959 static bool
has_capability(char const * name _GL_UNUSED)2960 has_capability (char const *name _GL_UNUSED)
2961 {
2962 errno = ENOTSUP;
2963 return false;
2964 }
2965 #endif
2966
2967 /* Enter and remove entries in the table 'cwd_file'. */
2968
2969 static void
free_ent(struct fileinfo * f)2970 free_ent (struct fileinfo *f)
2971 {
2972 free (f->name);
2973 free (f->linkname);
2974 free (f->absolute_name);
2975 if (f->scontext != UNKNOWN_SECURITY_CONTEXT)
2976 {
2977 if (is_smack_enabled ())
2978 free (f->scontext);
2979 else
2980 freecon (f->scontext);
2981 }
2982 }
2983
2984 /* Empty the table of files. */
2985 static void
clear_files(void)2986 clear_files (void)
2987 {
2988 for (size_t i = 0; i < cwd_n_used; i++)
2989 {
2990 struct fileinfo *f = sorted_file[i];
2991 free_ent (f);
2992 }
2993
2994 cwd_n_used = 0;
2995 cwd_some_quoted = false;
2996 any_has_acl = false;
2997 inode_number_width = 0;
2998 block_size_width = 0;
2999 nlink_width = 0;
3000 owner_width = 0;
3001 group_width = 0;
3002 author_width = 0;
3003 scontext_width = 0;
3004 major_device_number_width = 0;
3005 minor_device_number_width = 0;
3006 file_size_width = 0;
3007 }
3008
3009 /* Return true if ERR implies lack-of-support failure by a
3010 getxattr-calling function like getfilecon or file_has_acl. */
3011 static bool
errno_unsupported(int err)3012 errno_unsupported (int err)
3013 {
3014 return (err == EINVAL || err == ENOSYS || is_ENOTSUP (err));
3015 }
3016
3017 /* Cache *getfilecon failure, when it's trivial to do so.
3018 Like getfilecon/lgetfilecon, but when F's st_dev says it's doesn't
3019 support getting the security context, fail with ENOTSUP immediately. */
3020 static int
getfilecon_cache(char const * file,struct fileinfo * f,bool deref)3021 getfilecon_cache (char const *file, struct fileinfo *f, bool deref)
3022 {
3023 /* st_dev of the most recently processed device for which we've
3024 found that [l]getfilecon fails indicating lack of support. */
3025 static dev_t unsupported_device;
3026
3027 if (f->stat.st_dev == unsupported_device)
3028 {
3029 errno = ENOTSUP;
3030 return -1;
3031 }
3032 int r = 0;
3033 #ifdef HAVE_SMACK
3034 if (is_smack_enabled ())
3035 r = smack_new_label_from_path (file, "security.SMACK64", deref,
3036 &f->scontext);
3037 else
3038 #endif
3039 r = (deref
3040 ? getfilecon (file, &f->scontext)
3041 : lgetfilecon (file, &f->scontext));
3042 if (r < 0 && errno_unsupported (errno))
3043 unsupported_device = f->stat.st_dev;
3044 return r;
3045 }
3046
3047 /* Cache file_has_acl failure, when it's trivial to do.
3048 Like file_has_acl, but when F's st_dev says it's on a file
3049 system lacking ACL support, return 0 with ENOTSUP immediately. */
3050 static int
file_has_acl_cache(char const * file,struct fileinfo * f)3051 file_has_acl_cache (char const *file, struct fileinfo *f)
3052 {
3053 /* st_dev of the most recently processed device for which we've
3054 found that file_has_acl fails indicating lack of support. */
3055 static dev_t unsupported_device;
3056
3057 if (f->stat.st_dev == unsupported_device)
3058 {
3059 errno = ENOTSUP;
3060 return 0;
3061 }
3062
3063 /* Zero errno so that we can distinguish between two 0-returning cases:
3064 "has-ACL-support, but only a default ACL" and "no ACL support". */
3065 errno = 0;
3066 int n = file_has_acl (file, &f->stat);
3067 if (n <= 0 && errno_unsupported (errno))
3068 unsupported_device = f->stat.st_dev;
3069 return n;
3070 }
3071
3072 /* Cache has_capability failure, when it's trivial to do.
3073 Like has_capability, but when F's st_dev says it's on a file
3074 system lacking capability support, return 0 with ENOTSUP immediately. */
3075 static bool
has_capability_cache(char const * file,struct fileinfo * f)3076 has_capability_cache (char const *file, struct fileinfo *f)
3077 {
3078 /* st_dev of the most recently processed device for which we've
3079 found that has_capability fails indicating lack of support. */
3080 static dev_t unsupported_device;
3081
3082 if (f->stat.st_dev == unsupported_device)
3083 {
3084 errno = ENOTSUP;
3085 return 0;
3086 }
3087
3088 bool b = has_capability (file);
3089 if ( !b && errno_unsupported (errno))
3090 unsupported_device = f->stat.st_dev;
3091 return b;
3092 }
3093
3094 static bool
needs_quoting(char const * name)3095 needs_quoting (char const* name)
3096 {
3097 char test[2];
3098 size_t len = quotearg_buffer (test, sizeof test , name, -1,
3099 filename_quoting_options);
3100 return *name != *test || strlen (name) != len;
3101 }
3102
3103 /* Add a file to the current table of files.
3104 Verify that the file exists, and print an error message if it does not.
3105 Return the number of blocks that the file occupies. */
3106 static uintmax_t
gobble_file(char const * name,enum filetype type,ino_t inode,bool command_line_arg,char const * dirname)3107 gobble_file (char const *name, enum filetype type, ino_t inode,
3108 bool command_line_arg, char const *dirname)
3109 {
3110 uintmax_t blocks = 0;
3111 struct fileinfo *f;
3112
3113 /* An inode value prior to gobble_file necessarily came from readdir,
3114 which is not used for command line arguments. */
3115 assert (! command_line_arg || inode == NOT_AN_INODE_NUMBER);
3116
3117 if (cwd_n_used == cwd_n_alloc)
3118 {
3119 cwd_file = xnrealloc (cwd_file, cwd_n_alloc, 2 * sizeof *cwd_file);
3120 cwd_n_alloc *= 2;
3121 }
3122
3123 f = &cwd_file[cwd_n_used];
3124 memset (f, '\0', sizeof *f);
3125 f->stat.st_ino = inode;
3126 f->filetype = type;
3127
3128 f->quoted = -1;
3129 if ((! cwd_some_quoted) && align_variable_outer_quotes)
3130 {
3131 /* Determine if any quoted for padding purposes. */
3132 f->quoted = needs_quoting (name);
3133 if (f->quoted)
3134 cwd_some_quoted = 1;
3135 }
3136
3137 if (command_line_arg
3138 || print_hyperlink
3139 || format_needs_stat
3140 /* When coloring a directory (we may know the type from
3141 direct.d_type), we have to stat it in order to indicate
3142 sticky and/or other-writable attributes. */
3143 || (type == directory && print_with_color
3144 && (is_colored (C_OTHER_WRITABLE)
3145 || is_colored (C_STICKY)
3146 || is_colored (C_STICKY_OTHER_WRITABLE)))
3147 /* When dereferencing symlinks, the inode and type must come from
3148 stat, but readdir provides the inode and type of lstat. */
3149 || ((print_inode || format_needs_type)
3150 && (type == symbolic_link || type == unknown)
3151 && (dereference == DEREF_ALWAYS
3152 || color_symlink_as_referent || check_symlink_color))
3153 /* Command line dereferences are already taken care of by the above
3154 assertion that the inode number is not yet known. */
3155 || (print_inode && inode == NOT_AN_INODE_NUMBER)
3156 || (format_needs_type
3157 && (type == unknown || command_line_arg
3158 /* --indicator-style=classify (aka -F)
3159 requires that we stat each regular file
3160 to see if it's executable. */
3161 || (type == normal && (indicator_style == classify
3162 /* This is so that --color ends up
3163 highlighting files with these mode
3164 bits set even when options like -F are
3165 not specified. Note we do a redundant
3166 stat in the very unlikely case where
3167 C_CAP is set but not the others. */
3168 || (print_with_color
3169 && (is_colored (C_EXEC)
3170 || is_colored (C_SETUID)
3171 || is_colored (C_SETGID)
3172 || is_colored (C_CAP)))
3173 )))))
3174
3175 {
3176 /* Absolute name of this file. */
3177 char *full_name;
3178 bool do_deref;
3179 int err;
3180
3181 if (name[0] == '/' || dirname[0] == 0)
3182 full_name = (char *) name;
3183 else
3184 {
3185 full_name = alloca (strlen (name) + strlen (dirname) + 2);
3186 attach (full_name, dirname, name);
3187 }
3188
3189 if (print_hyperlink)
3190 {
3191 f->absolute_name = canonicalize_filename_mode (full_name,
3192 CAN_MISSING);
3193 if (! f->absolute_name)
3194 file_failure (command_line_arg,
3195 _("error canonicalizing %s"), full_name);
3196 }
3197
3198 switch (dereference)
3199 {
3200 case DEREF_ALWAYS:
3201 err = stat (full_name, &f->stat);
3202 do_deref = true;
3203 break;
3204
3205 case DEREF_COMMAND_LINE_ARGUMENTS:
3206 case DEREF_COMMAND_LINE_SYMLINK_TO_DIR:
3207 if (command_line_arg)
3208 {
3209 bool need_lstat;
3210 err = stat (full_name, &f->stat);
3211 do_deref = true;
3212
3213 if (dereference == DEREF_COMMAND_LINE_ARGUMENTS)
3214 break;
3215
3216 need_lstat = (err < 0
3217 ? errno == ENOENT
3218 : ! S_ISDIR (f->stat.st_mode));
3219 if (!need_lstat)
3220 break;
3221
3222 /* stat failed because of ENOENT, maybe indicating a dangling
3223 symlink. Or stat succeeded, FULL_NAME does not refer to a
3224 directory, and --dereference-command-line-symlink-to-dir is
3225 in effect. Fall through so that we call lstat instead. */
3226 }
3227 FALLTHROUGH;
3228
3229 default: /* DEREF_NEVER */
3230 err = lstat (full_name, &f->stat);
3231 do_deref = false;
3232 break;
3233 }
3234
3235 if (err != 0)
3236 {
3237 /* Failure to stat a command line argument leads to
3238 an exit status of 2. For other files, stat failure
3239 provokes an exit status of 1. */
3240 file_failure (command_line_arg,
3241 _("cannot access %s"), full_name);
3242 if (command_line_arg)
3243 return 0;
3244
3245 f->name = xstrdup (name);
3246 cwd_n_used++;
3247
3248 return 0;
3249 }
3250
3251 f->stat_ok = true;
3252
3253 /* Note has_capability() adds around 30% runtime to 'ls --color' */
3254 if ((type == normal || S_ISREG (f->stat.st_mode))
3255 && print_with_color && is_colored (C_CAP))
3256 f->has_capability = has_capability_cache (full_name, f);
3257
3258 if (format == long_format || print_scontext)
3259 {
3260 bool have_scontext = false;
3261 bool have_acl = false;
3262 int attr_len = getfilecon_cache (full_name, f, do_deref);
3263 err = (attr_len < 0);
3264
3265 if (err == 0)
3266 {
3267 if (is_smack_enabled ())
3268 have_scontext = ! STREQ ("_", f->scontext);
3269 else
3270 have_scontext = ! STREQ ("unlabeled", f->scontext);
3271 }
3272 else
3273 {
3274 f->scontext = UNKNOWN_SECURITY_CONTEXT;
3275
3276 /* When requesting security context information, don't make
3277 ls fail just because the file (even a command line argument)
3278 isn't on the right type of file system. I.e., a getfilecon
3279 failure isn't in the same class as a stat failure. */
3280 if (is_ENOTSUP (errno) || errno == ENODATA)
3281 err = 0;
3282 }
3283
3284 if (err == 0 && format == long_format)
3285 {
3286 int n = file_has_acl_cache (full_name, f);
3287 err = (n < 0);
3288 have_acl = (0 < n);
3289 }
3290
3291 f->acl_type = (!have_scontext && !have_acl
3292 ? ACL_T_NONE
3293 : (have_scontext && !have_acl
3294 ? ACL_T_LSM_CONTEXT_ONLY
3295 : ACL_T_YES));
3296 any_has_acl |= f->acl_type != ACL_T_NONE;
3297
3298 if (err)
3299 error (0, errno, "%s", quotef (full_name));
3300 }
3301
3302 if (S_ISLNK (f->stat.st_mode)
3303 && (format == long_format || check_symlink_color))
3304 {
3305 struct stat linkstats;
3306
3307 get_link_name (full_name, f, command_line_arg);
3308 char *linkname = make_link_name (full_name, f->linkname);
3309
3310 /* Use the slower quoting path for this entry, though
3311 don't update CWD_SOME_QUOTED since alignment not affected. */
3312 if (linkname && f->quoted == 0 && needs_quoting (f->linkname))
3313 f->quoted = -1;
3314
3315 /* Avoid following symbolic links when possible, ie, when
3316 they won't be traced and when no indicator is needed. */
3317 if (linkname
3318 && (file_type <= indicator_style || check_symlink_color)
3319 && stat (linkname, &linkstats) == 0)
3320 {
3321 f->linkok = true;
3322
3323 /* Symbolic links to directories that are mentioned on the
3324 command line are automatically traced if not being
3325 listed as files. */
3326 if (!command_line_arg || format == long_format
3327 || !S_ISDIR (linkstats.st_mode))
3328 {
3329 /* Get the linked-to file's mode for the filetype indicator
3330 in long listings. */
3331 f->linkmode = linkstats.st_mode;
3332 }
3333 }
3334 free (linkname);
3335 }
3336
3337 if (S_ISLNK (f->stat.st_mode))
3338 f->filetype = symbolic_link;
3339 else if (S_ISDIR (f->stat.st_mode))
3340 {
3341 if (command_line_arg && !immediate_dirs)
3342 f->filetype = arg_directory;
3343 else
3344 f->filetype = directory;
3345 }
3346 else
3347 f->filetype = normal;
3348
3349 blocks = ST_NBLOCKS (f->stat);
3350 if (format == long_format || print_block_size)
3351 {
3352 char buf[LONGEST_HUMAN_READABLE + 1];
3353 int len = mbswidth (human_readable (blocks, buf, human_output_opts,
3354 ST_NBLOCKSIZE, output_block_size),
3355 0);
3356 if (block_size_width < len)
3357 block_size_width = len;
3358 }
3359
3360 if (format == long_format)
3361 {
3362 if (print_owner)
3363 {
3364 int len = format_user_width (f->stat.st_uid);
3365 if (owner_width < len)
3366 owner_width = len;
3367 }
3368
3369 if (print_group)
3370 {
3371 int len = format_group_width (f->stat.st_gid);
3372 if (group_width < len)
3373 group_width = len;
3374 }
3375
3376 if (print_author)
3377 {
3378 int len = format_user_width (f->stat.st_author);
3379 if (author_width < len)
3380 author_width = len;
3381 }
3382 }
3383
3384 if (print_scontext)
3385 {
3386 int len = strlen (f->scontext);
3387 if (scontext_width < len)
3388 scontext_width = len;
3389 }
3390
3391 if (format == long_format)
3392 {
3393 char b[INT_BUFSIZE_BOUND (uintmax_t)];
3394 int b_len = strlen (umaxtostr (f->stat.st_nlink, b));
3395 if (nlink_width < b_len)
3396 nlink_width = b_len;
3397
3398 if (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode))
3399 {
3400 char buf[INT_BUFSIZE_BOUND (uintmax_t)];
3401 int len = strlen (umaxtostr (major (f->stat.st_rdev), buf));
3402 if (major_device_number_width < len)
3403 major_device_number_width = len;
3404 len = strlen (umaxtostr (minor (f->stat.st_rdev), buf));
3405 if (minor_device_number_width < len)
3406 minor_device_number_width = len;
3407 len = major_device_number_width + 2 + minor_device_number_width;
3408 if (file_size_width < len)
3409 file_size_width = len;
3410 }
3411 else
3412 {
3413 char buf[LONGEST_HUMAN_READABLE + 1];
3414 uintmax_t size = unsigned_file_size (f->stat.st_size);
3415 int len = mbswidth (human_readable (size, buf,
3416 file_human_output_opts,
3417 1, file_output_block_size),
3418 0);
3419 if (file_size_width < len)
3420 file_size_width = len;
3421 }
3422 }
3423 }
3424
3425 if (print_inode)
3426 {
3427 char buf[INT_BUFSIZE_BOUND (uintmax_t)];
3428 int len = strlen (umaxtostr (f->stat.st_ino, buf));
3429 if (inode_number_width < len)
3430 inode_number_width = len;
3431 }
3432
3433 f->name = xstrdup (name);
3434 cwd_n_used++;
3435
3436 return blocks;
3437 }
3438
3439 /* Return true if F refers to a directory. */
3440 static bool
is_directory(const struct fileinfo * f)3441 is_directory (const struct fileinfo *f)
3442 {
3443 return f->filetype == directory || f->filetype == arg_directory;
3444 }
3445
3446 /* Put the name of the file that FILENAME is a symbolic link to
3447 into the LINKNAME field of 'f'. COMMAND_LINE_ARG indicates whether
3448 FILENAME is a command-line argument. */
3449
3450 static void
get_link_name(char const * filename,struct fileinfo * f,bool command_line_arg)3451 get_link_name (char const *filename, struct fileinfo *f, bool command_line_arg)
3452 {
3453 f->linkname = areadlink_with_size (filename, f->stat.st_size);
3454 if (f->linkname == NULL)
3455 file_failure (command_line_arg, _("cannot read symbolic link %s"),
3456 filename);
3457 }
3458
3459 /* If LINKNAME is a relative name and NAME contains one or more
3460 leading directories, return LINKNAME with those directories
3461 prepended; otherwise, return a copy of LINKNAME.
3462 If LINKNAME is NULL, return NULL. */
3463
3464 static char *
make_link_name(char const * name,char const * linkname)3465 make_link_name (char const *name, char const *linkname)
3466 {
3467 if (!linkname)
3468 return NULL;
3469
3470 if (IS_ABSOLUTE_FILE_NAME (linkname))
3471 return xstrdup (linkname);
3472
3473 /* The link is to a relative name. Prepend any leading directory
3474 in 'name' to the link name. */
3475 size_t prefix_len = dir_len (name);
3476 if (prefix_len == 0)
3477 return xstrdup (linkname);
3478
3479 char *p = xmalloc (prefix_len + 1 + strlen (linkname) + 1);
3480
3481 /* PREFIX_LEN usually specifies a string not ending in slash.
3482 In that case, extend it by one, since the next byte *is* a slash.
3483 Otherwise, the prefix is "/", so leave the length unchanged. */
3484 if ( ! ISSLASH (name[prefix_len - 1]))
3485 ++prefix_len;
3486
3487 stpcpy (stpncpy (p, name, prefix_len), linkname);
3488 return p;
3489 }
3490
3491 /* Return true if the last component of NAME is '.' or '..'
3492 This is so we don't try to recurse on '././././. ...' */
3493
3494 static bool
basename_is_dot_or_dotdot(const char * name)3495 basename_is_dot_or_dotdot (const char *name)
3496 {
3497 char const *base = last_component (name);
3498 return dot_or_dotdot (base);
3499 }
3500
3501 /* Remove any entries from CWD_FILE that are for directories,
3502 and queue them to be listed as directories instead.
3503 DIRNAME is the prefix to prepend to each dirname
3504 to make it correct relative to ls's working dir;
3505 if it is null, no prefix is needed and "." and ".." should not be ignored.
3506 If COMMAND_LINE_ARG is true, this directory was mentioned at the top level,
3507 This is desirable when processing directories recursively. */
3508
3509 static void
extract_dirs_from_files(char const * dirname,bool command_line_arg)3510 extract_dirs_from_files (char const *dirname, bool command_line_arg)
3511 {
3512 size_t i;
3513 size_t j;
3514 bool ignore_dot_and_dot_dot = (dirname != NULL);
3515
3516 if (dirname && LOOP_DETECT)
3517 {
3518 /* Insert a marker entry first. When we dequeue this marker entry,
3519 we'll know that DIRNAME has been processed and may be removed
3520 from the set of active directories. */
3521 queue_directory (NULL, dirname, false);
3522 }
3523
3524 /* Queue the directories last one first, because queueing reverses the
3525 order. */
3526 for (i = cwd_n_used; i-- != 0; )
3527 {
3528 struct fileinfo *f = sorted_file[i];
3529
3530 if (is_directory (f)
3531 && (! ignore_dot_and_dot_dot
3532 || ! basename_is_dot_or_dotdot (f->name)))
3533 {
3534 if (!dirname || f->name[0] == '/')
3535 queue_directory (f->name, f->linkname, command_line_arg);
3536 else
3537 {
3538 char *name = file_name_concat (dirname, f->name, NULL);
3539 queue_directory (name, f->linkname, command_line_arg);
3540 free (name);
3541 }
3542 if (f->filetype == arg_directory)
3543 free_ent (f);
3544 }
3545 }
3546
3547 /* Now delete the directories from the table, compacting all the remaining
3548 entries. */
3549
3550 for (i = 0, j = 0; i < cwd_n_used; i++)
3551 {
3552 struct fileinfo *f = sorted_file[i];
3553 sorted_file[j] = f;
3554 j += (f->filetype != arg_directory);
3555 }
3556 cwd_n_used = j;
3557 }
3558
3559 /* Use strcoll to compare strings in this locale. If an error occurs,
3560 report an error and longjmp to failed_strcoll. */
3561
3562 static jmp_buf failed_strcoll;
3563
3564 static int
xstrcoll(char const * a,char const * b)3565 xstrcoll (char const *a, char const *b)
3566 {
3567 int diff;
3568 errno = 0;
3569 diff = strcoll (a, b);
3570 if (errno)
3571 {
3572 error (0, errno, _("cannot compare file names %s and %s"),
3573 quote_n (0, a), quote_n (1, b));
3574 set_exit_status (false);
3575 longjmp (failed_strcoll, 1);
3576 }
3577 return diff;
3578 }
3579
3580 /* Comparison routines for sorting the files. */
3581
3582 typedef void const *V;
3583 typedef int (*qsortFunc)(V a, V b);
3584
3585 /* Used below in DEFINE_SORT_FUNCTIONS for _df_ sort function variants.
3586 The do { ... } while(0) makes it possible to use the macro more like
3587 a statement, without violating C89 rules: */
3588 #define DIRFIRST_CHECK(a, b) \
3589 do \
3590 { \
3591 bool a_is_dir = is_directory ((struct fileinfo const *) a); \
3592 bool b_is_dir = is_directory ((struct fileinfo const *) b); \
3593 if (a_is_dir && !b_is_dir) \
3594 return -1; /* a goes before b */ \
3595 if (!a_is_dir && b_is_dir) \
3596 return 1; /* b goes before a */ \
3597 } \
3598 while (0)
3599
3600 /* Define the 8 different sort function variants required for each sortkey.
3601 KEY_NAME is a token describing the sort key, e.g., ctime, atime, size.
3602 KEY_CMP_FUNC is a function to compare records based on that key, e.g.,
3603 ctime_cmp, atime_cmp, size_cmp. Append KEY_NAME to the string,
3604 '[rev_][x]str{cmp|coll}[_df]_', to create each function name. */
3605 #define DEFINE_SORT_FUNCTIONS(key_name, key_cmp_func) \
3606 /* direct, non-dirfirst versions */ \
3607 static int xstrcoll_##key_name (V a, V b) \
3608 { return key_cmp_func (a, b, xstrcoll); } \
3609 static int _GL_ATTRIBUTE_PURE strcmp_##key_name (V a, V b) \
3610 { return key_cmp_func (a, b, strcmp); } \
3611 \
3612 /* reverse, non-dirfirst versions */ \
3613 static int rev_xstrcoll_##key_name (V a, V b) \
3614 { return key_cmp_func (b, a, xstrcoll); } \
3615 static int _GL_ATTRIBUTE_PURE rev_strcmp_##key_name (V a, V b) \
3616 { return key_cmp_func (b, a, strcmp); } \
3617 \
3618 /* direct, dirfirst versions */ \
3619 static int xstrcoll_df_##key_name (V a, V b) \
3620 { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, xstrcoll); } \
3621 static int _GL_ATTRIBUTE_PURE strcmp_df_##key_name (V a, V b) \
3622 { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, strcmp); } \
3623 \
3624 /* reverse, dirfirst versions */ \
3625 static int rev_xstrcoll_df_##key_name (V a, V b) \
3626 { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, xstrcoll); } \
3627 static int _GL_ATTRIBUTE_PURE rev_strcmp_df_##key_name (V a, V b) \
3628 { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, strcmp); }
3629
3630 static inline int
cmp_ctime(struct fileinfo const * a,struct fileinfo const * b,int (* cmp)(char const *,char const *))3631 cmp_ctime (struct fileinfo const *a, struct fileinfo const *b,
3632 int (*cmp) (char const *, char const *))
3633 {
3634 int diff = timespec_cmp (get_stat_ctime (&b->stat),
3635 get_stat_ctime (&a->stat));
3636 return diff ? diff : cmp (a->name, b->name);
3637 }
3638
3639 static inline int
cmp_mtime(struct fileinfo const * a,struct fileinfo const * b,int (* cmp)(char const *,char const *))3640 cmp_mtime (struct fileinfo const *a, struct fileinfo const *b,
3641 int (*cmp) (char const *, char const *))
3642 {
3643 int diff = timespec_cmp (get_stat_mtime (&b->stat),
3644 get_stat_mtime (&a->stat));
3645 return diff ? diff : cmp (a->name, b->name);
3646 }
3647
3648 static inline int
cmp_atime(struct fileinfo const * a,struct fileinfo const * b,int (* cmp)(char const *,char const *))3649 cmp_atime (struct fileinfo const *a, struct fileinfo const *b,
3650 int (*cmp) (char const *, char const *))
3651 {
3652 int diff = timespec_cmp (get_stat_atime (&b->stat),
3653 get_stat_atime (&a->stat));
3654 return diff ? diff : cmp (a->name, b->name);
3655 }
3656
3657 static inline int
cmp_size(struct fileinfo const * a,struct fileinfo const * b,int (* cmp)(char const *,char const *))3658 cmp_size (struct fileinfo const *a, struct fileinfo const *b,
3659 int (*cmp) (char const *, char const *))
3660 {
3661 int diff = longdiff (b->stat.st_size, a->stat.st_size);
3662 return diff ? diff : cmp (a->name, b->name);
3663 }
3664
3665 static inline int
cmp_name(struct fileinfo const * a,struct fileinfo const * b,int (* cmp)(char const *,char const *))3666 cmp_name (struct fileinfo const *a, struct fileinfo const *b,
3667 int (*cmp) (char const *, char const *))
3668 {
3669 return cmp (a->name, b->name);
3670 }
3671
3672 /* Compare file extensions. Files with no extension are 'smallest'.
3673 If extensions are the same, compare by file names instead. */
3674
3675 static inline int
cmp_extension(struct fileinfo const * a,struct fileinfo const * b,int (* cmp)(char const *,char const *))3676 cmp_extension (struct fileinfo const *a, struct fileinfo const *b,
3677 int (*cmp) (char const *, char const *))
3678 {
3679 char const *base1 = strrchr (a->name, '.');
3680 char const *base2 = strrchr (b->name, '.');
3681 int diff = cmp (base1 ? base1 : "", base2 ? base2 : "");
3682 return diff ? diff : cmp (a->name, b->name);
3683 }
3684
DEFINE_SORT_FUNCTIONS(ctime,cmp_ctime)3685 DEFINE_SORT_FUNCTIONS (ctime, cmp_ctime)
3686 DEFINE_SORT_FUNCTIONS (mtime, cmp_mtime)
3687 DEFINE_SORT_FUNCTIONS (atime, cmp_atime)
3688 DEFINE_SORT_FUNCTIONS (size, cmp_size)
3689 DEFINE_SORT_FUNCTIONS (name, cmp_name)
3690 DEFINE_SORT_FUNCTIONS (extension, cmp_extension)
3691
3692 /* Compare file versions.
3693 Unlike all other compare functions above, cmp_version depends only
3694 on filevercmp, which does not fail (even for locale reasons), and does not
3695 need a secondary sort key. See lib/filevercmp.h for function description.
3696
3697 All the other sort options, in fact, need xstrcoll and strcmp variants,
3698 because they all use a string comparison (either as the primary or secondary
3699 sort key), and xstrcoll has the ability to do a longjmp if strcoll fails for
3700 locale reasons. Lastly, filevercmp is ALWAYS available with gnulib. */
3701 static inline int
3702 cmp_version (struct fileinfo const *a, struct fileinfo const *b)
3703 {
3704 return filevercmp (a->name, b->name);
3705 }
3706
xstrcoll_version(V a,V b)3707 static int xstrcoll_version (V a, V b)
3708 { return cmp_version (a, b); }
rev_xstrcoll_version(V a,V b)3709 static int rev_xstrcoll_version (V a, V b)
3710 { return cmp_version (b, a); }
xstrcoll_df_version(V a,V b)3711 static int xstrcoll_df_version (V a, V b)
3712 { DIRFIRST_CHECK (a, b); return cmp_version (a, b); }
rev_xstrcoll_df_version(V a,V b)3713 static int rev_xstrcoll_df_version (V a, V b)
3714 { DIRFIRST_CHECK (a, b); return cmp_version (b, a); }
3715
3716
3717 /* We have 2^3 different variants for each sort-key function
3718 (for 3 independent sort modes).
3719 The function pointers stored in this array must be dereferenced as:
3720
3721 sort_variants[sort_key][use_strcmp][reverse][dirs_first]
3722
3723 Note that the order in which sort keys are listed in the function pointer
3724 array below is defined by the order of the elements in the time_type and
3725 sort_type enums! */
3726
3727 #define LIST_SORTFUNCTION_VARIANTS(key_name) \
3728 { \
3729 { \
3730 { xstrcoll_##key_name, xstrcoll_df_##key_name }, \
3731 { rev_xstrcoll_##key_name, rev_xstrcoll_df_##key_name }, \
3732 }, \
3733 { \
3734 { strcmp_##key_name, strcmp_df_##key_name }, \
3735 { rev_strcmp_##key_name, rev_strcmp_df_##key_name }, \
3736 } \
3737 }
3738
3739 static qsortFunc const sort_functions[][2][2][2] =
3740 {
3741 LIST_SORTFUNCTION_VARIANTS (name),
3742 LIST_SORTFUNCTION_VARIANTS (extension),
3743 LIST_SORTFUNCTION_VARIANTS (size),
3744
3745 {
3746 {
3747 { xstrcoll_version, xstrcoll_df_version },
3748 { rev_xstrcoll_version, rev_xstrcoll_df_version },
3749 },
3750
3751 /* We use NULL for the strcmp variants of version comparison
3752 since as explained in cmp_version definition, version comparison
3753 does not rely on xstrcoll, so it will never longjmp, and never
3754 need to try the strcmp fallback. */
3755 {
3756 { NULL, NULL },
3757 { NULL, NULL },
3758 }
3759 },
3760
3761 /* last are time sort functions */
3762 LIST_SORTFUNCTION_VARIANTS (mtime),
3763 LIST_SORTFUNCTION_VARIANTS (ctime),
3764 LIST_SORTFUNCTION_VARIANTS (atime)
3765 };
3766
3767 /* The number of sort keys is calculated as the sum of
3768 the number of elements in the sort_type enum (i.e., sort_numtypes)
3769 the number of elements in the time_type enum (i.e., time_numtypes) - 1
3770 This is because when sort_type==sort_time, we have up to
3771 time_numtypes possible sort keys.
3772
3773 This line verifies at compile-time that the array of sort functions has been
3774 initialized for all possible sort keys. */
3775 verify (ARRAY_CARDINALITY (sort_functions)
3776 == sort_numtypes + time_numtypes - 1 );
3777
3778 /* Set up SORTED_FILE to point to the in-use entries in CWD_FILE, in order. */
3779
3780 static void
initialize_ordering_vector(void)3781 initialize_ordering_vector (void)
3782 {
3783 for (size_t i = 0; i < cwd_n_used; i++)
3784 sorted_file[i] = &cwd_file[i];
3785 }
3786
3787 /* Sort the files now in the table. */
3788
3789 static void
sort_files(void)3790 sort_files (void)
3791 {
3792 bool use_strcmp;
3793
3794 if (sorted_file_alloc < cwd_n_used + cwd_n_used / 2)
3795 {
3796 free (sorted_file);
3797 sorted_file = xnmalloc (cwd_n_used, 3 * sizeof *sorted_file);
3798 sorted_file_alloc = 3 * cwd_n_used;
3799 }
3800
3801 initialize_ordering_vector ();
3802
3803 if (sort_type == sort_none)
3804 return;
3805
3806 /* Try strcoll. If it fails, fall back on strcmp. We can't safely
3807 ignore strcoll failures, as a failing strcoll might be a
3808 comparison function that is not a total order, and if we ignored
3809 the failure this might cause qsort to dump core. */
3810
3811 if (! setjmp (failed_strcoll))
3812 use_strcmp = false; /* strcoll() succeeded */
3813 else
3814 {
3815 use_strcmp = true;
3816 assert (sort_type != sort_version);
3817 initialize_ordering_vector ();
3818 }
3819
3820 /* When sort_type == sort_time, use time_type as subindex. */
3821 mpsort ((void const **) sorted_file, cwd_n_used,
3822 sort_functions[sort_type + (sort_type == sort_time ? time_type : 0)]
3823 [use_strcmp][sort_reverse]
3824 [directories_first]);
3825 }
3826
3827 /* List all the files now in the table. */
3828
3829 static void
print_current_files(void)3830 print_current_files (void)
3831 {
3832 size_t i;
3833
3834 switch (format)
3835 {
3836 case one_per_line:
3837 for (i = 0; i < cwd_n_used; i++)
3838 {
3839 print_file_name_and_frills (sorted_file[i], 0);
3840 putchar ('\n');
3841 }
3842 break;
3843
3844 case many_per_line:
3845 if (! line_length)
3846 print_with_separator (' ');
3847 else
3848 print_many_per_line ();
3849 break;
3850
3851 case horizontal:
3852 if (! line_length)
3853 print_with_separator (' ');
3854 else
3855 print_horizontal ();
3856 break;
3857
3858 case with_commas:
3859 print_with_separator (',');
3860 break;
3861
3862 case long_format:
3863 for (i = 0; i < cwd_n_used; i++)
3864 {
3865 set_normal_color ();
3866 print_long_format (sorted_file[i]);
3867 DIRED_PUTCHAR ('\n');
3868 }
3869 break;
3870 }
3871 }
3872
3873 /* Replace the first %b with precomputed aligned month names.
3874 Note on glibc-2.7 at least, this speeds up the whole 'ls -lU'
3875 process by around 17%, compared to letting strftime() handle the %b. */
3876
3877 static size_t
align_nstrftime(char * buf,size_t size,bool recent,struct tm const * tm,timezone_t tz,int ns)3878 align_nstrftime (char *buf, size_t size, bool recent, struct tm const *tm,
3879 timezone_t tz, int ns)
3880 {
3881 char const *nfmt = (use_abformat
3882 ? abformat[recent][tm->tm_mon]
3883 : long_time_format[recent]);
3884 return nstrftime (buf, size, nfmt, tm, tz, ns);
3885 }
3886
3887 /* Return the expected number of columns in a long-format timestamp,
3888 or zero if it cannot be calculated. */
3889
3890 static int
long_time_expected_width(void)3891 long_time_expected_width (void)
3892 {
3893 static int width = -1;
3894
3895 if (width < 0)
3896 {
3897 time_t epoch = 0;
3898 struct tm tm;
3899 char buf[TIME_STAMP_LEN_MAXIMUM + 1];
3900
3901 /* In case you're wondering if localtime_rz can fail with an input time_t
3902 value of 0, let's just say it's very unlikely, but not inconceivable.
3903 The TZ environment variable would have to specify a time zone that
3904 is 2**31-1900 years or more ahead of UTC. This could happen only on
3905 a 64-bit system that blindly accepts e.g., TZ=UTC+20000000000000.
3906 However, this is not possible with Solaris 10 or glibc-2.3.5, since
3907 their implementations limit the offset to 167:59 and 24:00, resp. */
3908 if (localtime_rz (localtz, &epoch, &tm))
3909 {
3910 size_t len = align_nstrftime (buf, sizeof buf, false,
3911 &tm, localtz, 0);
3912 if (len != 0)
3913 width = mbsnwidth (buf, len, 0);
3914 }
3915
3916 if (width < 0)
3917 width = 0;
3918 }
3919
3920 return width;
3921 }
3922
3923 /* Print the user or group name NAME, with numeric id ID, using a
3924 print width of WIDTH columns. */
3925
3926 static void
format_user_or_group(char const * name,unsigned long int id,int width)3927 format_user_or_group (char const *name, unsigned long int id, int width)
3928 {
3929 size_t len;
3930
3931 if (name)
3932 {
3933 int width_gap = width - mbswidth (name, 0);
3934 int pad = MAX (0, width_gap);
3935 fputs (name, stdout);
3936 len = strlen (name) + pad;
3937
3938 do
3939 putchar (' ');
3940 while (pad--);
3941 }
3942 else
3943 {
3944 printf ("%*lu ", width, id);
3945 len = width;
3946 }
3947
3948 dired_pos += len + 1;
3949 }
3950
3951 /* Print the name or id of the user with id U, using a print width of
3952 WIDTH. */
3953
3954 static void
format_user(uid_t u,int width,bool stat_ok)3955 format_user (uid_t u, int width, bool stat_ok)
3956 {
3957 format_user_or_group (! stat_ok ? "?" :
3958 (numeric_ids ? NULL : getuser (u)), u, width);
3959 }
3960
3961 /* Likewise, for groups. */
3962
3963 static void
format_group(gid_t g,int width,bool stat_ok)3964 format_group (gid_t g, int width, bool stat_ok)
3965 {
3966 format_user_or_group (! stat_ok ? "?" :
3967 (numeric_ids ? NULL : getgroup (g)), g, width);
3968 }
3969
3970 /* Return the number of columns that format_user_or_group will print. */
3971
3972 static int
format_user_or_group_width(char const * name,unsigned long int id)3973 format_user_or_group_width (char const *name, unsigned long int id)
3974 {
3975 if (name)
3976 {
3977 int len = mbswidth (name, 0);
3978 return MAX (0, len);
3979 }
3980 else
3981 {
3982 char buf[INT_BUFSIZE_BOUND (id)];
3983 sprintf (buf, "%lu", id);
3984 return strlen (buf);
3985 }
3986 }
3987
3988 /* Return the number of columns that format_user will print. */
3989
3990 static int
format_user_width(uid_t u)3991 format_user_width (uid_t u)
3992 {
3993 return format_user_or_group_width (numeric_ids ? NULL : getuser (u), u);
3994 }
3995
3996 /* Likewise, for groups. */
3997
3998 static int
format_group_width(gid_t g)3999 format_group_width (gid_t g)
4000 {
4001 return format_user_or_group_width (numeric_ids ? NULL : getgroup (g), g);
4002 }
4003
4004 /* Return a pointer to a formatted version of F->stat.st_ino,
4005 possibly using buffer, BUF, of length BUFLEN, which must be at least
4006 INT_BUFSIZE_BOUND (uintmax_t) bytes. */
4007 static char *
format_inode(char * buf,size_t buflen,const struct fileinfo * f)4008 format_inode (char *buf, size_t buflen, const struct fileinfo *f)
4009 {
4010 assert (INT_BUFSIZE_BOUND (uintmax_t) <= buflen);
4011 return (f->stat_ok && f->stat.st_ino != NOT_AN_INODE_NUMBER
4012 ? umaxtostr (f->stat.st_ino, buf)
4013 : (char *) "?");
4014 }
4015
4016 /* Print information about F in long format. */
4017 static void
print_long_format(const struct fileinfo * f)4018 print_long_format (const struct fileinfo *f)
4019 {
4020 char modebuf[12];
4021 char buf
4022 [LONGEST_HUMAN_READABLE + 1 /* inode */
4023 + LONGEST_HUMAN_READABLE + 1 /* size in blocks */
4024 + sizeof (modebuf) - 1 + 1 /* mode string */
4025 + INT_BUFSIZE_BOUND (uintmax_t) /* st_nlink */
4026 + LONGEST_HUMAN_READABLE + 2 /* major device number */
4027 + LONGEST_HUMAN_READABLE + 1 /* minor device number */
4028 + TIME_STAMP_LEN_MAXIMUM + 1 /* max length of time/date */
4029 ];
4030 size_t s;
4031 char *p;
4032 struct timespec when_timespec;
4033 struct tm when_local;
4034
4035 /* Compute the mode string, except remove the trailing space if no
4036 file in this directory has an ACL or security context. */
4037 if (f->stat_ok)
4038 filemodestring (&f->stat, modebuf);
4039 else
4040 {
4041 modebuf[0] = filetype_letter[f->filetype];
4042 memset (modebuf + 1, '?', 10);
4043 modebuf[11] = '\0';
4044 }
4045 if (! any_has_acl)
4046 modebuf[10] = '\0';
4047 else if (f->acl_type == ACL_T_LSM_CONTEXT_ONLY)
4048 modebuf[10] = '.';
4049 else if (f->acl_type == ACL_T_YES)
4050 modebuf[10] = '+';
4051
4052 switch (time_type)
4053 {
4054 case time_ctime:
4055 when_timespec = get_stat_ctime (&f->stat);
4056 break;
4057 case time_mtime:
4058 when_timespec = get_stat_mtime (&f->stat);
4059 break;
4060 case time_atime:
4061 when_timespec = get_stat_atime (&f->stat);
4062 break;
4063 default:
4064 abort ();
4065 }
4066
4067 p = buf;
4068
4069 if (print_inode)
4070 {
4071 char hbuf[INT_BUFSIZE_BOUND (uintmax_t)];
4072 sprintf (p, "%*s ", inode_number_width,
4073 format_inode (hbuf, sizeof hbuf, f));
4074 /* Increment by strlen (p) here, rather than by inode_number_width + 1.
4075 The latter is wrong when inode_number_width is zero. */
4076 p += strlen (p);
4077 }
4078
4079 if (print_block_size)
4080 {
4081 char hbuf[LONGEST_HUMAN_READABLE + 1];
4082 char const *blocks =
4083 (! f->stat_ok
4084 ? "?"
4085 : human_readable (ST_NBLOCKS (f->stat), hbuf, human_output_opts,
4086 ST_NBLOCKSIZE, output_block_size));
4087 int pad;
4088 for (pad = block_size_width - mbswidth (blocks, 0); 0 < pad; pad--)
4089 *p++ = ' ';
4090 while ((*p++ = *blocks++))
4091 continue;
4092 p[-1] = ' ';
4093 }
4094
4095 /* The last byte of the mode string is the POSIX
4096 "optional alternate access method flag". */
4097 {
4098 char hbuf[INT_BUFSIZE_BOUND (uintmax_t)];
4099 sprintf (p, "%s %*s ", modebuf, nlink_width,
4100 ! f->stat_ok ? "?" : umaxtostr (f->stat.st_nlink, hbuf));
4101 }
4102 /* Increment by strlen (p) here, rather than by, e.g.,
4103 sizeof modebuf - 2 + any_has_acl + 1 + nlink_width + 1.
4104 The latter is wrong when nlink_width is zero. */
4105 p += strlen (p);
4106
4107 DIRED_INDENT ();
4108
4109 if (print_owner || print_group || print_author || print_scontext)
4110 {
4111 DIRED_FPUTS (buf, stdout, p - buf);
4112
4113 if (print_owner)
4114 format_user (f->stat.st_uid, owner_width, f->stat_ok);
4115
4116 if (print_group)
4117 format_group (f->stat.st_gid, group_width, f->stat_ok);
4118
4119 if (print_author)
4120 format_user (f->stat.st_author, author_width, f->stat_ok);
4121
4122 if (print_scontext)
4123 format_user_or_group (f->scontext, 0, scontext_width);
4124
4125 p = buf;
4126 }
4127
4128 if (f->stat_ok
4129 && (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode)))
4130 {
4131 char majorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
4132 char minorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
4133 int blanks_width = (file_size_width
4134 - (major_device_number_width + 2
4135 + minor_device_number_width));
4136 sprintf (p, "%*s, %*s ",
4137 major_device_number_width + MAX (0, blanks_width),
4138 umaxtostr (major (f->stat.st_rdev), majorbuf),
4139 minor_device_number_width,
4140 umaxtostr (minor (f->stat.st_rdev), minorbuf));
4141 p += file_size_width + 1;
4142 }
4143 else
4144 {
4145 char hbuf[LONGEST_HUMAN_READABLE + 1];
4146 char const *size =
4147 (! f->stat_ok
4148 ? "?"
4149 : human_readable (unsigned_file_size (f->stat.st_size),
4150 hbuf, file_human_output_opts, 1,
4151 file_output_block_size));
4152 int pad;
4153 for (pad = file_size_width - mbswidth (size, 0); 0 < pad; pad--)
4154 *p++ = ' ';
4155 while ((*p++ = *size++))
4156 continue;
4157 p[-1] = ' ';
4158 }
4159
4160 s = 0;
4161 *p = '\1';
4162
4163 if (f->stat_ok && localtime_rz (localtz, &when_timespec.tv_sec, &when_local))
4164 {
4165 struct timespec six_months_ago;
4166 bool recent;
4167
4168 /* If the file appears to be in the future, update the current
4169 time, in case the file happens to have been modified since
4170 the last time we checked the clock. */
4171 if (timespec_cmp (current_time, when_timespec) < 0)
4172 gettime (¤t_time);
4173
4174 /* Consider a time to be recent if it is within the past six months.
4175 A Gregorian year has 365.2425 * 24 * 60 * 60 == 31556952 seconds
4176 on the average. Write this value as an integer constant to
4177 avoid floating point hassles. */
4178 six_months_ago.tv_sec = current_time.tv_sec - 31556952 / 2;
4179 six_months_ago.tv_nsec = current_time.tv_nsec;
4180
4181 recent = (timespec_cmp (six_months_ago, when_timespec) < 0
4182 && (timespec_cmp (when_timespec, current_time) < 0));
4183
4184 /* We assume here that all time zones are offset from UTC by a
4185 whole number of seconds. */
4186 s = align_nstrftime (p, TIME_STAMP_LEN_MAXIMUM + 1, recent,
4187 &when_local, localtz, when_timespec.tv_nsec);
4188 }
4189
4190 if (s || !*p)
4191 {
4192 p += s;
4193 *p++ = ' ';
4194
4195 /* NUL-terminate the string -- fputs (via DIRED_FPUTS) requires it. */
4196 *p = '\0';
4197 }
4198 else
4199 {
4200 /* The time cannot be converted using the desired format, so
4201 print it as a huge integer number of seconds. */
4202 char hbuf[INT_BUFSIZE_BOUND (intmax_t)];
4203 sprintf (p, "%*s ", long_time_expected_width (),
4204 (! f->stat_ok
4205 ? "?"
4206 : timetostr (when_timespec.tv_sec, hbuf)));
4207 /* FIXME: (maybe) We discarded when_timespec.tv_nsec. */
4208 p += strlen (p);
4209 }
4210
4211 DIRED_FPUTS (buf, stdout, p - buf);
4212 size_t w = print_name_with_quoting (f, false, &dired_obstack, p - buf);
4213
4214 if (f->filetype == symbolic_link)
4215 {
4216 if (f->linkname)
4217 {
4218 DIRED_FPUTS_LITERAL (" -> ", stdout);
4219 print_name_with_quoting (f, true, NULL, (p - buf) + w + 4);
4220 if (indicator_style != none)
4221 print_type_indicator (true, f->linkmode, unknown);
4222 }
4223 }
4224 else if (indicator_style != none)
4225 print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
4226 }
4227
4228 /* Write to *BUF a quoted representation of the file name NAME, if non-NULL,
4229 using OPTIONS to control quoting. *BUF is set to NAME if no quoting
4230 is required. *BUF is allocated if more space required (and the original
4231 *BUF is not deallocated).
4232 Store the number of screen columns occupied by NAME's quoted
4233 representation into WIDTH, if non-NULL.
4234 Store into PAD whether an initial space is needed for padding.
4235 Return the number of bytes in *BUF. */
4236
4237 static size_t
quote_name_buf(char ** inbuf,size_t bufsize,char * name,struct quoting_options const * options,int needs_general_quoting,size_t * width,bool * pad)4238 quote_name_buf (char **inbuf, size_t bufsize, char *name,
4239 struct quoting_options const *options,
4240 int needs_general_quoting, size_t *width, bool *pad)
4241 {
4242 char *buf = *inbuf;
4243 size_t displayed_width IF_LINT ( = 0);
4244 size_t len = 0;
4245 bool quoted;
4246
4247 enum quoting_style qs = get_quoting_style (options);
4248 bool needs_further_quoting = qmark_funny_chars
4249 && (qs == shell_quoting_style
4250 || qs == shell_always_quoting_style
4251 || qs == literal_quoting_style);
4252
4253 if (needs_general_quoting != 0)
4254 {
4255 len = quotearg_buffer (buf, bufsize, name, -1, options);
4256 if (bufsize <= len)
4257 {
4258 buf = xmalloc (len + 1);
4259 quotearg_buffer (buf, len + 1, name, -1, options);
4260 }
4261
4262 quoted = (*name != *buf) || strlen (name) != len;
4263 }
4264 else if (needs_further_quoting)
4265 {
4266 len = strlen (name);
4267 if (bufsize <= len)
4268 buf = xmalloc (len + 1);
4269 memcpy (buf, name, len + 1);
4270
4271 quoted = false;
4272 }
4273 else
4274 {
4275 len = strlen (name);
4276 buf = name;
4277 quoted = false;
4278 }
4279
4280 if (needs_further_quoting)
4281 {
4282 if (MB_CUR_MAX > 1)
4283 {
4284 char const *p = buf;
4285 char const *plimit = buf + len;
4286 char *q = buf;
4287 displayed_width = 0;
4288
4289 while (p < plimit)
4290 switch (*p)
4291 {
4292 case ' ': case '!': case '"': case '#': case '%':
4293 case '&': case '\'': case '(': case ')': case '*':
4294 case '+': case ',': case '-': case '.': case '/':
4295 case '0': case '1': case '2': case '3': case '4':
4296 case '5': case '6': case '7': case '8': case '9':
4297 case ':': case ';': case '<': case '=': case '>':
4298 case '?':
4299 case 'A': case 'B': case 'C': case 'D': case 'E':
4300 case 'F': case 'G': case 'H': case 'I': case 'J':
4301 case 'K': case 'L': case 'M': case 'N': case 'O':
4302 case 'P': case 'Q': case 'R': case 'S': case 'T':
4303 case 'U': case 'V': case 'W': case 'X': case 'Y':
4304 case 'Z':
4305 case '[': case '\\': case ']': case '^': case '_':
4306 case 'a': case 'b': case 'c': case 'd': case 'e':
4307 case 'f': case 'g': case 'h': case 'i': case 'j':
4308 case 'k': case 'l': case 'm': case 'n': case 'o':
4309 case 'p': case 'q': case 'r': case 's': case 't':
4310 case 'u': case 'v': case 'w': case 'x': case 'y':
4311 case 'z': case '{': case '|': case '}': case '~':
4312 /* These characters are printable ASCII characters. */
4313 *q++ = *p++;
4314 displayed_width += 1;
4315 break;
4316 default:
4317 /* If we have a multibyte sequence, copy it until we
4318 reach its end, replacing each non-printable multibyte
4319 character with a single question mark. */
4320 {
4321 mbstate_t mbstate = { 0, };
4322 do
4323 {
4324 wchar_t wc;
4325 size_t bytes;
4326 int w;
4327
4328 bytes = mbrtowc (&wc, p, plimit - p, &mbstate);
4329
4330 if (bytes == (size_t) -1)
4331 {
4332 /* An invalid multibyte sequence was
4333 encountered. Skip one input byte, and
4334 put a question mark. */
4335 p++;
4336 *q++ = '?';
4337 displayed_width += 1;
4338 break;
4339 }
4340
4341 if (bytes == (size_t) -2)
4342 {
4343 /* An incomplete multibyte character
4344 at the end. Replace it entirely with
4345 a question mark. */
4346 p = plimit;
4347 *q++ = '?';
4348 displayed_width += 1;
4349 break;
4350 }
4351
4352 if (bytes == 0)
4353 /* A null wide character was encountered. */
4354 bytes = 1;
4355
4356 w = wcwidth (wc);
4357 if (w >= 0)
4358 {
4359 /* A printable multibyte character.
4360 Keep it. */
4361 for (; bytes > 0; --bytes)
4362 *q++ = *p++;
4363 displayed_width += w;
4364 }
4365 else
4366 {
4367 /* An unprintable multibyte character.
4368 Replace it entirely with a question
4369 mark. */
4370 p += bytes;
4371 *q++ = '?';
4372 displayed_width += 1;
4373 }
4374 }
4375 while (! mbsinit (&mbstate));
4376 }
4377 break;
4378 }
4379
4380 /* The buffer may have shrunk. */
4381 len = q - buf;
4382 }
4383 else
4384 {
4385 char *p = buf;
4386 char const *plimit = buf + len;
4387
4388 while (p < plimit)
4389 {
4390 if (! isprint (to_uchar (*p)))
4391 *p = '?';
4392 p++;
4393 }
4394 displayed_width = len;
4395 }
4396 }
4397 else if (width != NULL)
4398 {
4399 if (MB_CUR_MAX > 1)
4400 displayed_width = mbsnwidth (buf, len, 0);
4401 else
4402 {
4403 char const *p = buf;
4404 char const *plimit = buf + len;
4405
4406 displayed_width = 0;
4407 while (p < plimit)
4408 {
4409 if (isprint (to_uchar (*p)))
4410 displayed_width++;
4411 p++;
4412 }
4413 }
4414 }
4415
4416 /* Set padding to better align quoted items,
4417 and also give a visual indication that quotes are
4418 not actually part of the name. */
4419 *pad = (align_variable_outer_quotes && cwd_some_quoted && ! quoted);
4420
4421 if (width != NULL)
4422 *width = displayed_width;
4423
4424 *inbuf = buf;
4425
4426 return len;
4427 }
4428
4429 static size_t
quote_name_width(const char * name,struct quoting_options const * options,int needs_general_quoting)4430 quote_name_width (const char *name, struct quoting_options const *options,
4431 int needs_general_quoting)
4432 {
4433 char smallbuf[BUFSIZ];
4434 char *buf = smallbuf;
4435 size_t width;
4436 bool pad;
4437
4438 quote_name_buf (&buf, sizeof smallbuf, (char *) name, options,
4439 needs_general_quoting, &width, &pad);
4440
4441 if (buf != smallbuf && buf != name)
4442 free (buf);
4443
4444 width += pad;
4445
4446 return width;
4447 }
4448
4449 /* %XX escape any input out of range as defined in RFC3986,
4450 and also if PATH, convert all path separators to '/'. */
4451 static char *
file_escape(const char * str,bool path)4452 file_escape (const char *str, bool path)
4453 {
4454 char *esc = xnmalloc (3, strlen (str) + 1);
4455 char *p = esc;
4456 while (*str)
4457 {
4458 if (path && ISSLASH (*str))
4459 {
4460 *p++ = '/';
4461 str++;
4462 }
4463 else if (RFC3986[to_uchar (*str)])
4464 *p++ = *str++;
4465 else
4466 p += sprintf (p, "%%%02x", to_uchar (*str++));
4467 }
4468 *p = '\0';
4469 return esc;
4470 }
4471
4472 static size_t
quote_name(char const * name,struct quoting_options const * options,int needs_general_quoting,const struct bin_str * color,bool allow_pad,struct obstack * stack,char const * absolute_name)4473 quote_name (char const *name, struct quoting_options const *options,
4474 int needs_general_quoting, const struct bin_str *color,
4475 bool allow_pad, struct obstack *stack, char const *absolute_name)
4476 {
4477 char smallbuf[BUFSIZ];
4478 char *buf = smallbuf;
4479 size_t len;
4480 bool pad;
4481
4482 len = quote_name_buf (&buf, sizeof smallbuf, (char *) name, options,
4483 needs_general_quoting, NULL, &pad);
4484
4485 if (pad && allow_pad)
4486 DIRED_PUTCHAR (' ');
4487
4488 if (color)
4489 print_color_indicator (color);
4490
4491 /* If we're padding, then don't include the outer quotes in
4492 the --hyperlink, to improve the alignment of those links. */
4493 bool skip_quotes = false;
4494
4495 if (absolute_name)
4496 {
4497 if (align_variable_outer_quotes && cwd_some_quoted && ! pad)
4498 {
4499 skip_quotes = true;
4500 putchar (*buf);
4501 }
4502 char *h = file_escape (hostname, /* path= */ false);
4503 char *n = file_escape (absolute_name, /* path= */ true);
4504 /* TODO: It would be good to be able to define parameters
4505 to give hints to the terminal as how best to render the URI.
4506 For example since ls is outputting a dense block of URIs
4507 it would be best to not underline by default, and only
4508 do so upon hover etc. */
4509 printf ("\033]8;;file://%s%s%s\a", h, *n == '/' ? "" : "/", n);
4510 free (h);
4511 free (n);
4512 }
4513
4514 if (stack)
4515 PUSH_CURRENT_DIRED_POS (stack);
4516
4517 fwrite (buf + skip_quotes, 1, len - (skip_quotes * 2), stdout);
4518
4519 dired_pos += len;
4520
4521 if (stack)
4522 PUSH_CURRENT_DIRED_POS (stack);
4523
4524 if (absolute_name)
4525 {
4526 fputs ("\033]8;;\a", stdout);
4527 if (skip_quotes)
4528 putchar (*(buf + len - 1));
4529 }
4530
4531 if (buf != smallbuf && buf != name)
4532 free (buf);
4533
4534 return len + pad;
4535 }
4536
4537 static size_t
print_name_with_quoting(const struct fileinfo * f,bool symlink_target,struct obstack * stack,size_t start_col)4538 print_name_with_quoting (const struct fileinfo *f,
4539 bool symlink_target,
4540 struct obstack *stack,
4541 size_t start_col)
4542 {
4543 const char* name = symlink_target ? f->linkname : f->name;
4544
4545 const struct bin_str *color = print_with_color ?
4546 get_color_indicator (f, symlink_target) : NULL;
4547
4548 bool used_color_this_time = (print_with_color
4549 && (color || is_colored (C_NORM)));
4550
4551 size_t len = quote_name (name, filename_quoting_options, f->quoted,
4552 color, !symlink_target, stack, f->absolute_name);
4553
4554 process_signals ();
4555 if (used_color_this_time)
4556 {
4557 prep_non_filename_text ();
4558
4559 /* We use the byte length rather than display width here as
4560 an optimization to avoid accurately calculating the width,
4561 because we only output the clear to EOL sequence if the name
4562 _might_ wrap to the next line. This may output a sequence
4563 unnecessarily in multi-byte locales for example,
4564 but in that case it's inconsequential to the output. */
4565 if (line_length
4566 && (start_col / line_length != (start_col + len - 1) / line_length))
4567 put_indicator (&color_indicator[C_CLR_TO_EOL]);
4568 }
4569
4570 return len;
4571 }
4572
4573 static void
prep_non_filename_text(void)4574 prep_non_filename_text (void)
4575 {
4576 if (color_indicator[C_END].string != NULL)
4577 put_indicator (&color_indicator[C_END]);
4578 else
4579 {
4580 put_indicator (&color_indicator[C_LEFT]);
4581 put_indicator (&color_indicator[C_RESET]);
4582 put_indicator (&color_indicator[C_RIGHT]);
4583 }
4584 }
4585
4586 /* Print the file name of 'f' with appropriate quoting.
4587 Also print file size, inode number, and filetype indicator character,
4588 as requested by switches. */
4589
4590 static size_t
print_file_name_and_frills(const struct fileinfo * f,size_t start_col)4591 print_file_name_and_frills (const struct fileinfo *f, size_t start_col)
4592 {
4593 char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))];
4594
4595 set_normal_color ();
4596
4597 if (print_inode)
4598 printf ("%*s ", format == with_commas ? 0 : inode_number_width,
4599 format_inode (buf, sizeof buf, f));
4600
4601 if (print_block_size)
4602 printf ("%*s ", format == with_commas ? 0 : block_size_width,
4603 ! f->stat_ok ? "?"
4604 : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts,
4605 ST_NBLOCKSIZE, output_block_size));
4606
4607 if (print_scontext)
4608 printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext);
4609
4610 size_t width = print_name_with_quoting (f, false, NULL, start_col);
4611
4612 if (indicator_style != none)
4613 width += print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
4614
4615 return width;
4616 }
4617
4618 /* Given these arguments describing a file, return the single-byte
4619 type indicator, or 0. */
4620 static char
get_type_indicator(bool stat_ok,mode_t mode,enum filetype type)4621 get_type_indicator (bool stat_ok, mode_t mode, enum filetype type)
4622 {
4623 char c;
4624
4625 if (stat_ok ? S_ISREG (mode) : type == normal)
4626 {
4627 if (stat_ok && indicator_style == classify && (mode & S_IXUGO))
4628 c = '*';
4629 else
4630 c = 0;
4631 }
4632 else
4633 {
4634 if (stat_ok ? S_ISDIR (mode) : type == directory || type == arg_directory)
4635 c = '/';
4636 else if (indicator_style == slash)
4637 c = 0;
4638 else if (stat_ok ? S_ISLNK (mode) : type == symbolic_link)
4639 c = '@';
4640 else if (stat_ok ? S_ISFIFO (mode) : type == fifo)
4641 c = '|';
4642 else if (stat_ok ? S_ISSOCK (mode) : type == sock)
4643 c = '=';
4644 else if (stat_ok && S_ISDOOR (mode))
4645 c = '>';
4646 else
4647 c = 0;
4648 }
4649 return c;
4650 }
4651
4652 static bool
print_type_indicator(bool stat_ok,mode_t mode,enum filetype type)4653 print_type_indicator (bool stat_ok, mode_t mode, enum filetype type)
4654 {
4655 char c = get_type_indicator (stat_ok, mode, type);
4656 if (c)
4657 DIRED_PUTCHAR (c);
4658 return !!c;
4659 }
4660
4661 /* Returns if color sequence was printed. */
4662 static bool
print_color_indicator(const struct bin_str * ind)4663 print_color_indicator (const struct bin_str *ind)
4664 {
4665 if (ind)
4666 {
4667 /* Need to reset so not dealing with attribute combinations */
4668 if (is_colored (C_NORM))
4669 restore_default_color ();
4670 put_indicator (&color_indicator[C_LEFT]);
4671 put_indicator (ind);
4672 put_indicator (&color_indicator[C_RIGHT]);
4673 }
4674
4675 return ind != NULL;
4676 }
4677
4678 /* Returns color indicator or NULL if none. */
4679 static const struct bin_str* _GL_ATTRIBUTE_PURE
get_color_indicator(const struct fileinfo * f,bool symlink_target)4680 get_color_indicator (const struct fileinfo *f, bool symlink_target)
4681 {
4682 enum indicator_no type;
4683 struct color_ext_type *ext; /* Color extension */
4684 size_t len; /* Length of name */
4685
4686 const char* name;
4687 mode_t mode;
4688 int linkok;
4689 if (symlink_target)
4690 {
4691 name = f->linkname;
4692 mode = f->linkmode;
4693 linkok = f->linkok ? 0 : -1;
4694 }
4695 else
4696 {
4697 name = f->name;
4698 mode = FILE_OR_LINK_MODE (f);
4699 linkok = f->linkok;
4700 }
4701
4702 /* Is this a nonexistent file? If so, linkok == -1. */
4703
4704 if (linkok == -1 && is_colored (C_MISSING))
4705 type = C_MISSING;
4706 else if (!f->stat_ok)
4707 {
4708 static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS;
4709 type = filetype_indicator[f->filetype];
4710 }
4711 else
4712 {
4713 if (S_ISREG (mode))
4714 {
4715 type = C_FILE;
4716
4717 if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
4718 type = C_SETUID;
4719 else if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
4720 type = C_SETGID;
4721 else if (is_colored (C_CAP) && f->has_capability)
4722 type = C_CAP;
4723 else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC))
4724 type = C_EXEC;
4725 else if ((1 < f->stat.st_nlink) && is_colored (C_MULTIHARDLINK))
4726 type = C_MULTIHARDLINK;
4727 }
4728 else if (S_ISDIR (mode))
4729 {
4730 type = C_DIR;
4731
4732 if ((mode & S_ISVTX) && (mode & S_IWOTH)
4733 && is_colored (C_STICKY_OTHER_WRITABLE))
4734 type = C_STICKY_OTHER_WRITABLE;
4735 else if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE))
4736 type = C_OTHER_WRITABLE;
4737 else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY))
4738 type = C_STICKY;
4739 }
4740 else if (S_ISLNK (mode))
4741 type = C_LINK;
4742 else if (S_ISFIFO (mode))
4743 type = C_FIFO;
4744 else if (S_ISSOCK (mode))
4745 type = C_SOCK;
4746 else if (S_ISBLK (mode))
4747 type = C_BLK;
4748 else if (S_ISCHR (mode))
4749 type = C_CHR;
4750 else if (S_ISDOOR (mode))
4751 type = C_DOOR;
4752 else
4753 {
4754 /* Classify a file of some other type as C_ORPHAN. */
4755 type = C_ORPHAN;
4756 }
4757 }
4758
4759 /* Check the file's suffix only if still classified as C_FILE. */
4760 ext = NULL;
4761 if (type == C_FILE)
4762 {
4763 /* Test if NAME has a recognized suffix. */
4764
4765 len = strlen (name);
4766 name += len; /* Pointer to final \0. */
4767 for (ext = color_ext_list; ext != NULL; ext = ext->next)
4768 {
4769 if (ext->ext.len <= len
4770 && c_strncasecmp (name - ext->ext.len, ext->ext.string,
4771 ext->ext.len) == 0)
4772 break;
4773 }
4774 }
4775
4776 /* Adjust the color for orphaned symlinks. */
4777 if (type == C_LINK && !linkok)
4778 {
4779 if (color_symlink_as_referent || is_colored (C_ORPHAN))
4780 type = C_ORPHAN;
4781 }
4782
4783 const struct bin_str *const s
4784 = ext ? &(ext->seq) : &color_indicator[type];
4785
4786 return s->string ? s : NULL;
4787 }
4788
4789 /* Output a color indicator (which may contain nulls). */
4790 static void
put_indicator(const struct bin_str * ind)4791 put_indicator (const struct bin_str *ind)
4792 {
4793 if (! used_color)
4794 {
4795 used_color = true;
4796
4797 /* If the standard output is a controlling terminal, watch out
4798 for signals, so that the colors can be restored to the
4799 default state if "ls" is suspended or interrupted. */
4800
4801 if (0 <= tcgetpgrp (STDOUT_FILENO))
4802 signal_init ();
4803
4804 prep_non_filename_text ();
4805 }
4806
4807 fwrite (ind->string, ind->len, 1, stdout);
4808 }
4809
4810 static size_t
length_of_file_name_and_frills(const struct fileinfo * f)4811 length_of_file_name_and_frills (const struct fileinfo *f)
4812 {
4813 size_t len = 0;
4814 char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))];
4815
4816 if (print_inode)
4817 len += 1 + (format == with_commas
4818 ? strlen (umaxtostr (f->stat.st_ino, buf))
4819 : inode_number_width);
4820
4821 if (print_block_size)
4822 len += 1 + (format == with_commas
4823 ? strlen (! f->stat_ok ? "?"
4824 : human_readable (ST_NBLOCKS (f->stat), buf,
4825 human_output_opts, ST_NBLOCKSIZE,
4826 output_block_size))
4827 : block_size_width);
4828
4829 if (print_scontext)
4830 len += 1 + (format == with_commas ? strlen (f->scontext) : scontext_width);
4831
4832 len += quote_name_width (f->name, filename_quoting_options, f->quoted);
4833
4834 if (indicator_style != none)
4835 {
4836 char c = get_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
4837 len += (c != 0);
4838 }
4839
4840 return len;
4841 }
4842
4843 static void
print_many_per_line(void)4844 print_many_per_line (void)
4845 {
4846 size_t row; /* Current row. */
4847 size_t cols = calculate_columns (true);
4848 struct column_info const *line_fmt = &column_info[cols - 1];
4849
4850 /* Calculate the number of rows that will be in each column except possibly
4851 for a short column on the right. */
4852 size_t rows = cwd_n_used / cols + (cwd_n_used % cols != 0);
4853
4854 for (row = 0; row < rows; row++)
4855 {
4856 size_t col = 0;
4857 size_t filesno = row;
4858 size_t pos = 0;
4859
4860 /* Print the next row. */
4861 while (1)
4862 {
4863 struct fileinfo const *f = sorted_file[filesno];
4864 size_t name_length = length_of_file_name_and_frills (f);
4865 size_t max_name_length = line_fmt->col_arr[col++];
4866 print_file_name_and_frills (f, pos);
4867
4868 filesno += rows;
4869 if (filesno >= cwd_n_used)
4870 break;
4871
4872 indent (pos + name_length, pos + max_name_length);
4873 pos += max_name_length;
4874 }
4875 putchar ('\n');
4876 }
4877 }
4878
4879 static void
print_horizontal(void)4880 print_horizontal (void)
4881 {
4882 size_t filesno;
4883 size_t pos = 0;
4884 size_t cols = calculate_columns (false);
4885 struct column_info const *line_fmt = &column_info[cols - 1];
4886 struct fileinfo const *f = sorted_file[0];
4887 size_t name_length = length_of_file_name_and_frills (f);
4888 size_t max_name_length = line_fmt->col_arr[0];
4889
4890 /* Print first entry. */
4891 print_file_name_and_frills (f, 0);
4892
4893 /* Now the rest. */
4894 for (filesno = 1; filesno < cwd_n_used; ++filesno)
4895 {
4896 size_t col = filesno % cols;
4897
4898 if (col == 0)
4899 {
4900 putchar ('\n');
4901 pos = 0;
4902 }
4903 else
4904 {
4905 indent (pos + name_length, pos + max_name_length);
4906 pos += max_name_length;
4907 }
4908
4909 f = sorted_file[filesno];
4910 print_file_name_and_frills (f, pos);
4911
4912 name_length = length_of_file_name_and_frills (f);
4913 max_name_length = line_fmt->col_arr[col];
4914 }
4915 putchar ('\n');
4916 }
4917
4918 /* Output name + SEP + ' '. */
4919
4920 static void
print_with_separator(char sep)4921 print_with_separator (char sep)
4922 {
4923 size_t filesno;
4924 size_t pos = 0;
4925
4926 for (filesno = 0; filesno < cwd_n_used; filesno++)
4927 {
4928 struct fileinfo const *f = sorted_file[filesno];
4929 size_t len = line_length ? length_of_file_name_and_frills (f) : 0;
4930
4931 if (filesno != 0)
4932 {
4933 char separator;
4934
4935 if (! line_length
4936 || ((pos + len + 2 < line_length)
4937 && (pos <= SIZE_MAX - len - 2)))
4938 {
4939 pos += 2;
4940 separator = ' ';
4941 }
4942 else
4943 {
4944 pos = 0;
4945 separator = '\n';
4946 }
4947
4948 putchar (sep);
4949 putchar (separator);
4950 }
4951
4952 print_file_name_and_frills (f, pos);
4953 pos += len;
4954 }
4955 putchar ('\n');
4956 }
4957
4958 /* Assuming cursor is at position FROM, indent up to position TO.
4959 Use a TAB character instead of two or more spaces whenever possible. */
4960
4961 static void
indent(size_t from,size_t to)4962 indent (size_t from, size_t to)
4963 {
4964 while (from < to)
4965 {
4966 if (tabsize != 0 && to / tabsize > (from + 1) / tabsize)
4967 {
4968 putchar ('\t');
4969 from += tabsize - from % tabsize;
4970 }
4971 else
4972 {
4973 putchar (' ');
4974 from++;
4975 }
4976 }
4977 }
4978
4979 /* Put DIRNAME/NAME into DEST, handling '.' and '/' properly. */
4980 /* FIXME: maybe remove this function someday. See about using a
4981 non-malloc'ing version of file_name_concat. */
4982
4983 static void
attach(char * dest,const char * dirname,const char * name)4984 attach (char *dest, const char *dirname, const char *name)
4985 {
4986 const char *dirnamep = dirname;
4987
4988 /* Copy dirname if it is not ".". */
4989 if (dirname[0] != '.' || dirname[1] != 0)
4990 {
4991 while (*dirnamep)
4992 *dest++ = *dirnamep++;
4993 /* Add '/' if 'dirname' doesn't already end with it. */
4994 if (dirnamep > dirname && dirnamep[-1] != '/')
4995 *dest++ = '/';
4996 }
4997 while (*name)
4998 *dest++ = *name++;
4999 *dest = 0;
5000 }
5001
5002 /* Allocate enough column info suitable for the current number of
5003 files and display columns, and initialize the info to represent the
5004 narrowest possible columns. */
5005
5006 static void
init_column_info(void)5007 init_column_info (void)
5008 {
5009 size_t i;
5010 size_t max_cols = MIN (max_idx, cwd_n_used);
5011
5012 /* Currently allocated columns in column_info. */
5013 static size_t column_info_alloc;
5014
5015 if (column_info_alloc < max_cols)
5016 {
5017 size_t new_column_info_alloc;
5018 size_t *p;
5019
5020 if (max_cols < max_idx / 2)
5021 {
5022 /* The number of columns is far less than the display width
5023 allows. Grow the allocation, but only so that it's
5024 double the current requirements. If the display is
5025 extremely wide, this avoids allocating a lot of memory
5026 that is never needed. */
5027 column_info = xnrealloc (column_info, max_cols,
5028 2 * sizeof *column_info);
5029 new_column_info_alloc = 2 * max_cols;
5030 }
5031 else
5032 {
5033 column_info = xnrealloc (column_info, max_idx, sizeof *column_info);
5034 new_column_info_alloc = max_idx;
5035 }
5036
5037 /* Allocate the new size_t objects by computing the triangle
5038 formula n * (n + 1) / 2, except that we don't need to
5039 allocate the part of the triangle that we've already
5040 allocated. Check for address arithmetic overflow. */
5041 {
5042 size_t column_info_growth = new_column_info_alloc - column_info_alloc;
5043 size_t s = column_info_alloc + 1 + new_column_info_alloc;
5044 size_t t = s * column_info_growth;
5045 if (s < new_column_info_alloc || t / column_info_growth != s)
5046 xalloc_die ();
5047 p = xnmalloc (t / 2, sizeof *p);
5048 }
5049
5050 /* Grow the triangle by parceling out the cells just allocated. */
5051 for (i = column_info_alloc; i < new_column_info_alloc; i++)
5052 {
5053 column_info[i].col_arr = p;
5054 p += i + 1;
5055 }
5056
5057 column_info_alloc = new_column_info_alloc;
5058 }
5059
5060 for (i = 0; i < max_cols; ++i)
5061 {
5062 size_t j;
5063
5064 column_info[i].valid_len = true;
5065 column_info[i].line_len = (i + 1) * MIN_COLUMN_WIDTH;
5066 for (j = 0; j <= i; ++j)
5067 column_info[i].col_arr[j] = MIN_COLUMN_WIDTH;
5068 }
5069 }
5070
5071 /* Calculate the number of columns needed to represent the current set
5072 of files in the current display width. */
5073
5074 static size_t
calculate_columns(bool by_columns)5075 calculate_columns (bool by_columns)
5076 {
5077 size_t filesno; /* Index into cwd_file. */
5078 size_t cols; /* Number of files across. */
5079
5080 /* Normally the maximum number of columns is determined by the
5081 screen width. But if few files are available this might limit it
5082 as well. */
5083 size_t max_cols = MIN (max_idx, cwd_n_used);
5084
5085 init_column_info ();
5086
5087 /* Compute the maximum number of possible columns. */
5088 for (filesno = 0; filesno < cwd_n_used; ++filesno)
5089 {
5090 struct fileinfo const *f = sorted_file[filesno];
5091 size_t name_length = length_of_file_name_and_frills (f);
5092
5093 for (size_t i = 0; i < max_cols; ++i)
5094 {
5095 if (column_info[i].valid_len)
5096 {
5097 size_t idx = (by_columns
5098 ? filesno / ((cwd_n_used + i) / (i + 1))
5099 : filesno % (i + 1));
5100 size_t real_length = name_length + (idx == i ? 0 : 2);
5101
5102 if (column_info[i].col_arr[idx] < real_length)
5103 {
5104 column_info[i].line_len += (real_length
5105 - column_info[i].col_arr[idx]);
5106 column_info[i].col_arr[idx] = real_length;
5107 column_info[i].valid_len = (column_info[i].line_len
5108 < line_length);
5109 }
5110 }
5111 }
5112 }
5113
5114 /* Find maximum allowed columns. */
5115 for (cols = max_cols; 1 < cols; --cols)
5116 {
5117 if (column_info[cols - 1].valid_len)
5118 break;
5119 }
5120
5121 return cols;
5122 }
5123
5124 void
usage(int status)5125 usage (int status)
5126 {
5127 if (status != EXIT_SUCCESS)
5128 emit_try_help ();
5129 else
5130 {
5131 printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);
5132 fputs (_("\
5133 List information about the FILEs (the current directory by default).\n\
5134 Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.\n\
5135 "), stdout);
5136
5137 emit_mandatory_arg_note ();
5138
5139 fputs (_("\
5140 -a, --all do not ignore entries starting with .\n\
5141 -A, --almost-all do not list implied . and ..\n\
5142 --author with -l, print the author of each file\n\
5143 -b, --escape print C-style escapes for nongraphic characters\n\
5144 "), stdout);
5145 fputs (_("\
5146 --block-size=SIZE with -l, scale sizes by SIZE when printing them;\n\
5147 e.g., '--block-size=M'; see SIZE format below\n\
5148 "), stdout);
5149 fputs (_("\
5150 -B, --ignore-backups do not list implied entries ending with ~\n\
5151 -c with -lt: sort by, and show, ctime (time of last\n\
5152 modification of file status information);\n\
5153 with -l: show ctime and sort by name;\n\
5154 otherwise: sort by ctime, newest first\n\
5155 "), stdout);
5156 fputs (_("\
5157 -C list entries by columns\n\
5158 --color[=WHEN] colorize the output; WHEN can be 'always' (default\
5159 \n\
5160 if omitted), 'auto', or 'never'; more info below\
5161 \n\
5162 -d, --directory list directories themselves, not their contents\n\
5163 -D, --dired generate output designed for Emacs' dired mode\n\
5164 "), stdout);
5165 fputs (_("\
5166 -f do not sort, enable -aU, disable -ls --color\n\
5167 -F, --classify append indicator (one of */=>@|) to entries\n\
5168 --file-type likewise, except do not append '*'\n\
5169 --format=WORD across -x, commas -m, horizontal -x, long -l,\n\
5170 single-column -1, verbose -l, vertical -C\n\
5171 --full-time like -l --time-style=full-iso\n\
5172 "), stdout);
5173 fputs (_("\
5174 -g like -l, but do not list owner\n\
5175 "), stdout);
5176 fputs (_("\
5177 --group-directories-first\n\
5178 group directories before files;\n\
5179 can be augmented with a --sort option, but any\n\
5180 use of --sort=none (-U) disables grouping\n\
5181 "), stdout);
5182 fputs (_("\
5183 -G, --no-group in a long listing, don't print group names\n\
5184 "), stdout);
5185 fputs (_("\
5186 -h, --human-readable with -l and -s, print sizes like 1K 234M 2G etc.\n\
5187 --si likewise, but use powers of 1000 not 1024\n\
5188 "), stdout);
5189 fputs (_("\
5190 -H, --dereference-command-line\n\
5191 follow symbolic links listed on the command line\n\
5192 --dereference-command-line-symlink-to-dir\n\
5193 follow each command line symbolic link\n\
5194 that points to a directory\n\
5195 --hide=PATTERN do not list implied entries matching shell PATTERN\
5196 \n\
5197 (overridden by -a or -A)\n\
5198 "), stdout);
5199 fputs (_("\
5200 --hyperlink[=WHEN] hyperlink file names; WHEN can be 'always'\n\
5201 (default if omitted), 'auto', or 'never'\n\
5202 "), stdout);
5203 fputs (_("\
5204 --indicator-style=WORD append indicator with style WORD to entry names:\
5205 \n\
5206 none (default), slash (-p),\n\
5207 file-type (--file-type), classify (-F)\n\
5208 -i, --inode print the index number of each file\n\
5209 -I, --ignore=PATTERN do not list implied entries matching shell PATTERN\
5210 \n\
5211 "), stdout);
5212 fputs (_("\
5213 -k, --kibibytes default to 1024-byte blocks for disk usage;\n\
5214 used only with -s and per directory totals\n\
5215 "), stdout);
5216 fputs (_("\
5217 -l use a long listing format\n\
5218 -L, --dereference when showing file information for a symbolic\n\
5219 link, show information for the file the link\n\
5220 references rather than for the link itself\n\
5221 -m fill width with a comma separated list of entries\
5222 \n\
5223 "), stdout);
5224 fputs (_("\
5225 -n, --numeric-uid-gid like -l, but list numeric user and group IDs\n\
5226 -N, --literal print entry names without quoting\n\
5227 -o like -l, but do not list group information\n\
5228 -p, --indicator-style=slash\n\
5229 append / indicator to directories\n\
5230 "), stdout);
5231 fputs (_("\
5232 -q, --hide-control-chars print ? instead of nongraphic characters\n\
5233 --show-control-chars show nongraphic characters as-is (the default,\n\
5234 unless program is 'ls' and output is a terminal)\
5235 \n\
5236 -Q, --quote-name enclose entry names in double quotes\n\
5237 --quoting-style=WORD use quoting style WORD for entry names:\n\
5238 literal, locale, shell, shell-always,\n\
5239 shell-escape, shell-escape-always, c, escape\n\
5240 (overrides QUOTING_STYLE environment variable)\n\
5241 "), stdout);
5242 fputs (_("\
5243 -r, --reverse reverse order while sorting\n\
5244 -R, --recursive list subdirectories recursively\n\
5245 -s, --size print the allocated size of each file, in blocks\n\
5246 "), stdout);
5247 fputs (_("\
5248 -S sort by file size, largest first\n\
5249 --sort=WORD sort by WORD instead of name: none (-U), size (-S)\
5250 ,\n\
5251 time (-t), version (-v), extension (-X)\n\
5252 --time=WORD with -l, show time as WORD instead of default\n\
5253 modification time: atime or access or use (-u);\
5254 \n\
5255 ctime or status (-c); also use specified time\n\
5256 as sort key if --sort=time (newest first)\n\
5257 "), stdout);
5258 fputs (_("\
5259 --time-style=TIME_STYLE time/date format with -l; see TIME_STYLE below\n\
5260 "), stdout);
5261 fputs (_("\
5262 -t sort by modification time, newest first\n\
5263 -T, --tabsize=COLS assume tab stops at each COLS instead of 8\n\
5264 "), stdout);
5265 fputs (_("\
5266 -u with -lt: sort by, and show, access time;\n\
5267 with -l: show access time and sort by name;\n\
5268 otherwise: sort by access time, newest first\n\
5269 -U do not sort; list entries in directory order\n\
5270 -v natural sort of (version) numbers within text\n\
5271 "), stdout);
5272 fputs (_("\
5273 -w, --width=COLS set output width to COLS. 0 means no limit\n\
5274 -x list entries by lines instead of by columns\n\
5275 -X sort alphabetically by entry extension\n\
5276 -Z, --context print any security context of each file\n\
5277 -1 list one file per line. Avoid '\\n' with -q or -b\
5278 \n\
5279 "), stdout);
5280 fputs (HELP_OPTION_DESCRIPTION, stdout);
5281 fputs (VERSION_OPTION_DESCRIPTION, stdout);
5282 emit_size_note ();
5283 fputs (_("\
5284 \n\
5285 The TIME_STYLE argument can be full-iso, long-iso, iso, locale, or +FORMAT.\n\
5286 FORMAT is interpreted like in date(1). If FORMAT is FORMAT1<newline>FORMAT2,\n\
5287 then FORMAT1 applies to non-recent files and FORMAT2 to recent files.\n\
5288 TIME_STYLE prefixed with 'posix-' takes effect only outside the POSIX locale.\n\
5289 Also the TIME_STYLE environment variable sets the default style to use.\n\
5290 "), stdout);
5291 fputs (_("\
5292 \n\
5293 Using color to distinguish file types is disabled both by default and\n\
5294 with --color=never. With --color=auto, ls emits color codes only when\n\
5295 standard output is connected to a terminal. The LS_COLORS environment\n\
5296 variable can change the settings. Use the dircolors command to set it.\n\
5297 "), stdout);
5298 fputs (_("\
5299 \n\
5300 Exit status:\n\
5301 0 if OK,\n\
5302 1 if minor problems (e.g., cannot access subdirectory),\n\
5303 2 if serious trouble (e.g., cannot access command-line argument).\n\
5304 "), stdout);
5305 emit_ancillary_info (PROGRAM_NAME);
5306 }
5307 exit (status);
5308 }
5309