Category : UNIX Files
Archive   : UUPC11YS.ZIP
Filename : MAILLIB.C

 
Output of file : MAILLIB.C contained in archive : UUPC11YS.ZIP
/*--------------------------------------------------------------------*/
/* m a i l l i b . c */
/* */
/* Mail user agent subroutine library for UUPC/extended */
/* */
/* Changes Copyright (c) 1990-1993 by Kendra Electronic */
/* Wonderworks; all rights reserved except those explicitly */
/* granted by the UUPC/extended license. */
/*--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*/
/* Change History: */
/* */
/* 3 May 90 Create from mail.c */
/* 16 Jun 90: Added support for mail (~) subcommands pdm */
/* chgd calling seq of Collect_Mail to support */
/* above */
/* chges to CopyMsg to support ~i subcmd */
/* mods to SendMail to support autosign option */
/* broke out signature append code to seperate fn */
/* added support for alternate signature file */
/*--------------------------------------------------------------------*/

/*
* $Id: MAILLIB.C 1.3 1993/04/11 00:33:05 ahd Exp $
*
* $Log: MAILLIB.C $
* Revision 1.3 1993/04/11 00:33:05 ahd
* Global edits for year, TEXT, etc.
*
* Revision 1.2 1992/11/27 14:36:10 ahd
* Use scrsize() for screen size
*
*/

#include
#include
#include
#include

#include "lib.h"
#include "address.h"
#include "hlib.h"
#include "mlib.h"
#include "alias.h"
#include "mail.h"
#include "maillib.h"
#include "scrsize.h"

#define INDENT "> "

/*--------------------------------------------------------------------*/
/* Local variables */
/*--------------------------------------------------------------------*/

static int PageCount = 0;

static char *ignorelist[] = { "Message-ID:",
"Received:",
"Status: ",
"X-Mailer: ",
"From " ,
"Path: ",
"Lines: ",
"References: ",
"" };

currentfile(); /* Define current file for panic() */

/*--------------------------------------------------------------------*/
/* P a g e r */
/* */
/* Page through a message */
/* */
/* There are hooks here to let the user use his/her own pager, */
/* like LIST, MORE, or LESS. We just write the message out to */
/* a temporary file and invoke the appropriate external program */
/* to do the browsing. */
/*--------------------------------------------------------------------*/

boolean Pager(const int msgnum,
boolean external,
copyopt received,
const boolean reset)
{
long nextloc;
char *browse = NULL;
char buf[BUFSIZ];
boolean exit = FALSE; /* Flag for PRE-MATURE exit ahd */
FILE *fmailbag;

if (msgnum == -1)
return FALSE;

if (bflag[F_PAGER]) /* User want pager option inverted? */
external = ! external; /* Yes --> Do the inversion */

if (letters[msgnum].status < M_READ)
letters[msgnum].status = M_READ;

if (external && (E_pager != nil(char)))
{
browse = mktempname( NULL,"TMP" );/* Get a temporary file name */

if ((fmailbag = FOPEN(browse, "w",TEXT_MODE)) == nil(FILE))
{
printerr(browse);
printmsg(0,"Cannot open browse file %s",browse);
return FALSE;
} /* if */
CopyMsg(msgnum, fmailbag, received, FALSE);
fclose(fmailbag);

L_invoke_pager(E_pager, browse);
remove(browse);
free(browse);

} /* if */
else {
fseek(fmailbox, letters[msgnum].adr , SEEK_SET);
nextloc = letters[msgnum + 1].adr;

if ( reset )
ClearScreen();
else
PageLine("\n");

sprintf(buf,"Mailbox item %d:\n",msgnum + 1);
PageLine(buf);
while (ftell(fmailbox) < nextloc && (!exit) &&
fgets(buf, BUFSIZ, fmailbox) != nil(char))
{
boolean print = TRUE;

switch(received)
{
case nocontinue:
if ((*buf != '\n') && !isgraph(*buf)) {
print = FALSE;
break;
}
else
received = noreceived;
case noreceived:
{
char entry = 0;
while ( strlen(ignorelist[entry]) && print )
{
if (equalni(ignorelist[entry],
buf,strlen(ignorelist[entry])))
{
print = FALSE;
received = nocontinue;
}
else
entry++;
} /* while */
} /* case noreceived */
} /* switch */
if (received != seperators)
if (equal(buf,"\n"))
received = seperators;

if (print)
if (PageLine(buf)) /* Exit if the user hits Q */
exit = TRUE;
} /* while */

if (equal(buf,"\n") && (!exit)) /* ahd */
putchar('\n'); /* ahd */
} /* else */

return ! exit;
} /*Pager*/


/*--------------------------------------------------------------------*/
/* S u b _ P a g e r */
/* pager for the ~p mail subcommand */
/* page through a mail message currently being entered */
/* */
/* Clone of the Pager function */
/*--------------------------------------------------------------------*/

void Sub_Pager(const char *tinput,
boolean external )
{
boolean exit = FALSE; /* Flag for PRE-MATURE exit ahd */

if (bflag[ F_PAGER ])
external = ! external;

if ( external && (E_pager != nil(char)) )
L_invoke_pager(E_pager, tinput);
else {
FILE *finput;
char buf[BUFSIZ];
finput = FOPEN(tinput, "r",TEXT_MODE);
if (finput == NULL) {
printmsg(0,"Cannot open file %s for display",tinput);
printerr(tinput);
return;
}
PageReset();
ClearScreen();
while ( (!exit) && fgets(buf, BUFSIZ, finput) != nil(char))
{
if (PageLine(buf)) /* Exit if the user hits Q */
exit = TRUE;
}
fclose(finput);
}

} /*Sub_Pager*/

/*--------------------------------------------------------------------*/
/* P a g e R e s e t */
/* */
/* Reset page function to top of page */
/*--------------------------------------------------------------------*/

void PageReset()
{
PageCount = 0;
} /*PageReset*/

/*--------------------------------------------------------------------*/
/* P a g e L i n e */
/* */
/* Print one line when paging through a file */
/*--------------------------------------------------------------------*/

boolean PageLine(char *line)
{

short pagesize = scrsize() - 3;
fputs(line, stdout);

PageCount = PageCount + 1 + strlen(line) / 81; /* Handle long lines */

if (PageCount > (pagesize))
{
int c;
fputs("More?", stdout);
c = Get_One();

switch (tolower(c))
{
case 'q':
case '\003':
case 'n': /* Because that's what I
keep Pressing */
case 'x':
fputs("\rAborted.\n", stdout);
return TRUE;

case 'd':
PageCount = pagesize / 2; /* Half a Page More */
break;

case '\r':
PageCount = pagesize; /* Only print one line */
break;

default:
PageCount = 0; /* Print full screen */
}
fputs("\r \r",stdout);
}

return FALSE;

} /*PageLine*/

/*--------------------------------------------------------------------*/
/* C o p y M s g */
/* */
/* Copy a message */
/* */
/* Allows copying message with one or more of the options */
/* specified in the copyopt data type. */
/*--------------------------------------------------------------------*/

boolean CopyMsg(int msgnum, FILE *f, copyopt headers, boolean indent)
{
long nextloc;
boolean print;
char buf[BUFSIZ];

/*--------------------------------------------------------------------*/
/* Write a separator line, if needed */
/*--------------------------------------------------------------------*/

if (headers == seperators)
{
if (fputs(MESSAGESEP,f) == EOF) /* Write out separator line */
{
printerr("CopyMsg");
panic();
} /* if (fputs(MESSAGESEP,f) == EOF) */
} /* if (headers == seperators) */

/*--------------------------------------------------------------------*/
/* else add a one line from line, if desired */
/*--------------------------------------------------------------------*/

else if (headers == fromheader )
{
register char *sp = buf;
headers = noheader; /* Do not print full header */
if (RetrieveLine(letters[msgnum].date, buf, LSIZE))
{
register char *sp = buf;
while (!isspace(*sp))
sp++;
while (isspace(*sp))
sp++;
fprintf(f,"On %s,", sp );
} /* if */

if (RetrieveLine(letters[msgnum].from, buf, BUFSIZ))
{
while (!isspace(*sp) && (*sp != '\0'))
sp++;
BuildAddress( buf, sp );
} /* if */
else
strcpy(buf,"you"); /* Wimp out without admitting it */

fprintf(f, " %s wrote:\n", buf) ;
} /* if (headers == fromheader ) */

/*--------------------------------------------------------------------*/
/* Now position to the front of the letter */
/*--------------------------------------------------------------------*/

fseek(fmailbox, letters[msgnum].adr , SEEK_SET);
nextloc = letters[msgnum + 1].adr;

while (ftell(fmailbox) < nextloc &&
fgets(buf, BUFSIZ, fmailbox) != nil(char)) {

/*--------------------------------------------------------------------*/
/* Determine if we should write the line */
/*--------------------------------------------------------------------*/

print = TRUE;

switch (headers)
{
case noheader:
print = FALSE;
break;

case nocontinue:
if ((*buf != '\n') && !isgraph(*buf)) {
print = FALSE;
break;
}
else
headers = noreceived;
/* Fall through ... */
case noreceived:
{
char entry = 0;
while ( strlen(ignorelist[entry]) && print )
{
if (equalni(ignorelist[entry],buf,strlen(ignorelist[entry])))
{
print = FALSE;
headers = nocontinue;
}
else
entry++;
}
} /* case noreceived */
/* Fall through */
case noseperator:
case seperators:
break;

default:
printmsg(0,"CopyMsg: Bad header copy state of %d",headers);
panic();
} /* switch */

/*--------------------------------------------------------------------*/
/* If we should print the line, do so */
/*--------------------------------------------------------------------*/

if (print)
{
if (indent)
{
if ( fputs(INDENT , f ) == EOF )
{
printerr( "CopyMsg" );
panic();
} /* if ( fputs(INDENT , f ) == EOF ) */
} /* if (indent) */

if ( fputs(buf , f ) == EOF )
{
printerr( "CopyMsg" );
panic();
} /* if ( fputs(buf , f ) == EOF ) */

} /* if (print) */

/*--------------------------------------------------------------------*/
/* If end of the header, print all data until the end of the input */
/*--------------------------------------------------------------------*/

if ( (headers != seperators) && equal(buf, "\n") )
headers = seperators;

} /*while*/

return TRUE;
} /*CopyMsg*/

/*--------------------------------------------------------------------*/
/* N u m e r i c */
/* */
/* Determine if a string is numeric. Returns TRUE if string is */
/* numeric, else FALSE. */
/*--------------------------------------------------------------------*/

boolean Numeric( const char *number)
{
char *column = (char *) number;

if (*column == '\0')
return FALSE;

while( isdigit(*column) ) /* Scan to string end or 1st non-digit */
column++;

return *column == '\0'; /* Success if whole string was made of
digits */
} /* Numeric */

/*--------------------------------------------------------------------*/
/* R e t r i e v e L i n e */
/* */
/* Read a line from a mail header, if available */
/*--------------------------------------------------------------------*/

boolean RetrieveLine(long adr, char *line, const size_t len)
{
char *cp = line;
size_t count;

*line = '\0'; /* Insure nothing to find */
if (adr == MISSING) /* No information to read? */
return FALSE; /* Report this to caller */

if (fseek(fmailbox, adr, SEEK_SET)) /* Position to data */
{ /* Have a problem? */
printerr("mailbox"); /* Yes --> Report and return */
return FALSE;
}

/*--------------------------------------------------------------------*/
/* Actually read the data in */
/*--------------------------------------------------------------------*/

count = fread(line, sizeof *line, len-1, fmailbox);

if ((count < (len-1)) && ferror( fmailbox ))
{
printerr( "RetrieveLine");
return FALSE;
}

line[count] = '\0'; /* Terminate the string read */

/*--------------------------------------------------------------------*/
/* A field continues until a new field begins in column of the */
/* next line or the header ends (an empty line); find the end */
/* of the field, trimming extra white space from the beginning */
/* of each line as we go */
/*--------------------------------------------------------------------*/

while( (cp = strchr(cp , '\n')) != NULL )
{
if ((cp[1] == '\n') || !isspace(cp[1])) /* End of field? */
*cp = '\0'; /* Yes --> Terminate string */
else {
char *next;

*cp++ = ' '; /* Convert line break to whitespace */
next = ++cp; /* Get first position of new line */
while( isspace( *next ) ) /* Ignore leading white space */
next++;

memmove( cp , next , strlen(next) + 1 );
/* Trim leading white space */
} /* else */
} /* while */

return TRUE;

} /*RetrieveLine*/

/*--------------------------------------------------------------------*/
/* R e t u r n A d d r e s s */
/* */
/* Returns the user name (if available and requested) or */
/* E-mail address of the user */
/* */
/* Written by ahd 15 July 1989 */
/*--------------------------------------------------------------------*/

void ReturnAddress(char *line, struct ldesc *ld)
{
char buffer[BUFSIZ];

if (!RetrieveLine(ld->from, buffer, BUFSIZ))
/* From: line available? */
strcpy(line,"-- Unknown --"); /* No --> Return error */
else {
char *begin = buffer;
while (!isspace(*begin) && (*begin != '\0'))
begin++;
if (strlen(begin))
ExtractName(line,begin); /* Yes --> Return name */
else
strcpy(line,"-- Invalid From: line --");
}

return;

} /*ReturnAddress*/

/*--------------------------------------------------------------------*/
/* s a y o p t i o n s */
/* */
/* Announce user options in effect */
/*--------------------------------------------------------------------*/

void sayoptions( FLAGTABLE *flags)
{

size_t subscript;
size_t used = 0;

printf("\nThe following options are set:\n");

for (subscript = 0; (subscript < F_LAST); subscript++)
{
size_t width;

if (flags[subscript].bits & B_GLOBAL)
continue; /* Don't print system options */

width = 1 + strlen( flags[subscript].sym ) +
( bflag[ flags[subscript].position ] ? 0 : 2 );

used += width;
if ( subscript > 0 )
{
if ( used > 79 )
{
putchar('\n');
used = width;
} /* if ( used > 79 ) */
else
putchar(' ');
} /* if ( subscript > 0 ) */

printf("%s%s",
bflag[ flags[subscript].position ] ? "" : "no" ,
flags[subscript].sym );

} /* for */

putchar('\n');

} /* sayoptions */


  3 Responses to “Category : UNIX Files
Archive   : UUPC11YS.ZIP
Filename : MAILLIB.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/