1 /* `dir', `vdir' and `ls' directory listing programs for GNU.
2 Copyright (C) 85, 88, 90, 91, 1995-2002 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>
75 /* Get mbstate_t, mbrtowc(), mbsinit(), wcwidth(). */
84 #if !defined iswprint && !HAVE_ISWPRINT
85 # define iswprint(wc) 1
88 #ifndef HAVE_DECL_WCWIDTH
89 "this configure-time declaration test was not run"
91 #if !HAVE_DECL_WCWIDTH
95 /* If wcwidth() doesn't exist, assume all printable characters have
99 # define wcwidth(wc) ((wc) == 0 ? 0 : iswprint (wc) ? 1 : -1)
107 #include "argmatch.h"
111 #include "hard-locale.h"
114 #include "filemode.h"
116 #include "mbswidth.h"
118 #include "path-concat.h"
120 #include "quotearg.h"
122 #include "strverscmp.h"
124 #include "xreadlink.h"
126 #define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \
127 : (ls_mode == LS_MULTI_COL \
130 #define AUTHORS N_ ("Richard Stallman and David MacKenzie")
132 #define obstack_chunk_alloc malloc
133 #define obstack_chunk_free free
135 /* Return an int indicating the result of comparing two integers.
136 Subtracting doesn't always work, due to overflow. */
137 #define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b))
139 /* The field width for inode numbers. On some hosts inode numbers are
140 64 bits, so columns won't line up exactly when a huge inode number
141 is encountered, but in practice 7 digits is usually enough. */
143 # define INODE_DIGITS 7
147 # define HAVE_SYMLINKS 1
149 # define HAVE_SYMLINKS 0
152 /* Arrange to make lstat calls go through the wrapper function
153 on systems with an lstat function that does not dereference symlinks
154 that are specified with a trailing slash. */
155 #if ! LSTAT_FOLLOWS_SLASHED_SYMLINK
156 int rpl_lstat
PARAMS((const char *, struct stat
*));
158 # define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
161 #if HAVE_STRUCT_DIRENT_D_TYPE && defined DTTOIF
162 # define DT_INIT(Val) = Val
164 # define DT_INIT(Val) /* empty */
168 # define TIMESPEC_NS(timespec) ((timespec).ST_MTIM_NSEC)
170 # define TIMESPEC_NS(timespec) 0
173 #if ! HAVE_STRUCT_STAT_ST_AUTHOR
174 # define st_author st_uid
177 /* Cray/Unicos DMF: use the file's migrated, not real, status */
179 # define ST_DM_MODE(Stat_buf) ((Stat_buf).st_dm_mode)
181 # define ST_DM_MODE(Stat_buf) ((Stat_buf).st_mode)
184 #ifndef LOGIN_NAME_MAX
185 # if _POSIX_LOGIN_NAME_MAX
186 # define LOGIN_NAME_MAX _POSIX_LOGIN_NAME_MAX
188 # define LOGIN_NAME_MAX 17
192 /* The maximum length of a string representation of a user or group ID,
193 not counting any terminating NUL byte. */
194 #define ID_LENGTH_MAX \
195 MAX (LOGIN_NAME_MAX - 1, LONGEST_HUMAN_READABLE)
199 unknown
DT_INIT (DT_UNKNOWN
),
200 fifo
DT_INIT (DT_FIFO
),
201 chardev
DT_INIT (DT_CHR
),
202 directory
DT_INIT (DT_DIR
),
203 blockdev
DT_INIT (DT_BLK
),
204 normal
DT_INIT (DT_REG
),
205 symbolic_link
DT_INIT (DT_LNK
),
206 sock
DT_INIT (DT_SOCK
),
207 arg_directory
DT_INIT (2 * (DT_UNKNOWN
| DT_FIFO
| DT_CHR
| DT_DIR
| DT_BLK
208 | DT_REG
| DT_LNK
| DT_SOCK
))
218 /* For symbolic link, name of the file linked to, otherwise zero. */
221 /* For symbolic link and long listing, st_mode of file linked to, otherwise
225 /* For symbolic link and color printing, 1 if linked-to file
226 exists, otherwise 0. */
229 enum filetype filetype
;
232 /* For long listings, true if the file has an access control list. */
238 # define FILE_HAS_ACL(F) ((F)->have_acl)
240 # define FILE_HAS_ACL(F) 0
243 #define LEN_STR_PAIR(s) sizeof (s) - 1, s
245 /* Null is a valid character in a color indicator (think about Epson
246 printers, for example) so we have to use a length/buffer string
251 int len
; /* Number of bytes */
252 const char *string
; /* Pointer to the same */
259 size_t nstrftime
PARAMS ((char *, size_t, char const *,
260 struct tm
const *, int, int));
264 static size_t quote_name
PARAMS ((FILE *out
, const char *name
,
265 struct quoting_options
const *options
));
266 static char *make_link_path
PARAMS ((const char *path
, const char *linkname
));
267 static int decode_switches
PARAMS ((int argc
, char **argv
));
268 static int file_interesting
PARAMS ((const struct dirent
*next
));
269 static uintmax_t gobble_file
PARAMS ((const char *name
, enum filetype type
,
270 int explicit_arg
, const char *dirname
));
271 static void print_color_indicator
PARAMS ((const char *name
, mode_t mode
,
273 static void put_indicator
PARAMS ((const struct bin_str
*ind
));
274 static int length_of_file_name_and_frills
PARAMS ((const struct fileinfo
*f
));
275 static void add_ignore_pattern
PARAMS ((const char *pattern
));
276 static void attach
PARAMS ((char *dest
, const char *dirname
, const char *name
));
277 static void clear_files
PARAMS ((void));
278 static void extract_dirs_from_files
PARAMS ((const char *dirname
,
279 int ignore_dot_and_dot_dot
));
280 static void get_link_name
PARAMS ((const char *filename
, struct fileinfo
*f
));
281 static void indent
PARAMS ((int from
, int to
));
282 static void init_column_info
PARAMS ((void));
283 static void print_current_files
PARAMS ((void));
284 static void print_dir
PARAMS ((const char *name
, const char *realname
));
285 static void print_file_name_and_frills
PARAMS ((const struct fileinfo
*f
));
286 static void print_horizontal
PARAMS ((void));
287 static void print_long_format
PARAMS ((const struct fileinfo
*f
));
288 static void print_many_per_line
PARAMS ((void));
289 static void print_name_with_quoting
PARAMS ((const char *p
, mode_t mode
,
291 struct obstack
*stack
));
292 static void prep_non_filename_text
PARAMS ((void));
293 static void print_type_indicator
PARAMS ((mode_t mode
));
294 static void print_with_commas
PARAMS ((void));
295 static void queue_directory
PARAMS ((const char *name
, const char *realname
));
296 static void sort_files
PARAMS ((void));
297 static void parse_ls_color
PARAMS ((void));
298 void usage
PARAMS ((int status
));
300 /* The name the program was run with, stripped of any leading path. */
303 /* Initial size of hash table.
304 Most hierarchies are likely to be shallower than this. */
305 #define INITIAL_TABLE_SIZE 30
307 /* The set of `active' directories, from the current command-line argument
308 to the level in the hierarchy at which files are being listed.
309 A directory is represented by its device and inode numbers.
310 A directory is added to this set when ls begins listing it or its
311 entries, and it is removed from the set just after ls has finished
312 processing it. This set is used solely to detect loops, e.g., with
313 mkdir loop; cd loop; ln -s ../loop sub; ls -RL */
314 static Hash_table
*active_dir_set
;
316 #define LOOP_DETECT (!!active_dir_set)
318 /* An entry in the active_dir_set. */
325 /* The table of files in the current directory:
327 `files' points to a vector of `struct fileinfo', one per file.
328 `nfiles' is the number of elements space has been allocated for.
329 `files_index' is the number actually in use. */
331 /* Address of block containing the files that are described. */
332 static struct fileinfo
*files
; /* FIXME: rename this to e.g. cwd_file */
334 /* Length of block that `files' points to, measured in files. */
335 static int nfiles
; /* FIXME: rename this to e.g. cwd_n_alloc */
337 /* Index of first unused in `files'. */
338 static int files_index
; /* FIXME: rename this to e.g. cwd_n_used */
340 /* When nonzero, in a color listing, color each symlink name according to the
341 type of file it points to. Otherwise, color them according to the `ln'
342 directive in LS_COLORS. Dangling (orphan) symlinks are treated specially,
343 regardless. This is set when `ln=target' appears in LS_COLORS. */
345 static int color_symlink_as_referent
;
347 /* mode of appropriate file for colorization */
348 #define FILE_OR_LINK_MODE(File) \
349 ((color_symlink_as_referent && (File)->linkok) \
350 ? (File)->linkmode : (File)->stat.st_mode)
353 /* Record of one pending directory waiting to be listed. */
358 /* If the directory is actually the file pointed to by a symbolic link we
359 were told to list, `realname' will contain the name of the symbolic
360 link, otherwise zero. */
362 struct pending
*next
;
365 static struct pending
*pending_dirs
;
367 /* Current time in seconds and nanoseconds since 1970, updated as
368 needed when deciding whether a file is recent. */
370 static time_t current_time
= TYPE_MINIMUM (time_t);
371 static int current_time_ns
= -1;
373 /* The number of digits to use for block sizes.
374 4, or more if needed for bigger numbers. */
376 static int block_size_size
;
380 /* long_format for lots of info, one per line.
381 one_per_line for just names, one per line.
382 many_per_line for just names, many per line, sorted vertically.
383 horizontal for just names, many per line, sorted horizontally.
384 with_commas for just names, many per line, separated by commas.
386 -l (and other options that imply -l), -1, -C, -x and -m control
391 long_format
, /* -l and other options that imply -l */
392 one_per_line
, /* -1 */
393 many_per_line
, /* -C */
398 static enum format format
;
400 /* `full-iso' uses full ISO-style dates and times. `long-iso' uses longer
401 ISO-style time stamps, though shorter than `full-iso'. `iso' uses shorter
402 ISO-style time stamps. `locale' uses locale-dependent time stamps. */
405 full_iso_time_style
, /* --time-style=full-iso */
406 long_iso_time_style
, /* --time-style=long-iso */
407 iso_time_style
, /* --time-style=iso */
408 locale_time_style
/* --time-style=locale */
411 static char const *const time_style_args
[] =
413 "full-iso", "long-iso", "iso", "locale", 0
416 static enum time_style
const time_style_types
[] =
418 full_iso_time_style
, long_iso_time_style
, iso_time_style
,
422 /* Type of time to print or sort by. Controlled by -c and -u. */
426 time_mtime
, /* default */
431 static enum time_type time_type
;
433 /* The file characteristic to sort by. Controlled by -t, -S, -U, -X, -v. */
438 sort_name
, /* default */
439 sort_extension
, /* -X */
442 sort_version
/* -v */
445 static enum sort_type sort_type
;
447 /* Direction of sort.
448 0 means highest first if numeric,
449 lowest first if alphabetic;
450 these are the defaults.
451 1 means the opposite order in each case. -r */
453 static int sort_reverse
;
455 /* Nonzero means to display owner information. -g turns this off. */
457 static int print_owner
= 1;
459 /* Nonzero means to display author information. */
461 static bool print_author
;
463 /* Nonzero means to display group information. -G and -o turn this off. */
465 static int print_group
= 1;
467 /* Nonzero means print the user and group id's as numbers rather
470 static int numeric_ids
;
472 /* Nonzero means mention the size in blocks of each file. -s */
474 static int print_block_size
;
476 /* If positive, the units to use when printing sizes;
477 if negative, the human-readable base. */
478 static int output_block_size
;
480 /* Precede each line of long output (per file) with a string like `m,n:'
481 where M is the number of characters after the `:' and before the
482 filename and N is the length of the filename. Using this format,
483 Emacs' dired mode starts up twice as fast, and can handle all
484 strange characters in file names. */
487 /* `none' means don't mention the type of files.
488 `classify' means mention file types and mark executables.
489 `file_type' means mention only file types.
491 Controlled by -F, -p, and --indicator-style. */
495 none
, /* --indicator-style=none */
496 classify
, /* -F, --indicator-style=classify */
497 file_type
/* -p, --indicator-style=file-type */
500 static enum indicator_style indicator_style
;
502 /* Names of indicator styles. */
503 static char const *const indicator_style_args
[] =
505 "none", "classify", "file-type", 0
508 static enum indicator_style
const indicator_style_types
[]=
510 none
, classify
, file_type
513 /* Nonzero means use colors to mark types. Also define the different
514 colors as well as the stuff for the LS_COLORS environment variable.
515 The LS_COLORS variable is now in a termcap-like format. */
517 static int print_with_color
;
521 color_never
, /* 0: default or --color=never */
522 color_always
, /* 1: --color=always */
523 color_if_tty
/* 2: --color=tty */
526 enum Dereference_symlink
530 DEREF_COMMAND_LINE_ARGUMENTS
, /* -H */
531 DEREF_ALWAYS
/* -L */
536 C_LEFT
, C_RIGHT
, C_END
, C_NORM
, C_FILE
, C_DIR
, C_LINK
, C_FIFO
, C_SOCK
,
537 C_BLK
, C_CHR
, C_MISSING
, C_ORPHAN
, C_EXEC
, C_DOOR
540 static const char *const indicator_name
[]=
542 "lc", "rc", "ec", "no", "fi", "di", "ln", "pi", "so",
543 "bd", "cd", "mi", "or", "ex", "do", NULL
546 struct color_ext_type
548 struct bin_str ext
; /* The extension we're looking for */
549 struct bin_str seq
; /* The sequence to output when we do */
550 struct color_ext_type
*next
; /* Next in list */
553 static struct bin_str color_indicator
[] =
555 { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */
556 { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */
557 { 0, NULL
}, /* ec: End color (replaces lc+no+rc) */
558 { LEN_STR_PAIR ("0") }, /* no: Normal */
559 { LEN_STR_PAIR ("0") }, /* fi: File: default */
560 { LEN_STR_PAIR ("01;34") }, /* di: Directory: bright blue */
561 { LEN_STR_PAIR ("01;36") }, /* ln: Symlink: bright cyan */
562 { LEN_STR_PAIR ("33") }, /* pi: Pipe: yellow/brown */
563 { LEN_STR_PAIR ("01;35") }, /* so: Socket: bright magenta */
564 { LEN_STR_PAIR ("01;33") }, /* bd: Block device: bright yellow */
565 { LEN_STR_PAIR ("01;33") }, /* cd: Char device: bright yellow */
566 { 0, NULL
}, /* mi: Missing file: undefined */
567 { 0, NULL
}, /* or: Orphanned symlink: undefined */
568 { LEN_STR_PAIR ("01;32") }, /* ex: Executable: bright green */
569 { LEN_STR_PAIR ("01;35") } /* do: Door: bright magenta */
573 static struct color_ext_type
*color_ext_list
= NULL
;
575 /* Buffer for color sequences */
576 static char *color_buf
;
578 /* Nonzero means to check for orphaned symbolic link, for displaying
581 static int check_symlink_color
;
583 /* Nonzero means mention the inode number of each file. -i */
585 static int print_inode
;
587 /* What to do with symbolic links. Affected by -d, -F, -H, -l (and
588 other options that imply -l), and -L. */
590 static enum Dereference_symlink dereference
;
592 /* Nonzero means when a directory is found, display info on its
595 static int recursive
;
597 /* Nonzero means when an argument is a directory name, display info
600 static int immediate_dirs
;
602 /* Nonzero means don't omit files whose names start with `.'. -A */
604 static int all_files
;
606 /* Nonzero means don't omit files `.' and `..'
607 This flag implies `all_files'. -a */
609 static int really_all_files
;
611 /* A linked list of shell-style globbing patterns. If a non-argument
612 file name matches any of these patterns, it is omitted.
613 Controlled by -I. Multiple -I options accumulate.
614 The -B option adds `*~' and `.*~' to this list. */
616 struct ignore_pattern
619 struct ignore_pattern
*next
;
622 static struct ignore_pattern
*ignore_patterns
;
624 /* Nonzero means output nongraphic chars in file names as `?'.
625 (-q, --hide-control-chars)
626 qmark_funny_chars and the quoting style (-Q, --quoting-style=WORD) are
627 independent. The algorithm is: first, obey the quoting style to get a
628 string representing the file name; then, if qmark_funny_chars is set,
629 replace all nonprintable chars in that string with `?'. It's necessary
630 to replace nonprintable chars even in quoted strings, because we don't
631 want to mess up the terminal if control chars get sent to it, and some
632 quoting methods pass through control chars as-is. */
633 static int qmark_funny_chars
;
635 /* Quoting options for file and dir name output. */
637 static struct quoting_options
*filename_quoting_options
;
638 static struct quoting_options
*dirname_quoting_options
;
640 /* The number of chars per hardware tab stop. Setting this to zero
641 inhibits the use of TAB characters for separating columns. -T */
644 /* Nonzero means we are listing the working directory because no
645 non-option arguments were given. */
647 static int dir_defaulted
;
649 /* Nonzero means print each directory name before listing it. */
651 static int print_dir_name
;
653 /* The line length to use for breaking lines in many-per-line format.
654 Can be set with -w. */
656 static int line_length
;
658 /* If nonzero, the file listing format requires that stat be called on
661 static int format_needs_stat
;
663 /* Similar to `format_needs_stat', but set if only the file type is
666 static int format_needs_type
;
668 /* strftime formats for non-recent and recent files, respectively, in
671 static char const *long_time_format
[2] =
673 /* strftime format for non-recent files (older than 6 months), in
674 -l output when --time-style=locale is specified. This should
675 contain the year, month and day (at least), in an order that is
676 understood by people in your locale's territory.
677 Please try to keep the number of used screen columns small,
678 because many people work in windows with only 80 columns. But
679 make this as wide as the other string below, for recent files. */
681 /* strftime format for recent files (younger than 6 months), in
682 -l output when --time-style=locale is specified. This should
683 contain the month, day and time (at least), in an order that is
684 understood by people in your locale's territory.
685 Please try to keep the number of used screen columns small,
686 because many people work in windows with only 80 columns. But
687 make this as wide as the other string above, for non-recent files. */
691 /* The exit status to use if we don't get any fatal errors. */
693 static int exit_status
;
695 /* For long options that have no equivalent short option, use a
696 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
699 AUTHOR_OPTION
= CHAR_MAX
+ 1,
704 INDICATOR_STYLE_OPTION
,
705 QUOTING_STYLE_OPTION
,
706 SHOW_CONTROL_CHARS_OPTION
,
713 static struct option
const long_options
[] =
715 {"all", no_argument
, 0, 'a'},
716 {"escape", no_argument
, 0, 'b'},
717 {"directory", no_argument
, 0, 'd'},
718 {"dired", no_argument
, 0, 'D'},
719 {"full-time", no_argument
, 0, FULL_TIME_OPTION
},
720 {"human-readable", no_argument
, 0, 'h'},
721 {"inode", no_argument
, 0, 'i'},
722 {"kilobytes", no_argument
, 0, 'k'}, /* long form is obsolescent */
723 {"numeric-uid-gid", no_argument
, 0, 'n'},
724 {"no-group", no_argument
, 0, 'G'},
725 {"hide-control-chars", no_argument
, 0, 'q'},
726 {"reverse", no_argument
, 0, 'r'},
727 {"size", no_argument
, 0, 's'},
728 {"width", required_argument
, 0, 'w'},
729 {"almost-all", no_argument
, 0, 'A'},
730 {"ignore-backups", no_argument
, 0, 'B'},
731 {"classify", no_argument
, 0, 'F'},
732 {"file-type", no_argument
, 0, 'p'},
733 {"si", no_argument
, 0, SI_OPTION
},
734 {"dereference-command-line", no_argument
, 0, 'H'},
735 {"ignore", required_argument
, 0, 'I'},
736 {"indicator-style", required_argument
, 0, INDICATOR_STYLE_OPTION
},
737 {"dereference", no_argument
, 0, 'L'},
738 {"literal", no_argument
, 0, 'N'},
739 {"quote-name", no_argument
, 0, 'Q'},
740 {"quoting-style", required_argument
, 0, QUOTING_STYLE_OPTION
},
741 {"recursive", no_argument
, 0, 'R'},
742 {"format", required_argument
, 0, FORMAT_OPTION
},
743 {"show-control-chars", no_argument
, 0, SHOW_CONTROL_CHARS_OPTION
},
744 {"sort", required_argument
, 0, SORT_OPTION
},
745 {"tabsize", required_argument
, 0, 'T'},
746 {"time", required_argument
, 0, TIME_OPTION
},
747 {"time-style", required_argument
, 0, TIME_STYLE_OPTION
},
748 {"color", optional_argument
, 0, COLOR_OPTION
},
749 {"block-size", required_argument
, 0, BLOCK_SIZE_OPTION
},
750 {"author", no_argument
, 0, AUTHOR_OPTION
},
751 {GETOPT_HELP_OPTION_DECL
},
752 {GETOPT_VERSION_OPTION_DECL
},
756 static char const *const format_args
[] =
758 "verbose", "long", "commas", "horizontal", "across",
759 "vertical", "single-column", 0
762 static enum format
const format_types
[] =
764 long_format
, long_format
, with_commas
, horizontal
, horizontal
,
765 many_per_line
, one_per_line
768 static char const *const sort_args
[] =
770 "none", "time", "size", "extension", "version", 0
773 static enum sort_type
const sort_types
[] =
775 sort_none
, sort_time
, sort_size
, sort_extension
, sort_version
778 static char const *const time_args
[] =
780 "atime", "access", "use", "ctime", "status", 0
783 static enum time_type
const time_types
[] =
785 time_atime
, time_atime
, time_atime
, time_ctime
, time_ctime
788 static char const *const color_args
[] =
790 /* force and none are for compatibility with another color-ls version */
791 "always", "yes", "force",
792 "never", "no", "none",
793 "auto", "tty", "if-tty", 0
796 static enum color_type
const color_types
[] =
798 color_always
, color_always
, color_always
,
799 color_never
, color_never
, color_never
,
800 color_if_tty
, color_if_tty
, color_if_tty
803 /* Information about filling a column. */
811 /* Array with information about column filledness. */
812 static struct column_info
*column_info
;
814 /* Maximum number of columns ever possible for this display. */
817 /* The minimum width of a colum is 3: 1 character for the name and 2
818 for the separating white space. */
819 #define MIN_COLUMN_WIDTH 3
822 /* This zero-based index is used solely with the --dired option.
823 When that option is in effect, this counter is incremented for each
824 character of output generated by this program so that the beginning
825 and ending indices (in that output) of every file name can be recorded
826 and later output themselves. */
827 static size_t dired_pos
;
829 #define DIRED_PUTCHAR(c) do {putchar ((c)); ++dired_pos;} while (0)
831 /* Write S to STREAM and increment DIRED_POS by S_LEN. */
832 #define DIRED_FPUTS(s, stream, s_len) \
833 do {fputs ((s), (stream)); dired_pos += s_len;} while (0)
835 /* Like DIRED_FPUTS, but for use when S is a literal string. */
836 #define DIRED_FPUTS_LITERAL(s, stream) \
837 do {fputs ((s), (stream)); dired_pos += sizeof((s)) - 1;} while (0)
839 #define DIRED_INDENT() \
842 /* FIXME: remove the `&& format == long_format' clause. */ \
843 if (dired && format == long_format) \
844 DIRED_FPUTS_LITERAL (" ", stdout); \
848 /* With --dired, store pairs of beginning and ending indices of filenames. */
849 static struct obstack dired_obstack
;
851 /* With --dired, store pairs of beginning and ending indices of any
852 directory names that appear as headers (just before `total' line)
853 for lists of directory entries. Such directory names are seen when
854 listing hierarchies using -R and when a directory is listed with at
855 least one other command line argument. */
856 static struct obstack subdired_obstack
;
858 /* Save the current index on the specified obstack, OBS. */
859 #define PUSH_CURRENT_DIRED_POS(obs) \
862 /* FIXME: remove the `&& format == long_format' clause. */ \
863 if (dired && format == long_format) \
864 obstack_grow ((obs), &dired_pos, sizeof (dired_pos)); \
868 /* With -R, this stack is used to help detect directory cycles.
869 The device/inode pairs on this stack mirror the pairs in the
870 active_dir_set hash table. */
871 static struct obstack dev_ino_obstack
;
873 /* Push a pair onto the device/inode stack. */
874 #define DEV_INO_PUSH(Dev, Ino) \
877 struct dev_ino *di; \
878 obstack_blank (&dev_ino_obstack, sizeof (struct dev_ino)); \
879 di = -1 + (struct dev_ino *) obstack_next_free (&dev_ino_obstack); \
880 di->st_dev = (Dev); \
881 di->st_ino = (Ino); \
885 /* Pop a dev/ino struct off the global dev_ino_obstack
886 and return that struct. */
887 static struct dev_ino
890 assert (sizeof (struct dev_ino
) <= obstack_object_size (&dev_ino_obstack
));
891 obstack_blank (&dev_ino_obstack
, -(int) (sizeof (struct dev_ino
)));
892 return *(struct dev_ino
*) obstack_next_free (&dev_ino_obstack
);
895 #define ASSERT_MATCHING_DEV_INO(Name, Di) \
900 assert (0 <= stat (Name, &sb)); \
901 assert (sb.st_dev == Di.st_dev); \
902 assert (sb.st_ino == Di.st_ino); \
907 /* Write to standard output PREFIX, followed by the quoting style and
908 a space-separated list of the integers stored in OS all on one line. */
911 dired_dump_obstack (const char *prefix
, struct obstack
*os
)
915 n_pos
= obstack_object_size (os
) / sizeof (dired_pos
);
921 pos
= (size_t *) obstack_finish (os
);
922 fputs (prefix
, stdout
);
923 for (i
= 0; i
< n_pos
; i
++)
924 printf (" %lu", (unsigned long) pos
[i
]);
925 fputs ("\n", stdout
);
930 dev_ino_hash (void const *x
, unsigned int table_size
)
932 struct dev_ino
const *p
= x
;
933 return (uintmax_t) p
->st_ino
% table_size
;
937 dev_ino_compare (void const *x
, void const *y
)
939 struct dev_ino
const *a
= x
;
940 struct dev_ino
const *b
= y
;
941 return SAME_INODE (*a
, *b
) ? true : false;
945 dev_ino_free (void *x
)
950 /* Add the device/inode pair (P->st_dev/P->st_ino) to the set of
951 active directories. Return nonzero if there is already a matching
952 entry in the table. Otherwise, return zero. */
955 visit_dir (dev_t dev
, ino_t ino
)
958 struct dev_ino
*ent_from_table
;
961 ent
= XMALLOC (struct dev_ino
, 1);
965 /* Attempt to insert this entry into the table. */
966 ent_from_table
= hash_insert (active_dir_set
, ent
);
968 if (ent_from_table
== NULL
)
970 /* Insertion failed due to lack of memory. */
974 found_match
= (ent_from_table
!= ent
);
978 /* ent was not inserted, so free it. */
986 free_pending_ent (struct pending
*p
)
996 main (int argc
, char **argv
)
999 register struct pending
*thispend
;
1000 unsigned int n_files
;
1002 program_name
= argv
[0];
1003 setlocale (LC_ALL
, "");
1004 bindtextdomain (PACKAGE
, LOCALEDIR
);
1005 textdomain (PACKAGE
);
1007 atexit (close_stdout
);
1009 #define N_ENTRIES(Array) (sizeof Array / sizeof *(Array))
1010 assert (N_ENTRIES (color_indicator
) + 1 == N_ENTRIES (indicator_name
));
1017 i
= decode_switches (argc
, argv
);
1019 if (print_with_color
)
1022 /* Test print_with_color again, because the call to parse_ls_color
1023 may have just reset it -- e.g., if LS_COLORS is invalid. */
1024 if (print_with_color
)
1026 prep_non_filename_text ();
1027 /* Avoid following symbolic links when possible. */
1028 if (color_indicator
[C_ORPHAN
].string
!= NULL
1029 || (color_indicator
[C_MISSING
].string
!= NULL
1030 && format
== long_format
))
1031 check_symlink_color
= 1;
1034 if (dereference
== DEREF_UNDEFINED
)
1035 dereference
= ((immediate_dirs
1036 || indicator_style
== classify
1037 || format
== long_format
)
1039 : DEREF_COMMAND_LINE_ARGUMENTS
);
1041 /* When using -R, initialize a data structure we'll use to
1042 detect any directory cycles. */
1045 active_dir_set
= hash_initialize (INITIAL_TABLE_SIZE
, NULL
,
1049 if (active_dir_set
== NULL
)
1052 obstack_init (&dev_ino_obstack
);
1055 format_needs_stat
= sort_type
== sort_time
|| sort_type
== sort_size
1056 || format
== long_format
1057 || dereference
== DEREF_ALWAYS
1058 || recursive
|| print_block_size
|| print_inode
;
1059 format_needs_type
= (format_needs_stat
== 0
1060 && (print_with_color
|| indicator_style
!= none
));
1062 if (dired
&& format
== long_format
)
1064 obstack_init (&dired_obstack
);
1065 obstack_init (&subdired_obstack
);
1069 files
= XMALLOC (struct fileinfo
, nfiles
);
1078 for (; i
< argc
; i
++)
1080 gobble_file (argv
[i
], unknown
, 1, "");
1086 gobble_file (".", directory
, 1, "");
1088 queue_directory (".", 0);
1094 if (!immediate_dirs
)
1095 extract_dirs_from_files ("", 0);
1096 /* `files_index' might be zero now. */
1099 /* In the following if/else blocks, it is sufficient to test `pending_dirs'
1100 (and not pending_dirs->name) because there may be no markers in the queue
1101 at this point. A marker may be enqueued when extract_dirs_from_files is
1102 called with a non-empty string or via print_dir. */
1105 print_current_files ();
1107 DIRED_PUTCHAR ('\n');
1109 else if (n_files
<= 1 && pending_dirs
&& pending_dirs
->next
== 0)
1112 while (pending_dirs
)
1114 thispend
= pending_dirs
;
1115 pending_dirs
= pending_dirs
->next
;
1119 if (thispend
->name
== NULL
)
1121 /* thispend->name == NULL means this is a marker entry
1122 indicating we've finished processing the directory.
1123 Use its dev/ino numbers to remove the corresponding
1124 entry from the active_dir_set hash table. */
1125 struct dev_ino di
= dev_ino_pop ();
1126 struct dev_ino
*found
= hash_delete (active_dir_set
, &di
);
1127 /* ASSERT_MATCHING_DEV_INO (thispend->realname, di); */
1129 dev_ino_free (found
);
1130 free_pending_ent (thispend
);
1135 print_dir (thispend
->name
, thispend
->realname
);
1137 free_pending_ent (thispend
);
1141 if (dired
&& format
== long_format
)
1143 /* No need to free these since we're about to exit. */
1144 dired_dump_obstack ("//DIRED//", &dired_obstack
);
1145 dired_dump_obstack ("//SUBDIRED//", &subdired_obstack
);
1146 printf ("//DIRED-OPTIONS// --quoting-style=%s\n",
1147 quoting_style_args
[get_quoting_style (filename_quoting_options
)]);
1150 /* Restore default color before exiting */
1151 if (print_with_color
)
1153 put_indicator (&color_indicator
[C_LEFT
]);
1154 put_indicator (&color_indicator
[C_RIGHT
]);
1159 assert (hash_get_n_entries (active_dir_set
) == 0);
1160 hash_free (active_dir_set
);
1166 /* Set all the option flags according to the switches specified.
1167 Return the index of the first non-option argument. */
1170 decode_switches (int argc
, char **argv
)
1173 char *time_style_option
= 0;
1175 /* Record whether there is an option specifying sort type. */
1176 int sort_type_specified
= 0;
1178 qmark_funny_chars
= 0;
1180 /* initialize all switches to default settings */
1185 /* This is for the `dir' program. */
1186 format
= many_per_line
;
1187 set_quoting_style (NULL
, escape_quoting_style
);
1190 case LS_LONG_FORMAT
:
1191 /* This is for the `vdir' program. */
1192 format
= long_format
;
1193 set_quoting_style (NULL
, escape_quoting_style
);
1197 /* This is for the `ls' program. */
1198 if (isatty (STDOUT_FILENO
))
1200 format
= many_per_line
;
1201 /* See description of qmark_funny_chars, above. */
1202 qmark_funny_chars
= 1;
1206 format
= one_per_line
;
1207 qmark_funny_chars
= 0;
1215 time_type
= time_mtime
;
1216 sort_type
= sort_name
;
1219 print_block_size
= 0;
1220 indicator_style
= none
;
1222 dereference
= DEREF_UNDEFINED
;
1226 really_all_files
= 0;
1227 ignore_patterns
= 0;
1229 /* FIXME: put this in a function. */
1231 char const *q_style
= getenv ("QUOTING_STYLE");
1234 int i
= ARGCASEMATCH (q_style
, quoting_style_args
, quoting_style_vals
);
1236 set_quoting_style (NULL
, quoting_style_vals
[i
]);
1239 _("ignoring invalid value of environment variable QUOTING_STYLE: %s"),
1240 quotearg (q_style
));
1244 human_block_size (getenv ("LS_BLOCK_SIZE"), 0, &output_block_size
);
1248 char const *p
= getenv ("COLUMNS");
1252 if (xstrtol (p
, NULL
, 0, &tmp_long
, NULL
) == LONGINT_OK
1253 && 0 < tmp_long
&& tmp_long
<= INT_MAX
)
1255 line_length
= (int) tmp_long
;
1260 _("ignoring invalid width in environment variable COLUMNS: %s"),
1270 if (ioctl (STDOUT_FILENO
, TIOCGWINSZ
, &ws
) != -1 && ws
.ws_col
!= 0)
1271 line_length
= ws
.ws_col
;
1275 /* Using the TABSIZE environment variable is not POSIX-approved.
1276 Ignore it when POSIXLY_CORRECT is set. */
1280 if (!getenv ("POSIXLY_CORRECT") && (p
= getenv ("TABSIZE")))
1283 if (xstrtol (p
, NULL
, 0, &tmp_long
, NULL
) == LONGINT_OK
1284 && 0 <= tmp_long
&& tmp_long
<= INT_MAX
)
1286 tabsize
= (int) tmp_long
;
1291 _("ignoring invalid tab size in environment variable TABSIZE: %s"),
1297 while ((c
= getopt_long (argc
, argv
,
1298 "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UX1",
1299 long_options
, NULL
)) != -1)
1308 really_all_files
= 1;
1312 set_quoting_style (NULL
, escape_quoting_style
);
1316 time_type
= time_ctime
;
1324 /* Same as enabling -a -U and disabling -l -s. */
1326 really_all_files
= 1;
1327 sort_type
= sort_none
;
1328 sort_type_specified
= 1;
1330 if (format
== long_format
)
1331 format
= (isatty (STDOUT_FILENO
) ? many_per_line
: one_per_line
);
1332 print_block_size
= 0; /* disable -s */
1333 print_with_color
= 0; /* disable --color */
1337 format
= long_format
;
1342 output_block_size
= -1024;
1350 output_block_size
= 1024;
1354 format
= long_format
;
1358 format
= with_commas
;
1363 format
= long_format
;
1366 case 'o': /* Just like -l, but don't display group info. */
1367 format
= long_format
;
1372 indicator_style
= file_type
;
1376 qmark_funny_chars
= 1;
1384 print_block_size
= 1;
1388 sort_type
= sort_time
;
1389 sort_type_specified
= 1;
1393 time_type
= time_atime
;
1397 sort_type
= sort_version
;
1398 sort_type_specified
= 1;
1404 if (xstrtol (optarg
, NULL
, 0, &tmp_long
, NULL
) != LONGINT_OK
1405 || tmp_long
<= 0 || tmp_long
> INT_MAX
)
1406 error (EXIT_FAILURE
, 0, _("invalid line width: %s"),
1408 line_length
= (int) tmp_long
;
1413 format
= horizontal
;
1417 really_all_files
= 0;
1422 add_ignore_pattern ("*~");
1423 add_ignore_pattern (".*~");
1427 format
= many_per_line
;
1435 indicator_style
= classify
;
1438 case 'G': /* inhibit display of group info */
1443 dereference
= DEREF_COMMAND_LINE_ARGUMENTS
;
1447 add_ignore_pattern (optarg
);
1451 dereference
= DEREF_ALWAYS
;
1455 set_quoting_style (NULL
, literal_quoting_style
);
1459 set_quoting_style (NULL
, c_quoting_style
);
1467 sort_type
= sort_size
;
1468 sort_type_specified
= 1;
1474 if (xstrtol (optarg
, NULL
, 0, &tmp_long
, NULL
) != LONGINT_OK
1475 || tmp_long
< 0 || tmp_long
> INT_MAX
)
1476 error (EXIT_FAILURE
, 0, _("invalid tab size: %s"),
1478 tabsize
= (int) tmp_long
;
1483 sort_type
= sort_none
;
1484 sort_type_specified
= 1;
1488 sort_type
= sort_extension
;
1489 sort_type_specified
= 1;
1493 /* -1 has no effect after -l. */
1494 if (format
!= long_format
)
1495 format
= one_per_line
;
1499 print_author
= true;
1503 sort_type
= XARGMATCH ("--sort", optarg
, sort_args
, sort_types
);
1504 sort_type_specified
= 1;
1508 time_type
= XARGMATCH ("--time", optarg
, time_args
, time_types
);
1512 format
= XARGMATCH ("--format", optarg
, format_args
, format_types
);
1515 case FULL_TIME_OPTION
:
1516 format
= long_format
;
1517 time_style_option
= "full-iso";
1524 i
= XARGMATCH ("--color", optarg
, color_args
, color_types
);
1526 /* Using --color with no argument is equivalent to using
1530 print_with_color
= (i
== color_always
1531 || (i
== color_if_tty
1532 && isatty (STDOUT_FILENO
)));
1534 if (print_with_color
)
1536 /* Don't use TAB characters in output. Some terminal
1537 emulators can't handle the combination of tabs and
1538 color codes on the same line. */
1544 case INDICATOR_STYLE_OPTION
:
1545 indicator_style
= XARGMATCH ("--indicator-style", optarg
,
1546 indicator_style_args
,
1547 indicator_style_types
);
1550 case QUOTING_STYLE_OPTION
:
1551 set_quoting_style (NULL
,
1552 XARGMATCH ("--quoting-style", optarg
,
1554 quoting_style_vals
));
1557 case TIME_STYLE_OPTION
:
1558 time_style_option
= optarg
;
1561 case SHOW_CONTROL_CHARS_OPTION
:
1562 qmark_funny_chars
= 0;
1565 case BLOCK_SIZE_OPTION
:
1566 human_block_size (optarg
, 1, &output_block_size
);
1570 output_block_size
= -1000;
1573 case_GETOPT_HELP_CHAR
;
1575 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
1578 usage (EXIT_FAILURE
);
1582 filename_quoting_options
= clone_quoting_options (NULL
);
1583 if (get_quoting_style (filename_quoting_options
) == escape_quoting_style
)
1584 set_char_quoting (filename_quoting_options
, ' ', 1);
1585 if (indicator_style
!= none
)
1588 for (p
= "*=@|" + (int) indicator_style
- 1; *p
; p
++)
1589 set_char_quoting (filename_quoting_options
, *p
, 1);
1592 dirname_quoting_options
= clone_quoting_options (NULL
);
1593 set_char_quoting (dirname_quoting_options
, ':', 1);
1595 /* If -c or -u is specified and not -l (or any other option that implies -l),
1596 and no sort-type was specified, then sort by the ctime (-c) or atime (-u).
1597 The behavior of ls when using either -c or -u but with neither -l nor -t
1598 appears to be unspecified by POSIX. So, with GNU ls, `-u' alone means
1599 sort by atime (this is the one that's not specified by the POSIX spec),
1600 -lu means show atime and sort by name, -lut means show atime and sort
1603 if ((time_type
== time_ctime
|| time_type
== time_atime
)
1604 && !sort_type_specified
&& format
!= long_format
)
1606 sort_type
= sort_time
;
1609 if (format
== long_format
)
1611 char *style
= time_style_option
;
1612 static char const posix_prefix
[] = "posix-";
1615 if (! (style
= getenv ("TIME_STYLE")))
1616 style
= "posix-long-iso";
1618 while (strncmp (style
, posix_prefix
, sizeof posix_prefix
- 1) == 0)
1620 if (! hard_locale (LC_TIME
))
1622 style
+= sizeof posix_prefix
- 1;
1627 char *p0
= style
+ 1;
1628 char *p1
= strchr (p0
, '\n');
1633 if (strchr (p1
+ 1, '\n'))
1634 error (EXIT_FAILURE
, 0, _("invalid time style format %s"),
1638 long_time_format
[0] = p0
;
1639 long_time_format
[1] = p1
;
1642 switch (XARGMATCH ("time style", style
,
1646 case full_iso_time_style
:
1647 long_time_format
[0] = long_time_format
[1] =
1648 "%Y-%m-%d %H:%M:%S.%N %z";
1651 case long_iso_time_style
:
1652 long_time_format
[0] = long_time_format
[1] = "%Y-%m-%d %H:%M";
1655 case iso_time_style
:
1656 long_time_format
[0] = "%Y-%m-%d ";
1657 long_time_format
[1] = "%m-%d %H:%M";
1660 case locale_time_style
:
1661 if (hard_locale (LC_TIME
))
1664 for (i
= 0; i
< 2; i
++)
1665 long_time_format
[i
] =
1666 dcgettext (NULL
, long_time_format
[i
], LC_TIME
);
1674 /* Parse a string as part of the LS_COLORS variable; this may involve
1675 decoding all kinds of escape characters. If equals_end is set an
1676 unescaped equal sign ends the string, otherwise only a : or \0
1677 does. Returns the number of characters output, or -1 on failure.
1679 The resulting string is *not* null-terminated, but may contain
1682 Note that both dest and src are char **; on return they point to
1683 the first free byte after the array and the character that ended
1684 the input string, respectively. */
1687 get_funky_string (char **dest
, const char **src
, int equals_end
)
1689 int num
; /* For numerical codes */
1690 int count
; /* Something to count with */
1692 ST_GND
, ST_BACKSLASH
, ST_OCTAL
, ST_HEX
, ST_CARET
, ST_END
, ST_ERROR
1697 p
= *src
; /* We don't want to double-indirect */
1698 q
= *dest
; /* the whole darn time. */
1700 count
= 0; /* No characters counted in yet. */
1703 state
= ST_GND
; /* Start in ground state. */
1704 while (state
< ST_END
)
1708 case ST_GND
: /* Ground state (no escapes) */
1713 state
= ST_END
; /* End of string */
1716 state
= ST_BACKSLASH
; /* Backslash scape sequence */
1720 state
= ST_CARET
; /* Caret escape */
1726 state
= ST_END
; /* End */
1729 /* else fall through */
1737 case ST_BACKSLASH
: /* Backslash escaped character */
1748 state
= ST_OCTAL
; /* Octal sequence */
1753 state
= ST_HEX
; /* Hex sequence */
1756 case 'a': /* Bell */
1757 num
= 7; /* Not all C compilers know what \a means */
1759 case 'b': /* Backspace */
1762 case 'e': /* Escape */
1765 case 'f': /* Form feed */
1768 case 'n': /* Newline */
1771 case 'r': /* Carriage return */
1777 case 'v': /* Vtab */
1780 case '?': /* Delete */
1783 case '_': /* Space */
1786 case '\0': /* End of string */
1787 state
= ST_ERROR
; /* Error! */
1789 default: /* Escaped character like \ ^ : = */
1793 if (state
== ST_BACKSLASH
)
1802 case ST_OCTAL
: /* Octal sequence */
1803 if (*p
< '0' || *p
> '7')
1810 num
= (num
<< 3) + (*(p
++) - '0');
1813 case ST_HEX
: /* Hex sequence */
1826 num
= (num
<< 4) + (*(p
++) - '0');
1834 num
= (num
<< 4) + (*(p
++) - 'a') + 10;
1842 num
= (num
<< 4) + (*(p
++) - 'A') + 10;
1852 case ST_CARET
: /* Caret escape */
1853 state
= ST_GND
; /* Should be the next state... */
1854 if (*p
>= '@' && *p
<= '~')
1856 *(q
++) = *(p
++) & 037;
1876 return state
== ST_ERROR
? -1 : count
;
1880 parse_ls_color (void)
1882 const char *p
; /* Pointer to character being parsed */
1883 char *buf
; /* color_buf buffer pointer */
1884 int state
; /* State of parser */
1885 int ind_no
; /* Indicator number */
1886 char label
[3]; /* Indicator label */
1887 struct color_ext_type
*ext
; /* Extension we are working on */
1889 if ((p
= getenv ("LS_COLORS")) == NULL
|| *p
== '\0')
1893 strcpy (label
, "??");
1895 /* This is an overly conservative estimate, but any possible
1896 LS_COLORS string will *not* generate a color_buf longer than
1897 itself, so it is a safe way of allocating a buffer in
1899 buf
= color_buf
= xstrdup (p
);
1906 case 1: /* First label character */
1914 /* Allocate new extension block and add to head of
1915 linked list (this way a later definition will
1916 override an earlier one, which can be useful for
1917 having terminal-specific defs override global). */
1919 ext
= XMALLOC (struct color_ext_type
, 1);
1920 ext
->next
= color_ext_list
;
1921 color_ext_list
= ext
;
1924 ext
->ext
.string
= buf
;
1926 state
= (ext
->ext
.len
=
1927 get_funky_string (&buf
, &p
, 1)) < 0 ? -1 : 4;
1931 state
= 0; /* Done! */
1934 default: /* Assume it is file type label */
1941 case 2: /* Second label character */
1948 state
= -1; /* Error */
1951 case 3: /* Equal sign after indicator label */
1952 state
= -1; /* Assume failure... */
1953 if (*(p
++) == '=')/* It *should* be... */
1955 for (ind_no
= 0; indicator_name
[ind_no
] != NULL
; ++ind_no
)
1957 if (STREQ (label
, indicator_name
[ind_no
]))
1959 color_indicator
[ind_no
].string
= buf
;
1960 state
= ((color_indicator
[ind_no
].len
=
1961 get_funky_string (&buf
, &p
, 0)) < 0 ? -1 : 1);
1966 error (0, 0, _("unrecognized prefix: %s"), quotearg (label
));
1970 case 4: /* Equal sign after *.ext */
1973 ext
->seq
.string
= buf
;
1974 state
= (ext
->seq
.len
=
1975 get_funky_string (&buf
, &p
, 0)) < 0 ? -1 : 1;
1985 struct color_ext_type
*e
;
1986 struct color_ext_type
*e2
;
1989 _("unparsable value for LS_COLORS environment variable"));
1991 for (e
= color_ext_list
; e
!= NULL
; /* empty */)
1997 print_with_color
= 0;
2000 if (color_indicator
[C_LINK
].len
== 6
2001 && !strncmp (color_indicator
[C_LINK
].string
, "target", 6))
2002 color_symlink_as_referent
= 1;
2005 /* Request that the directory named NAME have its contents listed later.
2006 If REALNAME is nonzero, it will be used instead of NAME when the
2007 directory name is printed. This allows symbolic links to directories
2008 to be treated as regular directories but still be listed under their
2009 real names. NAME == NULL is used to insert a marker entry for the
2010 directory named in REALNAME.
2011 If F is non-NULL, we use its dev/ino information to save
2012 a call to stat -- when doing a recursive (-R) traversal. */
2015 queue_directory (const char *name
, const char *realname
)
2017 struct pending
*new;
2019 new = XMALLOC (struct pending
, 1);
2020 new->realname
= realname
? xstrdup (realname
) : NULL
;
2021 new->name
= name
? xstrdup (name
) : NULL
;
2022 new->next
= pending_dirs
;
2026 /* Read directory `name', and list the files in it.
2027 If `realname' is nonzero, print its name instead of `name';
2028 this is used for symbolic links to directories. */
2031 print_dir (const char *name
, const char *realname
)
2033 register DIR *reading
;
2034 register struct dirent
*next
;
2035 register uintmax_t total_blocks
= 0;
2036 static int first
= 1;
2039 reading
= opendir (name
);
2042 error (0, errno
, "%s", quotearg_colon (name
));
2049 struct stat dir_stat
;
2050 int fd
= dirfd (reading
);
2052 /* If dirfd failed, endure the overhead of using stat. */
2054 ? fstat (fd
, &dir_stat
)
2055 : stat (name
, &dir_stat
)) < 0)
2057 error (0, errno
, _("cannot determine device and inode of %s"),
2058 quotearg_colon (name
));
2063 /* If we've already visited this dev/inode pair, warn that
2064 we've found a loop, and do not process this directory. */
2065 if (visit_dir (dir_stat
.st_dev
, dir_stat
.st_ino
))
2067 error (0, 0, _("not listing already-listed directory: %s"),
2068 quotearg_colon (name
));
2072 DEV_INO_PUSH (dir_stat
.st_dev
, dir_stat
.st_ino
);
2075 /* Read the directory entries, and insert the subfiles into the `files'
2080 while ((next
= readdir (reading
)) != NULL
)
2081 if (file_interesting (next
))
2083 enum filetype type
= unknown
;
2085 #if HAVE_STRUCT_DIRENT_D_TYPE
2086 if (next
->d_type
== DT_DIR
|| next
->d_type
== DT_CHR
2087 || next
->d_type
== DT_BLK
|| next
->d_type
== DT_SOCK
2088 || next
->d_type
== DT_FIFO
)
2089 type
= next
->d_type
;
2091 total_blocks
+= gobble_file (next
->d_name
, type
, 0, name
);
2094 if (CLOSEDIR (reading
))
2096 error (0, errno
, "%s", quotearg_colon (name
));
2098 /* Don't return; print whatever we got. */
2101 /* Sort the directory contents. */
2104 /* If any member files are subdirectories, perhaps they should have their
2105 contents listed rather than being mentioned here as files. */
2108 extract_dirs_from_files (name
, 1);
2110 if (recursive
|| print_dir_name
)
2113 DIRED_PUTCHAR ('\n');
2116 PUSH_CURRENT_DIRED_POS (&subdired_obstack
);
2117 dired_pos
+= quote_name (stdout
, realname
? realname
: name
,
2118 dirname_quoting_options
);
2119 PUSH_CURRENT_DIRED_POS (&subdired_obstack
);
2120 DIRED_FPUTS_LITERAL (":\n", stdout
);
2123 if (format
== long_format
|| print_block_size
)
2126 char buf
[LONGEST_HUMAN_READABLE
+ 1];
2130 DIRED_FPUTS (p
, stdout
, strlen (p
));
2131 DIRED_PUTCHAR (' ');
2132 p
= human_readable_inexact (total_blocks
, buf
, ST_NBLOCKSIZE
,
2133 output_block_size
, human_ceiling
);
2134 DIRED_FPUTS (p
, stdout
, strlen (p
));
2135 DIRED_PUTCHAR ('\n');
2139 print_current_files ();
2142 /* Add `pattern' to the list of patterns for which files that match are
2146 add_ignore_pattern (const char *pattern
)
2148 register struct ignore_pattern
*ignore
;
2150 ignore
= XMALLOC (struct ignore_pattern
, 1);
2151 ignore
->pattern
= pattern
;
2152 /* Add it to the head of the linked list. */
2153 ignore
->next
= ignore_patterns
;
2154 ignore_patterns
= ignore
;
2157 /* Return nonzero if the file in `next' should be listed. */
2160 file_interesting (const struct dirent
*next
)
2162 register struct ignore_pattern
*ignore
;
2164 for (ignore
= ignore_patterns
; ignore
; ignore
= ignore
->next
)
2165 if (fnmatch (ignore
->pattern
, next
->d_name
, FNM_PERIOD
) == 0)
2168 if (really_all_files
2169 || next
->d_name
[0] != '.'
2171 && next
->d_name
[1] != '\0'
2172 && (next
->d_name
[1] != '.' || next
->d_name
[2] != '\0')))
2178 /* Enter and remove entries in the table `files'. */
2180 /* Empty the table of files. */
2187 for (i
= 0; i
< files_index
; i
++)
2189 free (files
[i
].name
);
2190 if (files
[i
].linkname
)
2191 free (files
[i
].linkname
);
2195 block_size_size
= 4;
2198 /* Add a file to the current table of files.
2199 Verify that the file exists, and print an error message if it does not.
2200 Return the number of blocks that the file occupies. */
2203 gobble_file (const char *name
, enum filetype type
, int explicit_arg
,
2204 const char *dirname
)
2206 register uintmax_t blocks
;
2207 register char *path
;
2209 if (files_index
== nfiles
)
2212 files
= XREALLOC (files
, struct fileinfo
, nfiles
);
2215 files
[files_index
].linkname
= 0;
2216 files
[files_index
].linkmode
= 0;
2217 files
[files_index
].linkok
= 0;
2219 /* FIXME: this use of ls: `mkdir a; touch a/{b,c,d}; ls -R a'
2220 shouldn't require that ls stat b, c, and d -- at least
2221 not on systems with usable d_type. The problem is that
2222 format_needs_stat is set, because of the -R. */
2223 if (explicit_arg
|| format_needs_stat
2224 || (format_needs_type
&& type
== unknown
))
2226 /* `path' is the absolute pathname of this file. */
2229 if (name
[0] == '/' || dirname
[0] == 0)
2230 path
= (char *) name
;
2233 path
= (char *) alloca (strlen (name
) + strlen (dirname
) + 2);
2234 attach (path
, dirname
, name
);
2237 val
= (DEREF_ALWAYS
<= dereference
+ explicit_arg
2238 ? stat (path
, &files
[files_index
].stat
)
2239 : lstat (path
, &files
[files_index
].stat
));
2243 error (0, errno
, "%s", quotearg_colon (path
));
2249 if (format
== long_format
)
2251 int n
= file_has_acl (path
, &files
[files_index
].stat
);
2252 files
[files_index
].have_acl
= (0 < n
);
2254 error (0, errno
, "%s", quotearg_colon (path
));
2258 if (S_ISLNK (files
[files_index
].stat
.st_mode
)
2259 && (format
== long_format
|| check_symlink_color
))
2262 struct stat linkstats
;
2264 get_link_name (path
, &files
[files_index
]);
2265 linkpath
= make_link_path (path
, files
[files_index
].linkname
);
2267 /* Avoid following symbolic links when possible, ie, when
2268 they won't be traced and when no indicator is needed. */
2270 && (indicator_style
!= none
|| check_symlink_color
)
2271 && stat (linkpath
, &linkstats
) == 0)
2273 files
[files_index
].linkok
= 1;
2275 /* Symbolic links to directories that are mentioned on the
2276 command line are automatically traced if not being
2278 if (explicit_arg
&& format
!= long_format
2279 && S_ISDIR (linkstats
.st_mode
))
2281 /* Substitute the linked-to directory's name, but
2282 save the real name in `linkname' for printing. */
2283 if (!immediate_dirs
)
2285 const char *tempname
= name
;
2287 linkpath
= files
[files_index
].linkname
;
2288 files
[files_index
].linkname
= (char *) tempname
;
2290 files
[files_index
].stat
= linkstats
;
2294 /* Get the linked-to file's mode for the filetype indicator
2295 in long listings. */
2296 files
[files_index
].linkmode
= linkstats
.st_mode
;
2297 files
[files_index
].linkok
= 1;
2304 if (S_ISLNK (files
[files_index
].stat
.st_mode
))
2305 files
[files_index
].filetype
= symbolic_link
;
2306 else if (S_ISDIR (files
[files_index
].stat
.st_mode
))
2308 if (explicit_arg
&& !immediate_dirs
)
2309 files
[files_index
].filetype
= arg_directory
;
2311 files
[files_index
].filetype
= directory
;
2314 files
[files_index
].filetype
= normal
;
2316 blocks
= ST_NBLOCKS (files
[files_index
].stat
);
2318 char buf
[LONGEST_HUMAN_READABLE
+ 1];
2319 int len
= strlen (human_readable_inexact (blocks
, buf
, ST_NBLOCKSIZE
,
2322 if (block_size_size
< len
)
2323 block_size_size
= len
< 7 ? len
: 7;
2328 files
[files_index
].filetype
= type
;
2329 #if HAVE_STRUCT_DIRENT_D_TYPE
2330 files
[files_index
].stat
.st_mode
= DTTOIF (type
);
2335 files
[files_index
].name
= xstrdup (name
);
2343 /* Put the name of the file that `filename' is a symbolic link to
2344 into the `linkname' field of `f'. */
2347 get_link_name (const char *filename
, struct fileinfo
*f
)
2349 f
->linkname
= xreadlink (filename
);
2350 if (f
->linkname
== NULL
)
2352 error (0, errno
, _("cannot read symbolic link %s"),
2353 quotearg_colon (filename
));
2358 /* If `linkname' is a relative path and `path' contains one or more
2359 leading directories, return `linkname' with those directories
2360 prepended; otherwise, return a copy of `linkname'.
2361 If `linkname' is zero, return zero. */
2364 make_link_path (const char *path
, const char *linkname
)
2372 if (*linkname
== '/')
2373 return xstrdup (linkname
);
2375 /* The link is to a relative path. Prepend any leading path
2376 in `path' to the link name. */
2377 linkbuf
= strrchr (path
, '/');
2379 return xstrdup (linkname
);
2381 bufsiz
= linkbuf
- path
+ 1;
2382 linkbuf
= xmalloc (bufsiz
+ strlen (linkname
) + 1);
2383 strncpy (linkbuf
, path
, bufsiz
);
2384 strcpy (linkbuf
+ bufsiz
, linkname
);
2389 /* Return nonzero if base_name (NAME) ends in `.' or `..'
2390 This is so we don't try to recurse on `././././. ...' */
2393 basename_is_dot_or_dotdot (const char *name
)
2395 char const *base
= base_name (name
);
2396 return DOT_OR_DOTDOT (base
);
2399 /* Remove any entries from `files' that are for directories,
2400 and queue them to be listed as directories instead.
2401 `dirname' is the prefix to prepend to each dirname
2402 to make it correct relative to ls's working dir.
2403 If IGNORE_DOT_AND_DOT_DOT is nonzero don't treat `.' and `..' as dirs.
2404 This is desirable when processing directories recursively. */
2407 extract_dirs_from_files (const char *dirname
, int ignore_dot_and_dot_dot
)
2411 if (*dirname
&& LOOP_DETECT
)
2413 /* Insert a marker entry first. When we dequeue this marker entry,
2414 we'll know that DIRNAME has been processed and may be removed
2415 from the set of active directories. */
2416 queue_directory (NULL
, dirname
);
2419 /* Queue the directories last one first, because queueing reverses the
2421 for (i
= files_index
- 1; i
>= 0; i
--)
2422 if ((files
[i
].filetype
== directory
|| files
[i
].filetype
== arg_directory
)
2423 && (!ignore_dot_and_dot_dot
2424 || !basename_is_dot_or_dotdot (files
[i
].name
)))
2426 if (files
[i
].name
[0] == '/' || dirname
[0] == 0)
2428 queue_directory (files
[i
].name
, files
[i
].linkname
);
2432 char *path
= path_concat (dirname
, files
[i
].name
, NULL
);
2433 queue_directory (path
, files
[i
].linkname
);
2436 if (files
[i
].filetype
== arg_directory
)
2437 free (files
[i
].name
);
2440 /* Now delete the directories from the table, compacting all the remaining
2443 for (i
= 0, j
= 0; i
< files_index
; i
++)
2444 if (files
[i
].filetype
!= arg_directory
)
2445 files
[j
++] = files
[i
];
2449 /* Use strcoll to compare strings in this locale. If an error occurs,
2450 report an error and longjmp to failed_strcoll. */
2452 static jmp_buf failed_strcoll
;
2455 xstrcoll (char const *a
, char const *b
)
2459 diff
= strcoll (a
, b
);
2462 error (0, errno
, _("cannot compare file names %s and %s"),
2463 quote_n (0, a
), quote_n (1, b
));
2465 longjmp (failed_strcoll
, 1);
2470 /* Comparison routines for sorting the files. */
2472 typedef void const *V
;
2475 cmp_ctime (struct fileinfo
const *a
, struct fileinfo
const *b
,
2476 int (*cmp
) PARAMS ((char const *, char const *)))
2478 int diff
= CTIME_CMP (b
->stat
, a
->stat
);
2479 return diff
? diff
: cmp (a
->name
, b
->name
);
2481 static int compare_ctime (V a
, V b
) { return cmp_ctime (a
, b
, xstrcoll
); }
2482 static int compstr_ctime (V a
, V b
) { return cmp_ctime (a
, b
, strcmp
); }
2483 static int rev_cmp_ctime (V a
, V b
) { return compare_ctime (b
, a
); }
2484 static int rev_str_ctime (V a
, V b
) { return compstr_ctime (b
, a
); }
2487 cmp_mtime (struct fileinfo
const *a
, struct fileinfo
const *b
,
2488 int (*cmp
) PARAMS((char const *, char const *)))
2490 int diff
= MTIME_CMP (b
->stat
, a
->stat
);
2491 return diff
? diff
: cmp (a
->name
, b
->name
);
2493 static int compare_mtime (V a
, V b
) { return cmp_mtime (a
, b
, xstrcoll
); }
2494 static int compstr_mtime (V a
, V b
) { return cmp_mtime (a
, b
, strcmp
); }
2495 static int rev_cmp_mtime (V a
, V b
) { return compare_mtime (b
, a
); }
2496 static int rev_str_mtime (V a
, V b
) { return compstr_mtime (b
, a
); }
2499 cmp_atime (struct fileinfo
const *a
, struct fileinfo
const *b
,
2500 int (*cmp
) PARAMS ((char const *, char const *)))
2502 int diff
= ATIME_CMP (b
->stat
, a
->stat
);
2503 return diff
? diff
: cmp (a
->name
, b
->name
);
2505 static int compare_atime (V a
, V b
) { return cmp_atime (a
, b
, xstrcoll
); }
2506 static int compstr_atime (V a
, V b
) { return cmp_atime (a
, b
, strcmp
); }
2507 static int rev_cmp_atime (V a
, V b
) { return compare_atime (b
, a
); }
2508 static int rev_str_atime (V a
, V b
) { return compstr_atime (b
, a
); }
2511 cmp_size (struct fileinfo
const *a
, struct fileinfo
const *b
,
2512 int (*cmp
) PARAMS ((char const *, char const *)))
2514 int diff
= longdiff (b
->stat
.st_size
, a
->stat
.st_size
);
2515 return diff
? diff
: cmp (a
->name
, b
->name
);
2517 static int compare_size (V a
, V b
) { return cmp_size (a
, b
, xstrcoll
); }
2518 static int compstr_size (V a
, V b
) { return cmp_size (a
, b
, strcmp
); }
2519 static int rev_cmp_size (V a
, V b
) { return compare_size (b
, a
); }
2520 static int rev_str_size (V a
, V b
) { return compstr_size (b
, a
); }
2523 cmp_version (struct fileinfo
const *a
, struct fileinfo
const *b
)
2525 return strverscmp (a
->name
, b
->name
);
2527 static int compare_version (V a
, V b
) { return cmp_version (a
, b
); }
2528 static int rev_cmp_version (V a
, V b
) { return compare_version (b
, a
); }
2531 cmp_name (struct fileinfo
const *a
, struct fileinfo
const *b
,
2532 int (*cmp
) PARAMS ((char const *, char const *)))
2534 return cmp (a
->name
, b
->name
);
2536 static int compare_name (V a
, V b
) { return cmp_name (a
, b
, xstrcoll
); }
2537 static int compstr_name (V a
, V b
) { return cmp_name (a
, b
, strcmp
); }
2538 static int rev_cmp_name (V a
, V b
) { return compare_name (b
, a
); }
2539 static int rev_str_name (V a
, V b
) { return compstr_name (b
, a
); }
2541 /* Compare file extensions. Files with no extension are `smallest'.
2542 If extensions are the same, compare by filenames instead. */
2545 cmp_extension (struct fileinfo
const *a
, struct fileinfo
const *b
,
2546 int (*cmp
) PARAMS ((char const *, char const *)))
2548 char const *base1
= strrchr (a
->name
, '.');
2549 char const *base2
= strrchr (b
->name
, '.');
2550 int diff
= cmp (base1
? base1
: "", base2
? base2
: "");
2551 return diff
? diff
: cmp (a
->name
, b
->name
);
2553 static int compare_extension (V a
, V b
) { return cmp_extension (a
, b
, xstrcoll
); }
2554 static int compstr_extension (V a
, V b
) { return cmp_extension (a
, b
, strcmp
); }
2555 static int rev_cmp_extension (V a
, V b
) { return compare_extension (b
, a
); }
2556 static int rev_str_extension (V a
, V b
) { return compstr_extension (b
, a
); }
2558 /* Sort the files now in the table. */
2563 int (*func
) PARAMS ((V
, V
));
2573 func
= sort_reverse
? rev_cmp_ctime
: compare_ctime
;
2576 func
= sort_reverse
? rev_cmp_mtime
: compare_mtime
;
2579 func
= sort_reverse
? rev_cmp_atime
: compare_atime
;
2586 func
= sort_reverse
? rev_cmp_name
: compare_name
;
2588 case sort_extension
:
2589 func
= sort_reverse
? rev_cmp_extension
: compare_extension
;
2592 func
= sort_reverse
? rev_cmp_size
: compare_size
;
2595 func
= sort_reverse
? rev_cmp_version
: compare_version
;
2601 /* Try strcoll. If it fails, fall back on strcmp. We can't safely
2602 ignore strcoll failures, as a failing strcoll might be a
2603 comparison function that is not a total order, and if we ignored
2604 the failure this might cause qsort to dump core. */
2606 if (setjmp (failed_strcoll
))
2614 func
= sort_reverse
? rev_str_ctime
: compstr_ctime
;
2617 func
= sort_reverse
? rev_str_mtime
: compstr_mtime
;
2620 func
= sort_reverse
? rev_str_atime
: compstr_atime
;
2627 func
= sort_reverse
? rev_str_name
: compstr_name
;
2629 case sort_extension
:
2630 func
= sort_reverse
? rev_str_extension
: compstr_extension
;
2633 func
= sort_reverse
? rev_str_size
: compstr_size
;
2640 qsort (files
, files_index
, sizeof (struct fileinfo
), func
);
2643 /* List all the files now in the table. */
2646 print_current_files (void)
2653 for (i
= 0; i
< files_index
; i
++)
2655 print_file_name_and_frills (files
+ i
);
2661 init_column_info ();
2662 print_many_per_line ();
2666 init_column_info ();
2667 print_horizontal ();
2671 print_with_commas ();
2675 for (i
= 0; i
< files_index
; i
++)
2677 print_long_format (files
+ i
);
2678 DIRED_PUTCHAR ('\n');
2684 /* Return the expected number of columns in a long-format time stamp,
2685 or zero if it cannot be calculated. */
2688 long_time_expected_width (void)
2690 static int width
= -1;
2695 struct tm
const *tm
= localtime (&epoch
);
2696 char const *fmt
= long_time_format
[0];
2698 char *buf
= initbuf
;
2699 size_t bufsize
= sizeof initbuf
;
2705 len
= nstrftime (buf
, bufsize
, fmt
, tm
, 0, 0);
2708 buf
= alloca (bufsize
*= 2);
2711 width
= mbsnwidth (buf
, len
, 0);
2719 /* Get the current time. */
2722 get_current_time (void)
2724 #if HAVE_CLOCK_GETTIME && defined CLOCK_REALTIME
2726 struct timespec timespec
;
2727 if (clock_gettime (CLOCK_REALTIME
, ×pec
) == 0)
2729 current_time
= timespec
.tv_sec
;
2730 current_time_ns
= timespec
.tv_nsec
;
2736 /* The clock does not have nanosecond resolution, so get the maximum
2737 possible value for the current time that is consistent with the
2738 reported clock. That way, files are not considered to be in the
2739 future merely because their time stamps have higher resolution
2740 than the clock resolution. */
2742 #if HAVE_GETTIMEOFDAY
2744 struct timeval timeval
;
2745 if (gettimeofday (&timeval
, NULL
) == 0)
2747 current_time
= timeval
.tv_sec
;
2748 current_time_ns
= timeval
.tv_usec
* 1000 + 999;
2754 current_time
= time (NULL
);
2755 current_time_ns
= 999999999;
2758 /* Format into BUFFER the name or id of the user with id U. Return
2759 the length of the formatted buffer, not counting the terminating
2763 format_user (char *buffer
, uid_t u
)
2765 char const *name
= (numeric_ids
? NULL
: getuser (u
));
2767 sprintf (buffer
, "%-8s ", name
);
2769 sprintf (buffer
, "%-8lu ", (unsigned long) u
);
2770 return strlen (buffer
);
2773 /* Print information about F in long format. */
2776 print_long_format (const struct fileinfo
*f
)
2780 [LONGEST_HUMAN_READABLE
+ 1 /* inode */
2781 + LONGEST_HUMAN_READABLE
+ 1 /* size in blocks */
2782 + sizeof (modebuf
) - 1 + 1 /* mode string */
2783 + LONGEST_HUMAN_READABLE
+ 1 /* st_nlink */
2784 + ID_LENGTH_MAX
+ 1 /* owner name */
2785 + ID_LENGTH_MAX
+ 1 /* group name */
2786 + ID_LENGTH_MAX
+ 1 /* author name */
2787 + LONGEST_HUMAN_READABLE
+ 1 /* major device number */
2788 + LONGEST_HUMAN_READABLE
+ 1 /* minor device number */
2789 + 35 + 1 /* usual length of time/date -- may be longer; see below */
2791 char *buf
= init_bigbuf
;
2792 size_t bufsize
= sizeof (init_bigbuf
);
2796 int when_ns
IF_LINT (= 0);
2797 struct tm
*when_local
;
2799 /* Compute mode string. On most systems, it's based on st_mode.
2800 On systems with migration (via the stat.st_dm_mode field), use
2801 the file's migrated status. */
2802 mode_string (ST_DM_MODE (f
->stat
), modebuf
);
2804 modebuf
[10] = (FILE_HAS_ACL (f
) ? '+' : ' ');
2810 when
= f
->stat
.st_ctime
;
2811 when_ns
= TIMESPEC_NS (f
->stat
.st_ctim
);
2814 when
= f
->stat
.st_mtime
;
2815 when_ns
= TIMESPEC_NS (f
->stat
.st_mtim
);
2818 when
= f
->stat
.st_atime
;
2819 when_ns
= TIMESPEC_NS (f
->stat
.st_atim
);
2827 char hbuf
[LONGEST_HUMAN_READABLE
+ 1];
2828 sprintf (p
, "%*s ", INODE_DIGITS
,
2829 human_readable ((uintmax_t) f
->stat
.st_ino
, hbuf
, 1, 1));
2833 if (print_block_size
)
2835 char hbuf
[LONGEST_HUMAN_READABLE
+ 1];
2836 sprintf (p
, "%*s ", block_size_size
,
2837 human_readable_inexact ((uintmax_t) ST_NBLOCKS (f
->stat
), hbuf
,
2838 ST_NBLOCKSIZE
, output_block_size
,
2843 /* The last byte of the mode string is the POSIX
2844 "optional alternate access method flag". */
2845 sprintf (p
, "%s %3lu ", modebuf
, (unsigned long) f
->stat
.st_nlink
);
2849 p
+= format_user (p
, f
->stat
.st_uid
);
2853 char const *group_name
= (numeric_ids
? NULL
: getgroup (f
->stat
.st_gid
));
2855 sprintf (p
, "%-8s ", group_name
);
2857 sprintf (p
, "%-8lu ", (unsigned long) f
->stat
.st_gid
);
2862 p
+= format_user (p
, f
->stat
.st_author
);
2864 if (S_ISCHR (f
->stat
.st_mode
) || S_ISBLK (f
->stat
.st_mode
))
2865 sprintf (p
, "%3lu, %3lu ",
2866 (unsigned long) major (f
->stat
.st_rdev
),
2867 (unsigned long) minor (f
->stat
.st_rdev
));
2870 char hbuf
[LONGEST_HUMAN_READABLE
+ 1];
2871 uintmax_t size
= f
->stat
.st_size
;
2873 /* POSIX requires that the size be printed without a sign, even
2874 when negative. Assume the typical case where negative sizes
2875 are actually positive values that have wrapped around. */
2876 size
+= (f
->stat
.st_size
< 0) * ((uintmax_t) OFF_T_MAX
- OFF_T_MIN
+ 1);
2879 human_readable (size
, hbuf
, 1,
2880 output_block_size
< 0 ? output_block_size
: 1));
2885 if ((when_local
= localtime (&when
)))
2887 time_t six_months_ago
;
2891 /* If the file appears to be in the future, update the current
2892 time, in case the file happens to have been modified since
2893 the last time we checked the clock. */
2894 if (current_time
< when
2895 || (current_time
== when
&& current_time_ns
< when_ns
))
2897 /* Note that get_current_time calls gettimeofday which, on some non-
2898 compliant systems, clobbers the buffer used for localtime's result.
2899 But it's ok here, because we use a gettimeofday wrapper that
2900 saves and restores the buffer around the gettimeofday call. */
2901 get_current_time ();
2904 /* Consider a time to be recent if it is within the past six
2905 months. A Gregorian year has 365.2425 * 24 * 60 * 60 ==
2906 31556952 seconds on the average. Write this value as an
2907 integer constant to avoid floating point hassles. */
2908 six_months_ago
= current_time
- 31556952 / 2;
2909 recent
= (six_months_ago
<= when
2910 && (when
< current_time
2911 || (when
== current_time
&& when_ns
<= current_time_ns
)));
2912 fmt
= long_time_format
[recent
];
2918 s
= nstrftime (p
, buf
+ bufsize
- p
- 1, fmt
,
2919 when_local
, 0, when_ns
);
2922 newbuf
= alloca (bufsize
*= 2);
2923 memcpy (newbuf
, buf
, p
- buf
);
2924 p
= newbuf
+ (p
- buf
);
2931 /* NUL-terminate the string -- fputs (via DIRED_FPUTS) requires it. */
2936 /* The time cannot be represented as a local time;
2937 print it as a huge integer number of seconds. */
2938 char hbuf
[LONGEST_HUMAN_READABLE
+ 1];
2939 int width
= long_time_expected_width ();
2943 const char *num
= human_readable (- (uintmax_t) when
, hbuf
, 1, 1);
2944 int sign_width
= width
- strlen (num
);
2945 sprintf (p
, "%*s%s ", sign_width
< 0 ? 0 : sign_width
, "-", num
);
2948 sprintf (p
, "%*s ", width
,
2949 human_readable ((uintmax_t) when
, hbuf
, 1, 1));
2955 DIRED_FPUTS (buf
, stdout
, p
- buf
);
2956 print_name_with_quoting (f
->name
, FILE_OR_LINK_MODE (f
), f
->linkok
,
2959 if (f
->filetype
== symbolic_link
)
2963 DIRED_FPUTS_LITERAL (" -> ", stdout
);
2964 print_name_with_quoting (f
->linkname
, f
->linkmode
, f
->linkok
- 1,
2966 if (indicator_style
!= none
)
2967 print_type_indicator (f
->linkmode
);
2970 else if (indicator_style
!= none
)
2971 print_type_indicator (f
->stat
.st_mode
);
2974 /* Output to OUT a quoted representation of the file name NAME,
2975 using OPTIONS to control quoting. Produce no output if OUT is NULL.
2976 Return the number of screen columns occupied by NAME's quoted
2980 quote_name (FILE *out
, const char *name
, struct quoting_options
const *options
)
2982 char smallbuf
[BUFSIZ
];
2983 size_t len
= quotearg_buffer (smallbuf
, sizeof smallbuf
, name
, -1, options
);
2985 int displayed_width
;
2987 if (len
< sizeof smallbuf
)
2991 buf
= (char *) alloca (len
+ 1);
2992 quotearg_buffer (buf
, len
+ 1, name
, -1, options
);
2995 if (qmark_funny_chars
)
3000 char const *p
= buf
;
3001 char const *plimit
= buf
+ len
;
3003 displayed_width
= 0;
3008 case ' ': case '!': case '"': case '#': case '%':
3009 case '&': case '\'': case '(': case ')': case '*':
3010 case '+': case ',': case '-': case '.': case '/':
3011 case '0': case '1': case '2': case '3': case '4':
3012 case '5': case '6': case '7': case '8': case '9':
3013 case ':': case ';': case '<': case '=': case '>':
3015 case 'A': case 'B': case 'C': case 'D': case 'E':
3016 case 'F': case 'G': case 'H': case 'I': case 'J':
3017 case 'K': case 'L': case 'M': case 'N': case 'O':
3018 case 'P': case 'Q': case 'R': case 'S': case 'T':
3019 case 'U': case 'V': case 'W': case 'X': case 'Y':
3021 case '[': case '\\': case ']': case '^': case '_':
3022 case 'a': case 'b': case 'c': case 'd': case 'e':
3023 case 'f': case 'g': case 'h': case 'i': case 'j':
3024 case 'k': case 'l': case 'm': case 'n': case 'o':
3025 case 'p': case 'q': case 'r': case 's': case 't':
3026 case 'u': case 'v': case 'w': case 'x': case 'y':
3027 case 'z': case '{': case '|': case '}': case '~':
3028 /* These characters are printable ASCII characters. */
3030 displayed_width
+= 1;
3033 /* If we have a multibyte sequence, copy it until we
3034 reach its end, replacing each non-printable multibyte
3035 character with a single question mark. */
3038 memset (&mbstate
, 0, sizeof mbstate
);
3045 bytes
= mbrtowc (&wc
, p
, plimit
- p
, &mbstate
);
3047 if (bytes
== (size_t) -1)
3049 /* An invalid multibyte sequence was
3050 encountered. Skip one input byte, and
3051 put a question mark. */
3054 displayed_width
+= 1;
3058 if (bytes
== (size_t) -2)
3060 /* An incomplete multibyte character
3061 at the end. Replace it entirely with
3065 displayed_width
+= 1;
3070 /* A null wide character was encountered. */
3076 /* A printable multibyte character.
3078 for (; bytes
> 0; --bytes
)
3080 displayed_width
+= w
;
3084 /* An unprintable multibyte character.
3085 Replace it entirely with a question
3089 displayed_width
+= 1;
3092 while (! mbsinit (&mbstate
));
3097 /* The buffer may have shrunk. */
3104 char const *plimit
= buf
+ len
;
3108 if (! ISPRINT ((unsigned char) *p
))
3112 displayed_width
= len
;
3117 /* Assume unprintable characters have a displayed_width of 1. */
3120 displayed_width
= mbsnwidth (buf
, len
, 0);
3123 displayed_width
= len
;
3127 fwrite (buf
, 1, len
, out
);
3128 return displayed_width
;
3132 print_name_with_quoting (const char *p
, mode_t mode
, int linkok
,
3133 struct obstack
*stack
)
3135 if (print_with_color
)
3136 print_color_indicator (p
, mode
, linkok
);
3139 PUSH_CURRENT_DIRED_POS (stack
);
3141 dired_pos
+= quote_name (stdout
, p
, filename_quoting_options
);
3144 PUSH_CURRENT_DIRED_POS (stack
);
3146 if (print_with_color
)
3147 prep_non_filename_text ();
3151 prep_non_filename_text (void)
3153 if (color_indicator
[C_END
].string
!= NULL
)
3154 put_indicator (&color_indicator
[C_END
]);
3157 put_indicator (&color_indicator
[C_LEFT
]);
3158 put_indicator (&color_indicator
[C_NORM
]);
3159 put_indicator (&color_indicator
[C_RIGHT
]);
3163 /* Print the file name of `f' with appropriate quoting.
3164 Also print file size, inode number, and filetype indicator character,
3165 as requested by switches. */
3168 print_file_name_and_frills (const struct fileinfo
*f
)
3170 char buf
[LONGEST_HUMAN_READABLE
+ 1];
3173 printf ("%*s ", INODE_DIGITS
,
3174 human_readable ((uintmax_t) f
->stat
.st_ino
, buf
, 1, 1));
3176 if (print_block_size
)
3177 printf ("%*s ", block_size_size
,
3178 human_readable_inexact ((uintmax_t) ST_NBLOCKS (f
->stat
), buf
,
3179 ST_NBLOCKSIZE
, output_block_size
,
3182 print_name_with_quoting (f
->name
, FILE_OR_LINK_MODE (f
), f
->linkok
, NULL
);
3184 if (indicator_style
!= none
)
3185 print_type_indicator (f
->stat
.st_mode
);
3189 print_type_indicator (mode_t mode
)
3195 if (indicator_style
== classify
&& (mode
& S_IXUGO
))
3204 else if (S_ISLNK (mode
))
3206 else if (S_ISFIFO (mode
))
3208 else if (S_ISSOCK (mode
))
3210 else if (S_ISDOOR (mode
))
3221 print_color_indicator (const char *name
, mode_t mode
, int linkok
)
3224 struct color_ext_type
*ext
; /* Color extension */
3225 size_t len
; /* Length of name */
3227 /* Is this a nonexistent file? If so, linkok == -1. */
3229 if (linkok
== -1 && color_indicator
[C_MISSING
].string
!= NULL
)
3238 else if (S_ISLNK (mode
))
3239 type
= ((!linkok
&& color_indicator
[C_ORPHAN
].string
)
3240 ? C_ORPHAN
: C_LINK
);
3241 else if (S_ISFIFO (mode
))
3243 else if (S_ISSOCK (mode
))
3245 else if (S_ISBLK (mode
))
3247 else if (S_ISCHR (mode
))
3249 else if (S_ISDOOR (mode
))
3252 if (type
== C_FILE
&& (mode
& S_IXUGO
) != 0)
3255 /* Check the file's suffix only if still classified as C_FILE. */
3259 /* Test if NAME has a recognized suffix. */
3261 len
= strlen (name
);
3262 name
+= len
; /* Pointer to final \0. */
3263 for (ext
= color_ext_list
; ext
!= NULL
; ext
= ext
->next
)
3265 if ((size_t) ext
->ext
.len
<= len
3266 && strncmp (name
- ext
->ext
.len
, ext
->ext
.string
,
3273 put_indicator (&color_indicator
[C_LEFT
]);
3274 put_indicator (ext
? &(ext
->seq
) : &color_indicator
[type
]);
3275 put_indicator (&color_indicator
[C_RIGHT
]);
3278 /* Output a color indicator (which may contain nulls). */
3280 put_indicator (const struct bin_str
*ind
)
3283 register const char *p
;
3287 for (i
= ind
->len
; i
> 0; --i
)
3292 length_of_file_name_and_frills (const struct fileinfo
*f
)
3294 register int len
= 0;
3297 len
+= INODE_DIGITS
+ 1;
3299 if (print_block_size
)
3300 len
+= 1 + block_size_size
;
3302 len
+= quote_name (NULL
, f
->name
, filename_quoting_options
);
3304 if (indicator_style
!= none
)
3306 mode_t filetype
= f
->stat
.st_mode
;
3308 if (S_ISREG (filetype
))
3310 if (indicator_style
== classify
3311 && (f
->stat
.st_mode
& S_IXUGO
))
3314 else if (S_ISDIR (filetype
)
3315 || S_ISLNK (filetype
)
3316 || S_ISFIFO (filetype
)
3317 || S_ISSOCK (filetype
)
3318 || S_ISDOOR (filetype
)
3327 print_many_per_line (void)
3329 struct column_info
*line_fmt
;
3330 int filesno
; /* Index into files. */
3331 int row
; /* Current row. */
3332 int max_name_length
; /* Length of longest file name + frills. */
3333 int name_length
; /* Length of each file name + frills. */
3334 int pos
; /* Current character column. */
3335 int cols
; /* Number of files across. */
3336 int rows
; /* Maximum number of files down. */
3339 /* Normally the maximum number of columns is determined by the
3340 screen width. But if few files are available this might limit it
3342 max_cols
= max_idx
> files_index
? files_index
: max_idx
;
3344 /* Compute the maximum number of possible columns. */
3345 for (filesno
= 0; filesno
< files_index
; ++filesno
)
3349 name_length
= length_of_file_name_and_frills (files
+ filesno
);
3351 for (i
= 0; i
< max_cols
; ++i
)
3353 if (column_info
[i
].valid_len
)
3355 int idx
= filesno
/ ((files_index
+ i
) / (i
+ 1));
3356 int real_length
= name_length
+ (idx
== i
? 0 : 2);
3358 if (real_length
> column_info
[i
].col_arr
[idx
])
3360 column_info
[i
].line_len
+= (real_length
3361 - column_info
[i
].col_arr
[idx
]);
3362 column_info
[i
].col_arr
[idx
] = real_length
;
3363 column_info
[i
].valid_len
= column_info
[i
].line_len
< line_length
;
3369 /* Find maximum allowed columns. */
3370 for (cols
= max_cols
; cols
> 1; --cols
)
3372 if (column_info
[cols
- 1].valid_len
)
3376 line_fmt
= &column_info
[cols
- 1];
3378 /* Calculate the number of rows that will be in each column except possibly
3379 for a short column on the right. */
3380 rows
= files_index
/ cols
+ (files_index
% cols
!= 0);
3382 for (row
= 0; row
< rows
; row
++)
3387 /* Print the next row. */
3390 print_file_name_and_frills (files
+ filesno
);
3391 name_length
= length_of_file_name_and_frills (files
+ filesno
);
3392 max_name_length
= line_fmt
->col_arr
[col
++];
3395 if (filesno
>= files_index
)
3398 indent (pos
+ name_length
, pos
+ max_name_length
);
3399 pos
+= max_name_length
;
3406 print_horizontal (void)
3408 struct column_info
*line_fmt
;
3410 int max_name_length
;
3416 /* Normally the maximum number of columns is determined by the
3417 screen width. But if few files are available this might limit it
3419 max_cols
= max_idx
> files_index
? files_index
: max_idx
;
3421 /* Compute the maximum file name length. */
3422 max_name_length
= 0;
3423 for (filesno
= 0; filesno
< files_index
; ++filesno
)
3427 name_length
= length_of_file_name_and_frills (files
+ filesno
);
3429 for (i
= 0; i
< max_cols
; ++i
)
3431 if (column_info
[i
].valid_len
)
3433 int idx
= filesno
% (i
+ 1);
3434 int real_length
= name_length
+ (idx
== i
? 0 : 2);
3436 if (real_length
> column_info
[i
].col_arr
[idx
])
3438 column_info
[i
].line_len
+= (real_length
3439 - column_info
[i
].col_arr
[idx
]);
3440 column_info
[i
].col_arr
[idx
] = real_length
;
3441 column_info
[i
].valid_len
= column_info
[i
].line_len
< line_length
;
3447 /* Find maximum allowed columns. */
3448 for (cols
= max_cols
; cols
> 1; --cols
)
3450 if (column_info
[cols
- 1].valid_len
)
3454 line_fmt
= &column_info
[cols
- 1];
3458 /* Print first entry. */
3459 print_file_name_and_frills (files
);
3460 name_length
= length_of_file_name_and_frills (files
);
3461 max_name_length
= line_fmt
->col_arr
[0];
3464 for (filesno
= 1; filesno
< files_index
; ++filesno
)
3466 int col
= filesno
% cols
;
3475 indent (pos
+ name_length
, pos
+ max_name_length
);
3476 pos
+= max_name_length
;
3479 print_file_name_and_frills (files
+ filesno
);
3481 name_length
= length_of_file_name_and_frills (files
+ filesno
);
3482 max_name_length
= line_fmt
->col_arr
[col
];
3488 print_with_commas (void)
3495 for (filesno
= 0; filesno
< files_index
; filesno
++)
3499 pos
+= length_of_file_name_and_frills (files
+ filesno
);
3500 if (filesno
+ 1 < files_index
)
3501 pos
+= 2; /* For the comma and space */
3503 if (old_pos
!= 0 && pos
>= line_length
)
3509 print_file_name_and_frills (files
+ filesno
);
3510 if (filesno
+ 1 < files_index
)
3519 /* Assuming cursor is at position FROM, indent up to position TO.
3520 Use a TAB character instead of two or more spaces whenever possible. */
3523 indent (int from
, int to
)
3527 if (tabsize
> 0 && to
/ tabsize
> (from
+ 1) / tabsize
)
3530 from
+= tabsize
- from
% tabsize
;
3540 /* Put DIRNAME/NAME into DEST, handling `.' and `/' properly. */
3541 /* FIXME: maybe remove this function someday. See about using a
3542 non-malloc'ing version of path_concat. */
3545 attach (char *dest
, const char *dirname
, const char *name
)
3547 const char *dirnamep
= dirname
;
3549 /* Copy dirname if it is not ".". */
3550 if (dirname
[0] != '.' || dirname
[1] != 0)
3553 *dest
++ = *dirnamep
++;
3554 /* Add '/' if `dirname' doesn't already end with it. */
3555 if (dirnamep
> dirname
&& dirnamep
[-1] != '/')
3564 init_column_info (void)
3569 max_idx
= line_length
/ MIN_COLUMN_WIDTH
;
3573 if (column_info
== NULL
)
3575 column_info
= XMALLOC (struct column_info
, max_idx
);
3579 for (i
= 0; i
< max_idx
; ++i
)
3583 column_info
[i
].valid_len
= 1;
3584 column_info
[i
].line_len
= (i
+ 1) * MIN_COLUMN_WIDTH
;
3587 column_info
[i
].col_arr
= XMALLOC (int, i
+ 1);
3589 for (j
= 0; j
<= i
; ++j
)
3590 column_info
[i
].col_arr
[j
] = MIN_COLUMN_WIDTH
;
3598 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
3602 printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name
);
3604 List information about the FILEs (the current directory by default).\n\
3605 Sort entries alphabetically if none of -cftuSUX nor --sort.\n\
3609 Mandatory arguments to long options are mandatory for short options too.\n\
3612 -a, --all do not hide entries starting with .\n\
3613 -A, --almost-all do not list implied . and ..\n\
3614 --author print the author of each file\n\
3615 -b, --escape print octal escapes for nongraphic characters\n\
3618 --block-size=SIZE use SIZE-byte blocks\n\
3619 -B, --ignore-backups do not list implied entries ending with ~\n\
3620 -c with -lt: sort by, and show, ctime (time of last\n\
3621 modification of file status information)\n\
3622 with -l: show ctime and sort by name\n\
3623 otherwise: sort by ctime\n\
3626 -C list entries by columns\n\
3627 --color[=WHEN] control whether color is used to distinguish file\n\
3628 types. WHEN may be `never', `always', or `auto'\n\
3629 -d, --directory list directory entries instead of contents\n\
3630 -D, --dired generate output designed for Emacs' dired mode\n\
3633 -f do not sort, enable -aU, disable -lst\n\
3634 -F, --classify append indicator (one of */=@|) to entries\n\
3635 --format=WORD across -x, commas -m, horizontal -x, long -l,\n\
3636 single-column -1, verbose -l, vertical -C\n\
3637 --full-time like -l --time-style=full-iso\n\
3640 -g like -l, but do not list owner\n\
3641 -G, --no-group inhibit display of group information\n\
3642 -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\n\
3643 --si likewise, but use powers of 1000 not 1024\n\
3644 -H, --dereference-command-line follow symbolic links on the command line\n\
3647 --indicator-style=WORD append indicator with style WORD to entry names:\n\
3648 none (default), classify (-F), file-type (-p)\n\
3649 -i, --inode print index number of each file\n\
3650 -I, --ignore=PATTERN do not list implied entries matching shell PATTERN\n\
3651 -k like --block-size=1K\n\
3654 -l use a long listing format\n\
3655 -L, --dereference when showing file information for a symbolic\n\
3656 link, show information for the file the link\n\
3657 references rather than for the link itself\n\
3658 -m fill width with a comma separated list of entries\n\
3661 -n, --numeric-uid-gid like -l, but list numeric UIDs and GIDs\n\
3662 -N, --literal print raw entry names (don't treat e.g. control\n\
3663 characters specially)\n\
3664 -o like -l, but do not list group information\n\
3665 -p, --file-type append indicator (one of /=@|) to entries\n\
3668 -q, --hide-control-chars print ? instead of non graphic characters\n\
3669 --show-control-chars show non graphic characters as-is (default\n\
3670 unless program is `ls' and output is a terminal)\n\
3671 -Q, --quote-name enclose entry names in double quotes\n\
3672 --quoting-style=WORD use quoting style WORD for entry names:\n\
3673 literal, locale, shell, shell-always, c, escape\n\
3676 -r, --reverse reverse order while sorting\n\
3677 -R, --recursive list subdirectories recursively\n\
3678 -s, --size print size of each file, in blocks\n\
3681 -S sort by file size\n\
3682 --sort=WORD extension -X, none -U, size -S, time -t,\n\
3684 status -c, time -t, atime -u, access -u, use -u\n\
3685 --time=WORD show time as WORD instead of modification time:\n\
3686 atime, access, use, ctime or status; use\n\
3687 specified time as sort key if --sort=time\n\
3690 --time-style=STYLE show times using style STYLE:\n\
3691 full-iso, long-iso, iso, locale, +FORMAT\n\
3692 FORMAT is interpreted like `date'; if FORMAT is\n\
3693 FORMAT1<newline>FORMAT2, FORMAT1 applies to\n\
3694 non-recent files and FORMAT2 to recent files;\n\
3695 if STYLE is prefixed with `posix-', STYLE\n\
3696 takes effect only outside the POSIX locale\n\
3697 -t sort by modification time\n\
3698 -T, --tabsize=COLS assume tab stops at each COLS instead of 8\n\
3701 -u with -lt: sort by, and show, access time\n\
3702 with -l: show access time and sort by name\n\
3703 otherwise: sort by access time\n\
3704 -U do not sort; list entries in directory order\n\
3705 -v sort by version\n\
3708 -w, --width=COLS assume screen width instead of current value\n\
3709 -x list entries by lines instead of by columns\n\
3710 -X sort alphabetically by entry extension\n\
3711 -1 list one file per line\n\
3713 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
3714 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
3716 SIZE may be (or may be an integer optionally followed by) one of following:\n\
3717 kB 1000, K 1024, MB 1,000,000, M 1,048,576, and so on for G, T, P, E, Z, Y.\n\
3721 By default, color is not used to distinguish types of files. That is\n\
3722 equivalent to using --color=none. Using the --color option without the\n\
3723 optional WHEN argument is equivalent to using --color=always. With\n\
3724 --color=auto, color codes are output only if standard output is connected\n\
3725 to a terminal (tty).\n\
3727 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT
);