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

📄 create.c

📁 gnu tar 源码包。 tar 软件是 Unix 系统下的一个打包软件
💻 C
📖 第 1 页 / 共 4 页
字号:
  uintmax_t num = l->dev ^ l->ino;  return num % n_buckets;}/* Compare two links for equality.  */static boolcompare_links (void const *entry1, void const *entry2){  struct link const *link1 = entry1;  struct link const *link2 = entry2;  return ((link1->dev ^ link2->dev) | (link1->ino ^ link2->ino)) == 0;}static voidunknown_file_error (char const *p){  WARN ((0, 0, _("%s: Unknown file type; file ignored"),	 quotearg_colon (p)));  if (!ignore_failed_read_option)    exit_status = TAREXIT_FAILURE;}/* Handling of hard links *//* Table of all non-directories that we've written so far.  Any time   we see another, we check the table and avoid dumping the data   again if we've done it once already.  */static Hash_table *link_table;/* Try to dump stat as a hard link to another file in the archive.   Return true if successful.  */static booldump_hard_link (struct tar_stat_info *st){  if (link_table && st->stat.st_nlink > 1)    {      struct link lp;      struct link *duplicate;      off_t block_ordinal;      union block *blk;      lp.ino = st->stat.st_ino;      lp.dev = st->stat.st_dev;      if ((duplicate = hash_lookup (link_table, &lp)))	{	  /* We found a link.  */	  char const *link_name = safer_name_suffix (duplicate->name, true,	                                             absolute_names_option);	  duplicate->nlink--;	  block_ordinal = current_block_ordinal ();	  assign_string (&st->link_name, link_name);	  if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT)	      < strlen (link_name))	    write_long_link (st);	  st->stat.st_size = 0;	  blk = start_header (st);	  if (!blk)	    return false;	  tar_copy_str (blk->header.linkname, link_name, NAME_FIELD_SIZE);	  blk->header.typeflag = LNKTYPE;	  finish_header (st, blk, block_ordinal);	  if (remove_files_option && unlink (st->orig_file_name) != 0)	    unlink_error (st->orig_file_name);	  return true;	}    }  return false;}static voidfile_count_links (struct tar_stat_info *st){  if (hard_dereference_option)    return;  if (st->stat.st_nlink > 1)    {      struct link *duplicate;      struct link *lp = xmalloc (offsetof (struct link, name)				 + strlen (st->orig_file_name) + 1);      lp->ino = st->stat.st_ino;      lp->dev = st->stat.st_dev;      lp->nlink = st->stat.st_nlink;      strcpy (lp->name, st->orig_file_name);      if (! ((link_table	      || (link_table = hash_initialize (0, 0, hash_link,						compare_links, 0)))	     && (duplicate = hash_insert (link_table, lp))))	xalloc_die ();      if (duplicate != lp)	abort ();      lp->nlink--;    }}/* For each dumped file, check if all its links were dumped. Emit   warnings if it is not so. */voidcheck_links (void){  struct link *lp;  if (!link_table)    return;  for (lp = hash_get_first (link_table); lp;       lp = hash_get_next (link_table, lp))    {      if (lp->nlink)	{	  WARN ((0, 0, _("Missing links to %s.\n"), quote (lp->name)));	}    }}/* Dump a single file, recursing on directories.  P is the file name   to dump.  TOP_LEVEL tells whether this is a top-level call; zero   means no, positive means yes, and negative means the top level   of an incremental dump.  PARENT_DEVICE is the device of P's   parent directory; it is examined only if TOP_LEVEL is zero. *//* FIXME: One should make sure that for *every* path leading to setting   exit_status to failure, a clear diagnostic has been issued.  */static voiddump_file0 (struct tar_stat_info *st, const char *p,	    int top_level, dev_t parent_device){  union block *header;  char type;  off_t original_size;  struct timespec original_ctime;  struct timespec restore_times[2];  off_t block_ordinal = -1;  bool is_dir;  if (interactive_option && !confirm ("add", p))    return;  assign_string (&st->orig_file_name, p);  assign_string (&st->file_name,                 safer_name_suffix (p, false, absolute_names_option));  transform_name (&st->file_name);  if (deref_stat (dereference_option, p, &st->stat) != 0)    {      stat_diag (p);      return;    }  st->archive_file_size = original_size = st->stat.st_size;  st->atime = restore_times[0] = get_stat_atime (&st->stat);  st->mtime = restore_times[1] = get_stat_mtime (&st->stat);  st->ctime = original_ctime = get_stat_ctime (&st->stat);#ifdef S_ISHIDDEN  if (S_ISHIDDEN (st->stat.st_mode))    {      char *new = (char *) alloca (strlen (p) + 2);      if (new)	{	  strcpy (new, p);	  strcat (new, "@");	  p = new;	}    }#endif  /* See if we want only new files, and check if this one is too old to     put in the archive.     This check is omitted if incremental_option is set *and* the     requested file is not explicitely listed in the command line. */  if (!(incremental_option && !is_individual_file (p))      && !S_ISDIR (st->stat.st_mode)      && OLDER_TAR_STAT_TIME (*st, m)      && (!after_date_option || OLDER_TAR_STAT_TIME (*st, c)))    {      if (!incremental_option && verbose_option)	WARN ((0, 0, _("%s: file is unchanged; not dumped"),	       quotearg_colon (p)));      return;    }  /* See if we are trying to dump the archive.  */  if (sys_file_is_archive (st))    {      WARN ((0, 0, _("%s: file is the archive; not dumped"),	     quotearg_colon (p)));      return;    }  if (is_avoided_name (p))    return;  is_dir = S_ISDIR (st->stat.st_mode) != 0;  if (!is_dir && dump_hard_link (st))    return;  if (is_dir || S_ISREG (st->stat.st_mode) || S_ISCTG (st->stat.st_mode))    {      bool ok;      int fd = -1;      struct stat final_stat;      if (is_dir || file_dumpable_p (st))	{	  fd = open (p,		     (O_RDONLY | O_BINARY		      | (is_dir ? O_DIRECTORY | O_NONBLOCK : 0)		      | (atime_preserve_option == system_atime_preserve			 ? O_NOATIME			 : 0)));	  if (fd < 0)	    {	      if (!top_level && errno == ENOENT)		WARN ((0, 0, _("%s: File removed before we read it"),		       quotearg_colon (p)));	      else		open_diag (p);	      return;	    }	}      if (is_dir)	{	  const char *tag_file_name;	  ensure_slash (&st->orig_file_name);	  ensure_slash (&st->file_name);	  if (check_exclusion_tags (st->orig_file_name, &tag_file_name)	      == exclusion_tag_all)	    {	      exclusion_tag_warning (st->orig_file_name, tag_file_name,				     _("directory not dumped"));	      return;	    }	  	  ok = dump_dir (fd, st, top_level, parent_device);	  /* dump_dir consumes FD if successful.  */	  if (ok)	    fd = -1;	}      else	{	  enum dump_status status;	  if (fd != -1 && sparse_option && ST_IS_SPARSE (st->stat))	    {	      status = sparse_dump_file (fd, st);	      if (status == dump_status_not_implemented)		status = dump_regular_file (fd, st);	    }	  else	    status = dump_regular_file (fd, st);	  switch (status)	    {	    case dump_status_ok:	    case dump_status_short:	      mv_end ();	      file_count_links (st);	      break;	    case dump_status_fail:	      break;	    case dump_status_not_implemented:	      abort ();	    }	  ok = status == dump_status_ok;	}      if (ok)	{	  /* If possible, reopen a directory if we are preserving	     atimes, so that we can set just the atime on systems with	     _FIOSATIME.  */	  if (fd < 0 && is_dir	      && atime_preserve_option == replace_atime_preserve)	    fd = open (p, O_RDONLY | O_BINARY | O_DIRECTORY | O_NONBLOCK);	  if ((fd < 0	       ? deref_stat (dereference_option, p, &final_stat)	       : fstat (fd, &final_stat))	      != 0)	    {	      stat_diag (p);	      ok = false;	    }	}      if (ok)	{	  if ((timespec_cmp (get_stat_ctime (&final_stat), original_ctime) != 0	       /* Original ctime will change if the file is a directory and		  --remove-files is given */	       && !(remove_files_option && is_dir))	      || original_size < final_stat.st_size)	    {	      WARN ((0, 0, _("%s: file changed as we read it"),		     quotearg_colon (p)));	      if (exit_status == TAREXIT_SUCCESS)		exit_status = TAREXIT_DIFFERS;	    }	  else if (atime_preserve_option == replace_atime_preserve		   && set_file_atime (fd, p, restore_times) != 0)	    utime_error (p);	}      if (0 <= fd && close (fd) != 0)	{	  close_diag (p);	  ok = false;	}      if (ok && remove_files_option)	{	  if (is_dir)	    {	      if (rmdir (p) != 0 && errno != ENOTEMPTY)		rmdir_error (p);	    }	  else	    {	      if (unlink (p) != 0)		unlink_error (p);	    }	}      return;    }#ifdef HAVE_READLINK  else if (S_ISLNK (st->stat.st_mode))    {      char *buffer;      int size;      size_t linklen = st->stat.st_size;      if (linklen != st->stat.st_size || linklen + 1 == 0)	xalloc_die ();      buffer = (char *) alloca (linklen + 1);      size = readlink (p, buffer, linklen + 1);      if (size < 0)	{	  readlink_diag (p);	  return;	}      buffer[size] = '\0';      assign_string (&st->link_name, buffer);      transform_name (&st->link_name);      if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)	write_long_link (st);      block_ordinal = current_block_ordinal ();      st->stat.st_size = 0;	/* force 0 size on symlink */      header = start_header (st);      if (!header)	return;      tar_copy_str (header->header.linkname, st->link_name, NAME_FIELD_SIZE);      header->header.typeflag = SYMTYPE;      finish_header (st, header, block_ordinal);      /* nothing more to do to it */      if (remove_files_option)	{	  if (unlink (p) == -1)	    unlink_error (p);	}      file_count_links (st);      return;    }#endif  else if (S_ISCHR (st->stat.st_mode))    type = CHRTYPE;  else if (S_ISBLK (st->stat.st_mode))    type = BLKTYPE;  else if (S_ISFIFO (st->stat.st_mode))    type = FIFOTYPE;  else if (S_ISSOCK (st->stat.st_mode))    {      WARN ((0, 0, _("%s: socket ignored"), quotearg_colon (p)));      return;    }  else if (S_ISDOOR (st->stat.st_mode))    {      WARN ((0, 0, _("%s: door ignored"), quotearg_colon (p)));      return;    }  else    {      unknown_file_error (p);      return;    }  if (archive_format == V7_FORMAT)    {      unknown_file_error (p);      return;    }  block_ordinal = current_block_ordinal ();  st->stat.st_size = 0;	/* force 0 size */  header = start_header (st);  if (!header)    return;  header->header.typeflag = type;  if (type != FIFOTYPE)    {      MAJOR_TO_CHARS (major (st->stat.st_rdev),		      header->header.devmajor);      MINOR_TO_CHARS (minor (st->stat.st_rdev),		      header->header.devminor);    }  finish_header (st, header, block_ordinal);  if (remove_files_option)    {      if (unlink (p) == -1)	unlink_error (p);    }}voiddump_file (const char *p, int top_level, dev_t parent_device){  struct tar_stat_info st;  tar_stat_init (&st);  dump_file0 (&st, p, top_level, parent_device);  if (listed_incremental_option)    update_parent_directory (p);  tar_stat_destroy (&st);}

⌨️ 快捷键说明

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