PERFORCE change 20723 for review

Brian Feldman green at freebsd.org
Tue Nov 5 23:03:56 GMT 2002


http://perforce.freebsd.org/chv.cgi?CH=20723

Change 20723 by green at green_laptop_2 on 2002/11/05 15:03:40

	* Add an -s argument which is like the -f argument but causes
	  setfsmac to utilize assumption of SEBSD context file format.
	* Correct bugs.  By removing them.
	* Finish implementing the labeling routines so that e.g.
	  SEBSD, LOMAC labelling is verified to work.

Affected files ...

.. //depot/projects/trustedbsd/mac/sbin/setfsmac/setfsmac.c#2 edit

Differences ...

==== //depot/projects/trustedbsd/mac/sbin/setfsmac/setfsmac.c#2 (text+ko) ====

@@ -5,6 +5,7 @@
 
 #include <ctype.h>
 #include <err.h>
+#include <errno.h>
 #include <fts.h>
 #include <regex.h>
 #include <stdio.h>
@@ -17,7 +18,10 @@
 		regex_t regex;	/* compiled regular expression to match */
 		char *regexstr;	/* uncompiled regular expression */
 		mode_t mode;	/* mode to possibly match */
+		char *modestr;	/* print-worthy ",-?" mode string */
 		mac_t mac;	/* MAC label to apply */
+		int flags;	/* miscellaneous flags */
+#define		F_DONTLABEL	0x01
 	} *entries;
 	size_t nentries;	/* size of entries list */
 	STAILQ_ENTRY(label_spec) link;
@@ -29,9 +33,9 @@
 
 void usage(void) __dead2;
 struct label_specs *new_specs(void);
-void add_specs(struct label_specs *, const char *);
-void add_spec_line(const char *, struct label_spec_entry *, char *);
-int apply_specs(struct label_specs *, FTSENT *);
+void add_specs(struct label_specs *, const char *, int);
+void add_spec_line(const char *, int, struct label_spec_entry *, char *);
+int apply_specs(struct label_specs *, FTSENT *, int);
 
 int
 main(int argc, char **argv)
@@ -39,16 +43,23 @@
 	FTSENT *ftsent;
 	FTS *fts;
 	struct label_specs *specs;
-	int eflag = 0, xflag = 0;
+	int eflag = 0, xflag = 0, vflag = 0;
 	int ch;
 
-	while ((ch = getopt(argc, argv, "ef:x")) != -1) {
+	specs = new_specs();
+	while ((ch = getopt(argc, argv, "ef:s:vx")) != -1) {
 		switch (ch) {
 		case 'e':
 			eflag = 1;
 			break;
 		case 'f':
-			add_specs(specs, optarg);
+			add_specs(specs, optarg, 0);
+			break;
+		case 's':
+			add_specs(specs, optarg, 1);
+			break;
+		case 'v':
+			vflag++;
 			break;
 		case 'x':
 			xflag = FTS_XDEV;
@@ -75,7 +86,7 @@
 		case FTS_F:		/* do regular */
 		case FTS_SL:		/* do symlink */
 		case FTS_W:		/* do whiteout */
-			if (apply_specs(specs, ftsent)) {
+			if (apply_specs(specs, ftsent, vflag)) {
 				if (eflag) {
 					errx(1, "labeling not supported in "
 					    "%.*s", ftsent->fts_pathlen,
@@ -105,14 +116,15 @@
 usage(void)
 {
 
-	fprintf(stderr, "usage: setfsmac [-ex] [-f specfile [...]] path ...\n");
+	fprintf(stderr, "usage: setfsmac [-evx] [-f specfile [...]] [-s specfile [...]] path ...\n");
 	exit(1);
 }
 
-void
+int
 chomp_line(char **line, size_t *linesize)
 {
 	char *s;
+	int freeme = 0;
 	
 	for (s = *line; s - *line < *linesize; s++) {
 		if (!isspace(*s))
@@ -121,7 +133,7 @@
 	if (*s == '#') {
 		**line = '\0';
 		*linesize = 0;
-		return;
+		return (freeme);
 	}
 	memmove(*line, s, *linesize - (s - *line));
 	*linesize -= s - *line;
@@ -136,19 +148,21 @@
 		if (s == NULL)
 			err(1, "malloc");
 		strncpy(s, *line, *linesize);
-		free(*line);
 		*line = s;
+		freeme = 1;
 	}
 	(*line)[*linesize] = '\0';
+	return (freeme);
 }
 
 void
-add_specs(struct label_specs *specs, const char *file)
+add_specs(struct label_specs *specs, const char *file, int is_sebsd)
 {
 	struct label_spec *spec;
 	FILE *fp;
 	char *line;
 	size_t nlines = 0, linesize;
+	int freeline;
 
 	spec = malloc(sizeof(*spec));
 	if (spec == NULL)
@@ -157,10 +171,11 @@
 	if (fp == NULL)
 		err(1, "opening %s", file);
 	while ((line = fgetln(fp, &linesize)) != NULL) {
-		chomp_line(&line, &linesize);
+		freeline = chomp_line(&line, &linesize);
 		if (linesize > 0) /* only allocate space for non-comments */
 			nlines++;
-		free(line);
+		if (freeline)
+			free(line);
 	}
 	if (ferror(fp))
 		err(1, "fgetln on %s", file);
@@ -177,21 +192,24 @@
 			else
 				err(1, "failure reading %s", file);
 		}
-		chomp_line(&line, &linesize);
+		freeline = chomp_line(&line, &linesize);
 		if (linesize == 0) {
-			free(line);
+			if (freeline)
+				free(line);
 			continue;
 		}
-		add_spec_line(file, &spec->entries[--nlines], line);
-		free(line);
+		add_spec_line(file, is_sebsd, &spec->entries[--nlines], line);
+		if (freeline)
+			free(line);
 	}
 	STAILQ_INSERT_TAIL(&specs->head, spec, link);
 }
 
 void
-add_spec_line(const char *file, struct label_spec_entry *entry, char *line)
+add_spec_line(const char *file, int is_sebsd, struct label_spec_entry *entry,
+    char *line)
 {
-	char *regexstr, *modestr, *macstr, *regerrorstr;
+	char *regexstr, *modestr, *macstr, *regerrorstr, *sebsdstr;
 	size_t size;
 	int error;
 
@@ -211,53 +229,138 @@
 	/* assume we need to anchor this regex */
 	if (asprintf(&regexstr, "^%s$", regexstr) == -1)
 		err(1, "%s: processing regular expression", file);
+	entry->regexstr = regexstr;
 	error = regcomp(&entry->regex, regexstr, REG_EXTENDED | REG_NOSUB);
 	if (error) {
 		size = regerror(error, &entry->regex, NULL, 0);
 		regerrorstr = malloc(size);
 		if (regerrorstr == NULL)
 			err(1, "malloc");
-		regerror(error, &entry->regex, regerrorstr, size);
-		errx(1, "%s: %s", file, regerrorstr);
+		(void)regerror(error, &entry->regex, regerrorstr, size);
+		errx(1, "%s: %s: %s", file, entry->regexstr, regerrorstr);
+	}
+	if (!is_sebsd) {
+		if (mac_from_text(&entry->mac, macstr))
+			err(1, "%s: mac_from_text(%s)", file, macstr);
+	} else {
+		if (asprintf(&sebsdstr, "sebsd/%s", macstr) == -1)
+			err(1, "asprintf");
+		if (mac_from_text(&entry->mac, sebsdstr))
+			err(1, "%s: mac_from_text(%s)", file, sebsdstr);
+		if (strcmp(macstr, "<<none>>") == 0)
+			entry->flags |= F_DONTLABEL;
+		free(sebsdstr);
+
 	}
-	entry->regexstr = regexstr;
-	if (mac_from_text(&entry->mac, macstr))
-		err(1, "%s: mac_from_text(%s)", file, macstr);
 	if (modestr != NULL) {
 		if (strlen(modestr) != 2 || modestr[0] != '-')
 			errx(1, "%s: invalid mode string: %s", file, modestr);
 		switch (modestr[1]) {
 		case 'b':
 			entry->mode = S_IFBLK;
+			entry->modestr = ",-b";
 			break;
 		case 'c':
 			entry->mode = S_IFCHR;
+			entry->modestr = ",-c";
 			break;
 		case 'd':
 			entry->mode = S_IFDIR;
+			entry->modestr = ",-d";
 			break;
 		case 'p':
 			entry->mode = S_IFIFO;
+			entry->modestr = ",-p";
 			break;
 		case 'l':
 			entry->mode = S_IFLNK;
+			entry->modestr = ",-l";
 			break;
 		case 's':
 			entry->mode = S_IFSOCK;
+			entry->modestr = ",-s";
 			break;
 		case '-':
 			entry->mode = S_IFREG;
+			entry->modestr = ",--";
 			break;
 		default:
 			errx(1, "%s: invalid mode string: %s", file, modestr);
 		}
+	} else {
+		entry->modestr = "";
 	}
 }
 
 int
-apply_specs(struct label_specs *specs, FTSENT *ftsent)
+apply_specs(struct label_specs *specs, FTSENT *ftsent, int vflag)
 {
+	regmatch_t pmatch;
+	struct label_spec *ls;
+	struct label_spec_entry *ent;
+	char *regerrorstr, *mactext;
+	size_t size;
+	int error, matchedby;
 
+	/*
+	 * Work through file context sources in order of specification
+	 * on the command line, and through their entries in reverse
+	 * order to find the "last" (hopefully "best") match.
+	 */
+	matchedby = 0;
+	STAILQ_FOREACH(ls, &specs->head, link) {
+		for (ent = ls->entries; ent < &ls->entries[ls->nentries];
+		    ent++) {
+			if (ent->mode != 0 &&
+			    (ftsent->fts_statp->st_mode & S_IFMT) != ent->mode)
+				continue;
+			pmatch.rm_so = 0;
+			pmatch.rm_eo = ftsent->fts_pathlen;
+			error = regexec(&ent->regex, ftsent->fts_path, 1,
+			    &pmatch, REG_STARTEND);
+			switch (error) {
+			case REG_NOMATCH:
+				continue;
+			case 0:
+				break;
+			default:
+				size = regerror(error, &ent->regex, NULL, 0);
+				regerrorstr = malloc(size);
+				if (regerrorstr == NULL)
+					err(1, "malloc");
+				(void)regerror(error, &ent->regex, regerrorstr,
+				    size);
+				errx(1, "%s: %s", ent->regexstr, regerrorstr);
+			}
+			if (vflag) {
+				if (matchedby == 0) {
+					printf("%.*s matched by ",
+					    ftsent->fts_pathlen,
+					    ftsent->fts_path);
+					matchedby = 1;
+				}
+				if (mac_to_text(ent->mac, &mactext) != 0)
+					err(1, "mac_to_text");
+				printf("%s(%s%s,%s)", matchedby == 2 ? "," : "",
+				    ent->regexstr, ent->modestr, mactext);
+				if (matchedby == 1)
+					matchedby = 2;
+				free(mactext);
+			}
+			if ((ent->flags & F_DONTLABEL) == 0 &&
+			    mac_set_link(ftsent->fts_accpath, ent->mac) != 0) {
+				if (errno == EOPNOTSUPP)
+					return (1);
+				if (vflag)
+					printf("\n");
+				err(1, "mac_set_link(%.*s)",
+				    ftsent->fts_pathlen, ftsent->fts_path);
+			}
+			break;
+		}
+	}
+	if (vflag && matchedby)
+		printf("\n");
 	return (0);
 }
 
To Unsubscribe: send mail to majordomo at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message



More information about the trustedbsd-cvs mailing list