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

📄 cfls.c

📁 OXCC is a multipass, interpreting C compiler with several language extensions. It generates an Archi
💻 C
📖 第 1 页 / 共 5 页
字号:
/* `dir', `vdir' and `ls' directory listing programs for GNU.
   Copyright (C) 1985, 1988, 1989, 1990 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* If the macro MULTI_COL is defined,
   the multi-column format is the default regardless
   of the type of output device.
   This is for the `dir' program.

   If the macro LONG_FORMAT is defined,
   the long format is the default regardless of the
   type of output device.
   This is for the `vdir' program.

   If neither is defined,
   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. */
/* Modified for PCDOS and 32 Char filenames by Norman D. Culver */
/* Additonal mods for cff */

#include "cfls.h"


/* Return an int indicating the result of comparing two longs. */
#ifdef INT_16_BITS
#define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b) ? 1 : 0)
#else
#define longdiff(a, b) ((a) - (b))
#endif

int glob_match ();

char *copystring ();
char *getgroup ();
char *getuser ();
char *make_link_path ();
char *xmalloc ();
char *xrealloc ();
int argmatch ();
int compare_atime ();
int rev_cmp_atime ();
int compare_ctime ();
int rev_cmp_ctime ();
int compare_mtime ();
int rev_cmp_mtime ();
int compare_size ();
int rev_cmp_size ();
int compare_name ();
int rev_cmp_name ();
int compare_extension ();
int rev_cmp_extension ();
int decode_switches ();
int file_interesting ();
long gobble_file ();
int is_not_dot_or_dotdot ();
int length_of_file_name_and_frills ();
void add_ignore_pattern ();
void add_list_pattern ();
void attach ();
void clear_files ();
void error ();
void extract_dirs_from_files ();
void get_link_name ();
void indent ();
void invalid_arg ();
void print_current_files ();
void print_dir ();
void print_file_name_and_frills ();
void print_horizontal ();
void print_long_format ();
void print_many_per_line ();
void print_name_with_quoting ();
void print_type_indicator ();
void print_with_commas ();
void queue_directory ();
void sort_files ();
void usage ();

enum filetype
{
  symbolic_link,
  directory,
  arg_directory,    /* Directory given as command line arg. */
  normal      /* All others. */
};
typedef struct _lstat {
	unsigned long st_mode;
	unsigned long st_atime;
	unsigned long st_mtime;
	unsigned long st_ctime;
	unsigned long st_ino;
	unsigned long st_size;
	unsigned long st_alloc;
} LSTAT;

struct file
{
  /* The file name. */
  char *name;
  int namlen;
  LSTAT stats;
  char *linkname;
  unsigned long linkmode;
  enum filetype filetype;
};

/* The table of files in the current directory:

   `files' points to a vector of `struct file', 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.  */

struct file *files;

/* Length of block that `files' points to, measured in files.  */

int nfiles;

/* Index of first unused in `files'.  */

int files_index;

/* 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 ignore_pattern *list_patterns;
  struct pending *next;
};

struct pending *pending_dirs;

/* Current time (seconds since 1970).  When we are printing a file's time,
   include the year if it is more than 6 months before this time.  */

long current_time;

/* The number of digits to use for block sizes.
   4, or more if needed for bigger numbers.  */

int block_size_size;

/* The name the program was run with, stripped of any leading path. */
char *program_name;

/* 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, -1, -C, -x and -m control this parameter.  */

enum format
{
  long_format,      /* -l */
  one_per_line,     /* -1 */
  many_per_line,    /* -C */
  horizontal,     /* -x */
  with_commas     /* -m */
};

enum format format;

/* 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 */
};

enum time_type time_type;

/* The file characteristic to sort by.  Controlled by -t, -S, -U, -X. */

enum sort_type
{
  sort_none,      /* -U */
  sort_name,      /* default */
  sort_extension,   /* -X */
  sort_time,      /* -t */
  sort_size     /* -S */
};

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  */

int sort_reverse;

/* Nonzero means print the user and group id's as numbers rather
   than as names.  -n  */

int numeric_users;

/* Nonzero means mention the size in 512 byte blocks of each file.  -s  */

int print_block_size;

/* Nonzero means show file sizes in kilobytes instead of blocks
   (the size of which is system-dependant).  -k */

int kilobyte_blocks;

/* none means don't mention the type of files.
   all means mention the types of all files.
   not_programs means do so except for executables.

   Controlled by -F and -p.  */

enum indicator_style
{
  none,       /* default */
  all,        /* -F */
  not_programs      /* -p */
};

enum indicator_style indicator_style;

/* Nonzero means mention the inode number of each file.  -i  */

int print_inode;

/* Nonzero means when a symbolic link is found, display info on
   the file linked to.  -L  */

int trace_links;

/* Nonzero means when a directory is found, display info on its
   contents.  -R  */

int trace_dirs;

/* Nonzero means when an argument is a directory name, display info
   on it itself.  -d  */

int immediate_dirs;

/* Nonzero means don't omit files whose names start with `.'.  -A */

int all_files;

/* Nonzero means don't omit files `.' and `..'
   This flag implies `all_files'.  -a  */

int really_all_files;

/* A linked list of shell-style globbing patterns.  If a non-argument
   file name matches any of these patterns, it is omitted, or listed.
   List_patterns only occur if the shell fails to glob a pattern on
   the command line, PCDOS is a good example. Ignore_patterns are
   controlled by -I.  Multiple -I options accumulate.
   The -B option adds `*~' and `.*~' to this list.  */

struct ignore_pattern
{
  char *pattern;
  struct ignore_pattern *next;
};

struct ignore_pattern *ignore_patterns;

/* Nonzero means quote nongraphic chars in file names.  -b  */

int quote_funny_chars;

/* Nonzero means output nongraphic chars in file names as `?'.  -q  */

int qmark_funny_chars;

/* Nonzero means output each file name using C syntax for a string.
   Always accompanied by `quote_funny_chars'.
   This mode, together with -x or -C or -m,
   and without such frills as -F or -s,
   is guaranteed to make it possible for a program receiving
   the output to tell exactly what file names are present.  -Q  */

int quote_as_string;

/* The number of chars per hardware tab stop.  -T */
int tabsize;

/* Nonzero means we are listing the working directory because no
   non-option arguments were given. */

int dir_defaulted;

/* Nonzero means print each directory name before listing it. */

int print_dir_name;

/* The line length to use for breaking lines in many-per-line format.
   Can be set with -w.  */

int line_length;

/* If nonzero, the file listing format requires that stat be called on
   each file. */

int format_needs_stat;

struct option long_options[] =
{
  {"all", 0, NULL, 'a'},
  {"escape", 0, NULL, 'b'},
  {"directory", 0, NULL, 'd'},
  {"inode", 0, NULL, 'i'},
  {"kilobytes", 0, NULL, 'k'},
  {"numeric-uid-gid", 0, NULL, 'n'},
  {"hide-control-chars", 0, NULL, 'q'},
  {"reverse", 0, NULL, 'r'},
  {"size", 0, NULL, 's'},
  {"width", 1, NULL, 'w'},
  {"almost-all", 0, NULL, 'A'},
  {"ignore-backups", 0, NULL, 'B'},
  {"classify", 0, NULL, 'F'},
  {"file-type", 0, NULL, 'F'},
  {"ignore", 1, NULL, 'I'},
  {"dereference", 0, NULL, 'L'},
  {"literal", 0, NULL, 'N'},
  {"quote-name", 0, NULL, 'Q'},
  {"recursive", 0, NULL, 'R'},
  {"format", 1, NULL, 12},
  {"sort", 1, NULL, 10},
  {"tabsize", 1, NULL, 'T'},
  {"time", 1, NULL, 11},
  {NULL, 0, NULL, 0}
};

char *format_args[] =
{
  "verbose", "long", "commas", "horizontal", "across",
  "vertical", "single-column", NULL
};

enum format formats[] =
{
  long_format, long_format, with_commas, horizontal, horizontal,
  many_per_line, one_per_line
};

char *sort_args[] =
{
  "none", "time", "size", "extension", 0
};

enum sort_type sort_types[] =
{
  sort_none, sort_time, sort_size, sort_extension
};

char *time_args[] =
{
  "atime", "access", "use", "ctime", "status", 0
};

enum time_type time_types[] =
{
  time_atime, time_atime, time_atime, time_ctime, time_ctime
};
static int
is_printable(const char *cp, int len)
{
register int i;
	for(i = 0; i < len; ++i) {
		if(!isgraph(cp[i])) {
			if(cp[i] == '\0')
				break;
			return 0;
		}
	}
	return (i > 0) ? 1 : 0;
}
/* Set all the option flags according to the switches specified.
   Return the index of the first non-option argument.  */

int
decode_switches (argc, argv)
int argc;
char **argv;

{
  register char *p;
  int c;
  int longind;

  qmark_funny_chars = 0;
  quote_funny_chars = 0;

  /* initialize all switches to default settings */

#ifdef MULTI_COL
#define PROGNAME "dir"
  /* This is for the `dir' program.  */
  format = many_per_line;
  quote_funny_chars = 1;
#else
#ifdef LONG_FORMAT
#define PROGNAME "vdir"
  /* This is for the `vdir' program.  */
  format = long_format;
  quote_funny_chars = 1;
#else
#define PROGNAME "cfls"
  /* This is for the `ls' program.  */
  if (isatty (1))
  {
    format = many_per_line;
    qmark_funny_chars = 1;
  }
  else
  {
    format = one_per_line;
    qmark_funny_chars = 0;
  }
#endif
#endif

  time_type = time_mtime;
  sort_type = sort_name;
  sort_reverse = 0;
  numeric_users = 0;
  print_block_size = 0;
  kilobyte_blocks = 0;
  indicator_style = none;
  print_inode = 0;
  trace_links = 0;
  trace_dirs = 0;
  immediate_dirs = 0;
  all_files = 0;
  really_all_files = 0;
  ignore_patterns = 0;
  quote_as_string = 0;

  p = getenv ("COLUMNS");
  line_length = p ? atoi (p) : 80;

#ifdef TIOCGWINSZ
  {
    struct winsize ws;

    if (ioctl (1, TIOCGWINSZ, &ws) != -1 && ws.ws_col != 0)
      line_length = ws.ws_col;
  }
#endif

  p = getenv ("TABSIZE");
  tabsize = p ? atoi (p) : 8;

  while ((c = getopt_long (argc, argv, "abcdgiklmnpqrstuw:xABCFI:LNQRST:UX1",
         long_options, &longind)) != EOF)
  {
    switch (c)
    {
      case 'a':
        all_files = 1;
        really_all_files = 1;
        break;

      case 'b':
        quote_funny_chars = 1;
        qmark_funny_chars = 0;
        break;

      case 'c':
        time_type = time_ctime;
        break;

      case 'd':
        immediate_dirs = 1;
        break;

      case 'g':
    /* No effect.  For BSD compatibility. */
        break;

      case 'i':
        print_inode = 1;
        break;

      case 'k':
        kilobyte_blocks = 1;
        break;

      case 'l':
        format = long_format;
        break;

      case 'm':
        format = with_commas;
        break;

      case 'n':

⌨️ 快捷键说明

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