示例#1
0
文件: tape.c 项目: sofuture/bitrig
/*
 * Read the next block from the tape.
 * Check to see if it is one of several vintage headers.
 * If it is an old style header, convert it to a new style header.
 * If it is not any valid header, return an error.
 */
static int
gethead(struct s_spcl *buf)
{
	union u_ospcl u_ospcl;

	if (!cvtflag) {
		readtape((char *)buf);
		if (buf->c_magic != NFS_MAGIC &&
		    buf->c_magic != FS_UFS2_MAGIC) {
			if (swap32(buf->c_magic) != NFS_MAGIC &&
			    swap32(buf->c_magic) != FS_UFS2_MAGIC)
				return (FAIL);
			if (!Bcvt) {
				Vprintf(stdout, "Note: Doing Byte swapping\n");
				Bcvt = 1;
			}
		}
		if (checksum((int *)buf) == FAIL)
			return (FAIL);
		if (Bcvt)
			swap_header(buf);
		goto good;
	}

	readtape((char *)(&u_ospcl.s_ospcl));
	if (checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
		return (FAIL);
	if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC) {
		if (swap32(u_ospcl.s_ospcl.c_magic) != OFS_MAGIC)
			return (FAIL);
		if (!Bcvt) {
			fprintf(stdout, "Note: Doing Byte swapping\n");
			Bcvt = 1;
		}
		swap_old_header(&u_ospcl.s_ospcl);
	}

	memset(buf, 0, TP_BSIZE);
	buf->c_type = u_ospcl.s_ospcl.c_type;
	buf->c_date = u_ospcl.s_ospcl.c_date;
	buf->c_ddate = u_ospcl.s_ospcl.c_ddate;
	buf->c_volume = u_ospcl.s_ospcl.c_volume;
	buf->c_tapea = u_ospcl.s_ospcl.c_tapea;
	buf->c_inumber = u_ospcl.s_ospcl.c_inumber;
	buf->c_checksum = u_ospcl.s_ospcl.c_checksum;
	buf->c_mode = u_ospcl.s_ospcl.c_odinode.odi_mode;
	buf->c_uid = u_ospcl.s_ospcl.c_odinode.odi_uid;
	buf->c_gid = u_ospcl.s_ospcl.c_odinode.odi_gid;
	buf->c_size = u_ospcl.s_ospcl.c_odinode.odi_size;
	buf->c_rdev = u_ospcl.s_ospcl.c_odinode.odi_rdev;
	buf->c_atime = u_ospcl.s_ospcl.c_odinode.odi_atime;
	buf->c_mtime = u_ospcl.s_ospcl.c_odinode.odi_mtime;
	buf->c_count = u_ospcl.s_ospcl.c_count;
	memcpy(buf->c_addr, u_ospcl.s_ospcl.c_addr, 256);
	buf->c_magic = FS_UFS2_MAGIC;
good:
	switch (buf->c_type) {

	case TS_CLRI:
	case TS_BITS:
		/*
		 * Have to patch up missing information in bit map headers
		 */
		buf->c_inumber = 0;
		buf->c_size = buf->c_count * TP_BSIZE;
		break;

	case TS_TAPE:
		if ((buf->c_flags & DR_NEWINODEFMT) == 0)
			oldinofmt = 1;
		/* fall through */
	case TS_END:
		buf->c_inumber = 0;
		break;

	case TS_INODE:
		if (buf->c_magic == NFS_MAGIC) {
			buf->c_tapea = buf->c_old_tapea;
			buf->c_firstrec = buf->c_old_firstrec;
			buf->c_date = buf->c_old_date;
			buf->c_ddate = buf->c_old_ddate;
			buf->c_atime = buf->c_old_atime;
			buf->c_mtime = buf->c_old_mtime;
			buf->c_birthtime = 0;
			buf->c_birthtimensec = 0;
			buf->c_atimensec = buf->c_mtimensec = 0;
		}
			
	case TS_ADDR:
		break;

	default:
		panic("gethead: unknown inode type %d\n", buf->c_type);
		break;
	}

	buf->c_magic = FS_UFS2_MAGIC;

	/*
	 * If we are restoring a filesystem with old format inodes, 
	 * copy the uid/gid to the new location.
	 */
	if (oldinofmt) {
		buf->c_uid = buf->c_spare1[1];
		buf->c_gid = buf->c_spare1[2];
	}
	if (dflag)
		accthdr(buf);
	return(GOOD);
}
示例#2
0
文件: tape.c 项目: Alkzndr/freebsd
/*
 * Read the next block from the tape.
 * If it is not any valid header, return an error.
 */
static int
gethead(struct s_spcl *buf)
{
	long i;

	readtape((char *)buf);
	if (buf->c_magic != FS_UFS2_MAGIC && buf->c_magic != NFS_MAGIC) {
		if (buf->c_magic == OFS_MAGIC) {
			fprintf(stderr,
			    "Format of dump tape is too old. Must use\n");
			fprintf(stderr,
			    "a version of restore from before 2002.\n");
			return (FAIL);
		}
		if (swabl(buf->c_magic) != FS_UFS2_MAGIC &&
		    buf->c_magic != NFS_MAGIC) {
			if (buf->c_magic == OFS_MAGIC) {
				fprintf(stderr,
				  "Format of dump tape is too old. Must use\n");
				fprintf(stderr,
				  "a version of restore from before 2002.\n");
			}
			return (FAIL);
		}
		if (!Bcvt) {
			vprintf(stdout, "Note: Doing Byte swapping\n");
			Bcvt = 1;
		}
	}
	if (checksum((int *)buf) == FAIL)
		return (FAIL);
	if (Bcvt) {
		swabst((u_char *)"8l4s1q8l2q17l", (u_char *)buf);
		swabst((u_char *)"l",(u_char *) &buf->c_level);
		swabst((u_char *)"2l4q",(u_char *) &buf->c_flags);
	}
	readmapflag = 0;

	switch (buf->c_type) {

	case TS_CLRI:
	case TS_BITS:
		/*
		 * Have to patch up missing information in bit map headers
		 */
		buf->c_size = buf->c_count * TP_BSIZE;
		if (buf->c_count > TP_NINDIR)
			readmapflag = 1;
		else 
			for (i = 0; i < buf->c_count; i++)
				buf->c_addr[i]++;
		/* FALL THROUGH */

	case TS_TAPE:
		if (buf->c_magic == NFS_MAGIC &&
		    (buf->c_flags & NFS_DR_NEWINODEFMT) == 0)
			oldinofmt = 1;
		/* FALL THROUGH */

	case TS_END:
		buf->c_inumber = 0;
		/* FALL THROUGH */

	case TS_ADDR:
	case TS_INODE:
		/*
		 * For old dump tapes, have to copy up old fields to
		 * new locations.
		 */
		if (buf->c_magic == NFS_MAGIC) {
			buf->c_tapea = buf->c_old_tapea;
			buf->c_firstrec = buf->c_old_firstrec;
			buf->c_date = _time32_to_time(buf->c_old_date);
			buf->c_ddate = _time32_to_time(buf->c_old_ddate);
			buf->c_atime = _time32_to_time(buf->c_old_atime);
			buf->c_mtime = _time32_to_time(buf->c_old_mtime);
			buf->c_birthtime = 0;
			buf->c_birthtimensec = 0;
			buf->c_extsize = 0;
		}
		break;

	default:
		panic("gethead: unknown inode type %d\n", buf->c_type);
		break;
	}
	if (dumpdate != 0 && _time64_to_time(buf->c_date) != dumpdate)
		fprintf(stderr, "Header with wrong dumpdate.\n");
	/*
	 * If we're restoring a filesystem with the old (FreeBSD 1)
	 * format inodes, copy the uid/gid to the new location
	 */
	if (oldinofmt) {
		buf->c_uid = buf->c_spare1[1];
		buf->c_gid = buf->c_spare1[2];
	}
	buf->c_magic = FS_UFS2_MAGIC;
	tapeaddr = buf->c_tapea;
	if (dflag)
		accthdr(buf);
	return(GOOD);
}
示例#3
0
/*
 * Read the next block from the tape.
 * Check to see if it is one of several vintage headers.
 * If it is an old style header, convert it to a new style header.
 * If it is not any valid header, return an error.
 */
static int
gethead(struct s_spcl *buf)
{
	long i;
	union {
		quad_t	qval;
		int32_t	val[2];
	} qcvt;
	union u_ospcl {
		char dummy[TP_BSIZE];
		struct	s_ospcl {
			int32_t	c_type;
			int32_t	c_date;
			int32_t	c_ddate;
			int32_t	c_volume;
			int32_t	c_tapea;
			u_short	c_inumber;
			int32_t	c_magic;
			int32_t	c_checksum;
			struct odinode {
				unsigned short odi_mode;
				u_short	odi_nlink;
				u_short	odi_uid;
				u_short	odi_gid;
				int32_t	odi_size;
				int32_t	odi_rdev;
				char	odi_addr[36];
				int32_t	odi_atime;
				int32_t	odi_mtime;
				int32_t	odi_ctime;
			} c_dinode;
			int32_t	c_count;
			char	c_addr[256];
		} s_ospcl;
	} u_ospcl;

	if (!cvtflag) {
		readtape((char *)buf);
		if (buf->c_magic != NFS_MAGIC) {
			if (swabl(buf->c_magic) != NFS_MAGIC)
				return (FAIL);
			if (!Bcvt) {
				vprintf(stdout, "Note: Doing Byte swapping\n");
				Bcvt = 1;
			}
		}
		if (checksum((int *)buf) == FAIL)
			return (FAIL);
		if (Bcvt) {
			swabst((u_char *)"8l4s31l", (u_char *)buf);
			swabst((u_char *)"l",(u_char *) &buf->c_level);
			swabst((u_char *)"2l",(u_char *) &buf->c_flags);
		}
		goto good;
	}
	readtape((char *)(&u_ospcl.s_ospcl));
	memset(buf, 0, (long)TP_BSIZE);
	buf->c_type = u_ospcl.s_ospcl.c_type;
	buf->c_date = u_ospcl.s_ospcl.c_date;
	buf->c_ddate = u_ospcl.s_ospcl.c_ddate;
	buf->c_volume = u_ospcl.s_ospcl.c_volume;
	buf->c_tapea = u_ospcl.s_ospcl.c_tapea;
	buf->c_inumber = u_ospcl.s_ospcl.c_inumber;
	buf->c_checksum = u_ospcl.s_ospcl.c_checksum;
	buf->c_magic = u_ospcl.s_ospcl.c_magic;
	buf->c_dinode.di_mode = u_ospcl.s_ospcl.c_dinode.odi_mode;
	buf->c_dinode.di_nlink = u_ospcl.s_ospcl.c_dinode.odi_nlink;
	buf->c_dinode.di_uid = u_ospcl.s_ospcl.c_dinode.odi_uid;
	buf->c_dinode.di_gid = u_ospcl.s_ospcl.c_dinode.odi_gid;
	buf->c_dinode.di_size = u_ospcl.s_ospcl.c_dinode.odi_size;
	buf->c_dinode.di_rdev = u_ospcl.s_ospcl.c_dinode.odi_rdev;
	buf->c_dinode.di_atime = u_ospcl.s_ospcl.c_dinode.odi_atime;
	buf->c_dinode.di_mtime = u_ospcl.s_ospcl.c_dinode.odi_mtime;
	buf->c_dinode.di_ctime = u_ospcl.s_ospcl.c_dinode.odi_ctime;
	buf->c_count = u_ospcl.s_ospcl.c_count;
	memmove(buf->c_addr, u_ospcl.s_ospcl.c_addr, (long)256);
	if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
	    checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
		return(FAIL);
	buf->c_magic = NFS_MAGIC;

good:
	if ((buf->c_dinode.di_size == 0 || buf->c_dinode.di_size > 0xfffffff) &&
	    (buf->c_dinode.di_mode & IFMT) == IFDIR && Qcvt == 0) {
		qcvt.qval = buf->c_dinode.di_size;
		if (qcvt.val[0] || qcvt.val[1]) {
			printf("Note: Doing Quad swapping\n");
			Qcvt = 1;
		}
	}
	if (Qcvt) {
		qcvt.qval = buf->c_dinode.di_size;
		i = qcvt.val[1];
		qcvt.val[1] = qcvt.val[0];
		qcvt.val[0] = i;
		buf->c_dinode.di_size = qcvt.qval;
	}
	readmapflag = 0;

	switch (buf->c_type) {

	case TS_CLRI:
	case TS_BITS:
		/*
		 * Have to patch up missing information in bit map headers
		 */
		buf->c_inumber = 0;
		buf->c_dinode.di_size = buf->c_count * TP_BSIZE;
		if (buf->c_count > TP_NINDIR)
			readmapflag = 1;
		else 
			for (i = 0; i < buf->c_count; i++)
				buf->c_addr[i]++;
		break;

	case TS_TAPE:
		if ((buf->c_flags & DR_NEWINODEFMT) == 0)
			oldinofmt = 1;
		/* fall through */
	case TS_END:
		buf->c_inumber = 0;
		break;

	case TS_INODE:
	case TS_ADDR:
		break;

	default:
		panic("gethead: unknown inode type %d\n", buf->c_type);
		break;
	}
	/*
	 * If we are restoring a filesystem with old format inodes,
	 * copy the uid/gid to the new location.
	 */
	if (oldinofmt) {
		buf->c_dinode.di_uid = buf->c_dinode.di_ouid;
		buf->c_dinode.di_gid = buf->c_dinode.di_ogid;
	}
	tapeaddr = buf->c_tapea;
	if (dflag)
		accthdr(buf);
	return(GOOD);
}