コード例 #1
0
ファイル: create.c プロジェクト: dstrctrng/pkgsrc
void
cwalk(void)
{
	FTS *t;
	FTSENT *p;
	time_t clocktime;
	char host[MAXHOSTNAMELEN + 1];
	char *argv[2];
	char  dot[] = ".";
	argv[0] = dot;
	argv[1] = NULL;

	time(&clocktime);
	gethostname(host, sizeof(host));
	host[sizeof(host) - 1] = '\0';
	printf(
	    "#\t   user: %s\n#\tmachine: %s\n#\t   tree: %s\n#\t   date: %s",
	    getlogin(), host, fullpath, ctime(&clocktime));

	if ((t = fts_open(argv, ftsoptions, dsort)) == NULL)
		mtree_err("fts_open: %s", strerror(errno));
	while ((p = fts_read(t)) != NULL) {
		if (check_excludes(p->fts_name, p->fts_path)) {
			fts_set(t, p, FTS_SKIP);
			continue;
		}
		switch(p->fts_info) {
		case FTS_D:
			printf("\n# %s\n", p->fts_path);
			statd(t, p, &uid, &gid, &mode, &flags);
			statf(p);
			break;
		case FTS_DP:
			if (p->fts_level > 0)
				printf("# %s\n..\n\n", p->fts_path);
			break;
		case FTS_DNR:
		case FTS_ERR:
		case FTS_NS:
			mtree_err("%s: %s",
			    p->fts_path, strerror(p->fts_errno));
			break;
		default:
			if (!dflag)
				statf(p);
			break;

		}
	}
	fts_close(t);
	if (sflag && keys & F_CKSUM)
		mtree_err("%s checksum: %u", fullpath, crc_total);
}
コード例 #2
0
ファイル: excludes.c プロジェクト: kusumi/DragonFlyBSD
void
read_excludes_file(const char *name)
{
	FILE *fp;
	char *line;
	struct exclude *e;

	fp = fopen(name, "r");
	if (fp == 0)
		err(1, "%s", name);

	while ((line = fparseln(fp, NULL, NULL, NULL,
	    FPARSELN_UNESCCOMM | FPARSELN_UNESCCONT | FPARSELN_UNESCESC))
	    != NULL) {
		if (line[0] == '\0')
			continue;

		if ((e = malloc(sizeof *e)) == NULL)
			mtree_err("memory allocation error");

		e->glob = line;
		if (strchr(e->glob, '/') != NULL)
			e->pathname = 1;
		else
			e->pathname = 0;
		LIST_INSERT_HEAD(&excludes, e, link);
	}
	fclose(fp);
}
コード例 #3
0
ファイル: compare.c プロジェクト: AgamAgarwal/minix
const char *
rlink(const char *name)
{
	static char lbuf[MAXPATHLEN];
	int len;

	if ((len = readlink(name, lbuf, sizeof(lbuf) - 1)) == -1)
		mtree_err("%s: %s", name, strerror(errno));
	lbuf[len] = '\0';
	return (lbuf);
}
コード例 #4
0
ファイル: spec.c プロジェクト: AlexZhao/freebsd
static dev_t
parsedev(char *arg)
{
#define MAX_PACK_ARGS	3
	u_long	numbers[MAX_PACK_ARGS];
	char	*p, *ep, *dev;
	int	argc;
	pack_t	*pack;
	dev_t	result;
	const char *error = NULL;

	if ((dev = strchr(arg, ',')) != NULL) {
		*dev++='\0';
		if ((pack = pack_find(arg)) == NULL)
			mtree_err("unknown format `%s'", arg);
		argc = 0;
		while ((p = strsep(&dev, ",")) != NULL) {
			if (*p == '\0')
				mtree_err("missing number");
			numbers[argc++] = strtoul(p, &ep, 0);
			if (*ep != '\0')
				mtree_err("invalid number `%s'",
				    p);
			if (argc > MAX_PACK_ARGS)
				mtree_err("too many arguments");
		}
		if (argc < 2)
			mtree_err("not enough arguments");
		result = (*pack)(argc, numbers, &error);
		if (error != NULL)
			mtree_err("%s", error);
	} else {
		result = (dev_t)strtoul(arg, &ep, 0);
		if (*ep != '\0')
			mtree_err("invalid device `%s'", arg);
	}
	return (result);
}
コード例 #5
0
ファイル: spec.c プロジェクト: AlexZhao/freebsd
/*
 * dump_nodes --
 *	dump the NODEs from `cur', based in the directory `dir'.
 *	if pathlast is none zero, print the path last, otherwise print
 *	it first.
 */
void
dump_nodes(const char *dir, NODE *root, int pathlast)
{
	NODE	*cur;
	char	path[MAXPATHLEN];
	const char *name;
	char	*str;
	char	*p, *q;

	for (cur = root; cur != NULL; cur = cur->next) {
		if (cur->type != F_DIR && !matchtags(cur))
			continue;

		if (snprintf(path, sizeof(path), "%s%s%s",
		    dir, *dir ? "/" : "", cur->name)
		    >= (int)sizeof(path))
			mtree_err("Pathname too long.");

		if (!pathlast)
			printf("%s", vispath(path));

#define MATCHFLAG(f)	((keys & (f)) && (cur->flags & (f)))
		if (MATCHFLAG(F_TYPE))
			appendfield(pathlast, "type=%s", nodetype(cur->type));
		if (MATCHFLAG(F_UID | F_UNAME)) {
			if (keys & F_UNAME &&
			    (name = user_from_uid(cur->st_uid, 1)) != NULL)
				appendfield(pathlast, "uname=%s", name);
			else
				appendfield(pathlast, "uid=%u", cur->st_uid);
		}
		if (MATCHFLAG(F_GID | F_GNAME)) {
			if (keys & F_GNAME &&
			    (name = group_from_gid(cur->st_gid, 1)) != NULL)
				appendfield(pathlast, "gname=%s", name);
			else
				appendfield(pathlast, "gid=%u", cur->st_gid);
		}
		if (MATCHFLAG(F_MODE))
			appendfield(pathlast, "mode=%#o", cur->st_mode);
		if (MATCHFLAG(F_DEV) &&
		    (cur->type == F_BLOCK || cur->type == F_CHAR))
			appendfield(pathlast, "device=%#llx", (long long)cur->st_rdev);
		if (MATCHFLAG(F_NLINK))
			appendfield(pathlast, "nlink=%d", cur->st_nlink);
		if (MATCHFLAG(F_SLINK))
			appendfield(pathlast, "link=%s", vispath(cur->slink));
		if (MATCHFLAG(F_SIZE))
			appendfield(pathlast, "size=%lld", (long long)cur->st_size);
		if (MATCHFLAG(F_TIME))
			appendfield(pathlast, "time=%lld.%09ld",
			    (long long)cur->st_mtimespec.tv_sec,
			    cur->st_mtimespec.tv_nsec);
		if (MATCHFLAG(F_CKSUM))
			appendfield(pathlast, "cksum=%lu", cur->cksum);
		if (MATCHFLAG(F_MD5))
			appendfield(pathlast, "%s=%s", MD5KEY, cur->md5digest);
		if (MATCHFLAG(F_RMD160))
			appendfield(pathlast, "%s=%s", RMD160KEY,
			    cur->rmd160digest);
		if (MATCHFLAG(F_SHA1))
			appendfield(pathlast, "%s=%s", SHA1KEY,
			    cur->sha1digest);
		if (MATCHFLAG(F_SHA256))
			appendfield(pathlast, "%s=%s", SHA256KEY,
			    cur->sha256digest);
		if (MATCHFLAG(F_SHA384))
			appendfield(pathlast, "%s=%s", SHA384KEY,
			    cur->sha384digest);
		if (MATCHFLAG(F_SHA512))
			appendfield(pathlast, "%s=%s", SHA512KEY,
			    cur->sha512digest);
		if (MATCHFLAG(F_FLAGS)) {
			str = flags_to_string(cur->st_flags, "none");
			appendfield(pathlast, "flags=%s", str);
			free(str);
		}
		if (MATCHFLAG(F_IGN))
			appendfield(pathlast, "ignore");
		if (MATCHFLAG(F_OPT))
			appendfield(pathlast, "optional");
		if (MATCHFLAG(F_TAGS)) {
			/* don't output leading or trailing commas */
			p = cur->tags;
			while (*p == ',')
				p++;
			q = p + strlen(p);
			while(q > p && q[-1] == ',')
				q--;
			appendfield(pathlast, "tags=%.*s", (int)(q - p), p);
		}
		puts(pathlast ? vispath(path) : "");

		if (cur->child)
			dump_nodes(path, cur->child, pathlast);
	}
}
コード例 #6
0
ファイル: spec.c プロジェクト: AlexZhao/freebsd
NODE *
spec(FILE *fp)
{
	NODE *centry, *last, *pathparent, *cur;
	char *p, *e, *next;
	NODE ginfo, *root;
	char *buf, *tname, *ntname;
	size_t tnamelen, plen;

	root = NULL;
	centry = last = NULL;
	tname = NULL;
	tnamelen = 0;
	memset(&ginfo, 0, sizeof(ginfo));
	for (mtree_lineno = 0;
	    (buf = fparseln(fp, NULL, &mtree_lineno, NULL,
		FPARSELN_UNESCCOMM));
	    free(buf)) {
		/* Skip leading whitespace. */
		for (p = buf; *p && isspace((unsigned char)*p); ++p)
			continue;

		/* If nothing but whitespace, continue. */
		if (!*p)
			continue;

#ifdef DEBUG
		fprintf(stderr, "line %lu: {%s}\n",
		    (u_long)mtree_lineno, p);
#endif
		/* Grab file name, "$", "set", or "unset". */
		next = buf;
		while ((p = strsep(&next, " \t")) != NULL && *p == '\0')
			continue;
		if (p == NULL)
			mtree_err("missing field");

		if (p[0] == '/') {
			if (strcmp(p + 1, "set") == 0)
				set(next, &ginfo);
			else if (strcmp(p + 1, "unset") == 0)
				unset(next, &ginfo);
			else
				mtree_err("invalid specification `%s'", p);
			continue;
		}

		if (strcmp(p, "..") == 0) {
			/* Don't go up, if haven't gone down. */
			if (root == NULL)
				goto noparent;
			if (last->type != F_DIR || last->flags & F_DONE) {
				if (last == root)
					goto noparent;
				last = last->parent;
			}
			last->flags |= F_DONE;
			continue;

noparent:		mtree_err("no parent node");
		}

		plen = strlen(p) + 1;
		if (plen > tnamelen) {
			if ((ntname = realloc(tname, plen)) == NULL)
				mtree_err("realloc: %s", strerror(errno));
			tname = ntname;
			tnamelen = plen;
		}
		if (strunvis(tname, p) == -1)
			mtree_err("strunvis failed on `%s'", p);
		p = tname;

		pathparent = NULL;
		if (strchr(p, '/') != NULL) {
			cur = root;
			for (; (e = strchr(p, '/')) != NULL; p = e+1) {
				if (p == e)
					continue;	/* handle // */
				*e = '\0';
				if (strcmp(p, ".") != 0) {
					while (cur &&
					    strcmp(cur->name, p) != 0) {
						cur = cur->next;
					}
				}
				if (cur == NULL || cur->type != F_DIR) {
					mtree_err("%s: %s", tname,
					"missing directory in specification");
				}
				*e = '/';
				pathparent = cur;
				cur = cur->child;
			}
			if (*p == '\0')
				mtree_err("%s: empty leaf element", tname);
		}

		if ((centry = calloc(1, sizeof(NODE) + strlen(p))) == NULL)
			mtree_err("%s", strerror(errno));
		*centry = ginfo;
		centry->lineno = mtree_lineno;
		strcpy(centry->name, p);
#define	MAGIC	"?*["
		if (strpbrk(p, MAGIC))
			centry->flags |= F_MAGIC;
		set(next, centry);

		if (root == NULL) {
				/*
				 * empty tree
				 */
			if (strcmp(centry->name, ".") != 0 ||
			    centry->type != F_DIR)
				mtree_err(
				    "root node must be the directory `.'");
			last = root = centry;
			root->parent = root;
		} else if (pathparent != NULL) {
				/*
				 * full path entry; add or replace
				 */
			centry->parent = pathparent;
			addchild(pathparent, centry);
			last = centry;
		} else if (strcmp(centry->name, ".") == 0) {
				/*
				 * duplicate "." entry; always replace
				 */
			replacenode(root, centry);
		} else if (last->type == F_DIR && !(last->flags & F_DONE)) {
				/*
				 * new relative child in current dir;
				 * add or replace
				 */
			centry->parent = last;
			addchild(last, centry);
			last = centry;
		} else {
				/*
				 * new relative child in parent dir
				 * (after encountering ".." entry);
				 * add or replace
				 */
			centry->parent = last->parent;
			addchild(last->parent, centry);
			last = centry;
		}
	}
	return (root);
}
コード例 #7
0
ファイル: create.c プロジェクト: 0xenvision/minix
static int
statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode,
      u_long *pflags)
{
	FTSENT *p;
	gid_t sgid;
	uid_t suid;
	mode_t smode;
	u_long sflags = 0;
	const char *name;
	gid_t savegid;
	uid_t saveuid;
	mode_t savemode;
	u_long saveflags;
	u_short maxgid, maxuid, maxmode, maxflags;
	u_short g[MTREE_MAXGID], u[MTREE_MAXUID],
		m[MTREE_MAXMODE], f[MTREE_MAXFLAGS];
	static int first = 1;

	savegid = *pgid;
	saveuid = *puid;
	savemode = *pmode;
	saveflags = *pflags;
	if ((p = fts_children(t, 0)) == NULL) {
		if (errno)
			mtree_err("%s: %s", RP(parent), strerror(errno));
		return (1);
	}

	memset(g, 0, sizeof(g));
	memset(u, 0, sizeof(u));
	memset(m, 0, sizeof(m));
	memset(f, 0, sizeof(f));

	maxuid = maxgid = maxmode = maxflags = 0;
	for (; p; p = p->fts_link) {
		smode = p->fts_statp->st_mode & MBITS;
		if (smode < MTREE_MAXMODE && ++m[smode] > maxmode) {
			savemode = smode;
			maxmode = m[smode];
		}
		sgid = p->fts_statp->st_gid;
		if (sgid < MTREE_MAXGID && ++g[sgid] > maxgid) {
			savegid = sgid;
			maxgid = g[sgid];
		}
		suid = p->fts_statp->st_uid;
		if (suid < MTREE_MAXUID && ++u[suid] > maxuid) {
			saveuid = suid;
			maxuid = u[suid];
		}

#if HAVE_STRUCT_STAT_ST_FLAGS
		sflags = FLAGS2INDEX(p->fts_statp->st_flags);
		if (sflags < MTREE_MAXFLAGS && ++f[sflags] > maxflags) {
			saveflags = p->fts_statp->st_flags;
			maxflags = f[sflags];
		}
#endif
	}
	/*
	 * If the /set record is the same as the last one we do not need to
	 * output a new one.  So first we check to see if anything changed.
	 * Note that we always output a /set record for the first directory.
	 */
	if (((keys & (F_UNAME | F_UID)) && (*puid != saveuid)) ||
	    ((keys & (F_GNAME | F_GID)) && (*pgid != savegid)) ||
	    ((keys & F_MODE) && (*pmode != savemode)) || 
	    ((keys & F_FLAGS) && (*pflags != saveflags)) ||
	    first) {
		first = 0;
		printf("/set type=file");
		if (keys & (F_UID | F_UNAME)) {
			if (keys & F_UNAME &&
			    (name = user_from_uid(saveuid, 1)) != NULL)
				printf(" uname=%s", name);
			else /* if (keys & F_UID) */
				printf(" uid=%lu", (u_long)saveuid);
		}
		if (keys & (F_GID | F_GNAME)) {
			if (keys & F_GNAME &&
			    (name = group_from_gid(savegid, 1)) != NULL)
				printf(" gname=%s", name);
			else /* if (keys & F_UID) */
				printf(" gid=%lu", (u_long)savegid);
		}
		if (keys & F_MODE)
			printf(" mode=%#lo", (u_long)savemode);
		if (keys & F_NLINK)
			printf(" nlink=1");
		if (keys & F_FLAGS)
			printf(" flags=%s",
			    flags_to_string(saveflags, "none"));
		printf("\n");
		*puid = saveuid;
		*pgid = savegid;
		*pmode = savemode;
		*pflags = saveflags;
	}
	return (0);
}
コード例 #8
0
ファイル: create.c プロジェクト: 0xenvision/minix
static void
statf(FTSENT *p)
{
	u_int32_t len, val;
	int fd, indent;
	const char *name;
#if !defined(NO_MD5) || !defined(NO_RMD160) || !defined(NO_SHA1) || !defined(NO_SHA2)
	char *digestbuf;
#endif

	indent = printf("%s%s",
	    S_ISDIR(p->fts_statp->st_mode) ? "" : "    ", vispath(p->fts_name));

	if (indent > INDENTNAMELEN)
		indent = MAXLINELEN;
	else
		indent += printf("%*s", INDENTNAMELEN - indent, "");

	if (!S_ISREG(p->fts_statp->st_mode))
		output(&indent, "type=%s", inotype(p->fts_statp->st_mode));
	if (keys & (F_UID | F_UNAME) && p->fts_statp->st_uid != uid) {
		if (keys & F_UNAME &&
		    (name = user_from_uid(p->fts_statp->st_uid, 1)) != NULL)
			output(&indent, "uname=%s", name);
		else /* if (keys & F_UID) */
			output(&indent, "uid=%u", p->fts_statp->st_uid);
	}
	if (keys & (F_GID | F_GNAME) && p->fts_statp->st_gid != gid) {
		if (keys & F_GNAME &&
		    (name = group_from_gid(p->fts_statp->st_gid, 1)) != NULL)
			output(&indent, "gname=%s", name);
		else /* if (keys & F_GID) */
			output(&indent, "gid=%u", p->fts_statp->st_gid);
	}
	if (keys & F_MODE && (p->fts_statp->st_mode & MBITS) != mode)
		output(&indent, "mode=%#o", p->fts_statp->st_mode & MBITS);
	if (keys & F_DEV &&
	    (S_ISBLK(p->fts_statp->st_mode) || S_ISCHR(p->fts_statp->st_mode)))
		output(&indent, "device=%#llx",
		    (long long)p->fts_statp->st_rdev);
	if (keys & F_NLINK && p->fts_statp->st_nlink != 1)
		output(&indent, "nlink=%u", p->fts_statp->st_nlink);
	if (keys & F_SIZE && S_ISREG(p->fts_statp->st_mode))
		output(&indent, "size=%lld", (long long)p->fts_statp->st_size);
	if (keys & F_TIME)
#if defined(BSD4_4) && !defined(HAVE_NBTOOL_CONFIG_H)
		output(&indent, "time=%ld.%ld",
		    (long)p->fts_statp->st_mtimespec.tv_sec,
		    p->fts_statp->st_mtimespec.tv_nsec);
#else
		output(&indent, "time=%ld.%ld",
		    (long)p->fts_statp->st_mtime, (long)0);
#endif
	if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) {
		if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0 ||
		    crc(fd, &val, &len))
			mtree_err("%s: %s", p->fts_accpath, strerror(errno));
		close(fd);
		output(&indent, "cksum=%lu", (long)val);
	}
#ifndef NO_MD5
	if (keys & F_MD5 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = MD5File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: MD5File failed: %s", p->fts_accpath, strerror(errno));
		output(&indent, "md5=%s", digestbuf);
		free(digestbuf);
	}
#endif	/* ! NO_MD5 */
#ifndef NO_RMD160
	if (keys & F_RMD160 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = RMD160File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: RMD160File failed: %s", p->fts_accpath, strerror(errno));
		output(&indent, "rmd160=%s", digestbuf);
		free(digestbuf);
	}
#endif	/* ! NO_RMD160 */
#ifndef NO_SHA1
	if (keys & F_SHA1 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = SHA1File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: SHA1File failed: %s", p->fts_accpath, strerror(errno));
		output(&indent, "sha1=%s", digestbuf);
		free(digestbuf);
	}
#endif	/* ! NO_SHA1 */
#ifndef NO_SHA2
	if (keys & F_SHA256 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = SHA256_File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: SHA256_File failed: %s", p->fts_accpath, strerror(errno));
		output(&indent, "sha256=%s", digestbuf);
		free(digestbuf);
	}
	if (keys & F_SHA384 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = SHA384_File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: SHA384_File failed: %s", p->fts_accpath, strerror(errno));
		output(&indent, "sha384=%s", digestbuf);
		free(digestbuf);
	}
	if (keys & F_SHA512 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = SHA512_File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: SHA512_File failed: %s", p->fts_accpath, strerror(errno));
		output(&indent, "sha512=%s", digestbuf);
		free(digestbuf);
	}
#endif	/* ! NO_SHA2 */
	if (keys & F_SLINK &&
	    (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE))
		output(&indent, "link=%s", vispath(rlink(p->fts_accpath)));
#if HAVE_STRUCT_STAT_ST_FLAGS
	if (keys & F_FLAGS && p->fts_statp->st_flags != flags)
		output(&indent, "flags=%s",
		    flags_to_string(p->fts_statp->st_flags, "none"));
#endif
	putchar('\n');
}
コード例 #9
0
int
main(int argc, char **argv)
{
	int	ch, status;
	unsigned int	i;
	int	cflag, Cflag, Dflag, Uflag, wflag;
	char	*dir, *p;
	FILE	*spec1, *spec2;

	setprogname(argv[0]);

	cflag = Cflag = Dflag = Uflag = wflag = 0;
	dir = NULL;
	init_excludes();
	spec1 = stdin;
	spec2 = NULL;

	while ((ch = getopt(argc, argv,
	    "bcCdDeE:f:F:I:ijk:K:lLmMnN:O:p:PqrR:s:StuUwWxX:"))
	    != -1) {
		switch((char)ch) {
		case 'b':
			bflag = 1;
			break;
		case 'c':
			cflag = 1;
			break;
		case 'C':
			Cflag = 1;
			break;
		case 'd':
			dflag = 1;
			break;
		case 'D':
			Dflag = 1;
			break;
		case 'E':
			parsetags(&excludetags, optarg);
			break;
		case 'e':
			eflag = 1;
			break;
		case 'f':
			if (spec1 == stdin) {
				spec1 = fopen(optarg, "r");
				if (spec1 == NULL)
					mtree_err("%s: %s", optarg,
					    strerror(errno));
			} else if (spec2 == NULL) {
				spec2 = fopen(optarg, "r");
				if (spec2 == NULL)
					mtree_err("%s: %s", optarg,
					    strerror(errno));
			} else
				usage();
			break;
		case 'F':
			for (i = 0; i < __arraycount(flavors); i++)
				if (strcmp(optarg, flavors[i].name) == 0) {
					flavor = flavors[i].flavor;
					break;
				}
			if (i == __arraycount(flavors))
				usage();
			break;
		case 'i':
			iflag = 1;
			break;
		case 'I':
			parsetags(&includetags, optarg);
			break;
		case 'j':
			jflag = 1;
			break;
		case 'k':
			keys = F_TYPE;
			while ((p = strsep(&optarg, " \t,")) != NULL)
				if (*p != '\0')
					keys |= parsekey(p, NULL);
			break;
		case 'K':
			while ((p = strsep(&optarg, " \t,")) != NULL)
				if (*p != '\0')
					keys |= parsekey(p, NULL);
			break;
		case 'l':
			lflag = 1;
			break;
		case 'L':
			ftsoptions &= ~FTS_PHYSICAL;
			ftsoptions |= FTS_LOGICAL;
			break;
		case 'm':
			mflag = 1;
			break;
		case 'M':
			mtree_Mflag = 1;
			break;
		case 'n':
			nflag = 1;
			break;
		case 'N':
			if (! setup_getid(optarg))
				mtree_err(
			    "Unable to use user and group databases in `%s'",
				    optarg);
			break;
		case 'O':
			load_only(optarg);
			break;
		case 'p':
			dir = optarg;
			break;
		case 'P':
			ftsoptions &= ~FTS_LOGICAL;
			ftsoptions |= FTS_PHYSICAL;
			break;
		case 'q':
			qflag = 1;
			break;
		case 'r':
			rflag++;
			break;
		case 'R':
			while ((p = strsep(&optarg, " \t,")) != NULL)
				if (*p != '\0')
					keys &= ~parsekey(p, NULL);
			break;
		case 's':
			sflag = 1;
			crc_total = ~strtol(optarg, &p, 0);
			if (*p)
				mtree_err("illegal seed value -- %s", optarg);
			break;
		case 'S':
			mtree_Sflag = 1;
			break;
		case 't':
			tflag = 1;
			break;
		case 'u':
			uflag = 1;
			break;
		case 'U':
			Uflag = uflag = 1;
			break;
		case 'w':
			wflag = 1;
			break;
		case 'W':
			mtree_Wflag = 1;
			break;
		case 'x':
			ftsoptions |= FTS_XDEV;
			break;
		case 'X':
			read_excludes_file(optarg);
			break;
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc)
		usage();

	switch (flavor) {
	case F_FREEBSD9:
		if (cflag && iflag) {
			warnx("-c and -i passed, replacing -i with -j for "
			    "FreeBSD compatibility");
			iflag = 0;
			jflag = 1;
		}
		if (dflag && !bflag) {
			warnx("Adding -b to -d for FreeBSD compatibility");
			bflag = 1;
		}
		if (uflag && !iflag) {
			warnx("Adding -i to -%c for FreeBSD compatibility",
			    Uflag ? 'U' : 'u');
			iflag = 1;
		}
		if (uflag && !tflag) {
			warnx("Adding -t to -%c for FreeBSD compatibility",
			    Uflag ? 'U' : 'u');
			tflag = 1;
		}
		if (wflag)
			warnx("The -w flag is a no-op");
		break;
	default:
		if (wflag)
			usage();
	}

	if (spec2 && (cflag || Cflag || Dflag))
		mtree_err("Double -f, -c, -C and -D flags are mutually "
		    "exclusive");

	if (dir && spec2)
		mtree_err("Double -f and -p flags are mutually exclusive");

	if (dir && chdir(dir))
		mtree_err("%s: %s", dir, strerror(errno));

	if ((cflag || sflag) && !getcwd(fullpath, sizeof(fullpath)))
		mtree_err("%s", strerror(errno));

	if ((cflag && Cflag) || (cflag && Dflag) || (Cflag && Dflag))
		mtree_err("-c, -C and -D flags are mutually exclusive");

	if (iflag && mflag)
		mtree_err("-i and -m flags are mutually exclusive");

	if (lflag && uflag)
		mtree_err("-l and -u flags are mutually exclusive");

	if (cflag) {
		cwalk(stdout);
		exit(0);
	}
	if (Cflag || Dflag) {
		dump_nodes(stdout, "", spec(spec1), Dflag);
		exit(0);
	}
	if (spec2 != NULL)
		status = mtree_specspec(spec1, spec2);
	else
		status = verify(spec1);
	if (Uflag && (status == MISMATCHEXIT))
		status = 0;
	exit(status);
}
コード例 #10
0
ファイル: verify.c プロジェクト: vocho/qnxpkgsrcmirror
static int
vwalk(void)
{
	FTS *t;
	FTSENT *p;
	NODE *ep, *level;
	int specdepth, rval;
	char *argv[2];
	char  dot[] = ".";
	argv[0] = dot;
	argv[1] = NULL;

	if ((t = fts_open(argv, ftsoptions, NULL)) == NULL)
		mtree_err("fts_open: %s", strerror(errno));
	level = root;
	specdepth = rval = 0;
	while ((p = fts_read(t)) != NULL) {
		if (check_excludes(p->fts_name, p->fts_path)) {
			fts_set(t, p, FTS_SKIP);
			continue;
		}
		switch(p->fts_info) {
		case FTS_D:
		case FTS_SL:
			break;
		case FTS_DP:
			if (specdepth > p->fts_level) {
				for (level = level->parent; level->prev;
				    level = level->prev)
					continue;
				--specdepth;
			}
			continue;
		case FTS_DNR:
		case FTS_ERR:
		case FTS_NS:
			warnx("%s: %s", RP(p), strerror(p->fts_errno));
			continue;
		default:
			if (dflag)
				continue;
		}

		if (specdepth != p->fts_level)
			goto extra;
		for (ep = level; ep; ep = ep->next)
			if ((ep->flags & F_MAGIC &&
			    !fnmatch(ep->name, p->fts_name, FNM_PATHNAME)) ||
			    !strcmp(ep->name, p->fts_name)) {
				ep->flags |= F_VISIT;
				if (compare(ep, p))
					rval = MISMATCHEXIT;
				if (!(ep->flags & F_IGN) &&
				    ep->type == F_DIR &&
				    p->fts_info == FTS_D) {
					if (ep->child) {
						level = ep->child;
						++specdepth;
					}
				} else
					fts_set(t, p, FTS_SKIP);
				break;
			}

		if (ep)
			continue;
 extra:
		if (!eflag) {
			printf("extra: %s", RP(p));
			if (rflag) {
				if ((S_ISDIR(p->fts_statp->st_mode)
				    ? rmdir : unlink)(p->fts_accpath)) {
					printf(", not removed: %s",
					    strerror(errno));
				} else
					printf(", removed");
			}
			putchar('\n');
		}
		fts_set(t, p, FTS_SKIP);
	}
	fts_close(t);
	if (sflag)
		warnx("%s checksum: %u", fullpath, crc_total);
	return (rval);
}
コード例 #11
0
ファイル: verify.c プロジェクト: vocho/qnxpkgsrcmirror
static void
miss(NODE *p, char *tail)
{
	int create;
	char *tp;
	const char *type;
	u_int32_t flags;

	for (; p; p = p->next) {
		if (p->flags & F_OPT && !(p->flags & F_VISIT))
			continue;
		if (p->type != F_DIR && (dflag || p->flags & F_VISIT))
			continue;
		strcpy(tail, p->name);
		if (!(p->flags & F_VISIT))
			printf("missing: %s", path);
		switch (p->type) {
		case F_BLOCK:
		case F_CHAR:
			type = "device";
			break;
		case F_DIR:
			type = "directory";
			break;
		case F_LINK:
			type = "symlink";
			break;
		default:
			putchar('\n');
			continue;
		}

		create = 0;
		if (!(p->flags & F_VISIT) && uflag) {
			if (mtree_Wflag || p->type == F_LINK)
				goto createit;
			if (!(p->flags & (F_UID | F_UNAME)))
			    printf(
				" (%s not created: user not specified)", type);
			else if (!(p->flags & (F_GID | F_GNAME)))
			    printf(
				" (%s not created: group not specified)", type);
			else if (!(p->flags & F_MODE))
			    printf(
				" (%s not created: mode not specified)", type);
			else
 createit:
			switch (p->type) {
			case F_BLOCK:
			case F_CHAR:
				if (mtree_Wflag)
					continue;
				if (!(p->flags & F_DEV))
					printf(
				    " (%s not created: device not specified)",
					    type);
				else if (mknod(path,
				    p->st_mode | nodetoino(p->type),
				    p->st_rdev) == -1)
					printf(" (%s not created: %s)\n",
					    type, strerror(errno));
				else
					create = 1;
				break;
			case F_LINK:
				if (!(p->flags & F_SLINK))
					printf(
				    " (%s not created: link not specified)\n",
					    type);
				else if (symlink(p->slink, path))
					printf(
					    " (%s not created: %s)\n",
					    type, strerror(errno));
				else
					create = 1;
				break;
			case F_DIR:
				if (mkdir(path, S_IRWXU|S_IRWXG|S_IRWXO))
					printf(" (not created: %s)",
					    strerror(errno));
				else
					create = 1;
				break;
			default:
				mtree_err("can't create create %s",
				    nodetype(p->type));
			}
		}
		if (create)
			printf(" (created)");
		if (p->type == F_DIR) {
			if (!(p->flags & F_VISIT))
				putchar('\n');
			for (tp = tail; *tp; ++tp)
				continue;
			*tp = '/';
			miss(p->child, tp + 1);
			*tp = '\0';
		} else
			putchar('\n');

		if (!create || mtree_Wflag)
			continue;
		if ((p->flags & (F_UID | F_UNAME)) &&
		    (p->flags & (F_GID | F_GNAME)) &&
		    (lchown(path, p->st_uid, p->st_gid))) {
			printf("%s: user/group/mode not modified: %s\n",
			    path, strerror(errno));
			printf("%s: warning: file mode %snot set\n", path,
			    (p->flags & F_FLAGS) ? "and file flags " : "");
			continue;
		}
		if (p->flags & F_MODE) {
			if (lchmod(path, p->st_mode))
				printf("%s: permissions not set: %s\n",
				    path, strerror(errno));
		}
#if HAVE_STRUCT_STAT_ST_FLAGS
		if ((p->flags & F_FLAGS) && p->st_flags) {
			if (iflag)
				flags = p->st_flags;
			else
				flags = p->st_flags & ~SP_FLGS;
			if (lchflags(path, flags))
				printf("%s: file flags not set: %s\n",
				    path, strerror(errno));
		}
#endif	/* HAVE_STRUCT_STAT_ST_FLAGS */
	}
}
コード例 #12
0
ファイル: create.c プロジェクト: ChaosJohn/freebsd
void
cwalk(void)
{
	FTS *t;
	FTSENT *p;
	time_t clocktime;
	char host[MAXHOSTNAMELEN + 1];
	const char *user;
	char *argv[2];
	char  dot[] = ".";
	int indent = 0;

	argv[0] = dot;
	argv[1] = NULL;

	time(&clocktime);
	gethostname(host, sizeof(host));
	host[sizeof(host) - 1] = '\0';
	if ((user = getlogin()) == NULL) {
		struct passwd *pw;
		user = (pw = getpwuid(getuid())) == NULL ? pw->pw_name :
		    "<unknown>";
	}

	if (!nflag)
		printf(
	    	    "#\t   user: %s\n#\tmachine: %s\n#\t   tree: %s\n"
		    "#\t   date: %s",
		    user, host, fullpath, ctime(&clocktime));

	if ((t = fts_open(argv, ftsoptions, dcmp)) == NULL)
		mtree_err("fts_open: %s", strerror(errno));
	while ((p = fts_read(t)) != NULL) {
		if (jflag)
			indent = p->fts_level * 4;
		if (check_excludes(p->fts_name, p->fts_path)) {
			fts_set(t, p, FTS_SKIP);
			continue;
		}
		if (!find_only(p->fts_path)) {
			fts_set(t, p, FTS_SKIP);
			continue;
		}
		switch(p->fts_info) {
		case FTS_D:
			if (!bflag)
				printf("\n");
			if (!nflag)
				printf("# %s\n", p->fts_path);
			statd(t, p, &uid, &gid, &mode, &flags);
			statf(indent, p);
			break;
		case FTS_DP:
			if (p->fts_level > 0)
				if (!nflag)
					printf("%*s# %s\n", indent, "",
					    p->fts_path);
			if (p->fts_level > 0 || flavor == F_FREEBSD9) {
				printf("%*s..\n", indent, "");
				if (!bflag)
					printf("\n");
			}
			break;
		case FTS_DNR:
		case FTS_ERR:
		case FTS_NS:
			mtree_err("%s: %s",
			    p->fts_path, strerror(p->fts_errno));
			break;
		default:
			if (!dflag)
				statf(indent, p);
			break;

		}
	}
	fts_close(t);
	if (sflag && keys & F_CKSUM)
		mtree_err("%s checksum: %u", fullpath, crc_total);
}
コード例 #13
0
ファイル: create.c プロジェクト: ChaosJohn/freebsd
static void
statf(int indent, FTSENT *p)
{
	u_int32_t len, val;
	int fd, offset;
	const char *name = NULL;
#if !defined(NO_MD5) || !defined(NO_RMD160) || !defined(NO_SHA1) || !defined(NO_SHA2)
	char *digestbuf;
#endif

	offset = printf("%*s%s%s", indent, "",
	    S_ISDIR(p->fts_statp->st_mode) ? "" : "    ", vispath(p->fts_name));

	if (offset > (INDENTNAMELEN + indent))
		offset = MAXLINELEN;
	else
		offset += printf("%*s", (INDENTNAMELEN + indent) - offset, "");

	if (!S_ISREG(p->fts_statp->st_mode) && (flavor == F_NETBSD6 || !dflag))
		output(indent, &offset, "type=%s",
		    inotype(p->fts_statp->st_mode));
	if (keys & (F_UID | F_UNAME) && p->fts_statp->st_uid != uid) {
		if (keys & F_UNAME &&
		    (name = user_from_uid(p->fts_statp->st_uid, 1)) != NULL)
			output(indent, &offset, "uname=%s", name);
		if (keys & F_UID || (keys & F_UNAME && name == NULL))
			output(indent, &offset, "uid=%u", p->fts_statp->st_uid);
	}
	if (keys & (F_GID | F_GNAME) && p->fts_statp->st_gid != gid) {
		if (keys & F_GNAME &&
		    (name = group_from_gid(p->fts_statp->st_gid, 1)) != NULL)
			output(indent, &offset, "gname=%s", name);
		if (keys & F_GID || (keys & F_GNAME && name == NULL))
			output(indent, &offset, "gid=%u", p->fts_statp->st_gid);
	}
	if (keys & F_MODE && (p->fts_statp->st_mode & MBITS) != mode)
		output(indent, &offset, "mode=%#o",
		    p->fts_statp->st_mode & MBITS);
	if (keys & F_DEV &&
	    (S_ISBLK(p->fts_statp->st_mode) || S_ISCHR(p->fts_statp->st_mode)))
		output(indent, &offset, "device=%#jx",
		    (uintmax_t)p->fts_statp->st_rdev);
	if (keys & F_NLINK && p->fts_statp->st_nlink != 1)
		output(indent, &offset, "nlink=%u", p->fts_statp->st_nlink);
	if (keys & F_SIZE &&
	    (flavor == F_FREEBSD9 || S_ISREG(p->fts_statp->st_mode)))
		output(indent, &offset, "size=%ju",
		    (uintmax_t)p->fts_statp->st_size);
	if (keys & F_TIME)
#if defined(BSD4_4) && !defined(HAVE_NBTOOL_CONFIG_H)
		output(indent, &offset, "time=%jd.%09ld",
		    (intmax_t)p->fts_statp->st_mtimespec.tv_sec,
		    p->fts_statp->st_mtimespec.tv_nsec);
#else
		output(indent, &offset, "time=%jd.%09ld",
		    (intmax_t)p->fts_statp->st_mtime, (long)0);
#endif
	if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) {
		if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0 ||
		    crc(fd, &val, &len))
			mtree_err("%s: %s", p->fts_accpath, strerror(errno));
		close(fd);
		output(indent, &offset, "cksum=%lu", (long)val);
	}
#ifndef NO_MD5
	if (keys & F_MD5 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = MD5File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: MD5File failed: %s", p->fts_accpath,
			    strerror(errno));
		output(indent, &offset, "%s=%s", MD5KEY, digestbuf);
		free(digestbuf);
	}
#endif	/* ! NO_MD5 */
#ifndef NO_RMD160
	if (keys & F_RMD160 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = RMD160File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: RMD160File failed: %s", p->fts_accpath,
			    strerror(errno));
		output(indent, &offset, "%s=%s", RMD160KEY, digestbuf);
		free(digestbuf);
	}
#endif	/* ! NO_RMD160 */
#ifndef NO_SHA1
	if (keys & F_SHA1 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = SHA1File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: SHA1File failed: %s", p->fts_accpath,
			    strerror(errno));
		output(indent, &offset, "%s=%s", SHA1KEY, digestbuf);
		free(digestbuf);
	}
#endif	/* ! NO_SHA1 */
#ifndef NO_SHA2
	if (keys & F_SHA256 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = SHA256_File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: SHA256_File failed: %s", p->fts_accpath,
			    strerror(errno));
		output(indent, &offset, "%s=%s", SHA256KEY, digestbuf);
		free(digestbuf);
	}
#ifdef SHA384_BLOCK_LENGTH
	if (keys & F_SHA384 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = SHA384_File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: SHA384_File failed: %s", p->fts_accpath,
			    strerror(errno));
		output(indent, &offset, "%s=%s", SHA384KEY, digestbuf);
		free(digestbuf);
	}
#endif
	if (keys & F_SHA512 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = SHA512_File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: SHA512_File failed: %s", p->fts_accpath,
			    strerror(errno));
		output(indent, &offset, "%s=%s", SHA512KEY, digestbuf);
		free(digestbuf);
	}
#endif	/* ! NO_SHA2 */
	if (keys & F_SLINK &&
	    (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE))
		output(indent, &offset, "link=%s",
		    vispath(rlink(p->fts_accpath)));
#if HAVE_STRUCT_STAT_ST_FLAGS
	if (keys & F_FLAGS && p->fts_statp->st_flags != flags) {
		char *str = flags_to_string(p->fts_statp->st_flags, "none");
		output(indent, &offset, "flags=%s", str);
		free(str);
	}
#endif
	putchar('\n');
}
コード例 #14
0
ファイル: spec.c プロジェクト: djbclark/bb10qnx
/*
 * dump_nodes --
 *	dump the NODEs from `cur', based in the directory `dir'.
 *	if pathlast is none zero, print the path last, otherwise print
 *	it first.
 */
void
dump_nodes(const char *dir, NODE *root, int pathlast)
{
	NODE	*cur;
	char	path[MAXPATHLEN];
	const char *name;

	for (cur = root; cur != NULL; cur = cur->next) {
		if (cur->type != F_DIR && !matchtags(cur))
			continue;

		if (snprintf(path, sizeof(path), "%s%s%s",
		    dir, *dir ? "/" : "", cur->name)
		    >= sizeof(path))
			mtree_err("Pathname too long.");

		if (!pathlast)
			printf("%s ", vispath(path));

#define MATCHFLAG(f)	((keys & (f)) && (cur->flags & (f)))
		if (MATCHFLAG(F_TYPE))
			printf("type=%s ", nodetype(cur->type));
		if (MATCHFLAG(F_UID | F_UNAME)) {
			if (keys & F_UNAME &&
			    (name = user_from_uid(cur->st_uid, 1)) != NULL)
				printf("uname=%s ", name);
			else
				printf("uid=%u ", cur->st_uid);
		}
		if (MATCHFLAG(F_GID | F_GNAME)) {
			if (keys & F_GNAME &&
			    (name = group_from_gid(cur->st_gid, 1)) != NULL)
				printf("gname=%s ", name);
			else
				printf("gid=%u ", cur->st_gid);
		}
		if (MATCHFLAG(F_MODE))
			printf("mode=%#o ", cur->st_mode);
		if (MATCHFLAG(F_DEV) &&
		    (cur->type == F_BLOCK || cur->type == F_CHAR))
			printf("device=%#x ", cur->st_rdev);
		if (MATCHFLAG(F_NLINK))
			printf("nlink=%d ", cur->st_nlink);
		if (MATCHFLAG(F_SLINK))
			printf("link=%s ", cur->slink);
		if (MATCHFLAG(F_SIZE))
			printf("size=%lld ", (long long)cur->st_size);
		if (MATCHFLAG(F_TIME))
			printf("time=%ld.%ld ", (long)cur->st_mtimespec.tv_sec,
			    cur->st_mtimespec.tv_nsec);
		if (MATCHFLAG(F_CKSUM))
			printf("cksum=%lu ", cur->cksum);
		if (MATCHFLAG(F_MD5))
			printf("md5=%s ", cur->md5digest);
		if (MATCHFLAG(F_RMD160))
			printf("rmd160=%s ", cur->rmd160digest);
		if (MATCHFLAG(F_SHA1))
			printf("sha1=%s ", cur->sha1digest);
		if (MATCHFLAG(F_FLAGS))
			printf("flags=%s ",
			    flags_to_string(cur->st_flags, "none"));
		if (MATCHFLAG(F_IGN))
			printf("ignore ");
		if (MATCHFLAG(F_OPT))
			printf("optional ");
		if (MATCHFLAG(F_TAGS))
			printf("tags=%s ", cur->tags);
		puts(pathlast ? vispath(path) : "");

		if (cur->child)
			dump_nodes(path, cur->child, pathlast);
	}
}