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

📄 stat.c

📁 《linux应用开发技术详解》的配套代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* stat.c -- display file or filesystem status
   Copyright (C) 2001, 2002 Free Software Foundation.

   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.

   Written by Michael Meskes.  */

#include <config.h>

#include <stdio.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SYSMACROS_H
# include <sys/sysmacros.h>
#endif
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
#include <time.h>
#if HAVE_SYS_STATVFS_H
# include <sys/statvfs.h>
#endif
#if HAVE_SYS_VFS_H
# include <sys/vfs.h>
#endif

/* NetBSD 1.5.2 needs these, for the declaration of struct statfs. */
#if !HAVE_SYS_STATVFS_H && !HAVE_SYS_VFS_H
# if HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H
#  include <sys/param.h>
#  include <sys/mount.h>
# endif
#endif

#include <string.h>
#include <ctype.h>

#include "system.h"

#include "closeout.h"
#include "error.h"
#include "filemode.h"
#include "fs.h"
#include "getopt.h"
#include "quote.h"
#include "quotearg.h"
#include "xreadlink.h"

#define NAMEMAX_FORMAT PRIuMAX

#if HAVE_STRUCT_STATVFS_F_BASETYPE
# define STRUCT_STATVFS struct statvfs
# define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATVFS
# if HAVE_STRUCT_STATVFS_F_NAMEMAX
#  define SB_F_NAMEMAX(S) ((uintmax_t) ((S)->f_namemax))
# endif
#else
# define STRUCT_STATVFS struct statfs
# define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATFS
# if HAVE_STRUCT_STATFS_F_NAMELEN
#  define SB_F_NAMEMAX(S) ((uintmax_t) ((S)->f_namelen))
# endif
#endif

#ifndef SB_F_NAMEMAX
/* NetBSD 1.5.2 has neither f_namemax nor f_namelen.  */
# define SB_F_NAMEMAX(S) "*"
# undef NAMEMAX_FORMAT
# define NAMEMAX_FORMAT "s"
#endif

size_t nstrftime PARAMS ((char *, size_t, char const *,
			  struct tm const *, int, int));

#define PROGRAM_NAME "stat"

#define AUTHORS "Michael Meskes"

static struct option const long_options[] = {
  {"link", no_argument, 0, 'l'}, /* deprecated.  FIXME: remove in 2003 */
  {"dereference", no_argument, 0, 'L'},
  {"format", required_argument, 0, 'c'},
  {"filesystem", no_argument, 0, 'f'},
  {"terse", no_argument, 0, 't'},
  {GETOPT_HELP_OPTION_DECL},
  {GETOPT_VERSION_OPTION_DECL},
  {NULL, 0, NULL, 0}
};

char *program_name;

static void
print_human_type (mode_t mode)
{
  char const *type;
  switch (mode & S_IFMT)
    {
    case S_IFDIR:
      type = "Directory";
      break;
    case S_IFCHR:
      type = "Character Device";
      break;
    case S_IFBLK:
      type = "Block Device";
      break;
    case S_IFREG:
      type = "Regular File";
      break;
    case S_IFLNK:
      type = "Symbolic Link";
      break;
    case S_IFSOCK:
      type = "Socket";
      break;
    case S_IFIFO:
      type = "Fifo File";
      break;
    default:
      type = "Unknown";
    }
  fputs (type, stdout);
}

/* Return the type of the specified file system.
   Some systems have statfvs.f_basetype[FSTYPSZ]. (AIX, HP-UX, and Solaris)
   Others have statfs.f_fstypename[MFSNAMELEN]. (NetBSD 1.5.2)
   Still others have neither and have to get by with f_type (Linux).  */
static char *
human_fstype (STRUCT_STATVFS const *statfsbuf)
{
#if HAVE_STRUCT_STATVFS_F_BASETYPE
  return statfsbuf->f_basetype;
#else
# if HAVE_STRUCT_STATFS_F_FSTYPENAME
  return statfsbuf->f_fstypename;
# else
  char const *type;

  switch (statfsbuf->f_type)
    {
#  if defined __linux__
    case S_MAGIC_AFFS:
      type = "affs";
      break;
    case S_MAGIC_EXT:
      type = "ext";
      break;
    case S_MAGIC_EXT2_OLD:
      type = "ext2";
      break;
    case S_MAGIC_EXT2:
      type = "ext2/ext3";
      break;
    case S_MAGIC_HPFS:
      type = "hpfs";
      break;
    case S_MAGIC_ISOFS:
      type = "isofs";
      break;
    case S_MAGIC_ISOFS_WIN:
      type = "isofs";
      break;
    case S_MAGIC_ISOFS_R_WIN:
      type = "isofs";
      break;
    case S_MAGIC_MINIX:
      type = "minix";
      break;
    case S_MAGIC_MINIX_30:
      type = "minix (30 char.)";
      break;
    case S_MAGIC_MINIX_V2:
      type = "minix v2";
      break;
    case S_MAGIC_MINIX_V2_30:
      type = "minix v2 (30 char.)";
      break;
    case S_MAGIC_MSDOS:
      type = "msdos";
      break;
    case S_MAGIC_FAT:
      type = "fat";
      break;
    case S_MAGIC_NCP:
      type = "novell";
      break;
    case S_MAGIC_NFS:
      type = "nfs";
      break;
    case S_MAGIC_PROC:
      type = "proc";
      break;
    case S_MAGIC_SMB:
      type = "smb";
      break;
    case S_MAGIC_XENIX:
      type = "xenix";
      break;
    case S_MAGIC_SYSV4:
      type = "sysv4";
      break;
    case S_MAGIC_SYSV2:
      type = "sysv2";
      break;
    case S_MAGIC_COH:
      type = "coh";
      break;
    case S_MAGIC_UFS:
      type = "ufs";
      break;
    case S_MAGIC_XIAFS:
      type = "xia";
      break;
    case S_MAGIC_NTFS:
      type = "ntfs";
      break;
    case S_MAGIC_TMPFS:
      type = "tmpfs";
      break;
    case S_MAGIC_REISERFS:
      type = "reiserfs";
      break;
    case S_MAGIC_CRAMFS:
      type = "cramfs";
      break;
    case S_MAGIC_ROMFS:
      type = "romfs";
      break;
#  elif __GNU__
    case FSTYPE_UFS:
      type = "ufs";
      break;
    case FSTYPE_NFS:
      type = "nfs";
      break;
    case FSTYPE_GFS:
      type = "gfs";
      break;
    case FSTYPE_LFS:
      type = "lfs";
      break;
    case FSTYPE_SYSV:
      type = "sysv";
      break;
    case FSTYPE_FTP:
      type = "ftp";
      break;
    case FSTYPE_TAR:
      type = "tar";
      break;
    case FSTYPE_AR:
      type = "ar";
      break;
    case FSTYPE_CPIO:
      type = "cpio";
      break;
    case FSTYPE_MSLOSS:
      type = "msloss";
      break;
    case FSTYPE_CPM:
      type = "cpm";
      break;
    case FSTYPE_HFS:
      type = "hfs";
      break;
    case FSTYPE_DTFS:
      type = "dtfs";
      break;
    case FSTYPE_GRFS:
      type = "grfs";
      break;
    case FSTYPE_TERM:
      type = "term";
      break;
    case FSTYPE_DEV:
      type = "dev";
      break;
    case FSTYPE_PROC:
      type = "proc";
      break;
    case FSTYPE_IFSOCK:
      type = "ifsock";
      break;
    case FSTYPE_AFS:
      type = "afs";
      break;
    case FSTYPE_DFS:
      type = "dfs";
      break;
    case FSTYPE_PROC9:
      type = "proc9";
      break;
    case FSTYPE_SOCKET:
      type = "socket";
      break;
    case FSTYPE_MISC:
      type = "misc";
      break;
    case FSTYPE_EXT2FS:
      type = "ext2/ext3";
      break;
    case FSTYPE_HTTP:
      type = "http";
      break;
    case FSTYPE_MEMFS:
      type = "memfs";
      break;
    case FSTYPE_ISO9660:
      type = "iso9660";
      break;
#  endif
    default:
      type = NULL;
      break;
    }

  if (type)
    return (char *) type;

  {
    static char buf[sizeof "UNKNOWN (0x%x)" - 2
		    + 2 * sizeof (statfsbuf->f_type)];
    sprintf (buf, "UNKNOWN (0x%x)", statfsbuf->f_type);
    return buf;
  }
# endif
#endif
}

static void
print_human_access (struct stat const *statbuf)
{
  char modebuf[11];
  mode_string (statbuf->st_mode, modebuf);
  modebuf[10] = 0;
  fputs (modebuf, stdout);
}

static void
print_human_time (time_t const *t)
{
  char str[80];

#if 0  /* %c is too locale-dependent.  */
  if (strftime (str, 40, "%c", localtime (t)) > 0)
#else
  if (nstrftime (str, sizeof str, "%Y-%m-%d %H:%M:%S.%N %z",
		 localtime (t), 0, 0) > 0)
#endif
    fputs (str, stdout);
  else
    printf ("Cannot calculate human readable time, sorry");
}

/* print statfs info */
static void
print_statfs (char *pformat, char m, char const *filename,
	      void const *data)
{
  STRUCT_STATVFS const *statfsbuf = data;

  switch (m)
    {
    case 'n':
      strcat (pformat, "s");
      printf (pformat, filename);
      break;

    case 'i':
#if HAVE_STRUCT_STATXFS_F_FSID___VAL
      strcat (pformat, "x %-8x");
      printf (pformat, statfsbuf->f_fsid.__val[0], /* u_long */
	      statfsbuf->f_fsid.__val[1]);
#else
      strcat (pformat, "Lx");
      printf (pformat, statfsbuf->f_fsid);
#endif
      break;

    case 'l':
      strcat (pformat, NAMEMAX_FORMAT);
      printf (pformat, SB_F_NAMEMAX (statfsbuf));
      break;
    case 't':
#if HAVE_STRUCT_STATXFS_F_TYPE
      strcat (pformat, "lx");
      printf (pformat, (long int) (statfsbuf->f_type));  /* no equiv. */
#else
      fputc ('*', stdout);
#endif
      break;
    case 'T':
      strcat (pformat, "s");
      printf (pformat, human_fstype (statfsbuf));
      break;
    case 'b':
      strcat (pformat, PRIdMAX);
      printf (pformat, (intmax_t) (statfsbuf->f_blocks));
      break;
    case 'f':
      strcat (pformat, PRIdMAX);
      printf (pformat, (intmax_t) (statfsbuf->f_bfree));
      break;
    case 'a':
      strcat (pformat, PRIdMAX);
      printf (pformat, (intmax_t) (statfsbuf->f_bavail));
      break;
    case 's':
      strcat (pformat, "ld");

⌨️ 快捷键说明

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