|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T n
Length: 7989 (0x1f35)
Types: TextFile
Names: »newmail.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec1/elm/utils/newmail.c«
/** newmail.c **/
/** Keep track of the mail for the current user...if new mail
arrives, output a line of the form;
New mail from <name> - <subject>
where <name> is either the persons full name, or machine!login.
If there is no subject, it will say.
Added: you can specify a file other than the mailbox to keep
track of - if an argument is given, the program will try
to use it as a filename...
Also, the program will quit when you log off of the machine.
(C) Copyright 1986, Dave Taylor
**/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "defs.h"
#ifdef AUTO_BACKGROUND
#include <signal.h> /* background jobs ignore some signals... */
#endif
static char ident[] = { WHAT_STRING };
#define LINEFEED (char) 10
#define BEGINNING 0 /* seek fseek(3S) */
#define SLEEP_TIME 60
#define NO_SUBJECT "(No Subject Specified)"
FILE *mailfile;
long bytes();
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, getlogin());
#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;
while (1) {
#ifndef AUTO_BACKGROUND /* won't work if we're nested this deep! */
if (getppid() == 1) /* we've lost our shell! */
exit();
#endif
if (! isatty(1)) /* we're not sending output to a tty any more */
exit();
/** 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("\n\r"); /* blank lines surrounding message */
read_headers();
printf("\n\r");
}
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, priority=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,"Priority:"))
priority++;
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(priority, 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(priority, from, subject)
int priority;
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);
printf(">> %s mail from %s - %s\n\r",
priority? "PRIORITY" : "New", 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 ? buffer.st_size : 0);
}