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