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

📄 extract.c

📁 gnu tar 源码包。 tar 软件是 Unix 系统下的一个打包软件
💻 C
📖 第 1 页 / 共 3 页
字号:
  link_name = current_stat_info.link_name;    if (! absolute_names_option && contains_dot_dot (link_name))    return create_placeholder_file (file_name, false, &interdir_made);  do    {      struct stat st1, st2;      int e;      int status = link (link_name, file_name);      e = errno;      if (status == 0)	{	  struct delayed_link *ds = delayed_link_head;	  if (ds && lstat (link_name, &st1) == 0)	    for (; ds; ds = ds->next)	      if (ds->dev == st1.st_dev		  && ds->ino == st1.st_ino		  && timespec_cmp (ds->mtime, get_stat_mtime (&st1)) == 0)		{		  struct string_list *p =  xmalloc (offsetof (struct string_list, string)						    + strlen (file_name) + 1);		  strcpy (p->string, file_name);		  p->next = ds->sources;		  ds->sources = p;		  break;		}	  return 0;	}      else if ((e == EEXIST && strcmp (link_name, file_name) == 0)	       || (lstat (link_name, &st1) == 0		   && lstat (file_name, &st2) == 0		   && st1.st_dev == st2.st_dev		   && st1.st_ino == st2.st_ino))	return 0;      errno = e;    }  while (maybe_recoverable (file_name, &interdir_made));  if (!(incremental_option && errno == EEXIST))    {      link_error (link_name, file_name);      return 1;    }  return 0;}static intextract_symlink (char *file_name, int typeflag){#ifdef HAVE_SYMLINK  int status;  int interdir_made = 0;  transform_member_name (&current_stat_info.link_name, xform_symlink);  if (! absolute_names_option      && (IS_ABSOLUTE_FILE_NAME (current_stat_info.link_name)	  || contains_dot_dot (current_stat_info.link_name)))    return create_placeholder_file (file_name, true, &interdir_made);  while ((status = symlink (current_stat_info.link_name, file_name)))    if (!maybe_recoverable (file_name, &interdir_made))      break;  if (status == 0)    set_stat (file_name, &current_stat_info, NULL, 0, 0, SYMTYPE);  else    symlink_error (current_stat_info.link_name, file_name);  return status;#else  static int warned_once;  if (!warned_once)    {      warned_once = 1;      WARN ((0, 0, _("Attempting extraction of symbolic links as hard links")));    }  return extract_link (file_name, typeflag);#endif}#if S_IFCHR || S_IFBLKstatic intextract_node (char *file_name, int typeflag){  int status;  int interdir_made = 0;  mode_t mode = current_stat_info.stat.st_mode & ~ current_umask;  mode_t invert_permissions =    0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0;  do    status = mknod (file_name, mode ^ invert_permissions,		    current_stat_info.stat.st_rdev);  while (status && maybe_recoverable (file_name, &interdir_made));  if (status != 0)    mknod_error (file_name);  else    set_stat (file_name, &current_stat_info, NULL, invert_permissions,	      ARCHIVED_PERMSTATUS, typeflag);  return status;}#endif#if HAVE_MKFIFO || defined mkfifostatic intextract_fifo (char *file_name, int typeflag){  int status;  int interdir_made = 0;  mode_t mode = current_stat_info.stat.st_mode & ~ current_umask;  mode_t invert_permissions =    0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0;  while ((status = mkfifo (file_name, mode)) != 0)    if (!maybe_recoverable (file_name, &interdir_made))      break;  if (status == 0)    set_stat (file_name, &current_stat_info, NULL, invert_permissions,	      ARCHIVED_PERMSTATUS, typeflag);  else    mkfifo_error (file_name);  return status;}#endifstatic intextract_volhdr (char *file_name, int typeflag){  if (verbose_option)    fprintf (stdlis, _("Reading %s\n"), quote (current_stat_info.file_name));  skip_member ();  return 0;}static intextract_failure (char *file_name, int typeflag){  return 1;}typedef int (*tar_extractor_t) (char *file_name, int typeflag);/* Prepare to extract a file. Find extractor function.   Return zero if extraction should not proceed.  */static intprepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun){  int rc = 1;  if (EXTRACT_OVER_PIPE)    rc = 0;  /* Select the extractor */  switch (typeflag)    {    case GNUTYPE_SPARSE:      *fun = extract_file;      rc = 1;      break;    case AREGTYPE:    case REGTYPE:    case CONTTYPE:      /* Appears to be a file.  But BSD tar uses the convention that a slash	 suffix means a directory.  */      if (current_stat_info.had_trailing_slash)	*fun = extract_dir;      else	{	  *fun = extract_file;	  rc = 1;	}      break;    case SYMTYPE:      *fun = extract_symlink;      break;    case LNKTYPE:      *fun = extract_link;      break;#if S_IFCHR    case CHRTYPE:      current_stat_info.stat.st_mode |= S_IFCHR;      *fun = extract_node;      break;#endif#if S_IFBLK    case BLKTYPE:      current_stat_info.stat.st_mode |= S_IFBLK;      *fun = extract_node;      break;#endif#if HAVE_MKFIFO || defined mkfifo    case FIFOTYPE:      *fun = extract_fifo;      break;#endif    case DIRTYPE:    case GNUTYPE_DUMPDIR:      *fun = extract_dir;      if (current_stat_info.is_dumpdir)	delay_directory_restore_option = true;      break;    case GNUTYPE_VOLHDR:      *fun = extract_volhdr;      break;    case GNUTYPE_MULTIVOL:      ERROR ((0, 0,	      _("%s: Cannot extract -- file is continued from another volume"),	      quotearg_colon (current_stat_info.file_name)));      *fun = extract_failure;      break;    case GNUTYPE_LONGNAME:    case GNUTYPE_LONGLINK:      ERROR ((0, 0, _("Unexpected long name header")));      *fun = extract_failure;      break;    default:      WARN ((0, 0,	     _("%s: Unknown file type `%c', extracted as normal file"),	     quotearg_colon (file_name), typeflag));      *fun = extract_file;    }  /* Determine whether the extraction should proceed */  if (rc == 0)    return 0;  switch (old_files_option)    {    case UNLINK_FIRST_OLD_FILES:      if (!remove_any_file (file_name,                            recursive_unlink_option ? RECURSIVE_REMOVE_OPTION                                                      : ORDINARY_REMOVE_OPTION)	  && errno && errno != ENOENT)	{	  unlink_error (file_name);	  return 0;	}      break;    case KEEP_NEWER_FILES:      if (file_newer_p (file_name, &current_stat_info))	{	  WARN ((0, 0, _("Current %s is newer or same age"),		 quote (file_name)));	  return 0;	}      break;    default:      break;    }  return 1;}/* Extract a file from the archive.  */voidextract_archive (void){  char typeflag;  tar_extractor_t fun;  set_next_block_after (current_header);  decode_header (current_header, &current_stat_info, &current_format, 1);  if (!current_stat_info.file_name[0]      || (interactive_option	  && !confirm ("extract", current_stat_info.file_name)))    {      skip_member ();      return;    }  /* Print the block from current_header and current_stat.  */  if (verbose_option)    print_header (&current_stat_info, -1);  /* Restore stats for all non-ancestor directories, unless     it is an incremental archive.     (see NOTICE in the comment to delay_set_stat above) */  if (!delay_directory_restore_option)    apply_nonancestor_delayed_set_stat (current_stat_info.file_name, 0);  /* Take a safety backup of a previously existing file.  */  if (backup_option)    if (!maybe_backup_file (current_stat_info.file_name, 0))      {	int e = errno;	ERROR ((0, e, _("%s: Was unable to backup this file"),		quotearg_colon (current_stat_info.file_name)));	skip_member ();	return;      }  /* Extract the archive entry according to its type.  */  /* KLUDGE */  typeflag = sparse_member_p (&current_stat_info) ?                  GNUTYPE_SPARSE : current_header->header.typeflag;  if (prepare_to_extract (current_stat_info.file_name, typeflag, &fun))    {      if (fun && (*fun) (current_stat_info.file_name, typeflag)	  && backup_option)	undo_last_backup ();    }  else    skip_member ();}/* Extract the symbolic links whose final extraction were delayed.  */static voidapply_delayed_links (void){  struct delayed_link *ds;  for (ds = delayed_link_head; ds; )    {      struct string_list *sources = ds->sources;      char const *valid_source = 0;      for (sources = ds->sources; sources; sources = sources->next)	{	  char const *source = sources->string;	  struct stat st;	  /* Make sure the placeholder file is still there.  If not,	     don't create a link, as the placeholder was probably	     removed by a later extraction.  */	  if (lstat (source, &st) == 0	      && st.st_dev == ds->dev	      && st.st_ino == ds->ino	      && timespec_cmp (get_stat_mtime (&st), ds->mtime) == 0)	    {	      /* Unlink the placeholder, then create a hard link if possible,		 a symbolic link otherwise.  */	      if (unlink (source) != 0)		unlink_error (source);	      else if (valid_source && link (valid_source, source) == 0)		;	      else if (!ds->is_symlink)		{		  if (link (ds->target, source) != 0)		    link_error (ds->target, source);		}	      else if (symlink (ds->target, source) != 0)		symlink_error (ds->target, source);	      else		{		  struct tar_stat_info st1;		  st1.stat.st_uid = ds->uid;		  st1.stat.st_gid = ds->gid;		  set_stat (source, &st1, NULL, 0, 0, SYMTYPE);		  valid_source = source;		}	    }	}      for (sources = ds->sources; sources; )	{	  struct string_list *next = sources->next;	  free (sources);	  sources = next;	}      {	struct delayed_link *next = ds->next;	free (ds);	ds = next;      }    }  delayed_link_head = 0;}/* Finish the extraction of an archive.  */voidextract_finish (void){  /* First, fix the status of ordinary directories that need fixing.  */  apply_nonancestor_delayed_set_stat ("", 0);  /* Then, apply delayed links, so that they don't affect delayed     directory status-setting for ordinary directories.  */  apply_delayed_links ();  /* Finally, fix the status of directories that are ancestors     of delayed links.  */  apply_nonancestor_delayed_set_stat ("", 1);}boolrename_directory (char *src, char *dst){  if (rename (src, dst))    {      int e = errno;      switch (e)	{	case ENOENT:	  if (make_directories (dst))	    {	      if (rename (src, dst) == 0)		return true;	      e = errno;	    }	  break;	case EXDEV:	  /* FIXME: Fall back to recursive copying */	default:	  break;	}      ERROR ((0, e, _("Cannot rename %s to %s"),	      quote_n (0, src),	      quote_n (1, dst)));      return false;    }  return true;}voidfatal_exit (void){  extract_finish ();  error (TAREXIT_FAILURE, 0, _("Error is not recoverable: exiting now"));  abort ();}voidxalloc_die (void){  error (0, 0, "%s", _("memory exhausted"));  fatal_exit ();}

⌨️ 快捷键说明

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