home *** CD-ROM | disk | FTP | other *** search
- /* copyout.c - cpio copy out sub-function.
- Copyright (C) 1988, 1989, 1990 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 1, 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. */
-
- /* MS-DOS port (c) 1990 by Thorsten Ohl, ohl@gnu.ai.mit.edu
- This port is also distributed under the terms of the
- GNU General Public License as published by the
- Free Software Foundation.
-
- Please note that this file is not identical to the
- original GNU release, you should have received this
- code as patch to the official release.
-
- $Header: e:/gnu/cpio/RCS/copyout.c 1.1.0.2 90/09/23 23:33:23 tho Exp $
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifndef S_IFLNK
- #define lstat stat
- #endif
- #include <errno.h>
- #ifndef MSDOS /* sigh, it's `volatile' !!! */
- extern int errno;
- #endif
- #include <fcntl.h>
- #ifndef MSDOS
- #include <sys/file.h>
- #endif
- #ifdef USG
- #include <time.h>
- #include <string.h>
- #else
- #include <sys/time.h>
- #include <strings.h>
- #endif
- #include "cpio.h"
- #include "dstring.h"
- #include "extern.h"
-
- /* Write out header FILE_HDR, including the file name, to file
- descriptor OUT_DES. */
-
- void
- write_out_header (file_hdr, out_des)
- struct cpio_header *file_hdr;
- int out_des;
- {
- if (portability_flag)
- {
- char ascii_header[78];
-
-
- sprintf (ascii_header,
- #ifdef MSDOS
- "%06ho%06ho%06ho%06ho%06ho%06ho%06ho%06ho%011lo%06ho%011lo",
- #else
- "%06o%06o%06o%06o%06o%06o%06o%06o%011o%06o%011o",
- #endif
- file_hdr->h_magic & 0xFFFF, file_hdr->h_dev & 0xFFFF,
- file_hdr->h_ino & 0xFFFF, file_hdr->h_mode & 0xFFFF,
- file_hdr->h_uid & 0xFFFF, file_hdr->h_gid & 0xFFFF,
- file_hdr->h_nlink & 0xFFFF, file_hdr->h_rdev & 0xFFFF,
- file_hdr->h_mtime, file_hdr->h_namesize & 0xFFFF,
- file_hdr->h_filesize);
- copy_buf_out (ascii_header, out_des, 76);
-
- /* Write file name to output. */
- copy_buf_out (file_hdr->h_name, out_des, file_hdr->h_namesize);
- }
- else
- {
- /* Word align the output. */
- if (output_size & 1)
- copy_buf_out ("", out_des, 1);
-
- #ifdef MSDOS
- file_hdr->h_mtimes[0] = (unsigned int) (file_hdr->h_mtime >> 16);
- file_hdr->h_mtimes[1] = (unsigned int) (file_hdr->h_mtime & 0xFFFF);
-
- file_hdr->h_filesizes[0]
- = (unsigned int) (file_hdr->h_filesize >> 16);
- file_hdr->h_filesizes[1]
- = (unsigned int) (file_hdr->h_filesize & 0xFFFF);
- #else /* not MSDOS */
- file_hdr->h_mtimes[0] = file_hdr->h_mtime >> 16;
- file_hdr->h_mtimes[1] = file_hdr->h_mtime & 0xFFFF;
-
- file_hdr->h_filesizes[0] = file_hdr->h_filesize >> 16;
- file_hdr->h_filesizes[1] = file_hdr->h_filesize & 0xFFFF;
- #endif /* not MSDOS */
-
- /* Output the file header. */
- copy_buf_out ((char *) file_hdr, out_des, 26);
-
- /* Write file name to output. */
- copy_buf_out (file_hdr->h_name, out_des, file_hdr->h_namesize);
-
- /* Word align the output. */
- if (file_hdr->h_namesize % 2)
- copy_buf_out ("", out_des, 1);
- }
- }
-
- /* 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. */
- long times[2]; /* For resetting file times after copy. */
- struct stat file_stat; /* Stat record for file. */
- struct cpio_header file_hdr; /* Output header information. */
- int in_file_des; /* Source file descriptor. */
- int out_file_des; /* Output file descriptor. */
-
- #ifdef MSDOS
- setmode (fileno (stdout), O_BINARY);
- #endif
-
- /* Initialize copy out. */
- ds_init (&input_name, 128);
- file_hdr.h_magic = 070707;
-
- /* Check whether the output file might be a tape. */
- out_file_des = fileno (stdout);
- if (fstat (out_file_des, &file_stat))
- error (1, errno, "standard output is closed");
- #ifdef S_IFBLK
- output_is_special = ((file_stat.st_mode & S_IFMT) == S_IFCHR
- || (file_stat.st_mode & S_IFMT) == S_IFBLK);
- #else /* not S_IFBLK */
- output_is_special = ((file_stat.st_mode & S_IFMT) == S_IFCHR);
- #endif /* not S_IFBLK */
- output_is_seekable = ((file_stat.st_mode & S_IFMT) == S_IFREG);
-
- /* Copy files with names read from stdin. */
- while (ds_fgets (stdin, &input_name) != 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.h_dev = file_stat.st_dev;
- file_hdr.h_ino = file_stat.st_ino;
- file_hdr.h_mode = file_stat.st_mode;
- file_hdr.h_uid = file_stat.st_uid;
- file_hdr.h_gid = file_stat.st_gid;
- file_hdr.h_nlink = file_stat.st_nlink;
- file_hdr.h_rdev = file_stat.st_rdev;
- file_hdr.h_mtime = file_stat.st_mtime;
- file_hdr.h_filesize = file_stat.st_size;
- file_hdr.h_namesize = ds_strlen (&input_name) + 1;
- file_hdr.h_name = input_name.ds_string;
-
- /* Copy the named file to the output. */
- switch (file_hdr.h_mode & S_IFMT)
- {
- case S_IFREG:
- #ifdef MSDOS
- in_file_des = open (input_name.ds_string,
- O_RDONLY | O_BINARY, 0);
- #else
- in_file_des = open (input_name.ds_string, O_RDONLY, 0);
- #endif
- if (in_file_des < 0)
- {
- error (0, errno, "%s", input_name.ds_string);
- continue;
- }
-
- write_out_header (&file_hdr, out_file_des);
- copy_files (in_file_des, out_file_des, file_hdr.h_filesize);
- close (in_file_des);
- if (reset_time_flag)
- {
- times[0] = file_stat.st_atime;
- times[1] = file_stat.st_mtime;
- if (utime (file_hdr.h_name, times) < 0)
- error (0, errno, "%s", file_hdr.h_name);
- }
- break;
-
- case S_IFDIR:
- file_hdr.h_filesize = 0;
- write_out_header (&file_hdr, out_file_des);
- break;
-
- case S_IFCHR:
- #ifdef S_IFBLK
- case S_IFBLK:
- #endif
- #ifdef S_IFSOCK
- case S_IFSOCK:
- #endif
- #ifdef S_IFIFO
- case S_IFIFO:
- #endif
- file_hdr.h_filesize = 0;
- write_out_header (&file_hdr, out_file_des);
- break;
-
- #ifdef S_IFLNK
- case S_IFLNK:
- {
- char *link_name = (char *) xmalloc (file_stat.st_size);
-
- if (readlink (input_name.ds_string, link_name,
- file_stat.st_size) < 0)
- {
- error (0, errno, "%s", input_name.ds_string);
- free (link_name);
- continue;
- }
- write_out_header (&file_hdr, out_file_des);
- copy_buf_out (link_name, out_file_des, file_stat.st_size);
- free (link_name);
- }
- break;
- #endif
-
- default:
- error (0, 0, "%s: unknown file type", input_name.ds_string);
- }
-
- if (verbose_flag)
- fprintf (stderr, "%s\n", input_name.ds_string);
- }
- }
-
- /* The collection is complete; append the trailer. */
- file_hdr.h_filesize = 0;
- file_hdr.h_namesize = 11;
- file_hdr.h_name = "TRAILER!!!";
- write_out_header (&file_hdr, out_file_des);
-
- /* Fill up the output block. */
- while (output_size < io_block_size)
- {
- copy_buf_out (output_buffer, out_file_des,
- (2 * output_size < io_block_size) ?
- output_size : io_block_size - output_size);
- }
- empty_output_buffer (out_file_des);
- finish_output_file ("standard output", out_file_des);
- #ifdef MSDOS
- res = (int) (output_bytes / io_block_size);
- #else
- res = output_bytes / io_block_size;
- #endif
- if (res == 1)
- fprintf (stderr, "1 block\n");
- else
- fprintf (stderr, "%d blocks\n", res);
- }
-