📄 stat.c
字号:
printf (pformat, (long int) (statfsbuf->f_bsize));
break;
case 'c':
strcat (pformat, PRIdMAX);
printf (pformat, (intmax_t) (statfsbuf->f_files));
break;
case 'd':
strcat (pformat, PRIdMAX);
printf (pformat, (intmax_t) (statfsbuf->f_ffree));
break;
default:
strcat (pformat, "c");
printf (pformat, m);
break;
}
}
/* print stat info */
static void
print_stat (char *pformat, char m, char const *filename, void const *data)
{
struct stat *statbuf = (struct stat *) data;
struct passwd *pw_ent;
struct group *gw_ent;
switch (m)
{
case 'n':
strcat (pformat, "s");
printf (pformat, filename);
break;
case 'N':
strcat (pformat, "s");
if ((statbuf->st_mode & S_IFMT) == S_IFLNK)
{
char *linkname = xreadlink (filename);
if (linkname == NULL)
{
error (0, errno, _("cannot read symbolic link %s"),
quote (filename));
return;
}
/*printf("\"%s\" -> \"%s\"", filename, linkname); */
printf (pformat, quote (filename));
printf (" -> ");
printf (pformat, quote (linkname));
}
else
{
printf (pformat, quote (filename));
}
break;
case 'd':
strcat (pformat, "d");
printf (pformat, (int) statbuf->st_dev);
break;
case 'D':
strcat (pformat, "x");
printf (pformat, (int) statbuf->st_dev);
break;
case 'i':
strcat (pformat, "d");
printf (pformat, (int) statbuf->st_ino);
break;
case 'a':
strcat (pformat, "o");
printf (pformat, statbuf->st_mode & 07777);
break;
case 'A':
print_human_access (statbuf);
break;
case 'f':
strcat (pformat, "x");
printf (pformat, statbuf->st_mode);
break;
case 'F':
print_human_type (statbuf->st_mode);
break;
case 'h':
strcat (pformat, "d");
printf (pformat, (int) statbuf->st_nlink);
break;
case 'u':
strcat (pformat, "d");
printf (pformat, statbuf->st_uid);
break;
case 'U':
strcat (pformat, "s");
setpwent ();
pw_ent = getpwuid (statbuf->st_uid);
printf (pformat, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN");
break;
case 'g':
strcat (pformat, "d");
printf (pformat, statbuf->st_gid);
break;
case 'G':
strcat (pformat, "s");
setgrent ();
gw_ent = getgrgid (statbuf->st_gid);
printf (pformat, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
break;
case 't':
strcat (pformat, "x");
printf (pformat, major (statbuf->st_rdev));
break;
case 'T':
strcat (pformat, "x");
printf (pformat, minor (statbuf->st_rdev));
break;
case 's':
strcat (pformat, PRIuMAX);
printf (pformat, (uintmax_t) (statbuf->st_size));
break;
case 'b':
strcat (pformat, "u");
printf (pformat, (unsigned int) statbuf->st_blocks);
break;
case 'o':
strcat (pformat, "d");
printf (pformat, (int) statbuf->st_blksize);
break;
case 'x':
print_human_time (&(statbuf->st_atime));
break;
case 'X':
strcat (pformat, "d");
printf (pformat, (int) statbuf->st_atime);
break;
case 'y':
print_human_time (&(statbuf->st_mtime));
break;
case 'Y':
strcat (pformat, "d");
printf (pformat, (int) statbuf->st_mtime);
break;
case 'z':
print_human_time (&(statbuf->st_ctime));
break;
case 'Z':
strcat (pformat, "d");
printf (pformat, (int) statbuf->st_ctime);
break;
default:
strcat (pformat, "c");
printf (pformat, m);
break;
}
}
static void
print_it (char const *masterformat, char const *filename,
void (*print_func) (char *, char, char const *, void const *),
void const *data)
{
char *b;
/* create a working copy of the format string */
char *format = xstrdup (masterformat);
char *dest = xmalloc (strlen (format) + 1);
b = format;
while (b)
{
char *p = strchr (b, '%');
if (p != NULL)
{
size_t len;
*p++ = '\0';
fputs (b, stdout);
len = strspn (p, "#-+.I 0123456789");
dest[0] = '%';
memcpy (dest + 1, p, len);
dest[1 + len] = 0;
p += len;
switch (*p)
{
case '\0':
case '%':
fputs ("%", stdout);
break;
default:
print_func (dest, *p, filename, data);
break;
}
b = p + 1;
}
else
{
fputs (b, stdout);
b = NULL;
}
}
free (format);
free (dest);
fputc ('\n', stdout);
}
/* stat the filesystem and print what we find */
static void
do_statfs (char const *filename, int terse, char const *format)
{
STRUCT_STATVFS statfsbuf;
int i = statfs (filename, &statfsbuf);
if (i == -1)
{
error (0, errno, _("cannot read file system information for %s"),
quote (filename));
return;
}
if (format == NULL)
{
format = (terse
? "%n %i %l %t %b %f %a %s %c %d"
: " File: \"%n\"\n"
" ID: %-8i Namelen: %-7l Type: %T\n"
"Blocks: Total: %-10b Free: %-10f Available: %-10a Size: %s\n"
"Inodes: Total: %-10c Free: %-10d");
}
print_it (format, filename, print_statfs, &statfsbuf);
}
/* stat the file and print what we find */
static void
do_stat (char const *filename, int follow_links, int terse,
char const *format)
{
struct stat statbuf;
int i = ((follow_links == 1)
? stat (filename, &statbuf)
: lstat (filename, &statbuf));
if (i == -1)
{
error (0, errno, _("cannot stat %s"), quote (filename));
return;
}
if (format == NULL)
{
if (terse != 0)
{
format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o";
}
else
{
/* tmp hack to match orignal output until conditional implemented */
i = statbuf.st_mode & S_IFMT;
if (i == S_IFCHR || i == S_IFBLK)
{
format =
" File: %N\n"
" Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
"Device: %Dh/%dd\tInode: %-10i Links: %-5h"
" Device type: %t,%T\n"
"Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
"Access: %x\n" "Modify: %y\n" "Change: %z\n";
}
else
{
format =
" File: %N\n"
" Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
"Device: %Dh/%dd\tInode: %-10i Links: %-5h\n"
"Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
"Access: %x\n" "Modify: %y\n" "Change: %z\n";
}
}
}
print_it (format, filename, print_stat, &statbuf);
}
void
usage (int status)
{
if (status != 0)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
else
{
printf (_("Usage: %s [OPTION] FILE...\n"), program_name);
fputs (_("\
Display file or filesystem status.\n\
\n\
-f, --filesystem display filesystem status instead of file status\n\
-c --format=FORMAT use the specified FORMAT instead of the default\n\
-L, --dereference follow links\n\
-t, --terse print the information in terse form\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\n\
The valid format sequences for files (without --filesystem):\n\
\n\
%A - Access rights in human readable form\n\
%a - Access rights in octal\n\
%b - Number of blocks allocated\n\
"), stdout);
fputs (_("\
%D - Device number in hex\n\
%d - Device number in decimal\n\
%F - File type\n\
%f - raw mode in hex\n\
%G - Group name of owner\n\
%g - Group ID of owner\n\
"), stdout);
fputs (_("\
%h - Number of hard links\n\
%i - Inode number\n\
%N - Quoted File name with dereference if symbolic link\n\
%n - File name\n\
%o - IO block size\n\
%s - Total size, in bytes\n\
%T - Minor device type in hex\n\
%t - Major device type in hex\n\
"), stdout);
fputs (_("\
%U - User name of owner\n\
%u - User ID of owner\n\
%X - Time of last access as seconds since Epoch\n\
%x - Time of last access\n\
%Y - Time of last modification as seconds since Epoch\n\
%y - Time of last modification\n\
%Z - Time of last change as seconds since Epoch\n\
%z - Time of last change\n\
\n\
"), stdout);
fputs (_("\
Valid format sequences for file systems:\n\
\n\
%a - Free blocks available to non-superuser\n\
%b - Total data blocks in file system\n\
%c - Total file nodes in file system\n\
%d - Free file nodes in file system\n\
%f - Free blocks in file system\n\
"), stdout);
fputs (_("\
%i - File System id in hex\n\
%l - Maximum length of filenames\n\
%n - File name\n\
%s - Optimal transfer block size\n\
%T - Type in human readable form\n\
%t - Type in hex\n\
"), stdout);
printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
}
exit (status);
}
int
main (int argc, char *argv[])
{
int c;
int i;
int follow_links = 0;
int fs = 0;
int terse = 0;
char *format = NULL;
program_name = argv[0];
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
atexit (close_stdout);
while ((c = getopt_long (argc, argv, "c:fLlt", long_options, NULL)) != -1)
{
switch (c)
{
case 'c':
format = optarg;
break;
case 'l': /* deprecated */
case 'L':
follow_links = 1;
break;
case 'f':
fs = 1;
break;
case 't':
terse = 1;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
if (argc == optind)
{
error (0, 0, _("too few arguments"));
usage (EXIT_FAILURE);
}
for (i = optind; i < argc; i++)
{
if (fs == 0)
do_stat (argv[i], follow_links, terse, format);
else
do_statfs (argv[i], terse, format);
}
exit (EXIT_SUCCESS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -