1 /* `dir', `vdir' and `ls' directory listing programs for GNU.
2 Copyright (C) 85, 88, 90, 91, 1995-2001 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /* If ls_mode is LS_MULTI_COL,
19 the multi-column format is the default regardless
20 of the type of output device.
21 This is for the `dir' program.
23 If ls_mode is LS_LONG_FORMAT,
24 the long format is the default regardless of the
25 type of output device.
26 This is for the `vdir' program.
29 the output format depends on whether the output
31 This is for the `ls' program. */
33 /* Written by Richard Stallman and David MacKenzie. */
35 /* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
36 Flaherty <dennisf@denix.elk.miles.com> based on original patches by
37 Greg Lee <lee@uhunix.uhcc.hawaii.edu>. */
44 #include <sys/types.h>
47 # include <inttypes.h>
54 #ifdef GWINSZ_IN_SYS_IOCTL
55 # include <sys/ioctl.h>
58 #ifdef WINSIZE_IN_PTEM
59 # include <sys/stream.h>
60 # include <sys/ptem.h>
78 /* Get mbstate_t, mbrtowc(), mbsinit(), wcwidth(). */
87 #if !defined iswprint && !HAVE_ISWPRINT
88 # define iswprint(wc) 1
91 #ifndef HAVE_DECL_WCWIDTH
92 "this configure-time declaration test was not run"
94 #if !HAVE_DECL_WCWIDTH
98 /* If wcwidth() doesn't exist, assume all printable characters have
102 # define wcwidth(wc) ((wc) == 0 ? 0 : iswprint (wc) ? 1 : -1)
109 #include "argmatch.h"
113 #include "hard-locale.h"
116 #include "filemode.h"
118 #include "mbswidth.h"
120 #include "path-concat.h"
121 #include "quotearg.h"
123 #include "strverscmp.h"
126 #include "xreadlink.h"
128 /* Use access control lists only under all the following conditions.
129 Some systems (OSF4, Irix5, Irix6) have the acl function, but not
130 sys/acl.h or don't define the GETACLCNT macro. */
131 #if HAVE_SYS_ACL_H && HAVE_ACL && defined GETACLCNT
135 #define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \
136 : (ls_mode == LS_MULTI_COL \
139 #define AUTHORS N_ ("Richard Stallman and David MacKenzie")
141 #define obstack_chunk_alloc malloc
142 #define obstack_chunk_free free
144 /* Return an int indicating the result of comparing two integers.
145 Subtracting doesn't always work, due to overflow. */
146 #define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b))
148 /* The field width for inode numbers. On some hosts inode numbers are
149 64 bits, so columns won't line up exactly when a huge inode number
150 is encountered, but in practice 7 digits is usually enough. */
152 # define INODE_DIGITS 7
156 # define HAVE_SYMLINKS 1
158 # define HAVE_SYMLINKS 0
161 /* If any of the S_* macros are undefined, define them here so each
162 use doesn't have to be guarded with e.g., #ifdef S_ISLNK. */
164 # define S_ISLNK(Mode) 0
168 # define S_ISFIFO(Mode) 0
172 # define S_ISSOCK(Mode) 0
176 # define S_ISCHR(Mode) 0
180 # define S_ISBLK(Mode) 0
184 # define S_ISDOOR(Mode) 0
187 /* Arrange to make lstat calls go through the wrapper function
188 on systems with an lstat function that does not dereference symlinks
189 that are specified with a trailing slash. */
190 #if ! LSTAT_FOLLOWS_SLASHED_SYMLINK
191 int rpl_lstat PARAMS((const char *, struct stat *));
193 # define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
196 #if D_TYPE_IN_DIRENT && defined DTTOIF
197 # define HAVE_STRUCT_DIRENT_D_TYPE 1
198 # define DT_INIT(Val) = Val
200 # define HAVE_STRUCT_DIRENT_D_TYPE 0
201 # define DT_INIT(Val) /* empty */
205 # define TIMESPEC_NS(timespec) ((timespec).ST_MTIM_NSEC)
207 # define TIMESPEC_NS(timespec) 0
212 unknown DT_INIT (DT_UNKNOWN),
213 fifo DT_INIT (DT_FIFO),
214 chardev DT_INIT (DT_CHR),
215 directory DT_INIT (DT_DIR),
216 blockdev DT_INIT (DT_BLK),
217 normal DT_INIT (DT_REG),
218 symbolic_link DT_INIT (DT_LNK),
219 sock DT_INIT (DT_SOCK),
220 arg_directory DT_INIT (2 * (DT_UNKNOWN | DT_FIFO | DT_CHR | DT_DIR | DT_BLK
221 | DT_REG | DT_LNK | DT_SOCK))
231 /* For symbolic link, name of the file linked to, otherwise zero. */
234 /* For symbolic link and long listing, st_mode of file linked to, otherwise
238 /* For symbolic link and color printing, 1 if linked-to file
239 exists, otherwise 0. */
242 enum filetype filetype;
245 /* For long listings, nonzero if the file has an access control list,
252 # define FILE_HAS_ACL(F) ((F)->have_acl)
254 # define FILE_HAS_ACL(F) 0
257 #define LEN_STR_PAIR(s) sizeof (s) - 1, s
259 /* Null is a valid character in a color indicator (think about Epson
260 printers, for example) so we have to use a length/buffer string
265 int len; /* Number of bytes */
266 const char *string; /* Pointer to the same */
273 size_t nstrftime PARAMS ((char *, size_t, char const *,
274 struct tm const *, int, int));
278 static size_t quote_name PARAMS ((FILE *out, const char *name,
279 struct quoting_options const *options));
280 static char *make_link_path PARAMS ((const char *path, const char *linkname));
281 static int compare_atime PARAMS ((const struct fileinfo *file1,
282 const struct fileinfo *file2));
283 static int rev_cmp_atime PARAMS ((const struct fileinfo *file2,
284 const struct fileinfo *file1));
285 static int compare_ctime PARAMS ((const struct fileinfo *file1,
286 const struct fileinfo *file2));
287 static int rev_cmp_ctime PARAMS ((const struct fileinfo *file2,
288 const struct fileinfo *file1));
289 static int compare_mtime PARAMS ((const struct fileinfo *file1,
290 const struct fileinfo *file2));
291 static int rev_cmp_mtime PARAMS ((const struct fileinfo *file2,
292 const struct fileinfo *file1));
293 static int compare_size PARAMS ((const struct fileinfo *file1,
294 const struct fileinfo *file2));
295 static int rev_cmp_size PARAMS ((const struct fileinfo *file2,
296 const struct fileinfo *file1));
297 static int compare_name PARAMS ((const struct fileinfo *file1,
298 const struct fileinfo *file2));
299 static int rev_cmp_name PARAMS ((const struct fileinfo *file2,
300 const struct fileinfo *file1));
301 static int compare_extension PARAMS ((const struct fileinfo *file1,
302 const struct fileinfo *file2));
303 static int rev_cmp_extension PARAMS ((const struct fileinfo *file2,
304 const struct fileinfo *file1));
305 static int compare_version PARAMS ((const struct fileinfo *file1,
306 const struct fileinfo *file2));
307 static int rev_cmp_version PARAMS ((const struct fileinfo *file2,
308 const struct fileinfo *file1));
309 static int decode_switches PARAMS ((int argc, char **argv));
310 static int file_interesting PARAMS ((const struct dirent *next));
311 static uintmax_t gobble_file PARAMS ((const char *name, enum filetype type,
312 int explicit_arg, const char *dirname));
313 static void print_color_indicator PARAMS ((const char *name, mode_t mode,
315 static void put_indicator PARAMS ((const struct bin_str *ind));
316 static int length_of_file_name_and_frills PARAMS ((const struct fileinfo *f));
317 static void add_ignore_pattern PARAMS ((const char *pattern));
318 static void attach PARAMS ((char *dest, const char *dirname, const char *name));
319 static void clear_files PARAMS ((void));
320 static void extract_dirs_from_files PARAMS ((const char *dirname,
321 int ignore_dot_and_dot_dot));
322 static void get_link_name PARAMS ((const char *filename, struct fileinfo *f));
323 static void indent PARAMS ((int from, int to));
324 static void init_column_info PARAMS ((void));
325 static void print_current_files PARAMS ((void));
326 static void print_dir PARAMS ((const char *name, const char *realname));
327 static void print_file_name_and_frills PARAMS ((const struct fileinfo *f));
328 static void print_horizontal PARAMS ((void));
329 static void print_long_format PARAMS ((const struct fileinfo *f));
330 static void print_many_per_line PARAMS ((void));
331 static void print_name_with_quoting PARAMS ((const char *p, mode_t mode,
333 struct obstack *stack));
334 static void prep_non_filename_text PARAMS ((void));
335 static void print_type_indicator PARAMS ((mode_t mode));
336 static void print_with_commas PARAMS ((void));
337 static void queue_directory PARAMS ((const char *name, const char *realname));
338 static void sort_files PARAMS ((void));
339 static void parse_ls_color PARAMS ((void));
340 void usage PARAMS ((int status));
342 /* The name the program was run with, stripped of any leading path. */
345 /* Initial size of hash table.
346 Most hierarchies are likely to be shallower than this. */
347 #define INITIAL_TABLE_SIZE 30
349 /* The set of `active' directories, from the current command-line argument
350 to the level in the hierarchy at which files are being listed.
351 A directory is represented by its device and inode numbers.
352 A directory is added to this set when ls begins listing it or its
353 entries, and it is removed from the set just after ls has finished
354 processing it. This set is used solely to detect loops, e.g., with
355 mkdir loop; cd loop; ln -s ../loop sub; ls -RL */
356 static Hash_table *active_dir_set;
358 #define LOOP_DETECT (!!active_dir_set)
360 /* An entry in the active_dir_set. */
367 /* The table of files in the current directory:
369 `files' points to a vector of `struct fileinfo', one per file.
370 `nfiles' is the number of elements space has been allocated for.
371 `files_index' is the number actually in use. */
373 /* Address of block containing the files that are described. */
374 static struct fileinfo *files; /* FIXME: rename this to e.g. cwd_file */
376 /* Length of block that `files' points to, measured in files. */
377 static int nfiles; /* FIXME: rename this to e.g. cwd_n_alloc */
379 /* Index of first unused in `files'. */
380 static int files_index; /* FIXME: rename this to e.g. cwd_n_used */
382 /* When nonzero, in a color listing, color each symlink name according to the
383 type of file it points to. Otherwise, color them according to the `ln'
384 directive in LS_COLORS. Dangling (orphan) symlinks are treated specially,
385 regardless. This is set when `ln=target' appears in LS_COLORS. */
387 static int color_symlink_as_referent;
389 /* mode of appropriate file for colorization */
390 #define FILE_OR_LINK_MODE(File) \
391 ((color_symlink_as_referent && (File)->linkok) \
392 ? (File)->linkmode : (File)->stat.st_mode)
395 /* Record of one pending directory waiting to be listed. */
400 /* If the directory is actually the file pointed to by a symbolic link we
401 were told to list, `realname' will contain the name of the symbolic
402 link, otherwise zero. */
404 struct pending *next;
407 static struct pending *pending_dirs;
409 /* Current time in seconds and nanoseconds since 1970, updated as
410 needed when deciding whether a file is recent. */
412 static time_t current_time = TYPE_MINIMUM (time_t);
413 static int current_time_ns = -1;
415 /* The number of digits to use for block sizes.
416 4, or more if needed for bigger numbers. */
418 static int block_size_size;
422 /* long_format for lots of info, one per line.
423 one_per_line for just names, one per line.
424 many_per_line for just names, many per line, sorted vertically.
425 horizontal for just names, many per line, sorted horizontally.
426 with_commas for just names, many per line, separated by commas.
428 -l (and other options that imply -l), -1, -C, -x and -m control
433 long_format, /* -l and other options that imply -l */
434 one_per_line, /* -1 */
435 many_per_line, /* -C */
440 static enum format format;
442 /* `full-iso' uses full ISO-style dates and times. `iso' uses shorter
443 ISO-style time stamps. `locale' uses locale-dependent time stamps.
444 `posix-iso' uses traditional POSIX-locale-style dates where
445 POSIX requires it, ISO-style dates otherwise. */
448 full_iso_time_style, /* --time-style=full-iso */
449 iso_time_style, /* --time-style=iso */
450 locale_time_style, /* --time-style=locale */
451 posix_iso_time_style /* --time-style=posix-iso (default) */
454 static char const *const time_style_args[] =
456 "full-iso", "iso", "locale", "posix-iso", 0
459 static enum time_style const time_style_types[] =
461 full_iso_time_style, iso_time_style,
462 locale_time_style, posix_iso_time_style, 0
465 /* Type of time to print or sort by. Controlled by -c and -u. */
469 time_mtime, /* default */
474 static enum time_type time_type;
476 /* The file characteristic to sort by. Controlled by -t, -S, -U, -X, -v. */
481 sort_name, /* default */
482 sort_extension, /* -X */
485 sort_version /* -v */
488 static enum sort_type sort_type;
490 /* Direction of sort.
491 0 means highest first if numeric,
492 lowest first if alphabetic;
493 these are the defaults.
494 1 means the opposite order in each case. -r */
496 static int sort_reverse;
498 /* Nonzero means to display owner information. -g turns this off. */
500 static int print_owner = 1;
502 /* Nonzero means to display group information. -G and -o turn this off. */
504 static int print_group = 1;
506 /* Nonzero means print the user and group id's as numbers rather
509 static int numeric_ids;
511 /* Nonzero means mention the size in blocks of each file. -s */
513 static int print_block_size;
515 /* If positive, the units to use when printing sizes;
516 if negative, the human-readable base. */
517 static int output_block_size;
519 /* Precede each line of long output (per file) with a string like `m,n:'
520 where M is the number of characters after the `:' and before the
521 filename and N is the length of the filename. Using this format,
522 Emacs' dired mode starts up twice as fast, and can handle all
523 strange characters in file names. */
526 /* `none' means don't mention the type of files.
527 `classify' means mention file types and mark executables.
528 `file_type' means mention only file types.
530 Controlled by -F, -p, and --indicator-style. */
534 none, /* --indicator-style=none */
535 classify, /* -F, --indicator-style=classify */
536 file_type /* -p, --indicator-style=file-type */
539 static enum indicator_style indicator_style;
541 /* Names of indicator styles. */
542 static char const *const indicator_style_args[] =
544 "none", "classify", "file-type", 0
547 static enum indicator_style const indicator_style_types[]=
549 none, classify, file_type
552 /* Nonzero means use colors to mark types. Also define the different
553 colors as well as the stuff for the LS_COLORS environment variable.
554 The LS_COLORS variable is now in a termcap-like format. */
556 static int print_with_color;
560 color_never, /* 0: default or --color=never */
561 color_always, /* 1: --color=always */
562 color_if_tty /* 2: --color=tty */
565 enum Dereference_symlink
569 DEREF_COMMAND_LINE_ARGUMENTS, /* -H */
570 DEREF_ALWAYS /* -L */
575 C_LEFT, C_RIGHT, C_END, C_NORM, C_FILE, C_DIR, C_LINK, C_FIFO, C_SOCK,
576 C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR
579 static const char *const indicator_name[]=
581 "lc", "rc", "ec", "no", "fi", "di", "ln", "pi", "so",
582 "bd", "cd", "mi", "or", "ex", "do", NULL
585 struct color_ext_type
587 struct bin_str ext; /* The extension we're looking for */
588 struct bin_str seq; /* The sequence to output when we do */
589 struct color_ext_type *next; /* Next in list */
592 static struct bin_str color_indicator[] =
594 { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */
595 { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */
596 { 0, NULL }, /* ec: End color (replaces lc+no+rc) */
597 { LEN_STR_PAIR ("0") }, /* no: Normal */
598 { LEN_STR_PAIR ("0") }, /* fi: File: default */
599 { LEN_STR_PAIR ("01;34") }, /* di: Directory: bright blue */
600 { LEN_STR_PAIR ("01;36") }, /* ln: Symlink: bright cyan */
601 { LEN_STR_PAIR ("33") }, /* pi: Pipe: yellow/brown */
602 { LEN_STR_PAIR ("01;35") }, /* so: Socket: bright magenta */
603 { LEN_STR_PAIR ("01;33") }, /* bd: Block device: bright yellow */
604 { LEN_STR_PAIR ("01;33") }, /* cd: Char device: bright yellow */
605 { 0, NULL }, /* mi: Missing file: undefined */
606 { 0, NULL }, /* or: Orphanned symlink: undefined */
607 { LEN_STR_PAIR ("01;32") }, /* ex: Executable: bright green */
608 { LEN_STR_PAIR ("01;35") } /* do: Door: bright magenta */
612 static struct color_ext_type *color_ext_list = NULL;
614 /* Buffer for color sequences */
615 static char *color_buf;
617 /* Nonzero means to check for orphaned symbolic link, for displaying
620 static int check_symlink_color;
622 /* Nonzero means mention the inode number of each file. -i */
624 static int print_inode;
626 /* What to do with symbolic links. Affected by -d, -F, -H, -l (and
627 other options that imply -l), and -L. */
629 static enum Dereference_symlink dereference;
631 /* Nonzero means when a directory is found, display info on its
634 static int recursive;
636 /* Nonzero means when an argument is a directory name, display info
639 static int immediate_dirs;
641 /* Nonzero means don't omit files whose names start with `.'. -A */
643 static int all_files;
645 /* Nonzero means don't omit files `.' and `..'
646 This flag implies `all_files'. -a */
648 static int really_all_files;
650 /* A linked list of shell-style globbing patterns. If a non-argument
651 file name matches any of these patterns, it is omitted.
652 Controlled by -I. Multiple -I options accumulate.
653 The -B option adds `*~' and `.*~' to this list. */
655 struct ignore_pattern
658 struct ignore_pattern *next;
661 static struct ignore_pattern *ignore_patterns;
663 /* Nonzero means output nongraphic chars in file names as `?'.
664 (-q, --hide-control-chars)
665 qmark_funny_chars and the quoting style (-Q, --quoting-style=WORD) are
666 independent. The algorithm is: first, obey the quoting style to get a
667 string representing the file name; then, if qmark_funny_chars is set,
668 replace all nonprintable chars in that string with `?'. It's necessary
669 to replace nonprintable chars even in quoted strings, because we don't
670 want to mess up the terminal if control chars get sent to it, and some
671 quoting methods pass through control chars as-is. */
672 static int qmark_funny_chars;
674 /* Quoting options for file and dir name output. */
676 static struct quoting_options *filename_quoting_options;
677 static struct quoting_options *dirname_quoting_options;
679 /* The number of chars per hardware tab stop. Setting this to zero
680 inhibits the use of TAB characters for separating columns. -T */
683 /* Nonzero means we are listing the working directory because no
684 non-option arguments were given. */
686 static int dir_defaulted;
688 /* Nonzero means print each directory name before listing it. */
690 static int print_dir_name;
692 /* The line length to use for breaking lines in many-per-line format.
693 Can be set with -w. */
695 static int line_length;
697 /* If nonzero, the file listing format requires that stat be called on
700 static int format_needs_stat;
702 /* Similar to `format_needs_stat', but set if only the file type is
705 static int format_needs_type;
707 /* strftime formats for non-recent and recent files, respectively, in
710 static char const *long_time_format[2] = { N_("%b %e %Y"),
713 /* The exit status to use if we don't get any fatal errors. */
715 static int exit_status;
717 /* For long options that have no equivalent short option, use a
718 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
721 BLOCK_SIZE_OPTION = CHAR_MAX + 1,
725 INDICATOR_STYLE_OPTION,
726 QUOTING_STYLE_OPTION,
727 SHOW_CONTROL_CHARS_OPTION,
734 static struct option const long_options[] =
736 {"all", no_argument, 0, 'a'},
737 {"escape", no_argument, 0, 'b'},
738 {"directory", no_argument, 0, 'd'},
739 {"dired", no_argument, 0, 'D'},
740 {"full-time", no_argument, 0, FULL_TIME_OPTION},
741 {"human-readable", no_argument, 0, 'h'},
742 {"inode", no_argument, 0, 'i'},
743 {"kilobytes", no_argument, 0, 'k'},
744 {"numeric-uid-gid", no_argument, 0, 'n'},
745 {"no-group", no_argument, 0, 'G'},
746 {"hide-control-chars", no_argument, 0, 'q'},
747 {"reverse", no_argument, 0, 'r'},
748 {"size", no_argument, 0, 's'},
749 {"width", required_argument, 0, 'w'},
750 {"almost-all", no_argument, 0, 'A'},
751 {"ignore-backups", no_argument, 0, 'B'},
752 {"classify", no_argument, 0, 'F'},
753 {"file-type", no_argument, 0, 'p'},
754 {"si", no_argument, 0, SI_OPTION},
755 {"dereference-command-line", no_argument, 0, 'H'},
756 {"ignore", required_argument, 0, 'I'},
757 {"indicator-style", required_argument, 0, INDICATOR_STYLE_OPTION},
758 {"dereference", no_argument, 0, 'L'},
759 {"literal", no_argument, 0, 'N'},
760 {"quote-name", no_argument, 0, 'Q'},
761 {"quoting-style", required_argument, 0, QUOTING_STYLE_OPTION},
762 {"recursive", no_argument, 0, 'R'},
763 {"format", required_argument, 0, FORMAT_OPTION},
764 {"show-control-chars", no_argument, 0, SHOW_CONTROL_CHARS_OPTION},
765 {"sort", required_argument, 0, SORT_OPTION},
766 {"tabsize", required_argument, 0, 'T'},
767 {"time", required_argument, 0, TIME_OPTION},
768 {"time-style", required_argument, 0, TIME_STYLE_OPTION},
769 {"color", optional_argument, 0, COLOR_OPTION},
770 {"block-size", required_argument, 0, BLOCK_SIZE_OPTION},
771 {GETOPT_HELP_OPTION_DECL},
772 {GETOPT_VERSION_OPTION_DECL},
776 static char const *const format_args[] =
778 "verbose", "long", "commas", "horizontal", "across",
779 "vertical", "single-column", 0
782 static enum format const format_types[] =
784 long_format, long_format, with_commas, horizontal, horizontal,
785 many_per_line, one_per_line
788 static char const *const sort_args[] =
790 "none", "time", "size", "extension", "version", 0
793 static enum sort_type const sort_types[] =
795 sort_none, sort_time, sort_size, sort_extension, sort_version
798 static char const *const time_args[] =
800 "atime", "access", "use", "ctime", "status", 0
803 static enum time_type const time_types[] =
805 time_atime, time_atime, time_atime, time_ctime, time_ctime
808 static char const *const color_args[] =
810 /* force and none are for compatibility with another color-ls version */
811 "always", "yes", "force",
812 "never", "no", "none",
813 "auto", "tty", "if-tty", 0
816 static enum color_type const color_types[] =
818 color_always, color_always, color_always,
819 color_never, color_never, color_never,
820 color_if_tty, color_if_tty, color_if_tty
823 /* Information about filling a column. */
831 /* Array with information about column filledness. */
832 static struct column_info *column_info;
834 /* Maximum number of columns ever possible for this display. */
837 /* The minimum width of a colum is 3: 1 character for the name and 2
838 for the separating white space. */
839 #define MIN_COLUMN_WIDTH 3
842 /* This zero-based index is used solely with the --dired option.
843 When that option is in effect, this counter is incremented for each
844 character of output generated by this program so that the beginning
845 and ending indices (in that output) of every file name can be recorded
846 and later output themselves. */
847 static size_t dired_pos;
849 #define DIRED_PUTCHAR(c) do {putchar ((c)); ++dired_pos;} while (0)
851 /* Write S to STREAM and increment DIRED_POS by S_LEN. */
852 #define DIRED_FPUTS(s, stream, s_len) \
853 do {fputs ((s), (stream)); dired_pos += s_len;} while (0)
855 /* Like DIRED_FPUTS, but for use when S is a literal string. */
856 #define DIRED_FPUTS_LITERAL(s, stream) \
857 do {fputs ((s), (stream)); dired_pos += sizeof((s)) - 1;} while (0)
859 #define DIRED_INDENT() \
862 /* FIXME: remove the `&& format == long_format' clause. */ \
863 if (dired && format == long_format) \
864 DIRED_FPUTS_LITERAL (" ", stdout); \
868 /* With --dired, store pairs of beginning and ending indices of filenames. */
869 static struct obstack dired_obstack;
871 /* With --dired, store pairs of beginning and ending indices of any
872 directory names that appear as headers (just before `total' line)
873 for lists of directory entries. Such directory names are seen when
874 listing hierarchies using -R and when a directory is listed with at
875 least one other command line argument. */
876 static struct obstack subdired_obstack;
878 /* Save the current index on the specified obstack, OBS. */
879 #define PUSH_CURRENT_DIRED_POS(obs) \
882 /* FIXME: remove the `&& format == long_format' clause. */ \
883 if (dired && format == long_format) \
884 obstack_grow ((obs), &dired_pos, sizeof (dired_pos)); \
888 /* With -R, this stack is used to help detect directory cycles.
889 The device/inode pairs on this stack mirror the pairs in the
890 active_dir_set hash table. */
891 static struct obstack dev_ino_obstack;
893 /* Push a pair onto the device/inode stack. */
894 #define DEV_INO_PUSH(Dev, Ino) \
897 struct dev_ino *di; \
898 obstack_blank (&dev_ino_obstack, sizeof (struct dev_ino)); \
899 di = -1 + (struct dev_ino *) obstack_next_free (&dev_ino_obstack); \
900 di->st_dev = (Dev); \
901 di->st_ino = (Ino); \
905 /* Pop a dev/ino struct off the global dev_ino_obstack
906 and return that struct. */
907 static struct dev_ino
910 assert (sizeof (struct dev_ino) <= obstack_object_size (&dev_ino_obstack));
911 obstack_blank (&dev_ino_obstack, -(int) (sizeof (struct dev_ino)));
912 return *(struct dev_ino*) obstack_next_free (&dev_ino_obstack);
915 #define ASSERT_MATCHING_DEV_INO(Name, Di) \
920 assert (0 <= stat (Name, &sb)); \
921 assert (sb.st_dev == Di.st_dev); \
922 assert (sb.st_ino == Di.st_ino); \
927 /* Write to standard output PREFIX, followed by the quoting style and
928 a space-separated list of the integers stored in OS all on one line. */
931 dired_dump_obstack (const char *prefix, struct obstack *os)
935 n_pos = obstack_object_size (os) / sizeof (dired_pos);
941 pos = (size_t *) obstack_finish (os);
942 fputs (prefix, stdout);
943 for (i = 0; i < n_pos; i++)
944 printf (" %lu", (unsigned long) pos[i]);
945 fputs ("\n", stdout);
950 dev_ino_hash (void const *x, unsigned int table_size)
952 struct dev_ino const *p = x;
953 return (uintmax_t) p->st_ino % table_size;
957 dev_ino_compare (void const *x, void const *y)
959 struct dev_ino const *a = x;
960 struct dev_ino const *b = y;
961 return SAME_INODE (*a, *b) ? true : false;
965 dev_ino_free (void *x)
970 /* Add the device/inode pair (P->st_dev/P->st_ino) to the set of
971 active directories. Return nonzero if there is already a matching
972 entry in the table. Otherwise, return zero. */
975 visit_dir (dev_t dev, ino_t ino)
978 struct dev_ino *ent_from_table;
981 ent = XMALLOC (struct dev_ino, 1);
985 /* Attempt to insert this entry into the table. */
986 ent_from_table = hash_insert (active_dir_set, ent);
988 if (ent_from_table == NULL)
990 /* Insertion failed due to lack of memory. */
994 found_match = (ent_from_table != ent);
998 /* ent was not inserted, so free it. */
1006 free_pending_ent (struct pending *p)
1016 main (int argc, char **argv)
1019 register struct pending *thispend;
1020 unsigned int n_files;
1022 program_name = argv[0];
1023 setlocale (LC_ALL, "");
1024 bindtextdomain (PACKAGE, LOCALEDIR);
1025 textdomain (PACKAGE);
1027 atexit (close_stdout);
1029 #define N_ENTRIES(Array) (sizeof Array / sizeof *(Array))
1030 assert (N_ENTRIES (color_indicator) + 1 == N_ENTRIES (indicator_name));
1037 i = decode_switches (argc, argv);
1039 if (print_with_color)
1042 /* Test print_with_color again, because the call to parse_ls_color
1043 may have just reset it -- e.g., if LS_COLORS is invalid. */
1044 if (print_with_color)
1046 prep_non_filename_text ();
1047 /* Avoid following symbolic links when possible. */
1048 if (color_indicator[C_ORPHAN].string != NULL
1049 || (color_indicator[C_MISSING].string != NULL
1050 && format == long_format))
1051 check_symlink_color = 1;
1054 if (dereference == DEREF_UNDEFINED)
1055 dereference = ((immediate_dirs
1056 || indicator_style == classify
1057 || format == long_format)
1059 : DEREF_COMMAND_LINE_ARGUMENTS);
1061 /* When using -R, initialize a data structure we'll use to
1062 detect any directory cycles. */
1065 active_dir_set = hash_initialize (INITIAL_TABLE_SIZE, NULL,
1069 if (active_dir_set == NULL)
1072 obstack_init (&dev_ino_obstack);
1075 format_needs_stat = sort_type == sort_time || sort_type == sort_size
1076 || format == long_format
1077 || dereference == DEREF_ALWAYS
1078 || recursive || print_block_size || print_inode;
1079 format_needs_type = (format_needs_stat == 0
1080 && (print_with_color || indicator_style != none));
1082 if (dired && format == long_format)
1084 obstack_init (&dired_obstack);
1085 obstack_init (&subdired_obstack);
1089 files = XMALLOC (struct fileinfo, nfiles);
1098 for (; i < argc; i++)
1100 gobble_file (argv[i], unknown, 1, "");
1106 gobble_file (".", directory, 1, "");
1108 queue_directory (".", 0);
1114 if (!immediate_dirs)
1115 extract_dirs_from_files ("", 0);
1116 /* `files_index' might be zero now. */
1121 print_current_files ();
1122 if (pending_dirs && pending_dirs->name)
1123 DIRED_PUTCHAR ('\n');
1125 else if (n_files <= 1 && pending_dirs && pending_dirs->next == 0)
1128 while (pending_dirs)
1130 thispend = pending_dirs;
1131 pending_dirs = pending_dirs->next;
1135 if (thispend->name == NULL)
1137 /* thispend->name == NULL means this is a marker entry
1138 indicating we've finished processing the directory.
1139 Use its dev/ino numbers to remove the corresponding
1140 entry from the active_dir_set hash table. */
1141 struct dev_ino di = dev_ino_pop ();
1142 struct dev_ino *found = hash_delete (active_dir_set, &di);
1143 /* ASSERT_MATCHING_DEV_INO (thispend->realname, di); */
1145 dev_ino_free (found);
1146 free_pending_ent (thispend);
1151 print_dir (thispend->name, thispend->realname);
1153 free_pending_ent (thispend);
1157 if (dired && format == long_format)
1159 /* No need to free these since we're about to exit. */
1160 dired_dump_obstack ("//DIRED//", &dired_obstack);
1161 dired_dump_obstack ("//SUBDIRED//", &subdired_obstack);
1162 printf ("//DIRED-OPTIONS// --quoting-style=%s\n",
1163 quoting_style_args[get_quoting_style (filename_quoting_options)]);
1166 /* Restore default color before exiting */
1167 if (print_with_color)
1169 put_indicator (&color_indicator[C_LEFT]);
1170 put_indicator (&color_indicator[C_RIGHT]);
1175 assert (hash_get_n_entries (active_dir_set) == 0);
1176 hash_free (active_dir_set);
1182 /* Set all the option flags according to the switches specified.
1183 Return the index of the first non-option argument. */
1186 decode_switches (int argc, char **argv)
1189 char const *time_style_option = 0;
1191 /* Record whether there is an option specifying sort type. */
1192 int sort_type_specified = 0;
1194 qmark_funny_chars = 0;
1196 /* initialize all switches to default settings */
1201 /* This is for the `dir' program. */
1202 format = many_per_line;
1203 set_quoting_style (NULL, escape_quoting_style);
1206 case LS_LONG_FORMAT:
1207 /* This is for the `vdir' program. */
1208 format = long_format;
1209 set_quoting_style (NULL, escape_quoting_style);
1213 /* This is for the `ls' program. */
1214 if (isatty (STDOUT_FILENO))
1216 format = many_per_line;
1217 /* See description of qmark_funny_chars, above. */
1218 qmark_funny_chars = 1;
1222 format = one_per_line;
1223 qmark_funny_chars = 0;
1231 time_type = time_mtime;
1232 sort_type = sort_name;
1235 print_block_size = 0;
1236 indicator_style = none;
1238 dereference = DEREF_UNDEFINED;
1242 really_all_files = 0;
1243 ignore_patterns = 0;
1245 /* FIXME: put this in a function. */
1247 char const *q_style = getenv ("QUOTING_STYLE");
1250 int i = ARGCASEMATCH (q_style, quoting_style_args, quoting_style_vals);
1252 set_quoting_style (NULL, quoting_style_vals[i]);
1255 _("ignoring invalid value of environment variable QUOTING_STYLE: %s"),
1256 quotearg (q_style));
1260 human_block_size (getenv ("LS_BLOCK_SIZE"), 0, &output_block_size);
1264 char const *p = getenv ("COLUMNS");
1268 if (xstrtol (p, NULL, 0, &tmp_long, NULL) == LONGINT_OK
1269 && 0 < tmp_long && tmp_long <= INT_MAX)
1271 line_length = (int) tmp_long;
1276 _("ignoring invalid width in environment variable COLUMNS: %s"),
1286 if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 && ws.ws_col != 0)
1287 line_length = ws.ws_col;
1291 /* Using the TABSIZE environment variable is not POSIX-approved.
1292 Ignore it when POSIXLY_CORRECT is set. */
1296 if (!getenv ("POSIXLY_CORRECT") && (p = getenv ("TABSIZE")))
1299 if (xstrtol (p, NULL, 0, &tmp_long, NULL) == LONGINT_OK
1300 && 0 <= tmp_long && tmp_long <= INT_MAX)
1302 tabsize = (int) tmp_long;
1307 _("ignoring invalid tab size in environment variable TABSIZE: %s"),
1313 while ((c = getopt_long (argc, argv,
1314 "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UX1",
1315 long_options, NULL)) != -1)
1324 really_all_files = 1;
1328 set_quoting_style (NULL, escape_quoting_style);
1332 time_type = time_ctime;
1340 /* Same as enabling -a -U and disabling -l -s. */
1342 really_all_files = 1;
1343 sort_type = sort_none;
1344 sort_type_specified = 1;
1346 if (format == long_format)
1347 format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line);
1348 print_block_size = 0; /* disable -s */
1349 print_with_color = 0; /* disable --color */
1353 format = long_format;
1358 output_block_size = -1024;
1366 output_block_size = 1024;
1370 format = long_format;
1374 format = with_commas;
1379 format = long_format;
1382 case 'o': /* Just like -l, but don't display group info. */
1383 format = long_format;
1388 indicator_style = file_type;
1392 qmark_funny_chars = 1;
1400 print_block_size = 1;
1404 sort_type = sort_time;
1405 sort_type_specified = 1;
1409 time_type = time_atime;
1413 sort_type = sort_version;
1414 sort_type_specified = 1;
1420 if (xstrtol (optarg, NULL, 0, &tmp_long, NULL) != LONGINT_OK
1421 || tmp_long <= 0 || tmp_long > INT_MAX)
1422 error (EXIT_FAILURE, 0, _("invalid line width: %s"),
1424 line_length = (int) tmp_long;
1429 format = horizontal;
1433 really_all_files = 0;
1438 add_ignore_pattern ("*~");
1439 add_ignore_pattern (".*~");
1443 format = many_per_line;
1451 indicator_style = classify;
1454 case 'G': /* inhibit display of group info */
1459 dereference = DEREF_COMMAND_LINE_ARGUMENTS;
1463 add_ignore_pattern (optarg);
1467 dereference = DEREF_ALWAYS;
1471 set_quoting_style (NULL, literal_quoting_style);
1475 set_quoting_style (NULL, c_quoting_style);
1483 sort_type = sort_size;
1484 sort_type_specified = 1;
1490 if (xstrtol (optarg, NULL, 0, &tmp_long, NULL) != LONGINT_OK
1491 || tmp_long < 0 || tmp_long > INT_MAX)
1492 error (EXIT_FAILURE, 0, _("invalid tab size: %s"),
1494 tabsize = (int) tmp_long;
1499 sort_type = sort_none;
1500 sort_type_specified = 1;
1504 sort_type = sort_extension;
1505 sort_type_specified = 1;
1509 /* -1 has no effect after -l. */
1510 if (format != long_format)
1511 format = one_per_line;
1515 sort_type = XARGMATCH ("--sort", optarg, sort_args, sort_types);
1516 sort_type_specified = 1;
1520 time_type = XARGMATCH ("--time", optarg, time_args, time_types);
1524 format = XARGMATCH ("--format", optarg, format_args, format_types);
1527 case FULL_TIME_OPTION:
1528 format = long_format;
1529 time_style_option = "full-iso";
1536 i = XARGMATCH ("--color", optarg, color_args, color_types);
1538 /* Using --color with no argument is equivalent to using
1542 print_with_color = (i == color_always
1543 || (i == color_if_tty
1544 && isatty (STDOUT_FILENO)));
1546 if (print_with_color)
1548 /* Don't use TAB characters in output. Some terminal
1549 emulators can't handle the combination of tabs and
1550 color codes on the same line. */
1556 case INDICATOR_STYLE_OPTION:
1557 indicator_style = XARGMATCH ("--indicator-style", optarg,
1558 indicator_style_args,
1559 indicator_style_types);
1562 case QUOTING_STYLE_OPTION:
1563 set_quoting_style (NULL,
1564 XARGMATCH ("--quoting-style", optarg,
1566 quoting_style_vals));
1569 case TIME_STYLE_OPTION:
1570 time_style_option = optarg;
1573 case SHOW_CONTROL_CHARS_OPTION:
1574 qmark_funny_chars = 0;
1577 case BLOCK_SIZE_OPTION:
1578 human_block_size (optarg, 1, &output_block_size);
1582 output_block_size = -1000;
1585 case_GETOPT_HELP_CHAR;
1587 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1590 usage (EXIT_FAILURE);
1594 filename_quoting_options = clone_quoting_options (NULL);
1595 if (get_quoting_style (filename_quoting_options) == escape_quoting_style)
1596 set_char_quoting (filename_quoting_options, ' ', 1);
1597 if (indicator_style != none)
1600 for (p = "*=@|" + (int) indicator_style - 1; *p; p++)
1601 set_char_quoting (filename_quoting_options, *p, 1);
1604 dirname_quoting_options = clone_quoting_options (NULL);
1605 set_char_quoting (dirname_quoting_options, ':', 1);
1607 /* If -c or -u is specified and not -l (or any other option that implies -l),
1608 and no sort-type was specified, then sort by the ctime (-c) or atime (-u).
1609 The behavior of ls when using either -c or -u but with neither -l nor -t
1610 appears to be unspecified by POSIX. So, with GNU ls, `-u' alone means
1611 sort by atime (this is the one that's not specified by the POSIX spec),
1612 -lu means show atime and sort by name, -lut means show atime and sort
1615 if ((time_type == time_ctime || time_type == time_atime)
1616 && !sort_type_specified && format != long_format)
1618 sort_type = sort_time;
1621 if (format == long_format)
1623 if (! time_style_option)
1624 time_style_option = getenv ("TIME_STYLE");
1626 switch (time_style_option
1627 ? XARGMATCH ("time style", time_style_option,
1630 : posix_iso_time_style)
1632 case full_iso_time_style:
1633 long_time_format[0] = long_time_format[1] =
1634 "%Y-%m-%d %H:%M:%S.%N %z";
1637 case posix_iso_time_style:
1638 if (! hard_locale (LC_TIME))
1641 case iso_time_style:
1642 long_time_format[0] = "%Y-%m-%d ";
1643 long_time_format[1] = "%m-%d %H:%M";
1646 case locale_time_style:
1647 if (hard_locale (LC_TIME))
1650 for (i = 0; i < 2; i++)
1651 long_time_format[i] =
1652 dcgettext (NULL, long_time_format[i], LC_TIME);
1660 /* Parse a string as part of the LS_COLORS variable; this may involve
1661 decoding all kinds of escape characters. If equals_end is set an
1662 unescaped equal sign ends the string, otherwise only a : or \0
1663 does. Returns the number of characters output, or -1 on failure.
1665 The resulting string is *not* null-terminated, but may contain
1668 Note that both dest and src are char **; on return they point to
1669 the first free byte after the array and the character that ended
1670 the input string, respectively. */
1673 get_funky_string (char **dest, const char **src, int equals_end)
1675 int num; /* For numerical codes */
1676 int count; /* Something to count with */
1678 ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR
1683 p = *src; /* We don't want to double-indirect */
1684 q = *dest; /* the whole darn time. */
1686 count = 0; /* No characters counted in yet. */
1689 state = ST_GND; /* Start in ground state. */
1690 while (state < ST_END)
1694 case ST_GND: /* Ground state (no escapes) */
1699 state = ST_END; /* End of string */
1702 state = ST_BACKSLASH; /* Backslash scape sequence */
1706 state = ST_CARET; /* Caret escape */
1712 state = ST_END; /* End */
1715 /* else fall through */
1723 case ST_BACKSLASH: /* Backslash escaped character */
1734 state = ST_OCTAL; /* Octal sequence */
1739 state = ST_HEX; /* Hex sequence */
1742 case 'a': /* Bell */
1743 num = 7; /* Not all C compilers know what \a means */
1745 case 'b': /* Backspace */
1748 case 'e': /* Escape */
1751 case 'f': /* Form feed */
1754 case 'n': /* Newline */
1757 case 'r': /* Carriage return */
1763 case 'v': /* Vtab */
1766 case '?': /* Delete */
1769 case '_': /* Space */
1772 case '\0': /* End of string */
1773 state = ST_ERROR; /* Error! */
1775 default: /* Escaped character like \ ^ : = */
1779 if (state == ST_BACKSLASH)
1788 case ST_OCTAL: /* Octal sequence */
1789 if (*p < '0' || *p > '7')
1796 num = (num << 3) + (*(p++) - '0');
1799 case ST_HEX: /* Hex sequence */
1812 num = (num << 4) + (*(p++) - '0');
1820 num = (num << 4) + (*(p++) - 'a') + 10;
1828 num = (num << 4) + (*(p++) - 'A') + 10;
1838 case ST_CARET: /* Caret escape */
1839 state = ST_GND; /* Should be the next state... */
1840 if (*p >= '@' && *p <= '~')
1842 *(q++) = *(p++) & 037;
1862 return state == ST_ERROR ? -1 : count;
1866 parse_ls_color (void)
1868 const char *p; /* Pointer to character being parsed */
1869 char *buf; /* color_buf buffer pointer */
1870 int state; /* State of parser */
1871 int ind_no; /* Indicator number */
1872 char label[3]; /* Indicator label */
1873 struct color_ext_type *ext; /* Extension we are working on */
1875 if ((p = getenv ("LS_COLORS")) == NULL || *p == '\0')
1879 strcpy (label, "??");
1881 /* This is an overly conservative estimate, but any possible
1882 LS_COLORS string will *not* generate a color_buf longer than
1883 itself, so it is a safe way of allocating a buffer in
1885 buf = color_buf = xstrdup (p);
1892 case 1: /* First label character */
1900 /* Allocate new extension block and add to head of
1901 linked list (this way a later definition will
1902 override an earlier one, which can be useful for
1903 having terminal-specific defs override global). */
1905 ext = XMALLOC (struct color_ext_type, 1);
1906 ext->next = color_ext_list;
1907 color_ext_list = ext;
1910 ext->ext.string = buf;
1912 state = (ext->ext.len =
1913 get_funky_string (&buf, &p, 1)) < 0 ? -1 : 4;
1917 state = 0; /* Done! */
1920 default: /* Assume it is file type label */
1927 case 2: /* Second label character */
1934 state = -1; /* Error */
1937 case 3: /* Equal sign after indicator label */
1938 state = -1; /* Assume failure... */
1939 if (*(p++) == '=')/* It *should* be... */
1941 for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no)
1943 if (STREQ (label, indicator_name[ind_no]))
1945 color_indicator[ind_no].string = buf;
1946 state = ((color_indicator[ind_no].len =
1947 get_funky_string (&buf, &p, 0)) < 0 ? -1 : 1);
1952 error (0, 0, _("unrecognized prefix: %s"), quotearg (label));
1956 case 4: /* Equal sign after *.ext */
1959 ext->seq.string = buf;
1960 state = (ext->seq.len =
1961 get_funky_string (&buf, &p, 0)) < 0 ? -1 : 1;
1971 struct color_ext_type *e;
1972 struct color_ext_type *e2;
1975 _("unparsable value for LS_COLORS environment variable"));
1977 for (e = color_ext_list; e != NULL; /* empty */)
1983 print_with_color = 0;
1986 if (color_indicator[C_LINK].len == 6
1987 && !strncmp (color_indicator[C_LINK].string, "target", 6))
1988 color_symlink_as_referent = 1;
1991 /* Request that the directory named NAME have its contents listed later.
1992 If REALNAME is nonzero, it will be used instead of NAME when the
1993 directory name is printed. This allows symbolic links to directories
1994 to be treated as regular directories but still be listed under their
1995 real names. NAME == NULL is used to insert a marker entry for the
1996 directory named in REALNAME.
1997 If F is non-NULL, we use its dev/ino information to save
1998 a call to stat -- when doing a recursive (-R) traversal. */
2001 queue_directory (const char *name, const char *realname)
2003 struct pending *new;
2005 new = XMALLOC (struct pending, 1);
2006 new->realname = realname ? xstrdup (realname) : NULL;
2007 new->name = name ? xstrdup (name) : NULL;
2008 new->next = pending_dirs;
2012 /* Read directory `name', and list the files in it.
2013 If `realname' is nonzero, print its name instead of `name';
2014 this is used for symbolic links to directories. */
2017 print_dir (const char *name, const char *realname)
2019 register DIR *reading;
2020 register struct dirent *next;
2021 register uintmax_t total_blocks = 0;
2024 reading = opendir (name);
2027 error (0, errno, "%s", quotearg_colon (name));
2034 struct stat dir_stat;
2035 int fd = dirfd (reading);
2037 /* If dirfd failed, endure the overhead of using stat. */
2039 ? fstat (fd, &dir_stat)
2040 : stat (name, &dir_stat)) < 0)
2042 error (0, errno, _("cannot determine device and inode of %s"),
2043 quotearg_colon (name));
2048 /* If we've already visited this dev/inode pair, warn that
2049 we've found a loop, and do not process this directory. */
2050 if (visit_dir (dir_stat.st_dev, dir_stat.st_ino))
2052 error (0, 0, _("not listing already-listed directory: %s"),
2053 quotearg_colon (name));
2057 DEV_INO_PUSH (dir_stat.st_dev, dir_stat.st_ino);
2060 /* Read the directory entries, and insert the subfiles into the `files'
2065 while ((next = readdir (reading)) != NULL)
2066 if (file_interesting (next))
2068 enum filetype type = unknown;
2070 #if HAVE_STRUCT_DIRENT_D_TYPE
2071 if (next->d_type == DT_DIR || next->d_type == DT_CHR
2072 || next->d_type == DT_BLK || next->d_type == DT_SOCK
2073 || next->d_type == DT_FIFO)
2074 type = next->d_type;
2076 total_blocks += gobble_file (next->d_name, type, 0, name);
2079 if (CLOSEDIR (reading))
2081 error (0, errno, "%s", quotearg_colon (name));
2083 /* Don't return; print whatever we got. */
2086 /* Sort the directory contents. */
2089 /* If any member files are subdirectories, perhaps they should have their
2090 contents listed rather than being mentioned here as files. */
2093 extract_dirs_from_files (name, 1);
2095 if (recursive || print_dir_name)
2098 PUSH_CURRENT_DIRED_POS (&subdired_obstack);
2099 dired_pos += quote_name (stdout, realname ? realname : name,
2100 dirname_quoting_options);
2101 PUSH_CURRENT_DIRED_POS (&subdired_obstack);
2102 DIRED_FPUTS_LITERAL (":\n", stdout);
2105 if (format == long_format || print_block_size)
2108 char buf[LONGEST_HUMAN_READABLE + 1];
2112 DIRED_FPUTS (p, stdout, strlen (p));
2113 DIRED_PUTCHAR (' ');
2114 p = human_readable_inexact (total_blocks, buf, ST_NBLOCKSIZE,
2115 output_block_size, human_ceiling);
2116 DIRED_FPUTS (p, stdout, strlen (p));
2117 DIRED_PUTCHAR ('\n');
2121 print_current_files ();
2123 if (pending_dirs && pending_dirs->name)
2124 DIRED_PUTCHAR ('\n');
2127 /* Add `pattern' to the list of patterns for which files that match are
2131 add_ignore_pattern (const char *pattern)
2133 register struct ignore_pattern *ignore;
2135 ignore = XMALLOC (struct ignore_pattern, 1);
2136 ignore->pattern = pattern;
2137 /* Add it to the head of the linked list. */
2138 ignore->next = ignore_patterns;
2139 ignore_patterns = ignore;
2142 /* Return nonzero if the file in `next' should be listed. */
2145 file_interesting (const struct dirent *next)
2147 register struct ignore_pattern *ignore;
2149 for (ignore = ignore_patterns; ignore; ignore = ignore->next)
2150 if (fnmatch (ignore->pattern, next->d_name, FNM_PERIOD) == 0)
2153 if (really_all_files
2154 || next->d_name[0] != '.'
2156 && next->d_name[1] != '\0'
2157 && (next->d_name[1] != '.' || next->d_name[2] != '\0')))
2163 /* Enter and remove entries in the table `files'. */
2165 /* Empty the table of files. */
2172 for (i = 0; i < files_index; i++)
2174 free (files[i].name);
2175 if (files[i].linkname)
2176 free (files[i].linkname);
2180 block_size_size = 4;
2183 /* Add a file to the current table of files.
2184 Verify that the file exists, and print an error message if it does not.
2185 Return the number of blocks that the file occupies. */
2188 gobble_file (const char *name, enum filetype type, int explicit_arg,
2189 const char *dirname)
2191 register uintmax_t blocks;
2192 register char *path;
2194 if (files_index == nfiles)
2197 files = XREALLOC (files, struct fileinfo, nfiles);
2200 files[files_index].linkname = 0;
2201 files[files_index].linkmode = 0;
2202 files[files_index].linkok = 0;
2204 /* FIXME: this use of ls: `mkdir a; touch a/{b,c,d}; ls -R a'
2205 shouldn't require that ls stat b, c, and d -- at least
2206 not on systems with usable d_type. The problem is that
2207 format_needs_stat is set, because of the -R. */
2208 if (explicit_arg || format_needs_stat
2209 || (format_needs_type && type == unknown))
2211 /* `path' is the absolute pathname of this file. */
2214 if (name[0] == '/' || dirname[0] == 0)
2215 path = (char *) name;
2218 path = (char *) alloca (strlen (name) + strlen (dirname) + 2);
2219 attach (path, dirname, name);
2222 val = (DEREF_ALWAYS <= dereference + explicit_arg
2223 ? stat (path, &files[files_index].stat)
2224 : lstat (path, &files[files_index].stat));
2228 error (0, errno, "%s", quotearg_colon (path));
2234 if (format == long_format)
2235 files[files_index].have_acl =
2236 (! S_ISLNK (files[files_index].stat.st_mode)
2237 && 4 < acl (path, GETACLCNT, 0, NULL));
2240 if (S_ISLNK (files[files_index].stat.st_mode)
2241 && (format == long_format || check_symlink_color))
2244 struct stat linkstats;
2246 get_link_name (path, &files[files_index]);
2247 linkpath = make_link_path (path, files[files_index].linkname);
2249 /* Avoid following symbolic links when possible, ie, when
2250 they won't be traced and when no indicator is needed. */
2252 && (indicator_style != none || check_symlink_color)
2253 && stat (linkpath, &linkstats) == 0)
2255 files[files_index].linkok = 1;
2257 /* Symbolic links to directories that are mentioned on the
2258 command line are automatically traced if not being
2260 if (explicit_arg && format != long_format
2261 && S_ISDIR (linkstats.st_mode))
2263 /* Substitute the linked-to directory's name, but
2264 save the real name in `linkname' for printing. */
2265 if (!immediate_dirs)
2267 const char *tempname = name;
2269 linkpath = files[files_index].linkname;
2270 files[files_index].linkname = (char *) tempname;
2272 files[files_index].stat = linkstats;
2276 /* Get the linked-to file's mode for the filetype indicator
2277 in long listings. */
2278 files[files_index].linkmode = linkstats.st_mode;
2279 files[files_index].linkok = 1;
2286 if (S_ISLNK (files[files_index].stat.st_mode))
2287 files[files_index].filetype = symbolic_link;
2288 else if (S_ISDIR (files[files_index].stat.st_mode))
2290 if (explicit_arg && !immediate_dirs)
2291 files[files_index].filetype = arg_directory;
2293 files[files_index].filetype = directory;
2296 files[files_index].filetype = normal;
2298 blocks = ST_NBLOCKS (files[files_index].stat);
2300 char buf[LONGEST_HUMAN_READABLE + 1];
2301 int len = strlen (human_readable_inexact (blocks, buf, ST_NBLOCKSIZE,
2304 if (block_size_size < len)
2305 block_size_size = len < 7 ? len : 7;
2310 files[files_index].filetype = type;
2311 #if HAVE_STRUCT_DIRENT_D_TYPE
2312 files[files_index].stat.st_mode = DTTOIF (type);
2317 files[files_index].name = xstrdup (name);
2325 /* Put the name of the file that `filename' is a symbolic link to
2326 into the `linkname' field of `f'. */
2329 get_link_name (const char *filename, struct fileinfo *f)
2331 f->linkname = xreadlink (filename);
2332 if (f->linkname == NULL)
2334 error (0, errno, _("cannot read symbolic link %s"),
2335 quotearg_colon (filename));
2340 /* If `linkname' is a relative path and `path' contains one or more
2341 leading directories, return `linkname' with those directories
2342 prepended; otherwise, return a copy of `linkname'.
2343 If `linkname' is zero, return zero. */
2346 make_link_path (const char *path, const char *linkname)
2354 if (*linkname == '/')
2355 return xstrdup (linkname);
2357 /* The link is to a relative path. Prepend any leading path
2358 in `path' to the link name. */
2359 linkbuf = strrchr (path, '/');
2361 return xstrdup (linkname);
2363 bufsiz = linkbuf - path + 1;
2364 linkbuf = xmalloc (bufsiz + strlen (linkname) + 1);
2365 strncpy (linkbuf, path, bufsiz);
2366 strcpy (linkbuf + bufsiz, linkname);
2371 /* Return nonzero if base_name (NAME) ends in `.' or `..'
2372 This is so we don't try to recurse on `././././. ...' */
2375 basename_is_dot_or_dotdot (const char *name)
2377 char const *base = base_name (name);
2378 return DOT_OR_DOTDOT (base);
2381 /* Remove any entries from `files' that are for directories,
2382 and queue them to be listed as directories instead.
2383 `dirname' is the prefix to prepend to each dirname
2384 to make it correct relative to ls's working dir.
2385 If IGNORE_DOT_AND_DOT_DOT is nonzero don't treat `.' and `..' as dirs.
2386 This is desirable when processing directories recursively. */
2389 extract_dirs_from_files (const char *dirname, int ignore_dot_and_dot_dot)
2393 if (*dirname && LOOP_DETECT)
2395 /* Insert a marker entry first. When we dequeue this marker entry,
2396 we'll know that DIRNAME has been processed and may be removed
2397 from the set of active directories. */
2398 queue_directory (NULL, dirname);
2401 /* Queue the directories last one first, because queueing reverses the
2403 for (i = files_index - 1; i >= 0; i--)
2404 if ((files[i].filetype == directory || files[i].filetype == arg_directory)
2405 && (!ignore_dot_and_dot_dot
2406 || !basename_is_dot_or_dotdot (files[i].name)))
2408 if (files[i].name[0] == '/' || dirname[0] == 0)
2410 queue_directory (files[i].name, files[i].linkname);
2414 char *path = path_concat (dirname, files[i].name, NULL);
2415 queue_directory (path, files[i].linkname);
2418 if (files[i].filetype == arg_directory)
2419 free (files[i].name);
2422 /* Now delete the directories from the table, compacting all the remaining
2425 for (i = 0, j = 0; i < files_index; i++)
2426 if (files[i].filetype != arg_directory)
2427 files[j++] = files[i];
2431 /* Sort the files now in the table. */
2446 func = sort_reverse ? rev_cmp_ctime : compare_ctime;
2449 func = sort_reverse ? rev_cmp_mtime : compare_mtime;
2452 func = sort_reverse ? rev_cmp_atime : compare_atime;
2459 func = sort_reverse ? rev_cmp_name : compare_name;
2461 case sort_extension:
2462 func = sort_reverse ? rev_cmp_extension : compare_extension;
2465 func = sort_reverse ? rev_cmp_size : compare_size;
2468 func = sort_reverse ? rev_cmp_version : compare_version;
2474 qsort (files, files_index, sizeof (struct fileinfo), func);
2477 /* Comparison routines for sorting the files. */
2480 compare_ctime (const struct fileinfo *file1, const struct fileinfo *file2)
2482 int diff = CTIME_CMP (file2->stat, file1->stat);
2484 diff = strcoll (file1->name, file2->name);
2489 rev_cmp_ctime (const struct fileinfo *file2, const struct fileinfo *file1)
2491 int diff = CTIME_CMP (file2->stat, file1->stat);
2493 diff = strcoll (file1->name, file2->name);
2498 compare_mtime (const struct fileinfo *file1, const struct fileinfo *file2)
2500 int diff = MTIME_CMP (file2->stat, file1->stat);
2502 diff = strcoll (file1->name, file2->name);
2507 rev_cmp_mtime (const struct fileinfo *file2, const struct fileinfo *file1)
2509 int diff = MTIME_CMP (file2->stat, file1->stat);
2511 diff = strcoll (file1->name, file2->name);
2516 compare_atime (const struct fileinfo *file1, const struct fileinfo *file2)
2518 int diff = ATIME_CMP (file2->stat, file1->stat);
2520 diff = strcoll (file1->name, file2->name);
2525 rev_cmp_atime (const struct fileinfo *file2, const struct fileinfo *file1)
2527 int diff = ATIME_CMP (file2->stat, file1->stat);
2529 diff = strcoll (file1->name, file2->name);
2534 compare_size (const struct fileinfo *file1, const struct fileinfo *file2)
2536 int diff = longdiff (file2->stat.st_size, file1->stat.st_size);
2538 diff = strcoll (file1->name, file2->name);
2543 rev_cmp_size (const struct fileinfo *file2, const struct fileinfo *file1)
2545 int diff = longdiff (file2->stat.st_size, file1->stat.st_size);
2547 diff = strcoll (file1->name, file2->name);
2552 compare_version (const struct fileinfo *file1, const struct fileinfo *file2)
2554 return strverscmp (file1->name, file2->name);
2558 rev_cmp_version (const struct fileinfo *file2, const struct fileinfo *file1)
2560 return strverscmp (file1->name, file2->name);
2564 compare_name (const struct fileinfo *file1, const struct fileinfo *file2)
2566 return strcoll (file1->name, file2->name);
2570 rev_cmp_name (const struct fileinfo *file2, const struct fileinfo *file1)
2572 return strcoll (file1->name, file2->name);
2575 /* Compare file extensions. Files with no extension are `smallest'.
2576 If extensions are the same, compare by filenames instead. */
2579 compare_extension (const struct fileinfo *file1, const struct fileinfo *file2)
2582 char const *base1 = strrchr (file1->name, '.');
2583 char const *base2 = strrchr (file2->name, '.');
2584 if (base1 == 0 && base2 == 0)
2585 return strcoll (file1->name, file2->name);
2590 cmp = strcoll (base1, base2);
2592 return strcoll (file1->name, file2->name);
2597 rev_cmp_extension (const struct fileinfo *file2, const struct fileinfo *file1)
2600 char const *base1 = strrchr (file1->name, '.');
2601 char const *base2 = strrchr (file2->name, '.');
2602 if (base1 == 0 && base2 == 0)
2603 return strcoll (file1->name, file2->name);
2608 cmp = strcoll (base1, base2);
2610 return strcoll (file1->name, file2->name);
2614 /* List all the files now in the table. */
2617 print_current_files (void)
2624 for (i = 0; i < files_index; i++)
2626 print_file_name_and_frills (files + i);
2632 init_column_info ();
2633 print_many_per_line ();
2637 init_column_info ();
2638 print_horizontal ();
2642 print_with_commas ();
2646 for (i = 0; i < files_index; i++)
2648 print_long_format (files + i);
2649 DIRED_PUTCHAR ('\n');
2655 /* Return the expected number of columns in a long-format time stamp,
2656 or zero if it cannot be calculated. */
2659 long_time_expected_width (void)
2661 static int width = -1;
2666 struct tm const *tm = localtime (&epoch);
2667 char const *fmt = long_time_format[0];
2669 char *buf = initbuf;
2670 size_t bufsize = sizeof initbuf;
2676 len = nstrftime (buf, bufsize, fmt, tm, 0, 0);
2679 buf = alloca (bufsize *= 2);
2682 width = mbsnwidth (buf, len, 0);
2690 /* Get the current time. */
2693 get_current_time (void)
2695 #if HAVE_CLOCK_GETTIME && defined CLOCK_REALTIME
2697 struct timespec timespec;
2698 if (clock_gettime (CLOCK_REALTIME, ×pec) == 0)
2700 current_time = timespec.tv_sec;
2701 current_time_ns = timespec.tv_nsec;
2707 /* The clock does not have nanosecond resolution, so get the maximum
2708 possible value for the current time that is consistent with the
2709 reported clock. That way, files are not considered to be in the
2710 future merely because their time stamps have higher resolution
2711 than the clock resolution. */
2713 #if HAVE_GETTIMEOFDAY
2715 struct timeval timeval;
2716 if (gettimeofday (&timeval, NULL) == 0)
2718 current_time = timeval.tv_sec;
2719 current_time_ns = timeval.tv_usec * 1000 + 999;
2725 current_time = time (NULL);
2726 current_time_ns = 999999999;
2730 print_long_format (const struct fileinfo *f)
2734 /* 7 fields that may require LONGEST_HUMAN_READABLE bytes,
2735 1 10-byte mode string,
2736 1 35-byte time string (may be longer in some locales -- see below)
2737 or LONGEST_HUMAN_READABLE integer,
2738 9 spaces, one following each of these fields, and
2739 1 trailing NUL byte. */
2740 char init_bigbuf[7 * LONGEST_HUMAN_READABLE + 10
2741 + MAX (35, LONGEST_HUMAN_READABLE)
2743 char *buf = init_bigbuf;
2744 size_t bufsize = sizeof (init_bigbuf);
2748 int when_ns IF_LINT (= 0);
2749 struct tm *when_local;
2752 /* Cray DMF: look at the file's migrated, not real, status */
2753 mode_string (f->stat.st_dm_mode, modebuf);
2755 mode_string (f->stat.st_mode, modebuf);
2758 modebuf[10] = (FILE_HAS_ACL (f) ? '+' : ' ');
2764 when = f->stat.st_ctime;
2765 when_ns = TIMESPEC_NS (f->stat.st_ctim);
2768 when = f->stat.st_mtime;
2769 when_ns = TIMESPEC_NS (f->stat.st_mtim);
2772 when = f->stat.st_atime;
2773 when_ns = TIMESPEC_NS (f->stat.st_atim);
2781 char hbuf[LONGEST_HUMAN_READABLE + 1];
2782 sprintf (p, "%*s ", INODE_DIGITS,
2783 human_readable ((uintmax_t) f->stat.st_ino, hbuf, 1, 1));
2787 if (print_block_size)
2789 char hbuf[LONGEST_HUMAN_READABLE + 1];
2790 sprintf (p, "%*s ", block_size_size,
2791 human_readable_inexact ((uintmax_t) ST_NBLOCKS (f->stat), hbuf,
2792 ST_NBLOCKSIZE, output_block_size,
2797 /* The last byte of the mode string is the POSIX
2798 "optional alternate access method flag". */
2799 sprintf (p, "%s %3lu ", modebuf, (unsigned long) f->stat.st_nlink);
2804 char const *user_name = (numeric_ids ? NULL : getuser (f->stat.st_uid));
2806 sprintf (p, "%-8s ", user_name);
2808 sprintf (p, "%-8lu ", (unsigned long) f->stat.st_uid);
2814 char const *group_name = (numeric_ids ? NULL : getgroup (f->stat.st_gid));
2816 sprintf (p, "%-8s ", group_name);
2818 sprintf (p, "%-8lu ", (unsigned long) f->stat.st_gid);
2822 if (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode))
2823 sprintf (p, "%3lu, %3lu ",
2824 (unsigned long) major (f->stat.st_rdev),
2825 (unsigned long) minor (f->stat.st_rdev));
2828 char hbuf[LONGEST_HUMAN_READABLE + 1];
2829 uintmax_t size = f->stat.st_size;
2831 /* POSIX requires that the size be printed without a sign, even
2832 when negative. Assume the typical case where negative sizes
2833 are actually positive values that have wrapped around. */
2834 size += (f->stat.st_size < 0) * ((uintmax_t) OFF_T_MAX - OFF_T_MIN + 1);
2837 human_readable (size, hbuf, 1,
2838 output_block_size < 0 ? output_block_size : 1));
2843 if ((when_local = localtime (&when)))
2845 time_t six_months_ago;
2849 /* If the file appears to be in the future, update the current
2850 time, in case the file happens to have been modified since
2851 the last time we checked the clock. */
2852 if (current_time < when
2853 || (current_time == when && current_time_ns < when_ns))
2855 /* Note that get_current_time calls gettimeofday which, on some non-
2856 compliant systems, clobbers the buffer used for localtime's result.
2857 But it's ok here, because we use a gettimeofday wrapper that
2858 saves and restores the buffer around the gettimeofday call. */
2859 get_current_time ();
2862 /* Consider a time to be recent if it is within the past six
2863 months. A Gregorian year has 365.2425 * 24 * 60 * 60 ==
2864 31556952 seconds on the average. Write this value as an
2865 integer constant to avoid floating point hassles. */
2866 six_months_ago = current_time - 31556952 / 2;
2867 recent = (six_months_ago <= when
2868 && (when < current_time
2869 || (when == current_time && when_ns <= current_time_ns)));
2870 fmt = long_time_format[recent];
2876 s = nstrftime (p, buf + bufsize - p - 1, fmt,
2877 when_local, 0, when_ns);
2880 newbuf = alloca (bufsize *= 2);
2881 memcpy (newbuf, buf, p - buf);
2882 p = newbuf + (p - buf);
2889 /* NUL-terminate the string -- fputs (via DIRED_FPUTS) requires it. */
2894 /* The time cannot be represented as a local time;
2895 print it as a huge integer number of seconds. */
2896 char hbuf[LONGEST_HUMAN_READABLE + 1];
2897 int width = long_time_expected_width ();
2901 const char *num = human_readable (- (uintmax_t) when, hbuf, 1, 1);
2902 int sign_width = width - strlen (num);
2903 sprintf (p, "%*s%s ", sign_width < 0 ? 0 : sign_width, "-", num);
2906 sprintf (p, "%*s ", width,
2907 human_readable ((uintmax_t) when, hbuf, 1, 1));
2913 DIRED_FPUTS (buf, stdout, p - buf);
2914 print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok,
2917 if (f->filetype == symbolic_link)
2921 DIRED_FPUTS_LITERAL (" -> ", stdout);
2922 print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1,
2924 if (indicator_style != none)
2925 print_type_indicator (f->linkmode);
2928 else if (indicator_style != none)
2929 print_type_indicator (f->stat.st_mode);
2932 /* Output to OUT a quoted representation of the file name NAME,
2933 using OPTIONS to control quoting. Produce no output if OUT is NULL.
2934 Return the number of screen columns occupied by NAME's quoted
2938 quote_name (FILE *out, const char *name, struct quoting_options const *options)
2940 char smallbuf[BUFSIZ];
2941 size_t len = quotearg_buffer (smallbuf, sizeof smallbuf, name, -1, options);
2943 int displayed_width;
2945 if (len < sizeof smallbuf)
2949 buf = (char *) alloca (len + 1);
2950 quotearg_buffer (buf, len + 1, name, -1, options);
2953 if (qmark_funny_chars)
2958 char const *p = buf;
2959 char const *plimit = buf + len;
2961 displayed_width = 0;
2966 case ' ': case '!': case '"': case '#': case '%':
2967 case '&': case '\'': case '(': case ')': case '*':
2968 case '+': case ',': case '-': case '.': case '/':
2969 case '0': case '1': case '2': case '3': case '4':
2970 case '5': case '6': case '7': case '8': case '9':
2971 case ':': case ';': case '<': case '=': case '>':
2973 case 'A': case 'B': case 'C': case 'D': case 'E':
2974 case 'F': case 'G': case 'H': case 'I': case 'J':
2975 case 'K': case 'L': case 'M': case 'N': case 'O':
2976 case 'P': case 'Q': case 'R': case 'S': case 'T':
2977 case 'U': case 'V': case 'W': case 'X': case 'Y':
2979 case '[': case '\\': case ']': case '^': case '_':
2980 case 'a': case 'b': case 'c': case 'd': case 'e':
2981 case 'f': case 'g': case 'h': case 'i': case 'j':
2982 case 'k': case 'l': case 'm': case 'n': case 'o':
2983 case 'p': case 'q': case 'r': case 's': case 't':
2984 case 'u': case 'v': case 'w': case 'x': case 'y':
2985 case 'z': case '{': case '|': case '}': case '~':
2986 /* These characters are printable ASCII characters. */
2988 displayed_width += 1;
2991 /* If we have a multibyte sequence, copy it until we
2992 reach its end, replacing each non-printable multibyte
2993 character with a single question mark. */
2996 memset (&mbstate, 0, sizeof mbstate);
3003 bytes = mbrtowc (&wc, p, plimit - p, &mbstate);
3005 if (bytes == (size_t) -1)
3007 /* An invalid multibyte sequence was
3008 encountered. Skip one input byte, and
3009 put a question mark. */
3012 displayed_width += 1;
3016 if (bytes == (size_t) -2)
3018 /* An incomplete multibyte character
3019 at the end. Replace it entirely with
3023 displayed_width += 1;
3028 /* A null wide character was encountered. */
3034 /* A printable multibyte character.
3036 for (; bytes > 0; --bytes)
3038 displayed_width += w;
3042 /* An unprintable multibyte character.
3043 Replace it entirely with a question
3047 displayed_width += 1;
3050 while (! mbsinit (&mbstate));
3055 /* The buffer may have shrunk. */
3062 char const *plimit = buf + len;
3066 if (! ISPRINT ((unsigned char) *p))
3070 displayed_width = len;
3075 /* Assume unprintable characters have a displayed_width of 1. */
3078 displayed_width = mbsnwidth (buf, len, 0);
3081 displayed_width = len;
3085 fwrite (buf, 1, len, out);
3086 return displayed_width;
3090 print_name_with_quoting (const char *p, mode_t mode, int linkok,
3091 struct obstack *stack)
3093 if (print_with_color)
3094 print_color_indicator (p, mode, linkok);
3097 PUSH_CURRENT_DIRED_POS (stack);
3099 dired_pos += quote_name (stdout, p, filename_quoting_options);
3102 PUSH_CURRENT_DIRED_POS (stack);
3104 if (print_with_color)
3105 prep_non_filename_text ();
3109 prep_non_filename_text (void)
3111 if (color_indicator[C_END].string != NULL)
3112 put_indicator (&color_indicator[C_END]);
3115 put_indicator (&color_indicator[C_LEFT]);
3116 put_indicator (&color_indicator[C_NORM]);
3117 put_indicator (&color_indicator[C_RIGHT]);
3121 /* Print the file name of `f' with appropriate quoting.
3122 Also print file size, inode number, and filetype indicator character,
3123 as requested by switches. */
3126 print_file_name_and_frills (const struct fileinfo *f)
3128 char buf[LONGEST_HUMAN_READABLE + 1];
3131 printf ("%*s ", INODE_DIGITS,
3132 human_readable ((uintmax_t) f->stat.st_ino, buf, 1, 1));
3134 if (print_block_size)
3135 printf ("%*s ", block_size_size,
3136 human_readable_inexact ((uintmax_t) ST_NBLOCKS (f->stat), buf,
3137 ST_NBLOCKSIZE, output_block_size,
3140 print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok, NULL);
3142 if (indicator_style != none)
3143 print_type_indicator (f->stat.st_mode);
3147 print_type_indicator (mode_t mode)
3153 if (indicator_style == classify && (mode & S_IXUGO))
3162 else if (S_ISLNK (mode))
3164 else if (S_ISFIFO (mode))
3166 else if (S_ISSOCK (mode))
3168 else if (S_ISDOOR (mode))
3179 print_color_indicator (const char *name, mode_t mode, int linkok)
3182 struct color_ext_type *ext; /* Color extension */
3183 size_t len; /* Length of name */
3185 /* Is this a nonexistent file? If so, linkok == -1. */
3187 if (linkok == -1 && color_indicator[C_MISSING].string != NULL)
3196 else if (S_ISLNK (mode))
3197 type = ((!linkok && color_indicator[C_ORPHAN].string)
3198 ? C_ORPHAN : C_LINK);
3199 else if (S_ISFIFO (mode))
3201 else if (S_ISSOCK (mode))
3203 else if (S_ISBLK (mode))
3205 else if (S_ISCHR (mode))
3207 else if (S_ISDOOR (mode))
3210 if (type == C_FILE && (mode & S_IXUGO) != 0)
3213 /* Check the file's suffix only if still classified as C_FILE. */
3217 /* Test if NAME has a recognized suffix. */
3219 len = strlen (name);
3220 name += len; /* Pointer to final \0. */
3221 for (ext = color_ext_list; ext != NULL; ext = ext->next)
3223 if ((size_t) ext->ext.len <= len
3224 && strncmp (name - ext->ext.len, ext->ext.string,
3231 put_indicator (&color_indicator[C_LEFT]);
3232 put_indicator (ext ? &(ext->seq) : &color_indicator[type]);
3233 put_indicator (&color_indicator[C_RIGHT]);
3236 /* Output a color indicator (which may contain nulls). */
3238 put_indicator (const struct bin_str *ind)
3241 register const char *p;
3245 for (i = ind->len; i > 0; --i)
3250 length_of_file_name_and_frills (const struct fileinfo *f)
3252 register int len = 0;
3255 len += INODE_DIGITS + 1;
3257 if (print_block_size)
3258 len += 1 + block_size_size;
3260 len += quote_name (NULL, f->name, filename_quoting_options);
3262 if (indicator_style != none)
3264 mode_t filetype = f->stat.st_mode;
3266 if (S_ISREG (filetype))
3268 if (indicator_style == classify
3269 && (f->stat.st_mode & S_IXUGO))
3272 else if (S_ISDIR (filetype)
3273 || S_ISLNK (filetype)
3274 || S_ISFIFO (filetype)
3275 || S_ISSOCK (filetype)
3276 || S_ISDOOR (filetype)
3285 print_many_per_line (void)
3287 struct column_info *line_fmt;
3288 int filesno; /* Index into files. */
3289 int row; /* Current row. */
3290 int max_name_length; /* Length of longest file name + frills. */
3291 int name_length; /* Length of each file name + frills. */
3292 int pos; /* Current character column. */
3293 int cols; /* Number of files across. */
3294 int rows; /* Maximum number of files down. */
3297 /* Normally the maximum number of columns is determined by the
3298 screen width. But if few files are available this might limit it
3300 max_cols = max_idx > files_index ? files_index : max_idx;
3302 /* Compute the maximum number of possible columns. */
3303 for (filesno = 0; filesno < files_index; ++filesno)
3307 name_length = length_of_file_name_and_frills (files + filesno);
3309 for (i = 0; i < max_cols; ++i)
3311 if (column_info[i].valid_len)
3313 int idx = filesno / ((files_index + i) / (i + 1));
3314 int real_length = name_length + (idx == i ? 0 : 2);
3316 if (real_length > column_info[i].col_arr[idx])
3318 column_info[i].line_len += (real_length
3319 - column_info[i].col_arr[idx]);
3320 column_info[i].col_arr[idx] = real_length;
3321 column_info[i].valid_len = column_info[i].line_len < line_length;
3327 /* Find maximum allowed columns. */
3328 for (cols = max_cols; cols > 1; --cols)
3330 if (column_info[cols - 1].valid_len)
3334 line_fmt = &column_info[cols - 1];
3336 /* Calculate the number of rows that will be in each column except possibly
3337 for a short column on the right. */
3338 rows = files_index / cols + (files_index % cols != 0);
3340 for (row = 0; row < rows; row++)
3345 /* Print the next row. */
3348 print_file_name_and_frills (files + filesno);
3349 name_length = length_of_file_name_and_frills (files + filesno);
3350 max_name_length = line_fmt->col_arr[col++];
3353 if (filesno >= files_index)
3356 indent (pos + name_length, pos + max_name_length);
3357 pos += max_name_length;
3364 print_horizontal (void)
3366 struct column_info *line_fmt;
3368 int max_name_length;
3374 /* Normally the maximum number of columns is determined by the
3375 screen width. But if few files are available this might limit it
3377 max_cols = max_idx > files_index ? files_index : max_idx;
3379 /* Compute the maximum file name length. */
3380 max_name_length = 0;
3381 for (filesno = 0; filesno < files_index; ++filesno)
3385 name_length = length_of_file_name_and_frills (files + filesno);
3387 for (i = 0; i < max_cols; ++i)
3389 if (column_info[i].valid_len)
3391 int idx = filesno % (i + 1);
3392 int real_length = name_length + (idx == i ? 0 : 2);
3394 if (real_length > column_info[i].col_arr[idx])
3396 column_info[i].line_len += (real_length
3397 - column_info[i].col_arr[idx]);
3398 column_info[i].col_arr[idx] = real_length;
3399 column_info[i].valid_len = column_info[i].line_len < line_length;
3405 /* Find maximum allowed columns. */
3406 for (cols = max_cols; cols > 1; --cols)
3408 if (column_info[cols - 1].valid_len)
3412 line_fmt = &column_info[cols - 1];
3416 /* Print first entry. */
3417 print_file_name_and_frills (files);
3418 name_length = length_of_file_name_and_frills (files);
3419 max_name_length = line_fmt->col_arr[0];
3422 for (filesno = 1; filesno < files_index; ++filesno)
3424 int col = filesno % cols;
3433 indent (pos + name_length, pos + max_name_length);
3434 pos += max_name_length;
3437 print_file_name_and_frills (files + filesno);
3439 name_length = length_of_file_name_and_frills (files + filesno);
3440 max_name_length = line_fmt->col_arr[col];
3446 print_with_commas (void)
3453 for (filesno = 0; filesno < files_index; filesno++)
3457 pos += length_of_file_name_and_frills (files + filesno);
3458 if (filesno + 1 < files_index)
3459 pos += 2; /* For the comma and space */
3461 if (old_pos != 0 && pos >= line_length)
3467 print_file_name_and_frills (files + filesno);
3468 if (filesno + 1 < files_index)
3477 /* Assuming cursor is at position FROM, indent up to position TO.
3478 Use a TAB character instead of two or more spaces whenever possible. */
3481 indent (int from, int to)
3485 if (tabsize > 0 && to / tabsize > (from + 1) / tabsize)
3488 from += tabsize - from % tabsize;
3498 /* Put DIRNAME/NAME into DEST, handling `.' and `/' properly. */
3499 /* FIXME: maybe remove this function someday. See about using a
3500 non-malloc'ing version of path_concat. */
3503 attach (char *dest, const char *dirname, const char *name)
3505 const char *dirnamep = dirname;
3507 /* Copy dirname if it is not ".". */
3508 if (dirname[0] != '.' || dirname[1] != 0)
3511 *dest++ = *dirnamep++;
3512 /* Add '/' if `dirname' doesn't already end with it. */
3513 if (dirnamep > dirname && dirnamep[-1] != '/')
3522 init_column_info (void)
3527 max_idx = line_length / MIN_COLUMN_WIDTH;
3531 if (column_info == NULL)
3533 column_info = XMALLOC (struct column_info, max_idx);
3537 for (i = 0; i < max_idx; ++i)
3541 column_info[i].valid_len = 1;
3542 column_info[i].line_len = (i + 1) * MIN_COLUMN_WIDTH;
3545 column_info[i].col_arr = XMALLOC (int, i + 1);
3547 for (j = 0; j <= i; ++j)
3548 column_info[i].col_arr[j] = MIN_COLUMN_WIDTH;
3556 fprintf (stderr, _("Try `%s --help' for more information.\n"),
3560 printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);
3562 List information about the FILEs (the current directory by default).\n\
3563 Sort entries alphabetically if none of -cftuSUX nor --sort.\n\
3567 Mandatory arguments to long options are mandatory for short options too.\n\
3570 -a, --all do not hide entries starting with .\n\
3571 -A, --almost-all do not list implied . and ..\n\
3572 -b, --escape print octal escapes for nongraphic characters\n\
3575 --block-size=SIZE use SIZE-byte blocks\n\
3576 -B, --ignore-backups do not list implied entries ending with ~\n\
3577 -c with -lt: sort by, and show, ctime (time of last\n\
3578 modification of file status information)\n\
3579 with -l: show ctime and sort by name\n\
3580 otherwise: sort by ctime\n\
3583 -C list entries by columns\n\
3584 --color[=WHEN] control whether color is used to distinguish file\n\
3585 types. WHEN may be `never', `always', or `auto'\n\
3586 -d, --directory list directory entries instead of contents\n\
3587 -D, --dired generate output designed for Emacs' dired mode\n\
3590 -f do not sort, enable -aU, disable -lst\n\
3591 -F, --classify append indicator (one of */=@|) to entries\n\
3592 --format=WORD across -x, commas -m, horizontal -x, long -l,\n\
3593 single-column -1, verbose -l, vertical -C\n\
3594 --full-time like -l --time-style=full-iso\n\
3597 -g like -l, but do not list owner\n\
3598 -G, --no-group inhibit display of group information\n\
3599 -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\n\
3600 --si likewise, but use powers of 1000 not 1024\n\
3601 -H, --dereference-command-line follow symbolic links on the command line\n\
3604 --indicator-style=WORD append indicator with style WORD to entry names:\n\
3605 none (default), classify (-F), file-type (-p)\n\
3606 -i, --inode print index number of each file\n\
3607 -I, --ignore=PATTERN do not list implied entries matching shell PATTERN\n\
3608 -k, --kilobytes like --block-size=1024\n\
3611 -l use a long listing format\n\
3612 -L, --dereference when showing file information for a symbolic\n\
3613 link, show information for the file the link\n\
3614 references rather than for the link itself\n\
3615 -m fill width with a comma separated list of entries\n\
3618 -n, --numeric-uid-gid like -l, but list numeric UIDs and GIDs\n\
3619 -N, --literal print raw entry names (don't treat e.g. control\n\
3620 characters specially)\n\
3621 -o like -l, but do not list group information\n\
3622 -p, --file-type append indicator (one of /=@|) to entries\n\
3625 -q, --hide-control-chars print ? instead of non graphic characters\n\
3626 --show-control-chars show non graphic characters as-is (default\n\
3627 unless program is `ls' and output is a terminal)\n\
3628 -Q, --quote-name enclose entry names in double quotes\n\
3629 --quoting-style=WORD use quoting style WORD for entry names:\n\
3630 literal, locale, shell, shell-always, c, escape\n\
3633 -r, --reverse reverse order while sorting\n\
3634 -R, --recursive list subdirectories recursively\n\
3635 -s, --size print size of each file, in blocks\n\
3638 -S sort by file size\n\
3639 --sort=WORD extension -X, none -U, size -S, time -t,\n\
3641 status -c, time -t, atime -u, access -u, use -u\n\
3642 --time=WORD show time as WORD instead of modification time:\n\
3643 atime, access, use, ctime or status; use\n\
3644 specified time as sort key if --sort=time\n\
3647 --time-style=WORD show times using style WORD:\n\
3648 full-iso, iso, locale, posix-iso\n\
3649 -t sort by modification time\n\
3650 -T, --tabsize=COLS assume tab stops at each COLS instead of 8\n\
3653 -u with -lt: sort by, and show, access time\n\
3654 with -l: show access time and sort by name\n\
3655 otherwise: sort by access time\n\
3656 -U do not sort; list entries in directory order\n\
3657 -v sort by version\n\
3660 -w, --width=COLS assume screen width instead of current value\n\
3661 -x list entries by lines instead of by columns\n\
3662 -X sort alphabetically by entry extension\n\
3663 -1 list one file per line\n\
3666 --help display this help and exit\n\
3667 --version output version information and exit\n\
3671 By default, color is not used to distinguish types of files. That is\n\
3672 equivalent to using --color=none. Using the --color option without the\n\
3673 optional WHEN argument is equivalent to using --color=always. With\n\
3674 --color=auto, color codes are output only if standard output is connected\n\
3675 to a terminal (tty).\n\
3677 puts (_("\nReport bugs to <bug-fileutils@gnu.org>."));