示例#1
0
文件: rmtlib.c 项目: Ga-vin/MINIX3
/*
 *	Rmtisatty.  Do the isatty function.
 */
int
rmtisatty(int fd)
{

	if (isrmt(fd))
		return 0;
	else
		return isatty(fd);
}
示例#2
0
文件: rmtlib.c 项目: Ga-vin/MINIX3
/*
 *	Close a file.  Looks just like close(2) to caller.
 */
int
rmtclose(int fildes)
{

	if (isrmt(fildes)) {
		return _rmt_close(fildes - REM_BIAS);
	} else {
		return close(fildes);
	}
}
示例#3
0
文件: rmtlib.c 项目: Ga-vin/MINIX3
/*
 *	Perform lseek on file.  Looks just like lseek(2) to caller.
 */
off_t
rmtlseek(int fildes, off_t offset, int whence)
{

	if (isrmt(fildes)) {
		return _rmt_lseek(fildes - REM_BIAS, offset, whence);
	} else {
		return lseek(fildes, offset, whence);
	}
}
示例#4
0
文件: rmtlib.c 项目: Ga-vin/MINIX3
/*
 *	Duplicate an open file descriptor.  Looks just like dup(2)
 *	to caller.
 */
int
rmtdup(int fildes)
{

	if (isrmt(fildes)) {
		errno = EOPNOTSUPP;
		return -1;		/* For now (fnf) */
	} else {
		return dup(fildes);
	}
}
示例#5
0
文件: rmtlib.c 项目: Ga-vin/MINIX3
/*
 *	Write to stream.  Looks just like write(2) to caller.
 */
ssize_t
rmtwrite(int fildes, const void *buf, size_t nbyte)
{

	_DIAGASSERT(buf != NULL);

	if (isrmt(fildes)) {
		return _rmt_write(fildes - REM_BIAS, buf, nbyte);
	} else {
		return write(fildes, buf, nbyte);
	}
}
示例#6
0
文件: rmtlib.c 项目: Ga-vin/MINIX3
/*
 *	Read from stream.  Looks just like read(2) to caller.
 */
ssize_t
rmtread(int fildes, void *buf, size_t nbyte)
{

	_DIAGASSERT(buf != NULL);

	if (isrmt(fildes)) {
		return _rmt_read(fildes - REM_BIAS, buf, nbyte);
	} else {
		return read(fildes, buf, nbyte);
	}
}
示例#7
0
文件: rmtlib.c 项目: Ga-vin/MINIX3
/*
 *	Get file status.  Looks just like fstat(2) to caller.
 */
int
rmtfstat(int fildes, struct stat *buf)
{

	_DIAGASSERT(buf != NULL);

	if (isrmt(fildes)) {
		errno = EOPNOTSUPP;
		return -1;		/* For now (fnf) */
	} else {
		return fstat(fildes, buf);
	}
}
示例#8
0
文件: rmtlib.c 项目: Ga-vin/MINIX3
/*
 *	Rmtfcntl. Do a remote fcntl operation.
 */
int
rmtfcntl(int fd, int cmd, ...)
{
	void *arg;
	va_list ap;
	va_start(ap, cmd);

	arg = va_arg(ap, void *);
	va_end(ap);

	/* XXX: arg may be NULL ? */

	if (isrmt(fd)) {
		errno = EOPNOTSUPP;
		return -1;
	} else {
		return fcntl(fd, cmd, arg);
	}
}
示例#9
0
文件: rmtlib.c 项目: Ga-vin/MINIX3
/*
 *	Do ioctl on file.  Looks just like ioctl(2) to caller.
 */
int
rmtioctl(int fildes, unsigned long request, ...)
{
	void *arg;
	va_list ap;
	va_start(ap, request);

	arg = va_arg(ap, void *);
	va_end(ap);

	/* XXX: arg may be NULL ? */

	if (isrmt(fildes)) {
#ifdef RMTIOCTL
		return _rmt_ioctl(fildes - REM_BIAS, request, arg);
#else
		errno = EOPNOTSUPP;
		return -1;		/* For now (fnf) */
#endif
	} else {
		return ioctl(fildes, request, arg);
	}
}
示例#10
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;
}