コード例 #1
0
ファイル: compare.c プロジェクト: redwinner/unxutils
static void
read_and_process (long size, int (*processor) (long, char *))
{
  union block *data_block;
  long data_size;

  if (multi_volume_option)
    save_sizeleft = size;
  while (size)
    {
      data_block = find_next_block ();
      if (data_block == NULL)
	{
	  ERROR ((0, 0, _("Unexpected EOF on archive file")));
	  return;
	}

      data_size = available_space_after (data_block);
      if (data_size > size)
	data_size = size;
      if (!(*processor) (data_size, data_block->buffer))
	processor = process_noop;
      set_next_block_after ((union block *)
			    (data_block->buffer + data_size - 1));
      size -= data_size;
      if (multi_volume_option)
	save_sizeleft -= data_size;
    }
}
コード例 #2
0
/* Catenate file FILE_NAME to the archive without creating a header for it.
   It had better be a tar file or the archive is screwed.  */
static void
append_file (char *file_name)
{
  int handle = open (file_name, O_RDONLY | O_BINARY);
  struct stat stat_data;

  if (handle < 0)
    {
      open_error (file_name);
      return;
    }

  if (fstat (handle, &stat_data) != 0)
    stat_error (file_name);
  else
    {
      off_t bytes_left = stat_data.st_size;

      while (bytes_left > 0)
	{
	  union block *start = find_next_block ();
	  size_t buffer_size = available_space_after (start);
	  size_t status;
	  char buf[UINTMAX_STRSIZE_BOUND];

	  if (bytes_left < buffer_size)
	    {
	      buffer_size = bytes_left;
	      status = buffer_size % BLOCKSIZE;
	      if (status)
		memset (start->buffer + bytes_left, 0, BLOCKSIZE - status);
	    }

	  status = safe_read (handle, start->buffer, buffer_size);
	  if (status == SAFE_READ_ERROR)
	    read_fatal_details (file_name, stat_data.st_size - bytes_left,
				buffer_size);
	  if (status == 0)
	    FATAL_ERROR ((0, 0,
			  ngettext ("%s: File shrank by %s byte",
				    "%s: File shrank by %s bytes",
				    bytes_left),
			  quotearg_colon (file_name),
			  STRINGIFY_BIGINT (bytes_left, buf)));

	  bytes_left -= status;

	  set_next_block_after (start + (status - 1) / BLOCKSIZE);
	}
    }

  if (close (handle) != 0)
    close_error (file_name);
}
コード例 #3
0
ファイル: incremen.c プロジェクト: jelaas/bifrost-build
static void
get_gnu_dumpdir (struct tar_stat_info *stat_info)
{
  size_t size;
  size_t copied;
  union block *data_block;
  char *to;
  char *archive_dir;

  size = stat_info->stat.st_size;

  archive_dir = xmalloc (size);
  to = archive_dir;

  set_next_block_after (current_header);
  mv_begin (stat_info);

  for (; size > 0; size -= copied)
    {
      mv_size_left (size);
      data_block = find_next_block ();
      if (!data_block)
	ERROR ((1, 0, _("Unexpected EOF in archive")));
      copied = available_space_after (data_block);
      if (copied > size)
	copied = size;
      memcpy (to, data_block->buffer, copied);
      to += copied;
      set_next_block_after ((union block *)
			    (data_block->buffer + copied - 1));
    }

  mv_end ();

  stat_info->dumpdir = archive_dir;
  stat_info->skipped = true; /* For skip_member() and friends
				to work correctly */
}
コード例 #4
0
ファイル: incremen.c プロジェクト: pinard/paxutils
void
incremental_restore (int skipcrud)
{
  char *current_dir;
  char *archive_dir;
  struct accumulator *accumulator;
  char *p;
  DIR *dirp;
  struct dirent *d;
  char *cur, *arc;
  long size;
  size_t size_to_copy;
  union block *data_block;
  char *to;

#define CURRENT_FILE_NAME (skipcrud + current.name)

  dirp = opendir (CURRENT_FILE_NAME);

  if (!dirp)
    {
      /* The directory doesn't exist now.  It'll be created.  In any
	 case, we don't have to delete any files out of it.  */

      skip_file (current.stat.st_size);
      return;
    }

  accumulator = new_accumulator ();
  while (d = readdir (dirp), d)
    {
      if (is_dot_or_dotdot (d->d_name))
	continue;

      add_to_accumulator (accumulator, d->d_name, NAMLEN (d) + 1);
    }
  closedir (dirp);
  add_to_accumulator (accumulator, "", (size_t) 1);

  current_dir = get_accumulator (accumulator);
  archive_dir = (char *) xmalloc ((size_t) current.stat.st_size);
  to = archive_dir;
  for (size = current.stat.st_size; size > 0; size -= size_to_copy)
    {
      data_block = find_next_block ();
      if (!data_block)
	{
	  ERROR ((0, 0, _("Unexpected end of file in archive")));
	  break;		/* FIXME: What happens then?  */
	}
      size_to_copy = available_space_after (data_block);
      if (size_to_copy > size)
	size_to_copy = size;
      memcpy (to, data_block->buffer, size_to_copy);
      to += size_to_copy;
      set_next_block_after ((union block *)
			    (data_block->buffer + size_to_copy - 1));
    }

  for (cur = current_dir; *cur; cur += strlen (cur) + 1)
    {
      for (arc = archive_dir; *arc; arc += strlen (arc) + 1)
	{
	  arc++;
	  if (!strcmp (arc, cur))
	    break;
	}
      if (*arc == '\0')
	{
	  p = concat_with_slash (CURRENT_FILE_NAME, cur);
	  if (interactive_option && !confirm (_("delete %s?"), p))
	    {
	      free (p);
	      continue;
	    }
	  if (verbose_option)
	    {
	      if (checkpoint_option)
		flush_progress_dots ();
	      fprintf (stdlis, _("%s: Deleting %s\n"), program_name, p);
	    }
	  if (!remove_any_file (p, true))
	    ERROR ((0, errno, _("Error while deleting %s"), p));
	  free (p);
	}

    }
  delete_accumulator (accumulator);
  free (archive_dir);

#undef CURRENT_FILE_NAME
}
コード例 #5
0
ファイル: list.c プロジェクト: BackupTheBerlios/samqfs
enum read_header
read_header (void)
{
  int i;
  long unsigned_sum;		/* the POSIX one :-) */
  long signed_sum;		/* the Sun one :-( */
  long recorded_sum;
  char *p;
  union block *header;
  char **longp;
  char *bp;
  union block *data_block;
  long long size, written;
  static char *next_long_name, *next_long_link;

  while (1)
    {
      header = find_next_block ();
      current_header = header;
      if (!header)
	return HEADER_END_OF_FILE;

      recorded_sum
	= from_oct (sizeof header->header.chksum, header->header.chksum);

      unsigned_sum = 0;
      signed_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.  */

	  unsigned_sum += 0xFF & *p;
	  signed_sum += *p++;
	}

      /* Adjust checksum to count the "chksum" field as blanks.  */

      for (i = sizeof (header->header.chksum); --i >= 0;)
	{
	  unsigned_sum -= 0xFF & header->header.chksum[i];
	  signed_sum -= header->header.chksum[i];
	}
      unsigned_sum += ' ' * sizeof header->header.chksum;
      signed_sum += ' ' * sizeof header->header.chksum;

      if (unsigned_sum == sizeof header->header.chksum * ' ')
	{
	  /* This is a zeroed block...whole block is 0's except for the
	     blanks we faked for the checksum field.  */

	  return HEADER_ZERO_BLOCK;
	}

      if (unsigned_sum != recorded_sum && signed_sum != recorded_sum)
	return HEADER_FAILURE;

      /* Good block.  Decode file size and return.  */

      if (header->header.typeflag == LNKTYPE)
	current_stat.st_size = 0;	/* links 0 size on tape */
      else
	current_stat.st_size = llfrom_str (sizeof header->header.size, header->header.size);

      header->header.name[NAME_FIELD_SIZE - 1] = '\0';
      if (header->header.typeflag == GNUTYPE_LONGNAME
	  || header->header.typeflag == GNUTYPE_LONGLINK)
	{
	  longp = ((header->header.typeflag == GNUTYPE_LONGNAME)
		   ? &next_long_name
		   : &next_long_link);

	  set_next_block_after (header);
	  if (*longp)
	    free (*longp);
	  bp = *longp = (char *) xmalloc ((size_t) current_stat.st_size);

	  for (size = current_stat.st_size; size > 0; size -= written)
	    {
	      data_block = find_next_block ();
	      if (data_block == NULL)
		{
		  ERROR ((0, 0, _("Unexpected EOF on archive file")));
		  break;
		}
	      written = available_space_after (data_block);
	      if (written > size)
		written = size;

	      memcpy (bp, data_block->buffer, (size_t) written);
	      bp += written;
	      set_next_block_after ((union block *)
				    (data_block->buffer + written - 1));
	    }

	  /* Loop!  */

	}
      else
	{
	  assign_string (&current_file_name,
			 (next_long_name ? next_long_name
			  : current_header->header.name));
	  assign_string (&current_link_name,
			 (next_long_link ? next_long_link
			  : current_header->header.linkname));
	  next_long_link = next_long_name = 0;
	  return HEADER_SUCCESS;
	}
    }
}
コード例 #6
0
ファイル: list.c プロジェクト: BackupTheBerlios/samqfs
void
list_archive (void)
{
  int isextended = 0;		/* to remember if current_header is extended */

  /* Print the header block.  */

  if (verbose_option)
    {
      if (verbose_option > 1)
	decode_header (current_header, &current_stat, &current_format, 0);
      print_header ();
    }

  if (incremental_option && current_header->header.typeflag == GNUTYPE_DUMPDIR)
    {
      size_t size, written, check;
      union block *data_block;

      set_next_block_after (current_header);
      if (multi_volume_option)
	{
	  assign_string (&save_name, current_file_name);
	  save_totsize = current_stat.st_size;
	}
      for (size = current_stat.st_size; size > 0; size -= written)
	{
	  if (multi_volume_option)
	    save_sizeleft = size;
	  data_block = find_next_block ();
	  if (!data_block)
	    {
	      ERROR ((0, 0, _("EOF in archive file")));
	      break;		/* FIXME: What happens, then?  */
	    }
	  written = available_space_after (data_block);
	  if (written > size)
	    written = size;
	  errno = 0;		/* FIXME: errno should be read-only */
	  check = fwrite (data_block->buffer, sizeof (char), written, stdlis);
	  set_next_block_after ((union block *)
				(data_block->buffer + written - 1));
	  if (check != written)
	    {
	      ERROR ((0, errno, _("Only wrote %lu of %lu bytes to file %s"),
		      (unsigned long) check, (unsigned long) written, current_file_name));
	      skip_file ((long long) (size - written));
	      break;
	    }
	}
      if (multi_volume_option)
	assign_string (&save_name, NULL);
      fputc ('\n', stdlis);
      fflush (stdlis);
      return;

    }

  /* Check to see if we have an extended header to skip over also.  */

  if (current_header->oldgnu_header.isextended)
    isextended = 1;

  /* Skip past the header in the archive.  */

  set_next_block_after (current_header);

  /* If we needed to skip any extended headers, do so now, by reading
     extended headers and skipping past them in the archive.  */

  if (isextended)
    {
#if 0
      union block *exhdr;

      while (1)
	{
	  exhdr = find_next_block ();

	  if (!exhdr->sparse_header.isextended)
	    {
	      set_next_block_after (exhdr);
	      break;
	    }
	  set_next_block_after (exhdr);
	}
#endif
      skip_extended_headers ();
    }

  if (multi_volume_option)
    assign_string (&save_name, current_file_name);

  /* Skip to the next header on the archive.  */

  skip_file ((long long) current_stat.st_size);

  if (multi_volume_option)
    assign_string (&save_name, NULL);
}
コード例 #7
0
ファイル: list.c プロジェクト: pinard/paxutils
void
list_archive (void)
{
  bool is_extended = false;	/* to remember if current.header is extended */

  /* Print the header block.  */

  if (verbose_option)
    {
      if (verbose_option_count > 1)
	decode_header (&current, false);
      print_header (&current);
    }

  if (incremental_option && current.block->header.typeflag == GNUTAR_DUMPDIR)
    {
      size_t size;
      size_t size_to_write;
      ssize_t size_written;
      union block *data_block;

      set_next_block_after (current.block);
      if (multi_volume_option)
	{
	  assign_string (&save_name, current.name);
	  save_totsize = current.stat.st_size;
	}
      for (size = current.stat.st_size; size > 0; size -= size_to_write)
	{
	  if (multi_volume_option)
	    save_sizeleft = size;
	  data_block = find_next_block ();
	  if (!data_block)
	    {
	      ERROR ((0, 0, _("Unexpected end of file in archive")));
	      break;		/* FIXME: What happens, then?  */
	    }
	  size_to_write = available_space_after (data_block);
	  if (size_to_write > size)
	    size_to_write = size;
	  errno = 0;		/* FIXME: errno should be read-only */
	  size_written = fwrite (data_block->buffer, 1, size_to_write, stdlis);
	  set_next_block_after ((union block *)
				(data_block->buffer + size_to_write - 1));
	  if (size_written != size_to_write)
	    {
	      /* FIXME: size_written may be negative, here!  */
	      ERROR ((0, errno, _("Only wrote %lu of %lu bytes to file %s"),
		      (unsigned long) size_written,
		      (unsigned long) size_to_write, current.name));
	      skip_file ((off_t) (size - size_to_write));
	      break;
	    }
	}
      if (multi_volume_option)
	assign_string (&save_name, NULL);
      fputc ('\n', stdlis);
      fflush (stdlis);
      return;
    }

  /* Check to see if we have an extended header to skip over also.  */

  if (current.block->gnutar_header.isextended)
    is_extended = true;

  /* Skip past the header in the archive.  */

  set_next_block_after (current.block);

  /* If we needed to skip any extended headers, do so now, by reading
     extended headers and skipping past them in the archive.  */

  if (is_extended)
    {
#if 0
      union block *exhdr;

      while (true)
	{
	  exhdr = find_next_block ();

	  if (!exhdr->sparse_header.isextended)
	    {
	      set_next_block_after (exhdr);
	      break;
	    }
	  set_next_block_after (exhdr);
	}
#endif
      skip_extended_headers ();
    }

  if (multi_volume_option)
    assign_string (&save_name, current.name);

  /* Skip to the next header on the archive.  */

  skip_file (current.stat.st_size);

  if (multi_volume_option)
    assign_string (&save_name, NULL);
}
コード例 #8
0
ファイル: mangle.c プロジェクト: pinard/paxutils
void
extract_mangle (void)
{
  int size = current.stat.st_size;
  char *buffer = xmalloc ((size_t) (size + 1));
  char *copy = buffer;
  char *cursor = buffer;

  buffer[size] = '\0';

  while (size > 0)
    {
      union block *block = find_next_block ();
      size_t size_to_copy;

      if (!block)
	{
	  ERROR ((0, 0, _("Unexpected end of file in mangled file names")));
	  return;
	}
      size_to_copy = available_space_after (block);
      if (size_to_copy > size)
	size_to_copy = size;
      memcpy (copy, block->buffer, size_to_copy);
      copy += size_to_copy;
      size -= size_to_copy;
      set_next_block_after
	((union block *) (block->buffer + size_to_copy - 1));
    }

  while (*cursor)
    {
      char *next_cursor;
      char *name;
      char *name_end;

      next_cursor = strchr (cursor, '\n');
      *next_cursor++ = '\0';

      if (!strncmp (cursor, "Rename ", 7))
	{

	  name = cursor + 7;
	  name_end = strchr (name, ' ');
	  while (strncmp (name_end, " to ", 4))
	    {
	      name_end++;
	      name_end = strchr (name_end, ' ');
	    }
	  *name_end = '\0';
	  if (next_cursor[-2] == '/')
	    next_cursor[-2] = '\0';
	  unquote_string (name_end + 4);
	  if (rename (name, name_end + 4))
	    ERROR ((0, errno, _("Cannot rename %s to %s"), name, name_end + 4));
	  else if (verbose_option)
	    WARN ((0, 0, _("Renamed %s to %s"), name, name_end + 4));
	}
#ifdef S_ISLNK
      else if (!strncmp (cursor, "Symlink ", 8))
	{
	  name = cursor + 8;
	  name_end = strchr (name, ' ');
	  while (strncmp (name_end, " to ", 4))
	    {
	      name_end++;
	      name_end = strchr (name_end, ' ');
	    }
	  *name_end = '\0';
	  unquote_string (name);
	  unquote_string (name_end + 4);
	  if (symlink (name, name_end + 4)
	      && (unlink (name_end + 4) || symlink (name, name_end + 4)))
	    ERROR ((0, errno, _("Cannot symlink %s to %s"),
		    name, name_end + 4));
	  else if (verbose_option)
	    WARN ((0, 0, _("Symlinked %s to %s"), name, name_end + 4));
	}
#endif
      else
	ERROR ((0, 0, _("Unknown demangling command %s"), cursor));

      cursor = next_cursor;
    }
}
コード例 #9
0
int shfs_arch_write_flush(shfs_arch_t *arch, size_t buffer_level)
{
  ssize_t status;
  union block *header;
  char *copy_ptr;
  size_t copy_size;
  size_t bufsize;
  struct bufmap *map;

  status = shfs_arch_buffer_write(arch->archive, record_start->buffer, arch->record_size);
  if (status != arch->record_size && !multi_volume_option)
{}
  else
    {
      if (status)
        arch->records_written++;
      bytes_written += status;
    }

  if (status == arch->record_size)
    {
      return;
    }

  map = bufmap_locate (status);



  tar_stat_destroy (&dummy);

  //increase_volume_number ();
  prev_written += bytes_written;
  bytes_written = 0;

  copy_ptr = record_start->buffer + status;
  copy_size = buffer_level - status;

  /* Switch to the next buffer */
  arch->arch_record_index = !arch->arch_record_index;
  shfs_arch_init_buffer(arch);

  inhibit_map = 1;

  tar_stat_destroy (&dummy);

  header = shfs_arch_buffer_next(arch);
  bufmap_reset (map, header - record_start);
  bufsize = available_space_after (header);
  inhibit_map = 0;
  while (bufsize < copy_size)
    {
      memcpy (header->buffer, copy_ptr, bufsize);
      copy_ptr += bufsize;
      copy_size -= bufsize;
      shfs_arch_set_next_block_after(arch, header + (bufsize - 1) / BLOCKSIZE);
      header = shfs_arch_buffer_next(arch);
      bufsize = available_space_after (header);
    }
  memcpy (header->buffer, copy_ptr, copy_size);
  memset (header->buffer + copy_size, 0, bufsize - copy_size);
  shfs_arch_set_next_block_after(arch, header + (copy_size - 1) / BLOCKSIZE);
  shfs_arch_buffer_next(arch);

  return (0);
}