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

📄 create.c

📁 gnu tar 源码包。 tar 软件是 Unix 系统下的一个打包软件
💻 C
📖 第 1 页 / 共 4 页
字号:
      {	TIME_TO_CHARS (st->atime.tv_sec, header->oldgnu_header.atime);	TIME_TO_CHARS (st->ctime.tv_sec, header->oldgnu_header.ctime);      }  header->header.typeflag = archive_format == V7_FORMAT ? AREGTYPE : REGTYPE;  switch (archive_format)    {    case V7_FORMAT:      break;    case OLDGNU_FORMAT:    case GNU_FORMAT:   /*FIXME?*/      /* Overwrite header->header.magic and header.version in one blow.  */      strcpy (header->header.magic, OLDGNU_MAGIC);      break;    case POSIX_FORMAT:    case USTAR_FORMAT:      strncpy (header->header.magic, TMAGIC, TMAGLEN);      strncpy (header->header.version, TVERSION, TVERSLEN);      break;    default:      abort ();    }  if (archive_format == V7_FORMAT || numeric_owner_option)    {      /* header->header.[ug]name are left as the empty string.  */    }  else    {      uid_to_uname (st->stat.st_uid, &st->uname);      gid_to_gname (st->stat.st_gid, &st->gname);      if (archive_format == POSIX_FORMAT	  && (strlen (st->uname) > UNAME_FIELD_SIZE	      || !string_ascii_p (st->uname)))	xheader_store ("uname", st, NULL);      UNAME_TO_CHARS (st->uname, header->header.uname);      if (archive_format == POSIX_FORMAT	  && (strlen (st->gname) > GNAME_FIELD_SIZE	      || !string_ascii_p (st->gname)))	xheader_store ("gname", st, NULL);      GNAME_TO_CHARS (st->gname, header->header.gname);    }  return header;}voidsimple_finish_header (union block *header){  size_t i;  int sum;  char *p;  memcpy (header->header.chksum, CHKBLANKS, sizeof header->header.chksum);  sum = 0;  p = header->buffer;  for (i = sizeof *header; i-- != 0; )    /* We can't use unsigned char here because of old compilers, e.g. V7.  */    sum += 0xFF & *p++;  /* Fill in the checksum field.  It's formatted differently from the     other fields: it has [6] digits, a null, then a space -- rather than     digits, then a null.  We use to_chars.     The final space is already there, from     checksumming, and to_chars doesn't modify it.     This is a fast way to do:     sprintf(header->header.chksum, "%6o", sum);  */  uintmax_to_chars ((uintmax_t) sum, header->header.chksum, 7);  set_next_block_after (header);}/* Finish off a filled-in header block and write it out.  We also   print the file name and/or full info if verbose is on.  If BLOCK_ORDINAL   is not negative, is the block ordinal of the first record for this   file, which may be a preceding long name or long link record.  */voidfinish_header (struct tar_stat_info *st,	       union block *header, off_t block_ordinal){  /* Note: It is important to do this before the call to write_extended(),     so that the actual ustar header is printed */  if (verbose_option      && header->header.typeflag != GNUTYPE_LONGLINK      && header->header.typeflag != GNUTYPE_LONGNAME      && header->header.typeflag != XHDTYPE      && header->header.typeflag != XGLTYPE)    {      /* These globals are parameters to print_header, sigh.  */      current_header = header;      current_format = archive_format;      print_header (st, block_ordinal);    }  header = write_extended (false, st, header);  simple_finish_header (header);}voidpad_archive (off_t size_left){  union block *blk;  while (size_left > 0)    {      mv_size_left (size_left);      blk = find_next_block ();      memset (blk->buffer, 0, BLOCKSIZE);      set_next_block_after (blk);      size_left -= BLOCKSIZE;    }}static enum dump_statusdump_regular_file (int fd, struct tar_stat_info *st){  off_t size_left = st->stat.st_size;  off_t block_ordinal;  union block *blk;  block_ordinal = current_block_ordinal ();  blk = start_header (st);  if (!blk)    return dump_status_fail;  /* Mark contiguous files, if we support them.  */  if (archive_format != V7_FORMAT && S_ISCTG (st->stat.st_mode))    blk->header.typeflag = CONTTYPE;  finish_header (st, blk, block_ordinal);  mv_begin (st);  while (size_left > 0)    {      size_t bufsize, count;      mv_size_left (size_left);      blk = find_next_block ();      bufsize = available_space_after (blk);      if (size_left < bufsize)	{	  /* Last read -- zero out area beyond.  */	  bufsize = size_left;	  count = bufsize % BLOCKSIZE;	  if (count)	    memset (blk->buffer + size_left, 0, BLOCKSIZE - count);	}      count = (fd < 0) ? bufsize : safe_read (fd, blk->buffer, bufsize);      if (count == SAFE_READ_ERROR)	{	  read_diag_details (st->orig_file_name,	                     st->stat.st_size - size_left, bufsize);	  pad_archive (size_left);	  return dump_status_short;	}      size_left -= count;      set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE);      if (count != bufsize)	{	  char buf[UINTMAX_STRSIZE_BOUND];	  memset (blk->buffer + count, 0, bufsize - count);	  WARN ((0, 0,		 ngettext ("%s: File shrank by %s byte; padding with zeros",			   "%s: File shrank by %s bytes; padding with zeros",			   size_left),		 quotearg_colon (st->orig_file_name),		 STRINGIFY_BIGINT (size_left, buf)));	  if (! ignore_failed_read_option) 	    exit_status = TAREXIT_DIFFERS;	  pad_archive (size_left - (bufsize - count));	  return dump_status_short;	}    }  return dump_status_ok;}static voiddump_dir0 (char *directory,	   struct tar_stat_info *st, int top_level, dev_t parent_device){  dev_t our_device = st->stat.st_dev;  const char *tag_file_name;    if (!is_avoided_name (st->orig_file_name))    {      union block *blk = NULL;      off_t block_ordinal = current_block_ordinal ();      st->stat.st_size = 0;	/* force 0 size on dir */      blk = start_header (st);      if (!blk)	return;      if (incremental_option && archive_format != POSIX_FORMAT)	blk->header.typeflag = GNUTYPE_DUMPDIR;      else /* if (standard_option) */	blk->header.typeflag = DIRTYPE;      /* If we're gnudumping, we aren't done yet so don't close it.  */      if (!incremental_option)	finish_header (st, blk, block_ordinal);      else if (gnu_list_name->dir_contents)	{	  if (archive_format == POSIX_FORMAT)	    {	      xheader_store ("GNU.dumpdir", st, gnu_list_name->dir_contents);	      finish_header (st, blk, block_ordinal);	    }	  else	    {	      off_t size_left;	      off_t totsize;	      size_t bufsize;	      ssize_t count;	      const char *buffer, *p_buffer;	      block_ordinal = current_block_ordinal ();	      buffer = gnu_list_name->dir_contents;	      if (buffer)		totsize = dumpdir_size (buffer);	      else		totsize = 0;	      OFF_TO_CHARS (totsize, blk->header.size);	      finish_header (st, blk, block_ordinal);	      p_buffer = buffer;	      size_left = totsize;	      mv_begin (st);	      mv_total_size (totsize);	      while (size_left > 0)		{		  mv_size_left (size_left);		  blk = find_next_block ();		  bufsize = available_space_after (blk);		  if (size_left < bufsize)		    {		      bufsize = size_left;		      count = bufsize % BLOCKSIZE;		      if (count)			memset (blk->buffer + size_left, 0, BLOCKSIZE - count);		    }		  memcpy (blk->buffer, p_buffer, bufsize);		  size_left -= bufsize;		  p_buffer += bufsize;		  set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE);		}	      mv_end ();	    }	  return;	}    }  if (!recursion_option)    return;  if (one_file_system_option      && !top_level      && parent_device != st->stat.st_dev)    {      if (verbose_option)	WARN ((0, 0,	       _("%s: file is on a different filesystem; not dumped"),	       quotearg_colon (st->orig_file_name)));    }  else    {      char *name_buf;      size_t name_size;            switch (check_exclusion_tags (st->orig_file_name, &tag_file_name))	{	case exclusion_tag_all:	  /* Handled in dump_file0 */	  break;	  	case exclusion_tag_none:	  {	    char const *entry;	    size_t entry_len;	    size_t name_len;	    name_buf = xstrdup (st->orig_file_name);	    name_size = name_len = strlen (name_buf);	    /* Now output all the files in the directory.  */	    /* FIXME: Should speed this up by cd-ing into the dir.  */	    for (entry = directory; (entry_len = strlen (entry)) != 0;		 entry += entry_len + 1)	      {		if (name_size < name_len + entry_len)		  {		    name_size = name_len + entry_len;		    name_buf = xrealloc (name_buf, name_size + 1);		  }		strcpy (name_buf + name_len, entry);		if (!excluded_name (name_buf))		  dump_file (name_buf, 0, our_device);	      }	    	    free (name_buf);	  }	  break;	case exclusion_tag_contents:	  exclusion_tag_warning (st->orig_file_name, tag_file_name,				 _("contents not dumped"));	  name_size = strlen (st->orig_file_name) + strlen (tag_file_name) + 1;	  name_buf = xmalloc (name_size);	  strcpy (name_buf, st->orig_file_name);	  strcat (name_buf, tag_file_name);	  dump_file (name_buf, 0, our_device);	  free (name_buf);	  break;      	case exclusion_tag_under:	  exclusion_tag_warning (st->orig_file_name, tag_file_name,				 _("contents not dumped"));	  break;	}    }}/* Ensure exactly one trailing slash.  */static voidensure_slash (char **pstr){  size_t len = strlen (*pstr);  while (len >= 1 && ISSLASH ((*pstr)[len - 1]))    len--;  if (!ISSLASH ((*pstr)[len]))    *pstr = xrealloc (*pstr, len + 2);  (*pstr)[len++] = '/';  (*pstr)[len] = '\0';}static booldump_dir (int fd, struct tar_stat_info *st, int top_level, dev_t parent_device){  char *directory = fdsavedir (fd);  if (!directory)    {      savedir_diag (st->orig_file_name);      return false;    }  dump_dir0 (directory, st, top_level, parent_device);  free (directory);  return true;}/* Main functions of this module.  */voidcreate_archive (void){  const char *p;  open_archive (ACCESS_WRITE);  buffer_write_global_xheader ();  if (incremental_option)    {      size_t buffer_size = 1000;      char *buffer = xmalloc (buffer_size);      const char *q;      collect_and_sort_names ();      while ((p = name_from_list ()) != NULL)	if (!excluded_name (p))	  dump_file (p, -1, (dev_t) 0);      blank_name_list ();      while ((p = name_from_list ()) != NULL)	if (!excluded_name (p))	  {	    size_t plen = strlen (p);	    if (buffer_size <= plen)	      {		while ((buffer_size *= 2) <= plen)		  continue;		buffer = xrealloc (buffer, buffer_size);	      }	    memcpy (buffer, p, plen);	    if (! ISSLASH (buffer[plen - 1]))	      buffer[plen++] = '/';	    q = gnu_list_name->dir_contents;	    if (q)	      while (*q)		{		  size_t qlen = strlen (q);		  if (*q == 'Y')		    {		      if (buffer_size < plen + qlen)			{			  while ((buffer_size *=2 ) < plen + qlen)			    continue;			  buffer = xrealloc (buffer, buffer_size); 			}		      strcpy (buffer + plen, q + 1);		      dump_file (buffer, -1, (dev_t) 0);		    }		  q += qlen + 1;		}	  }      free (buffer);    }  else    {      while ((p = name_next (1)) != NULL)	if (!excluded_name (p))	  dump_file (p, 1, (dev_t) 0);    }  write_eot ();  close_archive ();  if (listed_incremental_option)    write_directory_file ();}/* Calculate the hash of a link.  */static size_thash_link (void const *entry, size_t n_buckets){  struct link const *l = entry;

⌨️ 快捷键说明

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