📄 ls.c
字号:
free (thispend->realname);
free (thispend);
print_dir_name = 1;
}
exit (0);
}
struct option long_options[] =
{
#ifdef MSDOS
{"copying", 0, NULL, 30},
{"version", 0, NULL, 31},
#endif
{"all", 0, 0, 'a'},
{"escape", 0, 0, 'b'},
{"directory", 0, 0, 'd'},
{"inode", 0, 0, 'i'},
{"kilobytes", 0, 0, 'k'},
{"numeric-uid-gid", 0, 0, 'n'},
{"hide-control-chars", 0, 0, 'q'},
{"reverse", 0, 0, 'r'},
{"size", 0, 0, 's'},
{"width", 1, 0, 'w'},
{"almost-all", 0, 0, 'A'},
{"ignore-backups", 0, 0, 'B'},
{"classify", 0, 0, 'F'},
{"file-type", 0, 0, 'F'},
{"ignore", 1, 0, 'I'},
{"dereference", 0, 0, 'L'},
{"literal", 0, 0, 'N'},
{"quote-name", 0, 0, 'Q'},
{"recursive", 0, 0, 'R'},
{"format", 1, 0, 12},
{"sort", 1, 0, 10},
{"tabsize", 1, 0, 'T'},
{"time", 1, 0, 11},
{0, 0, 0, 0}
};
char *format_args[] =
{
"verbose", "long", "commas", "horizontal", "across",
"vertical", "single-column", 0
};
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
};
/* 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 "ls"
/* 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':
numeric_users = 1;
break;
case 'p':
indicator_style = not_programs;
break;
case 'q':
qmark_funny_chars = 1;
quote_funny_chars = 0;
break;
case 'r':
sort_reverse = 1;
break;
case 's':
print_block_size = 1;
break;
case 't':
sort_type = sort_time;
break;
case 'u':
time_type = time_atime;
break;
case 'w':
line_length = atoi (optarg);
if (line_length < 1)
error (1, 0, "invalid line width: %s", optarg);
break;
case 'x':
format = horizontal;
break;
case 'A':
all_files = 1;
break;
case 'B':
add_ignore_pattern ("*~");
add_ignore_pattern (".*~");
break;
case 'C':
format = many_per_line;
break;
case 'F':
indicator_style = all;
break;
case 'I':
add_ignore_pattern (optarg);
break;
case 'L':
trace_links = 1;
break;
case 'N':
quote_funny_chars = 0;
qmark_funny_chars = 0;
break;
case 'Q':
quote_as_string = 1;
quote_funny_chars = 1;
qmark_funny_chars = 0;
break;
case 'R':
trace_dirs = 1;
break;
case 'S':
sort_type = sort_size;
break;
case 'T':
tabsize = atoi (optarg);
if (tabsize < 1)
error (1, 0, "invalid tab size: %s", optarg);
break;
case 'U':
sort_type = sort_none;
break;
case 'X':
sort_type = sort_extension;
break;
case '1':
format = one_per_line;
break;
case 10: /* +sort */
longind = argmatch (optarg, sort_args);
if (longind < 0)
{
invalid_arg ("sort type", optarg, longind);
usage ();
}
sort_type = sort_types[longind];
break;
case 11: /* +time */
longind = argmatch (optarg, time_args);
if (longind < 0)
{
invalid_arg ("time type", optarg, longind);
usage ();
}
time_type = time_types[longind];
break;
case 12: /* +format */
longind = argmatch (optarg, format_args);
if (longind < 0)
{
invalid_arg ("format type", optarg, longind);
usage ();
}
format = formats[longind];
break;
#ifdef MSDOS
case 30:
fprintf (stderr, COPYING);
exit (0);
break;
case 31:
fprintf (stderr, VERSION);
exit (0);
break;
#endif
default:
usage ();
}
}
return optind;
}
/* Request that the directory named `name' have its contents listed later.
If `realname' is nonzero, it will be used instead of `name' when the
directory name is printed. This allows symbolic links to directories
to be treated as regular directories but still be listed under their
real names. */
void
queue_directory (name, realname)
char *name;
char *realname;
{
struct pending *new;
new = (struct pending *) xmalloc (sizeof (struct pending));
new->next = pending_dirs;
pending_dirs = new;
new->name = copystring (name);
if (realname)
new->realname = copystring (realname);
else
new->realname = 0;
}
/* Read directory `name', and list the files in it.
If `realname' is nonzero, print its name instead of `name';
this is used for symbolic links to directories. */
void
print_dir (name, realname)
char *name;
char *realname;
{
register DIR *reading;
register struct direct *next;
register int total_blocks = 0;
errno = 0;
reading = opendir (name);
if (!reading)
{
error (0, errno, "%s", name);
return;
}
/* Read the directory entries, and insert the subfiles into the `files'
table. */
clear_files ();
while (next = readdir (reading))
if (file_interesting (next))
total_blocks += gobble_file (next->d_name, 0, name);
closedir (reading);
/* Sort the directory contents. */
sort_files ();
/* If any member files are subdirectories, perhaps they should have their
contents listed rather than being mentioned here as files. */
if (trace_dirs)
extract_dirs_from_files (name, 1);
if (print_dir_name)
{
if (realname)
printf ("%s:\n", realname);
else
printf ("%s:\n", name);
}
if (format == long_format || print_block_size)
printf ("total %u\n", total_blocks);
if (files_index)
print_current_files ();
if (pending_dirs)
putchar ('\n');
}
/* Add `pattern' to the list of patterns for which files that match are
not listed. */
void
add_ignore_pattern (pattern)
char *pattern;
{
register struct ignore_pattern *ignore;
ignore = (struct ignore_pattern *) xmalloc (sizeof (struct ignore_pattern));
ignore->pattern = pattern;
/* Add it to the head of the linked list. */
ignore->next = ignore_patterns;
ignore_patterns = ignore;
}
/* Return nonzero if the file in `next' should be listed. */
int
file_interesting (next)
register struct direct *next;
{
register struct ignore_pattern *ignore;
for (ignore = ignore_patterns; ignore; ignore = ignore->next)
if (glob_match (ignore->pattern, next->d_name, 1))
return 0;
if (really_all_files
|| next->d_name[0] != '.'
|| (all_files
&& next->d_name[1] != '\0'
&& (next->d_name[1] != '.' || next->d_name[2] != '\0')))
return 1;
return 0;
}
/* Enter and remove entries in the table `files'. */
/* Empty the table of files. */
void
clear_files ()
{
register int i;
for (i = 0; i < files_index; i++)
{
free (files[i].name);
if (files[i].linkname)
free (files[i].linkname);
}
files_index = 0;
block_size_size = 4;
}
/* Add a file to the current table of files.
Verify that the file exists, and print an error message if it does not.
Return the number of blocks that the file occupies. */
int
gobble_file (name, explicit_arg, dirname)
char *name;
int explicit_arg;
char *dirname;
{
register int blocks;
register int val;
register char *path;
if (files_index == nfiles)
{
nfiles *= 2;
files = (struct file *) xrealloc (files, sizeof (struct file) * nfiles);
}
files[files_index].linkname = 0;
files[files_index].linkmode = 0;
if (explicit_arg || format_needs_stat)
{
/* `path' is the absolute pathname of this file. */
if (name[0] == '/' || dirname[0] == 0)
path = name;
else
{
path = (char *) alloca (strlen (name) + strlen (dirname) + 2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -