Exemplo n.º 1
0
/*
 * Put the directory entries in the directory file
 */
static void
putdir(char *buf, long size)
{
	struct direct cvtbuf;
	struct odirect *odp;
	struct odirect *eodp;
	struct direct *dp;
	long loc, i;

	if (cvtflag) {
		eodp = (struct odirect *)&buf[size];
		for (odp = (struct odirect *)buf; odp < eodp; odp++)
			if (odp->d_ino != 0) {
				dcvt(odp, &cvtbuf);
				putent(&cvtbuf);
			}
	} else {
		for (loc = 0; loc < size; ) {
			dp = (struct direct *)(buf + loc);
			if (Bcvt)
				swabst((u_char *)"ls", (u_char *) dp);
			if (oldinofmt && dp->d_ino != 0) {
#				if BYTE_ORDER == BIG_ENDIAN
					if (Bcvt)
						dp->d_namlen = dp->d_type;
#				else
					if (!Bcvt)
						dp->d_namlen = dp->d_type;
#				endif
				dp->d_type = DT_UNKNOWN;
			}
			i = DIRBLKSIZ - (loc & (DIRBLKSIZ - 1));
			if ((dp->d_reclen & 0x3) != 0 ||
			    dp->d_reclen > i ||
			    dp->d_reclen < DIRSIZ(0, dp) ||
			    dp->d_namlen > NAME_MAX) {
				vprintf(stdout, "Mangled directory: ");
				if ((dp->d_reclen & 0x3) != 0)
					vprintf(stdout,
					   "reclen not multiple of 4 ");
				if (dp->d_reclen < DIRSIZ(0, dp))
					vprintf(stdout,
					   "reclen less than DIRSIZ (%d < %d) ",
					   dp->d_reclen, DIRSIZ(0, dp));
				if (dp->d_namlen > NAME_MAX)
					vprintf(stdout,
					   "reclen name too big (%d > %d) ",
					   dp->d_namlen, NAME_MAX);
				vprintf(stdout, "\n");
				loc += i;
				continue;
			}
			loc += dp->d_reclen;
			if (dp->d_ino != 0) {
				putent(dp);
			}
		}
	}
}
Exemplo n.º 2
0
/*
 * Put the directory entries in the directory file
 */
static void
putdir(char *buf, long size)
{
	struct direct *dp;
	long loc, i;

	for (loc = 0; loc < size; ) {
		dp = (struct direct *)(buf + loc);
		if (Bcvt)
			swabst((u_char *)"ls", (u_char *) dp);
		if (oldinofmt && dp->d_ino != 0) {
#if BYTE_ORDER == BIG_ENDIAN
			if (Bcvt)
				dp->d_namlen = dp->d_type;
#else
			if (!Bcvt && dp->d_namlen == 0)
				dp->d_namlen = dp->d_type;
#endif
			dp->d_type = DT_UNKNOWN;
		}
		i = DIRBLKSIZ - (loc & (DIRBLKSIZ - 1));
		if ((dp->d_reclen & 0x3) != 0 ||
		    dp->d_reclen > i ||
		    dp->d_reclen < DIRSIZ(0, dp)
#if NAME_MAX < 255
		    || dp->d_namlen > NAME_MAX
#endif
		    ) {
			vprintf(stdout, "Mangled directory: ");
			if ((dp->d_reclen & 0x3) != 0)
				vprintf(stdout,
				   "reclen not multiple of 4 ");
			if (dp->d_reclen < DIRSIZ(0, dp))
				vprintf(stdout,
				   "reclen less than DIRSIZ (%d < %zu) ",
				   dp->d_reclen, DIRSIZ(0, dp));
#if NAME_MAX < 255
			if (dp->d_namlen > NAME_MAX)
				vprintf(stdout,
				   "reclen name too big (%d > %d) ",
				   dp->d_namlen, NAME_MAX);
#endif
			vprintf(stdout, "\n");
			loc += i;
			continue;
		}
		loc += dp->d_reclen;
		if (dp->d_ino != 0) {
			putent(dp);
		}
	}
}
Exemplo n.º 3
0
static u_long
swabl(u_long x)
{
	swabst((u_char *)"l", (u_char *)&x);
	return (x);
}
Exemplo n.º 4
0
/*
 * 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);
}
Exemplo n.º 5
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);
}