fmt, as modified after using insight(1) at Myrias. There is some

architecture-specific code added.
This commit is contained in:
gdr 1997-09-21 22:12:27 +00:00
parent 5ea6ce9244
commit a739102c3a
8 changed files with 1042 additions and 53 deletions

24
usr.bin/fmt/Makefile Normal file
View File

@ -0,0 +1,24 @@
#
# $Id: Makefile,v 1.1 1997/09/21 22:12:26 gdr Exp $
#
include ../../../paths.mk
include ../../constants.mk
BUILD_TARGET = $(BUILD_DIR)/fmt
CPPFLAGS += -I../../hdr
build: setup $(BUILD_TARGET)
$(BUILD_TARGET): $(OBJS)
$(CC) -o $@ $(LDFLAGS) $(OBJS) $(LDLIBS)
install:
$(INSTALL) -m755 -d $(INSTROOT)/$(BUILD_DIR)/install
$(INSTALL) -m755 $(BUILD_TARGET) $(INSTROOT)/$(BUILD_DIR)/install
$(INSTALL) -m644 fmt.README $(INSTROOT)/$(BUILD_DIR)/install
clobber::
$(RM) -f *~
include ../../rules.mk
-include $(BUILD_DIR)/dependencies

276
usr.bin/fmt/def.h Normal file
View File

@ -0,0 +1,276 @@
/*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. 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.2 (Berkeley) 3/21/94
*/
/*
* Mail -- a mail program
*
* Author: Kurt Shoens (UCB) March 25, 1978
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <signal.h>
#include <sgtty.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "pathnames.h"
#define APPEND /* New mail goes to end of mailbox */
#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 STRINGSIZE ((unsigned) 128)/* Dynamic allocation units */
#define MAXARGC 1024 /* Maximum list of raw strings */
#define NOSTR ((char *) 0) /* Null string pointer */
#define MAXEXP 25 /* Maximum expansion of aliases */
#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_size; /* Bytes in the message */
long m_lines; /* Lines in the message */
};
/*
* 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 MODIFY (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 */
/*
* Given a file address, determine the block number it represents.
*/
#define blockof(off) ((int) ((off) / 4096))
#define offsetof(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 {
char *c_name; /* Name of command */
int (*c_func)(); /* Implementor of the command */
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 040 /* Autoprint dot after command */
#define I 0100 /* Interactive command bit */
#define M 0200 /* Legal from send mode bit */
#define W 0400 /* Illegal when read only bit */
#define F 01000 /* Is a conditional command */
#define T 02000 /* Is a transparent command */
#define R 04000 /* Cannot be called from collect */
/*
* 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 1 /* Grab To: line */
#define GSUBJECT 2 /* Likewise, Subject: line */
#define GCC 4 /* And the Cc: line */
#define GBCC 8 /* And also the Bcc: line */
#define GMASK (GTO|GSUBJECT|GCC|GBCC)
/* Mask of places from whence */
#define GNL 16 /* Print blank line after */
#define GDEL 32 /* Entity removed from list */
#define GCOMMA 64 /* detract puts in commas */
/*
* 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 */
};
/*
* 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 it's 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. */
};
#define NIL ((struct name *) 0) /* The nil pointer for namelists */
#define NONE ((struct cmd *) 0) /* The nil pointer to command tab */
#define NOVAR ((struct var *) 0) /* The nil pointer to variables */
#define NOGRP ((struct grouphead *) 0)/* The nil grouphead pointer */
#define NOGE ((struct group *) 0) /* The nil group pointer */
/*
* Structure of the hash table of ignored header fields
*/
struct ignoretab {
int 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];
};
/*
* Token values returned by the scanner used for argument lists.
* Also, sizes of scanner-related things.
*/
#define TEOL 0 /* End of the command line */
#define TNUMBER 1 /* A message number */
#define TDASH 2 /* A simple dash */
#define TSTRING 3 /* A string (possibly containing -) */
#define TDOT 4 /* A "." */
#define TUP 5 /* An "^" */
#define TDOLLAR 6 /* A "$" */
#define TSTAR 7 /* A "*" */
#define TOPEN 8 /* An '(' */
#define TCLOSE 9 /* A ')' */
#define TPLUS 10 /* A '+' */
#define TERROR 11 /* A lexical error */
#define REGDEP 2 /* Maximum regret depth. */
#define STRINGLEN 1024 /* Maximum length of string token */
/*
* Constants for conditional commands. These describe whether
* we should be executing stuff or not.
*/
#define CANY 0 /* Execute in send or receive mode */
#define CRCV 1 /* Execute in receive mode only */
#define CSEND 2 /* Execute in send mode only */
/*
* Kludges to handle the change from setexit / reset to setjmp / longjmp
*/
#define setexit() setjmp(srbuf)
#define reset(x) longjmp(srbuf, x)
/*
* 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), (long)ftell(stream)); \
}

261
usr.bin/fmt/extern.h Normal file
View File

@ -0,0 +1,261 @@
/*-
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. 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.1 (Berkeley) 6/6/93
*/
#ifndef __P
#ifdef __STDC__
#define __P(a) a
#else
#define __P(a) ()
#endif
#endif
struct name *cat __P((struct name *, struct name *));
struct name *delname __P((struct name *, char []));
struct name *elide __P((struct name *));
struct name *extract __P((char [], int));
struct name *gexpand __P((struct name *, struct grouphead *, int, int));
struct name *nalloc __P((char [], int));
struct name *outof __P((struct name *, FILE *, struct header *));
struct name *put __P((struct name *, struct name *));
struct name *tailof __P((struct name *));
struct name *usermap __P((struct name *));
FILE *Fdopen __P((int, char *));
FILE *Fopen __P((char *, char *));
FILE *Popen __P((char *, char *));
FILE *collect __P((struct header *, int));
char *copy __P((char *, char *));
char *copyin __P((char *, char **));
char *detract __P((struct name *, int));
char *expand __P((char *));
char *getdeadletter __P((void));
char *getname __P((int));
char *hfield __P((char [], struct message *));
FILE *infix __P((struct header *, FILE *));
char *ishfield __P((char [], char[], char *));
char *name1 __P((struct message *, int));
char *nameof __P((struct message *, int));
char *nextword __P((char *, char *));
char *readtty __P((char [], char []));
char *reedit __P((char *));
FILE *run_editor __P((FILE *, off_t, int, int));
char *salloc __P((int));
char *savestr __P((char *));
FILE *setinput __P((struct message *));
char *skin __P((char *));
char *skip_comment __P((char *));
char *snarf __P((char [], int *));
char *username __P((void));
char *value __P((char []));
char *vcopy __P((char []));
char *yankword __P((char *, char []));
int Fclose __P((FILE *));
int More __P((int *));
int Pclose __P((FILE *));
int Respond __P((int *));
int Type __P((int *));
int _Respond __P((int []));
int _respond __P((int *));
void alter __P((char *));
int alternates __P((char **));
void announce __P((void));
int anyof __P((char *, char *));
int append __P((struct message *, FILE *));
int argcount __P((char **));
void assign __P((char [], char []));
int bangexp __P((char *));
int blankline __P((char []));
void brokpipe __P((int));
int charcount __P((char *, int));
int check __P((int, int));
void clob1 __P((int));
int clobber __P((char **));
void close_all_files __P((void));
int cmatch __P((char *, char *));
void collhup __P((int));
void collint __P((int));
void collstop __P((int));
void commands __P((void));
int copycmd __P((char []));
int core __P((void));
int count __P((struct name *));
int delete __P((int []));
int delm __P((int []));
int deltype __P((int []));
void demail __P((void));
int diction __P((const void *, const void *));
int dosh __P((char *));
int echo __P((char **));
int edit1 __P((int *, int));
int editor __P((int *));
void edstop __P((void));
int elsecmd __P((void));
int endifcmd __P((void));
int evalcol __P((int));
int execute __P((char [], int));
int exwrite __P((char [], FILE *, int));
void fail __P((char [], char []));
int file __P((char **));
struct grouphead *
findgroup __P((char []));
void findmail __P((char *, char *));
int first __P((int, int));
void fixhead __P((struct header *, struct name *));
void fmt __P((char *, struct name *, FILE *, int));
int folders __P((void));
int forward __P((char [], FILE *, int));
void free_child __P((int));
int from __P((int *));
off_t fsize __P((FILE *));
int getfold __P((char *));
int gethfield __P((FILE *, char [], int, char **));
int getmsglist __P((char *, int *, int));
int getrawlist __P((char [], char **, int));
int getuserid __P((char []));
int grabh __P((struct header *, int));
int group __P((char **));
void hangup __P((int));
int hash __P((char *));
void hdrstop __P((int));
int headers __P((int *));
int help __P((void));
void holdsigs __P((void));
int ifcmd __P((char **));
int igcomp __P((const void *, const void *));
int igfield __P((char *[]));
int ignore1 __P((char *[], struct ignoretab *, char *));
int igshow __P((struct ignoretab *, char *));
void intr __P((int));
int isdate __P((char []));
int isdir __P((char []));
int isfileaddr __P((char *));
int ishead __P((char []));
int isign __P((char *, struct ignoretab []));
int isprefix __P((char *, char *));
void istrcpy __P((char *, char *));
struct cmd *
lex __P((char []));
void load __P((char *));
struct var *
lookup __P((char []));
int mail __P((struct name *,
struct name *, struct name *, struct name *, char *));
void mail1 __P((struct header *, int));
void makemessage __P((FILE *));
void mark __P((int));
int markall __P((char [], int));
int matchsender __P((char *, int));
int matchsubj __P((char *, int));
int mboxit __P((int []));
int member __P((char *, struct ignoretab *));
void mesedit __P((FILE *, int));
void mespipe __P((FILE *, char []));
int messize __P((int *));
int metamess __P((int, int));
int more __P((int *));
int newfileinfo __P((void));
int next __P((int *));
int null __P((int));
void panic __P((const char *, ...));
void parse __P((char [], struct headline *, char []));
int pcmdlist __P((void));
int pdot __P((void));
void prepare_child __P((int, int, int));
int preserve __P((int *));
void prettyprint __P((struct name *));
void printgroup __P((char []));
void printhead __P((int));
int puthead __P((struct header *, FILE *, int));
int putline __P((FILE *, char *));
int pversion __P((int));
void quit __P((void));
int quitcmd __P((void));
int raise __P((int));
int readline __P((FILE *, char *, int));
void register_file __P((FILE *, int, int));
void regret __P((int));
void relsesigs __P((void));
int respond __P((int *));
int retfield __P((char *[]));
int rexit __P((int));
int rm __P((char *));
int run_command __P((char *, int, int, int, char *, char *, char *));
int save __P((char []));
int save1 __P((char [], int, char *, struct ignoretab *));
void savedeadletter __P((FILE *));
int saveigfield __P((char *[]));
int savemail __P((char [], FILE *));
int saveretfield __P((char *[]));
int scan __P((char **));
void scaninit __P((void));
int schdir __P((char **));
int screensize __P((void));
int scroll __P((char []));
int send __P((struct message *, FILE *, struct ignoretab *, char *));
int sendmail __P((char *));
int set __P((char **));
int setfile __P((char *));
void setmsize __P((int));
void setptr __P((FILE *));
void setscreensize __P((void));
int shell __P((char *));
void sigchild __P((int));
void sort __P((char **));
int source __P((char **));
void spreserve __P((void));
void sreset __P((void));
int start_command __P((char *, int, int, int, char *, char *, char *));
void statusput __P((struct message *, FILE *, char *));
void stop __P((int));
int stouch __P((int []));
int swrite __P((char []));
void tinit __P((void));
int top __P((int *));
void touch __P((struct message *));
void ttyint __P((int));
void ttystop __P((int));
int type __P((int *));
int type1 __P((int *, int, int));
int undelete __P((int *));
void unmark __P((int));
char **unpack __P((struct name *));
int unread __P((int []));
void unregister_file __P((FILE *));
int unset __P((char **));
int unstack __P((void));
void vfree __P((char *));
int visual __P((int *));
int wait_child __P((int));
int wait_command __P((int));
int writeback __P((FILE *));

View File

@ -31,59 +31,67 @@
.\"
.\" @(#)fmt.1 8.1 (Berkeley) 6/6/93
.\"
.Dd June 6, 1993
.Dt FMT 1
.Os
.Sh NAME
.Nm fmt
.Nd simple text formatter
.Sh SYNOPSIS
.Nm fmt
.Oo
.Ar goal
.Op Ar maximum
.Oc
.Op name ...
.Sh DESCRIPTION
.Nm Fmt
.\" $Id: fmt.1,v 1.2 1997/09/21 22:12:26 gdr Exp $
.\"
.TH FMT 1 "2 August 1997" "GNO" "Commands and Applications"
.SH NAME
fmt \- simple text formatter
.SH SYNOPSIS
.BR fmt
[
.B -o
.I goal
[
.I maximum
]] [
.B -c
] [
.I "name ..."
]
.SH DESCRIPTION
.BR Fmt
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
.I goal
length
as possible without exceeding the maximum. The
.Ar goal
length defaults
to 65 and the maximum to 75. The spacing at the beginning of the
as possible without exceeding the
.IR maximum .
The
.I goal
length defaults to 65 and the
.I maximum
to 75. The spacing at the beginning of the
input lines is preserved in the output, as are blank lines and
interword spacing.
.Pp
.Nm Fmt
.LP
.BR Fmt
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
.BR ex (1)
editor (e.g.
.Xr vi 1 )
.BR vi (1))
the command
.Pp
.Dl \&!}fmt
.Pp
.nf
\&!}fmt
.fi
will reformat a paragraph,
evening the lines.
.Sh SEE ALSO
.Xr nroff 1 ,
.Xr mail 1
.Sh HISTORY
.SH SEE ALSO
.BR nroff (1),
.BR mail (1)
.SH HISTORY
The
.Nm fmt
command appeared in
.Bx 3 .
.\" .Sh AUTHOR
.\" Kurt Shoens
.\" .br
.\" Liz Allen (added goal length concept)
.Sh BUGS
.BR fmt
command appeared in 4.3BSD.
.SH AUTHOR
Kurt Shoens
.br
Liz Allen (Added goal length concept.)
.br
Devin Reade (Updated for GNO.)
.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.

View File

@ -31,6 +31,10 @@
* SUCH DAMAGE.
*/
#ifdef __GNUC__
#define lint
#endif
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1980, 1993\n\
@ -45,6 +49,43 @@ static char sccsid[] = "@(#)fmt.c 8.1 (Berkeley) 7/20/93";
#include <ctype.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#ifdef SUNOS4
#include "sunos4stdio.h"
#endif
#ifndef __P
#ifdef __STDC__
#define __P(a) a
#else
#define __P(a) ()
#endif
#endif
#define REALLOC my_realloc
static void fmt __P((FILE *fi));
static void prefix __P((char *line));
static void split __P((char *line));
static void setout __P((void));
static void pack __P((char *word, int wl));
static void oflush __P((void));
static void tabulate __P((char *line));
static void leadin __P((void));
static int ispref __P((char *s1, char *s2));
static void *my_realloc __P((void *buf, size_t size));
#if 0
static char *savestr __P((char *str));
#endif
extern int ishead __P((char *));
#if defined(SOLARIS) || defined(HALOS)
#define INDEX(s,c) strchr((s),(c))
#else
#define INDEX index
#endif
/*
* fmt -- format the concatenation of input files or standard input
@ -69,7 +110,6 @@ int pfx; /* Current leading blank count */
int lineno; /* Current input line */
int mark; /* Last place we saw a head line */
char *malloc(); /* for lint . . . */
char *headnames[] = {"To", "Subject", "Cc", 0};
/*
@ -78,6 +118,7 @@ char *headnames[] = {"To", "Subject", "Cc", 0};
* at the end.
*/
int
main(argc, argv)
int argc;
char **argv;
@ -134,6 +175,7 @@ main(argc, argv)
* doing ^H processing, expanding tabs, stripping trailing blanks,
* and sending each line down for analysis.
*/
static void
fmt(fi)
FILE *fi;
{
@ -154,9 +196,11 @@ fmt(fi)
if (cp - linebuf >= lbufsize) {
int offset = cp - linebuf;
lbufsize += CHUNKSIZE;
linebuf = realloc(linebuf, lbufsize);
if(linebuf == 0)
abort();
linebuf = REALLOC(linebuf, lbufsize);
if(linebuf == NULL) {
perror("linebuf allocation failed");
abort();
}
cp = linebuf + offset;
}
if (c == '\b') {
@ -193,15 +237,17 @@ fmt(fi)
col = 0;
cp = linebuf;
cp2 = canonb;
while (cc = *cp++) {
while ((cc = *cp++)) {
if (cc != '\t') {
col++;
if (cp2 - canonb >= cbufsize) {
int offset = cp2 - canonb;
cbufsize += CHUNKSIZE;
canonb = realloc(canonb, cbufsize);
if(canonb == 0)
abort();
canonb = REALLOC(canonb, cbufsize);
if(canonb == 0) {
perror("canob (1) allocation failed");
abort();
}
cp2 = canonb + offset;
}
*cp2++ = cc;
@ -211,9 +257,11 @@ fmt(fi)
if (cp2 - canonb >= cbufsize) {
int offset = cp2 - canonb;
cbufsize += CHUNKSIZE;
canonb = realloc(canonb, cbufsize);
if(canonb == 0)
abort();
canonb = REALLOC(canonb, cbufsize);
if(canonb == 0) {
perror("canob (2) allocation failed");
abort();
}
cp2 = canonb + offset;
}
*cp2++ = ' ';
@ -240,6 +288,7 @@ fmt(fi)
* Finally, if the line minus the prefix is a mail header, try to keep
* it on a line by itself.
*/
static void
prefix(line)
char line[];
{
@ -261,7 +310,7 @@ prefix(line)
*/
if (np != pfx && (np > pfx || abs(pfx-np) > 8))
oflush();
if (h = ishead(cp))
if ((h = ishead(cp)))
oflush(), mark = lineno;
if (lineno - mark < 3 && lineno - mark > 0)
for (hp = &headnames[0]; *hp != (char *) 0; hp++)
@ -287,6 +336,7 @@ prefix(line)
* attached at the end. Pass these words along to the output
* line packer.
*/
static void
split(line)
char line[];
{
@ -316,7 +366,7 @@ split(line)
*/
if (*cp == '\0') {
*cp2++ = ' ';
if (index(".:!", cp[-1]))
if (INDEX(".:!", cp[-1]))
*cp2++ = ' ';
}
while (*cp == ' ')
@ -344,6 +394,7 @@ char *outp; /* Pointer in above */
/*
* Initialize the output section.
*/
static void
setout()
{
outp = NOSTR;
@ -369,6 +420,7 @@ setout()
* pack(word)
* char word[];
*/
static void
pack(word,wl)
char word[];
int wl;
@ -407,6 +459,7 @@ pack(word,wl)
* its way. Set outp to NOSTR to indicate the absence of the current
* line prefix.
*/
static void
oflush()
{
if (outp == NOSTR)
@ -420,6 +473,7 @@ oflush()
* Take the passed line buffer, insert leading tabs where possible, and
* output on standard output (finally).
*/
static void
tabulate(line)
char line[];
{
@ -459,6 +513,7 @@ tabulate(line)
* Initialize the output line with the appropriate number of
* leading blanks.
*/
static void
leadin()
{
register int b;
@ -469,12 +524,13 @@ leadin()
outp = cp;
}
#if 0
/*
* Save a string in dynamic space.
* This little goodie is needed for
* a headline detector in head.c
*/
char *
static char *
savestr(str)
char str[];
{
@ -488,10 +544,12 @@ savestr(str)
strcpy(top, str);
return (top);
}
#endif
/*
* Is s1 a prefix of s2??
*/
static int
ispref(s1, s2)
register char *s1, *s2;
{
@ -500,3 +558,19 @@ ispref(s1, s2)
;
return (*s1 == '\0');
}
/*
* some architectures' reallocs are too damned stupid to accept NULL
* buf arguments ...
*/
static void *
my_realloc (void *buf, size_t size)
{
if (buf == NULL) {
return (void *) malloc(size);
} else {
return (void *) realloc(buf, size);
}
}

258
usr.bin/fmt/head.c Normal file
View File

@ -0,0 +1,258 @@
/*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. 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.
*/
#ifdef __GNUC__
#define lint
#endif
#ifndef lint
static char sccsid[] = "@(#)head.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#include "rcv.h"
#include "extern.h"
/*
* Mail -- a mail program
*
* Routines for processing and detecting headlines.
*/
/*
* See if the passed line buffer is a mail header.
* Return true if yes. Note the extreme pains to
* accomodate all funny formats.
*/
int
ishead(linebuf)
char linebuf[];
{
register char *cp;
struct headline hl;
char parbuf[BUFSIZ];
cp = linebuf;
if (*cp++ != 'F' || *cp++ != 'r' || *cp++ != 'o' || *cp++ != 'm' ||
*cp++ != ' ')
return (0);
parse(linebuf, &hl, parbuf);
if (hl.l_from == NOSTR || hl.l_date == NOSTR) {
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);
}
/*ARGSUSED*/
void
fail(linebuf, reason)
char linebuf[], reason[];
{
/*
if (value("debug") == NOSTR)
return;
fprintf(stderr, "\"%s\"\nnot a header because %s\n", linebuf, reason);
*/
}
/*
* 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.
*/
void
parse(line, hl, pbuf)
char line[], pbuf[];
register struct headline *hl;
{
register char *cp;
char *sp;
char word[LINESIZE];
hl->l_from = NOSTR;
hl->l_tty = NOSTR;
hl->l_date = NOSTR;
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 != NOSTR && cp[0] == 't' && cp[1] == 't' && cp[2] == 'y') {
cp = nextword(cp, word);
hl->l_tty = copyin(word, &sp);
}
if (cp != NOSTR)
hl->l_date = copyin(cp, &sp);
}
/*
* 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.
*/
char *
copyin(src, space)
register char *src;
char **space;
{
register char *cp;
char *top;
top = cp = *space;
while ((*cp++ = *src++))
;
*space = cp;
return (top);
}
/*
* 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
*/
char ctype[] = "Aaa Aaa O0 00:00:00 0000";
char tmztype[] = "Aaa Aaa O0 00:00:00 AAA 0000";
int
isdate(date)
char date[];
{
return cmatch(date, ctype) || cmatch(date, tmztype);
}
/*
* Match the given string (cp) against the given template (tp).
* Return 1 if they match, 0 if they don't
*/
int
cmatch(cp, tp)
register char *cp, *tp;
{
while (*cp && *tp)
switch (*tp++) {
case 'a':
if (!islower(*cp++))
return 0;
break;
case 'A':
if (!isupper(*cp++))
return 0;
break;
case ' ':
if (*cp++ != ' ')
return 0;
break;
case '0':
if (!isdigit(*cp++))
return 0;
break;
case 'O':
if (*cp != ' ' && !isdigit(*cp))
return 0;
cp++;
break;
case ':':
if (*cp++ != ':')
return 0;
break;
case 'N':
if (*cp++ != '\n')
return 0;
break;
}
if (*cp || *tp)
return 0;
return (1);
}
/*
* Collect a liberal (space, tab delimited) word into the word buffer
* passed. Also, return a pointer to the next word following that,
* or NOSTR if none follow.
*/
char *
nextword(wp, wbuf)
register char *wp, *wbuf;
{
register c;
if (wp == NOSTR) {
*wbuf = 0;
return (NOSTR);
}
while ((c = *wp++) && c != ' ' && c != '\t') {
*wbuf++ = c;
if (c == '"') {
while ((c = *wp++) && c != '"')
*wbuf++ = c;
if (c == '"')
*wbuf++ = c;
else
wp--;
}
}
*wbuf = '\0';
for (; c == ' ' || c == '\t'; c = *wp++)
;
if (c == 0)
return (NOSTR);
return (wp - 1);
}

42
usr.bin/fmt/pathnames.h Normal file
View File

@ -0,0 +1,42 @@
/*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. 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
*/
/* #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"

46
usr.bin/fmt/rcv.h Normal file
View File

@ -0,0 +1,46 @@
/*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. 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
*/
/*
* Mail -- a mail program
*
* This file is included by normal files which want both
* globals and declarations.
*/
#include "def.h"
#ifndef SUNOS4
#include "glob.h"
#endif