Example #1
0
File: hha.c Project: maksverver/hha
int main(int argc, char *argv[])
{
    assert(sizeof(Header)     == 16);
    assert(sizeof(IndexEntry) == 24);

    parse_args(argc, argv);

    switch (arg_mode)
    {
    case LIST:
        open_archive(arg_archive);
        process_header();
        list_entries();
        close_archive();
        break;

    case EXTRACT:
        open_archive(arg_archive);
        process_header();
        extract_entries();
        close_archive();
        break;

    case CREATE:
        create_archive(arg_archive, (const char**)arg_files_begin,
                                    (const char**)arg_files_end, arg_com);
        break;
    }

    return 0;
}
Example #2
0
// closes (and optionally compresses) the archive files.  Clears file
// pointers to indicate that files are not open.
//
void close_all_archives() {
    if (wu_stream) fprintf(wu_stream, "</archive>\n");
    if (re_stream) fprintf(re_stream, "</archive>\n");
    close_archive(WU_FILENAME_PREFIX, wu_stream);
    close_archive(RESULT_FILENAME_PREFIX, re_stream);
    close_archive(RESULT_INDEX_FILENAME_PREFIX, re_index_stream);
    close_archive(WU_INDEX_FILENAME_PREFIX, wu_index_stream);
    log_messages.printf(MSG_NORMAL,
        "Closed archive files with %d workunits\n",
        wu_stored_in_file
    );

    return;
}
Example #3
0
int
build(void)
{
	CF cf;
	int afd, tfd;
	int current_mid;
	off_t size;

	current_mid = -1;
	afd = open_archive(O_RDWR);
	fp = fdopen(afd, "r+");
	tfd = tmp();

	SETCF(afd, archive, tfd, tname, RPAD|WPAD);

	/* Read through the archive, creating list of symbols. */
	symcnt = tsymlen = 0;
	pnext = &rhead;
	while(get_arobj(afd)) {
		int new_mid;

		if (!strcmp(chdr.name, RANLIBMAG)) {
			skip_arobj(afd);
			continue;
		}
		new_mid = rexec(afd, tfd);
		if (new_mid != -1) {
			if (current_mid == -1)
				current_mid = new_mid;
			else if (new_mid != current_mid)
				errx(1, "Mixed object format archive: %d / %d", 
					new_mid, current_mid);
		}
		put_arobj(&cf, (struct stat *)NULL);
	}
	*pnext = NULL;

	/* Create the symbol table.  Endianess the same as last mid seen */
	symobj(current_mid);

	/* Copy the saved objects into the archive. */
	size = lseek(tfd, (off_t)0, SEEK_CUR);
	(void)lseek(tfd, (off_t)0, SEEK_SET);
	SETCF(tfd, tname, afd, archive, NOPAD);
	copy_ar(&cf, size);
	(void)ftruncate(afd, lseek(afd, (off_t)0, SEEK_CUR));
	(void)close(tfd);

	/* Set the time. */
	settime(afd);
	close_archive(afd);
	return(0);
}
Example #4
0
void
create_archive()
{
	register char	*p;

	open_archive(0);		/* Open for writing */

	while (p = name_next()) {
		dump_file(p, -1);
	}

	write_eot();
	close_archive();
	name_close();
}		
Example #5
0
int touch()
{
	int afd;

	afd = open_archive(O_RDWR);

	if (!get_arobj(afd) ||
	    strncmp(RANLIBMAG, chdr.name, sizeof(RANLIBMAG) - 1)) {
		(void)fprintf(stderr,
		    "ranlib: %s: no symbol table.\n", archive);
		return(1);
	}
	settime(afd);
	close_archive(afd);
	return(0);
}
Example #6
0
/*
 * append --
 *	Append files to the archive - modifies original archive or creates
 *	a new archive if named archive does not exist.
 */
int
append(char **argv)
{
	struct stat sb;
	CF cf;
	FILE *afp;
	char *file;
	int eval, ntsz;

	afp = open_archive(O_CREAT|O_RDWR);
	if (fseeko(afp, 0, SEEK_END) == (off_t)-1)
		err(1, "lseek: %s", archive);

	/* Read from disk, write to an archive; pad on write. */
	SETCF(0, 0, afp, archive, 0);

	if (options & AR_C) {
		/* ain't no need for a.out but a small price to pay */
		if ((ntsz = mknametab(argv)) == 0)
			;

		/* build and write the symdef, also need a mid! */
		/* mkranlib(argv);
		if (mid & ELF) */ {
			options |= AR_S5;
			/* write out the nametab */
			if (ntsz)
				put_nametab(&cf);
		}
	}

	for (eval = 0; (file = *argv++);) {
		if (!(cf.rfp = fopen(file, "r"))) {
			warn("fopen: %s", file);
			eval = 1;
			continue;
		}
		if (options & AR_V)
			(void)printf("q - %s\n", file);
		cf.rname = file;
		put_arobj(&cf, &sb);
		(void)fclose(cf.rfp);
	}
	close_archive(afp);
	return (eval);
}
Example #7
0
int
touch(void)
{
	FILE *afp;

	afp = open_archive(O_RDWR);

	if (!get_arobj(afp) ||
	    (strncmp(RANLIBMAG, chdr.name, sizeof(RANLIBMAG) - 1) &&
	     strncmp(RANLIBMAG2, chdr.name, sizeof(RANLIBMAG2) - 1))) {
		warnx("%s: no symbol table.", archive);
		return(1);
	}
	settime(afp);
	close_archive(afp);
	return(0);
}
Example #8
0
File: print.c Project: McIkye/tools
/*
 * print --
 *	Prints archive members on stdout - if member names given only
 *	print those members, otherwise print all members.
 */
int
print(char **argv)
{
	off_t size;
	CF cf;
	FILE *afp;
	char *file;
	int all;

	afp = open_archive(O_RDONLY);

	/* Read from an archive, write to stdout; pad on read. */
	SETCF(afp, archive, stdout, "stdout", 0);
	for (all = !*argv; get_arobj(afp);) {
		if (!strncmp(chdr.name, AR_NAMTAB, sizeof(AR_NAMTAB) - 1)) {
			size = ftello(afp);
			get_namtab(afp);
			(void)fseeko(afp, size, SEEK_SET);
			skip_arobj(afp);
			continue;
		}

		if (all)
			file = chdr.name;
		else if (!(file = files(argv))) {
			skip_arobj(afp);
			continue;
		}
		if (options & AR_V) {
			(void)printf("\n<%s>\n\n", file);
			(void)fflush(stdout);
		}
		copy_ar(&cf, chdr.size);
		if (!all && !*argv)
			break;
	}
	close_archive(afp);

	if (*argv) {
		orphans(argv);
		return (1);
	}
	return (0);
}
Example #9
0
File: create.c Project: npe9/sprite
void
create_archive()
{
	register char	*p;
	char *name_from_list();

	open_archive(0);		/* Open for writing */

	if(f_gnudump) {
		char buf[MAXNAMLEN],*q,*bufp;

		collect_and_sort_names();

		while(p=name_from_list())
			dump_file(p,-1);
		/* if(!f_dironly) { */
			blank_name_list();
			while(p=name_from_list()) {
				strcpy(buf,p);
				if(p[strlen(p)-1]!='/')
					strcat(buf,"/");
				bufp=buf+strlen(buf);
				for(q=gnu_list_name->dir_contents;*q;q+=strlen(q)+1) {
					if(*q=='Y') {
						strcpy(bufp,q+1);
						dump_file(buf,-1);
					}
				}
			}
		/* } */

	} else {
		while (p = name_next(1)) {
			dump_file(p, -1);
		}
	}

	write_eot();
	close_archive();
	name_close();
}
Example #10
0
build()
{
	CF cf;
	int afd, tfd;
	off_t size;

	afd = open_archive(O_RDWR);
	fp = fdopen(afd, "r+");
	tfd = tmp();

	SETCF(afd, archive, tfd, tname, RPAD|WPAD);

	/* Read through the archive, creating list of symbols. */
	pnext = &rhead;
	while(get_arobj(afd)) {
		if (!strcmp(chdr.name, RANLIBMAG)) {
			skip_arobj(afd);
			continue;
		}
		rexec(afd, tfd);
		put_arobj(&cf, (struct stat *)NULL);
	}
	*pnext = NULL;

	/* Create the symbol table. */
	symobj();

	/* Copy the saved objects into the archive. */
	size = lseek(tfd, (off_t)0, SEEK_CUR);
	(void)lseek(tfd, (off_t)0, SEEK_SET);
	SETCF(tfd, tname, afd, archive, RPAD|WPAD);
	copy_ar(&cf, size);
	(void)ftruncate(afd, lseek(afd, (off_t)0, SEEK_CUR));
	(void)close(tfd);

	/* Set the time. */
	settime(afd);
	close_archive(afd);
	return(0);
}
Example #11
0
static void
enlarge_archive (struct locarhandle *ah, const struct locarhead *head)
{
  struct stat64 st;
  int fd;
  struct locarhead newhead;
  size_t total;
  void *p;
  unsigned int cnt, loccnt;
  struct namehashent *oldnamehashtab;
  struct locrecent *oldlocrectab;
  struct locarhandle new_ah;
  struct oldlocrecent *oldlocrecarray;
  size_t prefix_len = output_prefix ? strlen (output_prefix) : 0;
  char archivefname[prefix_len + sizeof (ARCHIVE_NAME)];
  char fname[prefix_len + sizeof (ARCHIVE_NAME) + sizeof (".XXXXXX") - 1];

  if (output_prefix)
    memcpy (archivefname, output_prefix, prefix_len);
  strcpy (archivefname + prefix_len, ARCHIVE_NAME);
  strcpy (stpcpy (fname, archivefname), ".XXXXXX");

  /* Not all of the old file has to be mapped.  Change this now this
     we will have to access the whole content.  */
  if (fstat64 (ah->fd, &st) != 0)
  enomap:
    error (EXIT_FAILURE, errno, _("cannot map locale archive file"));

  if (st.st_size < ah->reserved)
    ah->addr = mmap64 (ah->addr, st.st_size, PROT_READ | PROT_WRITE,
		       MAP_SHARED | MAP_FIXED, ah->fd, 0);
  else
    {
      munmap (ah->addr, ah->reserved);
      ah->addr = mmap64 (NULL, st.st_size, PROT_READ | PROT_WRITE,
			 MAP_SHARED, ah->fd, 0);
      ah->reserved = st.st_size;
      head = ah->addr;
    }
  if (ah->addr == MAP_FAILED)
    goto enomap;
  ah->mmaped = st.st_size;

  /* Create a temporary file in the correct directory.  */
  fd = mkstemp (fname);
  if (fd == -1)
    error (EXIT_FAILURE, errno, _("cannot create temporary file"));

  /* Copy the existing head information.  */
  newhead = *head;

  /* Create the new archive header.  The sizes of the various tables
     should be double from what is currently used.  */
  newhead.namehash_size = MAX (next_prime (2 * newhead.namehash_used),
			       newhead.namehash_size);
  if (verbose)
    printf ("name: size: %u, used: %d, new: size: %u\n",
	    head->namehash_size, head->namehash_used, newhead.namehash_size);

  newhead.string_offset = (newhead.namehash_offset
			   + (newhead.namehash_size
			      * sizeof (struct namehashent)));
  /* Keep the string table size aligned to 4 bytes, so that
     all the struct { uint32_t } types following are happy.  */
  newhead.string_size = MAX ((2 * newhead.string_used + 3) & -4,
			     newhead.string_size);

  newhead.locrectab_offset = newhead.string_offset + newhead.string_size;
  newhead.locrectab_size = MAX (2 * newhead.locrectab_used,
				newhead.locrectab_size);

  newhead.sumhash_offset = (newhead.locrectab_offset
			    + (newhead.locrectab_size
			       * sizeof (struct locrecent)));
  newhead.sumhash_size = MAX (next_prime (2 * newhead.sumhash_used),
			      newhead.sumhash_size);

  total = (newhead.sumhash_offset
	   + newhead.sumhash_size * sizeof (struct sumhashent));

  /* The new file is empty now.  */
  newhead.namehash_used = 0;
  newhead.string_used = 0;
  newhead.locrectab_used = 0;
  newhead.sumhash_used = 0;

  /* Write out the header and create room for the other data structures.  */
  if (TEMP_FAILURE_RETRY (write (fd, &newhead, sizeof (newhead)))
      != sizeof (newhead))
    {
      int errval = errno;
      unlink (fname);
      error (EXIT_FAILURE, errval, _("cannot initialize archive file"));
    }

  if (ftruncate64 (fd, total) != 0)
    {
      int errval = errno;
      unlink (fname);
      error (EXIT_FAILURE, errval, _("cannot resize archive file"));
    }

  /* To prepare for enlargements of the mmaped area reserve some
     address space.  */
  size_t reserved = RESERVE_MMAP_SIZE;
  int xflags = 0;
  if (total < reserved
      && ((p = mmap64 (NULL, reserved, PROT_NONE, MAP_PRIVATE | MAP_ANON,
		       -1, 0)) != MAP_FAILED))
    xflags = MAP_FIXED;
  else
    {
      p = NULL;
      reserved = total;
    }

  /* Map the header and all the administration data structures.  */
  p = mmap64 (p, total, PROT_READ | PROT_WRITE, MAP_SHARED | xflags, fd, 0);
  if (p == MAP_FAILED)
    {
      int errval = errno;
      unlink (fname);
      error (EXIT_FAILURE, errval, _("cannot map archive header"));
    }

  /* Lock the new file.  */
  if (lockf64 (fd, F_LOCK, total) != 0)
    {
      int errval = errno;
      unlink (fname);
      error (EXIT_FAILURE, errval, _("cannot lock new archive"));
    }

  new_ah.mmaped = total;
  new_ah.addr = p;
  new_ah.fd = fd;
  new_ah.reserved = reserved;

  /* Walk through the hash name hash table to find out what data is
     still referenced and transfer it into the new file.  */
  oldnamehashtab = (struct namehashent *) ((char *) ah->addr
					   + head->namehash_offset);
  oldlocrectab = (struct locrecent *) ((char *) ah->addr
				       + head->locrectab_offset);

  /* Sort the old locrec table in order of data position.  */
  oldlocrecarray = alloca (sizeof (*oldlocrecarray) * head->namehash_size);
  for (cnt = 0, loccnt = 0; cnt < head->namehash_size; ++cnt)
    if (oldnamehashtab[cnt].locrec_offset != 0)
      {
	oldlocrecarray[loccnt].cnt = cnt;
	oldlocrecarray[loccnt++].locrec
	  = (struct locrecent *) ((char *) ah->addr
				  + oldnamehashtab[cnt].locrec_offset);
      }
  qsort (oldlocrecarray, loccnt, sizeof (struct oldlocrecent),
	 oldlocrecentcmp);

  uint32_t last_locrec_offset = 0;
  for (cnt = 0; cnt < loccnt; ++cnt)
    {
      /* Insert this entry in the new hash table.  */
      locale_data_t old_data;
      unsigned int idx;
      struct locrecent *oldlocrec = oldlocrecarray[cnt].locrec;

      for (idx = 0; idx < __LC_LAST; ++idx)
	if (idx != LC_ALL)
	  {
	    old_data[idx].size = oldlocrec->record[idx].len;
	    old_data[idx].addr
	      = ((char *) ah->addr + oldlocrec->record[idx].offset);

	    __md5_buffer (old_data[idx].addr, old_data[idx].size,
			  old_data[idx].sum);
	  }

      if (cnt > 0 && oldlocrecarray[cnt - 1].locrec == oldlocrec)
	{
	  const char *oldname
	    = ((char *) ah->addr
	       + oldnamehashtab[oldlocrecarray[cnt - 1].cnt].name_offset);

	  add_alias (&new_ah,
		     ((char *) ah->addr
		      + oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset),
		     0, oldname, &last_locrec_offset);
	  continue;
	}

      last_locrec_offset =
	add_locale (&new_ah,
		    ((char *) ah->addr
		     + oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset),
		    old_data, 0);
      if (last_locrec_offset == 0)
	error (EXIT_FAILURE, 0, _("cannot extend locale archive file"));
    }

  /* Make the file globally readable.  */
  if (fchmod (fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1)
    {
      int errval = errno;
      unlink (fname);
      error (EXIT_FAILURE, errval,
	     _("cannot change mode of resized locale archive"));
    }

  /* Rename the new file.  */
  if (rename (fname, archivefname) != 0)
    {
      int errval = errno;
      unlink (fname);
      error (EXIT_FAILURE, errval, _("cannot rename new archive"));
    }

  /* Close the old file.  */
  close_archive (ah);

  /* Add the information for the new one.  */
  *ah = new_ah;
}
Example #12
0
int
do_ranlib(void)
{
	CF cf;
	off_t size;
	FILE	*afp, *tfp;
	long	symcnt;			/* symbol count */
	long	tsymlen;		/* total string length */
	int	i, current_mid;

	current_mid = -1;
	afp = open_archive(O_RDWR);
	tfp = tmp();

	SETCF(afp, archive, tfp, tname, 0);

	/* Read through the archive, creating list of symbols. */
	symcnt = tsymlen = 0;
	ntsize = 0;
	r_fuzz = SARMAG;
	pnext = &rhead;
	while(get_arobj(afp)) {
		int new_mid;

		if (!strncmp(chdr.name, AR_NAMTAB, sizeof(AR_NAMTAB) - 1)) {
			size = ftello(afp);
			get_namtab(afp);
			ntsize = chdr.size + sizeof(struct ar_hdr);
			(void)fseeko(afp, size, SEEK_SET);
			r_fuzz += skip_arobj(afp);
			continue;
		}

		if (!strncmp(chdr.name, RANLIBMAG, sizeof(RANLIBMAG) - 1) ||
		    !strncmp(chdr.name, RANLIBMAG2, sizeof(RANLIBMAG2) - 1)) {
			r_fuzz += skip_arobj(afp);
			continue;
		}
		new_mid = read_exec(afp, tfp, &symcnt, &tsymlen);
		if (new_mid != -1) {
			if (current_mid == -1)
				current_mid = new_mid;
			else if (new_mid != current_mid)
				errx(1, "mixed object format archive: %x / %x",
					new_mid, current_mid);
		}
		put_arobj(&cf, NULL);
	}
	*pnext = NULL;

	SETCF(tfp, tname, afp, archive, NOPAD);

	/* Create the symbol table.  Endianess the same as last mid seen */
	symobj(afp, current_mid, symcnt, tsymlen);
	put_nametab(&cf);

	/* Copy the saved objects into the archive. */
	size = ftello(tfp);
	rewind(tfp);
	copy_ar(&cf, size);
	fflush(afp);
	(void)ftruncate(fileno(afp), ftello(afp));
	(void)fclose(tfp);

	/* Set the time. */
	settime(afp);
	close_archive(afp);
	return(0);
}
void
delete_archive_members (void)
{
  enum read_header logical_status = HEADER_STILL_UNREAD;
  enum read_header previous_status = HEADER_STILL_UNREAD;

  /* FIXME: Should clean the routine before cleaning these variables :-( */
  struct name *name;
  off_t blocks_to_skip = 0;
  off_t blocks_to_keep = 0;
  int kept_blocks_in_record;

  name_gather ();
  open_archive (ACCESS_UPDATE);
  acting_as_filter = strcmp (archive_name_array[0], "-") == 0;

  do
    {
      enum read_header status = read_header (true);

      switch (status)
	{
	case HEADER_STILL_UNREAD:
	  abort ();

	case HEADER_SUCCESS:
	  if ((name = name_scan (current_stat_info.file_name)) == NULL)
	    {
	      skip_member ();
	      break;
	    }
	  name->found_count++;
	  if (!ISFOUND(name))
	    {
	      skip_member ();
	      break;
	    }

	  /* Fall through.  */
	case HEADER_SUCCESS_EXTENDED:
	  logical_status = status;
	  break;

	case HEADER_ZERO_BLOCK:
	  if (ignore_zeros_option)
	    {
	      set_next_block_after (current_header);
	      break;
	    }
	  /* Fall through.  */
	case HEADER_END_OF_FILE:
	  logical_status = HEADER_END_OF_FILE;
	  break;

	case HEADER_FAILURE:
	  set_next_block_after (current_header);
	  switch (previous_status)
	    {
	    case HEADER_STILL_UNREAD:
	      WARN ((0, 0, _("This does not look like a tar archive")));
	      /* Fall through.  */

	    case HEADER_SUCCESS:
	    case HEADER_SUCCESS_EXTENDED:
	    case HEADER_ZERO_BLOCK:
	      ERROR ((0, 0, _("Skipping to next header")));
	      /* Fall through.  */

	    case HEADER_FAILURE:
	      break;

	    case HEADER_END_OF_FILE:
	      abort ();
	    }
	  break;
	}

      previous_status = status;
    }
  while (logical_status == HEADER_STILL_UNREAD);

  records_skipped = records_read - 1;
  new_record = xmalloc (record_size);

  if (logical_status == HEADER_SUCCESS
      || logical_status == HEADER_SUCCESS_EXTENDED)
    {
      write_archive_to_stdout = false;

      /* Save away blocks before this one in this record.  */

      new_blocks = current_block - record_start;
      if (new_blocks)
	memcpy (new_record, record_start, new_blocks * BLOCKSIZE);

      if (logical_status == HEADER_SUCCESS)
	{
	  /* FIXME: Pheew!  This is crufty code!  */
	  logical_status = HEADER_STILL_UNREAD;
	  goto flush_file;
	}

      /* FIXME: Solaris 2.4 Sun cc (the ANSI one, not the old K&R) says:
	 "delete.c", line 223: warning: loop not entered at top
	 Reported by Bruno Haible.  */
      while (1)
	{
	  enum read_header status;

	  /* Fill in a record.  */

	  if (current_block == record_end)
	    flush_archive ();
	  status = read_header (false);

	  xheader_decode (&current_stat_info);

	  if (status == HEADER_ZERO_BLOCK && ignore_zeros_option)
	    {
	      set_next_block_after (current_header);
	      continue;
	    }
	  if (status == HEADER_END_OF_FILE || status == HEADER_ZERO_BLOCK)
	    {
	      logical_status = HEADER_END_OF_FILE;
	      break;
	    }

	  if (status == HEADER_FAILURE)
	    {
	      ERROR ((0, 0, _("Deleting non-header from archive")));
	      set_next_block_after (current_header);
	      continue;
	    }

	  /* Found another header.  */

	  if ((name = name_scan (current_stat_info.file_name)) != NULL)
	    {
	      name->found_count++;
	      if (ISFOUND(name))
		{
		flush_file:
		  set_next_block_after (current_header);
		  blocks_to_skip = (current_stat_info.stat.st_size
				    + BLOCKSIZE - 1) / BLOCKSIZE;
		  
		  while (record_end - current_block <= blocks_to_skip)
		    {
		      blocks_to_skip -= (record_end - current_block);
		      flush_archive ();
		    }
		  current_block += blocks_to_skip;
		  blocks_to_skip = 0;
		  continue;
		}
	    }
	  /* Copy header.  */

	  if (extended_header.size)
	    {
	      write_recent_bytes (extended_header.buffer,
				  extended_header.size);
	    }
	  else
	    {
	      write_recent_blocks (recent_long_name, recent_long_name_blocks);
	      write_recent_blocks (recent_long_link, recent_long_link_blocks);
	    }
	  new_record[new_blocks] = *current_header;
	  new_blocks++;
	  blocks_to_keep
	    = (current_stat_info.stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;
	  set_next_block_after (current_header);
	  if (new_blocks == blocking_factor)
	    write_record (1);

	  /* Copy data.  */

	  kept_blocks_in_record = record_end - current_block;
	  if (kept_blocks_in_record > blocks_to_keep)
	    kept_blocks_in_record = blocks_to_keep;

	  while (blocks_to_keep)
	    {
	      int count;

	      if (current_block == record_end)
		{
		  flush_read ();
		  current_block = record_start;
		  kept_blocks_in_record = blocking_factor;
		  if (kept_blocks_in_record > blocks_to_keep)
		    kept_blocks_in_record = blocks_to_keep;
		}
	      count = kept_blocks_in_record;
	      if (blocking_factor - new_blocks < count)
		count = blocking_factor - new_blocks;

	      if (! count)
		abort ();

	      memcpy (new_record + new_blocks, current_block, count * BLOCKSIZE);
	      new_blocks += count;
	      current_block += count;
	      blocks_to_keep -= count;
	      kept_blocks_in_record -= count;

	      if (new_blocks == blocking_factor)
		write_record (1);
	    }
	}

      if (logical_status == HEADER_END_OF_FILE)
	{
	  /* Write the end of tape.  FIXME: we can't use write_eot here,
	     as it gets confused when the input is at end of file.  */

	  int total_zero_blocks = 0;

	  do
	    {
	      int zero_blocks = blocking_factor - new_blocks;
	      memset (new_record + new_blocks, 0, BLOCKSIZE * zero_blocks);
	      total_zero_blocks += zero_blocks;
	      write_record (total_zero_blocks < 2);
	    }
	  while (total_zero_blocks < 2);
	}

      if (! acting_as_filter && ! _isrmt (archive))
	{
	  if (sys_truncate (archive))
	    truncate_warn (archive_name_array[0]);
	}
    }
  free (new_record);

  close_archive ();
  names_notfound ();
}
Example #14
0
void
delete_archive_members (void)
{
  enum read_header logical_status = HEADER_STILL_UNREAD;
  enum read_header previous_status = HEADER_STILL_UNREAD;

  /* FIXME: Should clean the routine before cleaning these variables :-( */
  struct name *name;
  int blocks_to_skip = 0;
  int blocks_to_keep = 0;
  int kept_blocks_in_record;

  name_gather ();
  open_archive (ACCESS_UPDATE);

  while (logical_status == HEADER_STILL_UNREAD)
    {
      enum read_header status = read_header ();

      switch (status)
	{
	case HEADER_STILL_UNREAD:
	  abort ();

	case HEADER_SUCCESS:
	  if (name = name_scan (current_file_name), !name)
	    {
	      set_next_block_after (current_header);
	      if (current_header->oldgnu_header.isextended)
		skip_extended_headers ();
	      skip_file ((long) (current_stat.st_size));
	      break;
	    }
	  name->found = 1;
	  logical_status = HEADER_SUCCESS;
	  break;

	case HEADER_ZERO_BLOCK:
	case HEADER_END_OF_FILE:
	  logical_status = HEADER_END_OF_FILE;
	  break;

	case HEADER_FAILURE:
	  set_next_block_after (current_header);
	  switch (previous_status)
	    {
	    case HEADER_STILL_UNREAD:
	      WARN ((0, 0, _("This does not look like a tar archive")));
	      /* Fall through.  */

	    case HEADER_SUCCESS:
	    case HEADER_ZERO_BLOCK:
	      ERROR ((0, 0, _("Skipping to next header")));
	      /* Fall through.  */

	    case HEADER_FAILURE:
	      break;

	    case HEADER_END_OF_FILE:
	      abort ();
	    }
	  break;
	}

      previous_status = status;
    }

  if (logical_status != HEADER_SUCCESS)
    {
      write_eot ();
      close_archive ();
      names_notfound ();
      return;
    }

  write_archive_to_stdout = 0;
  new_record = (union block *) xmalloc ((size_t) record_size);

  /* Save away blocks before this one in this record.  */

  new_blocks = current_block - record_start;
  blocks_needed = blocking_factor - new_blocks;
  if (new_blocks)
    memcpy ((void *) new_record, (void *) record_start,
	   (size_t) (new_blocks * BLOCKSIZE));

#if 0
  /* FIXME: Old code, before the goto was inserted.  To be redesigned.  */
  set_next_block_after (current_header);
  if (current_header->oldgnu_header.isextended)
    skip_extended_headers ();
  skip_file ((long) (current_stat.st_size));
#endif
  logical_status = HEADER_STILL_UNREAD;
  goto flush_file;

  /* FIXME: Solaris 2.4 Sun cc (the ANSI one, not the old K&R) says:
       "delete.c", line 223: warning: loop not entered at top
     Reported by Bruno Haible.  */
  while (1)
    {
      enum read_header status;

      /* Fill in a record.  */

      if (current_block == record_end)
	{
	  flush_archive ();
	  records_read++;
	}
      status = read_header ();

      if (status == HEADER_ZERO_BLOCK && ignore_zeros_option)
	{
	  set_next_block_after (current_header);
	  continue;
	}
      if (status == HEADER_END_OF_FILE || status == HEADER_ZERO_BLOCK)
	{
	  logical_status = HEADER_END_OF_FILE;
	  memset (new_record[new_blocks].buffer, 0,
		 (size_t) (BLOCKSIZE * blocks_needed));
	  new_blocks += blocks_needed;
	  blocks_needed = 0;
	  write_record (0);
	  break;
	}

      if (status == HEADER_FAILURE)
	{
	  ERROR ((0, 0, _("Deleting non-header from archive")));
	  set_next_block_after (current_header);
	  continue;
	}

      /* Found another header.  */

      if (name = name_scan (current_file_name), name)
	{
	  name->found = 1;
	flush_file:
	  set_next_block_after (current_header);
	  blocks_to_skip = (current_stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;

	  while (record_end - current_block <= blocks_to_skip)
	    {
	      blocks_to_skip -= (record_end - current_block);
	      flush_archive ();
	      records_read++;
	    }
	  current_block += blocks_to_skip;
	  blocks_to_skip = 0;
	  continue;
	}

      /* Copy header.  */

      new_record[new_blocks] = *current_header;
      new_blocks++;
      blocks_needed--;
      blocks_to_keep
	= (current_stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;
      set_next_block_after (current_header);
      if (blocks_needed == 0)
	write_record (1);

      /* Copy data.  */

      kept_blocks_in_record = record_end - current_block;
      if (kept_blocks_in_record > blocks_to_keep)
	kept_blocks_in_record = blocks_to_keep;

      while (blocks_to_keep)
	{
	  int count;

	  if (current_block == record_end)
	    {
	      flush_read ();
	      records_read++;
	      current_block = record_start;
	      kept_blocks_in_record = blocking_factor;
	      if (kept_blocks_in_record > blocks_to_keep)
		kept_blocks_in_record = blocks_to_keep;
	    }
	  count = kept_blocks_in_record;
	  if (count > blocks_needed)
	    count = blocks_needed;

	  memcpy ((void *) (new_record + new_blocks),
		  (void *) current_block,
		  (size_t) (count * BLOCKSIZE));
	  new_blocks += count;
	  blocks_needed -= count;
	  current_block += count;
	  blocks_to_keep -= count;
	  kept_blocks_in_record -= count;

	  if (blocks_needed == 0)
	    write_record (1);
	}
    }

  write_eot ();
  close_archive ();
  names_notfound ();
}
Example #15
0
void
read_and (void (*do_something) ())
{
  enum read_header status = HEADER_STILL_UNREAD;
  enum read_header prev_status;
  char save_typeflag;

  name_gather ();
  open_archive (ACCESS_READ);

  while (1)
    {
      prev_status = status;
      status = read_header ();
      switch (status)
	{
	case HEADER_STILL_UNREAD:
	  abort ();

	case HEADER_SUCCESS:

	  /* Valid header.  We should decode next field (mode) first.
	     Ensure incoming names are null terminated.  */

	  /* FIXME: This is a quick kludge before 1.12 goes out.  */
	  current_stat.st_mtime
	    = from_oct (1 + 12, current_header->header.mtime);

	  if (!name_match (current_file_name)
	      || current_stat.st_mtime < newer_mtime_option
	      || (exclude_option && check_exclude (current_file_name)))
	    {
	      int isextended = 0;

	      if (current_header->header.typeflag == GNUTYPE_VOLHDR
		  || current_header->header.typeflag == GNUTYPE_MULTIVOL
		  || current_header->header.typeflag == GNUTYPE_NAMES)
		{
		  (*do_something) ();
		  continue;
		}
	      if (show_omitted_dirs_option
		  && current_header->header.typeflag == DIRTYPE)
		WARN ((0, 0, _("Omitting %s"), current_file_name));

	      /* Skip past it in the archive.  */

	      if (current_header->oldgnu_header.isextended)
		isextended = 1;
	      save_typeflag = current_header->header.typeflag;
	      set_next_block_after (current_header);
	      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 ();
		}

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

	      if (save_typeflag != DIRTYPE)
		skip_file ((long long) current_stat.st_size);
	      continue;
	    }

	  (*do_something) ();
	  continue;

	case HEADER_ZERO_BLOCK:
	  if (block_number_option)
	    fprintf (stdlis, _("block %10ld: ** Block of NULs **\n"),
		     current_block_ordinal ());

	  set_next_block_after (current_header);
	  status = prev_status;
	  if (ignore_zeros_option)
	    continue;
	  break;

	case HEADER_END_OF_FILE:
	  if (block_number_option)
	    fprintf (stdlis, _("block %10ld: ** End of File **\n"),
		     current_block_ordinal ());
	  break;

	case HEADER_FAILURE:
	  /* If the previous header was good, tell them that we are
	     skipping bad ones.  */
	  set_next_block_after (current_header);
	  switch (prev_status)
	    {
	    case HEADER_STILL_UNREAD:
	      WARN ((0, 0, _("Could not extract file(s); file might not be a tar archive")));
	      /* Fall through.  */

	    case HEADER_ZERO_BLOCK:
	    case HEADER_SUCCESS:
	      WARN ((0, 0, _("Skipping to next file header")));
	      break;

	    case HEADER_END_OF_FILE:
	    case HEADER_FAILURE:
	      /* We are in the middle of a cascade of errors.  */
	      break;
	    }
	  continue;
	}
      break;
    }

  apply_delayed_set_stat ();
  close_archive ();
  names_notfound ();		/* print names not found */
}
Example #16
0
/*
 * replace --
 *	Replace or add named members to archive.  Entries already in the
 *	archive are swapped in place.  Others are added before or after 
 *	the key entry, based on the a, b and i options.  If the u option
 *	is specified, modification dates select for replacement.
 */
int
replace(char **argv)
{
	char *file;
	int afd, curfd, errflg, exists, mods, sfd, tfd1, tfd2;
	struct stat sb;
	CF cf;
	off_t size, tsize;

	errflg = 0;
	/*
	 * If doesn't exist, simply append to the archive.  There's
	 * a race here, but it's pretty short, and not worth fixing.
	 */
	exists = !stat(archive, &sb);
	afd = open_archive(O_CREAT|O_RDWR);

	if (!exists) {
		tfd1 = -1;
		tfd2 = tmp();
		goto append;
	} 

	tfd1 = tmp();			/* Files before key file. */
	tfd2 = tmp();			/* Files after key file. */

	/*
	 * Break archive into two parts -- entries before and after the key
	 * entry.  If positioning before the key, place the key at the
	 * beginning of the after key entries and if positioning after the
	 * key, place the key at the end of the before key entries.  Put it
	 * all back together at the end.
	 */
	mods = (options & (AR_A|AR_B));
	for (curfd = tfd1; get_arobj(afd);) {
		if (*argv && (file = files(argv))) {
			if ((sfd = open(file, O_RDONLY)) < 0) {
				errflg = 1;
				warn("%s", file);
				goto useold;
			}
			(void)fstat(sfd, &sb);
			if (options & AR_U && sb.st_mtime <= chdr.date) {
				close(sfd);
				goto useold;
			}

			if (options & AR_V)
			     (void)printf("r - %s\n", file);

			/* Read from disk, write to an archive; pad on write */
			SETCF(sfd, file, curfd, tname, WPAD);
			put_arobj(&cf, &sb);
			(void)close(sfd);
			skip_arobj(afd);
			continue;
		}

		if (mods && compare(posname)) {
			mods = 0;
			if (options & AR_B)
				curfd = tfd2;
			/* Read and write to an archive; pad on both. */
			SETCF(afd, archive, curfd, tname, RPAD|WPAD);
			put_arobj(&cf, NULL);
			if (options & AR_A)
				curfd = tfd2;
		} else {
			/* Read and write to an archive; pad on both. */
useold:			SETCF(afd, archive, curfd, tname, RPAD|WPAD);
			put_arobj(&cf, NULL);
		}
	}

	if (mods) {
		warnx("%s: archive member not found", posarg);
                close_archive(afd);
                return (1);
        }

	/* Append any left-over arguments to the end of the after file. */
append:	while ((file = *argv++)) {
		if (options & AR_V)
			(void)printf("a - %s\n", file);
		if ((sfd = open(file, O_RDONLY)) < 0) {
			errflg = 1;
			warn("%s", file);
			continue;
		}
		(void)fstat(sfd, &sb);
		/* Read from disk, write to an archive; pad on write. */
		SETCF(sfd, file,
		    options & (AR_A|AR_B) ? tfd1 : tfd2, tname, WPAD);
		put_arobj(&cf, &sb);
		(void)close(sfd);
	}
	
	(void)lseek(afd, (off_t)SARMAG, SEEK_SET);

	SETCF(tfd1, tname, afd, archive, NOPAD);
	if (tfd1 != -1) {
		tsize = size = lseek(tfd1, (off_t)0, SEEK_CUR);
		(void)lseek(tfd1, (off_t)0, SEEK_SET);
		copy_ar(&cf, size);
	} else
		tsize = 0;

	tsize += size = lseek(tfd2, (off_t)0, SEEK_CUR);
	(void)lseek(tfd2, (off_t)0, SEEK_SET);
	cf.rfd = tfd2;
	copy_ar(&cf, size);

	(void)ftruncate(afd, tsize + SARMAG);
	close_archive(afd);
	return (errflg);
}	
Example #17
0
int main(int argc, char** argv)
{
    // Print an error if the user invokes Far with an incorrect number of
    // arguments. There should be at least "Far key archive"
    if (argc < 3) {
        ERROR("Usage: Far key archive [name]*");
        return 1;
    }

    char* key = argv[1];
    char* archive_name = argv[2];

    int num_files = argc - 3;
    char** filenames = argv + 3;

    // Ignore trailing / in NAME arguments
    for (int i = 0; i < num_files; i++) strip_trailing_slash(filenames[i]);

    if (!strcmp(key, "r")) {
        member_list* members = make_list_recursive(filenames, num_files);
        archive_t* archive = open_archive(archive_name, true);
        member_list* processed_members =
          process_members(archive, members, replace_current_member);
        // Now that previously existing files have been deleted, add the
        // files to the end of the archive
        member_node* cur_member = members;
        while (cur_member) {
            add_member(archive, cur_member->filename);
            cur_member = cur_member->next;
        }
        delete_list(processed_members);
        close_archive(archive, true);

        delete_list(members);
        return 0;
    } else if (!strcmp(key, "x")) {
        member_list* members = make_list(filenames, num_files);
        archive_t* archive = open_archive(archive_name, false);
        member_list* processed_members =
          process_members(archive, members, extract_current_member);
        // Error handling for unprocessed NAME arguments
        for (int i = 0; i < num_files; i++) {
            char* name = filenames[i];
            if (!find_member(name, processed_members)) {
                ERROR_CREATE(name);
            }
        }
        delete_list(processed_members);
        close_archive(archive, false);

        delete_list(members);
        return 0;
    } else if (!strcmp(key, "d")) {
        member_list* members = make_list(filenames, num_files);
        archive_t* archive = open_archive(archive_name, false);
        member_list* processed_members =
          process_members(archive, members, delete_current_member);
        // Error handling for unprocessed NAME arguments
        for (int i = 0; i < num_files; i++) {
            char* name = filenames[i];
            if (!find_member(name, processed_members) &&
                !find_child(name, processed_members)) {
                ERROR_FIND(name);
            }
        }
        delete_list(processed_members);
        close_archive(archive, true);

        delete_list(members);
        return 0;
    } else if (!strcmp(key, "t")) {
        archive_t* archive = open_archive(archive_name, false);
        member_list* processed_members =
          process_members(archive, NULL, print_current_member);
        delete_list(processed_members);
        close_archive(archive, false);
        return 0;
    } else {
        ERROR("Key options: 'r', 'x', 'd', 't'");
        return 1;
    }
}
Example #18
0
/*
 * extract --
 *	Extract files from the named archive - if member names given only
 *	extract those members otherwise extract all members.  If 'o' option
 *	selected modify date of newly created file to be same as archive
 *	members date otherwise date is time of extraction.  Does not modify
 *	archive.
 */
int
extract(char **argv)
{
	struct timeval tv[2];
	struct stat sb;
	CF cf;
	off_t size;
	FILE *afp;
	char *file;
	int all, eval, tfd;

	eval = 0;
	tv[0].tv_usec = tv[1].tv_usec = 0;

	afp = open_archive(O_RDONLY);

	/* Read from an archive, write to disk; pad on read. */
	SETCF(afp, archive, 0, 0, 0);
	for (all = !*argv; get_arobj(afp);) {
		if (!strncmp(chdr.name, AR_NAMTAB, sizeof(AR_NAMTAB) - 1)) {
			size = ftello(afp);
			get_namtab(afp);
			(void)fseeko(afp, size, SEEK_SET);
			skip_arobj(afp);
			continue;
		}

		if (all)
			file = chdr.name;
		else if (!(file = files(argv))) {
			skip_arobj(afp);
			continue;
		}

		if (options & AR_U && !stat(file, &sb) &&
		    sb.st_mtime > chdr.date)
			continue;

		if (options & AR_CC) {
			/* -C means do not overwrite existing files */
			if ((tfd = open(file, O_WRONLY|O_CREAT|O_EXCL,
			    S_IWUSR)) < 0) {
				skip_arobj(afp);
				eval = 1;
				continue;
			}
		} else {
			if ((tfd = open(file, O_WRONLY|O_CREAT|O_TRUNC,
			    S_IWUSR)) < 0) {
				warn("open: %s", file);
				skip_arobj(afp);
				eval = 1;
				continue;
			}
		}

		if (options & AR_V)
			(void)printf("x - %s\n", file);

		if (!(cf.wfp = fdopen(tfd, "w")))
			err(1, "fdopen: %s", file);
		cf.wname = file;
		copy_ar(&cf, chdr.size);

		if (fchmod(tfd, (mode_t)chdr.mode)) {
			warn("chmod: %s", file);
			eval = 1;
		}
		if (options & AR_O) {
			tv[0].tv_sec = tv[1].tv_sec = chdr.date;
			if (futimes(tfd, tv)) {
				warn("utimes: %s", file);
				eval = 1;
			}
		}
		(void)fclose(cf.wfp);
		if (!all && !*argv)
			break;
	}
	close_archive(afp);

	if (*argv) {
		orphans(argv);
		return (1);
	}
	return (0);
}
Example #19
0
/* Implement the 'r' (add files to end of archive), and 'u' (add files
   to end of archive if they aren't there, or are more up to date than
   the version in the archive) commands.  */
void
update_archive (void)
{
  enum read_header previous_status = HEADER_STILL_UNREAD;
  bool found_end = false;

  name_gather ();
  open_archive (ACCESS_UPDATE);
  xheader_write_global ();

  while (!found_end)
    {
      enum read_header status = read_header (false);

      switch (status)
	{
	case HEADER_STILL_UNREAD:
	case HEADER_SUCCESS_EXTENDED:
	  abort ();

	case HEADER_SUCCESS:
	  {
	    struct name *name;

	    decode_header (current_header, &current_stat_info,
			   &current_format, 0);
	    archive_format = current_format;
	    
	    if (subcommand_option == UPDATE_SUBCOMMAND
		&& (name = name_scan (current_stat_info.file_name)) != NULL)
	      {
		struct stat s;

		chdir_do (name->change_dir);
		if (deref_stat (dereference_option,
				current_stat_info.file_name, &s) == 0
		    && s.st_mtime <= current_stat_info.stat.st_mtime)
		  add_avoided_name (current_stat_info.file_name);
	      }

	    skip_member ();
	    break;
	  }

	case HEADER_ZERO_BLOCK:
	  current_block = current_header;
	  found_end = true;
	  break;

	case HEADER_END_OF_FILE:
	  found_end = true;
	  break;

	case HEADER_FAILURE:
	  set_next_block_after (current_header);
	  switch (previous_status)
	    {
	    case HEADER_STILL_UNREAD:
	      WARN ((0, 0, _("This does not look like a tar archive")));
	      /* Fall through.  */

	    case HEADER_SUCCESS:
	    case HEADER_ZERO_BLOCK:
	      ERROR ((0, 0, _("Skipping to next header")));
	      /* Fall through.  */

	    case HEADER_FAILURE:
	      break;

	    case HEADER_END_OF_FILE:
	    case HEADER_SUCCESS_EXTENDED:
	      abort ();
	    }
	  break;
	}

      tar_stat_destroy (&current_stat_info);
      xheader_destroy (&extended_header);
      previous_status = status;
    }

  reset_eof ();
  time_to_start_writing = true;
  output_start = current_block->buffer;

  {
    char *file_name;

    while ((file_name = name_from_list ()) != NULL)
      {
	if (excluded_name (file_name))
	  continue;
	if (interactive_option && !confirm ("add", file_name))
	  continue;
	if (subcommand_option == CAT_SUBCOMMAND)
	  append_file (file_name);
	else
	  dump_file (file_name, 1, (dev_t) 0);
      }
  }

  write_eot ();
  close_archive ();
  names_notfound ();
}
Example #20
0
File: delete.c Project: WndSks/msys
void
delete_archive_members (void)
{
  enum read_header logical_status = HEADER_STILL_UNREAD;
  enum read_header previous_status = HEADER_STILL_UNREAD;

  /* FIXME: Should clean the routine before cleaning these variables :-( */
  struct name *name;
  off_t blocks_to_skip = 0;
  off_t blocks_to_keep = 0;
  int kept_blocks_in_record;

  name_gather ();
  open_archive (ACCESS_UPDATE);
  acting_as_filter = strcmp (archive_name_array[0], "-") == 0;

  do
    {
      enum read_header status = read_header ();

      switch (status)
	{
	case HEADER_STILL_UNREAD:
	  abort ();

	case HEADER_SUCCESS:
	  if (name = name_scan (current_file_name), !name)
	    {
	      skip_member ();
	      break;
	    }
	  name->found = 1;
	  logical_status = HEADER_SUCCESS;
	  break;

	case HEADER_ZERO_BLOCK:
	  if (ignore_zeros_option)
	    {
	      set_next_block_after (current_header);
	      break;
	    }
	  /* Fall through.  */
	case HEADER_END_OF_FILE:
	  logical_status = HEADER_END_OF_FILE;
	  break;

	case HEADER_FAILURE:
	  set_next_block_after (current_header);
	  switch (previous_status)
	    {
	    case HEADER_STILL_UNREAD:
	      WARN ((0, 0, _("This does not look like a tar archive")));
	      /* Fall through.  */

	    case HEADER_SUCCESS:
	    case HEADER_ZERO_BLOCK:
	      ERROR ((0, 0, _("Skipping to next header")));
	      /* Fall through.  */

	    case HEADER_FAILURE:
	      break;

	    case HEADER_END_OF_FILE:
	      abort ();
	    }
	  break;
	}

      previous_status = status;
    }
  while (logical_status == HEADER_STILL_UNREAD);

  new_record = xmalloc (record_size);

  if (logical_status == HEADER_SUCCESS)
    {
      write_archive_to_stdout = 0;

      /* Save away blocks before this one in this record.  */

      new_blocks = current_block - record_start;
      if (new_blocks)
	memcpy (new_record, record_start, new_blocks * BLOCKSIZE);

#if 0
      /* FIXME: Old code, before the goto was inserted.  To be redesigned.  */
      skip_member ();
#endif
      logical_status = HEADER_STILL_UNREAD;
      goto flush_file;

      /* FIXME: Solaris 2.4 Sun cc (the ANSI one, not the old K&R) says:
	 "delete.c", line 223: warning: loop not entered at top
	 Reported by Bruno Haible.  */
      while (1)
	{
	  enum read_header status;

	  /* Fill in a record.  */

	  if (current_block == record_end)
	    {
	      flush_archive ();
	      records_read++;
	    }
	  status = read_header ();

	  if (status == HEADER_ZERO_BLOCK && ignore_zeros_option)
	    {
	      set_next_block_after (current_header);
	      continue;
	    }
	  if (status == HEADER_END_OF_FILE || status == HEADER_ZERO_BLOCK)
	    {
	      logical_status = HEADER_END_OF_FILE;
	      break;
	    }

	  if (status == HEADER_FAILURE)
	    {
	      ERROR ((0, 0, _("Deleting non-header from archive")));
	      set_next_block_after (current_header);
	      continue;
	    }

	  /* Found another header.  */

	  if (name = name_scan (current_file_name), name)
	    {
	      name->found = 1;
	    flush_file:
	      set_next_block_after (current_header);
	      blocks_to_skip = (current_stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;

	      while (record_end - current_block <= blocks_to_skip)
		{
		  blocks_to_skip -= (record_end - current_block);
		  flush_archive ();
		  records_read++;
		}
	      current_block += blocks_to_skip;
	      blocks_to_skip = 0;
	      continue;
	    }

	  /* Copy header.  */

	  new_record[new_blocks] = *current_header;
	  new_blocks++;
	  blocks_to_keep
	    = (current_stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;
	  set_next_block_after (current_header);
	  if (new_blocks == blocking_factor)
	    write_record (1);

	  /* Copy data.  */

	  kept_blocks_in_record = record_end - current_block;
	  if (kept_blocks_in_record > blocks_to_keep)
	    kept_blocks_in_record = blocks_to_keep;

	  while (blocks_to_keep)
	    {
	      int count;

	      if (current_block == record_end)
		{
		  flush_read ();
		  records_read++;
		  current_block = record_start;
		  kept_blocks_in_record = blocking_factor;
		  if (kept_blocks_in_record > blocks_to_keep)
		    kept_blocks_in_record = blocks_to_keep;
		}
	      count = kept_blocks_in_record;
	      if (blocking_factor - new_blocks < count)
		count = blocking_factor - new_blocks;

	      if (! count)
		abort ();

	      memcpy (new_record + new_blocks, current_block, count * BLOCKSIZE);
	      new_blocks += count;
	      current_block += count;
	      blocks_to_keep -= count;
	      kept_blocks_in_record -= count;

	      if (new_blocks == blocking_factor)
		write_record (1);
	    }
	}
    }

  if (logical_status == HEADER_END_OF_FILE)
    {
      /* Write the end of tape.  FIXME: we can't use write_eot here,
	 as it gets confused when the input is at end of file.  */

      int total_zero_blocks = 0;

      do
	{
	  int zero_blocks = blocking_factor - new_blocks;
	  memset (new_record + new_blocks, 0, BLOCKSIZE * zero_blocks);
	  total_zero_blocks += zero_blocks;
	  write_record (total_zero_blocks < 2);
	}
      while (total_zero_blocks < 2);
    }

  free (new_record);

  if (! acting_as_filter && ! _isrmt (archive))
    {
#if MSDOS
      int status = write (archive, "", 0);
#else
      off_t pos = lseek (archive, (off_t) 0, SEEK_CUR);
      int status = pos < 0 ? -1 : ftruncate (archive, pos);
#endif
      if (status != 0)
	truncate_warn (archive_name_array[0]);
    }

  close_archive ();
  names_notfound ();
}
Example #21
0
File: rw.c Project: ah42/CUDALucas
void archivebits(double *x, UL q, UL n, UL totalbits, UL b, UL c, double hi, double lo,
		const char *version_info, FILE *outfp, FILE *dupfp) {

	FILE *archfp = NULL;
	
	archfp = open_archive();

	if (is_zero(x, n, 0, 0)) {
		if (outfp != NULL && !ferror(outfp)) fprintf(outfp,  "M( " PRINTF_FMT_UL " )P, n = " PRINTF_FMT_UL ", %s\n", q, n, version_info);
		if (dupfp != NULL && !ferror(dupfp)) fprintf(dupfp,  "M( " PRINTF_FMT_UL " )P, n = " PRINTF_FMT_UL ", %s\n", q, n, version_info);
		if (archfp != NULL)                  fprintf(archfp, "M( " PRINTF_FMT_UL " )P, n = " PRINTF_FMT_UL ", %s\n", q, n, version_info);
		
		if (archfp != NULL) close_archive(archfp, outfp, dupfp);
		
		return;
	}

	if (outfp != NULL && !ferror(outfp)) fprintf(outfp,  "M( " PRINTF_FMT_UL " )C", q);
	if (dupfp != NULL && !ferror(dupfp)) fprintf(dupfp,  "M( " PRINTF_FMT_UL " )C", q);
	if (archfp != NULL)                  fprintf(archfp, "M( " PRINTF_FMT_UL " )C", q);

	balancedtostdrep(x, n, b, c, hi, lo, 0, 0);
	static UL *hex = NULL;
	static UL prior_hex = 0;
	if (hex != NULL && totalbits/BITS_IN_LONG + 1 > prior_hex) {
		free(hex);
		hex = NULL;
		prior_hex = totalbits/BITS_IN_LONG + 1;
	}

	if (hex == NULL && (hex = (UL *)calloc(totalbits/BITS_IN_LONG + 1, sizeof(UL))) == NULL) {
		perror(program_name);
		fprintf(stderr, "%s: cannot get memory for residue bits; calloc() errno %d\n", program_name, errno);
		exit(errno);
	}
	
	int i = 0;
	int j = 0;
	do {
		UL k = (long)(ceil((double)q*(j + 1)/n) - ceil((double)q*j/n));
		if (k > totalbits) k = totalbits;
		totalbits -= k;
		int word = (long)x[j];
		for (j++; k > 0; k--, i++) {
			if (i % BITS_IN_LONG == 0)
				hex[i/BITS_IN_LONG] = 0L;
			hex[i/BITS_IN_LONG] |= ((word & 0x1) << (i % BITS_IN_LONG));
			word >>= 1;
		}
	} while(totalbits > 0);
	
	if (outfp != NULL && !ferror(outfp)) fputs(", 0x", outfp);
	if (dupfp != NULL && !ferror(dupfp)) fputs(", 0x", dupfp);
	if (archfp != NULL)                  fputs(", 0x", archfp);
	
	static char bits_fmt[16] = "\0"; /* "%%0%ulx" -> "%08lx" or "%016lx" depending on sizeof(UL) */
	
	if (bits_fmt[0] != '%')
		sprintf(bits_fmt, "%%0" PRINTF_FMT_UL "%s", (UL)(BITS_IN_LONG/4), "lx"); /* 4 bits per hex 'digit' */
	
	for (j = (i - 1)/BITS_IN_LONG; j >= 0; j--) {
		if (outfp != NULL && !ferror(outfp)) fprintf(outfp, bits_fmt, hex[j]);
		if (dupfp != NULL && !ferror(dupfp)) fprintf(dupfp, bits_fmt, hex[j]);
		if (archfp != NULL)                  fprintf(archfp, bits_fmt, hex[j]);
	}
	
	if (outfp != NULL && !ferror(outfp)) {
		fprintf(outfp, ", n = " PRINTF_FMT_UL ", %s", n, version_info);
		fprintf(outfp, "\n");
		fflush(outfp);
	}

	if (dupfp != NULL && !ferror(dupfp))
		fprintf(dupfp, ", n = " PRINTF_FMT_UL ", %s\n", n, version_info);
	if (archfp != NULL) {
		fprintf(archfp, ", n = " PRINTF_FMT_UL ", %s\n", n, version_info);
		close_archive(archfp, outfp, dupfp);
	}
	return;
}
bool vogl_trace_file_writer::close()
{
    VOGL_FUNC_TRACER

    vogl_debug_printf("%s\n", VOGL_METHOD_NAME);

    if (!m_stream.is_opened())
        return false;

    vogl_message_printf("%s: Flushing trace file %s (this could take some time), %u total frame file offsets\n", VOGL_METHOD_NAME, m_filename.get_ptr(), m_frame_file_offsets.size());

    bool success = true;

    dynamic_string trace_archive_filename;

    if (!write_eof_packet())
    {
        vogl_error_printf("%s: Failed writing to trace file \"%s\"\n", VOGL_METHOD_NAME, m_filename.get_ptr());
        success = false;
    }
    else if (m_pTrace_archive.get())
    {
        trace_archive_filename = m_pTrace_archive->get_archive_filename();

        if ((!write_frame_file_offsets_to_archive()) || !m_pTrace_archive->deinit())
        {
            vogl_error_printf("%s: Failed closing trace archive \"%s\"!\n", VOGL_FUNCTION_NAME, trace_archive_filename.get_ptr());
            success = false;
        }
        else
        {
            if (!file_utils::get_file_size(trace_archive_filename.get_ptr(), m_sof_packet.m_archive_size))
            {
                vogl_error_printf("%s: Failed determining file size of archive file \"%s\"\n", VOGL_FUNCTION_NAME, trace_archive_filename.get_ptr());
                success = false;
            }
            else if (m_sof_packet.m_archive_size)
            {
                m_sof_packet.m_archive_offset = m_stream.get_size();

                vogl_message_printf("Copying %" PRIu64 " archive bytes into output trace file\n", m_sof_packet.m_archive_size);

                if (!m_stream.write_file_data(trace_archive_filename.get_ptr()))
                {
                    vogl_error_printf("%s: Failed copying source archive \"%s\" into trace file!\n", VOGL_METHOD_NAME, trace_archive_filename.get_ptr());
                    success = false;
                }

                m_sof_packet.m_archive_size = m_stream.get_size() - m_sof_packet.m_archive_offset;
            }
        }

        if (success)
        {
            m_sof_packet.finalize();
            VOGL_VERIFY(m_sof_packet.full_validation(sizeof(m_sof_packet)));

            if (!m_stream.seek(0, false) || (m_stream.write(&m_sof_packet, sizeof(m_sof_packet)) != sizeof(m_sof_packet)))
            {
                vogl_error_printf("%s: Failed writing to trace file \"%s\"\n", VOGL_METHOD_NAME, m_filename.get_ptr());
                success = false;
            }
        }
    }

    close_archive(trace_archive_filename.get_ptr());

    uint64_t total_trace_file_size = m_stream.get_size();

    if (!m_stream.close())
    {
        vogl_error_printf("Failed writing to or closing trace file!\n");
        success = false;
    }

    dynamic_string full_trace_filename(m_filename);
    file_utils::full_path(full_trace_filename);

    if (success)
        vogl_message_printf("%s: Successfully closed trace file %s, total file size: %s\n", VOGL_METHOD_NAME, full_trace_filename.get_ptr(), uint64_to_string_with_commas(total_trace_file_size).get_ptr());
    else
        vogl_error_printf("%s: Failed closing trace file %s! (Trace will probably not be valid.)\n", VOGL_METHOD_NAME, full_trace_filename.get_ptr());

    return success;
}
Example #23
0
/* Implement the 'r' (add files to end of archive), and 'u' (add files to
   end of archive if they arent there, or are more up to date than the
   version in the archive.) commands.*/
void
update_archive ()
{
  int found_end = 0;
  int status = 3;
  int prev_status;
  char *p;
  struct name *name;
  extern void dump_file ();

  name_gather ();
  if (cmd_mode == CMD_UPDATE)
    name_expand ();
  open_archive (2);		/* Open for updating */

  do
    {
      prev_status = status;
      status = read_header ();
      switch (status)
	{
	case EOF:
	  found_end = 1;
	  break;

	case 0:		/* A bad record */
	  userec (head);
	  switch (prev_status)
	    {
	    case 3:
	      msg ("This doesn't look like a tar archive.");
	      /* FALL THROUGH */
	    case 2:
	    case 1:
	      msg ("Skipping to next header");
	    case 0:
	      break;
	    }
	  break;

	  /* A good record */
	case 1:
	  /* printf("File %s\n",head->header.name); */
	  /* head->header.name[NAMSIZ-1]='\0'; */
	  if (cmd_mode == CMD_UPDATE && (name = name_scan (current_file_name)))
	    {

	      /* struct stat hstat; */
	      struct stat nstat;
	      int head_standard;

	      decode_header (head, &hstat, &head_standard, 0);
	      if (stat (current_file_name, &nstat) < 0)
		{
		  msg_perror ("can't stat %s:", current_file_name);
		}
	      else
		{
		  if (hstat.st_mtime >= nstat.st_mtime)
		    name->found++;
		}
	    }
	  userec (head);
	  if (head->header.isextended)
	    skip_extended_headers ();
	  skip_file ((long) hstat.st_size);
	  break;

	case 2:
	  ar_record = head;
	  found_end = 1;
	  break;
	}
    }
  while (!found_end);

  reset_eof ();
  time_to_start_writing = 1;
  output_start = ar_record->charptr;

  while (p = name_from_list ())
    {
      if (f_confirm && !confirm ("add", p))
	continue;
      if (cmd_mode == CMD_CAT)
	append_file (p);
      else
	dump_file (p, -1, 1);
    }

  write_eot ();
  close_archive ();
  names_notfound ();
}
Example #24
0
int read_archive()

#endif
{
    Stat            sb;
    char            name[PATH_MAX + 1];
    int             match;
    int		    pad;

    name_gather();		/* get names from command line */
    name[0] = '\0';
    while (get_header(name, &sb) == 0) {
	match = name_match(name) ^ f_reverse_match;
	if (f_list) {		/* only wanted a table of contents */
	    if (match) {
		print_entry(name, &sb);
	    }
	    if (((ar_format == TAR) 
		? buf_skip(ROUNDUP((OFFSET) sb.sb_size, BLOCKSIZE)) 
		: buf_skip((OFFSET) sb.sb_size)) < 0) {
		warn(name, "File data is corrupt");
	    }
	} else if (match) {
	    if (rplhead != (Replstr *)NULL) {
		rpl_name(name);
		if (strlen(name) == 0) {
		    continue;
		}
	    }
	    if (get_disposition("extract", name) || 
                get_newname(name, sizeof(name))) {
		/* skip file... */
		if (((ar_format == TAR) 
		    ? buf_skip(ROUNDUP((OFFSET) sb.sb_size, BLOCKSIZE)) 
		    : buf_skip((OFFSET) sb.sb_size)) < 0) {
		    warn(name, "File data is corrupt");
		}
		continue;
	    } 
	    if (inentry(name, &sb) < 0) {
		warn(name, "File data is corrupt");
	    }
	    if (f_verbose) {
		print_entry(name, &sb);
	    }
	    if (ar_format == TAR && sb.sb_nlink > 1) {
		/*
		 * This kludge makes sure that the link table is cleared
		 * before attempting to process any other links.
		 */
		if (sb.sb_nlink > 1) {
		    linkfrom(name, &sb);
		}
	    }
	    if (ar_format == TAR && (pad = sb.sb_size % BLOCKSIZE) != 0) {
		pad = BLOCKSIZE - pad;
		buf_skip((OFFSET) pad);
	    }
	} else {
	    if (((ar_format == TAR) 
		? buf_skip(ROUNDUP((OFFSET) sb.sb_size, BLOCKSIZE)) 
		: buf_skip((OFFSET) sb.sb_size)) < 0) {
		warn(name, "File data is corrupt");
	    }
	}
    }

    close_archive();
}