./usr/bin/flex++ minix-base
./usr/bin/flex minix-base
./usr/bin/flock minix-base
+./usr/bin/fmt minix-base
./usr/bin/fold minix-base
./usr/bin/format minix-base
./usr/bin/fpr minix-base
./usr/libdata/debug/usr/bin/finger.debug minix-debug debug
./usr/libdata/debug/usr/bin/fix.debug minix-debug debug
./usr/libdata/debug/usr/bin/flock.debug minix-debug debug
+./usr/libdata/debug/usr/bin/fmt.debug minix-debug debug
./usr/libdata/debug/usr/bin/fold.debug minix-debug debug
./usr/libdata/debug/usr/bin/format.debug minix-debug debug
./usr/libdata/debug/usr/bin/fpr.debug minix-debug debug
./usr/man/man1/flex.1 minix-man
./usr/man/man1/flexdoc.1 minix-man obsolete
./usr/man/man1/flock.1 minix-man
+./usr/man/man1/fmt.1 minix-man
./usr/man/man1/fold.1 minix-man
./usr/man/man1/for.1 minix-man obsolete
./usr/man/man1/foreach.1 minix-man
column comm csplit ctags cut \
deroff dirname du \
env expand \
- false find finger flock fold fpr from \
+ false find finger flock fold fmt fpr from \
fsplit ftp genassym gencat \
getopt \
head hexdump id indent infocmp ipcrm ipcs join jot \
--- /dev/null
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+# $NetBSD: Makefile,v 1.10 2009/04/14 22:15:20 lukem Exp $
+
+.include <bsd.own.mk>
+
+PROG= fmt
+SRCS= fmt.c head.c
+CPPFLAGS+= -DFMT_PROG
+
+.PATH: ${NETBSDSRCDIR}/usr.bin/mail
+
+.include <bsd.prog.mk>
--- /dev/null
+/* $NetBSD: buffer.h,v 1.4 2008/04/28 20:24:12 martin Exp $ */
+
+/*-
+ * Copyright (c) 2005 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <err.h>
+
+#define BUF_SIZE BUFSIZ
+struct buffer {
+ char *ptr;
+ char *bptr;
+ char *eptr;
+};
+
+static void
+buf_init(struct buffer *buf)
+{
+ buf->ptr = buf->bptr = malloc(BUF_SIZE);
+ if (buf->ptr == NULL)
+ err(1, "Cannot allocate buffer");
+ buf->eptr = buf->ptr + BUF_SIZE;
+}
+
+static void
+buf_end(struct buffer *buf)
+{
+ free(buf->bptr);
+}
+
+static void
+buf_grow(struct buffer *buf, size_t minsize)
+{
+ ptrdiff_t diff;
+ size_t len = (buf->eptr - buf->bptr) +
+ (minsize > BUF_SIZE ? minsize : BUF_SIZE);
+ char *nptr = realloc(buf->bptr, len);
+
+ if (nptr == NULL)
+ err(1, "Cannot grow buffer");
+
+ if (nptr == buf->bptr) {
+ buf->eptr = buf->bptr + len;
+ return;
+ }
+
+ diff = nptr - buf->bptr;
+ buf->bptr += diff;
+ buf->eptr = buf->bptr + len;
+ buf->ptr += diff;
+}
+
+static inline void
+buf_putc(struct buffer *buf, char c)
+{
+ if (buf->ptr >= buf->eptr)
+ buf_grow(buf, 1);
+ *buf->ptr++ = c;
+}
+
+static inline void
+buf_reset(struct buffer *buf)
+{
+ buf->ptr = buf->bptr;
+}
+
+static inline char
+buf_unputc(struct buffer *buf)
+{
+ return buf->ptr > buf->bptr ? *--buf->ptr : '\0';
+}
--- /dev/null
+.\" $NetBSD: fmt.1,v 1.13 2012/06/30 21:31:15 christos Exp $
+.\"
+.\" Copyright (c) 1980, 1990, 1993
+.\" The Regents of the University of California. 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.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+.\"
+.\" @(#)fmt.1 8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 31, 2012
+.Dt FMT 1
+.Os
+.Sh NAME
+.Nm fmt
+.Nd simple text formatter
+.Sh SYNOPSIS
+.Nm
+.Op Fl Cr
+.Oo
+.Ar goal
+.Op Ar maximum
+.Oc
+.Op name ...
+.Nm
+.Op Fl Cr
+.Op Fl g Ar goal
+.Op Fl m Ar maximum
+.Op Fl w Ar maximum
+.Op name ...
+.Sh DESCRIPTION
+.Nm
+is a simple text formatter which reads the concatenation of input
+files (or standard input if none are given) and produces on standard
+output a version of its input with lines as close to the
+.Ar goal
+length as possible without exceeding the
+.Ar maximum .
+The
+.Ar goal
+length defaults to 65 and the
+.Ar maximum
+to 75.
+The spacing at the beginning of the input lines is preserved in
+the output, as are blank lines and interword spacing.
+In non raw mode, lines that look like mail headers or begin with
+a period are not formatted.
+.Pp
+.Bl -tag -width ".Fl m Ar maximum"
+.It Fl C
+instructs
+.Nm
+to center the text.
+.It Fl g Ar goal
+New way to set the goal length.
+.It Fl m Ar maximum
+New way to set the maximum length.
+.It Fl w Ar maximum
+New way to set the maximum length.
+.It Fl r
+Raw mode; formats all lines and does not make exceptions for lines
+that start with a period or look like mail headers.
+.El
+.Pp
+.Nm
+is meant to format mail messages prior to sending, but may also be useful
+for other simple tasks.
+For instance, within visual mode of the
+.Xr ex 1
+editor (e.g.,
+.Xr vi 1 )
+the command
+.Pp
+.Dl \&!}fmt
+.Pp
+will reformat a paragraph, evening the lines.
+.Sh SEE ALSO
+.Xr mail 1 ,
+.Xr nroff 1
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 3 .
+.\" .Sh AUTHORS
+.\" Kurt Shoens
+.\" .Pp
+.\" Liz Allen (added goal length concept)
+.Sh BUGS
+The program was designed to be simple and fast \- for more complex
+operations, the standard text processors are likely to be more
+appropriate.
--- /dev/null
+/* $NetBSD: fmt.c,v 1.32 2012/06/30 21:31:15 christos Exp $ */
+
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1980, 1993\
+ The Regents of the University of California. All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)fmt.c 8.1 (Berkeley) 7/20/93";
+#endif
+__RCSID("$NetBSD: fmt.c,v 1.32 2012/06/30 21:31:15 christos Exp $");
+#endif /* not lint */
+
+#include <ctype.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <err.h>
+#include <limits.h>
+#include <string.h>
+#include "buffer.h"
+
+/*
+ * fmt -- format the concatenation of input files or standard input
+ * onto standard output. Designed for use with Mail ~|
+ *
+ * Syntax : fmt [ goal [ max ] ] [ name ... ]
+ * Authors: Kurt Shoens (UCB) 12/7/78;
+ * Liz Allen (UMCP) 2/24/83 [Addition of goal length concept].
+ */
+
+/* LIZ@UOM 6/18/85 --New variables goal_length and max_length */
+#define GOAL_LENGTH 65
+#define MAX_LENGTH 75
+static size_t goal_length; /* Target or goal line length in output */
+static size_t max_length; /* Max line length in output */
+static size_t pfx; /* Current leading blank count */
+static int raw; /* Don't treat mail specially */
+static int lineno; /* Current input line */
+static int mark; /* Last place we saw a head line */
+static int center;
+static struct buffer outbuf;
+
+static const char *headnames[] = {"To", "Subject", "Cc", 0};
+
+static void usage(void) __dead;
+static int getnum(const char *, const char *, size_t *, int);
+static void fmt(FILE *);
+static int ispref(const char *, const char *);
+static void leadin(void);
+static void oflush(void);
+static void pack(const char *, size_t);
+static void prefix(const struct buffer *, int);
+static void split(const char *, int);
+static void tabulate(struct buffer *);
+
+
+int ishead(const char *);
+
+/*
+ * Drive the whole formatter by managing input files. Also,
+ * cause initialization of the output stuff and flush it out
+ * at the end.
+ */
+
+int
+main(int argc, char **argv)
+{
+ FILE *fi;
+ int errs = 0;
+ int compat = 1;
+ int c;
+
+ goal_length = GOAL_LENGTH;
+ max_length = MAX_LENGTH;
+ buf_init(&outbuf);
+ lineno = 1;
+ mark = -10;
+
+ setprogname(*argv);
+ (void)setlocale(LC_ALL, "");
+
+ while ((c = getopt(argc, argv, "Cg:m:rw:")) != -1)
+ switch (c) {
+ case 'C':
+ center++;
+ break;
+ case 'g':
+ (void)getnum(optarg, "goal", &goal_length, 1);
+ compat = 0;
+ break;
+ case 'm':
+ case 'w':
+ (void)getnum(optarg, "max", &max_length, 1);
+ compat = 0;
+ break;
+ case 'r':
+ raw++;
+ break;
+ default:
+ usage();
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /*
+ * compatibility with old usage.
+ */
+ if (compat && argc > 0 && getnum(*argv, "goal", &goal_length, 0)) {
+ argv++;
+ argc--;
+ if (argc > 0 && getnum(*argv, "max", &max_length, 0)) {
+ argv++;
+ argc--;
+ }
+ }
+
+ if (max_length <= goal_length) {
+ errx(1, "Max length (%zu) must be greater than goal "
+ "length (%zu)", max_length, goal_length);
+ }
+ if (argc == 0) {
+ fmt(stdin);
+ oflush();
+ return 0;
+ }
+ for (;argc; argc--, argv++) {
+ if ((fi = fopen(*argv, "r")) == NULL) {
+ warn("Cannot open `%s'", *argv);
+ errs++;
+ continue;
+ }
+ fmt(fi);
+ (void)fclose(fi);
+ }
+ oflush();
+ buf_end(&outbuf);
+ return errs;
+}
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr,
+ "Usage: %s [-Cr] [-g <goal>] [-m|w <max>] [<files>..]\n"
+ "\t %s [-Cr] [<goal>] [<max>] [<files>]\n",
+ getprogname(), getprogname());
+ exit(1);
+}
+
+static int
+getnum(const char *str, const char *what, size_t *res, int badnum)
+{
+ unsigned long ul;
+ char *ep;
+
+ errno = 0;
+ ul = strtoul(str, &ep, 0);
+ if (*str != '\0' && *ep == '\0') {
+ if ((errno == ERANGE && ul == ULONG_MAX) || ul > SIZE_T_MAX)
+ errx(1, "%s number `%s' too big", what, str);
+ *res = (size_t)ul;
+ return 1;
+ } else if (badnum)
+ errx(1, "Bad %s number `%s'", what, str);
+
+ return 0;
+}
+
+/*
+ * Read up characters from the passed input file, forming lines,
+ * doing ^H processing, expanding tabs, stripping trailing blanks,
+ * and sending each line down for analysis.
+ */
+static void
+fmt(FILE *fi)
+{
+ struct buffer lbuf, cbuf;
+ char *cp, *cp2;
+ int c, add_space;
+ size_t len, col, i;
+
+ if (center) {
+ for (;;) {
+ cp = fgetln(fi, &len);
+ if (!cp)
+ return;
+
+ /* skip over leading space */
+ while (len > 0) {
+ if (!isspace((unsigned char)*cp))
+ break;
+ cp++;
+ len--;
+ }
+
+ /* clear trailing space */
+ while (len > 0) {
+ if (!isspace((unsigned char)cp[len-1]))
+ break;
+ len--;
+ }
+
+ if (len == 0) {
+ /* blank line */
+ (void)putchar('\n');
+ continue;
+ }
+
+ if (goal_length > len) {
+ for (i = 0; i < (goal_length - len) / 2; i++) {
+ (void)putchar(' ');
+ }
+ }
+ for (i = 0; i < len; i++) {
+ (void)putchar(cp[i]);
+ }
+ (void)putchar('\n');
+ }
+ }
+
+ buf_init(&lbuf);
+ buf_init(&cbuf);
+ c = getc(fi);
+
+ while (c != EOF) {
+ /*
+ * Collect a line, doing ^H processing.
+ * Leave tabs for now.
+ */
+ buf_reset(&lbuf);
+ while (c != '\n' && c != EOF) {
+ if (c == '\b') {
+ (void)buf_unputc(&lbuf);
+ c = getc(fi);
+ continue;
+ }
+ if(!(isprint(c) || c == '\t' || c >= 160)) {
+ c = getc(fi);
+ continue;
+ }
+ buf_putc(&lbuf, c);
+ c = getc(fi);
+ }
+ buf_putc(&lbuf, '\0');
+ (void)buf_unputc(&lbuf);
+ add_space = c != EOF;
+
+ /*
+ * Expand tabs on the way.
+ */
+ col = 0;
+ cp = lbuf.bptr;
+ buf_reset(&cbuf);
+ while ((c = *cp++) != '\0') {
+ if (c != '\t') {
+ col++;
+ buf_putc(&cbuf, c);
+ continue;
+ }
+ do {
+ buf_putc(&cbuf, ' ');
+ col++;
+ } while ((col & 07) != 0);
+ }
+
+ /*
+ * Swipe trailing blanks from the line.
+ */
+ for (cp2 = cbuf.ptr - 1; cp2 >= cbuf.bptr && *cp2 == ' '; cp2--)
+ continue;
+ cbuf.ptr = cp2 + 1;
+ buf_putc(&cbuf, '\0');
+ (void)buf_unputc(&cbuf);
+ prefix(&cbuf, add_space);
+ if (c != EOF)
+ c = getc(fi);
+ }
+ buf_end(&cbuf);
+ buf_end(&lbuf);
+}
+
+/*
+ * Take a line devoid of tabs and other garbage and determine its
+ * blank prefix. If the indent changes, call for a linebreak.
+ * If the input line is blank, echo the blank line on the output.
+ * Finally, if the line minus the prefix is a mail header, try to keep
+ * it on a line by itself.
+ */
+static void
+prefix(const struct buffer *buf, int add_space)
+{
+ const char *cp;
+ const char **hp;
+ size_t np;
+ int h;
+
+ if (buf->ptr == buf->bptr) {
+ oflush();
+ (void)putchar('\n');
+ return;
+ }
+ for (cp = buf->bptr; *cp == ' '; cp++)
+ continue;
+ np = cp - buf->bptr;
+
+ /*
+ * The following horrible expression attempts to avoid linebreaks
+ * when the indent changes due to a paragraph.
+ */
+ if (np != pfx && (np > pfx || abs((int)(pfx - np)) > 8))
+ oflush();
+ if (!raw) {
+ if ((h = ishead(cp)) != 0) {
+ oflush();
+ mark = lineno;
+ }
+ if (lineno - mark < 3 && lineno - mark > 0)
+ for (hp = &headnames[0]; *hp != NULL; hp++)
+ if (ispref(*hp, cp)) {
+ h = 1;
+ oflush();
+ break;
+ }
+ if (!h && (h = (*cp == '.')))
+ oflush();
+ } else
+ h = 0;
+ pfx = np;
+ if (h) {
+ pack(cp, (size_t)(buf->ptr - cp));
+ oflush();
+ } else
+ split(cp, add_space);
+ lineno++;
+}
+
+/*
+ * Split up the passed line into output "words" which are
+ * maximal strings of non-blanks with the blank separation
+ * attached at the end. Pass these words along to the output
+ * line packer.
+ */
+static void
+split(const char line[], int add_space)
+{
+ const char *cp;
+ struct buffer word;
+ size_t wlen;
+
+ buf_init(&word);
+ cp = line;
+ while (*cp) {
+ buf_reset(&word);
+ wlen = 0;
+
+ /*
+ * Collect a 'word,' allowing it to contain escaped white
+ * space.
+ */
+ while (*cp && *cp != ' ') {
+ if (*cp == '\\' && isspace((unsigned char)cp[1]))
+ buf_putc(&word, *cp++);
+ buf_putc(&word, *cp++);
+ wlen++;
+ }
+
+ /*
+ * Guarantee a space at end of line. Two spaces after end of
+ * sentence punctuation.
+ */
+ if (*cp == '\0' && add_space) {
+ buf_putc(&word, ' ');
+ if (strchr(".:!", cp[-1]))
+ buf_putc(&word, ' ');
+ }
+ while (*cp == ' ')
+ buf_putc(&word, *cp++);
+
+ buf_putc(&word, '\0');
+ (void)buf_unputc(&word);
+
+ pack(word.bptr, wlen);
+ }
+ buf_end(&word);
+}
+
+/*
+ * Output section.
+ * Build up line images from the words passed in. Prefix
+ * each line with correct number of blanks.
+ *
+ * At the bottom of this whole mess, leading tabs are reinserted.
+ */
+
+/*
+ * Pack a word onto the output line. If this is the beginning of
+ * the line, push on the appropriately-sized string of blanks first.
+ * If the word won't fit on the current line, flush and begin a new
+ * line. If the word is too long to fit all by itself on a line,
+ * just give it its own and hope for the best.
+ *
+ * LIZ@UOM 6/18/85 -- If the new word will fit in at less than the
+ * goal length, take it. If not, then check to see if the line
+ * will be over the max length; if so put the word on the next
+ * line. If not, check to see if the line will be closer to the
+ * goal length with or without the word and take it or put it on
+ * the next line accordingly.
+ */
+
+static void
+pack(const char *word, size_t wlen)
+{
+ const char *cp;
+ size_t s, t;
+
+ if (outbuf.bptr == outbuf.ptr)
+ leadin();
+ /*
+ * LIZ@UOM 6/18/85 -- change condition to check goal_length; s is the
+ * length of the line before the word is added; t is now the length
+ * of the line after the word is added
+ */
+ s = outbuf.ptr - outbuf.bptr;
+ t = wlen + s;
+ if ((t <= goal_length) || ((t <= max_length) &&
+ (s <= goal_length) && (t - goal_length <= goal_length - s))) {
+ /*
+ * In like flint!
+ */
+ for (cp = word; *cp;)
+ buf_putc(&outbuf, *cp++);
+ return;
+ }
+ if (s > pfx) {
+ oflush();
+ leadin();
+ }
+ for (cp = word; *cp;)
+ buf_putc(&outbuf, *cp++);
+}
+
+/*
+ * If there is anything on the current output line, send it on
+ * its way. Reset outbuf.
+ */
+static void
+oflush(void)
+{
+ if (outbuf.bptr == outbuf.ptr)
+ return;
+ buf_putc(&outbuf, '\0');
+ (void)buf_unputc(&outbuf);
+ tabulate(&outbuf);
+ buf_reset(&outbuf);
+}
+
+/*
+ * Take the passed line buffer, insert leading tabs where possible, and
+ * output on standard output (finally).
+ */
+static void
+tabulate(struct buffer *buf)
+{
+ char *cp;
+ size_t b, t;
+
+ /*
+ * Toss trailing blanks in the output line.
+ */
+ for (cp = buf->ptr - 1; cp >= buf->bptr && *cp == ' '; cp--)
+ continue;
+ *++cp = '\0';
+
+ /*
+ * Count the leading blank space and tabulate.
+ */
+ for (cp = buf->bptr; *cp == ' '; cp++)
+ continue;
+ b = cp - buf->bptr;
+ t = b / 8;
+ b = b % 8;
+ if (t > 0)
+ do
+ (void)putchar('\t');
+ while (--t);
+ if (b > 0)
+ do
+ (void)putchar(' ');
+ while (--b);
+ while (*cp)
+ (void)putchar(*cp++);
+ (void)putchar('\n');
+}
+
+/*
+ * Initialize the output line with the appropriate number of
+ * leading blanks.
+ */
+static void
+leadin(void)
+{
+ size_t b;
+
+ buf_reset(&outbuf);
+
+ for (b = 0; b < pfx; b++)
+ buf_putc(&outbuf, ' ');
+}
+
+/*
+ * Is s1 a prefix of s2??
+ */
+static int
+ispref(const char *s1, const char *s2)
+{
+
+ while (*s1++ == *s2)
+ continue;
+ return *s1 == '\0';
+}
--- /dev/null
+/* $NetBSD: def.h,v 1.28 2014/10/18 08:33:30 snj Exp $ */
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)def.h 8.4 (Berkeley) 4/20/95
+ * $NetBSD: def.h,v 1.28 2014/10/18 08:33:30 snj Exp $
+ */
+
+/*
+ * Mail -- a mail program
+ *
+ * Author: Kurt Shoens (UCB) March 25, 1978
+ */
+
+#ifndef __DEF_H__
+#define __DEF_H__
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <time.h>
+#include <unistd.h>
+#include <vis.h>
+
+#include "pathnames.h"
+
+#define APPEND /* New mail goes to end of mailbox */
+
+#define COMMENT_CHAR '#' /* Comment character when sourcing */
+#define ESCAPE '~' /* Default escape for sending */
+#define NMLSIZE 1024 /* max names in a message list */
+#define PATHSIZE MAXPATHLEN /* Size of pathnames throughout */
+#define HSHSIZE 59 /* Hash size for aliases and vars */
+#define LINESIZE BUFSIZ /* max readable line width */
+#define MAXARGC 1024 /* Maximum list of raw strings */
+#define MAXEXP 25 /* Maximum expansion of aliases */
+
+#define PUBLIC /* make it easy to find the entry points */
+
+/*
+ * User environment variable names.
+ * See complete.h, mime.h, and thread.h for names specific to those modules.
+ */
+#define ENAME_INDENT_POSTSCRIPT "indentpostscript"
+#define ENAME_INDENT_PREAMBLE "indentpreamble"
+#define ENAME_APPEND "append"
+#define ENAME_ASK "ask"
+#define ENAME_ASKBCC "askbcc"
+#define ENAME_ASKCC "askcc"
+#define ENAME_ASKSUB "asksub"
+#define ENAME_AUTOINC "autoinc"
+#define ENAME_AUTOPRINT "autoprint"
+#define ENAME_CRT "crt"
+#define ENAME_DEAD "DEAD"
+#define ENAME_DEBUG "debug"
+#define ENAME_DONTSENDEMPTY "dontsendempty"
+#define ENAME_DOT "dot"
+#define ENAME_EDITOR "EDITOR"
+#define ENAME_ENABLE_PIPES "enable-pipes"
+#define ENAME_ESCAPE "escape"
+#define ENAME_FOLDER "folder"
+#define ENAME_HEADER_FORMAT "header-format"
+#define ENAME_HOLD "hold"
+#define ENAME_IGNORE "ignore"
+#define ENAME_IGNOREEOF "ignoreeof"
+#define ENAME_INDENTPREFIX "indentprefix"
+#define ENAME_INTERACTIVE "interactive"
+#define ENAME_KEEP "keep"
+#define ENAME_KEEPSAVE "keepsave"
+#define ENAME_LISTER "LISTER"
+#define ENAME_MBOX "MBOX"
+#define ENAME_METOO "metoo"
+#define ENAME_NOHEADER "noheader"
+#define ENAME_NOSAVE "nosave"
+#define ENAME_PAGE_ALSO "page-also"
+#define ENAME_PAGER "PAGER"
+#define ENAME_PAGER_OFF "pager-off"
+#define ENAME_PROMPT "prompt"
+#define ENAME_QUIET "quiet"
+#define ENAME_RECORD "record"
+#define ENAME_REGEX_SEARCH "regex-search"
+#define ENAME_REPLYALL "Replyall"
+#define ENAME_REPLYASRECIPIENT "ReplyAsRecipient"
+#define ENAME_SCREEN "screen"
+#define ENAME_SCREENHEIGHT "screenheight"
+#define ENAME_SCREENWIDTH "screenwidth"
+#define ENAME_SEARCHHEADERS "searchheaders"
+#define ENAME_SENDMAIL "sendmail"
+#define ENAME_SHELL "SHELL"
+#define ENAME_SHOW_RCPT "show-rcpt"
+#define ENAME_SMOPTS_VERIFY "smopts-verify"
+#define ENAME_TOPLINES "toplines"
+#define ENAME_VERBOSE "verbose"
+#define ENAME_VISUAL "VISUAL"
+
+#define equal(a, b) (strcmp(a,b)==0)/* A nice function to string compare */
+
+struct message {
+ short m_flag; /* flags, see below */
+ short m_offset; /* offset in block of message */
+ long m_block; /* block number of this message */
+ long m_lines; /* Lines in the message */
+ off_t m_size; /* Bytes in the message */
+ long m_blines; /* Body (non-header) lines */
+
+ /*
+ * threading fields
+ */
+ int m_index; /* message index in this thread */
+ int m_depth; /* depth in thread */
+ struct message *m_flink; /* link to next message */
+ struct message *m_blink; /* link to previous message */
+ struct message *m_clink; /* link to child of this message */
+ struct message *m_plink; /* link to parent of thread */
+};
+typedef struct mime_info mime_info_t; /* phantom structure only to attach.c */
+
+/*
+ * flag bits.
+ */
+
+#define MUSED (1<<0) /* entry is used, but this bit isn't */
+#define MDELETED (1<<1) /* entry has been deleted */
+#define MSAVED (1<<2) /* entry has been saved */
+#define MTOUCH (1<<3) /* entry has been noticed */
+#define MPRESERVE (1<<4) /* keep entry in sys mailbox */
+#define MMARK (1<<5) /* message is marked! */
+#define MMODIFY (1<<6) /* message has been modified */
+#define MNEW (1<<7) /* message has never been seen */
+#define MREAD (1<<8) /* message has been read sometime. */
+#define MSTATUS (1<<9) /* message status has changed */
+#define MBOX (1<<10) /* Send this to mbox, regardless */
+#define MTAGGED (1<<11) /* message has been tagged */
+
+/*
+ * Given a file address, determine the block number it represents.
+ */
+#define blockof(off) ((int) ((off) / 4096))
+#define blkoffsetof(off) ((int) ((off) % 4096))
+#define positionof(block, offset) ((off_t)(block) * 4096 + (offset))
+
+/*
+ * Format of the command description table.
+ * The actual table is declared and initialized
+ * in lex.c
+ */
+struct cmd {
+ const char *c_name; /* Name of command */
+ int (*c_func)(void *); /* Implementor of the command */
+ int c_pipe; /* Pipe output through the pager */
+# define C_PIPE_PAGER 1 /* enable use of pager */
+# define C_PIPE_CRT 2 /* use the pager if CRT is defined */
+# define C_PIPE_SHELL 4 /* enable shell pipes */
+#ifdef USE_EDITLINE
+ const char *c_complete; /* String describing completion */
+#endif
+ short c_argtype; /* Type of arglist (see below) */
+ short c_msgflag; /* Required flags of messages */
+ short c_msgmask; /* Relevant flags of messages */
+};
+
+/* Yechh, can't initialize unions */
+
+#define c_minargs c_msgflag /* Minimum argcount for RAWLIST */
+#define c_maxargs c_msgmask /* Max argcount for RAWLIST */
+
+/*
+ * Argument types.
+ */
+
+#define MSGLIST 0 /* Message list type */
+#define STRLIST 1 /* A pure string */
+#define RAWLIST 2 /* Shell string list */
+#define NOLIST 3 /* Just plain 0 */
+#define NDMLIST 4 /* Message list, no defaults */
+
+#define P 0x010 /* Autoprint dot after command */
+#define I 0x020 /* Interactive command bit */
+#define M 0x040 /* Legal from send mode bit */
+#define W 0x080 /* Illegal when read only bit */
+#define F 0x100 /* Is a conditional command */
+#define T 0x200 /* Is a transparent command */
+#define R 0x400 /* Cannot be called from collect */
+#define ARGTYPE_MASK ~(P|I|M|W|F|T|R)
+
+/*
+ * Oft-used mask values
+ */
+
+#define MMNORM (MDELETED|MSAVED)/* Look at both save and delete bits */
+#define MMNDEL MDELETED /* Look only at deleted bit */
+
+/*
+ * Structure used to return a break down of a head
+ * line (hats off to Bill Joy!)
+ */
+
+struct headline {
+ char *l_from; /* The name of the sender */
+ char *l_tty; /* His tty string (if any) */
+ char *l_date; /* The entire date string */
+};
+
+#define GTO 0x001 /* Grab To: line */
+#define GSUBJECT 0x002 /* Likewise, Subject: line */
+#define GCC 0x004 /* And the Cc: line */
+#define GBCC 0x008 /* And also the Bcc: line */
+#define GSMOPTS 0x010 /* Grab the sendmail options */
+#define GMISC 0x020 /* miscellaneous extra fields for sending */
+#ifdef MIME_SUPPORT
+#define GMIME 0x040 /* mime flag */
+#endif
+#define GMASK (GTO | GSUBJECT | GCC | GBCC | GSMOPTS)
+ /* Mask of places from whence */
+
+#define GNL 0x100 /* Print blank line after */
+#define GDEL 0x200 /* Entity removed from list */
+#define GCOMMA 0x400 /* detract puts in commas */
+
+#ifdef MIME_SUPPORT
+/*
+ * Structure of MIME content.
+ */
+struct Content {
+ const char *C_type; /* content type */
+ const char *C_encoding; /* content transfer encoding */
+ const char *C_disposition; /* content disposition */
+ const char *C_description; /* content description */
+ const char *C_id; /* content id */
+};
+/* Header strings corresponding to the above Content fields. */
+#define MIME_HDR_TYPE "Content-Type"
+#define MIME_HDR_ENCODING "Content-Transfer-Encoding"
+#define MIME_HDR_DISPOSITION "Content-Disposition"
+#define MIME_HDR_ID "Content-ID"
+#define MIME_HDR_DESCRIPTION "Content-Description"
+#define MIME_HDR_VERSION "MIME-Version"
+/* the value of the MIME-Version field */
+#define MIME_VERSION "1.0"
+
+typedef enum {
+ ATTACH_INVALID = 0, /* do not use! */
+ ATTACH_FNAME = 1,
+ ATTACH_MSG = 2,
+ ATTACH_FILENO = 3
+} attach_t;
+
+/*
+ * Structure of a MIME attachment.
+ */
+struct attachment {
+ struct attachment *a_flink; /* Forward link in list. */
+ struct attachment *a_blink; /* Backward list link */
+
+ attach_t a_type; /* attachment type */
+#if 1
+ union {
+ char *u_name; /* file name */
+ struct message *u_msg; /* message */
+ int u_fileno; /* file number */
+ } a_u;
+
+ #define a_name a_u.u_name
+ #define a_msg a_u.u_msg
+ #define a_fileno a_u.u_fileno
+#else
+ char *a_name; /* file name */
+ struct message *a_msg; /* message */
+ int a_fileno; /* file number */
+#endif
+
+ struct Content a_Content; /* MIME content strings */
+};
+#endif /* MIME_SUPPORT */
+
+/*
+ * Structure used to pass about the current
+ * state of the user-typed message header.
+ */
+
+struct header {
+ struct name *h_to; /* Dynamic "To:" string */
+ char *h_subject; /* Subject string */
+ struct name *h_cc; /* Carbon copies string */
+ struct name *h_bcc; /* Blind carbon copies */
+ struct name *h_smopts; /* Sendmail options */
+ char *h_in_reply_to; /* In-Reply-To: field */
+ struct name *h_references; /* References: field */
+ struct name *h_extra; /* extra header fields */
+#ifdef MIME_SUPPORT
+ char *h_mime_boundary; /* MIME multipart boundary string */
+ struct Content h_Content; /* MIME content for message */
+ struct attachment *h_attach; /* MIME attachments */
+#endif
+};
+
+/*
+ * Structure of namelist nodes used in processing
+ * the recipients of mail and aliases and all that
+ * kind of stuff.
+ */
+
+struct name {
+ struct name *n_flink; /* Forward link in list. */
+ struct name *n_blink; /* Backward list link */
+ short n_type; /* From which list it came */
+ char *n_name; /* This fella's name */
+};
+
+/*
+ * Structure of a variable node. All variables are
+ * kept on a singly-linked list of these, rooted by
+ * "variables"
+ */
+
+struct var {
+ struct var *v_link; /* Forward link to next variable */
+ char *v_name; /* The variable's name */
+ char *v_value; /* And its current value */
+};
+
+struct group {
+ struct group *ge_link; /* Next person in this group */
+ char *ge_name; /* This person's user name */
+};
+
+struct grouphead {
+ struct grouphead *g_link; /* Next grouphead in list */
+ char *g_name; /* Name of this group */
+ struct group *g_list; /* Users in group. */
+};
+
+struct smopts_s {
+ struct smopts_s *s_link; /* Link to next smopts_s in list */
+ char *s_name; /* Name of this smopts_s */
+ struct name *s_smopts; /* sendmail options name list */
+};
+
+/*
+ * Structure of the hash table of ignored header fields
+ */
+struct ignoretab {
+ size_t i_count; /* Number of entries */
+ struct ignore {
+ struct ignore *i_link; /* Next ignored field in bucket */
+ char *i_field; /* This ignored field */
+ } *i_head[HSHSIZE];
+};
+
+/*
+ * Constants for conditional commands. These control whether we
+ * should be executing commands or not.
+ */
+struct cond_stack_s {
+ struct cond_stack_s *c_next;
+ int c_cond;
+};
+#define CNONE 0x00 /* Execute everything */
+#define CSKIP 0x01 /* Do not execute commands */
+#define CIF 0x02 /* Inside if/endif block */
+#define CELSE 0x04 /* The last conditional was else */
+#define CIGN 0x08 /* Conditional in a skipped block */
+
+enum mailmode_e {
+ mm_receiving, /* receiving mail mode */
+ mm_sending, /* sending mail mode */
+ mm_hdrsonly /* headers only mode */
+};
+
+/*
+ * Truncate a file to the last character written. This is
+ * useful just before closing an old file that was opened
+ * for read/write.
+ */
+#define trunc(stream) { \
+ (void)fflush(stream); \
+ (void)ftruncate(fileno(stream), (off_t)ftell(stream)); \
+}
+
+/*
+ * White Space (WSP) as specified in see RFC 2822.
+ *
+ * NOTE: Use this in place of isblank() so it is inline. Also, unlike
+ * the table implemented ctype(3) routines, this does not have input
+ * range issues caused by sign extensions.
+ *
+ * See mime_header.h for the related is_FWS().
+ */
+static inline int
+is_WSP(int c)
+{
+ return c == ' ' || c == '\t';
+}
+
+static inline char *
+skip_WSP(const char *cp)
+{
+ while (is_WSP(*cp))
+ cp++;
+ return __UNCONST(cp);
+}
+
+static inline char *
+skip_space(char *p)
+{
+ while (isspace((unsigned char)*p))
+ p++;
+ return p;
+}
+
+/*
+ * strip trailing white space
+ */
+static inline char *
+strip_WSP(char *line)
+{
+ char *cp;
+
+ cp = line + strlen(line) - 1;
+ while (cp >= line && is_WSP(*cp))
+ cp--;
+ *++cp = '\0';
+ return cp;
+}
+
+#endif /* __DEF_H__ */
--- /dev/null
+/* $NetBSD: extern.h,v 1.33 2014/12/16 19:30:24 christos Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)extern.h 8.2 (Berkeley) 4/20/95
+ * $NetBSD: extern.h,v 1.33 2014/12/16 19:30:24 christos Exp $
+ */
+
+#ifndef __EXTERN_H__
+#define __EXTERN_H__
+
+/*
+ * from cmd1.c
+ */
+int More(void *);
+int Type(void *);
+int folders(void *);
+int from(void *);
+int headers(void *);
+int inc(void *);
+int mboxit(void *);
+int more(void *);
+int pcmdlist(void *);
+int pdot(void *);
+int pipecmd(void *);
+int scroll(void *);
+int stouch(void *);
+int top(void *);
+int type(void *);
+#ifdef MIME_SUPPORT
+int page(void *);
+int Page(void *);
+int print(void *);
+int Print(void *);
+int view(void *);
+int View(void *);
+#endif
+/* XXX - should these be elsewhere? */
+void printhead(int);
+char * sget_msgnum(struct message *, struct message *);
+void show_msgnum(FILE *, struct message *, struct message *);
+
+/*
+ * from cmd2.c
+ */
+int Detach(void *);
+int Save(void *);
+int clobber(void *);
+int copycmd(void *);
+int core(void *);
+int delete(void *);
+int deltype(void *);
+int detach(void *);
+int igfield(void *);
+int next(void *);
+int retfield(void *);
+int save(void *);
+int saveigfield(void *);
+int saveretfield(void *);
+int swrite(void *);
+int undeletecmd(void *);
+
+/*
+ * from cmd3.c
+ */
+int Respond(void *);
+int alternates(void *);
+int bounce(void *);
+int dosh(void *);
+int echo(void *);
+int elsecmd(void *);
+int endifcmd(void *);
+int file(void *);
+int bounce(void *);
+int forward(void *);
+int group(void *);
+int help(void *);
+int ifcmd(void *);
+int ifdefcmd(void *v);
+int ifndefcmd(void *v);
+int markread(void *);
+int messize(void *);
+int null(void *);
+int preserve(void *);
+int respond(void *);
+int rexit(void *);
+int schdir(void *);
+int set(void *);
+int shell(void *);
+int show(void *);
+int unalias(void *);
+int unread(void *);
+int unset(void *);
+/* XXX - Should this be elsewhere? */
+void sort(const char **);
+
+/*
+ * from cmd4.c
+ */
+struct smopts_s *findsmopts(const char *, int);
+int smoptscmd(void *);
+int unsmoptscmd(void *);
+int Header(void *);
+
+/*
+ * from cmdtab.c
+ */
+extern const struct cmd cmdtab[];
+
+/*
+ * from collect.c
+ */
+FILE * collect(struct header *, int);
+void savedeadletter(FILE *);
+
+/*
+ * from dotlock.c
+ */
+int dot_lock(const char *, int, FILE *, const char *);
+void dot_unlock(const char *);
+
+/*
+ * from edit.c
+ */
+int editor(void *);
+int visual(void *);
+FILE * run_editor(FILE *, off_t, int, int);
+
+/*
+ * from fio.c
+ */
+const char *expand(const char *);
+off_t fsize(FILE *);
+const char *getdeadletter(void);
+int getfold(char *, size_t);
+#ifdef USE_EDITLINE
+#define readline xreadline /* readline() is defined in libedit */
+#endif
+int readline(FILE *, char *, int, int);
+int putline(FILE *, const char *, int);
+int rm(char *);
+FILE * setinput(const struct message *);
+void setptr(FILE *, off_t);
+
+/*
+ * from getname.c
+ */
+const char *getname(uid_t);
+int getuserid(char []);
+
+/*
+ * from head.c
+ */
+int ishead(const char []);
+void parse(const char [], struct headline *, char []);
+
+/*
+ * from lex.c
+ */
+void announce(void);
+void commands(void);
+enum execute_contxt_e { ec_normal, ec_composing, ec_autoprint };
+int execute(char [], enum execute_contxt_e);
+int incfile(void);
+const struct cmd *lex(char []);
+void load(const char *);
+int newfileinfo(int);
+int pversion(void *);
+int setfile(const char *);
+char * shellpr(char *);
+char * get_cmdname(char *);
+
+/*
+ * from list.c
+ */
+int first(int, int);
+int get_Hflag(char **);
+int getmsglist(char *, int *, int);
+int getrawlist(const char [], char **, int);
+int show_headers_and_exit(int) __dead;
+
+/*
+ * from main.c
+ */
+struct name *lexpand(char *, int);
+void setscreensize(void);
+int main(int, char **);
+
+/*
+ * from names.c
+ */
+struct name *cat(struct name *, struct name *);
+int count(struct name *);
+struct name *delname(struct name *, char []);
+char * detract(struct name *, int);
+struct name * elide(struct name *);
+struct name * extract(char [], int);
+struct name * gexpand(struct name *, struct grouphead *, int, int);
+struct name * nalloc(char [], int);
+struct name * outof(struct name *, FILE *, struct header *);
+const char ** unpack(struct name *, struct name *);
+struct name * usermap(struct name *);
+#if 0
+void prettyprint(struct name *); /* commented out? */
+#endif
+
+/*
+ * from popen.c
+ */
+int Fclose(FILE *);
+FILE * Fdopen(int, const char *);
+FILE * Fopen(const char *, const char *);
+int Pclose(FILE *);
+FILE * Popen(const char *, const char *);
+void close_all_files(void);
+void close_top_files(FILE *);
+void free_child(int);
+void prepare_child(sigset_t *, int, int);
+FILE * last_registered_file(int);
+void register_file(FILE *, int, int);
+int run_command(const char *, sigset_t *, int, int, ...);
+void sigchild(int);
+int start_command(const char *, sigset_t *, int, int, ...);
+int wait_child(int);
+#ifdef MIME_SUPPORT
+void flush_files(FILE *, int);
+#endif
+
+/*
+ * from quit.c
+ */
+void quit(jmp_buf);
+int quitcmd(void *);
+
+/*
+ * from send.c
+ */
+#ifndef MIME_SUPPORT
+# define sendmessage(a,b,c,d,e) legacy_sendmessage(a,b,c,d)
+# define mail(a,b,c,d,e,f) legacy_mail(a,b,c,d,e)
+#endif
+int sendmessage(struct message *, FILE *, struct ignoretab *, const char *, struct mime_info *);
+int mail(struct name *, struct name *, struct name *, struct name *, char *, struct attachment *);
+void mail1(struct header *, int);
+void mail2(FILE *, const char **);
+int puthead(struct header *, FILE *, int);
+int sendmail(void *);
+
+/*
+ * from strings.c
+ */
+void * csalloc(size_t, size_t);
+void * salloc(size_t);
+void sreset(void);
+void spreserve(void);
+
+/*
+ * from support.c
+ */
+void add_ignore(const char *, struct ignoretab *);
+void alter(char *);
+int argcount(char **);
+int blankline(char []);
+char * copy(char *, char *);
+char * hfield(const char [], const struct message *);
+int isdir(const char []);
+int isign(const char *, struct ignoretab []);
+void istrcpy(char *, const char *);
+int member(char *, struct ignoretab *);
+char * nameof(struct message *, int);
+int sasprintf(char **ret, const char *format, ...) __printflike(2, 3);
+char * savestr(const char *);
+struct message *set_m_flag(int, int, int);
+char * skin(char *);
+int source(void *);
+void touch(struct message *);
+int unstack(void);
+int upcase(int);
+void cathelp(const char *);
+
+/*
+ * from temp.c
+ */
+void tinit(void);
+
+/*
+ * from tty.c
+ */
+int grabh(struct header *, int);
+
+/*
+ * from vars.c
+ */
+void assign(const char [], const char []);
+struct grouphead * findgroup(const char []);
+int hash(const char *);
+struct var * lookup(const char []);
+void printgroup(const char []);
+void v_free(char *);
+char * value(const char []);
+char * vcopy(const char []);
+
+/*
+ * from v7.local.c
+ */
+void demail(void);
+void findmail(const char *, char *, size_t);
+const char *username(void);
+
+/*
+ * from version.c
+ */
+extern const char *version;
+
+
+#ifndef THREAD_SUPPORT
+/*
+ * Specials from fio.c (if THREAD_SUPPORT is not defined).
+ * With THREAD_SUPPORT, they live in thread.c.
+ */
+struct message *next_message(struct message *);
+struct message *prev_message(struct message *);
+struct message *get_message(int);
+int get_msgnum(struct message *);
+int get_msgCount(void);
+
+/* we remap these commands */
+# define get_abs_msgCount get_msgCount
+# define get_abs_message(a) get_message(a)
+# define next_abs_message(a) next_message(a)
+
+/* we trash these commands */
+# define do_recursion() 0
+# define thread_recursion(mp,fn,args) fn(mp,args)
+# define thread_fix_old_links(nmessage,message,omsgCount)
+# define thread_fix_new_links(message,omsgCount,msgCount)
+#endif /* THREAD_SUPPORT */
+
+#endif /* __EXTERN_H__ */
--- /dev/null
+/* $NetBSD: head.c,v 1.24 2013/01/16 15:21:42 christos Exp $ */
+
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)head.c 8.2 (Berkeley) 4/20/95";
+#else
+__RCSID("$NetBSD: head.c,v 1.24 2013/01/16 15:21:42 christos Exp $");
+#endif
+#endif /* not lint */
+
+#include "rcv.h"
+#include "extern.h"
+
+/*
+ * Mail -- a mail program
+ *
+ * Routines for processing and detecting headlines.
+ */
+
+/*
+ * Match the given string (cp) against the given template (tp).
+ * Return 1 if they match, 0 if they don't
+ */
+static int
+cmatch(const char *cp, const char *tp)
+{
+
+ while (*cp && *tp)
+ switch (*tp++) {
+ case 'a':
+ if (!islower((unsigned char)*cp++))
+ return 0;
+ break;
+ case 'A':
+ if (!isupper((unsigned char)*cp++))
+ return 0;
+ break;
+ case ' ':
+ if (*cp++ != ' ')
+ return 0;
+ break;
+ case '0':
+ if (!isdigit((unsigned char)*cp++))
+ return 0;
+ break;
+ case 'O':
+ if (*cp != ' ' && !isdigit((unsigned char)*cp))
+ return 0;
+ cp++;
+ break;
+ case ':':
+ if (*cp++ != ':')
+ return 0;
+ break;
+ case 'N':
+ if (*cp++ != '\n')
+ return 0;
+ break;
+ case '+':
+ if (*cp != '+' && *cp != '-')
+ return 0;
+ cp++;
+ break;
+ }
+ if (*cp || *tp)
+ return 0;
+ return 1;
+}
+
+/*
+ * Test to see if the passed string is a ctime(3) generated
+ * date string as documented in the manual. The template
+ * below is used as the criterion of correctness.
+ * Also, we check for a possible trailing time zone using
+ * the tmztype template.
+ */
+
+/*
+ * 'A' An upper case char
+ * 'a' A lower case char
+ * ' ' A space
+ * '0' A digit
+ * 'O' An optional digit or space
+ * ':' A colon
+ * 'N' A new line
+ * '+' A plus or minus sign
+ */
+static struct cmatch_data {
+ size_t tlen;
+ char const *tdata;
+} const cmatch_data[] = {
+#define TSZ(a) (sizeof(a) - 1), a
+ { TSZ("Aaa Aaa O0 00:00:00 0000") }, /* BSD ctype */
+ { TSZ("Aaa Aaa O0 00:00 0000") }, /* SysV ctype */
+ { TSZ("Aaa Aaa O0 00:00:00 AAA 0000") }, /* BSD tmztype */
+ { TSZ("Aaa Aaa O0 00:00 AAA 0000") }, /* SysV tmztype */
+ /*
+ * RFC 822-alike From_ lines do not conform to RFC 4155, but seem to
+ * be used in the wild by UW-imap (MBX format plus)
+ */
+ { TSZ("Aaa Aaa O0 00:00:00 0000 +0000") }, /* RFC822, UT offset */
+ /*
+ * RFC 822 with zone spec:
+ * 1. military,
+ * 2. UT,
+ * 3. north america time zone strings
+ * note that 1. is strictly speaking not correct as some letters are
+ * not used
+ */
+ { TSZ("Aaa Aaa O0 00:00:00 0000 A") },
+ { TSZ("Aaa Aaa O0 00:00:00 0000 AA") },
+ { TSZ("Aaa Aaa O0 00:00:00 0000 AAA") },
+ { 0, NULL },
+};
+
+static int
+isdate(const char date[])
+{
+ static size_t cmatch_minlen = 0;
+ struct cmatch_data const *cmdp;
+ size_t dl = strlen(date);
+
+ if (cmatch_minlen == 0)
+ for (cmdp = cmatch_data; cmdp->tdata != NULL; ++cmdp)
+ cmatch_minlen = MIN(cmatch_minlen, cmdp->tlen);
+
+ if (dl < cmatch_minlen)
+ return 0;
+
+ for (cmdp = cmatch_data; cmdp->tdata != NULL; ++cmdp)
+ if (dl == cmdp->tlen && cmatch(date, cmdp->tdata))
+ return 1;
+
+ return 0;
+}
+
+static void
+fail(const char linebuf[], const char reason[])
+{
+#ifndef FMT_PROG
+ if (debug)
+ (void)fprintf(stderr, "\"%s\"\nnot a header because %s\n",
+ linebuf, reason);
+#endif
+}
+
+/*
+ * Collect a liberal (space, tab delimited) word into the word buffer
+ * passed. Also, return a pointer to the next word following that,
+ * or NULL if none follow.
+ */
+static const char *
+nextword(const char *wp, char *wbuf)
+{
+ if (wp == NULL) {
+ *wbuf = 0;
+ return NULL;
+ }
+ while (*wp && !is_WSP(*wp)) {
+ *wbuf++ = *wp;
+ if (*wp++ == '"') {
+ while (*wp && *wp != '"')
+ *wbuf++ = *wp++;
+ if (*wp == '"')
+ *wbuf++ = *wp++;
+ }
+ }
+ *wbuf = '\0';
+ wp = skip_WSP(wp);
+ if (*wp == '\0')
+ return NULL;
+ return wp;
+}
+
+/*
+ * Copy the string on the left into the string on the right
+ * and bump the right (reference) string pointer by the length.
+ * Thus, dynamically allocate space in the right string, copying
+ * the left string into it.
+ */
+static char *
+copyin(const char *src, char **space)
+{
+ char *cp;
+ char *begin;
+
+ begin = cp = *space;
+ while ((*cp++ = *src++) != '\0')
+ continue;
+ *space = cp;
+ return begin;
+}
+
+/*
+ * Split a headline into its useful components.
+ * Copy the line into dynamic string space, then set
+ * pointers into the copied line in the passed headline
+ * structure. Actually, it scans.
+ *
+ * XXX - line[], pbuf[], and word[] must be LINESIZE in length or
+ * overflow can occur in nextword() or copyin().
+ */
+PUBLIC void
+parse(const char line[], struct headline *hl, char pbuf[])
+{
+ const char *cp;
+ char *sp;
+ char word[LINESIZE];
+
+ hl->l_from = NULL;
+ hl->l_tty = NULL;
+ hl->l_date = NULL;
+ cp = line;
+ sp = pbuf;
+ /*
+ * Skip over "From" first.
+ */
+ cp = nextword(cp, word);
+ cp = nextword(cp, word);
+ if (*word)
+ hl->l_from = copyin(word, &sp);
+ if (cp != NULL && cp[0] == 't' && cp[1] == 't' && cp[2] == 'y') {
+ cp = nextword(cp, word);
+ hl->l_tty = copyin(word, &sp);
+ }
+ if (cp != NULL)
+ hl->l_date = copyin(cp, &sp);
+}
+
+/*
+ * See if the passed line buffer is a mail header.
+ * Return true if yes. Note the extreme pains to
+ * accommodate all funny formats.
+ */
+PUBLIC int
+ishead(const char linebuf[])
+{
+ const char *cp;
+ struct headline hl;
+ char parbuf[LINESIZE];
+
+ cp = linebuf;
+ if (*cp++ != 'F' || *cp++ != 'r' || *cp++ != 'o' || *cp++ != 'm' ||
+ *cp++ != ' ')
+ return 0;
+ parse(linebuf, &hl, parbuf);
+ if (hl.l_from == NULL || hl.l_date == NULL) {
+ fail(linebuf, "No from or date field");
+ return 0;
+ }
+ if (!isdate(hl.l_date)) {
+ fail(linebuf, "Date field not legal date");
+ return 0;
+ }
+ /*
+ * I guess we got it!
+ */
+ return 1;
+}
--- /dev/null
+/* $NetBSD: pathnames.h,v 1.8 2006/11/28 18:45:32 christos Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)pathnames.h 8.1 (Berkeley) 6/6/93
+ * $NetBSD: pathnames.h,v 1.8 2006/11/28 18:45:32 christos Exp $
+ */
+
+#ifndef __PATHNAMES_H__
+#define __PATHNAMES_H__
+
+#include <paths.h>
+
+#define _PATH_EX "/usr/bin/ex"
+#define _PATH_HELP "/usr/share/misc/mail.help"
+#define _PATH_TILDE "/usr/share/misc/mail.tildehelp"
+#define _PATH_MASTER_RC "/etc/mail.rc"
+#define _PATH_MORE "/usr/bin/more"
+#ifdef MIME_SUPPORT
+#define _PATH_FILE "/usr/bin/file" /* Used to get mime type/subtype */
+#endif
+
+#endif /* __PATHNAMES_H__ */
--- /dev/null
+/* $NetBSD: rcv.h,v 1.7 2006/11/28 18:45:32 christos Exp $ */
+
+/*
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)rcv.h 8.1 (Berkeley) 6/6/93
+ * $NetBSD: rcv.h,v 1.7 2006/11/28 18:45:32 christos Exp $
+ */
+
+/*
+ * Mail -- a mail program
+ *
+ * This file is included by normal files which want both
+ * globals and declarations.
+ */
+
+#ifndef __RCV_H__
+#define __RCV_H__
+
+#include "def.h"
+#include "glob.h"
+
+#endif /* __RCV_H__ */