/* copyin.c - extract or list a cpio archive
   Copyright (C) 1990,1991,1992,2001,2002,2003,2004 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation, Inc.,
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#include <errno.h>
#include <fcntl.h>
#include <malloc.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
#ifndef	FNM_PATHNAME
#include <fnmatch.h>
#endif

#ifndef	O_BINARY
# define O_BINARY 0
#endif

# ifndef DIRECTORY_SEPARATOR
#  define DIRECTORY_SEPARATOR '/'
# endif

# ifndef ISSLASH
#  define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
# endif

/* Return 1 if an array of N objects, each of size S, cannot exist due
   to size arithmetic overflow.  S must be positive and N must be
   nonnegative.  This is a macro, not an inline function, so that it
   works correctly even when SIZE_MAX < N.

   By gnulib convention, SIZE_MAX represents overflow in size
   calculations, so the conservative dividend to use here is
   SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
   However, malloc (SIZE_MAX) fails on all known hosts where
   sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
   exactly-SIZE_MAX allocations on such hosts; this avoids a test and
   branch when S is known to be 1.  */
# define xalloc_oversized(n, s) \
    ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))

#define DISK_IO_BLOCK_SIZE	(512)

char *progname = NULL;

/* If true, print a . for each file processed. (-V) */
char dot_flag = false;

/* Input and output buffers.  */
char *input_buffer, *output_buffer;

/* The size of the input buffer.  */
long input_buffer_size;

/* Current locations in `input_buffer' and `output_buffer'.  */
char *in_buff, *out_buff;

/* Current number of bytes stored at `input_buff' and `output_buff'.  */
long input_size, output_size;

/* Block size value, initially 512.  -B sets to 5120.  */
int io_block_size = 512;

struct new_cpio_header {
	unsigned short c_magic;
	union {
		struct {
			unsigned long c_ino;
			unsigned long c_mode;
			unsigned long c_uid;
			unsigned long c_gid;
			unsigned long c_nlink;
			unsigned long c_mtime;
			unsigned long c_filesize;
			long c_dev_maj;
			long c_dev_min;
			long c_rdev_maj;
			long c_rdev_min;
			unsigned long c_namesize;
			unsigned long c_chksum;
		};
		unsigned long c_hdr[13];
	};
	char *c_name;
	char *c_tar_linkname;
};

/* Total number of bytes read and written for all files.
 * Now that many tape drives hold more than 4Gb we need more than 32
 *  bits to hold input_bytes and output_bytes.
 */
long long input_bytes, output_bytes;

/* Allocate N bytes of memory dynamically, with error checking.  */

static void *xmalloc(size_t n)
{
	void *p;
	if (xalloc_oversized(n, 1) || (!(p = malloc(n)) && n != 0)) {
		fprintf(stderr, "%s: memory exhausted\n", progname);
		exit(1);
	}
	return p;
/*   return xnmalloc_inline (n, 1); */
}

/* Clone STRING.  */

static char *xstrdup(char const *string)
{
	size_t s = strlen(string) + 1;
	return memcpy(xmalloc(s), string, s);
/*   return xmemdup_inline (string, strlen (string) + 1); */
}

/* Copy NUM_BYTES of buffer `in_buff' into IN_BUF.
   `in_buff' may be partly full.
   When `in_buff' is exhausted, refill it from file descriptor IN_DES.  */

static void tape_fill_input_buffer(int in_des, int num_bytes)
{
	in_buff = input_buffer;
	num_bytes = (num_bytes < io_block_size) ? num_bytes : io_block_size;
	input_size = read(in_des, input_buffer, num_bytes);
	if (input_size < 0) {
		fprintf(stderr, "%s: read error: %s\n", progname,
			strerror(errno));
		exit(1);
	}
	if (input_size == 0) {
		fprintf(stderr, "%s: premature end of file\n", progname);
		exit(1);
	}
	input_bytes += input_size;
}

/* Write `output_size' bytes of `output_buffer' to file
   descriptor OUT_DES and reset `output_size' and `out_buff'.
   If `swapping_halfwords' or `swapping_bytes' is set,
   do the appropriate swapping first.  Our callers have
   to make sure to only set these flags if `output_size'
   is appropriate (a multiple of 4 for `swapping_halfwords',
   2 for `swapping_bytes').  The fact that DISK_IO_BLOCK_SIZE
   must always be a multiple of 4 helps us (and our callers)
   insure this.  */

static void disk_empty_output_buffer(int out_des)
{
	int bytes_written;

	bytes_written = write(out_des, output_buffer, output_size);

	if (bytes_written != output_size) {
		fprintf(stderr, "%s: write error: %s\n",
			progname, strerror(errno));
		exit(1);
	}
	output_bytes += output_size;
	out_buff = output_buffer;
	output_size = 0;
}

/* Copy NUM_BYTES of buffer IN_BUF to `out_buff', which may be partly full.
   When `out_buff' fills up, flush it to file descriptor OUT_DES.  */

static void disk_buffered_write(char *in_buf, int out_des, long num_bytes)
{
	register long bytes_left = num_bytes;	/* Bytes needing to be copied.  */
	register long space_left;	/* Room left in output buffer.  */

	while (bytes_left > 0) {
		space_left = DISK_IO_BLOCK_SIZE - output_size;
		if (space_left == 0)
			disk_empty_output_buffer(out_des);
		else {
			if (bytes_left < space_left)
				space_left = bytes_left;
			memmove(out_buff, in_buf, (unsigned)space_left);
			out_buff += space_left;
			output_size += space_left;
			in_buf += space_left;
			bytes_left -= space_left;
		}
	}
}

/* Copy a file using the input and output buffers, which may start out
   partly full.  After the copy, the files are not closed nor the last
   block flushed to output, and the input buffer may still be partly
   full.  If `crc_i_flag' is set, add each byte to `crc'.
   IN_DES is the file descriptor for input;
   OUT_DES is the file descriptor for output;
   NUM_BYTES is the number of bytes to copy.  */

static void copy_files_tape_to_disk(int in_des, int out_des, long num_bytes)
{
	long size;

	while (num_bytes > 0) {
		if (input_size == 0)
			tape_fill_input_buffer(in_des, io_block_size);
		size = (input_size < num_bytes) ? input_size : num_bytes;
		disk_buffered_write(in_buff, out_des, size);
		num_bytes -= size;
		input_size -= size;
		in_buff += size;
	}
}

/* if IN_BUF is NULL, Skip the next NUM_BYTES bytes of file descriptor IN_DES. */
static void tape_buffered_read(char *in_buf, int in_des, long num_bytes)
{
	register long bytes_left = num_bytes;	/* Bytes needing to be copied.  */
	register long space_left;	/* Bytes to copy from input buffer.  */

	while (bytes_left > 0) {
		if (input_size == 0)
			tape_fill_input_buffer(in_des, io_block_size);
		if (bytes_left < input_size)
			space_left = bytes_left;
		else
			space_left = input_size;
		if (in_buf != NULL) {
			memmove(in_buf, in_buff, (unsigned)space_left);
			in_buf += space_left;
		}
		in_buff += space_left;
		input_size -= space_left;
		bytes_left -= space_left;
	}
}

/* Skip the next NUM_BYTES bytes of file descriptor IN_DES.  */
#define tape_toss_input(in_des,num_bytes) \
(tape_buffered_read(NULL,(in_des),(num_bytes)))

struct deferment {
	struct deferment *next;
	struct new_cpio_header header;
};

static struct deferment *create_deferment(struct new_cpio_header *file_hdr)
{
	struct deferment *d;
	d = (struct deferment *)xmalloc(sizeof(struct deferment));
	d->header = *file_hdr;
	d->header.c_name = (char *)xmalloc(strlen(file_hdr->c_name) + 1);
	strcpy(d->header.c_name, file_hdr->c_name);
	return d;
}

static void free_deferment(struct deferment *d)
{
	free(d->header.c_name);
	free(d);
}

static int link_to_name(char *link_name, char *link_target)
{
	int res = link(link_target, link_name);
	return res;
}

struct inode_val {
	unsigned long inode;
	unsigned long major_num;
	unsigned long minor_num;
	char *file_name;
};

/* Inode hash table.  Allocated by first call to add_inode.  */
static struct inode_val **hash_table = NULL;

/* Size of current hash table.  Initial size is 47.  (47 = 2*22 + 3) */
static int hash_size = 22;

/* Number of elements in current hash table.  */
static int hash_num;

/* Do the hash insert.  Used in normal inserts and resizing the hash
   table.  It is guaranteed that there is room to insert the item.
   NEW_VALUE is the pointer to the previously allocated inode, file
   name association record.  */

static void hash_insert(struct inode_val *new_value)
{
	int start;		/* Home position for the value.  */
	int temp;		/* Used for rehashing.  */

	/* Hash function is node number modulo the table size.  */
	start = new_value->inode % hash_size;

	/* Do the initial look into the table.  */
	if (hash_table[start] == NULL) {
		hash_table[start] = new_value;
		return;
	}

	/* If we get to here, the home position is full with a different inode
	   record.  Do a linear search for the first NULL pointer and insert
	   the new item there.  */
	temp = (start + 1) % hash_size;
	while (hash_table[temp] != NULL)
		temp = (temp + 1) % hash_size;

	/* Insert at the NULL.  */
	hash_table[temp] = new_value;
}

/* Associate FILE_NAME with the inode NODE_NUM.  (Insert into hash table.)  */

static void
add_inode(unsigned long node_num, char *file_name, unsigned long major_num,
	  unsigned long minor_num)
{
	struct inode_val *temp;

	/* Create new inode record.  */
	temp = (struct inode_val *)xmalloc(sizeof(struct inode_val));
	temp->inode = node_num;
	temp->major_num = major_num;
	temp->minor_num = minor_num;
	temp->file_name = xstrdup(file_name);

	/* Do we have to increase the size of (or initially allocate)
	   the hash table?  */
	if (hash_num == hash_size || hash_table == NULL) {
		struct inode_val **old_table;	/* Pointer to old table.  */
		int i;		/* Index for re-insert loop.  */

		/* Save old table.  */
		old_table = hash_table;
		if (old_table == NULL)
			hash_num = 0;

		/* Calculate new size of table and allocate it.
		   Sequence of table sizes is 47, 97, 197, 397, 797, 1597, 3197, 6397 ...
		   where 3197 and most of the sizes after 6397 are not prime.  The other
		   numbers listed are prime.  */
		hash_size = 2 * hash_size + 3;
		hash_table = (struct inode_val **)
		    xmalloc(hash_size * sizeof(struct inode_val *));
		memset(hash_table, 0, hash_size * sizeof(struct inode_val *));

		/* Insert the values from the old table into the new table.  */
		for (i = 0; i < hash_num; i++)
			hash_insert(old_table[i]);

		free(old_table);
	}

	/* Insert the new record and increment the count of elements in the
	   hash table.  */
	hash_insert(temp);
	hash_num++;
}

static char *find_inode_file(unsigned long node_num, unsigned long major_num,
		      unsigned long minor_num)
{
	int start;		/* Initial hash location.  */
	int temp;		/* Rehash search variable.  */

	if (hash_table != NULL) {
		/* Hash function is node number modulo the table size.  */
		start = node_num % hash_size;

		/* Initial look into the table.  */
		if (hash_table[start] == NULL)
			return NULL;
		if (hash_table[start]->inode == node_num
		    && hash_table[start]->major_num == major_num
		    && hash_table[start]->minor_num == minor_num)
			return hash_table[start]->file_name;

		/* The home position is full with a different inode record.
		   Do a linear search terminated by a NULL pointer.  */
		for (temp = (start + 1) % hash_size;
		     hash_table[temp] != NULL && temp != start;
		     temp = (temp + 1) % hash_size) {
			if (hash_table[temp]->inode == node_num
			    && hash_table[start]->major_num == major_num
			    && hash_table[start]->minor_num == minor_num)
				return hash_table[temp]->file_name;
		}
	}
	return NULL;
}

/* Try and create a hard link from FILE_NAME to another file
   with the given major/minor device number and inode.  If no other
   file with the same major/minor/inode numbers is known, add this file
   to the list of known files and associated major/minor/inode numbers
   and return -1.  If another file with the same major/minor/inode
   numbers is found, try and create another link to it using
   link_to_name, and return 0 for success and -1 for failure.  */

static int
link_to_maj_min_ino(char *file_name, int st_dev_maj, int st_dev_min, int st_ino)
{
	int link_res;
	char *link_name;
	link_res = -1;
	/* Is the file a link to a previously copied file?  */
	link_name = find_inode_file(st_ino, st_dev_maj, st_dev_min);
	if (link_name == NULL)
		add_inode(st_ino, file_name, st_dev_maj, st_dev_min);
	else
		link_res = link_to_name(file_name, link_name);
	return link_res;
}

static void copyin_regular_file(struct new_cpio_header *file_hdr,
				int in_file_des);

static void warn_junk_bytes(long bytes_skipped)
{
	fprintf(stderr, "%s: warning: skipped %ld byte(s) of junk\n",
		progname, bytes_skipped);
}

/* Skip the padding on IN_FILE_DES after a header or file,
   up to the next header.
   The number of bytes skipped is based on OFFSET -- the current offset
   from the last start of a header (or file) -- and the current
   header type.  */

static void tape_skip_padding(int in_file_des, int offset)
{
	int pad;
	pad = (4 - (offset % 4)) % 4;

	if (pad != 0)
		tape_toss_input(in_file_des, pad);
}

static int
try_existing_file(struct new_cpio_header *file_hdr, int in_file_des,
		  int *existing_dir)
{
	struct stat file_stat;

	*existing_dir = false;
	if (lstat(file_hdr->c_name, &file_stat) == 0) {
		if (S_ISDIR(file_stat.st_mode)
		    && ((file_hdr->c_mode & S_IFMT) == S_IFDIR)) {
			/* If there is already a directory there that
			   we are trying to create, don't complain about
			   it.  */
			*existing_dir = true;
			return 0;
		} else if (S_ISDIR(file_stat.st_mode)
			   ? rmdir(file_hdr->c_name)
			   : unlink(file_hdr->c_name)) {
			fprintf(stderr, "%s: cannot remove current %s: %s\n",
				progname, file_hdr->c_name, strerror(errno));
			tape_toss_input(in_file_des, file_hdr->c_filesize);
			tape_skip_padding(in_file_des, file_hdr->c_filesize);
			return -1;	/* Go to the next file.  */
		}
	}
	return 0;
}

/* The newc and crc formats store multiply linked copies of the same file
   in the archive only once.  The actual data is attached to the last link
   in the archive, and the other links all have a filesize of 0.  When a
   file in the archive has multiple links and a filesize of 0, its data is
   probably "attatched" to another file in the archive, so we can't create
   it right away.  We have to "defer" creating it until we have created
   the file that has the data "attatched" to it.  We keep a list of the
   "defered" links on deferments.  */

struct deferment *deferments = NULL;

/* Add a file header to the deferments list.  For now they all just
   go on one list, although we could optimize this if necessary.  */

static void defer_copyin(struct new_cpio_header *file_hdr)
{
	struct deferment *d;
	d = create_deferment(file_hdr);
	d->next = deferments;
	deferments = d;
	return;
}

/* We just created a file that (probably) has some other links to it
   which have been defered.  Go through all of the links on the deferments
   list and create any which are links to this file.  */

static void create_defered_links(struct new_cpio_header *file_hdr)
{
	struct deferment *d;
	struct deferment *d_prev;
	int ino;
	int maj;
	int min;
	int link_res;
	ino = file_hdr->c_ino;
	maj = file_hdr->c_dev_maj;
	min = file_hdr->c_dev_min;
	d = deferments;
	d_prev = NULL;
	while (d != NULL) {
		if ((d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
		    && (d->header.c_dev_min == min)) {
			struct deferment *d_free;
			link_res =
			    link_to_name(d->header.c_name, file_hdr->c_name);
			if (link_res < 0) {
				fprintf(stderr,
					"%s: cannot link %s to %s: %s\n",
					progname, d->header.c_name,
					file_hdr->c_name, strerror(errno));
			}
			if (d_prev != NULL)
				d_prev->next = d->next;
			else
				deferments = d->next;
			d_free = d;
			d = d->next;
			free_deferment(d_free);
		} else {
			d_prev = d;
			d = d->next;
		}
	}
}

/* If we had a multiply linked file that really was empty then we would
   have defered all of its links, since we never found any with data
   "attached", and they will still be on the deferment list even when
   we are done reading the whole archive.  Write out all of these
   empty links that are still on the deferments list.  */

static void create_final_defers(void)
{
	struct deferment *d;
	int link_res;
	int out_file_des;
	struct utimbuf times;	/* For setting file times.  */
	/* Initialize this in case it has members we don't know to set.  */
	memset(&times, 0, sizeof(struct utimbuf));

	for (d = deferments; d != NULL; d = d->next) {
		/* Debian hack: A line, which could cause an endless loop, was
		   removed (97/1/2).  It was reported by Ronald F. Guilmette to
		   the upstream maintainers. -BEM */
		/* Debian hack:  This was reported by Horst Knobloch. This bug has
		   been reported to "bug-gnu-utils@prep.ai.mit.edu". (99/1/6) -BEM
		 */
		link_res = link_to_maj_min_ino(d->header.c_name,
					       d->header.c_dev_maj,
					       d->header.c_dev_min,
					       d->header.c_ino);
		if (link_res == 0) {
			continue;
		}
		out_file_des = open(d->header.c_name,
				    O_CREAT | O_WRONLY | O_BINARY, 0600);
		if (out_file_des < 0) {
			fprintf(stderr, "%s: open %s: %s\n",
				progname, d->header.c_name, strerror(errno));
			continue;
		}

		/* File is now copied; set attributes.  */
		if ((fchown(out_file_des, d->header.c_uid, d->header.c_gid) < 0)
		    && errno != EPERM)
			fprintf(stderr, "%s: fchown %s: %s\n",
				progname, d->header.c_name, strerror(errno));
		/* chown may have turned off some permissions we wanted. */
		if (fchmod(out_file_des, (int)d->header.c_mode) < 0)
			fprintf(stderr, "%s: fchmod %s: %s\n",
				progname, d->header.c_name, strerror(errno));

		if (close(out_file_des) < 0)
			fprintf(stderr, "%s: close %s: %s\n",
				progname, d->header.c_name, strerror(errno));

	}
}

static void
copyin_regular_file(struct new_cpio_header *file_hdr, int in_file_des)
{
	int out_file_des;	/* Output file descriptor.  */

	/* Can the current file be linked to a previously copied file? */
	if (file_hdr->c_nlink > 1) {
		int link_res;
		if (file_hdr->c_filesize == 0) {
			/* The newc and crc formats store multiply linked copies
			   of the same file in the archive only once.  The
			   actual data is attached to the last link in the
			   archive, and the other links all have a filesize
			   of 0.  Since this file has multiple links and a
			   filesize of 0, its data is probably attatched to
			   another file in the archive.  Save the link, and
			   process it later when we get the actual data.  We
			   can't just create it with length 0 and add the
			   data later, in case the file is readonly.  We still
			   lose if its parent directory is readonly (and we aren't
			   running as root), but there's nothing we can do about
			   that.  */
			defer_copyin(file_hdr);
			tape_toss_input(in_file_des, file_hdr->c_filesize);
			tape_skip_padding(in_file_des, file_hdr->c_filesize);
			return;
		}
		/* If the file has data (filesize != 0), then presumably
		   any other links have already been defer_copyin'ed(),
		   but GNU cpio version 2.0-2.2 didn't do that, so we
		   still have to check for links here (and also in case
		   the archive was created and later appeneded to). */
		/* Debian hack: (97/1/2) This was reported by Ronald
		   F. Guilmette to the upstream maintainers. -BEM */
		link_res = link_to_maj_min_ino(file_hdr->c_name,
					       file_hdr->c_dev_maj,
					       file_hdr->c_dev_min,
					       file_hdr->c_ino);
		if (link_res == 0) {
			tape_toss_input(in_file_des, file_hdr->c_filesize);
			tape_skip_padding(in_file_des, file_hdr->c_filesize);
			return;
		}
	}

	/* If not linked, copy the contents of the file.  */
	out_file_des = open(file_hdr->c_name,
			    O_CREAT | O_WRONLY | O_BINARY, 0600);

	if (out_file_des < 0) {
		fprintf(stderr, "%s: open %s: %s\n",
			progname, file_hdr->c_name, strerror(errno));
		tape_toss_input(in_file_des, file_hdr->c_filesize);
		tape_skip_padding(in_file_des, file_hdr->c_filesize);
		return;
	}

	copy_files_tape_to_disk(in_file_des, out_file_des,
				file_hdr->c_filesize);
	disk_empty_output_buffer(out_file_des);

	if (close(out_file_des) < 0)
		fprintf(stderr, "%s: close %s: %s\n",
			progname, file_hdr->c_name, strerror(errno));

	/* File is now copied; set attributes.  */
	if ((chown(file_hdr->c_name, file_hdr->c_uid, file_hdr->c_gid) < 0)
	    && errno != EPERM)
		fprintf(stderr, "%s: chown %s: %s\n",
			progname, file_hdr->c_name, strerror(errno));

	/* chown may have turned off some permissions we wanted. */
	if (chmod(file_hdr->c_name, (int)file_hdr->c_mode) < 0)
		fprintf(stderr, "%s: chmod %s: %s\n",
			progname, file_hdr->c_name, strerror(errno));

	tape_skip_padding(in_file_des, file_hdr->c_filesize);
	if (file_hdr->c_nlink > 1) {
		/* (see comment above for how the newc and crc formats
		   store multiple links).  Now that we have the data
		   for this file, create any other links to it which
		   we defered.  */
		create_defered_links(file_hdr);
	}
}

/* In general, we can't use the builtin `basename' function if available,
   since it has different meanings in different environments.
   In some environments the builtin `basename' modifies its argument.

   Return the address of the last file name component of NAME.  If
   NAME has no file name components because it is all slashes, return
   NAME if it is empty, the address of its last slash otherwise.  */

static char *base_name(char const *name)
{
	char const *base = name;
	char const *p;

	for (p = base; *p; p++) {
		if (ISSLASH(*p)) {
			/* Treat multiple adjacent slashes like a single slash.  */
			do
				p++;
			while (ISSLASH(*p));

			/* If the file name ends in slash, use the trailing slash as
			   the basename if no non-slashes have been found.  */
			if (!*p) {
				if (ISSLASH(*base))
					base = p - 1;
				break;
			}

			/* *P is a non-slash preceded by a slash.  */
			base = p;
		}
	}

	return (char *)base;
}

/* Return the length of of the basename NAME.  Typically NAME is the
   value returned by base_name.  Act like strlen (NAME), except omit
   redundant trailing slashes.  */

static size_t base_len(char const *name)
{
	size_t len;

	for (len = strlen(name); 1 < len && ISSLASH(name[len - 1]); len--)
		continue;

	return len;
}

/* Remove trailing slashes from PATH.
   Return true if a trailing slash was removed.
   This is useful when using filename completion from a shell that
   adds a "/" after directory names (such as tcsh and bash), because
   the Unix rename and rmdir system calls return an "Invalid argument" error
   when given a path that ends in "/" (except for the root directory).  */

static bool strip_trailing_slashes(char *path)
{
	char *base = base_name(path);
	char *base_lim = base + base_len(base);
	bool had_slash = (*base_lim != '\0');
	*base_lim = '\0';
	return had_slash;
}

static void copyin_directory(struct new_cpio_header *file_hdr, int existing_dir)
{
	int res;		/* Result of various function calls.  */

	/* Strip any trailing `/'s off the filename; tar puts
	   them on.  We might as well do it here in case anybody
	   else does too, since they cause strange things to happen.  */
	strip_trailing_slashes(file_hdr->c_name);

	/* Ignore the current directory.  It must already exist,
	   and we don't want to change its permission, ownership
	   or time.  */
	if (file_hdr->c_name[0] == '.' && file_hdr->c_name[1] == '\0') {
		return;
	}

	if (!existing_dir)
	{
		res = mkdir(file_hdr->c_name, file_hdr->c_mode);
	} else
		res = 0;
	if (res < 0) {
		/* In some odd cases where the file_hdr->c_name includes `.',
		   the directory may have actually been created by
		   create_all_directories(), so the mkdir will fail
		   because the directory exists.  If that's the case,
		   don't complain about it.  */
		struct stat file_stat;
		if ((errno != EEXIST) ||
		    (lstat(file_hdr->c_name, &file_stat) != 0) ||
		    !(S_ISDIR(file_stat.st_mode))) {
			fprintf(stderr, "%s: lstat %s: %s\n",
				progname, file_hdr->c_name, strerror(errno));
			return;
		}
	}
	if ((chown(file_hdr->c_name, file_hdr->c_uid, file_hdr->c_gid) < 0)
	    && errno != EPERM)
		fprintf(stderr, "%s: chown %s: %s\n",
			progname, file_hdr->c_name, strerror(errno));
	/* chown may have turned off some permissions we wanted. */
	if (chmod(file_hdr->c_name, (int)file_hdr->c_mode) < 0)
		fprintf(stderr, "%s: chmod %s: %s\n",
			progname, file_hdr->c_name, strerror(errno));
}

static void copyin_device(struct new_cpio_header *file_hdr)
{
	int res;		/* Result of various function calls.  */

	if (file_hdr->c_nlink > 1) {
		int link_res;
		/* Debian hack:  This was reported by Horst
		   Knobloch. This bug has been reported to
		   "bug-gnu-utils@prep.ai.mit.edu". (99/1/6) -BEM */
		link_res = link_to_maj_min_ino(file_hdr->c_name,
					       file_hdr->c_dev_maj,
					       file_hdr->c_dev_min,
					       file_hdr->c_ino);
		if (link_res == 0) {
			return;
		}
	}

	res = mknod(file_hdr->c_name, file_hdr->c_mode,
		    makedev(file_hdr->c_rdev_maj, file_hdr->c_rdev_min));
	if (res < 0) {
		fprintf(stderr, "%s: mknod %s: %s\n", progname,
			file_hdr->c_name, strerror(errno));
		return;
	}
	if ((chown(file_hdr->c_name, file_hdr->c_uid, file_hdr->c_gid) < 0)
	    && errno != EPERM)
		fprintf(stderr, "%s: chown %s: %s\n", progname,
			file_hdr->c_name, strerror(errno));
	/* chown may have turned off some permissions we wanted. */
	if (chmod(file_hdr->c_name, file_hdr->c_mode) < 0)
		fprintf(stderr, "%s: chmod %s: %s\n", progname,
			file_hdr->c_name, strerror(errno));
}

static void copyin_link(struct new_cpio_header *file_hdr, int in_file_des)
{
	char *link_name = NULL;	/* Name of hard and symbolic links.  */
	int res;		/* Result of various function calls.  */

	link_name = (char *)xmalloc((unsigned int)file_hdr->c_filesize + 1);
	link_name[file_hdr->c_filesize] = '\0';
	tape_buffered_read(link_name, in_file_des, file_hdr->c_filesize);
	tape_skip_padding(in_file_des, file_hdr->c_filesize);

	res = symlink(link_name, file_hdr->c_name);
	if (res < 0) {
		fprintf(stderr, "%s: symlink %s: %s\n",
			progname, file_hdr->c_name, strerror(errno));
		free(link_name);
		return;
	}
	if ((lchown(file_hdr->c_name, file_hdr->c_uid, file_hdr->c_gid) < 0)
	    && errno != EPERM) {
		fprintf(stderr, "%s: lchown %s: %s\n",
			progname, file_hdr->c_name, strerror(errno));
	}
	free(link_name);
}

static void copyin_file(struct new_cpio_header *file_hdr, int in_file_des)
{
	int existing_dir;

	if (try_existing_file(file_hdr, in_file_des, &existing_dir) < 0)
		return;

	/* Do the real copy or link.  */
	switch (file_hdr->c_mode & S_IFMT) {
	case S_IFREG:
		copyin_regular_file(file_hdr, in_file_des);
		break;

	case S_IFDIR:
		copyin_directory(file_hdr, existing_dir);
		break;

	case S_IFCHR:
	case S_IFBLK:
	case S_IFSOCK:
	case S_IFIFO:
		copyin_device(file_hdr);
		break;

	case S_IFLNK:
		copyin_link(file_hdr, in_file_des);
		break;

	default:
		fprintf(stderr, "%s: %s: unknown file type\n",
			progname, file_hdr->c_name);
		tape_toss_input(in_file_des, file_hdr->c_filesize);
		tape_skip_padding(in_file_des, file_hdr->c_filesize);
	}
}

/* Fill in FILE_HDR by reading a new-format ASCII format cpio header from
   file descriptor IN_DES, except for the magic number, which is
   already filled in.  */

static void read_in_new_ascii(struct new_cpio_header *file_hdr, int in_des)
{
	char ascii_header[13*8], *ah, hexbuf[9];
	int i;

	tape_buffered_read(ascii_header, in_des, 13*8);
	ah = ascii_header;
	hexbuf[8] = '\0';
	for (i = 0; i < 13; i++) {
		memcpy(hexbuf, ah, 8);
		file_hdr->c_hdr[i] = strtoul(hexbuf, NULL, 16);
		ah += 8;
	}
	/* Read file name from input.  */
	free(file_hdr->c_name);
	file_hdr->c_name = (char *)xmalloc(file_hdr->c_namesize);
	tape_buffered_read(file_hdr->c_name, in_des,
			   (long)file_hdr->c_namesize);

	/* In SVR4 ASCII format, the amount of space allocated for the header
	   is rounded up to the next long-word, so we might need to drop
	   1-3 bytes.  */
	tape_skip_padding(in_des, file_hdr->c_namesize + 110);
}

/* Return 16-bit integer I with the bytes swapped.  */
#define swab_short(i) ((((i) << 8) & 0xff00) | (((i) >> 8) & 0x00ff))

/* Read the header, including the name of the file, from file
   descriptor IN_DES into FILE_HDR.  */

static void read_in_header(struct new_cpio_header *file_hdr, int in_des)
{
	long bytes_skipped = 0;	/* Bytes of junk found before magic number.  */

	/* Search for a valid magic number.  */

	file_hdr->c_tar_linkname = NULL;

	tape_buffered_read((char *)file_hdr, in_des, 6L);
	while (1) {
		if (!strncmp((char *)file_hdr, "070702", 6)
		    || !strncmp((char *)file_hdr, "070701", 6))
		{
			if (bytes_skipped > 0)
				warn_junk_bytes(bytes_skipped);

			read_in_new_ascii(file_hdr, in_des);
			break;
		}
		bytes_skipped++;
		memmove((char *)file_hdr, (char *)file_hdr + 1, 5);
		tape_buffered_read((char *)file_hdr + 5, in_des, 1L);
	}
}

/* Read the collection from standard input and create files
   in the file system.  */

static void process_copy_in(void)
{
	char done = false;	/* True if trailer reached.  */
	struct new_cpio_header file_hdr;	/* Output header information.  */
	int in_file_des;	/* Input file descriptor.  */

	/* Initialize the copy in.  */
	file_hdr.c_name = NULL;

	/* only from stdin */
	in_file_des = 0;

	/* While there is more input in the collection, process the input.  */
	while (!done) {
		/* Start processing the next file by reading the header.  */
		read_in_header(&file_hdr, in_file_des);

		/* Is this the header for the TRAILER file?  */
		if (strcmp("TRAILER!!!", file_hdr.c_name) == 0) {
			done = true;
			break;
		}

		/* Copy the input file into the directory structure.  */

		copyin_file(&file_hdr, in_file_des);

		if (dot_flag)
			fputc('.', stderr);
	}

	if (dot_flag)
		fputc('\n', stderr);

	create_final_defers();

}

/* Initialize the input and output buffers to their proper size and
   initialize all variables associated with the input and output
   buffers.  */

static void initialize_buffers(void)
{
	int in_buf_size, out_buf_size;

	/* Make sure the input buffer can always hold 2 blocks and that it
	   is big enough to hold 1 tar record (512 bytes) even if it
	   is not aligned on a block boundary.  The extra buffer space
	   is needed by process_copyin and peek_in_buf to automatically
	   figure out what kind of archive it is reading.  */
	if (io_block_size >= 512)
		in_buf_size = 2 * io_block_size;
	else
		in_buf_size = 1024;
	out_buf_size = DISK_IO_BLOCK_SIZE;

	input_buffer = (char *)xmalloc(in_buf_size);
	in_buff = input_buffer;
	input_buffer_size = in_buf_size;
	input_size = 0;
	input_bytes = 0;

	output_buffer = (char *)xmalloc(out_buf_size);
	out_buff = output_buffer;
	output_size = 0;
	output_bytes = 0;

}

int main(int argc, char *argv[])
{
	int c;
	int extract_flag = false;

	progname = argv[0];

	do {
		c = getopt(argc, argv, "iV");
		if (c == EOF)
			break;
		switch (c) {
		case 'V':
			dot_flag = true;
			break;

		case 'i':
			extract_flag = true;
			break;
		case '?':
			fprintf(stderr,
				"%s: not implemented or invalid option -%c\n",
				progname, optopt);
			exit(1);

		}
	} while (1);

	if (extract_flag) {
		initialize_buffers();

		process_copy_in();
	} else {
		fprintf(stderr, "Usage: %s [-V] -i [< archive]\n", progname);
		exit(1);
	}

	return 0;
}
