Date: Tue, 5 Nov 2002 15:03:56 -0800 (PST) From: Brian Feldman <green@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 20723 for review Message-ID: <200211052303.gA5N3ugW074814@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=20723 Change 20723 by green@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(®exstr, "^%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@FreeBSD.org with "unsubscribe p4-projects" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200211052303.gA5N3ugW074814>