<commit_before>/*-
 * Copyright (c) 1992 <NAME>.
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * <NAME> of the University of California, San Diego.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef lint
#if 0
static char sccsid[] = "@(#)ar_io.c	8.2 (Berkeley) 4/18/94";
#endif
#endif /* not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mtio.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "pax.h"
#include "options.h"
#include "extern.h"

/*
 * Routines which deal directly with the archive I/O device/file.
 */

#define DMOD		0666		/* default mode of created archives */
#define EXT_MODE	O_RDONLY	/* open mode for list/extract */
#define AR_MODE		(O_WRONLY | O_CREAT | O_TRUNC)	/* mode for archive */
#define APP_MODE	O_RDWR		/* mode for append */

static char none[] = "<NONE>";		/* pseudo name for no file */
static char stdo[] = "<STDOUT>";	/* pseudo name for stdout */
static char stdn[] = "<STDIN>";		/* pseudo name for stdin */
static int arfd = -1;			/* archive file descriptor */
static int artyp = ISREG;		/* archive type: file/FIFO/tape */
static int arvol = 1;			/* archive volume number */
static int lstrval = -1;		/* return value from last i/o */
static int io_ok;			/* i/o worked on volume after resync */
static int did_io;			/* did i/o ever occur on volume? */
static int done;			/* set via tty termination */
static struct stat arsb;		/* stat of archive device at open */
static int invld_rec;			/* tape has out of spec record size */
static int wr_trail = 1;		/* trailer was rewritten in append */
static int can_unlnk = 0;		/* do we unlink null archives?  */
const char *arcname;		  	/* printable name of archive */
const char *gzip_program;		/* name of gzip program */
static pid_t zpid = -1;			/* pid of child process */

static int get_phys(void);
extern sigset_t s_mask;
static void ar_start_gzip(int, const char *, int);

/*
 * ar_open()
 *	Opens the next archive volume. Determines the type of the device and
 *	sets up block sizes as required by the archive device and the format.
 *	Note: we may be called with name == NULL on the first open only.
 * Return:
 *	-1 on failure, 0 otherwise
 */

int
ar_open(const char *name)
{
	struct mtget mb;

	if (arfd != -1)
		(void)close(arfd);
	arfd = -1;
	can_unlnk = did_io = io_ok = invld_rec = 0;
	artyp = ISREG;
	flcnt = 0;

	/*
	 * open based on overall operation mode
	 */
	switch (act) {
	case LIST:
	case EXTRACT:
		if (name == NULL) {
			arfd = STDIN_FILENO;
			arcname = stdn;
		} else if ((arfd = open(name, EXT_MODE, DMOD)) < 0)
			syswarn(0, errno, "Failed open to read on %s", name);
		if (arfd != -1 && gzip_program != NULL)
			ar_start_gzip(arfd, gzip_program, 0);
		break;
	case ARCHIVE:
		if (name == NULL) {
			arfd = STDOUT_FILENO;
			arcname = stdo;
		} else if ((arfd = open(name, AR_MODE, DMOD)) < 0)
			syswarn(0, errno, "Failed open to write on %s", name);
		else
			can_unlnk = 1;
		if (arfd != -1 && gzip_program != NULL)
			ar_start_gzip(arfd, gzip_program, 1);
		break;
	case APPND:
		if (name == NULL) {
			arfd = STDOUT_FILENO;
			arcname = stdo;
		} else if ((arfd = open(name, APP_MODE, DMOD)) < 0)
			syswarn(0, errno, "Failed open to read/write on %s",
				name);
		break;
	case COPY:
		/*
		 * arfd not used in COPY mode
		 */
		arcname = none;
		lstrval = 1;
		return(0);
	}
	if (arfd < 0)
		return(-1);

	if (chdname != NULL)
		if (chdir(chdname) != 0)
			syswarn(1, errno, "Failed chdir to %s", chdname);
	/*
	 * set up is based on device type
	 */
	if (fstat(arfd, &arsb) < 0) {
		syswarn(0, errno, "Failed stat on %s", arcname);
		(void)close(arfd);
		arfd = -1;
		can_unlnk = 0;
		return(-1);
	}
	if (S_ISDIR(arsb.st_mode)) {
		paxwarn(0, "Cannot write an archive on top of a directory %s",
		    arcname);
		(void)close(arfd);
		arfd = -1;
		can_unlnk = 0;
		return(-1);
	}<commit_msg>Don't continue if the '-C' option (a-la GNUtar; commited in options.c rev 1.18, but not documented in the man page) caused a failed chdir. Otherwise, one can easily overwrite files.<commit_after>/*-
 * Copyright (c) 1992 <NAME>.
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * <NAME> of the University of California, San Diego.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef lint
#if 0
static char sccsid[] = "@(#)ar_io.c	8.2 (Berkeley) 4/18/94";
#endif
#endif /* not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mtio.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "pax.h"
#include "options.h"
#include "extern.h"

/*
 * Routines which deal directly with the archive I/O device/file.
 */

#define DMOD		0666		/* default mode of created archives */
#define EXT_MODE	O_RDONLY	/* open mode for list/extract */
#define AR_MODE		(O_WRONLY | O_CREAT | O_TRUNC)	/* mode for archive */
#define APP_MODE	O_RDWR		/* mode for append */

static char none[] = "<NONE>";		/* pseudo name for no file */
static char stdo[] = "<STDOUT>";	/* pseudo name for stdout */
static char stdn[] = "<STDIN>";		/* pseudo name for stdin */
static int arfd = -1;			/* archive file descriptor */
static int artyp = ISREG;		/* archive type: file/FIFO/tape */
static int arvol = 1;			/* archive volume number */
static int lstrval = -1;		/* return value from last i/o */
static int io_ok;			/* i/o worked on volume after resync */
static int did_io;			/* did i/o ever occur on volume? */
static int done;			/* set via tty termination */
static struct stat arsb;		/* stat of archive device at open */
static int invld_rec;			/* tape has out of spec record size */
static int wr_trail = 1;		/* trailer was rewritten in append */
static int can_unlnk = 0;		/* do we unlink null archives?  */
const char *arcname;		  	/* printable name of archive */
const char *gzip_program;		/* name of gzip program */
static pid_t zpid = -1;			/* pid of child process */

static int get_phys(void);
extern sigset_t s_mask;
static void ar_start_gzip(int, const char *, int);

/*
 * ar_open()
 *	Opens the next archive volume. Determines the type of the device and
 *	sets up block sizes as required by the archive device and the format.
 *	Note: we may be called with name == NULL on the first open only.
 * Return:
 *	-1 on failure, 0 otherwise
 */

int
ar_open(const char *name)
{
	struct mtget mb;

	if (arfd != -1)
		(void)close(arfd);
	arfd = -1;
	can_unlnk = did_io = io_ok = invld_rec = 0;
	artyp = ISREG;
	flcnt = 0;

	/*
	 * open based on overall operation mode
	 */
	switch (act) {
	case LIST:
	case EXTRACT:
		if (name == NULL) {
			arfd = STDIN_FILENO;
			arcname = stdn;
		} else if ((arfd = open(name, EXT_MODE, DMOD)) < 0)
			syswarn(0, errno, "Failed open to read on %s", name);
		if (arfd != -1 && gzip_program != NULL)
			ar_start_gzip(arfd, gzip_program, 0);
		break;
	case ARCHIVE:
		if (name == NULL) {
			arfd = STDOUT_FILENO;
			arcname = stdo;
		} else if ((arfd = open(name, AR_MODE, DMOD)) < 0)
			syswarn(0, errno, "Failed open to write on %s", name);
		else
			can_unlnk = 1;
		if (arfd != -1 && gzip_program != NULL)
			ar_start_gzip(arfd, gzip_program, 1);
		break;
	case APPND:
		if (name == NULL) {
			arfd = STDOUT_FILENO;
			arcname = stdo;
		} else if ((arfd = open(name, APP_MODE, DMOD)) < 0)
			syswarn(0, errno, "Failed open to read/write on %s",
				name);
		break;
	case COPY:
		/*
		 * arfd not used in COPY mode
		 */
		arcname = none;
		lstrval = 1;
		return(0);
	}
	if (arfd < 0)
		return(-1);

	if (chdname != NULL)
		if (chdir(chdname) != 0) {
			syswarn(1, errno, "Failed chdir to %s", chdname);
			return(-1);
		}
	/*
	 * set up is based on device type
	 */
	if (fstat(arfd, &arsb) < 0) {
		syswarn(0, errno, "Failed stat on %s", arcname);
		(void)close(arfd);
		arfd = -1;
		can_unlnk = 0;
		return(-1);
	}
	if (S_ISDIR(arsb.st_mode)) {
		paxwarn(0, "Cannot write an archive on top of a directory %s",
		    arcname);
		(void)close(arfd);
		arfd = -1;
		can_unlnk = 0;
		return(-1);
	}
{'fraction_non_alphanumeric': 0.1166797865826992, 'fraction_numerical': 0.01172045832240007, 'mean_word_length': 3.430065865943433, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2432744', 'n_tokens_mistral': 4229, 'n_tokens_neox': 3848, 'n_words': 1512}