Exemplo n.º 1
0
int
rmtopen(char *tape, int mode)
{
	struct mtget mt;
	char buf[256];
	int fd;

	(void) snprintf(buf, sizeof (buf), "O%s\n%d\n", tape, mode);
	rmtstate = TS_OPEN;
	fd = rmtcall(tape, buf);
	if (fd != -1) {
		/* see if the rmt server supports the extended protocol */
		rmtversion = rmtioctl(-1, 0);

		/*
		 * Some rmt daemons apparently close the connection
		 * when they get a bogus ioctl.  See 1210852 (ignore
		 * the evaluation).  Make sure we can still talk to
		 * the device, re-opening it if necessary.
		 */
		if (rmtversion < 1) {
			if (rmtstatus(&mt) < 0) {
				rmtclose();
				rmtgetconn();
				rmtversion = 0;
			}
		}
	}
	return (fd);
}
Exemplo n.º 2
0
Arquivo: mt.c Projeto: Bluerise/bitrig
void
_rmtclose(void)
{
#ifdef RMT
	if (host)
		rmtclose();
#endif
}
Exemplo n.º 3
0
void
closemt(void)
{

	if (mt < 0)
		return;
#ifdef RRESTORE
	if (host)
		rmtclose();
	else
#endif
		(void)close(mt);
}
Exemplo n.º 4
0
void
closemt(void)
{

	if (mt < 0)
		return;
	if (pipecmdin) {
		pclose(popenfp);
		popenfp = NULL;
	} else
#ifdef RRESTORE
	if (host)
		rmtclose();
	else
#endif
		(void) close(mt);
}
Exemplo n.º 5
0
/*
 * ar_close()
 *	closes archive device, increments volume number, and prints i/o summary
 */
void
ar_close(void)
{
	int status;

	if (arfd < 0) {
		did_io = io_ok = flcnt = 0;
		return;
	}


	/*
	 * Close archive file. This may take a LONG while on tapes (we may be
	 * forced to wait for the rewind to complete) so tell the user what is
	 * going on (this avoids the user hitting control-c thinking pax is
	 * broken).
	 */
	if ((vflag || Vflag) && (artyp == ISTAPE)) {
		if (vfpart)
			(void)putc('\n', listf);
		(void)fprintf(listf,
			"%s: Waiting for tape drive close to complete...",
			argv0);
		(void)fflush(listf);
	}

	/*
	 * if nothing was written to the archive (and we created it), we remove
	 * it
	 */
	if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) &&
	    (arsb.st_size == 0)) {
		(void)unlink(arcname);
		can_unlnk = 0;
	}

	/*
	 * for a quick extract/list, pax frequently exits before the child
	 * process is done
	 */
	if ((act == LIST || act == EXTRACT) && nflag && zpid > 0)
		kill(zpid, SIGINT);

#ifdef SUPPORT_RMT
	if (artyp == ISRMT)
		(void)rmtclose(arfd);
	else
#endif /* SUPPORT_RMT */
		(void)close(arfd);

	/* Do not exit before child to ensure data integrity */
	if (zpid > 0)
		waitpid(zpid, &status, 0);

	if ((vflag || Vflag) && (artyp == ISTAPE)) {
		(void)fputs("done.\n", listf);
		vfpart = 0;
		(void)fflush(listf);
	}
	arfd = -1;

	if (!io_ok && !did_io) {
		flcnt = 0;
		return;
	}
	did_io = io_ok = 0;

	/*
	 * The volume number is only increased when the last device has data
	 * and we have already determined the archive format.
	 */
	if (frmt != NULL)
		++arvol;

	if (!vflag && !Vflag) {
		flcnt = 0;
		return;
	}

	/*
	 * Print out a summary of I/O for this archive volume.
	 */
	if (vfpart) {
		(void)putc('\n', listf);
		vfpart = 0;
	}

	/* mimic cpio's block count first */
	if (frmt && strcmp(NM_CPIO, argv0) == 0) {
		(void)fprintf(listf, OFFT_F " blocks\n",
		    (rdcnt ? rdcnt : wrcnt) / 5120);
	}

	ar_summary(0);

	(void)fflush(listf);
	flcnt = 0;
}
Exemplo n.º 6
0
int
ar_open(const char *name)
{
#ifdef HAVE_SYS_MTIO_H
	struct mtget mb;
#endif

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

#ifdef SUPPORT_RMT
	if (name && strchr(name, ':') != NULL && !forcelocal) {
		artyp = ISRMT;
		if ((arfd = rmtopen(name, O_RDWR, DMOD)) == -1) {
			syswarn(0, errno, "Failed open on %s", name);
			return -1;
		}
		if (!isrmt(arfd)) {
			rmtclose(arfd);
			tty_warn(0, "Not a remote file: %s", name);
			return -1;
		}
		blksz = rdblksz = 8192;
		lstrval = 1;
		return 0;
	}
#endif /* SUPPORT_RMT */

	/*
	 * 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 (dochdir(chdname) == -1)
			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)) {
		tty_warn(0, "Cannot write an archive on top of a directory %s",
		    arcname);
		(void)close(arfd);
		arfd = -1;
		can_unlnk = 0;
		return -1;
	}

	if (S_ISCHR(arsb.st_mode)) {
#ifdef HAVE_SYS_MTIO_H
		artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE;
#else
		tty_warn(1, "System does not have tape support");
		artyp = ISREG;
#endif
	} else if (S_ISBLK(arsb.st_mode))
		artyp = ISBLK;
	else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE))
		artyp = ISPIPE;
	else
		artyp = ISREG;

	/*
	 * Special handling for empty files.
	 */
	if (artyp == ISREG && arsb.st_size == 0) {
		switch (act) {
		case LIST:
		case EXTRACT:
			return -1;
		case APPND:
			act = -ARCHIVE;
			return -1;
		case ARCHIVE:
			break;
		}
	}

	/*
	 * make sure we beyond any doubt that we only can unlink regular files
	 * we created
	 */
	if (artyp != ISREG)
		can_unlnk = 0;

	/*
	 * if we are writing, we are done
	 */
	if (act == ARCHIVE) {
		blksz = rdblksz = wrblksz;
		lstrval = 1;
		return 0;
	}

	/*
	 * set default blksz on read. APPNDs writes rdblksz on the last volume
	 * On all new archive volumes, we shift to wrblksz (if the user
	 * specified one, otherwize we will continue to use rdblksz). We
	 * must set blocksize based on what kind of device the archive is
	 * stored.
	 */
	switch(artyp) {
	case ISTAPE:
		/*
		 * Tape drives come in at least two flavors. Those that support
		 * variable sized records and those that have fixed sized
		 * records. They must be treated differently. For tape drives
		 * that support variable sized records, we must make large
		 * reads to make sure we get the entire record, otherwise we
		 * will just get the first part of the record (up to size we
		 * asked). Tapes with fixed sized records may or may not return
		 * multiple records in a single read. We really do not care
		 * what the physical record size is UNLESS we are going to
		 * append. (We will need the physical block size to rewrite
		 * the trailer). Only when we are appending do we go to the
		 * effort to figure out the true PHYSICAL record size.
		 */
		blksz = rdblksz = MAXBLK;
		break;
	case ISPIPE:
	case ISBLK:
	case ISCHR:
		/*
		 * Blocksize is not a major issue with these devices (but must
		 * be kept a multiple of 512). If the user specified a write
		 * block size, we use that to read. Under append, we must
		 * always keep blksz == rdblksz. Otherwise we go ahead and use
		 * the device optimal blocksize as (and if) returned by stat
		 * and if it is within pax specs.
		 */
		if ((act == APPND) && wrblksz) {
			blksz = rdblksz = wrblksz;
			break;
		}

		if ((arsb.st_blksize > 0) && (arsb.st_blksize < MAXBLK) &&
		    ((arsb.st_blksize % BLKMULT) == 0))
			rdblksz = arsb.st_blksize;
		else
			rdblksz = DEVBLK;
		/*
		 * For performance go for large reads when we can without harm
		 */
		if ((act == APPND) || (artyp == ISCHR))
			blksz = rdblksz;
		else
			blksz = MAXBLK;
		break;
	case ISREG:
		/*
		 * if the user specified wrblksz works, use it. Under appends
		 * we must always keep blksz == rdblksz
		 */
		if ((act == APPND) && wrblksz && ((arsb.st_size%wrblksz)==0)){
			blksz = rdblksz = wrblksz;
			break;
		}
		/*
		 * See if we can find the blocking factor from the file size
		 */
		for (rdblksz = MAXBLK; rdblksz > 0; rdblksz -= BLKMULT)
			if ((arsb.st_size % rdblksz) == 0)
				break;
		/*
		 * When we cannot find a match, we may have a flawed archive.
		 */
		if (rdblksz <= 0)
			rdblksz = FILEBLK;
		/*
		 * for performance go for large reads when we can
		 */
		if (act == APPND)
			blksz = rdblksz;
		else
			blksz = MAXBLK;
		break;
	default:
		/*
		 * should never happen, worst case, slow...
		 */
		blksz = rdblksz = BLKMULT;
		break;
	}
	lstrval = 1;
	return 0;
}