home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 7
/
FreshFishVol7.bin
/
bbs
/
gnu
/
cpio-2.3-src.lha
/
GNU
/
src
/
amiga
/
cpio-2.3
/
copyout.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-28
|
23KB
|
802 lines
/* copyout.c - create a cpio archive
Copyright (C) 1990, 1991, 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "filetypes.h"
#include "system.h"
#include "cpiohdr.h"
#include "dstring.h"
#include "extern.h"
#include "defer.h"
#include "rmt.h"
static unsigned long read_for_checksum ();
static void clear_rest_of_block ();
static void pad_output ();
static int last_link ();
static int count_defered_links_to_dev_ino ();
static void add_link_defer ();
static void writeout_other_defers ();
static void writeout_final_defers();
static void writeout_defered_file ();
/* Write out header FILE_HDR, including the file name, to file
descriptor OUT_DES. */
void
write_out_header (file_hdr, out_des)
struct new_cpio_header *file_hdr;
int out_des;
{
if (archive_format == arf_newascii || archive_format == arf_crcascii)
{
char ascii_header[112];
char *magic_string;
if (archive_format == arf_crcascii)
magic_string = "070702";
else
magic_string = "070701";
sprintf (ascii_header,
"%6s%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx",
magic_string,
file_hdr->c_ino, file_hdr->c_mode, file_hdr->c_uid,
file_hdr->c_gid, file_hdr->c_nlink, file_hdr->c_mtime,
file_hdr->c_filesize, file_hdr->c_dev_maj, file_hdr->c_dev_min,
file_hdr->c_rdev_maj, file_hdr->c_rdev_min, file_hdr->c_namesize,
file_hdr->c_chksum);
copy_buf_out (ascii_header, out_des, 110L);
/* Write file name to output. */
copy_buf_out (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
pad_output (out_des, file_hdr->c_namesize + 110);
}
else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
{
char ascii_header[78];
#ifndef __MSDOS__
dev_t dev;
dev_t rdev;
if (archive_format == arf_oldascii)
{
dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
}
else
{
/* HP/UX cpio creates archives that look just like ordinary archives,
but for devices it sets major = 0, minor = 1, and puts the
actual major/minor number in the filesize field. */
switch (file_hdr->c_mode & CP_IFMT)
{
case CP_IFCHR:
case CP_IFBLK:
#ifdef CP_IFSOCK
case CP_IFSOCK:
#endif
#ifdef CP_IFIFO
case CP_IFIFO:
#endif
file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
file_hdr->c_rdev_min);
rdev = 1;
break;
default:
dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
break;
}
}
#else
int dev = 0, rdev = 0;
#endif
if ((file_hdr->c_ino >> 16) != 0)
error (0, 0, "%s: truncating inode number", file_hdr->c_name);
sprintf (ascii_header,
"%06lo%06lo%06lo%06lo%06lo%06lo%06lo%06lo%011lo%06lo%011lo",
file_hdr->c_magic & 0xFFFF, dev & 0xFFFF,
file_hdr->c_ino & 0xFFFF, file_hdr->c_mode & 0xFFFF,
file_hdr->c_uid & 0xFFFF, file_hdr->c_gid & 0xFFFF,
file_hdr->c_nlink & 0xFFFF, rdev & 0xFFFF,
file_hdr->c_mtime, file_hdr->c_namesize & 0xFFFF,
file_hdr->c_filesize);
copy_buf_out (ascii_header, out_des, 76L);
/* Write file name to output. */
copy_buf_out (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
}
else if (archive_format == arf_tar || archive_format == arf_ustar)
{
write_out_tar_header (file_hdr, out_des);
}
else
{
struct old_cpio_header short_hdr;
short_hdr.c_magic = 070707;
short_hdr.c_dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
if ((file_hdr->c_ino >> 16) != 0)
error (0, 0, "%s: truncating inode number", file_hdr->c_name);
short_hdr.c_ino = file_hdr->c_ino & 0xFFFF;
short_hdr.c_mode = file_hdr->c_mode & 0xFFFF;
short_hdr.c_uid = file_hdr->c_uid & 0xFFFF;
short_hdr.c_gid = file_hdr->c_gid & 0xFFFF;
short_hdr.c_nlink = file_hdr->c_nlink & 0xFFFF;
if (archive_format != arf_hpbinary)
short_hdr.c_rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
else
{
switch (file_hdr->c_mode & CP_IFMT)
{
/* HP/UX cpio creates archives that look just like ordinary
archives, but for devices it sets major = 0, minor = 1, and
puts the actual major/minor number in the filesize field. */
case CP_IFCHR:
case CP_IFBLK:
#ifdef CP_IFSOCK
case CP_IFSOCK:
#endif
#ifdef CP_IFIFO
case CP_IFIFO:
#endif
file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
file_hdr->c_rdev_min);
short_hdr.c_rdev = makedev (0, 1);
break;
default:
short_hdr.c_rdev = makedev (file_hdr->c_rdev_maj,
file_hdr->c_rdev_min);
break;
}
}
short_hdr.c_mtimes[0] = file_hdr->c_mtime >> 16;
short_hdr.c_mtimes[1] = file_hdr->c_mtime & 0xFFFF;
short_hdr.c_namesize = file_hdr->c_namesize & 0xFFFF;
short_hdr.c_filesizes[0] = file_hdr->c_filesize >> 16;
short_hdr.c_filesizes[1] = file_hdr->c_filesize & 0xFFFF;
/* Output the file header. */
copy_buf_out ((char *) &short_hdr, out_des, 26L);
/* Write file name to output. */
copy_buf_out (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
pad_output (out_des, file_hdr->c_namesize + 26);
}
}
/* Read a list of file names from the standard input
and write a cpio collection on the standard output.
The format of the header depends on the compatibility (-c) flag. */
void
process_copy_out ()
{
int res; /* Result of functions. */
dynamic_string input_name; /* Name of file read from stdin. */
struct utimbuf times; /* For resetting file times after copy. */
struct stat file_stat; /* Stat record for file. */
struct new_cpio_header file_hdr; /* Output header information. */
int in_file_des; /* Source file descriptor. */
int out_file_des; /* Output file descriptor. */
char *p;
/* Initialize the copy out. */
ds_init (&input_name, 128);
/* Initialize this in case it has members we don't know to set. */
bzero (×, sizeof (struct utimbuf));
file_hdr.c_magic = 070707;
#ifdef __MSDOS__
setmode (archive_des, O_BINARY);
#endif
/* Check whether the output file might be a tape. */
out_file_des = archive_des;
if (_isrmt (out_file_des))
{
output_is_special = 1;
output_is_seekable = 0;
}
else
{
if (fstat (out_file_des, &file_stat))
error (1, errno, "standard output is closed");
output_is_special =
#ifdef S_ISBLK
S_ISBLK (file_stat.st_mode) ||
#endif
S_ISCHR (file_stat.st_mode);
output_is_seekable = S_ISREG (file_stat.st_mode);
}
if (append_flag)
{
process_copy_in ();
prepare_append (out_file_des);
}
/* Copy files with names read from stdin. */
while (ds_fgetstr (stdin, &input_name, name_end) != NULL)
{
/* Check for blank line. */
if (input_name.ds_string[0] == 0)
{
error (0, 0, "blank line ignored");
continue;
}
/* Process next file. */
if ((*xstat) (input_name.ds_string, &file_stat) < 0)
error (0, errno, "%s", input_name.ds_string);
else
{
/* Set values in output header. */
file_hdr.c_dev_maj = major (file_stat.st_dev);
file_hdr.c_dev_min = minor (file_stat.st_dev);
file_hdr.c_ino = file_stat.st_ino;
/* For POSIX systems that don't define the S_I