home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff319.lzh
/
CNewsSrc
/
uupc.lzh
/
uupc
/
mail.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-16
|
12KB
|
599 lines
/*
* mail
*
* Amiga system mailer
* This is the user interface for mail. It supports a limited command
* list and can display a list of messages waiting in the mailbox.
*
* $Id: mail.c,v 1.2 90/01/16 10:26:32 crash Exp Locker: crash $
*/
#ifndef lint
static char RCSid[] = "$Id: mail.c,v 1.2 90/01/16 10:26:32 crash Exp Locker: crash $";
#endif /* lint */
#define EXIT return
#include <stdio.h>
#include "host.h"
extern char *index();
extern char *rindex();
#ifdef MSDOS
# define PC_FILENMS 1
#endif
#ifdef AMIGA
# define PC_FILENMS 1
#endif
FILE *FOPEN();
FILE *freopen();
int debuglevel = 1;
#define OUT(x) fprintf(stderr, x)
#define LSIZE 256
#ifndef MAXNAMLEN
# define MAXNAMLEN 255
#endif
char line[LSIZE];
char resp[LSIZE];
char mfilename[MAXNAMLEN+1];
struct ldesc {
int delete; /* status of this message */
long adr; /* address of From line */
long date; /* address of Date: line */
long subject; /* address of Subject: line */
long from; /* address of From: line */
long size; /* number of lines */
};
#define MAXMSGS 300 /* Maxmimum number of letters */
struct ldesc letters[MAXMSGS];
int letternum = 0;
char thefilename[MAXNAMLEN+1];
char tmailbox[MAXNAMLEN+1];
char tmailbag[MAXNAMLEN+1];
FILE *fmailbox;
FILE *rmailbox;
FILE *fmailbag;
int error = 0;
int modified;
int printonly;
int PageCount = 0;
mailmain(argc, argv)
int argc;
char **argv;
{
#if 0 /* This is done by l_host.c before calling mailmain() */
HOSTINIT;
loadenv();
#endif
mkfilename( tmailbox, tempdir, "mailbox");
mkfilename( tmailbag, tempdir, "mailbag");
unlink( tmailbox );
if ( mailbox == (char *)NULL )
mailbox = "???";
if (argc == 1 || (argv[1][0] == '-') && (argv[1][1] != 's'))
showmail (argc, argv );
else
lmail (argc, argv );
finis();
}
finis()
{
if (fmailbag != (FILE *)NULL) fclose( fmailbag );
if (fmailbox != (FILE *)NULL) fclose( fmailbox );
unlink( tmailbox );
unlink( tmailbag );
EXIT( error );
}
/*
* sendmail
* send message n to "line"
*/
sendmail(n, line)
int n;
char *line;
{
#ifdef PC_FILENMS
FILE *tmpfp, *tmp2fp;
#endif
char *argv[50];
int argc;
char buf[BUFSIZ];
long bytes;
bytes = letters[ n+1 ].adr - letters[ n ].adr;
/* open a temporary file */
fmailbag = FOPEN( tmailbag, "w", 'b' );
/* copy nth message to mailbag file */
fseek( fmailbox, letters[ n ].adr, 0 );
while( bytes > 0 && fgets( buf, sizeof(buf), fmailbox) ) {
fputs( buf, fmailbag );
bytes -= strlen( buf );
}
fclose( fmailbag );
/* use mailbag as stdin to mail delivery */
FILEMODE( 'b' );
if ( freopen( tmailbag, "r", stdin ) != (FILE *)NULL ) {
argc = getargs( line, argv );
lmail( argc, argv );
}
#ifdef AMIGA
freopen( "*", "r", stdin );
#else
freopen( device, "r", stdin );
#endif
/* get rid of mailbag */
unlink( tmailbag );
}
invert( i )
{
return( letternum-i-1 );
}
showmail(argc, argv)
int argc;
char **argv;
{
int flg, i, j, k, print;
char *p, *cp, *getnext();
long nextadr;
struct ldesc *letter;
/* get mailbox file name */
mkfilename( mfilename, maildir, mailbox );
/* parse arg's */
for (; argc > 1; argv++, argc--) {
if ( argv[1][0] == '-' ) {
switch (argv[1][1]) {
case 'f' :
if (argc > 2) {
if (argv[2][0] == '~')
mkfilename( mfilename, maildir, argv[2]+1 );
else
strcpy( mfilename, argv[2] );
argv++;
argc--;
}
break;
case 'p' :
printonly = TRUE;
break;
default :
fprintf(stderr, "mail: unknown option %c\n", argv[1][1]);
finis();
}
} else
break;
}
/* open real mailbox file */
if (( rmailbox = FOPEN( mfilename, "r", 'b' )) == (FILE *)NULL) {
fprintf( stdout, "No mail in %s.\n", mfilename );
return;
}
/* open up tmp mailbox file */
if (( fmailbox = FOPEN( tmailbox, "w", 'b' )) == (FILE *)NULL ) {
fprintf( stderr, "mail: cannot open %s for writing\n", tmailbox );
finis();
}
/*
* Copy real mailbox file to tmp mailbox file.
*
* During the copy, record the header information so it can
* be displayed later.
*/
letternum = 0;
nextadr = 0;
while (fgets(line, LSIZE, rmailbox)) {
fputs(line, fmailbox);
if ( strncmp( line, "From ", 5 ) == SAME ) {
letter = &letters[letternum++];
letter->from = -1L;
letter->subject = -1L;
letter->date = -1L;
letter->adr = nextadr;
letter->delete = FALSE;
letter->size = 0L;
} else if ( strncmp( line, "Date: ", 6 ) == SAME )
letter->date = nextadr;
else if ( strncmp( line, "From: ", 6 ) == SAME )
letter->from = nextadr;
else if ( strncmp( line, "Subject: ", 9 ) == SAME )
letter->subject = nextadr;
letter->size++; /* Count number of lines */
nextadr += strlen( line ); /* Keep track of seek position */
}
letters[letternum].adr = nextadr; /* last plus 1 */
/* close mailbox files */
fclose( rmailbox );
fclose( fmailbox );
fmailbox = FOPEN( tmailbox, "r", 'b' );
modified = 0;
if (printonly) {
j = letternum;
while (j > 0)
pager(j--);
return;
}
printsub(-1); /* Print the subject list */
i = letternum-1;
while (TRUE) {
register char *inp = resp;
if (i < 0) i = 0;
if (i >= letternum) i = letternum-1;
j = invert(i);
fprintf(stdout, "%d ? ", j);
if (!fgets( inp, LSIZE, stdin)) break;
switch (*inp) {
default:
fprintf(stderr, "Usage\n");
case '?':
print = 0;
OUT("q\tquit\n");
OUT("x\texit\tmailbox restored\n");
OUT("p\tprint current message; also `RETURN'\n");
OUT("+\tprint next message; also `n'\n");
OUT("-\tprint last message; also `^'\n");
OUT("h\tprint subject header list; also `H'\n");
OUT("s[file]\tsave message to a file (default mbox)\n");
OUT("w[file]\t(same as `s' but without headers\n");
OUT("\t`file' may be absolute path or use ~ for $MAILDIR\n");
OUT("d\tdelete current message\n");
OUT("f user\tforward current message to `user'\n");
OUT("m user\tmail a message to `user'\n");
OUT("g num\tset current message; also `num'\n");
break;
case '+':
case 'n':
i-- ;
break;
case 'g':
i = invert(atoi(inp+1));
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
i = invert(atoi(inp));
break;
case 'x':
modified = 0;
case 'q':
goto donep;
case '\n':
case 'p':
pager( j );
break;
case '^':
case '-':
i++;
break;
case 'y':
case 'w':
case 's':
flg = 0;
k = *inp;
#ifdef FJE
inp++;
while (isspace(*inp))
inp++;
#else
if (inp[1] != '\n' && inp[1] != ' ') {
printf("illegal\n");
flg++;
print = 0;
continue;
}
#endif /* !FJE */
if (strlen(inp) < 2)
strcat(inp, "~mbox");
for (p = inp; p = getnext(&cp, p); ) {
if (*cp == '~')
mkfilename(thefilename, maildir, ++cp);
else
strcpy(thefilename, cp);
fprintf(stderr, "%s to %s\n",
(k == 's') ? "Saving" : "Writing", thefilename);
if ( !(fmailbag = FOPEN(thefilename, "a", 't')) ) {
fprintf(stderr, "mail: cannot open %s\n", thefilename);
flg++;
continue;
}
copymsg(j, fmailbag, k == 'w');
fclose( fmailbag );
}
if (flg)
print = 0;
else {
letters[j].delete = TRUE;
modified++;
i--;
}
break;
case 'm':
OUT("mail command not implemented yet!\n");
break;
case 'f':
flg = 0;
while (isspace(*inp))
inp++;
if (!*inp) {
printf("No user id to forward to!?\n");
i++;
continue;
}
sendmail(j, p);
if (flg)
print = 0;
else {
letters[j].delete = TRUE;
modified++;
i++;
}
break;
case 'd':
letters[j].delete = TRUE;
modified++;
i--;
if (inp[1] == 'q')
goto donep;
break;
case 'h':
printsub( -1 );
break;
case 'H':
printsub( i );
break;
}
}
donep:
if (modified) copyback();
}
readaline(adr, line)
long adr;
char *line;
{
char buf[132];
register char *cp = buf;
*line = '\0';
if (adr != -1L && !fseek(fmailbox, adr, 0) && fgets(cp, 132, fmailbox))
strcpy(line, cp);
if (cp = index(line, '\n'))
*cp = '\0';
}
#if 0
returnaddress()
{
readaline( lp->from, line );
if (i = index(line, '<') && k = index(line, '>') && k > i) {
strncpy(from, line[i], k-i);
from[k] = '\0';
}
}
#endif
printsub( K )
int K;
{
static char from[132], subject[132], date[132], line[132];
register char *sp, *dp, *lp, *tp;
struct ldesc *ld;
int k, mink, maxk, j;
pagereset();
if ( K == -1 ) {
maxk = letternum-1;
mink = 0;
} else
maxk = mink = K;
sprintf(line, "%3s %6s %-20s %-35s Lines\n",
"# ", "Date ", "From", "Subject");
pageline( line );
for (k = maxk; k >= mink; k--) {
j = invert(k);
ld = letters+j;
(void) strcpy(from, "unknown"); /* default to "unknown" */
readaline(ld->from, line);
if (strlen(line)) {
/*
* get first usable stuff after From:
*/
sp = index(line, ':')+1;
/*
* Is it "From: mailbox@site.domain (Proper Name)"?
*/
if ( (tp = index(line, '(')) && (lp = index(tp, ')')) )
sp = ++tp;
else
/*
* or "From: Proper Name <mailbox@site.domain>"
*/
lp = index( line, '<');
if ( *lp == '<' || *lp == ')' )
--lp;
/* if we didn't get either of the last two, just grab line */
if (lp < sp || !lp)
lp = line+strlen(line)-1;
while (isspace(*sp)) sp++;
while (isspace(*lp)) lp--;
dp = from;
while (sp <= lp) *dp++ = *sp++;
*dp = '\0';
}
/*
* Date formats:
* Date: Wed May 13 23:59:53 1987
*/
*date = '\0';
readaline(ld->date, date);
if (strlen(date)) {
sscanf(date, "%*s %*s %s %s", line, subject);
sprintf(date, "%s %s", line, subject);
}
strcpy(subject, "--- no subject ---");
readaline(ld->subject, line);
if (strlen(line)) {
sp = line;
while (!isspace(*sp)) sp++;
while ( isspace(*sp)) sp++;
strcpy(subject, sp);
}
sprintf(line, "%3.3d %6.6s %-20.20s %-35.35s (%ld)\n",
j, date, from, subject, ld->size);
if (pageline(line))
break;
}
}
copyback()
{
register i, n, c;
int new = 0;
if ( !(fmailbag = FOPEN(mfilename, "w", 'b')) ) {
fprintf(stderr, "mail: can't rewrite %s\n", mfilename);
finis();
}
n = 0;
for (i = 0; i < letternum; i++)
if (letters[i].delete == FALSE) {
copymsg(i, fmailbag, FALSE);
n++;
}
fclose(fmailbag);
}
/*
* copy a message
* if noheaders is TRUE, don't copy header lines
*/
copymsg(n, f, noheaders)
int n;
FILE *f;
int noheaders;
{
long bytes;
char buf[BUFSIZ];
fseek(fmailbox, letters[n].adr, 0);
bytes = letters[n+1].adr - letters[n].adr;
while (bytes > 0 && fgets(buf, sizeof(buf), fmailbox)) {
bytes -= strlen(buf);
if (!noheaders) fputs(buf, f);
if (noheaders && buf[0] == '\n' && !buf[1]) noheaders = FALSE;
}
}
pager(n)
int n;
{
long bytes;
char buf[BUFSIZ];
fseek(fmailbox, letters[n].adr, 0);
bytes = letters[n+1].adr - letters[n].adr;
pagereset();
while (bytes > 0 && fgets(buf, sizeof(buf), fmailbox)) {
bytes -= strlen(buf);
if (pageline(buf))
break;
}
pageline("\n");
}
pagereset()
{
PageCount = 0;
}
pageline(s)
char *s;
{
int c;
fputs(s, stdout);
if (++PageCount > 18) {
PageCount = 0;
fputs("\033[7m`q' to quit, SPACE to continue:\033[0m", stdout);
c = get_one();
fputs("\r\033[K", stdout);
switch (c) {
case 'q':
case 'Q':
case 'x':
case 'X':
case '\003': /* ^C */
case '\033': /* ESC */
return( TRUE );
}
}
return( FALSE );
}
char *getnext(s, p)
register char **s, *p;
{
*s = NULL;
while (*p == ' ' || *p == '\t')
p++;
if (*p == '\n' || !*p)
return( NULL );
*s = p;
while (isspace(*p))
*p++;
if (*p)
*p++ = '\0';
return(p);
}