v06i039: Elm mail system (elm) Part14/14
sources-request at mirror.UUCP
sources-request at mirror.UUCP
Wed Jul 2 22:14:24 AEST 1986
Submitted by: Dave Taylor <pyramid!hplabs!hpldat!taylor>
Mod.sources: Volume 6, Issue 39
Archive-name: elm/Part14
[ Last time, when MSG was posted, the moderator posted copies of the
documentation. With Dave's cooperation, this time we are making
available laser-printer hardcopy. People in the Northeast corner of
North America can get copies by mailing me their name and postal
address; I will send out a copy, and forward their name on to Dave
so he can maintain a list of users. People in other parts of the
world should send Dave their address; he will add other "regional
distributors" as necessary. --r$ ]
# Continuation of Shell Archive, created by hpldat!taylor
# This is part 14
# To unpack the enclosed files, please use this file as input to the
# Bourne (sh) shell. This can be most easily done by the command;
# sh < thisfilename
if [ ! -d utils ]
then
echo creating directory utils
mkdir utils
fi
# ---------- file utils/readmsg.c ----------
filename="utils/readmsg.c"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file utils/readmsg.c...
fi
cat << 'END-OF-FILE' > $filename
/** readmsg.c **/
/** This routine adds the functionality of the "~r" command to the Elm mail
system while still allowing the user to use the editor of their choice.
The program, without any arguments, tries to read a file in the users home
directory called ".readmsg" (actually defined in the sysdefs.h system
defines file) and if it finds it reads the current message. If it doesn't
find it, it will return a usage error.
The program can also be called with an explicit message number, list of
message numbers, or a string to match in the message (including the header).
NOTE that when you use the string matching option it will match the first
message containing that EXACT (case sensitive) string and then exit.
Changed 5/86 to SORT the input list of message numbers to ensure that
they're in first-to-last order...
Added the "weed" option as the default. This is inspired by the mail
system used at NASA RIACS. If THEY can do it, so can we!!
(C) Copyright 1985, Dave Taylor
**/
#include <stdio.h>
#include <ctype.h>
#include "defs.h"
/** three defines for what level of headers to display **/
#define ALL 1
#define WEED 2
#define NONE 3
static char ident[] = { WHAT_STRING };
#define MAX_LIST 25 /* largest single list of arguments */
#define LAST_MESSAGE 9999 /* last message in list ('$' char) */
#define LAST_CHAR '$' /* char to delimit last message.. */
int read_message[MAX_LIST]; /* list of messages to read */
int messages = 0; /* index into list of messages */
int numcmp(); /* strcmp, but for numbers */
char *words(); /* function defined below... */
#define DONE 0 /* for use with the getopt */
#define ERROR -1 /* library call... */
extern char *optional_arg; /* for parsing the ... */
extern int opt_index; /* .. starting arguments */
main(argc, argv)
int argc;
char *argv[];
{
FILE *file; /* generic file descriptor! */
char filename[SLEN], /* filename buffer */
infile[SLEN], /* input filename */
buffer[SLEN], /* file reading buffer */
string[SLEN]; /* string match buffer */
int current_in_queue = 0, /* these are used for... */
current = 0, /* ...going through msgs */
num, /* for argument parsing */
page_breaks = 0, /* use "^L" breaks?? */
total, /* number of msgs current */
include_headers = WEED, /* flag: include msg header? */
last_message = 0, /* flag: read last message? */
not_in_header = 0, /* flag: in msg header? */
string_match = 0; /* flag: using string match? */
/**** start of the actual program ****/
while ((num = get_options(argc, argv, "nhf:p")) > 0) {
switch (num) {
case 'n' : include_headers = NONE; break;
case 'h' : include_headers = ALL; break;
case 'f' : strcpy(infile, optional_arg); break;
case 'p' : page_breaks++; break;
}
}
if (num == ERROR) {
printf("Usage: %s [-n|-h] [-f filename] [-p] <message list>\n",
argv[0]);
exit(1);
}
/** whip past the starting arguments so that we're pointing
to the right stuff... **/
*argv++; /* past the program name... */
while (opt_index-- > 1) {
*argv++;
argc--;
}
/** now let's figure out the parameters to the program... **/
if (argc == 1) { /* no arguments... called from 'Elm'? */
sprintf(filename, "%s/%s", getenv("HOME"), readmsg_file);
if ((file = fopen(filename, "r")) != NULL) {
fscanf(file, "%d", &(read_message[messages++]));
fclose(file);
}
else { /* no arguments AND no .readmsg file!! */
fprintf(stderr,
"Usage: readmsg [-n|-h] [-f filename] [-p] <message list>\n");
exit(1);
}
}
else if (! isdigit(*argv[0]) && *argv[0] != LAST_CHAR) {
string_match++;
while (*argv)
sprintf(string, "%s%s%s", string, string[0] == '\0'? "" : " ",
*argv++);
}
else { /* list of nums */
while (--argc > 0) {
num = -1;
sscanf(*argv,"%d", &num);
if (num < 0) {
if (*argv[0] == LAST_CHAR) {
last_message++;
num = LAST_MESSAGE;
}
else {
fprintf(stderr,"I don't understand what '%s' means...\n",
*argv);
exit(1);
}
}
else if (num == 0) { /* another way to say "last" */
last_message++;
num = LAST_MESSAGE;
}
*argv++;
read_message[messages++] = num;
}
/** and now sort 'em to ensure they're in a reasonable order... **/
qsort(read_message, messages, sizeof(int), numcmp);
}
/** Now let's get to the mail file... **/
if (strlen(infile) == 0)
sprintf(infile, "%s/%s", mailhome, getenv("LOGNAME"));
if ((file = fopen(infile, "r")) == NULL) {
printf("But you have no mail!\n");
exit(0);
}
/** Now it's open, let's display some 'ole messages!! **/
if (string_match || last_message) { /* pass through it once */
if (last_message) {
total = count_messages(file); /* instantiate count */
for (num=0; num < messages; num++)
if (read_message[num] == LAST_MESSAGE)
read_message[num] = total;
}
else if (string_match)
match_string(file, string); /* stick msg# in list */
if (total == 0 && ! string_match) {
printf("There aren't any messages to read!\n");
exit(0);
}
}
/** now let's have some fun! **/
while (fgets(buffer, SLEN, file) != NULL) {
if (strncmp(buffer, "From ", 5) == 0) {
if (current == read_message[current_in_queue])
current_in_queue++;
if (current_in_queue >= messages)
exit(0);
current++;
if (current == read_message[current_in_queue] && page_breaks
&& current_in_queue > 0)
putchar(FORMFEED);
not_in_header = 0; /* we're in the header! */
}
if ((current == read_message[current_in_queue]))
if (include_headers==ALL || not_in_header)
printf("%s", buffer);
else if (strlen(buffer) < 2) {
not_in_header++;
if (include_headers==WEED)
list_saved_headers();
}
else if (include_headers==WEED)
possibly_save(buffer); /* check to see if we want this */
}
exit(0);
}
int
count_messages(file)
FILE *file;
{
/** Returns the number of messages in the file **/
char buffer[SLEN];
int count = 0;
while (fgets(buffer, SLEN, file) != NULL)
if (strncmp(buffer, "From ", 5) == 0)
count++;
rewind( file );
return( count );
}
match_string(mailfile, string)
FILE *mailfile;
char *string;
{
/** Increment "messages" and put the number of the message
in the message_count[] buffer until we match the specified
string... **/
char buffer[SLEN];
int message_count;
while (fgets(buffer, SLEN, mailfile) != NULL) {
if (strncmp(buffer, "From ", 5) == 0)
message_count++;
if (in_string(buffer, string)) {
read_message[messages++] = message_count;
rewind(mailfile);
return;
}
}
fprintf(stderr,"Couldn't find message containing '%s'\n", string);
exit(1);
}
int
in_string(buffer, pattern)
char *buffer, *pattern;
{
/** Returns TRUE iff pattern occurs IN IT'S ENTIRETY in buffer. **/
register int i = 0, j = 0;
while (buffer[i] != '\0') {
while (buffer[i++] == pattern[j++])
if (pattern[j] == '\0')
return(TRUE);
i = i - j + 1;
j = 0;
}
return(FALSE);
}
int
numcmp(a, b)
int *a, *b;
{
/** compare 'a' to 'b' returning less than, equal, or greater
than, accordingly.
**/
return(*a - *b);
}
static char from[SLEN], subject[SLEN], date[SLEN];
possibly_save(buffer)
char *buffer;
{
/** Check to see what "buffer" is...save it if it looks
interesting... We'll always try to get SOMETHING
by tearing apart the "From " line... **/
if (strncmp(buffer, "Date:", 5) == 0)
strcpy(date, buffer);
else if (strncmp(buffer, "Subject:", 8) == 0)
strcpy(subject,buffer);
else if (strncmp(buffer,"From:", 5) == 0)
strcpy(from, buffer);
else if (strncmp(buffer,"From ", 5) == 0) {
sprintf(from, "From: %s\n", words(2,1, buffer));
sprintf(date,"Date: %s", words(3,7, buffer));
}
}
list_saved_headers()
{
/** This routine will display the information saved from the
message being listed...If it displays anything it'll end
with a blank line... **/
register int displayed_line = FALSE;
if (strlen(from) > 0) { printf("%s", from); displayed_line++;}
if (strlen(subject) > 0) { printf("%s", subject); displayed_line++;}
if (strlen(date) > 0) { printf("%s", date); displayed_line++;}
if (displayed_line)
putchar('\n');
}
char *words(word, num_words, buffer)
int word, num_words;
char *buffer;
{
/** Return a buffer starting at 'word' and containing 'num_words'
words from buffer. Assume white space will delimit each word.
**/
static char internal_buffer[SLEN];
char *wordptr, *bufptr, mybuffer[SLEN], *strtok();
int wordnumber = 0, copying_words = 0;
internal_buffer[0] = '\0'; /* initialize */
strcpy(mybuffer, buffer);
bufptr = (char *) mybuffer; /* and setup */
while ((wordptr = strtok(bufptr, " \t")) != NULL) {
if (++wordnumber == word) {
strcpy(internal_buffer, wordptr);
copying_words++;
num_words--;
}
else if (copying_words) {
strcat(internal_buffer, " ");
strcat(internal_buffer, wordptr);
num_words--;
}
if (num_words < 1)
return((char *) internal_buffer);
bufptr = NULL;
}
return( (char *) internal_buffer);
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 9564 ]
then
echo $filename changed - should be 9564 bytes, not $size bytes
fi
chmod 666 $filename
fi
# ---------- file utils/Makefile ----------
filename="utils/Makefile"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file utils/Makefile...
fi
cat << 'END-OF-FILE' > $filename
#
# Makefile for the MSG system utilities
#
# (C) Copyright 1986, Dave Taylor
#
# Last modification: March 5th, 1986
SHELL=/bin/sh
##############################
#
# if on a BSD system;
# DEFINE=-DBSD
# LIB2 = -lcurses
# else if on a UTS system;
# DEFINE=-DUTS
# LIB2 = -la
# else if on a SUN system;
# DEFINE=-DBSD -DSUN
# LIB2 = -lcurses
# else if on a Pyramid system;
# DEFINE=-DBSD -DNO_VAR_ARGS
# LIB2 = -lcurses
# else
DEFINE=
LIB2 =
##############################
CFLAGS= -O -I../hdrs
CC= /bin/cc
RM= /bin/rm
ECHO= /bin/echo
OBJS= ../bin/newalias ../bin/from ../bin/newmail ../bin/answer \
../bin/printmail ../bin/fastmail ../bin/readmsg \
../bin/checkalias ../bin/arepdaemon ../bin/autoreply ../bin/wnewmail
all: ${OBJS}
../bin/newalias: ../hdrs/defs.h newalias.c ../src/validname.o \
../src/opt_utils.o
${CC} ${CFLAGS} ${DEFINE} newalias.c ../src/validname.o \
../src/opt_utils.o -o ../bin/newalias
../bin/from: from.c ../src/opt_utils.o ../src/string2.o
${CC} ${CFLAGS} ${DEFINE} from.c ../src/opt_utils.o \
../src/string2.o -o ../bin/from
../bin/newmail: ../src/opt_utils.c newmail.c ../src/string2.o
${CC} ${CFLAGS} ${DEFINE} newmail.c \
../src/string2.o -o ../bin/newmail
../bin/wnewmail: ../src/opt_utils.c wnewmail.c ../src/string2.o
${CC} ${CFLAGS} ${DEFINE} ../src/opt_utils.o \
../src/string2.o wnewmail.c -o ../bin/wnewmail
../bin/answer: answer.c ../src/opt_utils.o
${CC} ${CFLAGS} ${DEFINE} answer.c ../src/opt_utils.o -o ../bin/answer
../bin/printmail: printmail.c ../src/opt_utils.o
${CC} ${CFLAGS} ${DEFINE} printmail.c ../src/opt_utils.o \
-o ../bin/printmail
../bin/fastmail: fastmail.c
${CC} ${CFLAGS} ${DEFINE} fastmail.c ../src/opt_utils.o \
-o ../bin/fastmail
../bin/readmsg: readmsg.c ../src/getopt.o ../src/opt_utils.o
${CC} ${CFLAGS} ${DEFINE} readmsg.c ../src/getopt.o \
../src/opt_utils.o -o ../bin/readmsg
../bin/arepdaemon: arepdaemon.c
${CC} ${CFLAGS} ${DEFINE} arepdaemon.c -o ../bin/arepdaemon
../bin/autoreply: autoreply.c ../src/opt_utils.o
${CC} ${CFLAGS} ${DEFINE} autoreply.c ../src/opt_utils.o \
-o ../bin/autoreply
../bin/checkalias:
@echo '#!/bin/sh' > ../bin/checkalias
@echo 'if [ -z "$$*" ]; then' >> ../bin/checkalias
@echo ' echo Usage: checkalias alias \[or aliases\]' >> \
../bin/checkalias
@echo ' exit 1' >> ../bin/checkalias
@echo 'fi' >> ../bin/checkalias
@echo ' ' >> ../bin/checkalias
@echo 'exec elm -c $*' >> ../bin/checkalias
@chmod +x ../bin/checkalias
../src/validname.o: ../src/validname.c
@(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} validname.c; cd ../utils)
../src/opt_utils.o: ../src/opt_utils.c
@(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} opt_utils.c; cd ../utils)
../src/getopt.o: ../src/getopt.c
@(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} getopt.c; cd ../utils)
../src/string2.o: ../src/string2.c
@(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} string2.c; cd ../utils)
clean:
${RM} *.o ${OBJS}
lint:
lint -p -I../hdrs *.c > LINT.OUT
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 3031 ]
then
echo $filename changed - should be 3031 bytes, not $size bytes
fi
chmod 666 $filename
fi
# ---------- file utils/breakup.c ----------
filename="utils/breakup.c"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file utils/breakup.c...
fi
cat << 'END-OF-FILE' > $filename
/** breakup.c **/
/** This program reads in a rather LARGE number of mail files (folders)
from a directory OTHER THAN THE CURRENT ONE and breaks each into
a file per message (each message being put into the directory
MESSAGES) and adds entries for each message in a mailbox with the
same name as the source mailbox. The format of each new mailbox
is;
FILE: <filename>
SUBJECT: <subject>
FROM: <from>
TO: <to>
SENT: <sent date>
RECEIVED: <received date>
(enough information so that indexes can be generated without actually
having to reference the files in question...)
filename is "YY-MM-DD.number" where YY-MM-DD is the date the
message was received (in this order for sorting)
from is the persons name or machine!user address ONLY
dates are MM-DD-YY, HH:MM ONLY.
(C) Copyright 1986, Dave Taylor
**/
#include <stdio.h>
#include <errno.h>
#include "defs.h"
static int ident[] = { WHAT_STRING };
extern int errno;
#define first_word(s,w) strncmp(s, w, strlen(w))
#define MESSAGES "MESSAGES"
#define seqfile "MESSAGES/.msg_sequence"
#define SLEN 80
char *monthnames[] = { "month-zero",
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December",
"month-thirteen" };
FILE *boxfd;
int messagenum = 1;
char *strtok();
main(argc, argv)
int argc;
char *argv[];
{
FILE *fd, *outfd;
char filename[SLEN], *basename(), *box_name;
int start;
if (argc == 1)
exit(printf("Usage: breakup <list of files>\n"));
if (access(MESSAGES, 00) == -1)
exit(printf("Need 'MESSAGES' directory in this directory!\n"));
if ((fd = fopen(seqfile, "r")) == NULL)
printf("Warning: No sequence file. Starting with sequence #1\n");
else {
fscanf(fd,"%d", &messagenum);
printf("Starting sequencing with #%d\n", messagenum);
fclose(fd);
}
*argv++;
start = messagenum;
while (--argc) {
if ((fd = fopen(*argv, "r")) == NULL)
leave(printf("\nCouldn't open file '%s' for reading!\n", *argv));
box_name = basename(*argv);
if ((boxfd = fopen(box_name, "w")) == NULL)
leave(printf("\nCouldn't open box '%s' for writing!\n", box_name));
printf("%s...", *argv); fflush(stdout);
break_up(fd, &messagenum);
*argv++;
fclose(boxfd);
fclose(fd);
}
printf("\nSuccessfully broke into %d messages!\n", messagenum - start);
leave();
}
leave()
{
/** leave, updating messagenum **/
FILE *fd;
if ((fd = fopen(seqfile, "w")) == NULL)
printf("Warning: couldn't update sequence file '%s'\n", seqfile);
else {
fprintf(fd, "%d", messagenum);
fclose(fd);
}
exit(0);
}
break_up(msgfd, messagenum)
FILE *msgfd;
int *messagenum;
{
/** break up the mailbox into it's component messages,
writing each one to a file as we go along **/
FILE *outfd;
char filename[SLEN], buffer[SLEN], save_buffer[SLEN];
char *get_fdate(), *get_sdate(), *get_rdate();
char *extract_from(), *extract_date();
int in_header = 0, file_open = 0, from_obtained=0;
int date_obtained = 0;
while (fgets(buffer, SLEN, msgfd) != NULL) {
if (first_word(buffer, "From ") == 0) {
sprintf(filename, "%s/%s.%d", MESSAGES, get_fdate(buffer, '/'),
(*messagenum)++);
if (file_open) fclose(outfd);
check_for_dirs(filename);
if ((outfd = fopen(filename, "w")) == NULL)
leave(printf("Could not open file '%s' as message file!\n",
filename));
fprintf(outfd, "%s", buffer);
fprintf(boxfd, "\nFile: %s\nReceived: %s\n",
filename, get_rdate(buffer));
file_open++;
in_header++;
date_obtained = 0;
from_obtained = 0;
strcpy(save_buffer, buffer);
}
else if (file_open) {
if (in_header) {
if (first_word(buffer, "Subject:") == 0)
fprintf(boxfd, "%s", buffer);
else if (first_word(buffer, "Date:") == 0) {
date_obtained++;
fprintf(boxfd, "Sent: %s\n", get_sdate());
}
else if (first_word(buffer, "From:") == 0) {
from_obtained++;
fprintf(boxfd, "%s", buffer);
}
else if (first_word(buffer,">From") == 0)
strcpy(save_buffer, buffer);
else if (strlen(buffer) < 2) {
in_header = 0;
if (! from_obtained)
fprintf(boxfd, "%s\n", extract_from(save_buffer));
if (! date_obtained)
fprintf(boxfd, "Sent: %s\n", extract_date(save_buffer));
}
}
fprintf(outfd, "%s", buffer);
}
}
if (file_open) {
if (! from_obtained)
fprintf(boxfd, "From: %s", extract_from(save_buffer));
if (! date_obtained)
fprintf(boxfd, "Date: %s", extract_date(save_buffer));
fclose(msgfd);
}
}
char *get_fdate(buffer, separator)
char *buffer, separator;
{
/** given a "From xyz" buffer, return the date in the format
YY?MM?DD for filenaming, where ? = the separator char. **/
static char mybuf[SLEN];
char monthname[SLEN];
int month=0, day=0, year=0;
sscanf(buffer, "%*s %*s %*s %s %d %*s %d", monthname, &day, &year);
year = year % 1900;
switch (tolower(monthname[0])) {
case 'j' : if (tolower(monthname[1]) == 'a')
month = 1;
else if (tolower(monthname[2]) == 'n')
month = 6;
else
month = 7;
break;
case 'f' : month = 2; break;
case 'm' : if (tolower(monthname[2]) == 'r')
month = 3;
else
month = 5;
break;
case 'a' : if (tolower(monthname[1]) == 'p')
month = 4;
else
month = 8;
break;
case 's' : month = 9; break;
case 'o' : month = 10; break;
case 'n' : month = 11; break;
case 'd' : month = 12; break;
}
sprintf(mybuf, "%d%c%s%c%d", year+1900, separator,
monthnames[month], separator, day);
return( (char *) mybuf);
}
char *get_rdate(buffer)
char *buffer;
{
/** return buffer "From xyz <date>" in the format:
MM-DD-YY, HH:MM **/
static char mybuf[SLEN];
char monthname[20];
int month=0, day=0, year=0, hour, minute;
sscanf(buffer, "%*s %*s %*s %s %d %d:%d:%*d %d",
monthname, &day, &hour, &minute, &year);
year = year % 1900;
switch (tolower(monthname[0])) {
case 'j' : if (tolower(monthname[1]) == 'a')
month = 1;
else if (tolower(monthname[2]) == 'n')
month = 6;
else
month = 7;
break;
case 'f' : month = 2; break;
case 'm' : if (tolower(monthname[2]) == 'r')
month = 3;
else
month = 5;
break;
case 'a' : if (tolower(monthname[1]) == 'p')
month = 4;
else
month = 8;
break;
case 's' : month = 9; break;
case 'o' : month = 10; break;
case 'n' : month = 11; break;
case 'd' : month = 12; break;
}
sprintf(mybuf, "%d-%d-%d, %d:%d", month, day, year, hour, minute);
return( (char *) mybuf);
}
char *get_sdate()
{
return( NULL );
}
char *extract_from(buffer)
char *buffer;
{
/** extract machine!userid from ">From buffer.. and return From: x!z **/
/** if userid = To: <someone>, then return that field instead **/
static char mybuf[SLEN];
char name[SLEN], machine[SLEN];
sscanf(buffer,"%*s %s %*s %*s %*s %*s %*s %*s %*s %s", name, machine);
if (strncmp(name, "To:", 3) == 0)
strcpy(mybuf, name);
else if (strlen(machine) > 0)
sprintf(mybuf, "From: %s!%s", machine, name);
else
sprintf(mybuf, "From: ", name);
return( (char *) mybuf);
}
char *extract_date(buffer)
char *buffer;
{
/** extract the date, mm/dd/yy, hh:mm from the '>From' buffer **/
static char mybuf[SLEN];
char month[10], time[10];
int day, year;
sscanf(buffer, "%*s %*s %*s %s %d %s %d", month, &day, time, &year);
year = year % 1900;
sprintf(mybuf,"%s %d %d, %s", month, day, year, time);
return( (char *) mybuf);
}
check_for_dirs(fname)
char *fname;
{
/** Given a filename of the form x/y/z check for the existence of
the directories 'x' and 'y', and create them if they're not
currently there! **/
char buffer[SLEN], *dirname, dirbuf[SLEN], *bufptr;
int loc, i;
strcpy(buffer, fname);
for (loc = strlen(fname)-1; buffer[loc] != '/'; loc--)
;
buffer[loc] = '\0'; /* broken into directories only! */
bufptr = (char *) buffer;
dirbuf[0]= '\0';
while ((dirname = strtok(bufptr,"/")) != NULL) {
if (strlen(dirbuf) > 0)
strcat(dirbuf, "/");
strcat(dirbuf, dirname);
if (access(dirbuf, 00) == -1)
mkdir(dirbuf, 0700);
bufptr = NULL;
}
}
char *basename(filename)
char *filename;
{
/** returns a string that is the BASENAME of the filename! **/
static char mybuffer[SLEN];
register int loc, firstch = 0;
for (loc = 0; filename[loc] != '\0'; loc++)
if (filename[loc] == '/')
firstch = loc+1;
loc = 0;
while (filename[firstch] != '\0')
mybuffer[loc++] = filename[firstch++];
mybuffer[loc] = '\0';
return ( (char *) mybuffer);
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 8868 ]
then
echo $filename changed - should be 8868 bytes, not $size bytes
fi
chmod 666 $filename
fi
# ---------- file utils/mailrc.awk ----------
filename="utils/mailrc.awk"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file utils/mailrc.awk...
fi
cat << 'END-OF-FILE' > $filename
BEGIN {
print "# MSG alias_text file, from a .mailrc file..."
print ""
}
next_line == 1 {
next_line = 0;
group = ""
for (i = 1; i <= NF; i++) {
if (i == NF && $i == "\\") sep = ""
else sep = ", "
if ($i == "\\") {
group = sprintf("%s,", group)
next_line = 1;
}
else if (length(group) > 0)
group = sprintf("%s%s%s", group, sep, $i);
else
group = $i;
}
print "\t" group
}
$1 ~ /[Aa]lias|[Gg]roup/ {
if ( NF == 3)
print $2 " : user alias : " $3;
else {
group = ""
for (i = 3; i <= NF; i++) {
if (i == NF && $i == "\\") sep = ""
else sep = ", "
if ($i == "\\") {
group = sprintf("%s,", group)
next_line = 1;
}
else if (length(group) > 0)
group = sprintf("%s%s%s", group, sep, $i);
else
group = $i;
}
print $2 " : group alias : " group;
}
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 930 ]
then
echo $filename changed - should be 930 bytes, not $size bytes
fi
chmod 666 $filename
fi
# ---------- file utils/wnewmail.c ----------
filename="utils/wnewmail.c"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file utils/wnewmail.c...
fi
cat << 'END-OF-FILE' > $filename
/** wnewmail.c **/
/** Same as newmail.c but for a windowing system...
(C) Copyright 1986, Dave Taylor
**/
#ifdef AUTO_BACKGROUND
#include <signal.h> /* background jobs ignore some signals... */
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "defs.h"
static char ident[] = { WHAT_STRING };
#define LINEFEED (char) 10
#define BEGINNING 0 /* seek fseek(3S) */
#define SLEEP_TIME 10
#define NO_SUBJECT "(No Subject Specified)"
FILE *mailfile;
long bytes();
char *getusername();
main(argc, argv)
int argc;
char *argv[];
{
char filename[LONG_SLEN];
long size, newsize;
if (argc > 2)
fprintf(stderr, "Usage: %s [filename] &\n", argv[0]);
else if (argc == 2) {
strcpy(filename, argv[1]);
if (access(filename, ACCESS_EXISTS) == -1) {
fprintf(stderr,"%s: Can't open file %s to keep track of!\n",
argv[0], filename);
exit(1);
}
}
else
sprintf(filename,"%s%s",mailhome, getusername());
#ifdef AUTO_BACKGROUND
if (fork()) /* automatically puts this task in background! */
exit(0);
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
signal(SIGHUP, SIG_DFL); /* so we exit when logged out */
#endif
size = bytes(filename);
mailfile = (FILE *) NULL;
printf("Incoming Mail;\n");
while (1) {
#ifndef AUTO_BACKGROUND /* won't work if we're nested this deep! */
if (getppid() == 1) /* we've lost our shell! */
exit();
#endif
/** Note the lack of error checking on the fopen() (Philip Peake
did!) - this is okay since if it fails we don't have any
mail and we can sleep(60) and try again later...
**/
if (mailfile == (FILE *) NULL)
mailfile = fopen(filename,"r");
if ((newsize = bytes(filename)) > size) { /* new mail */
fseek(mailfile, size, BEGINNING); /* skip all current mail */
size = newsize;
printf("%c", 007); /* beep for new mail! */
read_headers();
}
else if (newsize != size) {
size = newsize; /* mail's been removed... */
(void) fclose(mailfile); /* close it and ... */
mailfile = (FILE *) NULL; /* let's reopen the file */
}
sleep(SLEEP_TIME);
}
}
int
read_headers()
{
/** read the headers, output as found **/
char buffer[LONG_SLEN], from_whom[SLEN], subject[SLEN];
register int subj = 0, in_header = 1, count = 0;
while (fgets(buffer, LONG_SLEN, mailfile) != NULL) {
if (first_word(buffer,"From ")) {
if (real_from(buffer, from_whom)) {
subj = 0;
in_header = 1;
}
}
else if (in_header) {
if (first_word(buffer,">From"))
forwarded(buffer, from_whom); /* return address */
else if (first_word(buffer,"Subject:") ||
first_word(buffer,"Re:")) {
if (! subj++) {
remove_first_word(buffer);
strcpy(subject, buffer);
}
}
else if (first_word(buffer,"From:"))
parse_arpa_from(buffer, from_whom);
else if (buffer[0] == LINEFEED) {
in_header = 0; /* in body of message! */
show_header(from_whom, subject);
from_whom[0] = 0;
subject[0] = 0;
count++;
}
}
}
return(count);
}
int
real_from(buffer, who)
char *buffer, *who;
{
/***** returns true iff 's' has the seven 'from' fields,
initializing the who to the sender *****/
char junk[80];
junk[0] = '\0';
sscanf(buffer, "%*s %s %*s %*s %*s %*s %s",
who, junk);
return(junk[0] != '\0');
}
forwarded(buffer, who)
char *buffer, *who;
{
/** change 'from' and date fields to reflect the ORIGINATOR of
the message by iteratively parsing the >From fields... **/
char machine[80], buff[80];
machine[0] = '\0';
sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s",
who, machine);
if (machine[0] == '\0') /* try for srm address */
sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s",
who, machine);
if (machine[0] == '\0')
sprintf(buff,"anonymous");
else
sprintf(buff,"%s!%s", machine, who);
strncpy(who, buff, 80);
}
remove_first_word(string)
char *string;
{ /** removes first word of string, ie up to first non-white space
following a white space! **/
register int loc;
for (loc = 0; string[loc] != ' ' && string[loc] != '\0'; loc++)
;
while (string[loc] == ' ' || string[loc] == '\t')
loc++;
move_left(string, loc);
}
move_left(string, chars)
char string[];
int chars;
{
/** moves string chars characters to the left DESTRUCTIVELY **/
register int i;
chars--; /* index starting at zero! */
for (i=chars; string[i] != '\0' && string[i] != '\n'; i++)
string[i-chars] = string[i];
string[i-chars] = '\0';
}
show_header(from, subject)
char *from, *subject;
{
/** Output header in clean format, including abbreviation
of return address if more than one machine name is
contained within it! **/
char buffer[SLEN];
int loc, i=0, exc=0;
#ifdef PREFER_UUCP
if (chloc(from,'!') != -1 && in_string(from, BOGUS_INTERNET))
from[strlen(from) - strlen(BOGUS_INTERNET)] = '\0';
#endif
loc = strlen(from);
while (exc < 2 && loc > 0)
if (from[--loc] == '!')
exc++;
if (exc == 2) { /* lots of machine names! Get last one */
loc++;
while (loc < strlen(from) && loc < SLEN)
buffer[i++] = from[loc++];
buffer[i] = '\0';
strcpy(from, buffer);
}
if (strlen(subject) < 2)
strcpy(subject, NO_SUBJECT);
if (strlen(from) > 0) /* last final check... */
printf("Mail from %s -- %s\n", from, subject);
}
parse_arpa_from(buffer, newfrom)
char *buffer, *newfrom;
{
/** try to parse the 'From:' line given... It can be in one of
two formats:
From: Dave Taylor <hpcnou!dat>
or From: hpcnou!dat (Dave Taylor)
Change 'newfrom' ONLY if sucessfully parsed this entry and
the resulting name is non-null!
**/
char temp_buffer[SLEN], *temp;
register int i, j = 0;
temp = (char *) temp_buffer;
temp[0] = '\0';
no_ret(buffer); /* blow away '\n' char! */
if (lastch(buffer) == '>') {
for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
buffer[i] != '('; i++)
temp[j++] = buffer[i];
temp[j] = '\0';
}
else if (lastch(buffer) == ')') {
for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '(' &&
buffer[i] != '<'; i--)
temp[j++] = buffer[i];
temp[j] = '\0';
reverse(temp);
}
if (strlen(temp) > 0) { /* mess with buffer... */
/* remove leading spaces... */
while (whitespace(temp[0]))
temp = (char *) (temp + 1); /* increment address! */
/* remove trailing spaces... */
i = strlen(temp) - 1;
while (whitespace(temp[i]))
temp[i--] = '\0';
/* if anything is left, let's change 'from' value! */
if (strlen(temp) > 0)
strcpy(newfrom, temp);
}
}
reverse(string)
char *string;
{
/** reverse string... pretty trivial routine, actually! **/
char buffer[SLEN];
register int i, j = 0;
for (i = strlen(string)-1; i >= 0; i--)
buffer[j++] = string[i];
buffer[j] = '\0';
strcpy(string, buffer);
}
long
bytes(name)
char *name;
{
/** return the number of bytes in the specified file. This
is to check to see if new mail has arrived.... **/
int ok = 1;
extern int errno; /* system error number! */
struct stat buffer;
if (stat(name, &buffer) != 0)
if (errno != 2)
exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name));
else
ok = 0;
return(ok ? (long) buffer.st_size : 0L);
}
char *getusername()
{
/** Getting the username on some systems is a real pain, so...
This routine is guaranteed to return a usable username **/
char *return_value, *cuserid(), *getlogin();
if ((return_value = cuserid(NULL)) == NULL)
if ((return_value = getlogin()) == NULL)
exit(printf("Newmail: I can't get username!\n"));
return( (char *) return_value);
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 7804 ]
then
echo $filename changed - should be 7804 bytes, not $size bytes
fi
chmod 666 $filename
fi
# ---------- file utils/page.c ----------
filename="utils/page.c"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file utils/page.c...
fi
cat << 'END-OF-FILE' > $filename
/** page.c **/
/** This is an alternative method of wandering through a file
and is essentially a "read-only" editor.
This is part of the Elm mail system, although it can be
used by itself...
The functions available are;
h help
-,b back a page
u back 1/2 a page
^M,+,f forward a page
d forward 1/2 a page
r reread file (start over)
/ skip forward to pattern
? skip backwards to pattern (with no arg, same as "h")
q quit
The starting flags are:
-s Use scrolling rather than paging
Page is also smart enough to know that if it's reading stdin
that it needs to open a temp file to stream the input into
to allow paging AND also knows that it then needs to read
/dev/tty rather than stdin (think about it).
(C) Copyright 1986 Dave Taylor
**/
#include <stdio.h>
#define SLEN 100
#define TOP_OF_PAGE 0
#define MIDDLE_OF_PAGE 1
#define MAX_PAGES 200 /* indicates how far back we'll remember */
#define MIDDLE 0
#define END 1
#define TEMPFILENAME "/tmp/page."
FILE *keyboard; /* always read keyboard with this... */
FILE *infile; /* the file we're reading... */
FILE *tempfile; /* temp file for streaming input */
int scrolling = 0, /* Flag: should we scroll instead of page? */
streaming = 0; /* Flag: are we reading stdin for file? */
long offsets[2][MAX_PAGES]; /* offsets into file as we go along */
long current_offset; /* offset into file currently */
int current_page, /* what page we're on... */
loc_on_page, /* where are we (HALF ON, or FULLY ON) */
line_on_page, /* what line on the page (Screen) */
lines_per_page = 24; /* lines per page on terminal */
main(argc, argv)
int argc;
char *argv[];
{
char filename[SLEN], buffer[SLEN];
if (argc > 1) {
strcpy(filename, argv[1]);
keyboard = stdin;
}
else if (isatty(fileno(stdin)))
exit(printf("Nothing to page through!\n"));
else {
sprintf(filename, "%s.%d", TEMPFILENAME, getpid());
streaming++;
keyboard = fopen("/dev/tty", "r");
}
/** now let's open the file accordingly... **/
if (streaming) {
infile = stdin;
if ((tempfile = fopen(filename, "w")) == NULL)
exit(printf("Can't open tempfile %s for paging!\n", filename));
}
else {
if ((infile = fopen(filename, "r")) == NULL)
exit(printf("Can't open file %s for reading!\n", filename));
}
/** initialize our variables... **/
current_page = 0;
current_offset = 0L;
line_on_page = 0;
loc_on_page = TOP_OF_PAGE;
if (getenv("LINES") != NULL)
lines_per_page = atoi(getenv("LINES")) - 2;
offsets[TOP_OF_PAGE][current_page] = current_offset; /* init */
while (gets(buffer, SLEN, infile) != NULL) {
line_on_page++;
if (line_on_page == (int) (lines_per_page / 2))
offsets[MIDDLE_OF_PAGE][current_page] = current_offset;
else if (line_on_page == lines_per_page) {
offsets[TOP_OF_PAGE][++current_page] = current_offset;
next_page(MIDDLE); /* could do a "seek" remember! */
}
}
next_page(END);
exit(0);
}
next_page(where)
int where;
{
/** End of page processing..where is either "MIDDLE", indicating
that we're in the middle of a file, or "END", indicating that
we've already hit the EOF mark **/
char buffer[3];
top: printf("\n%s Command? ", where == MIDDLE? "More..." :
"End of Message -");
fgets(buffer,2, keyboard);
line_on_page = 0;
switch (buffer[0]) {
case '+' :
case 'f' :
case '\n' : return; /* scroll to next page */
case 'd' : line_on_page = (int) (lines_per_page / 2);
return; /* scroll 1/2 next page */
case 'u' : getto(offsets[MIDDLE_OF_PAGE][current_page-1]);
return;
case 'b' :
case '-' : getto(offsets[TOP_OF_PAGE][current_page-1]);
return;
case 'q' : exit(0); /* we're outta here!! */
case 'h' : help(); goto top; /* this again? */
default : printf("Unknown command. Please use \"h\" for help\n");
goto top;
}
}
getto(offset)
long offset;
{
/** This routine seeks to the specified point in the file and
sets current page accordingly... **/
if (fseek(infile, offset, 0) != -1)
current_offset = offset; /* whee! */
}
help()
{
printf("\nThe following options are available;\n\n");
printf(" h help\n\n");
printf(" -,b back a page\n");
printf(" u back 1/2 a page\n\n");
printf(" <return>,+,f forward a page\n");
printf(" d forward 1/2 a page\n\n");
printf(" r reread file (start over)\n\n");
printf(" / skip forward to pattern\n");
printf(" ? skip backwards to pattern (with no arg, same as \"h\")\n\n");
printf(" q quit\n\n");
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 4759 ]
then
echo $filename changed - should be 4759 bytes, not $size bytes
fi
chmod 666 $filename
fi
echo done
exit 0
More information about the Mod.sources
mailing list