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

📄 genfile.c

📁 gnu tar 源码包。 tar 软件是 Unix 系统下的一个打包软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Generate a file containing some preset patterns.   Print statistics for existing files.   Copyright (C) 1995, 1996, 1997, 2001, 2003, 2004, 2005, 2006, 2007,   2008 Free Software Foundation, Inc.   François Pinard <pinard@iro.umontreal.ca>, 1995.   Sergey Poznyakoff <gray@mirddin.farlep.net>, 2004, 2005, 2006, 2007, 2008.   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 3, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/#include <system.h>#include <signal.h>#include <stdarg.h>#include <argmatch.h>#include <argp.h>#include <argcv.h>#include <getdate.h>#include <utimens.h>#include <inttostr.h>#include <fcntl.h>#include <sys/stat.h>#define obstack_chunk_alloc malloc#define obstack_chunk_free free#include <obstack.h>#ifndef EXIT_SUCCESS# define EXIT_SUCCESS 0#endif#ifndef EXIT_FAILURE# define EXIT_FAILURE 1#endif#if ! defined SIGCHLD && defined SIGCLD# define SIGCHLD SIGCLD#endifenum pattern{  DEFAULT_PATTERN,  ZEROS_PATTERN};/* The name this program was run with. */const char *program_name;/* Name of file to generate */static char *file_name;/* Name of the file-list file: */static char *files_from;static char filename_terminator = '\n';/* Length of file to generate.  */static off_t file_length = 0;static off_t seek_offset = 0;/* Pattern to generate.  */static enum pattern pattern = DEFAULT_PATTERN;/* Next checkpoint number */size_t checkpoint;enum genfile_mode  {    mode_generate,    mode_sparse,    mode_stat,    mode_exec  };enum genfile_mode mode = mode_generate;#define DEFAULT_STAT_FORMAT \  "name,dev,ino,mode,nlink,uid,gid,size,blksize,blocks,atime,mtime,ctime"/* Format for --stat option */static char *stat_format = DEFAULT_STAT_FORMAT;/* Size of a block for sparse file */size_t block_size = 512;/* Block buffer for sparse file */char *buffer;/* Number of arguments and argument vector for mode == mode_exec */int exec_argc;char **exec_argv;/* Time for --touch option */struct timespec touch_time;/* Verbose mode */int verbose;const char *argp_program_version = "genfile (" PACKAGE ") " VERSION;const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";static char doc[] = N_("genfile manipulates data files for GNU paxutils test suite.\n""OPTIONS are:\n");#define OPT_CHECKPOINT 256#define OPT_TOUCH      257#define OPT_APPEND     258#define OPT_TRUNCATE   259#define OPT_EXEC       260#define OPT_DATE       261#define OPT_VERBOSE    262#define OPT_SEEK       263static struct argp_option options[] = {#define GRP 0  {NULL, 0, NULL, 0,   N_("File creation options:"), GRP},  {"length", 'l', N_("SIZE"), 0,   N_("Create file of the given SIZE"), GRP+1 },  {"file", 'f', N_("NAME"), 0,   N_("Write to file NAME, instead of standard output"), GRP+1},  {"files-from", 'T', N_("FILE"), 0,   N_("Read file names from FILE"), GRP+1},  {"null", '0', NULL, 0,   N_("-T reads null-terminated names"), GRP+1},  {"pattern", 'p', N_("PATTERN"), 0,   N_("Fill the file with the given PATTERN. PATTERN is 'default' or 'zeros'"),   GRP+1 },  {"block-size", 'b', N_("SIZE"), 0,   N_("Size of a block for sparse file"), GRP+1},  {"sparse", 's', NULL, 0,   N_("Generate sparse file. Rest of the command line gives the file map."),   GRP+1 },  {"seek", OPT_SEEK, N_("OFFSET"), 0,   N_("Seek to the given offset before writing data"),   GRP+1 },#undef GRP#define GRP 10  {NULL, 0, NULL, 0,   N_("File statistics options:"), GRP},  {"stat", 'S', N_("FORMAT"), OPTION_ARG_OPTIONAL,   N_("Print contents of struct stat for each given file. Default FORMAT is: ")   DEFAULT_STAT_FORMAT,   GRP+1 },#undef GRP#define GRP 20  {NULL, 0, NULL, 0,   N_("Synchronous execution options:"), GRP},  {"run", 'r', N_("COMMAND"), 0,   N_("Execute given COMMAND. Useful with --checkpoint and one of --cut, --append, --touch"),   GRP+1 },  {"checkpoint", OPT_CHECKPOINT, N_("NUMBER"), 0,   N_("Perform given action (see below) upon reaching checkpoint NUMBER"),   GRP+1 },  {"date", OPT_DATE, N_("STRING"), 0,   N_("Set date for next --touch option"),   GRP+1 },  {"verbose", OPT_VERBOSE, NULL, 0,   N_("Display executed checkpoints and exit status of COMMAND"),   GRP+1 },#undef GRP#define GRP 30  {NULL, 0, NULL, 0,   N_("Synchronous execution actions. These are executed when checkpoint number given by --checkpoint option is reached."), GRP},  {"cut", OPT_TRUNCATE, N_("FILE"), 0,   N_("Truncate FILE to the size specified by previous --length option (or 0, if it is not given)"),   GRP+1 },  {"truncate", 0, NULL, OPTION_ALIAS, NULL, GRP+1 },  {"append", OPT_APPEND, N_("FILE"), 0,   N_("Append SIZE bytes to FILE. SIZE is given by previous --length option."),   GRP+1 },  {"touch", OPT_TOUCH, N_("FILE"), 0,   N_("Update the access and modification times of FILE"),   GRP+1 },  {"exec", OPT_EXEC, N_("COMMAND"), 0,   N_("Execute COMMAND"),   GRP+1 },#undef GRP  { NULL, }};static char const * const pattern_args[] = { "default", "zeros", 0 };static enum pattern const pattern_types[] = {DEFAULT_PATTERN, ZEROS_PATTERN};static intxlat_suffix (off_t *vp, const char *p){  off_t val = *vp;  if (p[1])    return 1;  switch (p[0])    {    case 'g':    case 'G':      *vp *= 1024;    case 'm':    case 'M':      *vp *= 1024;    case 'k':    case 'K':      *vp *= 1024;      break;    default:      return 1;    }  return *vp <= val;}static off_tget_size (const char *str, int allow_zero){  const char *p;  off_t v = 0;  for (p = str; *p; p++)    {      int digit = *p - '0';      off_t x = v * 10;      if (9 < (unsigned) digit)	{	  if (xlat_suffix (&v, p))	    error (EXIT_FAILURE, 0, _("Invalid size: %s"), str);	  else	    break;	}      else if (x / 10 != v)	error (EXIT_FAILURE, 0, _("Number out of allowed range: %s"), str);      v = x + digit;      if (v < 0)	error (EXIT_FAILURE, 0, _("Negative size: %s"), str);    }  return v;}voidverify_file (char *file_name){  if (file_name)    {      struct stat st;      if (stat (file_name, &st))	error (0, errno, _("stat(%s) failed"), file_name);      if (st.st_size != file_length + seek_offset)	{	  printf ("%lu %lu\n", (unsigned long)st.st_size , (unsigned long)file_length);	  exit (1);	}      if (mode == mode_sparse && !ST_IS_SPARSE (st))	exit (1);    }}struct action{  struct action *next;  size_t checkpoint;  int action;  char *name;  off_t size;  enum pattern pattern;  struct timespec ts;};static struct action *action_list;voidreg_action (int action, char *arg){  struct action *act = xmalloc (sizeof (*act));  act->checkpoint = checkpoint;  act->action = action;  act->pattern = pattern;  act->ts = touch_time;  act->size = file_length;  act->name = arg;  act->next = action_list;  action_list = act;}static error_tparse_opt (int key, char *arg, struct argp_state *state){  switch (key)    {    case '0':      filename_terminator = 0;      break;    case 'f':      file_name = arg;      break;    case 'l':      file_length = get_size (arg, 1);      break;    case 'p':      pattern = XARGMATCH ("--pattern", arg, pattern_args, pattern_types);      break;    case 'b':      block_size = get_size (arg, 0);      break;    case 's':      mode = mode_sparse;      break;    case 'S':      mode = mode_stat;      if (arg)	stat_format = arg;      break;    case 'r':      mode = mode_exec;      argcv_get (arg, "", NULL, &exec_argc, &exec_argv);      break;    case 'T':      files_from = arg;      break;    case OPT_SEEK:      seek_offset = get_size (arg, 0);      break;    case OPT_CHECKPOINT:      {	char *p;	checkpoint = strtoul (arg, &p, 0);	if (*p)	  argp_error (state, _("Error parsing number near `%s'"), p);      }      break;    case OPT_DATE:      if (!get_date (&touch_time, arg, NULL))	argp_error (state, _("Unknown date format"));      break;    case OPT_APPEND:    case OPT_TRUNCATE:    case OPT_TOUCH:    case OPT_EXEC:      reg_action (key, arg);      break;    case OPT_VERBOSE:      verbose++;      break;    default:      return ARGP_ERR_UNKNOWN;    }  return 0;}static struct argp argp = {  options,  parse_opt,  N_("[ARGS...]"),  doc,  NULL,  NULL,  NULL};voidfill (FILE *fp, off_t length, enum pattern pattern){  off_t i;  switch (pattern)    {    case DEFAULT_PATTERN:      for (i = 0; i < length; i++)	fputc (i & 255, fp);      break;    case ZEROS_PATTERN:      for (i = 0; i < length; i++)	fputc (0, fp);      break;    }}/* Generate Mode: usual files */static voidgenerate_simple_file (char *filename){  FILE *fp;  if (filename)    {      fp = fopen (filename, seek_offset ? "rb+" : "wb");      if (!fp)	error (EXIT_FAILURE, errno, _("cannot open `%s'"), filename);    }  else    fp = stdout;  if (fseeko (fp, seek_offset, 0))    error (EXIT_FAILURE, errno, "%s", _("cannot seek"));  fill (fp, file_length, pattern);  fclose (fp);}/* A simplified version of the same function from tar */intread_name_from_file (FILE *fp, struct obstack *stk){  int c;  size_t counter = 0;  for (c = getc (fp); c != EOF && c != filename_terminator; c = getc (fp))    {      if (c == 0)

⌨️ 快捷键说明

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