⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ls.c

📁 Linux.Programming.by example 的源代码绝对经典
💻 C
📖 第 1 页 / 共 5 页
字号:
/* `dir', `vdir' and `ls' directory listing programs for GNU.   Copyright (C) 85, 88, 90, 91, 1995-2003 Free Software Foundation, Inc.   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software Foundation,   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  *//* If ls_mode is LS_MULTI_COL,   the multi-column format is the default regardless   of the type of output device.   This is for the `dir' program.   If ls_mode is LS_LONG_FORMAT,   the long format is the default regardless of the   type of output device.   This is for the `vdir' program.   If ls_mode is LS_LS,   the output format depends on whether the output   device is a terminal.   This is for the `ls' program. *//* Written by Richard Stallman and David MacKenzie.  *//* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis   Flaherty <dennisf@denix.elk.miles.com> based on original patches by   Greg Lee <lee@uhunix.uhcc.hawaii.edu>.  */#ifdef _AIX #pragma alloca#endif#include <config.h>#include <sys/types.h>#if HAVE_TERMIOS_H# include <termios.h>#endif#ifdef GWINSZ_IN_SYS_IOCTL# include <sys/ioctl.h>#endif#ifdef WINSIZE_IN_PTEM# include <sys/stream.h># include <sys/ptem.h>#endif#include <stdio.h>#include <assert.h>#include <setjmp.h>#include <grp.h>#include <pwd.h>#include <getopt.h>#include <signal.h>/* Get MB_CUR_MAX.  */#if HAVE_STDLIB_H# include <stdlib.h>#endif/* Get mbstate_t, mbrtowc(), mbsinit(), wcwidth().  */#if HAVE_WCHAR_H# include <wchar.h>#endif/* Get iswprint().  */#if HAVE_WCTYPE_H# include <wctype.h>#endif#if !defined iswprint && !HAVE_ISWPRINT# define iswprint(wc) 1#endif#ifndef HAVE_DECL_WCWIDTH"this configure-time declaration test was not run"#endif#if !HAVE_DECL_WCWIDTHint wcwidth ();#endif/* If wcwidth() doesn't exist, assume all printable characters have   width 1.  */#ifndef wcwidth# if !HAVE_WCWIDTH#  define wcwidth(wc) ((wc) == 0 ? 0 : iswprint (wc) ? 1 : -1)# endif#endif#include "system.h"#include <fnmatch.h>#include "acl.h"#include "argmatch.h"#include "dev-ino.h"#include "dirname.h"#include "dirfd.h"#include "error.h"#include "full-write.h"#include "hard-locale.h"#include "hash.h"#include "human.h"#include "filemode.h"#include "inttostr.h"#include "ls.h"#include "mbswidth.h"#include "obstack.h"#include "path-concat.h"#include "quote.h"#include "quotearg.h"#include "same.h"#include "strftime.h"#include "strverscmp.h"#include "xstrtol.h"#include "xreadlink.h"#define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \		      : (ls_mode == LS_MULTI_COL \			 ? "dir" : "vdir"))#define AUTHORS N_ ("Richard Stallman and David MacKenzie")#define obstack_chunk_alloc malloc#define obstack_chunk_free free/* Return an int indicating the result of comparing two integers.   Subtracting doesn't always work, due to overflow.  */#define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b))/* The field width for inode numbers.  On some hosts inode numbers are   64 bits, so columns won't line up exactly when a huge inode number   is encountered, but in practice 7 digits is usually enough.  */#ifndef INODE_DIGITS# define INODE_DIGITS 7#endif/* Arrange to make lstat calls go through the wrapper function   on systems with an lstat function that does not dereference symlinks   that are specified with a trailing slash.  */#if ! LSTAT_FOLLOWS_SLASHED_SYMLINKint rpl_lstat (const char *, struct stat *);# undef lstat# define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)#endif#if HAVE_STRUCT_DIRENT_D_TYPE && defined DTTOIF# define DT_INIT(Val) = Val#else# define DT_INIT(Val) /* empty */#endif#ifdef ST_MTIM_NSEC# define TIMESPEC_NS(timespec) ((timespec).ST_MTIM_NSEC)#else# define TIMESPEC_NS(timespec) 0#endif#if ! HAVE_STRUCT_STAT_ST_AUTHOR# define st_author st_uid#endif/* Cray/Unicos DMF: use the file's migrated, not real, status */#if HAVE_ST_DM_MODE# define ST_DM_MODE(Stat_buf) ((Stat_buf).st_dm_mode)#else# define ST_DM_MODE(Stat_buf) ((Stat_buf).st_mode)#endif#ifndef LOGIN_NAME_MAX# if _POSIX_LOGIN_NAME_MAX#  define LOGIN_NAME_MAX _POSIX_LOGIN_NAME_MAX# else#  define LOGIN_NAME_MAX 17# endif#endif/* The maximum length of a string representation of a user or group ID,   not counting any terminating NUL byte.  */#define ID_LENGTH_MAX \  MAX (LOGIN_NAME_MAX - 1, LONGEST_HUMAN_READABLE)enum filetype  {    unknown DT_INIT (DT_UNKNOWN),    fifo DT_INIT (DT_FIFO),    chardev DT_INIT (DT_CHR),    directory DT_INIT (DT_DIR),    blockdev DT_INIT (DT_BLK),    normal DT_INIT (DT_REG),    symbolic_link DT_INIT (DT_LNK),    sock DT_INIT (DT_SOCK),    arg_directory DT_INIT (2 * (DT_UNKNOWN | DT_FIFO | DT_CHR | DT_DIR | DT_BLK				| DT_REG | DT_LNK | DT_SOCK))  };struct fileinfo  {    /* The file name. */    char *name;    struct stat stat;    /* For symbolic link, name of the file linked to, otherwise zero. */    char *linkname;    /* For symbolic link and long listing, st_mode of file linked to, otherwise       zero. */    mode_t linkmode;    /* For symbolic link and color printing, 1 if linked-to file       exists, otherwise 0.  */    int linkok;    enum filetype filetype;#if HAVE_ACL    /* For long listings, true if the file has an access control list.  */    bool have_acl;#endif  };#if HAVE_ACL# define FILE_HAS_ACL(F) ((F)->have_acl)#else# define FILE_HAS_ACL(F) 0#endif#define LEN_STR_PAIR(s) sizeof (s) - 1, s/* Null is a valid character in a color indicator (think about Epson   printers, for example) so we have to use a length/buffer string   type.  */struct bin_str  {    int len;			/* Number of bytes */    const char *string;		/* Pointer to the same */  };#ifndef STDC_HEADERStime_t time ();#endifchar *getgroup ();char *getuser ();static size_t quote_name (FILE *out, const char *name,			  struct quoting_options const *options,			  size_t *width);static char *make_link_path (const char *path, const char *linkname);static int decode_switches (int argc, char **argv);static int file_interesting (const struct dirent *next);static uintmax_t gobble_file (const char *name, enum filetype type,			      int explicit_arg, const char *dirname);static void print_color_indicator (const char *name, mode_t mode, int linkok);static void put_indicator (const struct bin_str *ind);static int put_indicator_direct (const struct bin_str *ind);static int length_of_file_name_and_frills (const struct fileinfo *f);static void add_ignore_pattern (const char *pattern);static void attach (char *dest, const char *dirname, const char *name);static void clear_files (void);static void extract_dirs_from_files (const char *dirname,				     int ignore_dot_and_dot_dot);static void get_link_name (const char *filename, struct fileinfo *f);static void indent (int from, int to);static void init_column_info (void);static void print_current_files (void);static void print_dir (const char *name, const char *realname);static void print_file_name_and_frills (const struct fileinfo *f);static void print_horizontal (void);static void print_long_format (const struct fileinfo *f);static void print_many_per_line (void);static void print_name_with_quoting (const char *p, mode_t mode,				     int linkok,				     struct obstack *stack);static void prep_non_filename_text (void);static void print_type_indicator (mode_t mode);static void print_with_commas (void);static void queue_directory (const char *name, const char *realname);static void sort_files (void);static void parse_ls_color (void);void usage (int status);/* The name the program was run with, stripped of any leading path. */char *program_name;/* Initial size of hash table.   Most hierarchies are likely to be shallower than this.  */#define INITIAL_TABLE_SIZE 30/* The set of `active' directories, from the current command-line argument   to the level in the hierarchy at which files are being listed.   A directory is represented by its device and inode numbers (struct dev_ino).   A directory is added to this set when ls begins listing it or its   entries, and it is removed from the set just after ls has finished   processing it.  This set is used solely to detect loops, e.g., with   mkdir loop; cd loop; ln -s ../loop sub; ls -RL  */static Hash_table *active_dir_set;#define LOOP_DETECT (!!active_dir_set)/* The table of files in the current directory:   `files' points to a vector of `struct fileinfo', one per file.   `nfiles' is the number of elements space has been allocated for.   `files_index' is the number actually in use.  *//* Address of block containing the files that are described.  */static struct fileinfo *files;  /* FIXME: rename this to e.g. cwd_file *//* Length of block that `files' points to, measured in files.  */static int nfiles;  /* FIXME: rename this to e.g. cwd_n_alloc *//* Index of first unused in `files'.  */static int files_index;  /* FIXME: rename this to e.g. cwd_n_used *//* When nonzero, in a color listing, color each symlink name according to the   type of file it points to.  Otherwise, color them according to the `ln'   directive in LS_COLORS.  Dangling (orphan) symlinks are treated specially,   regardless.  This is set when `ln=target' appears in LS_COLORS.  */static int color_symlink_as_referent;/* mode of appropriate file for colorization */#define FILE_OR_LINK_MODE(File) \    ((color_symlink_as_referent && (File)->linkok) \     ? (File)->linkmode : (File)->stat.st_mode)/* Record of one pending directory waiting to be listed.  */struct pending  {    char *name;    /* If the directory is actually the file pointed to by a symbolic link we       were told to list, `realname' will contain the name of the symbolic       link, otherwise zero. */    char *realname;    struct pending *next;  };static struct pending *pending_dirs;/* Current time in seconds and nanoseconds since 1970, updated as   needed when deciding whether a file is recent.  */static time_t current_time = TYPE_MINIMUM (time_t);static int current_time_ns = -1;/* The number of digits to use for block sizes.   4, or more if needed for bigger numbers.  */static int block_size_size;/* Option flags *//* long_format for lots of info, one per line.   one_per_line for just names, one per line.   many_per_line for just names, many per line, sorted vertically.   horizontal for just names, many per line, sorted horizontally.   with_commas for just names, many per line, separated by commas.   -l (and other options that imply -l), -1, -C, -x and -m control   this parameter.  */enum format  {    long_format,		/* -l and other options that imply -l */    one_per_line,		/* -1 */    many_per_line,		/* -C */    horizontal,			/* -x */    with_commas			/* -m */  };static enum format format;/* `full-iso' uses full ISO-style dates and times.  `long-iso' uses longer   ISO-style time stamps, though shorter than `full-iso'.  `iso' uses shorter   ISO-style time stamps.  `locale' uses locale-dependent time stamps.  */enum time_style  {    full_iso_time_style,	/* --time-style=full-iso */    long_iso_time_style,	/* --time-style=long-iso */    iso_time_style,		/* --time-style=iso */    locale_time_style		/* --time-style=locale */  };static char const *const time_style_args[] ={  "full-iso", "long-iso", "iso", "locale", 0};static enum time_style const time_style_types[] ={  full_iso_time_style, long_iso_time_style, iso_time_style,  locale_time_style, 0};/* Type of time to print or sort by.  Controlled by -c and -u.  */enum time_type  {    time_mtime,			/* default */    time_ctime,			/* -c */    time_atime			/* -u */  };static enum time_type time_type;/* The file characteristic to sort by.  Controlled by -t, -S, -U, -X, -v. */enum sort_type  {    sort_none,			/* -U */    sort_name,			/* default */    sort_extension,		/* -X */    sort_time,			/* -t */    sort_size,			/* -S */    sort_version		/* -v */  };static enum sort_type sort_type;/* Direction of sort.   0 means highest first if numeric,   lowest first if alphabetic;   these are the defaults.   1 means the opposite order in each case.  -r  */static int sort_reverse;/* Nonzero means to display owner information.  -g turns this off.  */static int print_owner = 1;/* Nonzero means to display author information.  */static bool print_author;/* Nonzero means to display group information.  -G and -o turn this off.  */static int print_group = 1;/* Nonzero means print the user and group id's as numbers rather   than as names.  -n  */static int numeric_ids;/* Nonzero means mention the size in blocks of each file.  -s  */static int print_block_size;/* Human-readable options for output.  */static int human_output_opts;/* The units to use when printing sizes other than file sizes.  */static uintmax_t output_block_size;/* Likewise, but for file sizes.  */static uintmax_t file_output_block_size = 1;/* Precede each line of long output (per file) with a string like `m,n:'   where M is the number of characters after the `:' and before the   filename and N is the length of the filename.  Using this format,   Emacs' dired mode starts up twice as fast, and can handle all   strange characters in file names.  */static int dired;/* `none' means don't mention the type of files.   `classify' means mention file types and mark executables.   `file_type' means mention only file types.   Controlled by -F, -p, and --indicator-style.  */enum indicator_style  {    none,	/*     --indicator-style=none */    classify,	/* -F, --indicator-style=classify */    file_type	/* -p, --indicator-style=file-type */  };static enum indicator_style indicator_style;/* Names of indicator styles.  */static char const *const indicator_style_args[] ={  "none", "classify", "file-type", 0};static enum indicator_style const indicator_style_types[]={  none, classify, file_type};/* Nonzero means use colors to mark types.  Also define the different   colors as well as the stuff for the LS_COLORS environment variable.   The LS_COLORS variable is now in a termcap-like format.  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -