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

📄 list.c

📁 gnu tar 源码包。 tar 软件是 Unix 系统下的一个打包软件
💻 C
📖 第 1 页 / 共 3 页
字号:
	      recent_long_link_blocks = next_long_link_blocks;	    }	  else	    {	      memcpy (namebuf, h->linkname, sizeof h->linkname);	      namebuf[sizeof h->linkname] = '\0';	      name = namebuf;	      recent_long_link = 0;	      recent_long_link_blocks = 0;	    }	  assign_string (&info->link_name, name);	  return HEADER_SUCCESS;	}    }}enum read_headerread_header (bool raw_extended_headers){  return read_header_primitive (raw_extended_headers, &current_stat_info);}static char *decode_xform (char *file_name, void *data){  xform_type type = *(xform_type*)data;  switch (type)    {    case xform_symlink:      /* FIXME: It is not quite clear how and to which extent are the symbolic	 links subject to filename transformation.  In the absence of another	 solution, symbolic links are exempt from component stripping and	 name suffix normalization, but subject to filename transformation	 proper. */       return file_name;          case xform_link:      file_name = safer_name_suffix (file_name, true, absolute_names_option);      break;          case xform_regfile:      file_name = safer_name_suffix (file_name, false, absolute_names_option);      break;    }    if (strip_name_components)    {      size_t prefix_len = stripped_prefix_len (file_name,					       strip_name_components);      if (prefix_len == (size_t) -1)	prefix_len = strlen (file_name);      file_name += prefix_len;    }  return file_name;}booltransform_member_name (char **pinput, xform_type type){  return transform_name_fp (pinput, decode_xform, &type);}#define ISOCTAL(c) ((c)>='0'&&(c)<='7')/* Decode things from a file HEADER block into STAT_INFO, also setting   *FORMAT_POINTER depending on the header block format.  If   DO_USER_GROUP, decode the user/group information (this is useful   for extraction, but waste time when merely listing).   read_header() has already decoded the checksum and length, so we don't.   This routine should *not* be called twice for the same block, since   the two calls might use different DO_USER_GROUP values and thus   might end up with different uid/gid for the two calls.  If anybody   wants the uid/gid they should decode it first, and other callers   should decode it without uid/gid before calling a routine,   e.g. print_header, that assumes decoded data.  */voiddecode_header (union block *header, struct tar_stat_info *stat_info,	       enum archive_format *format_pointer, int do_user_group){  enum archive_format format;  if (strcmp (header->header.magic, TMAGIC) == 0)    {      if (header->star_header.prefix[130] == 0	  && ISOCTAL (header->star_header.atime[0])	  && header->star_header.atime[11] == ' '	  && ISOCTAL (header->star_header.ctime[0])	  && header->star_header.ctime[11] == ' ')	format = STAR_FORMAT;      else if (stat_info->xhdr.size)	format = POSIX_FORMAT;      else	format = USTAR_FORMAT;    }  else if (strcmp (header->header.magic, OLDGNU_MAGIC) == 0)    format = OLDGNU_FORMAT;  else    format = V7_FORMAT;  *format_pointer = format;  stat_info->stat.st_mode = MODE_FROM_HEADER (header->header.mode);  stat_info->mtime.tv_sec = TIME_FROM_HEADER (header->header.mtime);  stat_info->mtime.tv_nsec = 0;  assign_string (&stat_info->uname,		 header->header.uname[0] ? header->header.uname : NULL);  assign_string (&stat_info->gname,		 header->header.gname[0] ? header->header.gname : NULL);  if (format == OLDGNU_FORMAT && incremental_option)    {      stat_info->atime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.atime);      stat_info->ctime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.ctime);      stat_info->atime.tv_nsec = stat_info->ctime.tv_nsec = 0;    }  else if (format == STAR_FORMAT)    {      stat_info->atime.tv_sec = TIME_FROM_HEADER (header->star_header.atime);      stat_info->ctime.tv_sec = TIME_FROM_HEADER (header->star_header.ctime);      stat_info->atime.tv_nsec = stat_info->ctime.tv_nsec = 0;    }  else    stat_info->atime = stat_info->ctime = start_time;  if (format == V7_FORMAT)    {      stat_info->stat.st_uid = UID_FROM_HEADER (header->header.uid);      stat_info->stat.st_gid = GID_FROM_HEADER (header->header.gid);      stat_info->stat.st_rdev = 0;    }  else    {      if (do_user_group)	{	  /* FIXME: Decide if this should somewhat depend on -p.  */	  if (numeric_owner_option	      || !*header->header.uname	      || !uname_to_uid (header->header.uname, &stat_info->stat.st_uid))	    stat_info->stat.st_uid = UID_FROM_HEADER (header->header.uid);	  if (numeric_owner_option	      || !*header->header.gname	      || !gname_to_gid (header->header.gname, &stat_info->stat.st_gid))	    stat_info->stat.st_gid = GID_FROM_HEADER (header->header.gid);	}      switch (header->header.typeflag)	{	case BLKTYPE:	case CHRTYPE:	  stat_info->stat.st_rdev =	    makedev (MAJOR_FROM_HEADER (header->header.devmajor),		     MINOR_FROM_HEADER (header->header.devminor));	  break;	default:	  stat_info->stat.st_rdev = 0;	}    }  stat_info->archive_file_size = stat_info->stat.st_size;  xheader_decode (stat_info);  if (sparse_member_p (stat_info))    {      sparse_fixup_header (stat_info);      stat_info->is_sparse = true;    }  else    {      stat_info->is_sparse = false;      if (((current_format == GNU_FORMAT	    || current_format == OLDGNU_FORMAT)	   && current_header->header.typeflag == GNUTYPE_DUMPDIR)          || stat_info->dumpdir)	stat_info->is_dumpdir = true;    }  transform_member_name (&stat_info->file_name, xform_regfile);}/* Convert buffer at WHERE0 of size DIGS from external format to   uintmax_t.  DIGS must be positive.  If TYPE is nonnull, the data   are of type TYPE.  The buffer must represent a value in the range   -MINUS_MINVAL through MAXVAL.  If OCTAL_ONLY, allow only octal   numbers instead of the other GNU extensions.  Return -1 on error,   diagnosing the error if TYPE is nonnull and if !SILENT.  */static uintmax_tfrom_header (char const *where0, size_t digs, char const *type,	     uintmax_t minus_minval, uintmax_t maxval,	     bool octal_only, bool silent){  uintmax_t value;  char const *where = where0;  char const *lim = where + digs;  int negative = 0;  /* Accommodate buggy tar of unknown vintage, which outputs leading     NUL if the previous field overflows.  */  where += !*where;  /* Accommodate older tars, which output leading spaces.  */  for (;;)    {      if (where == lim)	{	  if (type && !silent)	    ERROR ((0, 0,		    /* TRANSLATORS: %s is type of the value (gid_t, uid_t, etc.) */		    _("Blanks in header where numeric %s value expected"),		    type));	  return -1;	}      if (!ISSPACE ((unsigned char) *where))	break;      where++;    }  value = 0;  if (ISODIGIT (*where))    {      char const *where1 = where;      uintmax_t overflow = 0;      for (;;)	{	  value += *where++ - '0';	  if (where == lim || ! ISODIGIT (*where))	    break;	  overflow |= value ^ (value << LG_8 >> LG_8);	  value <<= LG_8;	}      /* Parse the output of older, unportable tars, which generate         negative values in two's complement octal.  If the leading         nonzero digit is 1, we can't recover the original value         reliably; so do this only if the digit is 2 or more.  This         catches the common case of 32-bit negative time stamps.  */      if ((overflow || maxval < value) && '2' <= *where1 && type)	{	  /* Compute the negative of the input value, assuming two's	     complement.  */	  int digit = (*where1 - '0') | 4;	  overflow = 0;	  value = 0;	  where = where1;	  for (;;)	    {	      value += 7 - digit;	      where++;	      if (where == lim || ! ISODIGIT (*where))		break;	      digit = *where - '0';	      overflow |= value ^ (value << LG_8 >> LG_8);	      value <<= LG_8;	    }	  value++;	  overflow |= !value;	  if (!overflow && value <= minus_minval)	    {	      if (!silent)		WARN ((0, 0,		       /* TRANSLATORS: Second %s is a type name (gid_t,uid_t,etc.) */		       _("Archive octal value %.*s is out of %s range; assuming two's complement"),		       (int) (where - where1), where1, type));	      negative = 1;	    }	}      if (overflow)	{	  if (type && !silent)	    ERROR ((0, 0,		    /* TRANSLATORS: Second %s is a type name (gid_t,uid_t,etc.) */		    _("Archive octal value %.*s is out of %s range"),		    (int) (where - where1), where1, type));	  return -1;	}    }  else if (octal_only)    {      /* Suppress the following extensions.  */    }  else if (*where == '-' || *where == '+')    {      /* Parse base-64 output produced only by tar test versions	 1.13.6 (1999-08-11) through 1.13.11 (1999-08-23).	 Support for this will be withdrawn in future releases.  */      int dig;      if (!silent)	{	  static bool warned_once;	  if (! warned_once)	    {	      warned_once = true;	      WARN ((0, 0, _("Archive contains obsolescent base-64 headers")));	    }	}      negative = *where++ == '-';      while (where != lim	     && (dig = base64_map[(unsigned char) *where]) < 64)	{	  if (value << LG_64 >> LG_64 != value)	    {	      char *string = alloca (digs + 1);	      memcpy (string, where0, digs);	      string[digs] = '\0';	      if (type && !silent)		ERROR ((0, 0,			_("Archive signed base-64 string %s is out of %s range"),			quote (string), type));	      return -1;	    }	  value = (value << LG_64) | dig;	  where++;	}    }  else if (*where == '\200' /* positive base-256 */	   || *where == '\377' /* negative base-256 */)    {      /* Parse base-256 output.  A nonnegative number N is	 represented as (256**DIGS)/2 + N; a negative number -N is	 represented as (256**DIGS) - N, i.e. as two's complement.	 The representation guarantees that the leading bit is	 always on, so that we don't confuse this format with the	 others (assuming ASCII bytes of 8 bits or more).  */      int signbit = *where & (1 << (LG_256 - 2));      uintmax_t topbits = (((uintmax_t) - signbit)			   << (CHAR_BIT * sizeof (uintmax_t)			       - LG_256 - (LG_256 - 2)));      value = (*where++ & ((1 << (LG_256 - 2)) - 1)) - signbit;      for (;;)	{	  value = (value << LG_256) + (unsigned char) *where++;	  if (where == lim)	    break;	  if (((value << LG_256 >> LG_256) | topbits) != value)	    {	      if (type && !silent)		ERROR ((0, 0,			_("Archive base-256 value is out of %s range"),			type));	      return -1;	    }	}      negative = signbit;      if (negative)	value = -value;    }  if (where != lim && *where && !ISSPACE ((unsigned char) *where))    {      if (type)	{	  char buf[1000]; /* Big enough to represent any header.  */	  static struct quoting_options *o;	  if (!o)	    {	      o = clone_quoting_options (0);	      set_quoting_style (o, locale_quoting_style);	    }	  while (where0 != lim && ! lim[-1])	    lim--;	  quotearg_buffer (buf, sizeof buf, where0, lim - where, o);	  if (!silent)	    ERROR ((0, 0,		    /* TRANSLATORS: Second %s is a type name (gid_t,uid_t,etc.) */		    _("Archive contains %.*s where numeric %s value expected"),		    (int) sizeof buf, buf, type));	}      return -1;    }  if (value <= (negative ? minus_minval : maxval))    return negative ? -value : value;  if (type && !silent)    {      char minval_buf[UINTMAX_STRSIZE_BOUND + 1];      char maxval_buf[UINTMAX_STRSIZE_BOUND];      char value_buf[UINTMAX_STRSIZE_BOUND + 1];      char *minval_string = STRINGIFY_BIGINT (minus_minval, minval_buf + 1);      char *value_string = STRINGIFY_BIGINT (value, value_buf + 1);      if (negative)	*--value_string = '-';      if (minus_minval)	*--minval_string = '-';      /* TRANSLATORS: Second %s is type name (gid_t,uid_t,etc.) */      ERROR ((0, 0, _("Archive value %s is out of %s range %s..%s"),	      value_string, type,	      minval_string, STRINGIFY_BIGINT (maxval, maxval_buf)));    }  return -1;}gid_tgid_from_header (const char *p, size_t s){  return from_header (p, s, "gid_t",		      - (uintmax_t) TYPE_MINIMUM (gid_t),		      (uintmax_t) TYPE_MAXIMUM (gid_t),		      false, false);}major_tmajor_from_header (const char *p, size_t s){  return from_header (p, s, "major_t",		      - (uintmax_t) TYPE_MINIMUM (major_t),		      (uintmax_t) TYPE_MAXIMUM (major_t), false, false);}minor_tminor_from_header (const char *p, size_t s){  return from_header (p, s, "minor_t",		      - (uintmax_t) TYPE_MINIMUM (minor_t),		      (uintmax_t) TYPE_MAXIMUM (minor_t), false, false);}mode_tmode_from_header (const char *p, size_t s){  /* Do not complain about unrecognized mode bits.  */  unsigned u = from_header (p, s, "mode_t",			    - (uintmax_t) TYPE_MINIMUM (mode_t),			    TYPE_MAXIMUM (uintmax_t), false, false);  return ((u & TSUID ? S_ISUID : 0)	  | (u & TSGID ? S_ISGID : 0)	  | (u & TSVTX ? S_ISVTX : 0)	  | (u & TUREAD ? S_IRUSR : 0)	  | (u & TUWRITE ? S_IWUSR : 0)	  | (u & TUEXEC ? S_IXUSR : 0)	  | (u & TGREAD ? S_IRGRP : 0)	  | (u & TGWRITE ? S_IWGRP : 0)	  | (u & TGEXEC ? S_IXGRP : 0)	  | (u & TOREAD ? S_IROTH : 0)	  | (u & TOWRITE ? S_IWOTH : 0)	  | (u & TOEXEC ? S_IXOTH : 0));

⌨️ 快捷键说明

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