static char sccsid
[] = "@(#)unixtomh.c 5.1 86/11/25";
* This program copies the mail file in standard unix format
* given as $1 to the file $2 in Rand Message Handler format.
* The change made is to bracket each message with a line
* containing 4 control-A's and to split the From line into
* a From: field and a Date: field, with the date in Arpanet
* This program is designed to be called from the rand mh program
* Set SENDMAIL if you are running sendmail -- this guarantees that
* From: and Date: lines will appear already, and will put the info
* in the UNIX-From line into a Received-From: field.
char *l_from
; /* The name of the sender */
char *l_tty
; /* His tty string (if any) */
char *l_date
; /* The entire date string */
char *savestr(), *copyin(), *copy(), *nextword(), *calloc();
#define NOSTR ((char *) 0)
#define UUCP /* Undo strange uucp naming */
register FILE *inf
, *outf
;
fprintf(stderr
, "Usage: unixtomh name1 name2\n");
if (inf
== NULL
&& (inf
= fopen(argv
[1], "r")) == NULL
) {
if (outf
== NULL
&& (outf
= fopen(argv
[2], "w")) == NULL
) {
while (nullgets(linebuf
, BUFSIZ
, inf
) > 0) {
if (maybe
&& ishead(linebuf
)) {
fputs("\1\1\1\1\n", outf
);
dohead(linebuf
, inf
, outf
);
if (strlen(linebuf
) == 0) {
if (inhdr
&& strcmpn(linebuf
, "Date: ", 6) == 0)
if (inhdr
&& strcmpn(linebuf
, "From: ", 6) == 0)
if (infld
&& isspace(linebuf
[0])) {
if (inhdr
&& !isspace(linebuf
[0])) {
colp
= index(linebuf
, ':');
sp
= index(linebuf
, ' ');
if (colp
== NOSTR
|| sp
== NOSTR
|| sp
< colp
) {
fputs("\1\1\1\1\n", outf
);
fprintf(stderr
, "unixtomh: write: ");
* Get a line from the given file descriptor, don't return the
nullgets(linebuf
, sz
, file
)
} while (c
!= EOF
&& c
!= '\n');
if (c
== EOF
&& cp
== linebuf
+1)
* Output the fields extracted from the From line --
* From: and Date: Untangle UUCP stuff if appropriate.
dohead(line
, infile
, outfile
)
register FILE *infile
, *outfile
;
parse(line
, &hl
, parbuf
);
putdate(hl
.l_date
, outfile
);
if (strcmp(hl
.l_from
, "uucp") == 0) {
if (fgets(linebuf
, BUFSIZ
, infile
) == NULL
)
if (strcmp(word(1, linebuf
), ">From") != 0)
if (strcmp(word(-3, linebuf
), "remote") != 0)
if (strcmp(word(-2, linebuf
), "from") != 0)
strcpy(namebuf
, word(-1, linebuf
));
strcat(namebuf
, word(2, linebuf
));
strcpy(rindex(namebuf
, '!')+1,
strcat(namebuf
, word(2, linebuf
));
fseek(infile
, curoff
, 0);
fprintf(outfile
, "Return-Path: <%s>\n", namebuf
);
fprintf(outfile
, "From: uucp\n");
fprintf(outfile
, "From: %s\n", namebuf
);
fprintf(outfile
, "Return-Path: %s\n", hl
.l_from
);
fprintf(outfile
, "Return-Path: <%s>\n", hl
.l_from
);
fprintf(outfile
, "From: %s\n", hl
.l_from
);
* Return liberal word i from the given string.
* The words are numbered 1, 2, 3, . . . from the left
* and -1, -2, . . . from the right.
secbuf
= (char *) alloca(strlen(str
) + 1);
cp
= word(-index
, secbuf
);
* Skip leading blanks in the string, return
* first liberal word collected.
while (*cp
&& any(*cp
, " \t\n"))
while (*cp
&& !any(*cp
, " \t\n"))
* Reverse the characters in the string in place
register char *cpl
, *cpr
;
* Save a string in dynamic space.
* This little goodie is needed for
* a headline detector in head.c
top
= calloc(strlen(str
) + 1, 1);
fprintf(stderr
, "unixtomh: Ran out of memory\n");
* See if the passed line buffer is a mail header.
* Return true if yes. Note the extreme pains to
* accomodate all funny formats.
if (!isname("From ", cp
, 5))
if (hl
.l_from
== NOSTR
|| hl
.l_date
== NOSTR
) {
fail(linebuf
, "No from or date field");
if (!isdate(hl
.l_date
)) {
fail(linebuf
, "Date field not legal date");
char 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.
* Skip the first "word" of the line, which should be "From"
hl
->l_from
= copyin(word
, &sp
);
if (isname(dp
, "tty", 3)) {
hl
->l_tty
= copyin(word
, &sp
);
hl
->l_date
= copyin(cp
, &sp
);
hl
->l_date
= copyin(dp
, &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.
* See if the two passed strings agree in the first n characters.
* Return true if they do, gnu.
* 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
#define L 1 /* A lower case char */
#define S 2 /* A space */
#define D 3 /* A digit */
#define O 4 /* An optional digit or space */
#define C 5 /* A colon */
#define N 6 /* A new line */
#define U 7 /* An upper case char */
char ctypes
[] = {U
,L
,L
,S
,U
,L
,L
,S
,O
,D
,S
,D
,D
,C
,D
,D
,C
,D
,D
,S
,D
,D
,D
,D
,0};
char tmztypes
[] = {U
,L
,L
,S
,U
,L
,L
,S
,O
,D
,S
,D
,D
,C
,D
,D
,C
,D
,D
,S
,U
,U
,U
,S
,D
,D
,D
,D
,0};
return(cmatch(cp
, tmztypes
));
* Match the given string against the given template.
* Return 1 if they match, 0 if they don't
while (*cp
!= '\0' && *tp
!= 0) {
if (c
!= ' ' && !isdigit(c
))
if (*cp
!= '\0' || *tp
!= 0)
* 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.
if ((cp
= wp
) == NOSTR
) {
while (!any(*cp
, " \t") && *cp
!= '\0')
while (*cp
!= '\0' && *cp
!= '"')
* Copy str1 to str2, return pointer to null in str2.
* Is ch any of the characters in str?
* Convert lower case letters to upper case.
if (c
>= 'a' && c
<= 'z')