예제 #1
0
파일: copyout.c 프로젝트: pinard/paxutils
static void
tape_clear_rest_of_block (int handle)
{
  while (output_buffer_remaining_size < io_block_size)
    {
      if ((io_block_size - output_buffer_remaining_size) > BLOCKSIZE)
	tape_buffered_write (zero_block, handle, BLOCKSIZE);
      else
	tape_buffered_write (zero_block, handle,
			     io_block_size - output_buffer_remaining_size);
    }
}
예제 #2
0
파일: copyout.c 프로젝트: pinard/paxutils
void
tape_pad_output (int handle, int offset)
{
  int pad;

  switch (archive_format)
    {
    case HPUX_OLD_ASCII_FORMAT:
    case OLD_ASCII_FORMAT:
      pad = 0;
      break;

    default:
      pad = PADDING (offset, 2);
      break;

    case CRC_ASCII_FORMAT:
    case NEW_ASCII_FORMAT:
      pad = PADDING (offset, 4);
      break;

    case GNUTAR_FORMAT:
    case POSIX_FORMAT:
    case V7_FORMAT:
      pad = PADDING (offset, BLOCKSIZE);
      break;
    }

  if (pad != 0)
    tape_buffered_write (zero_block, handle, pad);
}
예제 #3
0
파일: tar.c 프로젝트: wcatykid/GeoShader
void
write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des)
{
  int name_len;
  union tar_record tar_rec;
  struct tar_header *tar_hdr = (struct tar_header *) &tar_rec;

  memset (&tar_rec, 0, sizeof tar_rec);

  /* process_copy_out must ensure that file_hdr->c_name is short enough,
     or we will lose here.  */

  name_len = strlen (file_hdr->c_name);
  if (name_len <= TARNAMESIZE)
    {
      strncpy (tar_hdr->name, file_hdr->c_name, name_len);
    }
  else
    {
      /* Fit as much as we can into `name', the rest into `prefix'.  */
      int prefix_len = split_long_name (file_hdr->c_name, name_len);

      strncpy (tar_hdr->prefix, file_hdr->c_name, prefix_len);
      strncpy (tar_hdr->name, file_hdr->c_name + prefix_len + 1,
	       name_len - prefix_len - 1);
    }

  /* Ustar standard (POSIX.1-1988) requires the mode to contain only 3 octal
     digits */
  to_oct (file_hdr->c_mode & MODE_ALL, 8, tar_hdr->mode);
  to_oct (file_hdr->c_uid, 8, tar_hdr->uid);
  to_oct (file_hdr->c_gid, 8, tar_hdr->gid);
  to_oct (file_hdr->c_filesize, 12, tar_hdr->size);
  to_oct (file_hdr->c_mtime, 12, tar_hdr->mtime);

  switch (file_hdr->c_mode & CP_IFMT)
    {
    case CP_IFREG:
      if (file_hdr->c_tar_linkname)
	{
	  /* process_copy_out makes sure that c_tar_linkname is shorter
	     than TARLINKNAMESIZE.  */
	  strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname,
		   TARLINKNAMESIZE);
	  tar_hdr->typeflag = LNKTYPE;
	  to_oct (0, 12, tar_hdr->size);
	}
      else
	tar_hdr->typeflag = REGTYPE;
      break;
    case CP_IFDIR:
      tar_hdr->typeflag = DIRTYPE;
      break;
    case CP_IFCHR:
      tar_hdr->typeflag = CHRTYPE;
      break;
    case CP_IFBLK:
      tar_hdr->typeflag = BLKTYPE;
      break;
#ifdef CP_IFIFO
    case CP_IFIFO:
      tar_hdr->typeflag = FIFOTYPE;
      break;
#endif /* CP_IFIFO */
#ifdef CP_IFLNK
    case CP_IFLNK:
      tar_hdr->typeflag = SYMTYPE;
      /* process_copy_out makes sure that c_tar_linkname is shorter
	 than TARLINKNAMESIZE.  */
      strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname,
	       TARLINKNAMESIZE);
      to_oct (0, 12, tar_hdr->size);
      break;
#endif /* CP_IFLNK */
    }

  if (archive_format == arf_ustar)
    {
      char *name;

      strncpy (tar_hdr->magic, TMAGIC, TMAGLEN);
      strncpy (tar_hdr->version, TVERSION, TVERSLEN);

      name = getuser (file_hdr->c_uid);
      if (name)
	strcpy (tar_hdr->uname, name);
      name = getgroup (file_hdr->c_gid);
      if (name)
	strcpy (tar_hdr->gname, name);

      to_oct (file_hdr->c_rdev_maj, 8, tar_hdr->devmajor);
      to_oct (file_hdr->c_rdev_min, 8, tar_hdr->devminor);
    }

  to_oct (tar_checksum (tar_hdr), 8, tar_hdr->chksum);

  tape_buffered_write ((char *) &tar_rec, out_des, TARRECORDSIZE);
}
예제 #4
0
파일: copyout.c 프로젝트: pinard/paxutils
static void
copy_out_one_file (int handle, dynamic_string *input_name,
		   struct stat *stat_info)
{
  struct new_cpio_header header;
  int input_handle;		/* source file descriptor */
  char *p;

  /* Set values in output header.  */
  header.c_magic = 070707;
  header.c_dev_maj = major (stat_info->st_dev);
  header.c_dev_min = minor (stat_info->st_dev);
  header.c_ino = stat_info->st_ino;
#if DOSWIN
  /* DJGPP doesn't support st_rdev.  Repair that.  */
  stat_info->st_rdev = stat_info->st_dev;
#endif
  /* For POSIX systems that don't define the S_IF macros, we can't assume that
     S_ISfoo means the standard Unix S_IFfoo bit(s) are set.  So do it
     manually, with a different name.  Bleah.  */
  header.c_mode = (stat_info->st_mode & 07777);
  if (S_ISREG (stat_info->st_mode))
    header.c_mode |= CP_IFREG;
  else if (S_ISDIR (stat_info->st_mode))
    header.c_mode |= CP_IFDIR;
#ifdef S_ISBLK
  else if (S_ISBLK (stat_info->st_mode))
    header.c_mode |= CP_IFBLK;
#endif
#ifdef S_ISCHR
  else if (S_ISCHR (stat_info->st_mode))
    header.c_mode |= CP_IFCHR;
#endif
#ifdef S_ISFIFO
  else if (S_ISFIFO (stat_info->st_mode))
    header.c_mode |= CP_IFIFO;
#endif
#ifdef S_ISLNK
  else if (S_ISLNK (stat_info->st_mode))
    header.c_mode |= CP_IFLNK;
#endif
#ifdef S_ISSOCK
  else if (S_ISSOCK (stat_info->st_mode))
    header.c_mode |= CP_IFSOCK;
#endif
#ifdef S_ISNWK
  else if (S_ISNWK (stat_info->st_mode))
    header.c_mode |= CP_IFNWK;
#endif
  header.c_uid = stat_info->st_uid;
  header.c_gid = stat_info->st_gid;
  header.c_nlink = stat_info->st_nlink;
  header.c_rdev_maj = major (stat_info->st_rdev);
  header.c_rdev_min = minor (stat_info->st_rdev);
  header.c_mtime = (stat_info->st_mtime < 0) ? 0 :stat_info->st_mtime;
  header.c_filesize = stat_info->st_size;
  header.c_chksum = 0;
  header.c_tar_linkname = NULL;

  /* Handle HPUX CDF files.  */
  possibly_munge_cdf_directory_name (input_name->string, &header);

  if ((*name_too_long) (header.c_name))
    {
      error (0, 0, _("%s: file name too long"), header.c_name);
      return;
    }

  /* FIXME: there is a memory leak here, between this and the HPUX stuff
     above.  */
  header.c_name = possibly_rename_file (header.c_name);

  /* Copy the named file to the output.  */
  switch (header.c_mode & CP_IFMT)
    {
    case CP_IFREG:
#ifndef __MSDOS__
      if (archive_format == V7_FORMAT || archive_format == POSIX_FORMAT
	  || archive_format == GNUTAR_FORMAT)
	{
	  char *otherfile;
	  if ((otherfile = find_inode_file (header.c_ino,
					    header.c_dev_maj,
					    header.c_dev_min)))
	    {
	      header.c_tar_linkname = otherfile;
	      (*header_writer) (&header, handle);
	      break;
	    }
	}
      if ((archive_format == NEW_ASCII_FORMAT
	   || archive_format == CRC_ASCII_FORMAT)
	  && header.c_nlink > 1)
	if (last_link (&header) )
	  writeout_other_defers (&header, handle);
	else
	  {
	    add_link_defer (&header);
	    break;
	  }
#endif
      input_handle = open (input_name->string,
			  O_RDONLY | O_BINARY, 0);
      if (input_handle < 0)
	{
	  error (0, errno, "%s", input_name->string);
	  return;
	}

      if (archive_format == CRC_ASCII_FORMAT)
	header.c_chksum = read_for_checksum (input_handle,
					     header.c_filesize,
					     input_name->string);

      (*header_writer) (&header, handle);
      copy_files_disk_to_tape (input_handle, handle,
			       header.c_filesize,
			       input_name->string);

#ifndef __MSDOS__
      if (archive_format == V7_FORMAT
	  || archive_format == POSIX_FORMAT
	  || archive_format == GNUTAR_FORMAT)
	add_inode (header.c_ino, header.c_name,
		   header.c_dev_maj, header.c_dev_min);
#endif

      tape_pad_output (handle, header.c_filesize);

      if (close (input_handle) < 0)
	error (0, errno, "%s", input_name->string);
      if (reset_access_time_option)
	{
	  struct utimbuf times;

	  /* Initialize this in case it has members we don't
	     know to set.  */
	  memset (&times, 0, sizeof (struct utimbuf));
	  times.actime = stat_info->st_atime;
	  times.modtime = stat_info->st_mtime;
	  /* Silently ignore EROFS because reading the file won't have upset
	     its timestamp if it's on a read-only filesystem.  */
	  if (utime (header.c_name, &times) < 0 && errno != EROFS)
	    error (0, errno, _("%s: error resetting file access time"),
		   header.c_name);
	}
      break;

    case CP_IFDIR:
      header.c_filesize = 0;
      (*header_writer) (&header, handle);
      break;

#ifndef __MSDOS__
    case CP_IFCHR:
    case CP_IFBLK:
#ifdef CP_IFSOCK
    case CP_IFSOCK:
#endif
#ifdef CP_IFIFO
    case CP_IFIFO:
#endif
      if (archive_format == V7_FORMAT)
	{
	  error (0, 0, _("%s not dumped: not a regular file"), header.c_name);
	  return;
	}
      else if (archive_format == POSIX_FORMAT
	       || archive_format == GNUTAR_FORMAT)
	{
	  char *otherfile
	    = find_inode_file (header.c_ino,
			       header.c_dev_maj, header.c_dev_min);

	  if (otherfile)
	    {
	      /* This file is linked to another file already in the archive,
		 so write it out as a hard link.  */
	      header.c_mode = (stat_info->st_mode & 07777);
	      header.c_mode |= CP_IFREG;
	      header.c_tar_linkname = otherfile;
	      (*header_writer) (&header, handle);
	      break;
	    }
	  add_inode (header.c_ino, header.c_name,
		     header.c_dev_maj, header.c_dev_min);
	}
      header.c_filesize = 0;
      (*header_writer) (&header, handle);
      break;
#endif

#ifdef CP_IFLNK
    case CP_IFLNK:
      {
	char *link_name = (char *) xmalloc (stat_info->st_size + 1);
	int link_size = readlink (input_name->string, link_name,
				  stat_info->st_size);

	if (link_size < 0)
	  {
	    error (0, errno, "%s", input_name->string);
	    free (link_name);
	    return;
	  }
	header.c_filesize = link_size;
	if (archive_format == V7_FORMAT
	    || archive_format == POSIX_FORMAT
	    || archive_format == GNUTAR_FORMAT)
	  {
	    /* FIXME: tar can do long symlinks.  */
	    if (link_size + 1 > 100)
	      error (0, 0, _("%s: symbolic link too long"),
		     header.c_name);
	    else
	      {
		link_name[link_size] = '\0';
		header.c_tar_linkname = link_name;
		(*header_writer) (&header, handle);
	      }
	  }
	else
	  {
	    (*header_writer) (&header, handle);
	    tape_buffered_write (link_name, handle, link_size);
	    tape_pad_output (handle, link_size);
	  }
	free (link_name);
      }
      break;
#endif

    default:
      error (0, 0, _("%s: unknown file type"), input_name->string);
    }

  /* FIXME shouldn't do this for each file.  Should maintain a dstring
     somewhere.  */
  free (header.c_name);
  header.c_name = NULL;
}