diff options
author | tjr <tjr@FreeBSD.org> | 2005-10-01 04:47:43 +0000 |
---|---|---|
committer | tjr <tjr@FreeBSD.org> | 2005-10-01 04:47:43 +0000 |
commit | 97bb17a0b0cbdf752f776d2e68fa0faf87f5ba67 (patch) | |
tree | 5b8e67bbd15e90412bf5de6828a118728be6dbef /contrib/cpio/util.c | |
parent | c41ca4418deb57520faccf540a96bc118d6bb3e6 (diff) | |
download | FreeBSD-src-97bb17a0b0cbdf752f776d2e68fa0faf87f5ba67.zip FreeBSD-src-97bb17a0b0cbdf752f776d2e68fa0faf87f5ba67.tar.gz |
Remove files no longer present in GNU cpio distribution. Most of these
were actually moved into subdirectories.
Diffstat (limited to 'contrib/cpio/util.c')
-rw-r--r-- | contrib/cpio/util.c | 1343 |
1 files changed, 0 insertions, 1343 deletions
diff --git a/contrib/cpio/util.c b/contrib/cpio/util.c deleted file mode 100644 index 216041f..0000000 --- a/contrib/cpio/util.c +++ /dev/null @@ -1,1343 +0,0 @@ -/* util.c - Several utility routines for cpio. - 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> -#ifdef HPUX_CDF -#include <sys/stat.h> -#endif -#include "system.h" -#include "cpiohdr.h" -#include "dstring.h" -#include "extern.h" -#include "rmt.h" - -#ifndef __MSDOS__ -#include <sys/ioctl.h> -#else -#include <io.h> -#endif - -#ifdef HAVE_SYS_MTIO_H -#ifdef HAVE_SYS_IO_TRIOCTL_H -#include <sys/io/trioctl.h> -#endif -#include <sys/mtio.h> -#endif - -static void tape_fill_input_buffer P_((int in_des, int num_bytes)); -static int disk_fill_input_buffer P_((int in_des, int num_bytes)); -static void hash_insert (); -static void write_nuls_to_file P_((long num_bytes, int out_des)); - -/* Write `output_size' bytes of `output_buffer' to file - descriptor OUT_DES and reset `output_size' and `out_buff'. */ - -void -tape_empty_output_buffer (out_des) - int out_des; -{ - int bytes_written; - -#ifdef BROKEN_LONG_TAPE_DRIVER - static long output_bytes_before_lseek = 0; - - /* Some tape drivers seem to have a signed internal seek pointer and - they lose if it overflows and becomes negative (e.g. when writing - tapes > 2Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the - seek pointer and prevent it from overflowing. */ - if (output_is_special - && ( (output_bytes_before_lseek += output_size) >= 1073741824L) ) - { - lseek(out_des, 0L, SEEK_SET); - output_bytes_before_lseek = 0; - } -#endif - - bytes_written = rmtwrite (out_des, output_buffer, output_size); - if (bytes_written != output_size) - { - int rest_bytes_written; - int rest_output_size; - - if (output_is_special - && (bytes_written >= 0 - || (bytes_written < 0 - && (errno == ENOSPC || errno == EIO || errno == ENXIO)))) - { - get_next_reel (out_des); - if (bytes_written > 0) - rest_output_size = output_size - bytes_written; - else - rest_output_size = output_size; - rest_bytes_written = rmtwrite (out_des, output_buffer, - rest_output_size); - if (rest_bytes_written != rest_output_size) - error (1, errno, "write error"); - } - else - error (1, errno, "write error"); - } - output_bytes += output_size; - out_buff = output_buffer; - output_size = 0; -} - -/* 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. */ - -void -disk_empty_output_buffer (out_des) - int out_des; -{ - int bytes_written; - - if (swapping_halfwords || swapping_bytes) - { - if (swapping_halfwords) - { - int complete_words; - complete_words = output_size / 4; - swahw_array (output_buffer, complete_words); - if (swapping_bytes) - swab_array (output_buffer, 2 * complete_words); - } - else - { - int complete_halfwords; - complete_halfwords = output_size /2; - swab_array (output_buffer, complete_halfwords); - } - } - - if (sparse_flag) - bytes_written = sparse_write (out_des, output_buffer, output_size); - else - bytes_written = write (out_des, output_buffer, output_size); - - if (bytes_written != output_size) - { - error (1, errno, "write error"); - } - output_bytes += output_size; - out_buff = output_buffer; - output_size = 0; -} - -/* Exchange the halfwords of each element of the array of COUNT longs - starting at PTR. PTR does not have to be aligned at a word - boundary. */ - -void -swahw_array (ptr, count) - char *ptr; - int count; -{ - char tmp; - - for (; count > 0; --count) - { - tmp = *ptr; - *ptr = *(ptr + 2); - *(ptr + 2) = tmp; - ++ptr; - tmp = *ptr; - *ptr = *(ptr + 2); - *(ptr + 2) = tmp; - ptr += 3; - } -} - -/* Read at most NUM_BYTES or `io_block_size' bytes, whichever is smaller, - into the start of `input_buffer' from file descriptor IN_DES. - Set `input_size' to the number of bytes read and reset `in_buff'. - Exit with an error if end of file is reached. */ - -#ifdef BROKEN_LONG_TAPE_DRIVER -static long input_bytes_before_lseek = 0; -#endif - -static void -tape_fill_input_buffer (in_des, num_bytes) - int in_des; - int num_bytes; -{ -#ifdef BROKEN_LONG_TAPE_DRIVER - /* Some tape drivers seem to have a signed internal seek pointer and - they lose if it overflows and becomes negative (e.g. when writing - tapes > 4Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the - seek pointer and prevent it from overflowing. */ - if (input_is_special - && ( (input_bytes_before_lseek += num_bytes) >= 1073741824L) ) - { - lseek(in_des, 0L, SEEK_SET); - input_bytes_before_lseek = 0; - } -#endif - in_buff = input_buffer; - num_bytes = (num_bytes < io_block_size) ? num_bytes : io_block_size; - input_size = rmtread (in_des, input_buffer, num_bytes); - if (input_size == 0 && input_is_special) - { - get_next_reel (in_des); - input_size = rmtread (in_des, input_buffer, num_bytes); - } - if (input_size < 0) - error (1, errno, "read error"); - if (input_size == 0) - { - error (0, 0, "premature end of file"); - exit (1); - } - input_bytes += input_size; -} - -/* Read at most NUM_BYTES or `DISK_IO_BLOCK_SIZE' bytes, whichever is smaller, - into the start of `input_buffer' from file descriptor IN_DES. - Set `input_size' to the number of bytes read and reset `in_buff'. - Exit with an error if end of file is reached. */ - -static int -disk_fill_input_buffer (in_des, num_bytes) - int in_des; - int num_bytes; -{ - in_buff = input_buffer; - num_bytes = (num_bytes < DISK_IO_BLOCK_SIZE) ? num_bytes : DISK_IO_BLOCK_SIZE; - input_size = read (in_des, input_buffer, num_bytes); - if (input_size < 0) - { - input_size = 0; - return (-1); - } - else if (input_size == 0) - return (1); - input_bytes += input_size; - return (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. */ - -void -tape_buffered_write (in_buf, out_des, num_bytes) - 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 = io_block_size - output_size; - if (space_left == 0) - tape_empty_output_buffer (out_des); - else - { - if (bytes_left < space_left) - space_left = bytes_left; - bcopy (in_buf, out_buff, (unsigned) space_left); - out_buff += space_left; - output_size += space_left; - in_buf += space_left; - bytes_left -= space_left; - } - } -} - -/* 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. */ - -void -disk_buffered_write (in_buf, out_des, num_bytes) - 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; - bcopy (in_buf, out_buff, (unsigned) space_left); - out_buff += space_left; - output_size += space_left; - in_buf += space_left; - bytes_left -= space_left; - } - } -} - -/* 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. */ - -void -tape_buffered_read (in_buf, in_des, num_bytes) - 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; - bcopy (in_buff, in_buf, (unsigned) space_left); - in_buff += space_left; - in_buf += space_left; - input_size -= space_left; - bytes_left -= space_left; - } -} - -/* Copy the the next NUM_BYTES bytes of `input_buffer' into PEEK_BUF. - If NUM_BYTES bytes are not available, read the next `io_block_size' bytes - into the end of `input_buffer' and update `input_size'. - - Return the number of bytes copied into PEEK_BUF. - If the number of bytes returned is less than NUM_BYTES, - then EOF has been reached. */ - -int -tape_buffered_peek (peek_buf, in_des, num_bytes) - char *peek_buf; - int in_des; - int num_bytes; -{ - long tmp_input_size; - long got_bytes; - char *append_buf; - -#ifdef BROKEN_LONG_TAPE_DRIVER - /* Some tape drivers seem to have a signed internal seek pointer and - they lose if it overflows and becomes negative (e.g. when writing - tapes > 4Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the - seek pointer and prevent it from overflowing. */ - if (input_is_special - && ( (input_bytes_before_lseek += num_bytes) >= 1073741824L) ) - { - lseek(in_des, 0L, SEEK_SET); - input_bytes_before_lseek = 0; - } -#endif - - while (input_size < num_bytes) - { - append_buf = in_buff + input_size; - if ( (append_buf - input_buffer) >= input_buffer_size) - { - /* We can keep up to 2 "blocks" (either the physical block size - or 512 bytes(the size of a tar record), which ever is - larger) in the input buffer when we are peeking. We - assume that our caller will never be interested in peeking - ahead at more than 512 bytes, so we know that by the time - we need a 3rd "block" in the buffer we can throw away the - first block to make room. */ - int half; - half = input_buffer_size / 2; - bcopy (input_buffer + half, input_buffer, half); - in_buff = in_buff - half; - append_buf = append_buf - half; - } - tmp_input_size = rmtread (in_des, append_buf, io_block_size); - if (tmp_input_size == 0) - { - if (input_is_special) - { - get_next_reel (in_des); - tmp_input_size = rmtread (in_des, append_buf, io_block_size); - } - else - break; - } - if (tmp_input_size < 0) - error (1, errno, "read error"); - input_bytes += tmp_input_size; - input_size += tmp_input_size; - } - if (num_bytes <= input_size) - got_bytes = num_bytes; - else - got_bytes = input_size; - bcopy (in_buff, peek_buf, (unsigned) got_bytes); - return got_bytes; -} - -/* Skip the next NUM_BYTES bytes of file descriptor IN_DES. */ - -void -tape_toss_input (in_des, num_bytes) - 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 (crc_i_flag && only_verify_crc_flag) - { - int k; - for (k = 0; k < space_left; ++k) - crc += in_buff[k] & 0xff; - } - - in_buff += space_left; - input_size -= 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. */ - -void -copy_files_tape_to_disk (in_des, out_des, num_bytes) - int in_des; - int out_des; - long num_bytes; -{ - long size; - long k; - - 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; - if (crc_i_flag) - { - for (k = 0; k < size; ++k) - crc += in_buff[k] & 0xff; - } - disk_buffered_write (in_buff, out_des, size); - num_bytes -= size; - input_size -= size; - in_buff += size; - } -} -/* 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. */ - -void -copy_files_disk_to_tape (in_des, out_des, num_bytes, filename) - int in_des; - int out_des; - long num_bytes; - char *filename; -{ - long size; - long k; - int rc; - long original_num_bytes; - - original_num_bytes = num_bytes; - - while (num_bytes > 0) - { - if (input_size == 0) - if (rc = disk_fill_input_buffer (in_des, DISK_IO_BLOCK_SIZE)) - { - if (rc > 0) - error (0, 0, "File %s shrunk by %ld bytes, padding with zeros", - filename, num_bytes); - else - error (0, 0, "Read error at byte %ld in file %s, padding with zeros", - original_num_bytes - num_bytes, filename); - write_nuls_to_file (num_bytes, out_des); - break; - } - size = (input_size < num_bytes) ? input_size : num_bytes; - if (crc_i_flag) - { - for (k = 0; k < size; ++k) - crc += in_buff[k] & 0xff; - } - tape_buffered_write (in_buff, out_des, size); - num_bytes -= size; - input_size -= size; - in_buff += size; - } -} -/* 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. */ - -void -copy_files_disk_to_disk (in_des, out_des, num_bytes, filename) - int in_des; - int out_des; - long num_bytes; - char *filename; -{ - long size; - long k; - long original_num_bytes; - int rc; - - original_num_bytes = num_bytes; - while (num_bytes > 0) - { - if (input_size == 0) - if (rc = disk_fill_input_buffer (in_des, DISK_IO_BLOCK_SIZE)) - { - if (rc > 0) - error (0, 0, "File %s shrunk by %ld bytes, padding with zeros", - filename, num_bytes); - else - error (0, 0, "Read error at byte %ld in file %s, padding with zeros", - original_num_bytes - num_bytes, filename); - write_nuls_to_file (num_bytes, out_des); - break; - } - size = (input_size < num_bytes) ? input_size : num_bytes; - if (crc_i_flag) - { - for (k = 0; k < size; ++k) - crc += in_buff[k] & 0xff; - } - disk_buffered_write (in_buff, out_des, size); - num_bytes -= size; - input_size -= size; - in_buff += size; - } -} - -/* Create all directories up to but not including the last part of NAME. - Do not destroy any nondirectories while creating directories. */ - -void -create_all_directories (name) - char *name; -{ - char *dir; - int mode; -#ifdef HPUX_CDF - int cdf; -#endif - - dir = dirname (name); - mode = 0700; -#ifdef HPUX_CDF - cdf = islastparentcdf (name); - if (cdf) - { - dir [strlen (dir) - 1] = '\0'; /* remove final + */ - mode = 04700; - } - -#endif - - if (dir == NULL) - error (2, 0, "virtual memory exhausted"); - - if (dir[0] != '.' || dir[1] != '\0') - make_path (dir, mode, 0700, -1, -1, (char *) NULL); - - free (dir); -} - -/* Prepare to append to an archive. We have been in - process_copy_in, keeping track of the position where - the last header started in `last_header_start'. Now we - have the starting position of the last header (the TRAILER!!! - header, or blank record for tar archives) and we want to start - writing (appending) over the last header. The last header may - be in the middle of a block, so to keep the buffering in sync - we lseek back to the start of the block, read everything up - to but not including the last header, lseek back to the start - of the block, and then do a copy_buf_out of what we read. - Actually, we probably don't have to worry so much about keeping the - buffering perfect since you can only append to archives that - are disk files. */ - -void -prepare_append (out_file_des) - int out_file_des; -{ - int start_of_header; - int start_of_block; - int useful_bytes_in_block; - char *tmp_buf; - - start_of_header = last_header_start; - /* Figure out how many bytes we will rewrite, and where they start. */ - useful_bytes_in_block = start_of_header % io_block_size; - start_of_block = start_of_header - useful_bytes_in_block; - - if (lseek (out_file_des, start_of_block, SEEK_SET) < 0) - error (1, errno, "cannot seek on output"); - if (useful_bytes_in_block > 0) - { - tmp_buf = (char *) xmalloc (useful_bytes_in_block); - read (out_file_des, tmp_buf, useful_bytes_in_block); - if (lseek (out_file_des, start_of_block, SEEK_SET) < 0) - error (1, errno, "cannot seek on output"); - /* fix juo -- is this copy_tape_buf_out? or copy_disk? */ - tape_buffered_write (tmp_buf, out_file_des, useful_bytes_in_block); - free (tmp_buf); - } - - /* We are done reading the archive, so clear these since they - will now be used for reading in files that we are appending - to the archive. */ - input_size = 0; - input_bytes = 0; - in_buff = input_buffer; -} - -/* Support for remembering inodes with multiple links. Used in the - "copy in" and "copy pass" modes for making links instead of copying - the file. */ - -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; - -/* Find the file name associated with NODE_NUM. If there is no file - associated with NODE_NUM, return NULL. */ - -char * -find_inode_file (node_num, major_num, minor_num) - unsigned long node_num; - unsigned long major_num; - unsigned long minor_num; -{ -#ifndef __MSDOS__ - 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; - } - } -#endif - return NULL; -} - -/* Associate FILE_NAME with the inode NODE_NUM. (Insert into hash table.) */ - -void -add_inode (node_num, file_name, major_num, minor_num) - unsigned long node_num; - char *file_name; - unsigned long major_num; - unsigned long minor_num; -{ -#ifndef __MSDOS__ - 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 *)); - bzero (hash_table, 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]); - - if (old_table != NULL) - free (old_table); - } - - /* Insert the new record and increment the count of elements in the - hash table. */ - hash_insert (temp); - hash_num++; -#endif /* __MSDOS__ */ -} - -/* 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 (new_value) - 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; -} - -/* Open FILE in the mode specified by the command line options - and return an open file descriptor for it, - or -1 if it can't be opened. */ - -int -open_archive (file) - char *file; -{ - int fd; - void (*copy_in) (); /* Workaround for pcc bug. */ - - copy_in = process_copy_in; - - if (copy_function == copy_in) - fd = rmtopen (file, O_RDONLY | O_BINARY, 0666); - else - { - if (!append_flag) - fd = rmtopen (file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); - else - fd = rmtopen (file, O_RDWR | O_BINARY, 0666); - } - - return fd; -} - -/* Attempt to rewind the tape drive on file descriptor TAPE_DES - and take it offline. */ - -void -tape_offline (tape_des) - int tape_des; -{ -#if defined(MTIOCTOP) && defined(MTOFFL) - struct mtop control; - - control.mt_op = MTOFFL; - control.mt_count = 1; - rmtioctl (tape_des, MTIOCTOP, &control); /* Don't care if it fails. */ -#endif -} - -/* The file on file descriptor TAPE_DES is assumed to be magnetic tape - (or floppy disk or other device) and the end of the medium - has been reached. Ask the user for to mount a new "tape" to continue - the processing. If the user specified the device name on the - command line (with the -I, -O, -F or --file options), then we can - automatically re-open the same device to use the next medium. If the - user did not specify the device name, then we have to ask them which - device to use. */ - -void -get_next_reel (tape_des) - int tape_des; -{ - static int reel_number = 1; - FILE *tty_in; /* File for interacting with user. */ - FILE *tty_out; /* File for interacting with user. */ - int old_tape_des; - char *next_archive_name; - dynamic_string new_name; - char *str_res; - - ds_init (&new_name, 128); - - /* Open files for interactive communication. */ - tty_in = fopen (CONSOLE, "r"); - if (tty_in == NULL) - error (2, errno, CONSOLE); - tty_out = fopen (CONSOLE, "w"); - if (tty_out == NULL) - error (2, errno, CONSOLE); - - old_tape_des = tape_des; - tape_offline (tape_des); - rmtclose (tape_des); - - /* Give message and wait for carrage return. User should hit carrage return - only after loading the next tape. */ - ++reel_number; - if (new_media_message) - fprintf (tty_out, "%s", new_media_message); - else if (new_media_message_with_number) - fprintf (tty_out, "%s%d%s", new_media_message_with_number, reel_number, - new_media_message_after_number); - else if (archive_name) - fprintf (tty_out, "Found end of volume. Load next volume and press RETURN. "); - else - fprintf (tty_out, "Found end of volume. To continue, type device/file name when ready.\n"); - - fflush (tty_out); - - if (archive_name) - { - int c; - - do - c = getc (tty_in); - while (c != EOF && c != '\n'); - - tape_des = open_archive (archive_name); - if (tape_des == -1) - error (1, errno, "%s", archive_name); - } - else - { - do - { - if (tape_des < 0) - { - fprintf (tty_out, - "To continue, type device/file name when ready.\n"); - fflush (tty_out); - } - - str_res = ds_fgets (tty_in, &new_name); - if (str_res == NULL || str_res[0] == '\0') - exit (1); - next_archive_name = str_res; - - tape_des = open_archive (next_archive_name); - if (tape_des == -1) - error (0, errno, "%s", next_archive_name); - } - while (tape_des < 0); - } - - /* We have to make sure that `tape_des' has not changed its value even - though we closed it and reopened it, since there are local - copies of it in other routines. This works fine on Unix (even with - rmtread and rmtwrite) since open will always return the lowest - available file descriptor and we haven't closed any files (e.g., - stdin, stdout or stderr) that were opened before we originally opened - the archive. */ - - if (tape_des != old_tape_des) - error (1, 0, "internal error: tape descriptor changed from %d to %d", - old_tape_des, tape_des); - - free (new_name.ds_string); - fclose (tty_in); - fclose (tty_out); -} - -/* If MESSAGE does not contain the string "%d", make `new_media_message' - a copy of MESSAGE. If MESSAGES does contain the string "%d", make - `new_media_message_with_number' a copy of MESSAGE up to, but - not including, the string "%d", and make `new_media_message_after_number' - a copy of MESSAGE after the string "%d". */ - -void -set_new_media_message (message) - char *message; -{ - char *p; - int prev_was_percent; - - p = message; - prev_was_percent = 0; - while (*p != '\0') - { - if (*p == 'd' && prev_was_percent) - break; - prev_was_percent = (*p == '%'); - ++p; - } - if (*p == '\0') - { - new_media_message = xstrdup (message); - } - else - { - int length = p - message - 1; - - new_media_message_with_number = xmalloc (length + 1); - strncpy (new_media_message_with_number, message, length); - new_media_message_with_number[length] = '\0'; - length = strlen (p + 1); - new_media_message_after_number = xmalloc (length + 1); - strcpy (new_media_message_after_number, p + 1); - } -} - -#ifdef SYMLINK_USES_UMASK -/* Most machines always create symlinks with rwxrwxrwx protection, - but some (HP/UX 8.07; maybe DEC's OSF on MIPS, too?) use the - umask when creating symlinks, so if your umask is 022 you end - up with rwxr-xr-x symlinks (although HP/UX seems to completely - ignore the protection). There doesn't seem to be any way to - manipulate the modes once the symlinks are created (e.g. - a hypothetical "lchmod"), so to create them with the right - modes we have to set the umask first. */ - -int -umasked_symlink (name1, name2, mode) - char *name1; - char *name2; - int mode; -{ - int old_umask; - int rc; - mode = ~(mode & 0777) & 0777; - old_umask = umask (mode); - rc = symlink (name1, name2); - umask (old_umask); - return rc; -} -#endif /* SYMLINK_USES_UMASK */ - -#if defined(__MSDOS__) && !defined(__GNUC__) -int -chown (path, owner, group) - char *path; - int owner, group; -{ - return 0; -} -#endif - -#ifdef __TURBOC__ -#include <time.h> -#include <fcntl.h> -#include <io.h> - -int -utime (char *filename, struct utimbuf *utb) -{ - extern int errno; - struct tm *tm; - struct ftime filetime; - time_t when; - int fd; - int status; - - if (utb == 0) - when = time (0); - else - when = utb->modtime; - - fd = _open (filename, O_RDWR); - if (fd == -1) - return -1; - - tm = localtime (&when); - if (tm->tm_year < 80) - filetime.ft_year = 0; - else - filetime.ft_year = tm->tm_year - 80; - filetime.ft_month = tm->tm_mon + 1; - filetime.ft_day = tm->tm_mday; - if (tm->tm_hour < 0) - filetime.ft_hour = 0; - else - filetime.ft_hour = tm->tm_hour; - filetime.ft_min = tm->tm_min; - filetime.ft_tsec = tm->tm_sec / 2; - - status = setftime (fd, &filetime); - _close (fd); - return status; -} -#endif -#ifdef HPUX_CDF -/* When we create a cpio archive we mark CDF's by putting an extra `/' - after their component name so we can distinguish the CDF's when we - extract the archive (in case the "hidden" directory's files appear - in the archive before the directory itself). E.g., in the path - "a/b+/c", if b+ is a CDF, we will write this path as "a/b+//c" in - the archive so when we extract the archive we will know that b+ - is actually a CDF, and not an ordinary directory whose name happens - to end in `+'. We also do the same thing internally in copypass.c. */ - - -/* Take an input pathname and check it for CDF's. Insert an extra - `/' in the pathname after each "hidden" directory. If we add - any `/'s, return a malloced string (which it will reuse for - later calls so our caller doesn't have to worry about freeing - the string) instead of the original input string. */ - -char * -add_cdf_double_slashes (input_name) - char *input_name; -{ - static char *ret_name = NULL; /* re-usuable return buffer (malloc'ed) */ - static int ret_size = -1; /* size of return buffer. */ - char *p; - char *q; - int n; - struct stat dir_stat; - - /* Search for a `/' preceeded by a `+'. */ - - for (p = input_name; *p != '\0'; ++p) - { - if ( (*p == '+') && (*(p + 1) == '/') ) - break; - } - - /* If we didn't find a `/' preceeded by a `+' then there are - no CDF's in this pathname. Return the original pathname. */ - - if (*p == '\0') - return input_name; - - /* There was a `/' preceeded by a `+' in the pathname. If it is a CDF - then we will need to copy the input pathname to our return - buffer so we can insert the extra `/'s. Since we can't tell - yet whether or not it is a CDF we will just always copy the - string to the return buffer. First we have to make sure the - buffer is large enough to hold the string and any number of - extra `/'s we might add. */ - - n = 2 * (strlen (input_name) + 1); - if (n >= ret_size) - { - if (ret_size < 0) - ret_name = (char *) malloc (n); - else - ret_name = (char *)realloc (ret_name, n); - ret_size = n; - } - - /* Clear the `/' after this component, so we can stat the pathname - up to and including this component. */ - ++p; - *p = '\0'; - if ((*xstat) (input_name, &dir_stat) < 0) - { - error (0, errno, "%s", input_name); - return input_name; - } - - /* Now put back the `/' after this component and copy the pathname up to - and including this component and its trailing `/' to the return - buffer. */ - *p++ = '/'; - strncpy (ret_name, input_name, p - input_name); - q = ret_name + (p - input_name); - - /* If it was a CDF, add another `/'. */ - if (S_ISDIR (dir_stat.st_mode) && (dir_stat.st_mode & 04000) ) - *q++ = '/'; - - /* Go through the rest of the input pathname, copying it to the - return buffer, and adding an extra `/' after each CDF. */ - while (*p != '\0') - { - if ( (*p == '+') && (*(p + 1) == '/') ) - { - *q++ = *p++; - - *p = '\0'; - if ((*xstat) (input_name, &dir_stat) < 0) - { - error (0, errno, "%s", input_name); - return input_name; - } - *p = '/'; - - if (S_ISDIR (dir_stat.st_mode) && (dir_stat.st_mode & 04000) ) - *q++ = '/'; - } - *q++ = *p++; - } - *q = '\0'; - - return ret_name; -} - -/* Is the last parent directory (e.g., c in a/b/c/d) a CDF? If the - directory name ends in `+' and is followed by 2 `/'s instead of 1 - then it is. This is only the case for cpio archives, but we don't - have to worry about tar because tar always has the directory before - its files (or else we lose). */ - -islastparentcdf(path) - char *path; -{ - char *newpath; - char *slash; - int slash_count; - int length; /* Length of result, not including NUL. */ - - slash = rindex (path, '/'); - if (slash == 0) - return 0; - else - { - slash_count = 0; - while (slash > path && *slash == '/') - { - ++slash_count; - --slash; - } - - - if ( (*slash == '+') && (slash_count >= 2) ) - return 1; - } - return 0; -} -#endif - -#define DISKBLOCKSIZE (512) - -enum sparse_write_states { begin, in_zeros, not_in_zeros }; - - -static int -buf_all_zeros (buf, bufsize) - char *buf; - int bufsize; -{ - int i; - for (i = 0; i < bufsize; ++i) - { - if (*buf++ != '\0') - return 0; - } - return 1; -} - -int delayed_seek_count = 0; - -/* Write NBYTE bytes from BUF to remote tape connection FILDES. - Return the number of bytes written on success, -1 on error. */ - -int -sparse_write (fildes, buf, nbyte) - int fildes; - char *buf; - unsigned int nbyte; -{ - int complete_block_count; - int leftover_bytes_count; - int seek_count; - int write_count; - char *cur_write_start; - int lseek_rc; - int write_rc; - int i; - enum sparse_write_states state; - - complete_block_count = nbyte / DISKBLOCKSIZE; - leftover_bytes_count = nbyte % DISKBLOCKSIZE; - - if (delayed_seek_count != 0) - state = in_zeros; - else - state = begin; - - seek_count = delayed_seek_count; - - for (i = 0; i < complete_block_count; ++i) - { - switch (state) - { - case begin : - if (buf_all_zeros (buf, DISKBLOCKSIZE)) - { - seek_count = DISKBLOCKSIZE; - state = in_zeros; - } - else - { - cur_write_start = buf; - write_count = DISKBLOCKSIZE; - state = not_in_zeros; - } - buf += DISKBLOCKSIZE; - break; - case in_zeros : - if (buf_all_zeros (buf, DISKBLOCKSIZE)) - { - seek_count += DISKBLOCKSIZE; - } - else - { - lseek (fildes, seek_count, SEEK_CUR); - cur_write_start = buf; - write_count = DISKBLOCKSIZE; - state = not_in_zeros; - } - buf += DISKBLOCKSIZE; - break; - case not_in_zeros : - if (buf_all_zeros (buf, DISKBLOCKSIZE)) - { - write_rc = write (fildes, cur_write_start, write_count); - seek_count = DISKBLOCKSIZE; - state = in_zeros; - } - else - { - write_count += DISKBLOCKSIZE; - } - buf += DISKBLOCKSIZE; - break; - } - } - - switch (state) - { - case begin : - case in_zeros : - delayed_seek_count = seek_count; - break; - case not_in_zeros : - write_rc = write (fildes, cur_write_start, write_count); - delayed_seek_count = 0; - break; - } - - if (leftover_bytes_count != 0) - { - if (delayed_seek_count != 0) - { - lseek_rc = lseek (fildes, delayed_seek_count, SEEK_CUR); - delayed_seek_count = 0; - } - write_rc = write (fildes, buf, leftover_bytes_count); - } - return nbyte; -} - -static void -write_nuls_to_file (num_bytes, out_des) - long num_bytes; - int out_des; -{ - long blocks; - long extra_bytes; - long i; - - blocks = num_bytes / 512; - extra_bytes = num_bytes % 512; - for (i = 0; i < extra_bytes; ++i) - { - if (write (out_des, zeros_512, 512) != 512) - error (1, errno, "error writing NUL's"); - } - if (extra_bytes != 0) - { - if (write (out_des, zeros_512, extra_bytes) != extra_bytes) - error (1, errno, "error writing NUL's"); - } -} |