aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/sdiff
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2016-04-29 23:27:15 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2016-04-29 23:27:15 +0000
commit13b5b5486570cd88287ae97d741de8468428a6d3 (patch)
tree7ec38e45cbfa9d445907fa348017b10854448f2a /usr.bin/sdiff
parent5763d9db58d4d7671ac56057c98935c87aa695ad (diff)
downloadsrc-13b5b5486570cd88287ae97d741de8468428a6d3.tar.gz
src-13b5b5486570cd88287ae97d741de8468428a6d3.zip
Notes
Diffstat (limited to 'usr.bin/sdiff')
-rw-r--r--usr.bin/sdiff/Makefile16
-rw-r--r--usr.bin/sdiff/common.c24
-rw-r--r--usr.bin/sdiff/common.h9
-rw-r--r--usr.bin/sdiff/edit.c209
-rw-r--r--usr.bin/sdiff/extern.h12
-rw-r--r--usr.bin/sdiff/sdiff.1174
-rw-r--r--usr.bin/sdiff/sdiff.c1184
-rw-r--r--usr.bin/sdiff/tests/Makefile38
-rw-r--r--usr.bin/sdiff/tests/d_dot.in1
-rw-r--r--usr.bin/sdiff/tests/d_flags_l.out102
-rw-r--r--usr.bin/sdiff/tests/d_flags_s.out79
-rw-r--r--usr.bin/sdiff/tests/d_flags_w.out102
-rw-r--r--usr.bin/sdiff/tests/d_iflags_a1.out100
-rw-r--r--usr.bin/sdiff/tests/d_iflags_a2.out96
-rw-r--r--usr.bin/sdiff/tests/d_iflags_b1.out69
-rw-r--r--usr.bin/sdiff/tests/d_iflags_b2.out65
-rw-r--r--usr.bin/sdiff/tests/d_iflags_c1.out99
-rw-r--r--usr.bin/sdiff/tests/d_iflags_c2.out94
-rw-r--r--usr.bin/sdiff/tests/d_iflags_d1.out69
-rw-r--r--usr.bin/sdiff/tests/d_iflags_d2.out65
-rw-r--r--usr.bin/sdiff/tests/d_input172
-rw-r--r--usr.bin/sdiff/tests/d_input269
-rw-r--r--usr.bin/sdiff/tests/d_oneline.in1
-rw-r--r--usr.bin/sdiff/tests/d_oneline_a.out1
-rw-r--r--usr.bin/sdiff/tests/d_oneline_b.out1
-rw-r--r--usr.bin/sdiff/tests/d_same.out72
-rw-r--r--usr.bin/sdiff/tests/d_short.out15
-rw-r--r--usr.bin/sdiff/tests/d_tabends.in17
-rw-r--r--usr.bin/sdiff/tests/d_tabends_a.out17
-rw-r--r--usr.bin/sdiff/tests/d_tabends_b.out17
-rw-r--r--usr.bin/sdiff/tests/d_tabends_c.out17
-rw-r--r--usr.bin/sdiff/tests/d_tabs.out102
-rw-r--r--usr.bin/sdiff/tests/d_tabs1.in72
-rw-r--r--usr.bin/sdiff/tests/d_tabs2.in69
-rwxr-xr-xusr.bin/sdiff/tests/sdiff.sh207
35 files changed, 3356 insertions, 0 deletions
diff --git a/usr.bin/sdiff/Makefile b/usr.bin/sdiff/Makefile
new file mode 100644
index 000000000000..bc7d1dce1c53
--- /dev/null
+++ b/usr.bin/sdiff/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+PROG= sdiff
+SRCS= common.c edit.c sdiff.c
+WARNS= 3
+
+LIBADD= util
+MAN1= sdiff.1
+
+.if ${MK_TESTS} != "no"
+SUBDIR+= tests
+.endif
+
+.include <bsd.progs.mk>
diff --git a/usr.bin/sdiff/common.c b/usr.bin/sdiff/common.c
new file mode 100644
index 000000000000..686965c32b99
--- /dev/null
+++ b/usr.bin/sdiff/common.c
@@ -0,0 +1,24 @@
+/* $OpenBSD: common.c,v 1.4 2006/05/25 03:20:32 ray Exp $ */
+
+/*
+ * Written by Raymond Lai <ray@cyth.net>.
+ * Public domain.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <err.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "common.h"
+
+void
+cleanup(const char *filename)
+{
+
+ if (unlink(filename))
+ err(2, "could not delete: %s", filename);
+ exit(2);
+}
diff --git a/usr.bin/sdiff/common.h b/usr.bin/sdiff/common.h
new file mode 100644
index 000000000000..127c1f4b70f2
--- /dev/null
+++ b/usr.bin/sdiff/common.h
@@ -0,0 +1,9 @@
+/* $OpenBSD: common.h,v 1.2 2006/05/25 03:20:32 ray Exp $ */
+/* $FreeBSD$ */
+
+/*
+ * Written by Raymond Lai <ray@cyth.net>.
+ * Public domain.
+ */
+
+void cleanup(const char *) __dead2;
diff --git a/usr.bin/sdiff/edit.c b/usr.bin/sdiff/edit.c
new file mode 100644
index 000000000000..4d7fb5bcf8a2
--- /dev/null
+++ b/usr.bin/sdiff/edit.c
@@ -0,0 +1,209 @@
+/* $OpenBSD: edit.c,v 1.19 2009/06/07 13:29:50 ray Exp $ */
+
+/*
+ * Written by Raymond Lai <ray@cyth.net>.
+ * Public domain.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <paths.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "common.h"
+#include "extern.h"
+
+int editit(const char *);
+
+/*
+ * Execute an editor on the specified pathname, which is interpreted
+ * from the shell. This means flags may be included.
+ *
+ * Returns -1 on error, or the exit value on success.
+ */
+int
+editit(const char *pathname)
+{
+ char *argp[] = {"sh", "-c", NULL, NULL}, *ed, *p;
+ sig_t sighup, sigint, sigquit, sigchld;
+ pid_t pid;
+ int saved_errno, st, ret = -1;
+
+ ed = getenv("VISUAL");
+ if (ed == NULL || ed[0] == '\0')
+ ed = getenv("EDITOR");
+ if (ed == NULL || ed[0] == '\0')
+ ed = _PATH_VI;
+ if (asprintf(&p, "%s %s", ed, pathname) == -1)
+ return (-1);
+ argp[2] = p;
+
+ sighup = signal(SIGHUP, SIG_IGN);
+ sigint = signal(SIGINT, SIG_IGN);
+ sigquit = signal(SIGQUIT, SIG_IGN);
+ sigchld = signal(SIGCHLD, SIG_DFL);
+ if ((pid = fork()) == -1)
+ goto fail;
+ if (pid == 0) {
+ execv(_PATH_BSHELL, argp);
+ _exit(127);
+ }
+ while (waitpid(pid, &st, 0) == -1)
+ if (errno != EINTR)
+ goto fail;
+ if (!WIFEXITED(st))
+ errno = EINTR;
+ else
+ ret = WEXITSTATUS(st);
+
+ fail:
+ saved_errno = errno;
+ (void)signal(SIGHUP, sighup);
+ (void)signal(SIGINT, sigint);
+ (void)signal(SIGQUIT, sigquit);
+ (void)signal(SIGCHLD, sigchld);
+ free(p);
+ errno = saved_errno;
+ return (ret);
+}
+
+/*
+ * Parse edit command. Returns 0 on success, -1 on error.
+ */
+int
+eparse(const char *cmd, const char *left, const char *right)
+{
+ FILE *file;
+ size_t nread;
+ int fd;
+ char *filename;
+ char buf[BUFSIZ], *text;
+
+ /* Skip whitespace. */
+ while (isspace(*cmd))
+ ++cmd;
+
+ text = NULL;
+ switch (*cmd) {
+ case '\0':
+ /* Edit empty file. */
+ break;
+
+ case 'b':
+ /* Both strings. */
+ if (left == NULL)
+ goto RIGHT;
+ if (right == NULL)
+ goto LEFT;
+
+ /* Neither column is blank, so print both. */
+ if (asprintf(&text, "%s\n%s\n", left, right) == -1)
+ err(2, "could not allocate memory");
+ break;
+
+ case 'l':
+LEFT:
+ /* Skip if there is no left column. */
+ if (left == NULL)
+ break;
+
+ if (asprintf(&text, "%s\n", left) == -1)
+ err(2, "could not allocate memory");
+
+ break;
+
+ case 'r':
+RIGHT:
+ /* Skip if there is no right column. */
+ if (right == NULL)
+ break;
+
+ if (asprintf(&text, "%s\n", right) == -1)
+ err(2, "could not allocate memory");
+
+ break;
+
+ default:
+ return (-1);
+ }
+
+ /* Create temp file. */
+ if (asprintf(&filename, "%s/sdiff.XXXXXXXXXX", tmpdir) == -1)
+ err(2, "asprintf");
+ if ((fd = mkstemp(filename)) == -1)
+ err(2, "mkstemp");
+ if (text != NULL) {
+ size_t len;
+ ssize_t nwritten;
+
+ len = strlen(text);
+ if ((nwritten = write(fd, text, len)) == -1 ||
+ (size_t)nwritten != len) {
+ warn("error writing to temp file");
+ cleanup(filename);
+ }
+ }
+ close(fd);
+
+ /* text is no longer used. */
+ free(text);
+
+ /* Edit temp file. */
+ if (editit(filename) == -1) {
+ warn("error editing %s", filename);
+ cleanup(filename);
+ }
+
+ /* Open temporary file. */
+ if (!(file = fopen(filename, "r"))) {
+ warn("could not open edited file: %s", filename);
+ cleanup(filename);
+ }
+
+ /* Copy temporary file contents to output file. */
+ for (nread = sizeof(buf); nread == sizeof(buf);) {
+ size_t nwritten;
+
+ nread = fread(buf, sizeof(*buf), sizeof(buf), file);
+ /* Test for error or end of file. */
+ if (nread != sizeof(buf) &&
+ (ferror(file) || !feof(file))) {
+ warnx("error reading edited file: %s", filename);
+ cleanup(filename);
+ }
+
+ /*
+ * If we have nothing to read, break out of loop
+ * instead of writing nothing.
+ */
+ if (!nread)
+ break;
+
+ /* Write data we just read. */
+ nwritten = fwrite(buf, sizeof(*buf), nread, outfp);
+ if (nwritten != nread) {
+ warnx("error writing to output file");
+ cleanup(filename);
+ }
+ }
+
+ /* We've reached the end of the temporary file, so remove it. */
+ if (unlink(filename))
+ warn("could not delete: %s", filename);
+ fclose(file);
+
+ free(filename);
+
+ return (0);
+}
diff --git a/usr.bin/sdiff/extern.h b/usr.bin/sdiff/extern.h
new file mode 100644
index 000000000000..2f240912ddc1
--- /dev/null
+++ b/usr.bin/sdiff/extern.h
@@ -0,0 +1,12 @@
+/* $OpenBSD: extern.h,v 1.5 2009/06/07 13:29:50 ray Exp $ */
+/* $FreeBSD$ */
+
+/*
+ * Written by Raymond Lai <ray@cyth.net>.
+ * Public domain.
+ */
+
+extern FILE *outfp; /* file to save changes to */
+extern const char *tmpdir;
+
+int eparse(const char *, const char *, const char *);
diff --git a/usr.bin/sdiff/sdiff.1 b/usr.bin/sdiff/sdiff.1
new file mode 100644
index 000000000000..16e340a70ded
--- /dev/null
+++ b/usr.bin/sdiff/sdiff.1
@@ -0,0 +1,174 @@
+.\" $FreeBSD$
+.\" $OpenBSD: sdiff.1,v 1.15 2007/06/29 14:48:07 jmc Exp $
+.\"
+.\" Written by Raymond Lai <ray@cyth.net>.
+.\" Public domain.
+.\"
+.Dd $Mdocdate: July 5 2012 $
+.Dt SDIFF 1
+.Os
+.Sh NAME
+.Nm sdiff
+.Nd side-by-side diff
+.Sh SYNOPSIS
+.Nm
+.Op Fl abdilstW
+.Op Fl I Ar regexp
+.Op Fl o Ar outfile
+.Op Fl w Ar width
+.Ar file1
+.Ar file2
+.Sh DESCRIPTION
+.Nm
+displays two files side by side,
+with any differences between the two highlighted as follows:
+new lines are marked with
+.Sq \*(Gt ;
+deleted lines are marked with
+.Sq \*(Lt ;
+and changed lines are marked with
+.Sq \*(Ba .
+.Pp
+.Nm
+can also be used to interactively merge two files,
+prompting at each set of differences.
+See the
+.Fl o
+option for an explanation.
+.Pp
+The options are:
+.Bl -tag -width Ds
+.It Fl l -left-column
+Only print the left column for identical lines.
+.It Fl o -output Ar outfile
+Interactively merge
+.Ar file1
+and
+.Ar file2
+into
+.Ar outfile .
+In this mode, the user is prompted for each set of differences.
+See
+.Ev EDITOR
+and
+.Ev VISUAL ,
+below,
+for details of which editor, if any, is invoked.
+.Pp
+The commands are as follows:
+.Bl -tag -width Ds
+.It Cm l | 1
+Choose left set of diffs.
+.It Cm r | 2
+Choose right set of diffs.
+.It Cm s
+Silent mode \(en identical lines are not printed.
+.It Cm v
+Verbose mode \(en identical lines are printed.
+.It Cm e
+Start editing an empty file, which will be merged into
+.Ar outfile
+upon exiting the editor.
+.It Cm e Cm l
+Start editing file with left set of diffs.
+.It Cm e Cm r
+Start editing file with right set of diffs.
+.It Cm e Cm b
+Start editing file with both sets of diffs.
+.It Cm q
+Quit
+.Nm .
+.El
+.It Fl s -suppress-common-lines
+Skip identical lines.
+.It Fl w -width Ar width
+Print a maximum of
+.Ar width
+characters on each line.
+The default is 130 characters.
+.El
+.Pp
+Options passed to
+.Xr diff 1
+are:
+.Bl -tag -width Ds
+.It Fl a -text
+Treat
+.Ar file1
+and
+.Ar file2
+as text files.
+.It Fl b -ignore-space-change
+Ignore trailing blank spaces.
+.It Fl d -minimal
+Minimize diff size.
+.It Fl I -ignore-matching-lines Ar regexp
+Ignore line changes matching
+.Ar regexp .
+All lines in the change must match
+.Ar regexp
+for the change to be ignored.
+.It Fl i -ignore-case
+Do a case-insensitive comparison.
+.It Fl t -expand-tabs
+Expand tabs to spaces.
+.It Fl W -ignore-all-space
+Ignore all spaces.
+.It Fl B -ignore-blank-lines
+Ignore blank lines.
+.It Fl E -ignore-tab-expansion
+Treat tabs and eight spaces as the same.
+.It Fl t -ignore-tabs
+Ignore tabs.
+.It Fl H -speed-large-files
+Assume scattered small changes in a large file.
+.It Fl -ignore-file-name-case
+Ignore the case of file names.
+.It Fl -no-ignore-file-name-case
+Do not ignore file name case.
+.It Fl -strip-trailing-cr
+Skip identical lines.
+.It Fl -tabsize Ar NUM
+Change the size of tabs (default is 8.)
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width Ds
+.It Ev EDITOR , VISUAL
+Specifies an editor to use with the
+.Fl o
+option.
+If both
+.Ev EDITOR
+and
+.Ev VISUAL
+are set,
+.Ev VISUAL
+takes precedence.
+If neither
+.Ev EDITOR
+nor
+.Ev VISUAL
+are set,
+the default is
+.Xr vi 1 .
+.It Ev TMPDIR
+Specifies a directory for temporary files to be created.
+The default is
+.Pa /tmp .
+.El
+.Sh SEE ALSO
+.Xr cmp 1 ,
+.Xr diff 1 ,
+.Xr diff3 1 ,
+.Xr vi 1 ,
+.Xr re_format 7
+.Sh AUTHORS
+.Nm
+was written from scratch for the public domain by
+.An Ray Lai Aq ray@cyth.net .
+.Sh CAVEATS
+.Pp
+Tabs are treated as anywhere from one to eight characters wide,
+depending on the current column.
+Terminals that treat tabs as eight characters wide will look best.
+
diff --git a/usr.bin/sdiff/sdiff.c b/usr.bin/sdiff/sdiff.c
new file mode 100644
index 000000000000..0c822aae738b
--- /dev/null
+++ b/usr.bin/sdiff/sdiff.c
@@ -0,0 +1,1184 @@
+/* $OpenBSD: sdiff.c,v 1.36 2015/12/29 19:04:46 gsoares Exp $ */
+
+/*
+ * Written by Raymond Lai <ray@cyth.net>.
+ * Public domain.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <libutil.h>
+
+#include "common.h"
+#include "extern.h"
+
+#define DIFF_PATH "/usr/bin/diff"
+
+#define WIDTH 126
+/*
+ * Each column must be at least one character wide, plus three
+ * characters between the columns (space, [<|>], space).
+ */
+#define WIDTH_MIN 5
+
+/* 3 kilobytes of chars */
+#define MAX_CHECK 768
+
+/* A single diff line. */
+struct diffline {
+ STAILQ_ENTRY(diffline) diffentries;
+ char *left;
+ char div;
+ char *right;
+};
+
+static void astrcat(char **, const char *);
+static void enqueue(char *, char, char *);
+static char *mktmpcpy(const char *);
+static int istextfile(FILE *);
+static void binexec(char *, char *, char *) __dead2;
+static void freediff(struct diffline *);
+static void int_usage(void);
+static int parsecmd(FILE *, FILE *, FILE *);
+static void printa(FILE *, size_t);
+static void printc(FILE *, size_t, FILE *, size_t);
+static void printcol(const char *, size_t *, const size_t);
+static void printd(FILE *, size_t);
+static void println(const char *, const char, const char *);
+static void processq(void);
+static void prompt(const char *, const char *);
+static void usage(void) __dead2;
+static char *xfgets(FILE *);
+
+static STAILQ_HEAD(, diffline) diffhead = STAILQ_HEAD_INITIALIZER(diffhead);
+static size_t line_width; /* width of a line (two columns and divider) */
+static size_t width; /* width of each column */
+static size_t file1ln, file2ln; /* line number of file1 and file2 */
+static int Iflag = 0; /* ignore sets matching regexp */
+static int lflag; /* print only left column for identical lines */
+static int sflag; /* skip identical lines */
+FILE *outfp; /* file to save changes to */
+const char *tmpdir; /* TMPDIR or /tmp */
+
+enum {
+ HELP_OPT = CHAR_MAX + 1,
+ NORMAL_OPT,
+ FCASE_SENSITIVE_OPT,
+ FCASE_IGNORE_OPT,
+ FROMFILE_OPT,
+ TOFILE_OPT,
+ UNIDIR_OPT,
+ STRIPCR_OPT,
+ HORIZ_OPT,
+ LEFTC_OPT,
+ SUPCL_OPT,
+ LF_OPT,
+ /* the following groupings must be in sequence */
+ OLDGF_OPT,
+ NEWGF_OPT,
+ UNCGF_OPT,
+ CHGF_OPT,
+ OLDLF_OPT,
+ NEWLF_OPT,
+ UNCLF_OPT,
+ /* end order-sensitive enums */
+ TSIZE_OPT,
+ HLINES_OPT,
+ LFILES_OPT,
+ DIFFPROG_OPT,
+ PIPE_FD,
+ /* pid from the diff parent (if applicable) */
+ DIFF_PID,
+
+ NOOP_OPT,
+};
+
+static struct option longopts[] = {
+ /* options only processed in sdiff */
+ { "left-column", no_argument, NULL, LEFTC_OPT },
+ { "suppress-common-lines", no_argument, NULL, 's' },
+ { "width", required_argument, NULL, 'w' },
+
+ { "output", required_argument, NULL, 'o' },
+ { "diff-program", required_argument, NULL, DIFFPROG_OPT },
+
+ { "pipe-fd", required_argument, NULL, PIPE_FD },
+ { "diff-pid", required_argument, NULL, DIFF_PID },
+ /* Options processed by diff. */
+ { "ignore-file-name-case", no_argument, NULL, FCASE_IGNORE_OPT },
+ { "no-ignore-file-name-case", no_argument, NULL, FCASE_SENSITIVE_OPT },
+ { "strip-trailing-cr", no_argument, NULL, STRIPCR_OPT },
+ { "tabsize", required_argument, NULL, TSIZE_OPT },
+ { "help", no_argument, NULL, HELP_OPT },
+ { "text", no_argument, NULL, 'a' },
+ { "ignore-blank-lines", no_argument, NULL, 'B' },
+ { "ignore-space-change", no_argument, NULL, 'b' },
+ { "minimal", no_argument, NULL, 'd' },
+ { "ignore-tab-expansion", no_argument, NULL, 'E' },
+ { "ignore-matching-lines", required_argument, NULL, 'I' },
+ { "ignore-case", no_argument, NULL, 'i' },
+ { "expand-tabs", no_argument, NULL, 't' },
+ { "speed-large-files", no_argument, NULL, 'H' },
+ { "ignore-all-space", no_argument, NULL, 'W' },
+
+ { NULL, 0, NULL, '\0'}
+};
+
+static const char *help_msg[] = {
+ "\nusage: sdiff [-abdilstW] [-I regexp] [-o outfile] [-w width] file1 file2\n",
+ "\t-l, --left-column, Only print the left column for identical lines.",
+ "\t-o OUTFILE, --output=OUTFILE, nteractively merge file1 and file2 into outfile.",
+ "\t-s, --suppress-common-lines, Skip identical lines.",
+ "\t-w WIDTH, --width=WIDTH, Print a maximum of WIDTH characters on each line.",
+ "\tOptions passed to diff(1) are:",
+ "\t\t-a, --text, Treat file1 and file2 as text files.",
+ "\t\t-b, --ignore-trailing-cr, Ignore trailing blank spaces.",
+ "\t\t-d, --minimal, Minimize diff size.",
+ "\t\t-I RE, --ignore-matching-lines=RE, Ignore changes whose line matches RE.",
+ "\t\t-i, --ignore-case, Do a case-insensitive comparison.",
+ "\t\t-t, --expand-tabs Expand tabs to spaces.",
+ "\t\t-W, --ignore-all-spaces, Ignore all spaces.",
+ "\t\t--speed-large-files, Assume large file with scattered changes.",
+ "\t\t--strip-trailing-cr, Strip trailing carriage return.",
+ "\t\t--ignore-file-name-case, Ignore case of file names.",
+ "\t\t--no-ignore-file-name-case, Do not ignore file name case",
+ "\t\t--tabsize NUM, Change size of tabs (default 8.)",
+
+ NULL,
+};
+
+/*
+ * Create temporary file if source_file is not a regular file.
+ * Returns temporary file name if one was malloced, NULL if unnecessary.
+ */
+static char *
+mktmpcpy(const char *source_file)
+{
+ struct stat sb;
+ ssize_t rcount;
+ int ifd, ofd;
+ u_char buf[BUFSIZ];
+ char *target_file;
+
+ /* Open input and output. */
+ ifd = open(source_file, O_RDONLY, 0);
+ /* File was opened successfully. */
+ if (ifd != -1) {
+ if (fstat(ifd, &sb) == -1)
+ err(2, "error getting file status from %s", source_file);
+
+ /* Regular file. */
+ if (S_ISREG(sb.st_mode)) {
+ close(ifd);
+ return (NULL);
+ }
+ } else {
+ /* If ``-'' does not exist the user meant stdin. */
+ if (errno == ENOENT && strcmp(source_file, "-") == 0)
+ ifd = STDIN_FILENO;
+ else
+ err(2, "error opening %s", source_file);
+ }
+
+ /* Not a regular file, so copy input into temporary file. */
+ if (asprintf(&target_file, "%s/sdiff.XXXXXXXXXX", tmpdir) == -1)
+ err(2, "asprintf");
+ if ((ofd = mkstemp(target_file)) == -1) {
+ warn("error opening %s", target_file);
+ goto FAIL;
+ }
+ while ((rcount = read(ifd, buf, sizeof(buf))) != -1 &&
+ rcount != 0) {
+ ssize_t wcount;
+
+ wcount = write(ofd, buf, (size_t)rcount);
+ if (-1 == wcount || rcount != wcount) {
+ warn("error writing to %s", target_file);
+ goto FAIL;
+ }
+ }
+ if (rcount == -1) {
+ warn("error reading from %s", source_file);
+ goto FAIL;
+ }
+
+ close(ifd);
+ close(ofd);
+
+ return (target_file);
+
+FAIL:
+ unlink(target_file);
+ exit(2);
+}
+
+int
+main(int argc, char **argv)
+{
+ FILE *diffpipe=NULL, *file1, *file2;
+ size_t diffargc = 0, wflag = WIDTH;
+ int ch, fd[2] = {-1}, status;
+ pid_t pid=0; pid_t ppid =-1;
+ const char *outfile = NULL;
+ struct option *popt;
+ char **diffargv, *diffprog = DIFF_PATH, *filename1, *filename2,
+ *tmp1, *tmp2, *s1, *s2;
+ int i;
+
+ /*
+ * Process diff flags.
+ */
+ /*
+ * Allocate memory for diff arguments and NULL.
+ * Each flag has at most one argument, so doubling argc gives an
+ * upper limit of how many diff args can be passed. argv[0],
+ * file1, and file2 won't have arguments so doubling them will
+ * waste some memory; however we need an extra space for the
+ * NULL at the end, so it sort of works out.
+ */
+ if (!(diffargv = calloc(argc, sizeof(char **) * 2)))
+ err(2, "main");
+
+ /* Add first argument, the program name. */
+ diffargv[diffargc++] = diffprog;
+
+ /* create a dynamic string for merging single-switch options */
+ if ( asprintf(&diffargv[diffargc++], "-") < 0 )
+ err(2, "main");
+
+ while ((ch = getopt_long(argc, argv, "aBbdEHI:ilo:stWw:",
+ longopts, NULL)) != -1) {
+ const char *errstr;
+
+ switch (ch) {
+ /* only compatible --long-name-form with diff */
+ case FCASE_IGNORE_OPT:
+ case FCASE_SENSITIVE_OPT:
+ case STRIPCR_OPT:
+ case TSIZE_OPT:
+ case 'S':
+ break;
+ /* combine no-arg single switches */
+ case 'a':
+ case 'B':
+ case 'b':
+ case 'd':
+ case 'E':
+ case 'i':
+ case 't':
+ case 'H':
+ case 'W':
+ for(popt = longopts; ch != popt->val && popt->name != NULL; popt++);
+ diffargv[1] = realloc(diffargv[1], sizeof(char) * strlen(diffargv[1]) + 2);
+ /*
+ * In diff, the 'W' option is 'w' and the 'w' is 'W'.
+ */
+ if (ch == 'W')
+ sprintf(diffargv[1], "%sw", diffargv[1]);
+ else
+ sprintf(diffargv[1], "%s%c", diffargv[1], ch);
+ break;
+ case DIFFPROG_OPT:
+ diffargv[0] = diffprog = optarg;
+ break;
+ case 'I':
+ Iflag = 1;
+ diffargv[diffargc++] = "-I";
+ diffargv[diffargc++] = optarg;
+ break;
+ case 'l':
+ lflag = 1;
+ break;
+ case 'o':
+ outfile = optarg;
+ break;
+ case 's':
+ sflag = 1;
+ break;
+ case 'w':
+ wflag = strtonum(optarg, WIDTH_MIN,
+ INT_MAX, &errstr);
+ if (errstr)
+ errx(2, "width is %s: %s", errstr, optarg);
+ break;
+ case DIFF_PID:
+ ppid = strtonum(optarg, 0, INT_MAX, &errstr);
+ if (errstr)
+ errx(2, "diff pid value is %s: %s", errstr, optarg);
+ break;
+ case HELP_OPT:
+ for (i = 0; help_msg[i] != NULL; i++)
+ printf("%s\n", help_msg[i]);
+ exit(0);
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ /* no single switches were used */
+ if (strcmp(diffargv[1], "-") == 0 ) {
+ for ( i = 1; i < argc-1; i++) {
+ diffargv[i] = diffargv[i+1];
+ }
+ diffargv[diffargc-1] = NULL;
+ diffargc--;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 2)
+ usage();
+
+ if (outfile && (outfp = fopen(outfile, "w")) == NULL)
+ err(2, "could not open: %s", optarg);
+
+ if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0')
+ tmpdir = _PATH_TMP;
+
+ filename1 = argv[0];
+ filename2 = argv[1];
+
+ /*
+ * Create temporary files for diff and sdiff to share if file1
+ * or file2 are not regular files. This allows sdiff and diff
+ * to read the same inputs if one or both inputs are stdin.
+ *
+ * If any temporary files were created, their names would be
+ * saved in tmp1 or tmp2. tmp1 should never equal tmp2.
+ */
+ tmp1 = tmp2 = NULL;
+ /* file1 and file2 are the same, so copy to same temp file. */
+ if (strcmp(filename1, filename2) == 0) {
+ if ((tmp1 = mktmpcpy(filename1)))
+ filename1 = filename2 = tmp1;
+ /* Copy file1 and file2 into separate temp files. */
+ } else {
+ if ((tmp1 = mktmpcpy(filename1)))
+ filename1 = tmp1;
+ if ((tmp2 = mktmpcpy(filename2)))
+ filename2 = tmp2;
+ }
+
+ diffargv[diffargc++] = filename1;
+ diffargv[diffargc++] = filename2;
+ /* Add NULL to end of array to indicate end of array. */
+ diffargv[diffargc++] = NULL;
+
+ /* Subtract column divider and divide by two. */
+ width = (wflag - 3) / 2;
+ /* Make sure line_width can fit in size_t. */
+ if (width > (SIZE_MAX - 3) / 2)
+ errx(2, "width is too large: %zu", width);
+ line_width = width * 2 + 3;
+
+ if (ppid == -1 ) {
+ if (pipe(fd))
+ err(2, "pipe");
+
+ switch (pid = fork()) {
+ case 0:
+ /* child */
+ /* We don't read from the pipe. */
+ close(fd[0]);
+ if (dup2(fd[1], STDOUT_FILENO) == -1)
+ err(2, "child could not duplicate descriptor");
+ /* Free unused descriptor. */
+ close(fd[1]);
+ execvp(diffprog, diffargv);
+ err(2, "could not execute diff: %s", diffprog);
+ break;
+ case -1:
+ err(2, "could not fork");
+ break;
+ }
+
+ /* parent */
+ /* We don't write to the pipe. */
+ close(fd[1]);
+
+ /* Open pipe to diff command. */
+ if ((diffpipe = fdopen(fd[0], "r")) == NULL)
+ err(2, "could not open diff pipe");
+ }
+ if ((file1 = fopen(filename1, "r")) == NULL)
+ err(2, "could not open %s", filename1);
+ if ((file2 = fopen(filename2, "r")) == NULL)
+ err(2, "could not open %s", filename2);
+ if (!istextfile(file1) || !istextfile(file2)) {
+ /* Close open files and pipe, delete temps */
+ fclose(file1);
+ fclose(file2);
+ fclose(diffpipe);
+ if (tmp1)
+ if (unlink(tmp1))
+ warn("Error deleting %s.", tmp1);
+ if (tmp2)
+ if (unlink(tmp2))
+ warn("Error deleting %s.", tmp2);
+ free(tmp1);
+ free(tmp2);
+ binexec(diffprog, filename1, filename2);
+ }
+ /* Line numbers start at one. */
+ file1ln = file2ln = 1;
+
+ /* Read and parse diff output. */
+ while (parsecmd(diffpipe, file1, file2) != EOF)
+ ;
+ fclose(diffpipe);
+
+ /* Wait for diff to exit. */
+ if (waitpid(pid, &status, 0) == -1 || !WIFEXITED(status) ||
+ WEXITSTATUS(status) >= 2)
+ err(2, "diff exited abnormally.");
+
+ /* Delete and free unneeded temporary files. */
+ if (tmp1)
+ if (unlink(tmp1))
+ warn("Error deleting %s.", tmp1);
+ if (tmp2)
+ if (unlink(tmp2))
+ warn("Error deleting %s.", tmp2);
+ free(tmp1);
+ free(tmp2);
+ filename1 = filename2 = tmp1 = tmp2 = NULL;
+
+ /* No more diffs, so print common lines. */
+ if (lflag)
+ while ((s1 = xfgets(file1)))
+ enqueue(s1, ' ', NULL);
+ else
+ for (;;) {
+ s1 = xfgets(file1);
+ s2 = xfgets(file2);
+ if (s1 || s2)
+ enqueue(s1, ' ', s2);
+ else
+ break;
+ }
+ fclose(file1);
+ fclose(file2);
+ /* Process unmodified lines. */
+ processq();
+
+ /* Return diff exit status. */
+ return (WEXITSTATUS(status));
+}
+
+/*
+ * When sdiff/zsdiff detects a binary file as input, executes them with
+ * diff/zdiff to maintain the same behavior as GNU sdiff with binary input.
+ */
+static void
+binexec(char *diffprog, char *f1, char *f2)
+{
+
+ char *args[] = {diffprog, f1, f2, (char *) 0};
+ execv(diffprog, args);
+
+ /* If execv() fails, sdiff's execution will continue below. */
+ errx(1, "Could not execute diff process.\n");
+}
+
+/*
+ * Checks whether a file appears to be a text file.
+ */
+static int
+istextfile(FILE *f)
+{
+ int i;
+ char ch;
+
+ if (f == NULL)
+ return (1);
+ rewind(f);
+ for (i = 0; i <= MAX_CHECK || ch != EOF; i++) {
+ ch = fgetc(f);
+ if (ch == '\0') {
+ rewind(f);
+ return (0);
+ }
+ }
+ rewind(f);
+ return (1);
+}
+
+/*
+ * Prints an individual column (left or right), taking into account
+ * that tabs are variable-width. Takes a string, the current column
+ * the cursor is on the screen, and the maximum value of the column.
+ * The column value is updated as we go along.
+ */
+static void
+printcol(const char *s, size_t *col, const size_t col_max)
+{
+
+ for (; *s && *col < col_max; ++s) {
+ size_t new_col;
+
+ switch (*s) {
+ case '\t':
+ /*
+ * If rounding to next multiple of eight causes
+ * an integer overflow, just return.
+ */
+ if (*col > SIZE_MAX - 8)
+ return;
+
+ /* Round to next multiple of eight. */
+ new_col = (*col / 8 + 1) * 8;
+
+ /*
+ * If printing the tab goes past the column
+ * width, don't print it and just quit.
+ */
+ if (new_col > col_max)
+ return;
+ *col = new_col;
+ break;
+ default:
+ ++(*col);
+ }
+ putchar(*s);
+ }
+}
+
+/*
+ * Prompts user to either choose between two strings or edit one, both,
+ * or neither.
+ */
+static void
+prompt(const char *s1, const char *s2)
+{
+ char *cmd;
+
+ /* Print command prompt. */
+ putchar('%');
+
+ /* Get user input. */
+ for (; (cmd = xfgets(stdin)); free(cmd)) {
+ const char *p;
+
+ /* Skip leading whitespace. */
+ for (p = cmd; isspace(*p); ++p)
+ ;
+ switch (*p) {
+ case 'e':
+ /* Skip `e'. */
+ ++p;
+ if (eparse(p, s1, s2) == -1)
+ goto USAGE;
+ break;
+ case 'l':
+ case '1':
+ /* Choose left column as-is. */
+ if (s1 != NULL)
+ fprintf(outfp, "%s\n", s1);
+ /* End of command parsing. */
+ break;
+ case 'q':
+ goto QUIT;
+ case 'r':
+ case '2':
+ /* Choose right column as-is. */
+ if (s2 != NULL)
+ fprintf(outfp, "%s\n", s2);
+ /* End of command parsing. */
+ break;
+ case 's':
+ sflag = 1;
+ goto PROMPT;
+ case 'v':
+ sflag = 0;
+ /* FALLTHROUGH */
+ default:
+ /* Interactive usage help. */
+USAGE:
+ int_usage();
+PROMPT:
+ putchar('%');
+
+ /* Prompt user again. */
+ continue;
+ }
+ free(cmd);
+ return;
+ }
+
+ /*
+ * If there was no error, we received an EOF from stdin, so we
+ * should quit.
+ */
+QUIT:
+ fclose(outfp);
+ exit(0);
+}
+
+/*
+ * Takes two strings, separated by a column divider. NULL strings are
+ * treated as empty columns. If the divider is the ` ' character, the
+ * second column is not printed (-l flag). In this case, the second
+ * string must be NULL. When the second column is NULL, the divider
+ * does not print the trailing space following the divider character.
+ *
+ * Takes into account that tabs can take multiple columns.
+ */
+static void
+println(const char *s1, const char div, const char *s2)
+{
+ size_t col;
+
+ /* Print first column. Skips if s1 == NULL. */
+ col = 0;
+ if (s1) {
+ /* Skip angle bracket and space. */
+ printcol(s1, &col, width);
+
+ }
+
+ /* Otherwise, we pad this column up to width. */
+ for (; col < width; ++col)
+ putchar(' ');
+
+ /* Only print left column. */
+ if (div == ' ' && !s2) {
+ printf(" (\n");
+ return;
+ }
+
+ /*
+ * Print column divider. If there is no second column, we don't
+ * need to add the space for padding.
+ */
+ if (!s2) {
+ printf(" %c\n", div);
+ return;
+ }
+ printf(" %c ", div);
+ col += 3;
+
+ /* Skip angle bracket and space. */
+ printcol(s2, &col, line_width);
+
+ putchar('\n');
+}
+
+/*
+ * Reads a line from file and returns as a string. If EOF is reached,
+ * NULL is returned. The returned string must be freed afterwards.
+ */
+static char *
+xfgets(FILE *file)
+{
+ const char delim[3] = {'\0', '\0', '\0'};
+ char *s;
+
+ /* XXX - Is this necessary? */
+ clearerr(file);
+
+ if (!(s = fparseln(file, NULL, NULL, delim, 0)) &&
+ ferror(file))
+ err(2, "error reading file");
+
+ if (!s) {
+ return (NULL);
+ }
+
+ return (s);
+}
+
+/*
+ * Parse ed commands from diffpipe and print lines from file1 (lines
+ * to change or delete) or file2 (lines to add or change).
+ * Returns EOF or 0.
+ */
+static int
+parsecmd(FILE *diffpipe, FILE *file1, FILE *file2)
+{
+ size_t file1start, file1end, file2start, file2end, n;
+ /* ed command line and pointer to characters in line */
+ char *line, *p, *q;
+ const char *errstr;
+ char c, cmd;
+
+ /* Read ed command. */
+ if (!(line = xfgets(diffpipe)))
+ return (EOF);
+
+ p = line;
+ /* Go to character after line number. */
+ while (isdigit(*p))
+ ++p;
+ c = *p;
+ *p++ = 0;
+ file1start = strtonum(line, 0, INT_MAX, &errstr);
+ if (errstr)
+ errx(2, "file1 start is %s: %s", errstr, line);
+
+ /* A range is specified for file1. */
+ if (c == ',') {
+ q = p;
+ /* Go to character after file2end. */
+ while (isdigit(*p))
+ ++p;
+ c = *p;
+ *p++ = 0;
+ file1end = strtonum(q, 0, INT_MAX, &errstr);
+ if (errstr)
+ errx(2, "file1 end is %s: %s", errstr, line);
+ if (file1start > file1end)
+ errx(2, "invalid line range in file1: %s", line);
+ } else
+ file1end = file1start;
+
+ cmd = c;
+ /* Check that cmd is valid. */
+ if (!(cmd == 'a' || cmd == 'c' || cmd == 'd'))
+ errx(2, "ed command not recognized: %c: %s", cmd, line);
+
+ q = p;
+ /* Go to character after line number. */
+ while (isdigit(*p))
+ ++p;
+ c = *p;
+ *p++ = 0;
+ file2start = strtonum(q, 0, INT_MAX, &errstr);
+ if (errstr)
+ errx(2, "file2 start is %s: %s", errstr, line);
+
+ /*
+ * There should either be a comma signifying a second line
+ * number or the line should just end here.
+ */
+ if (c != ',' && c != '\0')
+ errx(2, "invalid line range in file2: %c: %s", c, line);
+
+ if (c == ',') {
+
+ file2end = strtonum(p, 0, INT_MAX, &errstr);
+ if (errstr)
+ errx(2, "file2 end is %s: %s", errstr, line);
+ if (file2start >= file2end)
+ errx(2, "invalid line range in file2: %s", line);
+ } else
+ file2end = file2start;
+
+ /* Appends happen _after_ stated line. */
+ if (cmd == 'a') {
+ if (file1start != file1end)
+ errx(2, "append cannot have a file1 range: %s",
+ line);
+ if (file1start == SIZE_MAX)
+ errx(2, "file1 line range too high: %s", line);
+ file1start = ++file1end;
+ }
+ /*
+ * I'm not sure what the deal is with the line numbers for
+ * deletes, though.
+ */
+ else if (cmd == 'd') {
+ if (file2start != file2end)
+ errx(2, "delete cannot have a file2 range: %s",
+ line);
+ if (file2start == SIZE_MAX)
+ errx(2, "file2 line range too high: %s", line);
+ file2start = ++file2end;
+ }
+
+ /*
+ * Continue reading file1 and file2 until we reach line numbers
+ * specified by diff. Should only happen with -I flag.
+ */
+ for (; file1ln < file1start && file2ln < file2start;
+ ++file1ln, ++file2ln) {
+ char *s1, *s2;
+
+ if (!(s1 = xfgets(file1)))
+ errx(2, "file1 shorter than expected");
+ if (!(s2 = xfgets(file2)))
+ errx(2, "file2 shorter than expected");
+
+ /* If the -l flag was specified, print only left column. */
+ if (lflag) {
+ free(s2);
+ /*
+ * XXX - If -l and -I are both specified, all
+ * unchanged or ignored lines are shown with a
+ * `(' divider. This matches GNU sdiff, but I
+ * believe it is a bug. Just check out:
+ * gsdiff -l -I '^$' samefile samefile.
+ */
+ if (Iflag)
+ enqueue(s1, '(', NULL);
+ else
+ enqueue(s1, ' ', NULL);
+ } else
+ enqueue(s1, ' ', s2);
+ }
+ /* Ignore deleted lines. */
+ for (; file1ln < file1start; ++file1ln) {
+ char *s;
+
+ if (!(s = xfgets(file1)))
+ errx(2, "file1 shorter than expected");
+
+ enqueue(s, '(', NULL);
+ }
+ /* Ignore added lines. */
+ for (; file2ln < file2start; ++file2ln) {
+ char *s;
+
+ if (!(s = xfgets(file2)))
+ errx(2, "file2 shorter than expected");
+
+ /* If -l flag was given, don't print right column. */
+ if (lflag)
+ free(s);
+ else
+ enqueue(NULL, ')', s);
+ }
+
+ /* Process unmodified or skipped lines. */
+ processq();
+
+ switch (cmd) {
+ case 'a':
+ printa(file2, file2end);
+ n = file2end - file2start + 1;
+ break;
+ case 'c':
+ printc(file1, file1end, file2, file2end);
+ n = file1end - file1start + 1 + 1 + file2end - file2start + 1;
+ break;
+ case 'd':
+ printd(file1, file1end);
+ n = file1end - file1start + 1;
+ break;
+ default:
+ errx(2, "invalid diff command: %c: %s", cmd, line);
+ }
+ free(line);
+
+ /* Skip to next ed line. */
+ while (n--) {
+ if (!(line = xfgets(diffpipe)))
+ errx(2, "diff ended early");
+ free(line);
+ }
+
+ return (0);
+}
+
+/*
+ * Queues up a diff line.
+ */
+static void
+enqueue(char *left, char div, char *right)
+{
+ struct diffline *diffp;
+
+ if (!(diffp = malloc(sizeof(struct diffline))))
+ err(2, "enqueue");
+ diffp->left = left;
+ diffp->div = div;
+ diffp->right = right;
+ STAILQ_INSERT_TAIL(&diffhead, diffp, diffentries);
+}
+
+/*
+ * Free a diffline structure and its elements.
+ */
+static void
+freediff(struct diffline *diffp)
+{
+
+ free(diffp->left);
+ free(diffp->right);
+ free(diffp);
+}
+
+/*
+ * Append second string into first. Repeated appends to the same string
+ * are cached, making this an O(n) function, where n = strlen(append).
+ */
+static void
+astrcat(char **s, const char *append)
+{
+ /* Length of string in previous run. */
+ static size_t offset = 0;
+ size_t newsiz;
+ /*
+ * String from previous run. Compared to *s to see if we are
+ * dealing with the same string. If so, we can use offset.
+ */
+ static const char *oldstr = NULL;
+ char *newstr;
+
+ /*
+ * First string is NULL, so just copy append.
+ */
+ if (!*s) {
+ if (!(*s = strdup(append)))
+ err(2, "astrcat");
+
+ /* Keep track of string. */
+ offset = strlen(*s);
+ oldstr = *s;
+
+ return;
+ }
+
+ /*
+ * *s is a string so concatenate.
+ */
+
+ /* Did we process the same string in the last run? */
+ /*
+ * If this is a different string from the one we just processed
+ * cache new string.
+ */
+ if (oldstr != *s) {
+ offset = strlen(*s);
+ oldstr = *s;
+ }
+
+ /* Size = strlen(*s) + \n + strlen(append) + '\0'. */
+ newsiz = offset + 1 + strlen(append) + 1;
+
+ /* Resize *s to fit new string. */
+ newstr = realloc(*s, newsiz);
+ if (newstr == NULL)
+ err(2, "astrcat");
+ *s = newstr;
+
+ /* *s + offset should be end of string. */
+ /* Concatenate. */
+ strlcpy(*s + offset, "\n", newsiz - offset);
+ strlcat(*s + offset, append, newsiz - offset);
+
+ /* New string length should be exactly newsiz - 1 characters. */
+ /* Store generated string's values. */
+ offset = newsiz - 1;
+ oldstr = *s;
+}
+
+/*
+ * Process diff set queue, printing, prompting, and saving each diff
+ * line stored in queue.
+ */
+static void
+processq(void)
+{
+ struct diffline *diffp;
+ char divc, *left, *right;
+
+ /* Don't process empty queue. */
+ if (STAILQ_EMPTY(&diffhead))
+ return;
+
+ /* Remember the divider. */
+ divc = STAILQ_FIRST(&diffhead)->div;
+
+ left = NULL;
+ right = NULL;
+ /*
+ * Go through set of diffs, concatenating each line in left or
+ * right column into two long strings, `left' and `right'.
+ */
+ STAILQ_FOREACH(diffp, &diffhead, diffentries) {
+ /*
+ * Print changed lines if -s was given,
+ * print all lines if -s was not given.
+ */
+ if (!sflag || diffp->div == '|' || diffp->div == '<' ||
+ diffp->div == '>')
+ println(diffp->left, diffp->div, diffp->right);
+
+ /* Append new lines to diff set. */
+ if (diffp->left)
+ astrcat(&left, diffp->left);
+ if (diffp->right)
+ astrcat(&right, diffp->right);
+ }
+
+ /* Empty queue and free each diff line and its elements. */
+ while (!STAILQ_EMPTY(&diffhead)) {
+ diffp = STAILQ_FIRST(&diffhead);
+ STAILQ_REMOVE_HEAD(&diffhead, diffentries);
+ freediff(diffp);
+ }
+
+ /* Write to outfp, prompting user if lines are different. */
+ if (outfp)
+ switch (divc) {
+ case ' ': case '(': case ')':
+ fprintf(outfp, "%s\n", left);
+ break;
+ case '|': case '<': case '>':
+ prompt(left, right);
+ break;
+ default:
+ errx(2, "invalid divider: %c", divc);
+ }
+
+ /* Free left and right. */
+ free(left);
+ free(right);
+}
+
+/*
+ * Print lines following an (a)ppend command.
+ */
+static void
+printa(FILE *file, size_t line2)
+{
+ char *line;
+
+ for (; file2ln <= line2; ++file2ln) {
+ if (!(line = xfgets(file)))
+ errx(2, "append ended early");
+ enqueue(NULL, '>', line);
+ }
+ processq();
+}
+
+/*
+ * Print lines following a (c)hange command, from file1ln to file1end
+ * and from file2ln to file2end.
+ */
+static void
+printc(FILE *file1, size_t file1end, FILE *file2, size_t file2end)
+{
+ struct fileline {
+ STAILQ_ENTRY(fileline) fileentries;
+ char *line;
+ };
+ STAILQ_HEAD(, fileline) delqhead = STAILQ_HEAD_INITIALIZER(delqhead);
+
+ /* Read lines to be deleted. */
+ for (; file1ln <= file1end; ++file1ln) {
+ struct fileline *linep;
+ char *line1;
+
+ /* Read lines from both. */
+ if (!(line1 = xfgets(file1)))
+ errx(2, "error reading file1 in delete in change");
+
+ /* Add to delete queue. */
+ if (!(linep = malloc(sizeof(struct fileline))))
+ err(2, "printc");
+ linep->line = line1;
+ STAILQ_INSERT_TAIL(&delqhead, linep, fileentries);
+ }
+
+ /* Process changed lines.. */
+ for (; !STAILQ_EMPTY(&delqhead) && file2ln <= file2end;
+ ++file2ln) {
+ struct fileline *del;
+ char *add;
+
+ /* Get add line. */
+ if (!(add = xfgets(file2)))
+ errx(2, "error reading add in change");
+
+ del = STAILQ_FIRST(&delqhead);
+ enqueue(del->line, '|', add);
+ STAILQ_REMOVE_HEAD(&delqhead, fileentries);
+ /*
+ * Free fileline structure but not its elements since
+ * they are queued up.
+ */
+ free(del);
+ }
+ processq();
+
+ /* Process remaining lines to add. */
+ for (; file2ln <= file2end; ++file2ln) {
+ char *add;
+
+ /* Get add line. */
+ if (!(add = xfgets(file2)))
+ errx(2, "error reading add in change");
+
+ enqueue(NULL, '>', add);
+ }
+ processq();
+
+ /* Process remaining lines to delete. */
+ while (!STAILQ_EMPTY(&delqhead)) {
+ struct fileline *filep;
+
+ filep = STAILQ_FIRST(&delqhead);
+ enqueue(filep->line, '<', NULL);
+ STAILQ_REMOVE_HEAD(&delqhead, fileentries);
+ free(filep);
+ }
+ processq();
+}
+
+/*
+ * Print deleted lines from file, from file1ln to file1end.
+ */
+static void
+printd(FILE *file1, size_t file1end)
+{
+ char *line1;
+
+ /* Print out lines file1ln to line2. */
+ for (; file1ln <= file1end; ++file1ln) {
+ if (!(line1 = xfgets(file1)))
+ errx(2, "file1 ended early in delete");
+ enqueue(line1, '<', NULL);
+ }
+ processq();
+}
+
+/*
+ * Interactive mode usage.
+ */
+static void
+int_usage(void)
+{
+
+ puts("e:\tedit blank diff\n"
+ "eb:\tedit both diffs concatenated\n"
+ "el:\tedit left diff\n"
+ "er:\tedit right diff\n"
+ "l | 1:\tchoose left diff\n"
+ "r | 2:\tchoose right diff\n"
+ "s:\tsilent mode--don't print identical lines\n"
+ "v:\tverbose mode--print identical lines\n"
+ "q:\tquit");
+}
+
+static void
+usage(void)
+{
+
+ fprintf(stderr,
+ "usage: sdiff [-abdilstW] [-I regexp] [-o outfile] [-w width] file1"
+ " file2\n");
+ exit(2);
+}
diff --git a/usr.bin/sdiff/tests/Makefile b/usr.bin/sdiff/tests/Makefile
new file mode 100644
index 000000000000..2c0b916bb9e1
--- /dev/null
+++ b/usr.bin/sdiff/tests/Makefile
@@ -0,0 +1,38 @@
+# $FreeBSD$
+
+PACKAGE= tests
+FILEGROUPS= TESTS
+TESTPACKAGE= ${PACKAGE}
+TESTDIR= ${TESTSBASE}/usr.bin/sdiff
+
+ATF_TESTS_SH= sdiff
+
+FILESDIR= ${TESTDIR}
+FILES= d_dot.in \
+ d_flags_l.out \
+ d_flags_s.out \
+ d_flags_w.out \
+ d_iflags_a1.out \
+ d_iflags_a2.out \
+ d_iflags_b1.out \
+ d_iflags_b2.out \
+ d_iflags_c1.out \
+ d_iflags_c2.out \
+ d_iflags_d1.out \
+ d_iflags_d2.out \
+ d_input1 \
+ d_input2 \
+ d_oneline.in \
+ d_oneline_a.out \
+ d_oneline_b.out \
+ d_same.out \
+ d_short.out \
+ d_tabends.in \
+ d_tabends_a.out \
+ d_tabends_b.out \
+ d_tabends_c.out \
+ d_tabs.out \
+ d_tabs1.in \
+ d_tabs2.in
+
+.include <bsd.test.mk>
diff --git a/usr.bin/sdiff/tests/d_dot.in b/usr.bin/sdiff/tests/d_dot.in
new file mode 100644
index 000000000000..9c558e357c41
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_dot.in
@@ -0,0 +1 @@
+.
diff --git a/usr.bin/sdiff/tests/d_flags_l.out b/usr.bin/sdiff/tests/d_flags_l.out
new file mode 100644
index 000000000000..ac8d2ad41e5a
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_flags_l.out
@@ -0,0 +1,102 @@
+Policy: /usr/bin/lynx, Emulation: native (
+ > native-issetugid: permit
+ > native-mprotect: permit
+ > native-mmap: permit
+ native-__sysctl: permit (
+ > native-fsread: filename eq "/var/run/ld.so.hints" then pe
+ > native-fstat: permit
+ native-close: permit (
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-fsread: filename match "/usr/lib/libssl.so.*" then
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-read: permit
+ native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" t
+ native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*"
+ native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then p
+ native-fsread: filename match "/<non-existent filename>: | native-munmap: permit
+ native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit
+ native-fsread: filename eq "/etc/malloc.conf" then permit (
+ native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit
+ native-fsread: filename eq "/etc/utmp" then permit <
+ native-fsread: filename eq "/home" then permit <
+ native-fsread: filename eq "$HOME" then permit <
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then per <
+ native-fsread: filename eq "$HOME/.lynxrc" then permit <
+ native-fsread: filename eq "$HOME/.mailcap" then permit <
+ native-fsread: filename eq "$HOME/.mime.types" then permi <
+ native-fsread: filename eq "$HOME/.terminfo" then permit <
+ native-fsread: filename eq "$HOME/.terminfo.db" then perm <
+ native-fsread: filename eq "/obj" then permit <
+ native-fsread: filename eq "/tmp" then permit (
+ > native-fswrite: filename match "/tmp/lynx-*" then permit
+ native-fsread: filename match "/tmp/lynx-*/." then permit (
+ > native-fsread: filename eq "$HOME" then permit
+ > native-fsread: filename eq "/etc/lynx.cfg" then permit
+ > native-fsread: filename eq "/" then permit
+ > native-fsread: filename eq "/usr/obj/bin/systrace/." then
+ > native-fsread: filename eq "/usr/obj/bin" then permit
+ > native-fcntl: permit
+ > native-getdirentries: permit
+ > native-lseek: permit
+ > native-fsread: filename eq "/usr/obj" then permit
+ native-fsread: filename eq "/usr" then permit (
+ native-fsread: filename eq "/usr/bin" then permit (
+ native-fsread: filename eq "/usr/games" then permit (
+ native-fsread: filename eq "/usr/include" then permit (
+ native-fsread: filename eq "/usr/lib" then permit (
+ native-fsread: filename match "/usr/lib/libc.so.*" then p <
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" t <
+ native-fsread: filename match "/usr/lib/libncurses.so.*" <
+ native-fsread: filename match "/usr/lib/libssl.so.*" then <
+ native-fsread: filename eq "/usr/libdata" then permit (
+ native-fsread: filename eq "/usr/libexec" then permit (
+ native-fsread: filename eq "/usr/lkm" then permit (
+ native-fsread: filename eq "/usr/local" then permit (
+ native-fsread: filename eq "/usr/mdec" then permit (
+ native-fsread: filename eq "/usr/obj" then permit | native-fsread: filename eq "/home" then permit
+ native-fsread: filename eq "/usr/obj/bin" then permit | native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then | native-fsread: filename eq "$HOME/.lynxrc" then permit
+ > native-fsread: filename match "/<non-existent filename>:
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mailca (
+ > native-fsread: filename eq "$HOME/.mailcap" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t (
+ > native-fsread: filename eq "$HOME/.mime.types" then permi
+ > native-sigaction: permit
+ > native-ioctl: permit
+ > native-fsread: filename eq "$HOME/.terminfo.db" then perm
+ > native-fsread: filename eq "$HOME/.terminfo" then permit
+ native-fsread: filename eq "/usr/share/misc/terminfo.db" (
+ > native-pread: permit
+ > native-write: permit
+ > native-fsread: filename eq "$HOME/.lynx-keymaps" then per
+ native-fsread: filename eq "/var/run/dev.db" then permit (
+ native-fsread: filename eq "/var/run/ld.so.hints" then pe | native-fsread: filename eq "/etc/utmp" then permit
+ native-fstat: permit <
+ native-fswrite: filename match "/tmp/lynx-*" then permit <
+ native-getdirentries: permit <
+ native-getpid: permit <
+ native-gettimeofday: permit <
+ native-ioctl: permit <
+ native-issetugid: permit <
+ native-lseek: permit <
+ native-mmap: permit <
+ native-mprotect: prot eq "PROT_READ" then permit <
+ native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" <
+ native-munmap: permit <
+ native-nanosleep: permit <
+ native-poll: permit (
+ native-pread: permit | native-nanosleep: permit
+ native-read: permit | native-gettimeofday: permit
+ native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit
+ native-select: permit <
+ native-sendto: true then permit <
+ native-sigaction: permit <
+ native-sigprocmask: permit <
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK (
+ > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe
+ > native-sendto: true then permit
+ > native-select: permit
+ > native-recvfrom: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK (
+ native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p
+ > native-exit: permit
diff --git a/usr.bin/sdiff/tests/d_flags_s.out b/usr.bin/sdiff/tests/d_flags_s.out
new file mode 100644
index 000000000000..8af11f3ff4b6
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_flags_s.out
@@ -0,0 +1,79 @@
+ > native-issetugid: permit
+ > native-mprotect: permit
+ > native-mmap: permit
+ > native-fsread: filename eq "/var/run/ld.so.hints" then pe
+ > native-fstat: permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-fsread: filename match "/usr/lib/libssl.so.*" then
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-read: permit
+ native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" t
+ native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*"
+ native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then p
+ native-fsread: filename match "/<non-existent filename>: | native-munmap: permit
+ native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit
+ native-fsread: filename eq "/etc/utmp" then permit <
+ native-fsread: filename eq "/home" then permit <
+ native-fsread: filename eq "$HOME" then permit <
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then per <
+ native-fsread: filename eq "$HOME/.lynxrc" then permit <
+ native-fsread: filename eq "$HOME/.mailcap" then permit <
+ native-fsread: filename eq "$HOME/.mime.types" then permi <
+ native-fsread: filename eq "$HOME/.terminfo" then permit <
+ native-fsread: filename eq "$HOME/.terminfo.db" then perm <
+ native-fsread: filename eq "/obj" then permit <
+ > native-fswrite: filename match "/tmp/lynx-*" then permit
+ > native-fsread: filename eq "$HOME" then permit
+ > native-fsread: filename eq "/etc/lynx.cfg" then permit
+ > native-fsread: filename eq "/" then permit
+ > native-fsread: filename eq "/usr/obj/bin/systrace/." then
+ > native-fsread: filename eq "/usr/obj/bin" then permit
+ > native-fcntl: permit
+ > native-getdirentries: permit
+ > native-lseek: permit
+ > native-fsread: filename eq "/usr/obj" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" then p <
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" t <
+ native-fsread: filename match "/usr/lib/libncurses.so.*" <
+ native-fsread: filename match "/usr/lib/libssl.so.*" then <
+ native-fsread: filename eq "/usr/obj" then permit | native-fsread: filename eq "/home" then permit
+ native-fsread: filename eq "/usr/obj/bin" then permit | native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then | native-fsread: filename eq "$HOME/.lynxrc" then permit
+ > native-fsread: filename match "/<non-existent filename>:
+ > native-fsread: filename eq "$HOME/.mailcap" then permit
+ > native-fsread: filename eq "$HOME/.mime.types" then permi
+ > native-sigaction: permit
+ > native-ioctl: permit
+ > native-fsread: filename eq "$HOME/.terminfo.db" then perm
+ > native-fsread: filename eq "$HOME/.terminfo" then permit
+ > native-pread: permit
+ > native-write: permit
+ > native-fsread: filename eq "$HOME/.lynx-keymaps" then per
+ native-fsread: filename eq "/var/run/ld.so.hints" then pe | native-fsread: filename eq "/etc/utmp" then permit
+ native-fstat: permit <
+ native-fswrite: filename match "/tmp/lynx-*" then permit <
+ native-getdirentries: permit <
+ native-getpid: permit <
+ native-gettimeofday: permit <
+ native-ioctl: permit <
+ native-issetugid: permit <
+ native-lseek: permit <
+ native-mmap: permit <
+ native-mprotect: prot eq "PROT_READ" then permit <
+ native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" <
+ native-munmap: permit <
+ native-nanosleep: permit <
+ native-pread: permit | native-nanosleep: permit
+ native-read: permit | native-gettimeofday: permit
+ native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit
+ native-select: permit <
+ native-sendto: true then permit <
+ native-sigaction: permit <
+ native-sigprocmask: permit <
+ > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe
+ > native-sendto: true then permit
+ > native-select: permit
+ > native-recvfrom: permit
+ native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p
+ > native-exit: permit
diff --git a/usr.bin/sdiff/tests/d_flags_w.out b/usr.bin/sdiff/tests/d_flags_w.out
new file mode 100644
index 000000000000..19ea79bf6112
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_flags_w.out
@@ -0,0 +1,102 @@
+Policy: /usr/bin/lynx, Emulation: native Policy: /usr/bin/lynx, Emulation: native
+ > native-issetugid: permit
+ > native-mprotect: permit
+ > native-mmap: permit
+ native-__sysctl: permit native-__sysctl: permit
+ > native-fsread: filename eq "/var/run/ld.so.hints" then pe
+ > native-fstat: permit
+ native-close: permit native-close: permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-fsread: filename match "/usr/lib/libssl.so.*" then
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-read: permit
+ native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" t
+ native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*"
+ native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then p
+ native-fsread: filename match "/<non-existent filename>: | native-munmap: permit
+ native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit
+ native-fsread: filename eq "/etc/malloc.conf" then permit native-fsread: filename eq "/etc/malloc.conf" then permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit
+ native-fsread: filename eq "/etc/utmp" then permit <
+ native-fsread: filename eq "/home" then permit <
+ native-fsread: filename eq "$HOME" then permit <
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then per <
+ native-fsread: filename eq "$HOME/.lynxrc" then permit <
+ native-fsread: filename eq "$HOME/.mailcap" then permit <
+ native-fsread: filename eq "$HOME/.mime.types" then permi <
+ native-fsread: filename eq "$HOME/.terminfo" then permit <
+ native-fsread: filename eq "$HOME/.terminfo.db" then perm <
+ native-fsread: filename eq "/obj" then permit <
+ native-fsread: filename eq "/tmp" then permit native-fsread: filename eq "/tmp" then permit
+ > native-fswrite: filename match "/tmp/lynx-*" then permit
+ native-fsread: filename match "/tmp/lynx-*/." then permit native-fsread: filename match "/tmp/lynx-*/." then permit
+ > native-fsread: filename eq "$HOME" then permit
+ > native-fsread: filename eq "/etc/lynx.cfg" then permit
+ > native-fsread: filename eq "/" then permit
+ > native-fsread: filename eq "/usr/obj/bin/systrace/." then
+ > native-fsread: filename eq "/usr/obj/bin" then permit
+ > native-fcntl: permit
+ > native-getdirentries: permit
+ > native-lseek: permit
+ > native-fsread: filename eq "/usr/obj" then permit
+ native-fsread: filename eq "/usr" then permit native-fsread: filename eq "/usr" then permit
+ native-fsread: filename eq "/usr/bin" then permit native-fsread: filename eq "/usr/bin" then permit
+ native-fsread: filename eq "/usr/games" then permit native-fsread: filename eq "/usr/games" then permit
+ native-fsread: filename eq "/usr/include" then permit native-fsread: filename eq "/usr/include" then permit
+ native-fsread: filename eq "/usr/lib" then permit native-fsread: filename eq "/usr/lib" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" then p <
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" t <
+ native-fsread: filename match "/usr/lib/libncurses.so.*" <
+ native-fsread: filename match "/usr/lib/libssl.so.*" then <
+ native-fsread: filename eq "/usr/libdata" then permit native-fsread: filename eq "/usr/libdata" then permit
+ native-fsread: filename eq "/usr/libexec" then permit native-fsread: filename eq "/usr/libexec" then permit
+ native-fsread: filename eq "/usr/lkm" then permit native-fsread: filename eq "/usr/lkm" then permit
+ native-fsread: filename eq "/usr/local" then permit native-fsread: filename eq "/usr/local" then permit
+ native-fsread: filename eq "/usr/mdec" then permit native-fsread: filename eq "/usr/mdec" then permit
+ native-fsread: filename eq "/usr/obj" then permit | native-fsread: filename eq "/home" then permit
+ native-fsread: filename eq "/usr/obj/bin" then permit | native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then | native-fsread: filename eq "$HOME/.lynxrc" then permit
+ > native-fsread: filename match "/<non-existent filename>:
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mailca native-fsread: filename eq "/usr/obj/bin/systrace/.mailca
+ > native-fsread: filename eq "$HOME/.mailcap" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t
+ > native-fsread: filename eq "$HOME/.mime.types" then permi
+ > native-sigaction: permit
+ > native-ioctl: permit
+ > native-fsread: filename eq "$HOME/.terminfo.db" then perm
+ > native-fsread: filename eq "$HOME/.terminfo" then permit
+ native-fsread: filename eq "/usr/share/misc/terminfo.db" native-fsread: filename eq "/usr/share/misc/terminfo.db"
+ > native-pread: permit
+ > native-write: permit
+ > native-fsread: filename eq "$HOME/.lynx-keymaps" then per
+ native-fsread: filename eq "/var/run/dev.db" then permit native-fsread: filename eq "/var/run/dev.db" then permit
+ native-fsread: filename eq "/var/run/ld.so.hints" then pe | native-fsread: filename eq "/etc/utmp" then permit
+ native-fstat: permit <
+ native-fswrite: filename match "/tmp/lynx-*" then permit <
+ native-getdirentries: permit <
+ native-getpid: permit <
+ native-gettimeofday: permit <
+ native-ioctl: permit <
+ native-issetugid: permit <
+ native-lseek: permit <
+ native-mmap: permit <
+ native-mprotect: prot eq "PROT_READ" then permit <
+ native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" <
+ native-munmap: permit <
+ native-nanosleep: permit <
+ native-poll: permit native-poll: permit
+ native-pread: permit | native-nanosleep: permit
+ native-read: permit | native-gettimeofday: permit
+ native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit
+ native-select: permit <
+ native-sendto: true then permit <
+ native-sigaction: permit <
+ native-sigprocmask: permit <
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK native-socket: sockdom eq "AF_INET" and socktype eq "SOCK
+ > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe
+ > native-sendto: true then permit
+ > native-select: permit
+ > native-recvfrom: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK native-socket: sockdom eq "AF_INET" and socktype eq "SOCK
+ native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p
+ > native-exit: permit
diff --git a/usr.bin/sdiff/tests/d_iflags_a1.out b/usr.bin/sdiff/tests/d_iflags_a1.out
new file mode 100644
index 000000000000..2a0f5328aeb2
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_iflags_a1.out
@@ -0,0 +1,100 @@
+Policy: /usr/bin/lynx, Emulation: native Policy: /usr/bin/lynx, Emulation: native
+ > native-issetugid: permit
+ > native-mprotect: permit
+ > native-mmap: permit
+ native-__sysctl: permit native-__sysctl: permit
+ > native-fsread: filename eq "/var/run/ld.so.hints" then pe
+ > native-fstat: permit
+ native-close: permit native-close: permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-fsread: filename match "/usr/lib/libssl.so.*" then
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-read: permit
+ native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" t
+ native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*"
+ native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then p
+ native-fsread: filename match "/<non-existent filename>: | native-munmap: permit
+ native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit
+ native-fsread: filename eq "/etc/malloc.conf" then permit native-fsread: filename eq "/etc/malloc.conf" then permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit
+ native-fsread: filename eq "/etc/utmp" then permit <
+ native-fsread: filename eq "/home" then permit <
+ native-fsread: filename eq "$HOME" then permit <
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then per <
+ native-fsread: filename eq "$HOME/.lynxrc" then permit <
+ native-fsread: filename eq "$HOME/.mailcap" then permit <
+ native-fsread: filename eq "$HOME/.mime.types" then permi <
+ native-fsread: filename eq "$HOME/.terminfo" then permit <
+ native-fsread: filename eq "$HOME/.terminfo.db" then perm <
+ native-fsread: filename eq "/obj" then permit <
+ native-fsread: filename eq "/tmp" then permit native-fsread: filename eq "/tmp" then permit
+ native-fsread: filename match "/tmp/lynx-*/." then permit native-fswrite: filename match "/tmp/lynx-*" then permit
+ ) native-fsread: filename match "/tmp/lynx-*/." then permit
+ > native-fsread: filename eq "$HOME" then permit
+ > native-fsread: filename eq "/etc/lynx.cfg" then permit
+ > native-fsread: filename eq "/" then permit
+ > native-fsread: filename eq "/usr/obj/bin/systrace/." then
+ > native-fsread: filename eq "/usr/obj/bin" then permit
+ > native-fcntl: permit
+ > native-getdirentries: permit
+ > native-lseek: permit
+ > native-fsread: filename eq "/usr/obj" then permit
+ native-fsread: filename eq "/usr" then permit native-fsread: filename eq "/usr" then permit
+ native-fsread: filename eq "/usr/bin" then permit native-fsread: filename eq "/usr/bin" then permit
+ native-fsread: filename eq "/usr/games" then permit native-fsread: filename eq "/usr/games" then permit
+ native-fsread: filename eq "/usr/include" then permit native-fsread: filename eq "/usr/include" then permit
+ native-fsread: filename eq "/usr/lib" then permit native-fsread: filename eq "/usr/lib" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" then p native-fsread: filename eq "/usr/libdata" then permit
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" t native-fsread: filename eq "/usr/libexec" then permit
+ native-fsread: filename match "/usr/lib/libncurses.so.*" native-fsread: filename eq "/usr/lkm" then permit
+ native-fsread: filename match "/usr/lib/libssl.so.*" then native-fsread: filename eq "/usr/local" then permit
+ native-fsread: filename eq "/usr/libdata" then permit native-fsread: filename eq "/usr/mdec" then permit
+ native-fsread: filename eq "/usr/libexec" then permit native-fsread: filename eq "/home" then permit
+ native-fsread: filename eq "/usr/lkm" then permit native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "/usr/local" then permit native-fsread: filename eq "$HOME/.lynxrc" then permit
+ native-fsread: filename eq "/usr/mdec" then permit native-fsread: filename match "/<non-existent filename>:
+ native-fsread: filename eq "/usr/obj" then permit native-fsread: filename eq "/usr/obj/bin/systrace/.mailca
+ native-fsread: filename eq "/usr/obj/bin" then permit native-fsread: filename eq "$HOME/.mailcap" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mailca (
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t (
+ > native-fsread: filename eq "$HOME/.mime.types" then permi
+ > native-sigaction: permit
+ > native-ioctl: permit
+ > native-fsread: filename eq "$HOME/.terminfo.db" then perm
+ > native-fsread: filename eq "$HOME/.terminfo" then permit
+ native-fsread: filename eq "/usr/share/misc/terminfo.db" native-fsread: filename eq "/usr/share/misc/terminfo.db"
+ > native-pread: permit
+ > native-write: permit
+ > native-fsread: filename eq "$HOME/.lynx-keymaps" then per
+ native-fsread: filename eq "/var/run/dev.db" then permit native-fsread: filename eq "/var/run/dev.db" then permit
+ native-fsread: filename eq "/var/run/ld.so.hints" then pe | native-fsread: filename eq "/etc/utmp" then permit
+ native-fstat: permit <
+ native-fswrite: filename match "/tmp/lynx-*" then permit <
+ native-getdirentries: permit <
+ native-getpid: permit <
+ native-gettimeofday: permit <
+ native-ioctl: permit <
+ native-issetugid: permit <
+ native-lseek: permit <
+ native-mmap: permit <
+ native-mprotect: prot eq "PROT_READ" then permit <
+ native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" <
+ native-munmap: permit <
+ native-nanosleep: permit <
+ native-poll: permit native-poll: permit
+ native-pread: permit | native-nanosleep: permit
+ native-read: permit | native-gettimeofday: permit
+ native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit
+ native-select: permit <
+ native-sendto: true then permit <
+ native-sigaction: permit <
+ native-sigprocmask: permit <
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK native-socket: sockdom eq "AF_INET" and socktype eq "SOCK
+ > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe
+ > native-sendto: true then permit
+ > native-select: permit
+ > native-recvfrom: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK native-socket: sockdom eq "AF_INET" and socktype eq "SOCK
+ native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p
+ > native-exit: permit
diff --git a/usr.bin/sdiff/tests/d_iflags_a2.out b/usr.bin/sdiff/tests/d_iflags_a2.out
new file mode 100644
index 000000000000..4e0d349b79e7
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_iflags_a2.out
@@ -0,0 +1,96 @@
+Policy: /usr/bin/lynx, Emulation: native Policy: /usr/bin/lynx, Emulation: native
+ native-issetugid: permit <
+ native-mprotect: permit <
+ native-mmap: permit <
+ native-__sysctl: permit native-__sysctl: permit
+ native-fsread: filename eq "/var/run/ld.so.hints" then pe <
+ native-fstat: permit <
+ native-close: permit native-close: permit
+ native-fsread: filename match "/usr/lib/libssl.so.*" then | native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe
+ native-read: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" t | native-exit: permit
+ native-fsread: filename match "/usr/lib/libncurses.so.*" | native-fcntl: cmd eq "F_SETFD" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" then p | native-fsread: filename eq "/" then permit
+ native-munmap: permit | native-fsread: filename match "/<non-existent filename>:
+ native-sigprocmask: permit | native-fsread: filename eq "/etc/lynx.cfg" then permit
+ native-fsread: filename eq "/etc/malloc.conf" then permit native-fsread: filename eq "/etc/malloc.conf" then permit
+ native-getpid: permit | native-fsread: filename eq "/etc/resolv.conf" then permit
+ > native-fsread: filename eq "/etc/utmp" then permit
+ > native-fsread: filename eq "/home" then permit
+ > native-fsread: filename eq "$HOME" then permit
+ > native-fsread: filename eq "$HOME/.lynx-keymaps" then per
+ > native-fsread: filename eq "$HOME/.lynxrc" then permit
+ > native-fsread: filename eq "$HOME/.mailcap" then permit
+ > native-fsread: filename eq "$HOME/.mime.types" then permi
+ > native-fsread: filename eq "$HOME/.terminfo" then permit
+ > native-fsread: filename eq "$HOME/.terminfo.db" then perm
+ > native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "/tmp" then permit native-fsread: filename eq "/tmp" then permit
+ native-fswrite: filename match "/tmp/lynx-*" then permit native-fsread: filename match "/tmp/lynx-*/." then permit
+ native-fsread: filename match "/tmp/lynx-*/." then permit (
+ native-fsread: filename eq "$HOME" then permit <
+ native-fsread: filename eq "/etc/lynx.cfg" then permit <
+ native-fsread: filename eq "/" then permit <
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then <
+ native-fsread: filename eq "/usr/obj/bin" then permit <
+ native-fcntl: permit <
+ native-getdirentries: permit <
+ native-lseek: permit <
+ native-fsread: filename eq "/usr/obj" then permit <
+ native-fsread: filename eq "/usr" then permit native-fsread: filename eq "/usr" then permit
+ native-fsread: filename eq "/usr/bin" then permit native-fsread: filename eq "/usr/bin" then permit
+ native-fsread: filename eq "/usr/games" then permit native-fsread: filename eq "/usr/games" then permit
+ native-fsread: filename eq "/usr/include" then permit native-fsread: filename eq "/usr/include" then permit
+ native-fsread: filename eq "/usr/lib" then permit native-fsread: filename eq "/usr/lib" then permit
+ native-fsread: filename eq "/usr/libdata" then permit native-fsread: filename match "/usr/lib/libc.so.*" then p
+ native-fsread: filename eq "/usr/libexec" then permit native-fsread: filename match "/usr/lib/libcrypto.so.*" t
+ native-fsread: filename eq "/usr/lkm" then permit native-fsread: filename match "/usr/lib/libncurses.so.*"
+ native-fsread: filename eq "/usr/local" then permit native-fsread: filename match "/usr/lib/libssl.so.*" then
+ native-fsread: filename eq "/usr/mdec" then permit native-fsread: filename eq "/usr/libdata" then permit
+ native-fsread: filename eq "/home" then permit native-fsread: filename eq "/usr/libexec" then permit
+ native-fsread: filename eq "/obj" then permit native-fsread: filename eq "/usr/lkm" then permit
+ native-fsread: filename eq "$HOME/.lynxrc" then permit native-fsread: filename eq "/usr/local" then permit
+ native-fsread: filename match "/<non-existent filename>: native-fsread: filename eq "/usr/mdec" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mailca native-fsread: filename eq "/usr/obj" then permit
+ native-fsread: filename eq "$HOME/.mailcap" then permit native-fsread: filename eq "/usr/obj/bin" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t native-fsread: filename eq "/usr/obj/bin/systrace/." then
+ ) native-fsread: filename eq "/usr/obj/bin/systrace/.mailca
+ ) native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t
+ native-fsread: filename eq "$HOME/.mime.types" then permi <
+ native-sigaction: permit <
+ native-ioctl: permit <
+ native-fsread: filename eq "$HOME/.terminfo.db" then perm <
+ native-fsread: filename eq "$HOME/.terminfo" then permit <
+ native-fsread: filename eq "/usr/share/misc/terminfo.db" native-fsread: filename eq "/usr/share/misc/terminfo.db"
+ native-pread: permit <
+ native-write: permit <
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then per <
+ native-fsread: filename eq "/var/run/dev.db" then permit native-fsread: filename eq "/var/run/dev.db" then permit
+ native-fsread: filename eq "/etc/utmp" then permit | native-fsread: filename eq "/var/run/ld.so.hints" then pe
+ native-poll: permit | native-fstat: permit
+ native-nanosleep: permit | native-fswrite: filename match "/tmp/lynx-*" then permit
+ > native-getdirentries: permit
+ > native-getpid: permit
+ native-gettimeofday: permit native-gettimeofday: permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit | native-ioctl: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK | native-issetugid: permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-lseek: permit
+ native-sendto: true then permit | native-mmap: permit
+ native-select: permit | native-mprotect: prot eq "PROT_READ" then permit
+ > native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi
+ > native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm
+ > native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC"
+ > native-munmap: permit
+ > native-nanosleep: permit
+ > native-poll: permit
+ > native-pread: permit
+ > native-read: permit
+ native-recvfrom: permit native-recvfrom: permit
+ > native-select: permit
+ > native-sendto: true then permit
+ > native-sigaction: permit
+ > native-sigprocmask: permit
+ > native-socket: sockdom eq "AF_INET" and socktype eq "SOCK
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK native-socket: sockdom eq "AF_INET" and socktype eq "SOCK
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-write: permit
+ native-exit: permit <
diff --git a/usr.bin/sdiff/tests/d_iflags_b1.out b/usr.bin/sdiff/tests/d_iflags_b1.out
new file mode 100644
index 000000000000..3e548b693d08
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_iflags_b1.out
@@ -0,0 +1,69 @@
+ > native-issetugid: permit
+ > native-mprotect: permit
+ > native-mmap: permit
+ > native-fsread: filename eq "/var/run/ld.so.hints" then pe
+ > native-fstat: permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-fsread: filename match "/usr/lib/libssl.so.*" then
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-read: permit
+ native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" t
+ native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*"
+ native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then p
+ native-fsread: filename match "/<non-existent filename>: | native-munmap: permit
+ native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit
+ native-fsread: filename eq "/etc/utmp" then permit <
+ native-fsread: filename eq "/home" then permit <
+ native-fsread: filename eq "$HOME" then permit <
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then per <
+ native-fsread: filename eq "$HOME/.lynxrc" then permit <
+ native-fsread: filename eq "$HOME/.mailcap" then permit <
+ native-fsread: filename eq "$HOME/.mime.types" then permi <
+ native-fsread: filename eq "$HOME/.terminfo" then permit <
+ native-fsread: filename eq "$HOME/.terminfo.db" then perm <
+ native-fsread: filename eq "/obj" then permit <
+ > native-fsread: filename eq "$HOME" then permit
+ > native-fsread: filename eq "/etc/lynx.cfg" then permit
+ > native-fsread: filename eq "/" then permit
+ > native-fsread: filename eq "/usr/obj/bin/systrace/." then
+ > native-fsread: filename eq "/usr/obj/bin" then permit
+ > native-fcntl: permit
+ > native-getdirentries: permit
+ > native-lseek: permit
+ > native-fsread: filename eq "/usr/obj" then permit
+ > native-fsread: filename eq "$HOME/.mime.types" then permi
+ > native-sigaction: permit
+ > native-ioctl: permit
+ > native-fsread: filename eq "$HOME/.terminfo.db" then perm
+ > native-fsread: filename eq "$HOME/.terminfo" then permit
+ > native-pread: permit
+ > native-write: permit
+ > native-fsread: filename eq "$HOME/.lynx-keymaps" then per
+ native-fsread: filename eq "/var/run/ld.so.hints" then pe | native-fsread: filename eq "/etc/utmp" then permit
+ native-fstat: permit <
+ native-fswrite: filename match "/tmp/lynx-*" then permit <
+ native-getdirentries: permit <
+ native-getpid: permit <
+ native-gettimeofday: permit <
+ native-ioctl: permit <
+ native-issetugid: permit <
+ native-lseek: permit <
+ native-mmap: permit <
+ native-mprotect: prot eq "PROT_READ" then permit <
+ native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" <
+ native-munmap: permit <
+ native-nanosleep: permit <
+ native-pread: permit | native-nanosleep: permit
+ native-read: permit | native-gettimeofday: permit
+ native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit
+ native-select: permit <
+ native-sendto: true then permit <
+ native-sigaction: permit <
+ native-sigprocmask: permit <
+ > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe
+ > native-sendto: true then permit
+ > native-select: permit
+ > native-recvfrom: permit
+ native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p
+ > native-exit: permit
diff --git a/usr.bin/sdiff/tests/d_iflags_b2.out b/usr.bin/sdiff/tests/d_iflags_b2.out
new file mode 100644
index 000000000000..4504c36ec035
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_iflags_b2.out
@@ -0,0 +1,65 @@
+ native-issetugid: permit <
+ native-mprotect: permit <
+ native-mmap: permit <
+ native-fsread: filename eq "/var/run/ld.so.hints" then pe <
+ native-fstat: permit <
+ native-fsread: filename match "/usr/lib/libssl.so.*" then | native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe
+ native-read: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" t | native-exit: permit
+ native-fsread: filename match "/usr/lib/libncurses.so.*" | native-fcntl: cmd eq "F_SETFD" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" then p | native-fsread: filename eq "/" then permit
+ native-munmap: permit | native-fsread: filename match "/<non-existent filename>:
+ native-sigprocmask: permit | native-fsread: filename eq "/etc/lynx.cfg" then permit
+ native-getpid: permit | native-fsread: filename eq "/etc/resolv.conf" then permit
+ > native-fsread: filename eq "/etc/utmp" then permit
+ > native-fsread: filename eq "/home" then permit
+ > native-fsread: filename eq "$HOME" then permit
+ > native-fsread: filename eq "$HOME/.lynx-keymaps" then per
+ > native-fsread: filename eq "$HOME/.lynxrc" then permit
+ > native-fsread: filename eq "$HOME/.mailcap" then permit
+ > native-fsread: filename eq "$HOME/.mime.types" then permi
+ > native-fsread: filename eq "$HOME/.terminfo" then permit
+ > native-fsread: filename eq "$HOME/.terminfo.db" then perm
+ > native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "$HOME" then permit <
+ native-fsread: filename eq "/etc/lynx.cfg" then permit <
+ native-fsread: filename eq "/" then permit <
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then <
+ native-fsread: filename eq "/usr/obj/bin" then permit <
+ native-fcntl: permit <
+ native-getdirentries: permit <
+ native-lseek: permit <
+ native-fsread: filename eq "/usr/obj" then permit <
+ native-fsread: filename eq "$HOME/.mime.types" then permi <
+ native-sigaction: permit <
+ native-ioctl: permit <
+ native-fsread: filename eq "$HOME/.terminfo.db" then perm <
+ native-fsread: filename eq "$HOME/.terminfo" then permit <
+ native-pread: permit <
+ native-write: permit <
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then per <
+ native-fsread: filename eq "/etc/utmp" then permit | native-fsread: filename eq "/var/run/ld.so.hints" then pe
+ native-poll: permit | native-fstat: permit
+ native-nanosleep: permit | native-fswrite: filename match "/tmp/lynx-*" then permit
+ > native-getdirentries: permit
+ > native-getpid: permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit | native-ioctl: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK | native-issetugid: permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-lseek: permit
+ native-sendto: true then permit | native-mmap: permit
+ native-select: permit | native-mprotect: prot eq "PROT_READ" then permit
+ > native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi
+ > native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm
+ > native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC"
+ > native-munmap: permit
+ > native-nanosleep: permit
+ > native-poll: permit
+ > native-pread: permit
+ > native-read: permit
+ > native-select: permit
+ > native-sendto: true then permit
+ > native-sigaction: permit
+ > native-sigprocmask: permit
+ > native-socket: sockdom eq "AF_INET" and socktype eq "SOCK
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-write: permit
+ native-exit: permit <
diff --git a/usr.bin/sdiff/tests/d_iflags_c1.out b/usr.bin/sdiff/tests/d_iflags_c1.out
new file mode 100644
index 000000000000..e9ac88e54ae1
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_iflags_c1.out
@@ -0,0 +1,99 @@
+Policy: /usr/bin/lynx, Emulation: native (
+ > native-issetugid: permit
+ > native-mprotect: permit
+ > native-mmap: permit
+ native-__sysctl: permit (
+ > native-fsread: filename eq "/var/run/ld.so.hints" then pe
+ > native-fstat: permit
+ native-close: permit (
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-fsread: filename match "/usr/lib/libssl.so.*" then
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-read: permit
+ native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" t
+ native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*"
+ native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then p
+ native-fsread: filename match "/<non-existent filename>: | native-munmap: permit
+ native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit
+ native-fsread: filename eq "/etc/malloc.conf" then permit (
+ native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit
+ native-fsread: filename eq "/etc/utmp" then permit <
+ native-fsread: filename eq "/home" then permit <
+ native-fsread: filename eq "$HOME" then permit <
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then per <
+ native-fsread: filename eq "$HOME/.lynxrc" then permit <
+ native-fsread: filename eq "$HOME/.mailcap" then permit <
+ native-fsread: filename eq "$HOME/.mime.types" then permi <
+ native-fsread: filename eq "$HOME/.terminfo" then permit <
+ native-fsread: filename eq "$HOME/.terminfo.db" then perm <
+ native-fsread: filename eq "/obj" then permit <
+ native-fsread: filename eq "/tmp" then permit (
+ native-fsread: filename match "/tmp/lynx-*/." then permit (
+ > native-fsread: filename eq "$HOME" then permit
+ > native-fsread: filename eq "/etc/lynx.cfg" then permit
+ > native-fsread: filename eq "/" then permit
+ > native-fsread: filename eq "/usr/obj/bin/systrace/." then
+ > native-fsread: filename eq "/usr/obj/bin" then permit
+ > native-fcntl: permit
+ > native-getdirentries: permit
+ > native-lseek: permit
+ > native-fsread: filename eq "/usr/obj" then permit
+ native-fsread: filename eq "/usr" then permit (
+ native-fsread: filename eq "/usr/bin" then permit (
+ native-fsread: filename eq "/usr/games" then permit (
+ native-fsread: filename eq "/usr/include" then permit (
+ native-fsread: filename eq "/usr/lib" then permit (
+ native-fsread: filename match "/usr/lib/libc.so.*" then p (
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" t (
+ native-fsread: filename match "/usr/lib/libncurses.so.*" (
+ native-fsread: filename match "/usr/lib/libssl.so.*" then (
+ native-fsread: filename eq "/usr/libdata" then permit (
+ native-fsread: filename eq "/usr/libexec" then permit (
+ native-fsread: filename eq "/usr/lkm" then permit (
+ native-fsread: filename eq "/usr/local" then permit (
+ native-fsread: filename eq "/usr/mdec" then permit (
+ native-fsread: filename eq "/usr/obj" then permit (
+ native-fsread: filename eq "/usr/obj/bin" then permit (
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then (
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mailca (
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t (
+ > native-fsread: filename eq "$HOME/.mime.types" then permi
+ > native-sigaction: permit
+ > native-ioctl: permit
+ > native-fsread: filename eq "$HOME/.terminfo.db" then perm
+ > native-fsread: filename eq "$HOME/.terminfo" then permit
+ native-fsread: filename eq "/usr/share/misc/terminfo.db" (
+ > native-pread: permit
+ > native-write: permit
+ > native-fsread: filename eq "$HOME/.lynx-keymaps" then per
+ native-fsread: filename eq "/var/run/dev.db" then permit (
+ native-fsread: filename eq "/var/run/ld.so.hints" then pe | native-fsread: filename eq "/etc/utmp" then permit
+ native-fstat: permit <
+ native-fswrite: filename match "/tmp/lynx-*" then permit <
+ native-getdirentries: permit <
+ native-getpid: permit <
+ native-gettimeofday: permit <
+ native-ioctl: permit <
+ native-issetugid: permit <
+ native-lseek: permit <
+ native-mmap: permit <
+ native-mprotect: prot eq "PROT_READ" then permit <
+ native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" <
+ native-munmap: permit <
+ native-nanosleep: permit <
+ native-poll: permit (
+ native-pread: permit | native-nanosleep: permit
+ native-read: permit | native-gettimeofday: permit
+ native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit
+ native-select: permit <
+ native-sendto: true then permit <
+ native-sigaction: permit <
+ native-sigprocmask: permit <
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK (
+ > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe
+ > native-sendto: true then permit
+ > native-select: permit
+ > native-recvfrom: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK (
+ native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p
+ > native-exit: permit
diff --git a/usr.bin/sdiff/tests/d_iflags_c2.out b/usr.bin/sdiff/tests/d_iflags_c2.out
new file mode 100644
index 000000000000..fe7af0ebee54
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_iflags_c2.out
@@ -0,0 +1,94 @@
+Policy: /usr/bin/lynx, Emulation: native (
+ native-issetugid: permit <
+ native-mprotect: permit <
+ native-mmap: permit <
+ native-__sysctl: permit (
+ native-fsread: filename eq "/var/run/ld.so.hints" then pe <
+ native-fstat: permit <
+ native-close: permit (
+ native-fsread: filename match "/usr/lib/libssl.so.*" then | native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe
+ native-read: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" t | native-exit: permit
+ native-fsread: filename match "/usr/lib/libncurses.so.*" | native-fcntl: cmd eq "F_SETFD" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" then p | native-fsread: filename eq "/" then permit
+ native-munmap: permit | native-fsread: filename match "/<non-existent filename>:
+ native-sigprocmask: permit | native-fsread: filename eq "/etc/lynx.cfg" then permit
+ native-fsread: filename eq "/etc/malloc.conf" then permit (
+ native-getpid: permit | native-fsread: filename eq "/etc/resolv.conf" then permit
+ > native-fsread: filename eq "/etc/utmp" then permit
+ > native-fsread: filename eq "/home" then permit
+ > native-fsread: filename eq "$HOME" then permit
+ > native-fsread: filename eq "$HOME/.lynx-keymaps" then per
+ > native-fsread: filename eq "$HOME/.lynxrc" then permit
+ > native-fsread: filename eq "$HOME/.mailcap" then permit
+ > native-fsread: filename eq "$HOME/.mime.types" then permi
+ > native-fsread: filename eq "$HOME/.terminfo" then permit
+ > native-fsread: filename eq "$HOME/.terminfo.db" then perm
+ > native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "/tmp" then permit (
+ native-fswrite: filename match "/tmp/lynx-*" then permit (
+ native-fsread: filename match "/tmp/lynx-*/." then permit (
+ native-fsread: filename eq "$HOME" then permit <
+ native-fsread: filename eq "/etc/lynx.cfg" then permit <
+ native-fsread: filename eq "/" then permit <
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then <
+ native-fsread: filename eq "/usr/obj/bin" then permit <
+ native-fcntl: permit <
+ native-getdirentries: permit <
+ native-lseek: permit <
+ native-fsread: filename eq "/usr/obj" then permit <
+ native-fsread: filename eq "/usr" then permit (
+ native-fsread: filename eq "/usr/bin" then permit (
+ native-fsread: filename eq "/usr/games" then permit (
+ native-fsread: filename eq "/usr/include" then permit (
+ native-fsread: filename eq "/usr/lib" then permit (
+ native-fsread: filename eq "/usr/libdata" then permit (
+ native-fsread: filename eq "/usr/libexec" then permit (
+ native-fsread: filename eq "/usr/lkm" then permit (
+ native-fsread: filename eq "/usr/local" then permit (
+ native-fsread: filename eq "/usr/mdec" then permit (
+ native-fsread: filename eq "/home" then permit (
+ native-fsread: filename eq "/obj" then permit (
+ native-fsread: filename eq "$HOME/.lynxrc" then permit (
+ native-fsread: filename match "/<non-existent filename>: (
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mailca (
+ native-fsread: filename eq "$HOME/.mailcap" then permit (
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t (
+ native-fsread: filename eq "$HOME/.mime.types" then permi <
+ native-sigaction: permit <
+ native-ioctl: permit <
+ native-fsread: filename eq "$HOME/.terminfo.db" then perm <
+ native-fsread: filename eq "$HOME/.terminfo" then permit <
+ native-fsread: filename eq "/usr/share/misc/terminfo.db" (
+ native-pread: permit <
+ native-write: permit <
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then per <
+ native-fsread: filename eq "/var/run/dev.db" then permit (
+ native-fsread: filename eq "/etc/utmp" then permit | native-fsread: filename eq "/var/run/ld.so.hints" then pe
+ native-poll: permit | native-fstat: permit
+ native-nanosleep: permit | native-fswrite: filename match "/tmp/lynx-*" then permit
+ > native-getdirentries: permit
+ > native-getpid: permit
+ native-gettimeofday: permit (
+ native-fsread: filename eq "/etc/resolv.conf" then permit | native-ioctl: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK | native-issetugid: permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-lseek: permit
+ native-sendto: true then permit | native-mmap: permit
+ native-select: permit | native-mprotect: prot eq "PROT_READ" then permit
+ > native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi
+ > native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm
+ > native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC"
+ > native-munmap: permit
+ > native-nanosleep: permit
+ > native-poll: permit
+ > native-pread: permit
+ > native-read: permit
+ native-recvfrom: permit (
+ > native-select: permit
+ > native-sendto: true then permit
+ > native-sigaction: permit
+ > native-sigprocmask: permit
+ > native-socket: sockdom eq "AF_INET" and socktype eq "SOCK
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK (
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-write: permit
+ native-exit: permit <
diff --git a/usr.bin/sdiff/tests/d_iflags_d1.out b/usr.bin/sdiff/tests/d_iflags_d1.out
new file mode 100644
index 000000000000..3e548b693d08
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_iflags_d1.out
@@ -0,0 +1,69 @@
+ > native-issetugid: permit
+ > native-mprotect: permit
+ > native-mmap: permit
+ > native-fsread: filename eq "/var/run/ld.so.hints" then pe
+ > native-fstat: permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-fsread: filename match "/usr/lib/libssl.so.*" then
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-read: permit
+ native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" t
+ native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*"
+ native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then p
+ native-fsread: filename match "/<non-existent filename>: | native-munmap: permit
+ native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit
+ native-fsread: filename eq "/etc/utmp" then permit <
+ native-fsread: filename eq "/home" then permit <
+ native-fsread: filename eq "$HOME" then permit <
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then per <
+ native-fsread: filename eq "$HOME/.lynxrc" then permit <
+ native-fsread: filename eq "$HOME/.mailcap" then permit <
+ native-fsread: filename eq "$HOME/.mime.types" then permi <
+ native-fsread: filename eq "$HOME/.terminfo" then permit <
+ native-fsread: filename eq "$HOME/.terminfo.db" then perm <
+ native-fsread: filename eq "/obj" then permit <
+ > native-fsread: filename eq "$HOME" then permit
+ > native-fsread: filename eq "/etc/lynx.cfg" then permit
+ > native-fsread: filename eq "/" then permit
+ > native-fsread: filename eq "/usr/obj/bin/systrace/." then
+ > native-fsread: filename eq "/usr/obj/bin" then permit
+ > native-fcntl: permit
+ > native-getdirentries: permit
+ > native-lseek: permit
+ > native-fsread: filename eq "/usr/obj" then permit
+ > native-fsread: filename eq "$HOME/.mime.types" then permi
+ > native-sigaction: permit
+ > native-ioctl: permit
+ > native-fsread: filename eq "$HOME/.terminfo.db" then perm
+ > native-fsread: filename eq "$HOME/.terminfo" then permit
+ > native-pread: permit
+ > native-write: permit
+ > native-fsread: filename eq "$HOME/.lynx-keymaps" then per
+ native-fsread: filename eq "/var/run/ld.so.hints" then pe | native-fsread: filename eq "/etc/utmp" then permit
+ native-fstat: permit <
+ native-fswrite: filename match "/tmp/lynx-*" then permit <
+ native-getdirentries: permit <
+ native-getpid: permit <
+ native-gettimeofday: permit <
+ native-ioctl: permit <
+ native-issetugid: permit <
+ native-lseek: permit <
+ native-mmap: permit <
+ native-mprotect: prot eq "PROT_READ" then permit <
+ native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" <
+ native-munmap: permit <
+ native-nanosleep: permit <
+ native-pread: permit | native-nanosleep: permit
+ native-read: permit | native-gettimeofday: permit
+ native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit
+ native-select: permit <
+ native-sendto: true then permit <
+ native-sigaction: permit <
+ native-sigprocmask: permit <
+ > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe
+ > native-sendto: true then permit
+ > native-select: permit
+ > native-recvfrom: permit
+ native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p
+ > native-exit: permit
diff --git a/usr.bin/sdiff/tests/d_iflags_d2.out b/usr.bin/sdiff/tests/d_iflags_d2.out
new file mode 100644
index 000000000000..4504c36ec035
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_iflags_d2.out
@@ -0,0 +1,65 @@
+ native-issetugid: permit <
+ native-mprotect: permit <
+ native-mmap: permit <
+ native-fsread: filename eq "/var/run/ld.so.hints" then pe <
+ native-fstat: permit <
+ native-fsread: filename match "/usr/lib/libssl.so.*" then | native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe
+ native-read: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" t | native-exit: permit
+ native-fsread: filename match "/usr/lib/libncurses.so.*" | native-fcntl: cmd eq "F_SETFD" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" then p | native-fsread: filename eq "/" then permit
+ native-munmap: permit | native-fsread: filename match "/<non-existent filename>:
+ native-sigprocmask: permit | native-fsread: filename eq "/etc/lynx.cfg" then permit
+ native-getpid: permit | native-fsread: filename eq "/etc/resolv.conf" then permit
+ > native-fsread: filename eq "/etc/utmp" then permit
+ > native-fsread: filename eq "/home" then permit
+ > native-fsread: filename eq "$HOME" then permit
+ > native-fsread: filename eq "$HOME/.lynx-keymaps" then per
+ > native-fsread: filename eq "$HOME/.lynxrc" then permit
+ > native-fsread: filename eq "$HOME/.mailcap" then permit
+ > native-fsread: filename eq "$HOME/.mime.types" then permi
+ > native-fsread: filename eq "$HOME/.terminfo" then permit
+ > native-fsread: filename eq "$HOME/.terminfo.db" then perm
+ > native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "$HOME" then permit <
+ native-fsread: filename eq "/etc/lynx.cfg" then permit <
+ native-fsread: filename eq "/" then permit <
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then <
+ native-fsread: filename eq "/usr/obj/bin" then permit <
+ native-fcntl: permit <
+ native-getdirentries: permit <
+ native-lseek: permit <
+ native-fsread: filename eq "/usr/obj" then permit <
+ native-fsread: filename eq "$HOME/.mime.types" then permi <
+ native-sigaction: permit <
+ native-ioctl: permit <
+ native-fsread: filename eq "$HOME/.terminfo.db" then perm <
+ native-fsread: filename eq "$HOME/.terminfo" then permit <
+ native-pread: permit <
+ native-write: permit <
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then per <
+ native-fsread: filename eq "/etc/utmp" then permit | native-fsread: filename eq "/var/run/ld.so.hints" then pe
+ native-poll: permit | native-fstat: permit
+ native-nanosleep: permit | native-fswrite: filename match "/tmp/lynx-*" then permit
+ > native-getdirentries: permit
+ > native-getpid: permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit | native-ioctl: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK | native-issetugid: permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-lseek: permit
+ native-sendto: true then permit | native-mmap: permit
+ native-select: permit | native-mprotect: prot eq "PROT_READ" then permit
+ > native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi
+ > native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm
+ > native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC"
+ > native-munmap: permit
+ > native-nanosleep: permit
+ > native-poll: permit
+ > native-pread: permit
+ > native-read: permit
+ > native-select: permit
+ > native-sendto: true then permit
+ > native-sigaction: permit
+ > native-sigprocmask: permit
+ > native-socket: sockdom eq "AF_INET" and socktype eq "SOCK
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-write: permit
+ native-exit: permit <
diff --git a/usr.bin/sdiff/tests/d_input1 b/usr.bin/sdiff/tests/d_input1
new file mode 100644
index 000000000000..686e8ea22774
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_input1
@@ -0,0 +1,72 @@
+Policy: /usr/bin/lynx, Emulation: native
+ native-__sysctl: permit
+ native-close: permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then permit
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then permit
+ native-exit: permit
+ native-fcntl: cmd eq "F_SETFD" then permit
+ native-fsread: filename eq "/" then permit
+ native-fsread: filename match "/<non-existent filename>: *" then permit
+ native-fsread: filename eq "/etc/lynx.cfg" then permit
+ native-fsread: filename eq "/etc/malloc.conf" then permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit
+ native-fsread: filename eq "/etc/utmp" then permit
+ native-fsread: filename eq "/home" then permit
+ native-fsread: filename eq "$HOME" then permit
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then permit
+ native-fsread: filename eq "$HOME/.lynxrc" then permit
+ native-fsread: filename eq "$HOME/.mailcap" then permit
+ native-fsread: filename eq "$HOME/.mime.types" then permit
+ native-fsread: filename eq "$HOME/.terminfo" then permit
+ native-fsread: filename eq "$HOME/.terminfo.db" then permit
+ native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "/tmp" then permit
+ native-fsread: filename match "/tmp/lynx-*/." then permit
+ native-fsread: filename eq "/usr" then permit
+ native-fsread: filename eq "/usr/bin" then permit
+ native-fsread: filename eq "/usr/games" then permit
+ native-fsread: filename eq "/usr/include" then permit
+ native-fsread: filename eq "/usr/lib" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" then permit
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" then permit
+ native-fsread: filename match "/usr/lib/libncurses.so.*" then permit
+ native-fsread: filename match "/usr/lib/libssl.so.*" then permit
+ native-fsread: filename eq "/usr/libdata" then permit
+ native-fsread: filename eq "/usr/libexec" then permit
+ native-fsread: filename eq "/usr/lkm" then permit
+ native-fsread: filename eq "/usr/local" then permit
+ native-fsread: filename eq "/usr/mdec" then permit
+ native-fsread: filename eq "/usr/obj" then permit
+ native-fsread: filename eq "/usr/obj/bin" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mailcap" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mime.types" then permit
+ native-fsread: filename eq "/usr/share/misc/terminfo.db" then permit
+ native-fsread: filename eq "/var/run/dev.db" then permit
+ native-fsread: filename eq "/var/run/ld.so.hints" then permit
+ native-fstat: permit
+ native-fswrite: filename match "/tmp/lynx-*" then permit
+ native-getdirentries: permit
+ native-getpid: permit
+ native-gettimeofday: permit
+ native-ioctl: permit
+ native-issetugid: permit
+ native-lseek: permit
+ native-mmap: permit
+ native-mprotect: prot eq "PROT_READ" then permit
+ native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permit
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE" then permit
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" then permit
+ native-munmap: permit
+ native-nanosleep: permit
+ native-poll: permit
+ native-pread: permit
+ native-read: permit
+ native-recvfrom: permit
+ native-select: permit
+ native-sendto: true then permit
+ native-sigaction: permit
+ native-sigprocmask: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_DGRAM" then permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_STREAM" then permit
+ native-write: permit
diff --git a/usr.bin/sdiff/tests/d_input2 b/usr.bin/sdiff/tests/d_input2
new file mode 100644
index 000000000000..70e1b57f5fbf
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_input2
@@ -0,0 +1,69 @@
+Policy: /usr/bin/lynx, Emulation: native
+ native-issetugid: permit
+ native-mprotect: permit
+ native-mmap: permit
+ native-__sysctl: permit
+ native-fsread: filename eq "/var/run/ld.so.hints" then permit
+ native-fstat: permit
+ native-close: permit
+ native-fsread: filename match "/usr/lib/libssl.so.*" then permit
+ native-read: permit
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" then permit
+ native-fsread: filename match "/usr/lib/libncurses.so.*" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" then permit
+ native-munmap: permit
+ native-sigprocmask: permit
+ native-fsread: filename eq "/etc/malloc.conf" then permit
+ native-getpid: permit
+ native-fsread: filename eq "/tmp" then permit
+ native-fswrite: filename match "/tmp/lynx-*" then permit
+ native-fsread: filename match "/tmp/lynx-*/." then permit
+ native-fsread: filename eq "$HOME" then permit
+ native-fsread: filename eq "/etc/lynx.cfg" then permit
+ native-fsread: filename eq "/" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then permit
+ native-fsread: filename eq "/usr/obj/bin" then permit
+ native-fcntl: permit
+ native-getdirentries: permit
+ native-lseek: permit
+ native-fsread: filename eq "/usr/obj" then permit
+ native-fsread: filename eq "/usr" then permit
+ native-fsread: filename eq "/usr/bin" then permit
+ native-fsread: filename eq "/usr/games" then permit
+ native-fsread: filename eq "/usr/include" then permit
+ native-fsread: filename eq "/usr/lib" then permit
+ native-fsread: filename eq "/usr/libdata" then permit
+ native-fsread: filename eq "/usr/libexec" then permit
+ native-fsread: filename eq "/usr/lkm" then permit
+ native-fsread: filename eq "/usr/local" then permit
+ native-fsread: filename eq "/usr/mdec" then permit
+ native-fsread: filename eq "/home" then permit
+ native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "$HOME/.lynxrc" then permit
+ native-fsread: filename match "/<non-existent filename>: *" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mailcap" then permit
+ native-fsread: filename eq "$HOME/.mailcap" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mime.types" then permit
+ native-fsread: filename eq "$HOME/.mime.types" then permit
+ native-sigaction: permit
+ native-ioctl: permit
+ native-fsread: filename eq "$HOME/.terminfo.db" then permit
+ native-fsread: filename eq "$HOME/.terminfo" then permit
+ native-fsread: filename eq "/usr/share/misc/terminfo.db" then permit
+ native-pread: permit
+ native-write: permit
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then permit
+ native-fsread: filename eq "/var/run/dev.db" then permit
+ native-fsread: filename eq "/etc/utmp" then permit
+ native-poll: permit
+ native-nanosleep: permit
+ native-gettimeofday: permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_DGRAM" then permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then permit
+ native-sendto: true then permit
+ native-select: permit
+ native-recvfrom: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_STREAM" then permit
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then permit
+ native-exit: permit
diff --git a/usr.bin/sdiff/tests/d_oneline.in b/usr.bin/sdiff/tests/d_oneline.in
new file mode 100644
index 000000000000..acbe86c7c895
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_oneline.in
@@ -0,0 +1 @@
+abcd
diff --git a/usr.bin/sdiff/tests/d_oneline_a.out b/usr.bin/sdiff/tests/d_oneline_a.out
new file mode 100644
index 000000000000..18f7c6bd02cb
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_oneline_a.out
@@ -0,0 +1 @@
+ > abcd
diff --git a/usr.bin/sdiff/tests/d_oneline_b.out b/usr.bin/sdiff/tests/d_oneline_b.out
new file mode 100644
index 000000000000..04cad47ce037
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_oneline_b.out
@@ -0,0 +1 @@
+abcd <
diff --git a/usr.bin/sdiff/tests/d_same.out b/usr.bin/sdiff/tests/d_same.out
new file mode 100644
index 000000000000..f929fcf1915b
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_same.out
@@ -0,0 +1,72 @@
+Policy: /usr/bin/lynx, Emulation: native Policy: /usr/bin/lynx, Emulation: native
+ native-__sysctl: permit native-__sysctl: permit
+ native-close: permit native-close: permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then p native-connect: sockaddr match "inet-\\\[*\\\]:80" then p
+ native-exit: permit native-exit: permit
+ native-fcntl: cmd eq "F_SETFD" then permit native-fcntl: cmd eq "F_SETFD" then permit
+ native-fsread: filename eq "/" then permit native-fsread: filename eq "/" then permit
+ native-fsread: filename match "/<non-existent filename>: native-fsread: filename match "/<non-existent filename>:
+ native-fsread: filename eq "/etc/lynx.cfg" then permit native-fsread: filename eq "/etc/lynx.cfg" then permit
+ native-fsread: filename eq "/etc/malloc.conf" then permit native-fsread: filename eq "/etc/malloc.conf" then permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit native-fsread: filename eq "/etc/resolv.conf" then permit
+ native-fsread: filename eq "/etc/utmp" then permit native-fsread: filename eq "/etc/utmp" then permit
+ native-fsread: filename eq "/home" then permit native-fsread: filename eq "/home" then permit
+ native-fsread: filename eq "$HOME" then permit native-fsread: filename eq "$HOME" then permit
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then per native-fsread: filename eq "$HOME/.lynx-keymaps" then per
+ native-fsread: filename eq "$HOME/.lynxrc" then permit native-fsread: filename eq "$HOME/.lynxrc" then permit
+ native-fsread: filename eq "$HOME/.mailcap" then permit native-fsread: filename eq "$HOME/.mailcap" then permit
+ native-fsread: filename eq "$HOME/.mime.types" then permi native-fsread: filename eq "$HOME/.mime.types" then permi
+ native-fsread: filename eq "$HOME/.terminfo" then permit native-fsread: filename eq "$HOME/.terminfo" then permit
+ native-fsread: filename eq "$HOME/.terminfo.db" then perm native-fsread: filename eq "$HOME/.terminfo.db" then perm
+ native-fsread: filename eq "/obj" then permit native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "/tmp" then permit native-fsread: filename eq "/tmp" then permit
+ native-fsread: filename match "/tmp/lynx-*/." then permit native-fsread: filename match "/tmp/lynx-*/." then permit
+ native-fsread: filename eq "/usr" then permit native-fsread: filename eq "/usr" then permit
+ native-fsread: filename eq "/usr/bin" then permit native-fsread: filename eq "/usr/bin" then permit
+ native-fsread: filename eq "/usr/games" then permit native-fsread: filename eq "/usr/games" then permit
+ native-fsread: filename eq "/usr/include" then permit native-fsread: filename eq "/usr/include" then permit
+ native-fsread: filename eq "/usr/lib" then permit native-fsread: filename eq "/usr/lib" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" then p native-fsread: filename match "/usr/lib/libc.so.*" then p
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" t native-fsread: filename match "/usr/lib/libcrypto.so.*" t
+ native-fsread: filename match "/usr/lib/libncurses.so.*" native-fsread: filename match "/usr/lib/libncurses.so.*"
+ native-fsread: filename match "/usr/lib/libssl.so.*" then native-fsread: filename match "/usr/lib/libssl.so.*" then
+ native-fsread: filename eq "/usr/libdata" then permit native-fsread: filename eq "/usr/libdata" then permit
+ native-fsread: filename eq "/usr/libexec" then permit native-fsread: filename eq "/usr/libexec" then permit
+ native-fsread: filename eq "/usr/lkm" then permit native-fsread: filename eq "/usr/lkm" then permit
+ native-fsread: filename eq "/usr/local" then permit native-fsread: filename eq "/usr/local" then permit
+ native-fsread: filename eq "/usr/mdec" then permit native-fsread: filename eq "/usr/mdec" then permit
+ native-fsread: filename eq "/usr/obj" then permit native-fsread: filename eq "/usr/obj" then permit
+ native-fsread: filename eq "/usr/obj/bin" then permit native-fsread: filename eq "/usr/obj/bin" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then native-fsread: filename eq "/usr/obj/bin/systrace/." then
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mailca native-fsread: filename eq "/usr/obj/bin/systrace/.mailca
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t
+ native-fsread: filename eq "/usr/share/misc/terminfo.db" native-fsread: filename eq "/usr/share/misc/terminfo.db"
+ native-fsread: filename eq "/var/run/dev.db" then permit native-fsread: filename eq "/var/run/dev.db" then permit
+ native-fsread: filename eq "/var/run/ld.so.hints" then pe native-fsread: filename eq "/var/run/ld.so.hints" then pe
+ native-fstat: permit native-fstat: permit
+ native-fswrite: filename match "/tmp/lynx-*" then permit native-fswrite: filename match "/tmp/lynx-*" then permit
+ native-getdirentries: permit native-getdirentries: permit
+ native-getpid: permit native-getpid: permit
+ native-gettimeofday: permit native-gettimeofday: permit
+ native-ioctl: permit native-ioctl: permit
+ native-issetugid: permit native-issetugid: permit
+ native-lseek: permit native-lseek: permit
+ native-mmap: permit native-mmap: permit
+ native-mprotect: prot eq "PROT_READ" then permit native-mprotect: prot eq "PROT_READ" then permit
+ native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC"
+ native-munmap: permit native-munmap: permit
+ native-nanosleep: permit native-nanosleep: permit
+ native-poll: permit native-poll: permit
+ native-pread: permit native-pread: permit
+ native-read: permit native-read: permit
+ native-recvfrom: permit native-recvfrom: permit
+ native-select: permit native-select: permit
+ native-sendto: true then permit native-sendto: true then permit
+ native-sigaction: permit native-sigaction: permit
+ native-sigprocmask: permit native-sigprocmask: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK native-socket: sockdom eq "AF_INET" and socktype eq "SOCK
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK native-socket: sockdom eq "AF_INET" and socktype eq "SOCK
+ native-write: permit native-write: permit
diff --git a/usr.bin/sdiff/tests/d_short.out b/usr.bin/sdiff/tests/d_short.out
new file mode 100644
index 000000000000..7a334601721c
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_short.out
@@ -0,0 +1,15 @@
+Policy: /usr/bin/lynx, Emulation: native
+ native-issetugid: permit
+ native-mprotect: permit
+ native-mmap: permit
+ native-__sysctl: permit
+ native-close: permit
+ native-fsread: filename match "/usr/lib/libssl.so.*" then permit
+ native-read: permit
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" then permit
+ native-fsread: filename match "/usr/lib/libncurses.so.*" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" then permit
+ native-munmap: permit
+ native-sigprocmask: permit
+ native-fsread: filename eq "/etc/malloc.conf" then permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit
diff --git a/usr.bin/sdiff/tests/d_tabends.in b/usr.bin/sdiff/tests/d_tabends.in
new file mode 100644
index 000000000000..0547049d45cc
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_tabends.in
@@ -0,0 +1,17 @@
+
+0
+01
+012
+0123
+01234
+012345
+0123456
+01234567
+012345670
+0123456701
+01234567012
+012345670123
+0123456701234
+01234567012345
+012345670123456
+0123456701234567
diff --git a/usr.bin/sdiff/tests/d_tabends_a.out b/usr.bin/sdiff/tests/d_tabends_a.out
new file mode 100644
index 000000000000..423bd02ce1b6
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_tabends_a.out
@@ -0,0 +1,17 @@
+ <
+0 <
+01 <
+012 <
+0123 <
+01234 <
+012345 <
+0123456 <
+01234567 <
+012345670 <
+0123456701 <
+01234567012 <
+012345670123 <
+0123456701234 <
+0123456701234 <
+0123456701234 <
+0123456701234 <
diff --git a/usr.bin/sdiff/tests/d_tabends_b.out b/usr.bin/sdiff/tests/d_tabends_b.out
new file mode 100644
index 000000000000..b180705452a4
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_tabends_b.out
@@ -0,0 +1,17 @@
+ >
+ > 0
+ > 01
+ > 012
+ > 0123
+ > 01234
+ > 012345
+ > 0123456
+ > 01234567
+ > 012345670
+ > 0123456701
+ > 01234567012
+ > 012345670123
+ > 0123456701234
+ > 0123456701234
+ > 0123456701234
+ > 0123456701234
diff --git a/usr.bin/sdiff/tests/d_tabends_c.out b/usr.bin/sdiff/tests/d_tabends_c.out
new file mode 100644
index 000000000000..c3013824af74
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_tabends_c.out
@@ -0,0 +1,17 @@
+ <
+0 <
+01 <
+012 <
+0123 <
+01234 <
+012345 <
+0123456 <
+01234567 <
+01234567 <
+01234567 <
+01234567 <
+01234567 <
+01234567 <
+01234567 <
+01234567 <
+01234567 <
diff --git a/usr.bin/sdiff/tests/d_tabs.out b/usr.bin/sdiff/tests/d_tabs.out
new file mode 100644
index 000000000000..a67d7b146a38
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_tabs.out
@@ -0,0 +1,102 @@
+Policy: /usr/bin/lynx, Emulation: native Policy: /usr/bin/lynx, Emulation: native
+ > native-issetugid: permit
+ > native-mprotect: permit
+ > native-mmap: permit
+ native-__sysctl: permit native-__sysctl: permit
+ > native-fsread: filename eq "/var/run/ld.so.hints" the
+ > native-fstat: permit
+ native-close: permit native-close: permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" the | native-fsread: filename match "/usr/lib/libssl.so.*"
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" th | native-read: permit
+ native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.
+ native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so
+ native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" th
+ native-fsread: filename match "/<non-existent filenam | native-munmap: permit
+ native-fsread: filename eq "/etc/lynx.cfg" then permi | native-sigprocmask: permit
+ native-fsread: filename eq "/etc/malloc.conf" then pe native-fsread: filename eq "/etc/malloc.conf" then pe
+ native-fsread: filename eq "/etc/resolv.conf" then pe | native-getpid: permit
+ native-fsread: filename eq "/etc/utmp" then permit <
+ native-fsread: filename eq "/home" then permit <
+ native-fsread: filename eq "$HOME" then permit <
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then <
+ native-fsread: filename eq "$HOME/.lynxrc" then permi <
+ native-fsread: filename eq "$HOME/.mailcap" then perm <
+ native-fsread: filename eq "$HOME/.mime.types" then p <
+ native-fsread: filename eq "$HOME/.terminfo" then per <
+ native-fsread: filename eq "$HOME/.terminfo.db" then <
+ native-fsread: filename eq "/obj" then permit <
+ native-fsread: filename eq "/tmp" then permit native-fsread: filename eq "/tmp" then permit
+ > native-fswrite: filename match "/tmp/lynx-*" then per
+ native-fsread: filename match "/tmp/lynx-*/." then pe native-fsread: filename match "/tmp/lynx-*/." then pe
+ > native-fsread: filename eq "$HOME" then permit
+ > native-fsread: filename eq "/etc/lynx.cfg" then permi
+ > native-fsread: filename eq "/" then permit
+ > native-fsread: filename eq "/usr/obj/bin/systrace/."
+ > native-fsread: filename eq "/usr/obj/bin" then permit
+ > native-fcntl: permit
+ > native-getdirentries: permit
+ > native-lseek: permit
+ > native-fsread: filename eq "/usr/obj" then permit
+ native-fsread: filename eq "/usr" then permit native-fsread: filename eq "/usr" then permit
+ native-fsread: filename eq "/usr/bin" then permit native-fsread: filename eq "/usr/bin" then permit
+ native-fsread: filename eq "/usr/games" then permit native-fsread: filename eq "/usr/games" then permit
+ native-fsread: filename eq "/usr/include" then permit native-fsread: filename eq "/usr/include" then permit
+ native-fsread: filename eq "/usr/lib" then permit native-fsread: filename eq "/usr/lib" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" th <
+ native-fsread: filename match "/usr/lib/libcrypto.so. <
+ native-fsread: filename match "/usr/lib/libncurses.so <
+ native-fsread: filename match "/usr/lib/libssl.so.*" <
+ native-fsread: filename eq "/usr/libdata" then permit native-fsread: filename eq "/usr/libdata" then permit
+ native-fsread: filename eq "/usr/libexec" then permit native-fsread: filename eq "/usr/libexec" then permit
+ native-fsread: filename eq "/usr/lkm" then permit native-fsread: filename eq "/usr/lkm" then permit
+ native-fsread: filename eq "/usr/local" then permit native-fsread: filename eq "/usr/local" then permit
+ native-fsread: filename eq "/usr/mdec" then permit native-fsread: filename eq "/usr/mdec" then permit
+ native-fsread: filename eq "/usr/obj" then permit | native-fsread: filename eq "/home" then permit
+ native-fsread: filename eq "/usr/obj/bin" then permit | native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/." | native-fsread: filename eq "$HOME/.lynxrc" then permi
+ > native-fsread: filename match "/<non-existent filenam
+ native-fsread: filename eq "/usr/obj/bin/systrace/.ma native-fsread: filename eq "/usr/obj/bin/systrace/.ma
+ > native-fsread: filename eq "$HOME/.mailcap" then perm
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mi native-fsread: filename eq "/usr/obj/bin/systrace/.mi
+ > native-fsread: filename eq "$HOME/.mime.types" then p
+ > native-sigaction: permit
+ > native-ioctl: permit
+ > native-fsread: filename eq "$HOME/.terminfo.db" then
+ > native-fsread: filename eq "$HOME/.terminfo" then per
+ native-fsread: filename eq "/usr/share/misc/terminfo. native-fsread: filename eq "/usr/share/misc/terminfo.
+ > native-pread: permit
+ > native-write: permit
+ > native-fsread: filename eq "$HOME/.lynx-keymaps" then
+ native-fsread: filename eq "/var/run/dev.db" then per native-fsread: filename eq "/var/run/dev.db" then per
+ native-fsread: filename eq "/var/run/ld.so.hints" the | native-fsread: filename eq "/etc/utmp" then permit
+ native-fstat: permit <
+ native-fswrite: filename match "/tmp/lynx-*" then per <
+ native-getdirentries: permit <
+ native-getpid: permit <
+ native-gettimeofday: permit <
+ native-ioctl: permit <
+ native-issetugid: permit <
+ native-lseek: permit <
+ native-mmap: permit <
+ native-mprotect: prot eq "PROT_READ" then permit <
+ native-mprotect: prot eq "PROT_READ|PROT_EXEC" then p <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE" then <
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_E <
+ native-munmap: permit <
+ native-nanosleep: permit <
+ native-poll: permit native-poll: permit
+ native-pread: permit | native-nanosleep: permit
+ native-read: permit | native-gettimeofday: permit
+ native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then pe
+ native-select: permit <
+ native-sendto: true then permit <
+ native-sigaction: permit <
+ native-sigprocmask: permit <
+ native-socket: sockdom eq "AF_INET" and socktype eq " native-socket: sockdom eq "AF_INET" and socktype eq "
+ > native-connect: sockaddr eq "inet-[127.0.0.1]:53" the
+ > native-sendto: true then permit
+ > native-select: permit
+ > native-recvfrom: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq " native-socket: sockdom eq "AF_INET" and socktype eq "
+ native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" th
+ > native-exit: permit
diff --git a/usr.bin/sdiff/tests/d_tabs1.in b/usr.bin/sdiff/tests/d_tabs1.in
new file mode 100644
index 000000000000..b5a1834a3397
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_tabs1.in
@@ -0,0 +1,72 @@
+Policy: /usr/bin/lynx, Emulation: native
+ native-__sysctl: permit
+ native-close: permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then permit
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then permit
+ native-exit: permit
+ native-fcntl: cmd eq "F_SETFD" then permit
+ native-fsread: filename eq "/" then permit
+ native-fsread: filename match "/<non-existent filename>: *" then permit
+ native-fsread: filename eq "/etc/lynx.cfg" then permit
+ native-fsread: filename eq "/etc/malloc.conf" then permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit
+ native-fsread: filename eq "/etc/utmp" then permit
+ native-fsread: filename eq "/home" then permit
+ native-fsread: filename eq "$HOME" then permit
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then permit
+ native-fsread: filename eq "$HOME/.lynxrc" then permit
+ native-fsread: filename eq "$HOME/.mailcap" then permit
+ native-fsread: filename eq "$HOME/.mime.types" then permit
+ native-fsread: filename eq "$HOME/.terminfo" then permit
+ native-fsread: filename eq "$HOME/.terminfo.db" then permit
+ native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "/tmp" then permit
+ native-fsread: filename match "/tmp/lynx-*/." then permit
+ native-fsread: filename eq "/usr" then permit
+ native-fsread: filename eq "/usr/bin" then permit
+ native-fsread: filename eq "/usr/games" then permit
+ native-fsread: filename eq "/usr/include" then permit
+ native-fsread: filename eq "/usr/lib" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" then permit
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" then permit
+ native-fsread: filename match "/usr/lib/libncurses.so.*" then permit
+ native-fsread: filename match "/usr/lib/libssl.so.*" then permit
+ native-fsread: filename eq "/usr/libdata" then permit
+ native-fsread: filename eq "/usr/libexec" then permit
+ native-fsread: filename eq "/usr/lkm" then permit
+ native-fsread: filename eq "/usr/local" then permit
+ native-fsread: filename eq "/usr/mdec" then permit
+ native-fsread: filename eq "/usr/obj" then permit
+ native-fsread: filename eq "/usr/obj/bin" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mailcap" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mime.types" then permit
+ native-fsread: filename eq "/usr/share/misc/terminfo.db" then permit
+ native-fsread: filename eq "/var/run/dev.db" then permit
+ native-fsread: filename eq "/var/run/ld.so.hints" then permit
+ native-fstat: permit
+ native-fswrite: filename match "/tmp/lynx-*" then permit
+ native-getdirentries: permit
+ native-getpid: permit
+ native-gettimeofday: permit
+ native-ioctl: permit
+ native-issetugid: permit
+ native-lseek: permit
+ native-mmap: permit
+ native-mprotect: prot eq "PROT_READ" then permit
+ native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permit
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE" then permit
+ native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" then permit
+ native-munmap: permit
+ native-nanosleep: permit
+ native-poll: permit
+ native-pread: permit
+ native-read: permit
+ native-recvfrom: permit
+ native-select: permit
+ native-sendto: true then permit
+ native-sigaction: permit
+ native-sigprocmask: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_DGRAM" then permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_STREAM" then permit
+ native-write: permit
diff --git a/usr.bin/sdiff/tests/d_tabs2.in b/usr.bin/sdiff/tests/d_tabs2.in
new file mode 100644
index 000000000000..d00f4155d23b
--- /dev/null
+++ b/usr.bin/sdiff/tests/d_tabs2.in
@@ -0,0 +1,69 @@
+Policy: /usr/bin/lynx, Emulation: native
+ native-issetugid: permit
+ native-mprotect: permit
+ native-mmap: permit
+ native-__sysctl: permit
+ native-fsread: filename eq "/var/run/ld.so.hints" then permit
+ native-fstat: permit
+ native-close: permit
+ native-fsread: filename match "/usr/lib/libssl.so.*" then permit
+ native-read: permit
+ native-fsread: filename match "/usr/lib/libcrypto.so.*" then permit
+ native-fsread: filename match "/usr/lib/libncurses.so.*" then permit
+ native-fsread: filename match "/usr/lib/libc.so.*" then permit
+ native-munmap: permit
+ native-sigprocmask: permit
+ native-fsread: filename eq "/etc/malloc.conf" then permit
+ native-getpid: permit
+ native-fsread: filename eq "/tmp" then permit
+ native-fswrite: filename match "/tmp/lynx-*" then permit
+ native-fsread: filename match "/tmp/lynx-*/." then permit
+ native-fsread: filename eq "$HOME" then permit
+ native-fsread: filename eq "/etc/lynx.cfg" then permit
+ native-fsread: filename eq "/" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/." then permit
+ native-fsread: filename eq "/usr/obj/bin" then permit
+ native-fcntl: permit
+ native-getdirentries: permit
+ native-lseek: permit
+ native-fsread: filename eq "/usr/obj" then permit
+ native-fsread: filename eq "/usr" then permit
+ native-fsread: filename eq "/usr/bin" then permit
+ native-fsread: filename eq "/usr/games" then permit
+ native-fsread: filename eq "/usr/include" then permit
+ native-fsread: filename eq "/usr/lib" then permit
+ native-fsread: filename eq "/usr/libdata" then permit
+ native-fsread: filename eq "/usr/libexec" then permit
+ native-fsread: filename eq "/usr/lkm" then permit
+ native-fsread: filename eq "/usr/local" then permit
+ native-fsread: filename eq "/usr/mdec" then permit
+ native-fsread: filename eq "/home" then permit
+ native-fsread: filename eq "/obj" then permit
+ native-fsread: filename eq "$HOME/.lynxrc" then permit
+ native-fsread: filename match "/<non-existent filename>: *" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mailcap" then permit
+ native-fsread: filename eq "$HOME/.mailcap" then permit
+ native-fsread: filename eq "/usr/obj/bin/systrace/.mime.types" then permit
+ native-fsread: filename eq "$HOME/.mime.types" then permit
+ native-sigaction: permit
+ native-ioctl: permit
+ native-fsread: filename eq "$HOME/.terminfo.db" then permit
+ native-fsread: filename eq "$HOME/.terminfo" then permit
+ native-fsread: filename eq "/usr/share/misc/terminfo.db" then permit
+ native-pread: permit
+ native-write: permit
+ native-fsread: filename eq "$HOME/.lynx-keymaps" then permit
+ native-fsread: filename eq "/var/run/dev.db" then permit
+ native-fsread: filename eq "/etc/utmp" then permit
+ native-poll: permit
+ native-nanosleep: permit
+ native-gettimeofday: permit
+ native-fsread: filename eq "/etc/resolv.conf" then permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_DGRAM" then permit
+ native-connect: sockaddr eq "inet-[127.0.0.1]:53" then permit
+ native-sendto: true then permit
+ native-select: permit
+ native-recvfrom: permit
+ native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_STREAM" then permit
+ native-connect: sockaddr match "inet-\\\[*\\\]:80" then permit
+ native-exit: permit
diff --git a/usr.bin/sdiff/tests/sdiff.sh b/usr.bin/sdiff/tests/sdiff.sh
new file mode 100755
index 000000000000..51aac6ba80f3
--- /dev/null
+++ b/usr.bin/sdiff/tests/sdiff.sh
@@ -0,0 +1,207 @@
+# $NetBSD: t_sdiff.sh,v 1.1 2012/03/17 16:33:15 jruoho Exp $
+# $FreeBSD$
+#
+# Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case flags
+flags_head()
+{
+ atf_set "descr" "Checks -l, -s and -w flags"
+}
+flags_body()
+{
+ atf_check -o file:$(atf_get_srcdir)/d_flags_l.out -s eq:1 \
+ sdiff -l "$(atf_get_srcdir)/d_input1" "$(atf_get_srcdir)/d_input2"
+
+ atf_check -o file:$(atf_get_srcdir)/d_flags_s.out -s eq:1 \
+ sdiff -s "$(atf_get_srcdir)/d_input1" "$(atf_get_srcdir)/d_input2"
+
+ atf_check -o file:$(atf_get_srcdir)/d_flags_w.out -s eq:1 \
+ sdiff -w 125 "$(atf_get_srcdir)/d_input1" "$(atf_get_srcdir)/d_input2"
+}
+
+atf_test_case iflags
+iflags_head()
+{
+ atf_set "descr" "Checks flags -l, -s and -w combined with -I"
+}
+iflags_body()
+{
+ tail1="-w 125 -I .*filename.* $(atf_get_srcdir)/d_input1 $(atf_get_srcdir)/d_input2"
+ tail2="-w 125 -I .*filename.* $(atf_get_srcdir)/d_input2 $(atf_get_srcdir)/d_input1"
+
+ atf_check -o file:$(atf_get_srcdir)/d_iflags_a1.out -s eq:1 sdiff ${tail1}
+ atf_check -o file:$(atf_get_srcdir)/d_iflags_a2.out -s eq:1 sdiff ${tail2}
+ atf_check -o file:$(atf_get_srcdir)/d_iflags_b1.out -s eq:1 sdiff -s ${tail1}
+ atf_check -o file:$(atf_get_srcdir)/d_iflags_b2.out -s eq:1 sdiff -s ${tail2}
+ atf_check -o file:$(atf_get_srcdir)/d_iflags_c1.out -s eq:1 sdiff -l ${tail1}
+ atf_check -o file:$(atf_get_srcdir)/d_iflags_c2.out -s eq:1 sdiff -l ${tail2}
+ atf_check -o file:$(atf_get_srcdir)/d_iflags_d1.out -s eq:1 sdiff -s ${tail1}
+ atf_check -o file:$(atf_get_srcdir)/d_iflags_d2.out -s eq:1 sdiff -s ${tail2}
+}
+
+atf_test_case tabs
+tabs_head()
+{
+ atf_set "descr" "Checks comparing files containing tabs"
+}
+tabs_body()
+{
+ atf_check -o file:$(atf_get_srcdir)/d_tabs.out -s eq:1 \
+ sdiff "$(atf_get_srcdir)/d_tabs1.in" "$(atf_get_srcdir)/d_tabs2.in"
+}
+
+atf_test_case tabends
+tabends_head()
+{
+ atf_set "descr" "Checks correct handling of lines ended with tabs"
+}
+tabends_body()
+{
+ atf_check -o file:$(atf_get_srcdir)/d_tabends_a.out -s eq:1 \
+ sdiff -w30 "$(atf_get_srcdir)/d_tabends.in" /dev/null
+
+ atf_check -o file:$(atf_get_srcdir)/d_tabends_b.out -s eq:1 \
+ sdiff -w30 /dev/null "$(atf_get_srcdir)/d_tabends.in"
+
+ atf_check -o file:$(atf_get_srcdir)/d_tabends_c.out -s eq:1 \
+ sdiff -w19 "$(atf_get_srcdir)/d_tabends.in" /dev/null
+}
+
+atf_test_case merge
+merge_head()
+{
+ atf_set "descr" "Checks interactive merging"
+}
+merge_body()
+{
+ merge_tail="-o merge.out $(atf_get_srcdir)/d_input1 \
+$(atf_get_srcdir)/d_input2 >/dev/null ; cat merge.out"
+
+ cp $(atf_get_srcdir)/d_input* .
+
+ atf_check -o file:d_input1 -x "yes l | sdiff ${merge_tail}"
+ atf_check -o file:d_input2 -x "yes r | sdiff ${merge_tail}"
+
+ atf_check -o file:d_input1 -x \
+ "yes el | EDITOR=cat VISUAL=cat sdiff ${merge_tail}"
+ atf_check -o file:d_input2 -x \
+ "yes er | EDITOR=cat VISUAL=cat sdiff ${merge_tail}"
+
+ atf_check -o file:d_input1 -x "yes l | sdiff -s ${merge_tail}"
+ atf_check -o file:d_input2 -x "yes r | sdiff -s ${merge_tail}"
+ atf_check -o file:d_input1 -x "yes l | sdiff -l ${merge_tail}"
+ atf_check -o file:d_input2 -x "yes r | sdiff -l ${merge_tail}"
+ atf_check -o file:d_input1 -x "yes l | sdiff -ls ${merge_tail}"
+ atf_check -o file:d_input2 -x "yes r | sdiff -ls ${merge_tail}"
+
+ atf_check -o file:d_input1 -x "{ while :; do echo s; echo l; \
+echo v; echo l; done; } | sdiff ${merge_tail}"
+
+ atf_check -o file:d_input2 -x "{ while :; do echo s; echo r; \
+echo v; echo r; done; } | sdiff ${merge_tail}"
+}
+
+atf_test_case same
+same_head()
+{
+ atf_set "descr" "Checks comparing file with itself"
+}
+same_body()
+{
+ atf_check -o file:$(atf_get_srcdir)/d_same.out \
+ sdiff "$(atf_get_srcdir)/d_input1" "$(atf_get_srcdir)/d_input1"
+}
+
+atf_test_case oneline
+oneline_head()
+{
+ atf_set "descr" "Checks comparing one-line files"
+}
+oneline_body()
+{
+ atf_check -o file:$(atf_get_srcdir)/d_oneline_a.out -s eq:1 \
+ sdiff /dev/null "$(atf_get_srcdir)/d_oneline.in"
+
+ atf_check -o file:$(atf_get_srcdir)/d_oneline_b.out -s eq:1 \
+ sdiff "$(atf_get_srcdir)/d_oneline.in" /dev/null
+}
+
+atf_test_case dot
+dot_head()
+{
+ atf_set "descr" "Checks comparing with file containing only one character"
+}
+dot_body()
+{
+ echo ". <" > expout
+ atf_check -o file:expout -s eq:1 sdiff "$(atf_get_srcdir)/d_dot.in" /dev/null
+
+ echo " > ." > expout
+ atf_check -o file:expout -s eq:1 sdiff /dev/null "$(atf_get_srcdir)/d_dot.in"
+}
+
+atf_test_case stdin
+stdin_head()
+{
+ atf_set "descr" "Checks reading data from stdin"
+}
+stdin_body()
+{
+ echo " > stdin" > expout
+ atf_check -o file:expout -s eq:1 -x \
+ "echo stdin | sdiff /dev/null /dev/stdin"
+
+ echo "stdin <" > expout
+ atf_check -o file:expout -s eq:1 -x \
+ "echo stdin | sdiff /dev/stdin /dev/null"
+}
+
+atf_test_case short
+short_head()
+{
+ atf_set "descr" "Checks premature stop of merging"
+}
+short_body()
+{
+ atf_check -o file:$(atf_get_srcdir)/d_short.out -x \
+ "printf \"r\\nl\\nr\\nl\" | sdiff -o merge.out $(atf_get_srcdir)/d_input1 \
+$(atf_get_srcdir)/d_input2 >/dev/null ; cat merge.out"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case flags
+ atf_add_test_case iflags
+ atf_add_test_case tabs
+ atf_add_test_case tabends
+ atf_add_test_case merge
+ atf_add_test_case same
+ atf_add_test_case oneline
+ atf_add_test_case dot
+ atf_add_test_case stdin
+ atf_add_test_case short
+}