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

📄 stat.c

📁 linux下一些命令的c语言的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
      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 + -