Exemple #1
0
int
extractfile(char *name)
{
	int flags;
	uid_t uid;
	gid_t gid;
	mode_t mode;
	int extsize;
	struct timeval mtimep[2], ctimep[2];
	struct entry *ep;
	char *buf;

	curfile.name = name;
	curfile.action = USING;
	mtimep[0].tv_sec = curfile.atime_sec;
	mtimep[0].tv_usec = curfile.atime_nsec / 1000;
	mtimep[1].tv_sec = curfile.mtime_sec;
	mtimep[1].tv_usec = curfile.mtime_nsec / 1000;
	ctimep[0].tv_sec = curfile.atime_sec;
	ctimep[0].tv_usec = curfile.atime_nsec / 1000;
	ctimep[1].tv_sec = curfile.birthtime_sec;
	ctimep[1].tv_usec = curfile.birthtime_nsec / 1000;
	extsize = curfile.extsize;
	uid = getuid();
	if (uid == 0)
		uid = curfile.uid;
	gid = curfile.gid;
	mode = curfile.mode;
	flags = curfile.file_flags;
	switch (mode & IFMT) {

	default:
		fprintf(stderr, "%s: unknown file mode 0%o\n", name, mode);
		skipfile();
		return (FAIL);

	case IFSOCK:
		vprintf(stdout, "skipped socket %s\n", name);
		skipfile();
		return (GOOD);

	case IFDIR:
		if (mflag) {
			ep = lookupname(name);
			if (ep == NULL || ep->e_flags & EXTRACT)
				panic("unextracted directory %s\n", name);
			skipfile();
			return (GOOD);
		}
		vprintf(stdout, "extract file %s\n", name);
		return (genliteraldir(name, curfile.ino));

	case IFLNK:
		lnkbuf[0] = '\0';
		pathlen = 0;
		buf = setupextattr(extsize);
		getfile(xtrlnkfile, xtrattr, xtrlnkskip);
		if (pathlen == 0) {
			vprintf(stdout,
			    "%s: zero length symbolic link (ignored)\n", name);
			return (GOOD);
		}
		if (linkit(lnkbuf, name, SYMLINK) == GOOD) {
			if (extsize > 0)
				set_extattr_link(name, buf, extsize);
			(void) lchown(name, uid, gid);
			(void) lchmod(name, mode);
			(void) lutimes(name, ctimep);
			(void) lutimes(name, mtimep);
			(void) lchflags(name, flags);
			return (GOOD);
		}
		return (FAIL);

	case IFIFO:
		vprintf(stdout, "extract fifo %s\n", name);
		if (Nflag) {
			skipfile();
			return (GOOD);
		}
		if (uflag)
			(void) unlink(name);
		if (mkfifo(name, 0600) < 0) {
			fprintf(stderr, "%s: cannot create fifo: %s\n",
			    name, strerror(errno));
			skipfile();
			return (FAIL);
		}
		if (extsize == 0) {
			skipfile();
		} else {
			buf = setupextattr(extsize);
			getfile(xtrnull, xtrattr, xtrnull);
			set_extattr_file(name, buf, extsize);
		}
		(void) chown(name, uid, gid);
		(void) chmod(name, mode);
		(void) utimes(name, ctimep);
		(void) utimes(name, mtimep);
		(void) chflags(name, flags);
		return (GOOD);

	case IFCHR:
	case IFBLK:
		vprintf(stdout, "extract special file %s\n", name);
		if (Nflag) {
			skipfile();
			return (GOOD);
		}
		if (uflag)
			(void) unlink(name);
		if (mknod(name, (mode & (IFCHR | IFBLK)) | 0600,
		    (int)curfile.rdev) < 0) {
			fprintf(stderr, "%s: cannot create special file: %s\n",
			    name, strerror(errno));
			skipfile();
			return (FAIL);
		}
		if (extsize == 0) {
			skipfile();
		} else {
			buf = setupextattr(extsize);
			getfile(xtrnull, xtrattr, xtrnull);
			set_extattr_file(name, buf, extsize);
		}
		(void) chown(name, uid, gid);
		(void) chmod(name, mode);
		(void) utimes(name, ctimep);
		(void) utimes(name, mtimep);
		(void) chflags(name, flags);
		return (GOOD);

	case IFREG:
		vprintf(stdout, "extract file %s\n", name);
		if (Nflag) {
			skipfile();
			return (GOOD);
		}
		if (uflag)
			(void) unlink(name);
		if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC,
		    0600)) < 0) {
			fprintf(stderr, "%s: cannot create file: %s\n",
			    name, strerror(errno));
			skipfile();
			return (FAIL);
		}
		buf = setupextattr(extsize);
		getfile(xtrfile, xtrattr, xtrskip);
		if (extsize > 0)
			set_extattr_fd(ofile, name, buf, extsize);
		(void) fchown(ofile, uid, gid);
		(void) fchmod(ofile, mode);
		(void) futimes(ofile, ctimep);
		(void) futimes(ofile, mtimep);
		(void) fchflags(ofile, flags);
		(void) close(ofile);
		return (GOOD);
	}
	/* NOTREACHED */
}
Exemple #2
0
/*
 * Set the mode, owner, and times for all new or changed directories
 */
void
setdirmodes(int flags)
{
	FILE *mf;
	struct modeinfo node;
	struct entry *ep;
	char *cp, *buf;
	const char *tmpdir;
	int bufsize;
	uid_t myuid;

	vprintf(stdout, "Set directory mode, owner, and times.\n");
	if ((tmpdir = getenv("TMPDIR")) == NULL || tmpdir[0] == '\0')
		tmpdir = _PATH_TMP;
	if (command == 'r' || command == 'R')
		(void) sprintf(modefile, "%s/rstmode%jd", tmpdir,
		    (intmax_t)dumpdate);
	if (modefile[0] == '#') {
		panic("modefile not defined\n");
		fprintf(stderr, "directory mode, owner, and times not set\n");
		return;
	}
	mf = fopen(modefile, "r");
	if (mf == NULL) {
		fprintf(stderr, "fopen: %s\n", strerror(errno));
		fprintf(stderr, "cannot open mode file %s\n", modefile);
		fprintf(stderr, "directory mode, owner, and times not set\n");
		return;
	}
	clearerr(mf);
	bufsize = 0;
	myuid = getuid();
	for (;;) {
		(void) fread((char *)&node, 1, sizeof(struct modeinfo), mf);
		if (ferror(mf)) {
			warn("%s: cannot read modefile.", modefile);
			fprintf(stderr, "Mode, owner, and times not set.\n");
			break;
		}
		if (feof(mf))
			break;
		if (node.extsize > 0) {
			if (bufsize < node.extsize) {
				if (bufsize > 0)
					free(buf);
				if ((buf = malloc(node.extsize)) != 0) {
					bufsize = node.extsize;
				} else {
					bufsize = 0;
				}
			}
			if (bufsize >= node.extsize) {
				(void) fread(buf, 1, node.extsize, mf);
				if (ferror(mf)) {
					warn("%s: cannot read modefile.",
					    modefile);
					fprintf(stderr, "Not all external ");
					fprintf(stderr, "attributes set.\n");
					break;
				}
			} else {
				(void) fseek(mf, node.extsize, SEEK_CUR);
				if (ferror(mf)) {
					warn("%s: cannot seek in modefile.",
					    modefile);
					fprintf(stderr, "Not all directory ");
					fprintf(stderr, "attributes set.\n");
					break;
				}
			}
		}
		ep = lookupino(node.ino);
		if (command == 'i' || command == 'x') {
			if (ep == NULL)
				continue;
			if ((flags & FORCE) == 0 && ep->e_flags & EXISTED) {
				ep->e_flags &= ~NEW;
				continue;
			}
			if (node.ino == ROOTINO &&
		   	    reply("set owner/mode for '.'") == FAIL)
				continue;
		}
		if (ep == NULL) {
			panic("cannot find directory inode %ju\n",
			    (uintmax_t)node.ino);
			continue;
		}
		cp = myname(ep);
		if (!Nflag) {
			if (node.extsize > 0) {
				if (bufsize >= node.extsize) {
					set_extattr_file(cp, buf, node.extsize);
				} else {
					fprintf(stderr, "Cannot restore %s%s\n",
					    "extended attributes for ", cp);
				}
			}
			if (myuid != 0)
				(void) chown(cp, myuid, node.gid);
			else
				(void) chown(cp, node.uid, node.gid);
			(void) chmod(cp, node.mode);
			utimes(cp, node.ctimep);
			utimes(cp, node.mtimep);
			(void) chflags(cp, node.flags);
		}
		ep->e_flags &= ~NEW;
	}
	if (bufsize > 0)
		free(buf);
	(void) fclose(mf);
}