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

 
Output of file : RMAIL.C contained in archive : UUPC11YS.ZIP
/*--------------------------------------------------------------------*/
/* r m a i l . c */
/* */
/* Delivery agent for UUPC/extended */
/*--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*/
/* Changes Copyright (c) 1989 by Andrew H. Derbyshire. */
/* */
/* Changes Copyright (c) 1990-1993 by Kendra Electronic */
/* Wonderworks. */
/* */
/* All rights reserved except those explicitly granted by the */
/* UUPC/extended license agreement. */
/*--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*/
/* RCS Information */
/*--------------------------------------------------------------------*/

/*
* $Id: RMAIL.C 1.8 1993/04/15 03:17:21 ahd Exp $
*
* $Log: RMAIL.C $
* Revision 1.8 1993/04/15 03:17:21 ahd
* Correct conditions under which name in userp structure used
*
* Revision 1.7 1993/04/13 02:26:30 ahd
* Make return codes more unique
*
* Revision 1.6 1993/04/11 00:33:05 ahd
* Global edits for year, TEXT, etc.
*
* Revision 1.5 1992/12/05 23:38:43 ahd
* Let logger close the log, not rmail
*
* Revision 1.4 1992/12/04 01:00:27 ahd
* Add copyright messages
*
*/

/*--------------------------------------------------------------------*/
/* Function: Stand alone mail delivery module for */
/* UUPC/extended */
/* Language: Borland C++ 3.1 (ANSI C mode) or Microsoft C 6.0. */
/* Arguments: One or more addresses to deliver mail to */
/* or "-t" to direct rmail to read the addresses */
/* from the RFC-822 header. */
/* A third mode of operation is to specify '-w' and/ */
/* or '-s subject' followed by one or more addresses */
/* with optional carbon copy flags (-c or -b) before */
/* additional addresses. This causes rmail to */
/* function like a bare bones batch version of the */
/* MAIL program; a valid RFC-822 header is generated */
/* and the mail is delivered, aliases are not expanded */
/* and the mail is not locally logged. (The current */
/* user id as the from address is used unless the */
/* environment variable LOGNAME is set, in which case */
/* it is used.) */
/* Optional argument "-f" to denote file to read in */
/* place of stdin. */
/* Optional argument "-F" to denote file to read in */
/* place of stdin and DELETE after readering. */
/* Optional argument "-x" to for debug level */
/* Input: mail to be delivered, with RFC-822 header, on */
/* stdin. */
/* Output: 'From' and 'Received:' headers are added, */
/* 'Bcc:' headers are removed, and the mail is */
/* delivered to one or more local users and/or */
/* one or more remote users. */
/* Exit code: 0 Success */
/* 1 One or more letters not delivered */
/* 2 No mail delivered */
/* 3 Configuration file error */
/* 4 Invalid option/help specified */
/* 5 Input/output error */
/* 6 Input/output error */
/* 7 Input/output error */
/* */
/* Note: When parsing RFC-822 headers, this program */
/* expects them to be "well-behaved", that is in */
/* format generated by UUPC/extended. This implies: */
/* */
/* One address per line */
/* */
/* Resent- headers, if any, before the original */
/* headers. */
/* */
/* From: header must precede To: header. */
/* */
/* To: header must precede Cc: and Bcc: headers. */
/* */
/* Cc: and Bcc: headers must be together (one */
/* after the other) */
/* */
/* The MUA has prefixed any obsolete Resent- */
/* headers by X- */
/* */
/* Note: The "-t" flag is supported by BSD sendmail for the */
/* purpose listed above, but we also turn use it to */
/* control other special options, all of which */
/* basically cause the program to act more like a */
/* local mailer than a remote mailer; these options */
/* include: */
/* */
/* Stripping off blind carbon copies */
/* */
/* Generating the UUCP From line differently */
/*--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*/
/* System include files */
/*--------------------------------------------------------------------*/

#include
#include
#include
#include
#include
#include
#include

/*--------------------------------------------------------------------*/
/* Application include files */
/*--------------------------------------------------------------------*/

#include "lib.h"
#include "address.h"
#include "arpadate.h"
#include "deliver.h"
#include "getopt.h"
#include "hlib.h"
#include "hostable.h"
#include "logger.h"
#include "security.h"
#include "usertabl.h"
#include "timestmp.h"
#include "catcher.h"

/*--------------------------------------------------------------------*/
/* Local defines */
/*--------------------------------------------------------------------*/

#define MOPLEN 10 /* Length of formatted header lines */
#define UUCPFROM "From " /* Length of UUCP incoming mail */

/*--------------------------------------------------------------------*/
/* Prototypes for internal files */
/*--------------------------------------------------------------------*/

static boolean CopyTemp( void );

static void ParseFrom( void );

static char **Parse822( boolean *header,
size_t *count);

static void Terminate( const int rc);

static void PutHead( const char *label,
const char *operand,
FILE *stream,
const boolean resent);

static boolean DaemonMail( const char *subject,
char **address,
int count );


static void usage( void );

/*--------------------------------------------------------------------*/
/* Global variables */
/*--------------------------------------------------------------------*/

currentfile(); /* Declare file name for checkref() */
char *tempname = NULL; /* Pointer to temporary input file */
char *namein = CONSOLE;
FILE *datain = stdin; /* Handle for reading input mail */
FILE *dataout = NULL; /* Handle for the output of mail */
char fromuser[MAXADDR] = ""; /* User id of originator */
char fromnode[MAXADDR] = ""; /* Node id of originator */
char *now; /* Time stamp for Received: banner */

static char received[] = "Received:";
static char receivedlen = sizeof( received) - 1;

/*--------------------------------------------------------------------*/
/* main program */
/*--------------------------------------------------------------------*/

void main(int argc, char **argv)
{
boolean ReadHeader = FALSE; /* TRUE = Parse RFC-822 headers */

int option; /* For parsing option list */
char **address; /* Pointer to list of target
addresses */
char *token;
size_t addressees; /* Number of targets in address */
size_t count; /* Loop variable for delivery */
size_t delivered = 0; /* Count of successfull deliveries */
boolean header = TRUE;
boolean DeleteInput = FALSE;

boolean daemon = FALSE;

char *subject = NULL;

/*--------------------------------------------------------------------*/
/* Make a copy of the Borland copyright for debugging purposes */
/*--------------------------------------------------------------------*/

#if defined(__CORE__)
copywrong = strdup(copyright);
checkref(copywrong);
#endif

banner( argv);

now = arpadate(); /* Set the current date */
debuglevel = -1; /* Set default so we can detect it */

/*--------------------------------------------------------------------*/
/* Load the UUPC/extended configuration file, and exit if any errors */
/*--------------------------------------------------------------------*/

if (!configure(B_MTA))
Terminate(3);

/*--------------------------------------------------------------------*/
/* Handle control-C interrupts */
/*--------------------------------------------------------------------*/

if( signal( SIGINT, ctrlchandler ) == SIG_ERR )
{
printmsg( 0, "Couldn't set SIGINT\n" );
panic();
}

/*--------------------------------------------------------------------*/
/* Begin logging messages */
/*--------------------------------------------------------------------*/

openlog( NULL );

/*--------------------------------------------------------------------*/
/* Parse our operand flags */
/*--------------------------------------------------------------------*/

while ((option = getopt(argc, argv, "ws:tF:f:x:")) != EOF)
{
switch (option) {
case 'w':
daemon = TRUE;
break;

case 's':
subject = optarg;
daemon = TRUE;
break;

case 't':
ReadHeader = TRUE;
break;

case 'x':
debuglevel = atoi(optarg);
break;

case 'F':
DeleteInput = TRUE;
case 'f':
namein = optarg;
datain = FOPEN(namein , "r",TEXT_MODE);
break;

case '?':
usage();
Terminate(4);
} /* switch */
} /* while */

if ( debuglevel > 1 )
{
for ( count = 1; (int) count < argc; count ++)
printmsg(4,"rmail argv[%d] = \"%s\"", count, argv[count] );
} /* if ( debuglevel > 4 ) */

if ((optind == argc) != ReadHeader)
{
puts("Missing/extra parameter(s) at end.");
Terminate(4);
}

remoteMail = ! (ReadHeader || daemon);
/* If not reading headers, must be in
normal rmail mode ... */

/*--------------------------------------------------------------------*/
/* If in local mode and the user doesn't want output, suppress */
/* routine delivery messages */
/*--------------------------------------------------------------------*/

if ( debuglevel == -1 )
{
if (remoteMail)
debuglevel = 1;
else
debuglevel = (int) bflag[F_VERBOSE];
}

/*--------------------------------------------------------------------*/
/* Verify we have input stream available */
/*--------------------------------------------------------------------*/

if (datain == NULL )
{
printerr(namein);
Terminate(6);
} /* if */

/*--------------------------------------------------------------------*/
/* Open up the output data stream */
/*--------------------------------------------------------------------*/

tempname = mktempname( NULL , "TMP");
dataout = FOPEN(tempname, "w",TEXT_MODE);

if (dataout == NULL)
{
printmsg(0,"Cannot open temporary file \"%s\" for output",
tempname);
Terminate(5);
} /* if */

/*--------------------------------------------------------------------*/
/* If in local mail mode, make up a list of addresses to mail to */
/*--------------------------------------------------------------------*/

if ( daemon )
{
addressees = argc - optind;
address = &argv[optind];
DaemonMail( subject, address, addressees );
header = FALSE;
}
else if (ReadHeader)
address = Parse822( &header, &addressees );
else {
ParseFrom(); /* Copy remote header instead */
addressees = argc - optind;
address = &argv[optind];
} /* if */

if ( addressees == 0 ) /* Can we deliver mail? */
{
printmsg(0, "No addressees to deliver to!");
Terminate( 2 ); /* No --> Execute punt formation */
}

/*--------------------------------------------------------------------*/
/* Copy the rest of the input file into our holding tank */
/*--------------------------------------------------------------------*/

header = CopyTemp( ) && header ;
if (header) /* Was the header ever terminated? */
{
printmsg(0,"rmail: Improper header, adding trailing newline");
fputc('\n', dataout); /* If not, it is now ... */
}

fclose(datain);
fclose(dataout);

if (DeleteInput) /* Make room for more data on disk */
remove(namein);

/*--------------------------------------------------------------------*/
/* Determine requestor node and user id for remote mail */
/*--------------------------------------------------------------------*/


/*--------------------------------------------------------------------*/
/* Perform delivery of the mail */
/*--------------------------------------------------------------------*/

while ((token = strpbrk(tempname ,"/")) != NULL)
*token = '\\';

for ( count = 0; count < addressees; count++)
if ( *address[count] == '-')
delivered ++; /* Ignore option flags on delivery */
else
delivered += Deliver(tempname, address[count], FALSE, TRUE);

/*--------------------------------------------------------------------*/
/* Terminate the program */
/*--------------------------------------------------------------------*/

printmsg(8,"rmail: %d addressees, delivered to %d mailboxes",
addressees, delivered);

if ( delivered >= addressees )
Terminate( 0 ); /* All mail delivered */
else if ( delivered == 0 )
Terminate( 2 ); /* No mail delivered */
else
Terminate (1 ); /* Some mail delivered */

} /* main */

/*--------------------------------------------------------------------*/
/* T e r m i n a t e */
/* */
/* Cleanup open files and return to operating system */
/*--------------------------------------------------------------------*/

static void Terminate( const int rc)
{
if (tempname != NULL) /* Did temporary file get named? */
{
if (datain != stdin) /* Non-standard input? */
fclose(stdin); /* Yes --> Close it */
remove(tempname); /* Purge temporary file, if exists */
} /* if */

exit( rc ); /* Return to operating systems */
} /* Terminate */

/*--------------------------------------------------------------------*/
/* P a r s e F r o m */

/* */
/* Read the from address of incoming data from UUCP */
/*--------------------------------------------------------------------*/

static void ParseFrom()
{
static char from[] = "From ";
static char remote[] = "remote from ";
static int remotelen = sizeof remote - 1;
static int fromlen = sizeof from - 1;
char *token;
char buf[BUFSIZ];
boolean hit;

/*--------------------------------------------------------------------*/
/* Use UUXQT Information, if available */
/*--------------------------------------------------------------------*/

token = getenv( UU_MACHINE );
if ( token == NULL )
*fromnode = '\0';
else {
strncpy( fromnode, token , sizeof fromnode );
fromnode[ sizeof fromnode - 1 ] = '\0';
}

fgets(buf, BUFSIZ , datain);
hit = equaln(buf, from, fromlen );

if (hit)
{
int nodelen = strlen( fromnode ) + 1; /* Plus ! */
char *s;
token = strtok( &buf[ fromlen ], " ");
s = strtok( NULL, "\n");

if (strlen( token ) + nodelen >= MAXADDR)
{
char *next;
token = strtok( token, "!" );

while ((next = strtok( NULL , "!")) != NULL )
{
token = next;
if (strlen( next ) + nodelen < MAXADDR)
break;
} /* while */
} /* if */

strncpy(fromuser, token , sizeof fromuser );
fromuser[ sizeof fromuser - nodelen ] = '\0';

if ( *fromnode == '\0')
{
while ( *s != '\0')
{
if equaln(s, remote, remotelen)
break;
else
s++;
} /* while */
strncpy( fromnode ,
(*s == '\0') ? E_nodename : s + remotelen ,
sizeof fromnode );
fromnode[ sizeof fromnode -1 ] = '\0';
} /* if ( *fromnode != '\0') */

} /* if */
else {
if ( *fromnode == '\0')
strcpy(fromnode, E_nodename );
strcpy(fromuser, "/dev/null");
} /* else */

/*--------------------------------------------------------------------*/
/* Generate required "From " and "Received" header lines */
/*--------------------------------------------------------------------*/

fprintf(dataout,"%-10s from %s by %s (%s %s) with UUCP;\n%-10s %s\n",
"Received:", fromnode, E_domain, compilep, compilev,
" ", now);

/*--------------------------------------------------------------------*/
/* If what we read wasn't a From line, write into the new file */
/*--------------------------------------------------------------------*/

if (!hit)
{
fputs(buf, dataout);
if (ferror(dataout))
{
printerr(tempname);
Terminate(6);
} /* if */
} /* if */

/*--------------------------------------------------------------------*/
/* Determine the requestor user id and node */
/*--------------------------------------------------------------------*/

token = getenv( UU_USER ); /* Get exactly what remote told us */

if ( token != NULL )
{ /* Use exactly what remote told us */
ruser = strtok( token , WHITESPACE );
rnode = strtok( NULL , WHITESPACE );
} /* else */

if ((rnode == NULL) || (strchr(rnode,'.') == NULL ))
/* Did it tell us the domain? */
{ /* No --> Use from information */
char node[MAXADDR];
char user[MAXADDR];

sprintf(buf ,"%s!%s", fromnode, fromuser);
user_at_node(buf , buf, node, user);
ruser = newstr( user );
rnode = newstr( node );
}

uuser = "uucp"; /* Effective id is always our daemon */

} /* ParseFrom */

/*--------------------------------------------------------------------*/
/* P a r s e 8 2 2 */
/* */
/* Parse an RFC-822 header generated by that esteemed mail user */
/* agent, UUPC/extended's MAIL. */
/* */
/* Note that we parse the header in the format we KNOW that UUPC */
/* generated it in: "To:", "Cc:", "Bcc:", optionally prefixed */
/* by "Resent-". We also know that mail comes in one address */
/* per line, and that the Resent- headers, if any, precede the */
/* original headers. */
/*--------------------------------------------------------------------*/

static char **Parse822( boolean *header,
size_t *count)
{

/*--------------------------------------------------------------------*/
/* Define the headers we will be examining and variables for their */
/* lengths */
/*--------------------------------------------------------------------*/

static char *to = "Resent-To:";
static char *cc = "Resent-Cc:";
static char *bcc = "Resent-Bcc:";
static char *resent = "Resent-";
static char *from = "Resent-From:";

size_t tolen;
size_t cclen;
size_t bcclen;
size_t resentlen = strlen(resent);
size_t offset = resentlen; /* Subscript for examining headers,
which allows us to ignore Resent- */
size_t fromlen = strlen( &from[offset] );
size_t allocated = 5; /* Reasonable first size for address */
/* Note: MUST BE AT LEAST 2 because we
add 50% below! */
boolean blind = FALSE;

char **addrlist = calloc( sizeof *addrlist , allocated);
char buf[BUFSIZ]; /* Input buffer for reading header */
char address[MAXADDR]; /* Buffer for parsed address */
char path[MAXADDR];
char *token; /* For parsing line in buf */
struct HostTable *hostp;

/*--------------------------------------------------------------------*/
/* Begin processing */
/*--------------------------------------------------------------------*/

*count = 0; /* No addresses discovered yet */
checkref(addrlist); /* Verify we had room for the list */

fprintf(dataout,"%-10s by %s (%s %s);\n%-10s %s\n",
"Received:",E_domain,compilep, compilev,
" ", now );

/*--------------------------------------------------------------------*/
/* Find the From: line */
/*--------------------------------------------------------------------*/

do {
if (fgets( buf, BUFSIZ, datain) == NULL) /* End of file? */
return NULL; /* Yes --> Very bad, report error */
fputs(buf, dataout );
if (*buf == '\n') /* End of the header? */
return NULL; /* Yes --> Very bad, report error */
else if (equalni(resent, buf, resentlen))
{
offset = 0;
fromlen = strlen(&from[offset]);
} /* if */
else if (equalni(received, buf, receivedlen))
hops++;
} while (!equalni(&from[offset], buf, fromlen));

strtok( buf , WHITESPACE); /* Drop the leading token */
token = strtok( NULL, "\n"); /* Get the token with From: addr */
ExtractAddress( address, token, FALSE );
/* Get the From: address itself */
user_at_node(address, path, fromnode, fromuser);
/* Separate portions of the address */

/*--------------------------------------------------------------------*/
/* Generate a Sender: line if we need it */
/*--------------------------------------------------------------------*/

if (equal(fromnode,HostAlias(E_fdomain))) /* Same as hidden site? */
strcpy(fromnode, E_nodename);/* Yes --> Declare as local system */

hostp = checkname( fromnode ); /* Look up real system name */

if (!equal(fromuser,E_mailbox) ||
(hostp == BADHOST) || (hostp->hstatus != localhost))
{
sprintf(buf, "%s <%s@%s>", E_name, E_mailbox, E_fdomain );
PutHead("Sender:", buf, dataout , offset == 0 );
} /* if */

/*--------------------------------------------------------------------*/
/* Set UUCP requestor name while we've got the information */
/*--------------------------------------------------------------------*/

if ((hostp != BADHOST) && (hostp->hstatus == localhost))
rnode = bflag[F_BANG] ? E_nodename : E_fdomain;
/* Use full domain address, if possible */
else
rnode = fromnode;

uuser = ruser = fromuser; /* User and requestor always the same
for locally generated mail */

/*--------------------------------------------------------------------*/
/* Generate a message-id */
/*--------------------------------------------------------------------*/

sprintf(buf, "<%lx.%s@%s>", time( NULL ) , E_nodename, E_domain);
PutHead("Message-ID:", buf, dataout , offset == 0 );
PutHead(NULL, NULL, dataout , FALSE );

/*--------------------------------------------------------------------*/
/* Locate the To: or Resent-To: line */
/*--------------------------------------------------------------------*/

tolen = strlen( &to[offset] );

do {
if (fgets( buf, BUFSIZ, datain ) == NULL) /* End of file? */
return NULL; /* Yes --> Very bad, report error */
fputs(buf, dataout );
if (*buf == '\n') /* End of the header? */
return NULL; /* Yes --> Very bad, report error */
else if (equalni(received, buf, receivedlen))
hops++;
} while ( !equalni(&to[offset] , buf , tolen ));

token = strpbrk( buf ," \t");

/*--------------------------------------------------------------------*/
/* Proccess the rest of the addressees */
/*--------------------------------------------------------------------*/

cclen = strlen( &cc[offset] );
bcclen = strlen( &bcc[offset] );

do {
if (allocated == (*count+1)) /* Do we have room for addr? */
{
allocated += allocated / 2; /* Choose larger array size */
addrlist = realloc( addrlist ,
allocated * sizeof( *addrlist ));
checkref(addrlist); /* Verify the allocation worked */
} /* if */

ExtractAddress( address, token, FALSE ); /* Get address itself*/
if (!strlen(address))
{
printmsg(0,"Could not locate expected address in header");
*count = 0;
return NULL;
} /* if */
else {
addrlist[*count] = newstr( address );
/* Save permanent copy of address */
checkref( addrlist[*count] ); /* Verify strdup worked */
printmsg(4,"address[%d]= \"%s\"",*count, address);
*count += 1; /* Flag we got the address */
} /* else */

if (fgets( buf, BUFSIZ, datain ) == NULL) /* End of file? */
token = NULL; /* Yes --> Odd, but no major problem */
else if (*buf == '\n') /* End of the header? */
{
token = NULL; /* Yes --> Exit loop */
*header = FALSE; /* Report to caller the header is done */
blind = FALSE; /* Denote not a blind header */
}
else if (isspace(*buf)) /* Another address? */
token = buf; /* Yes --> Write it out */
else { /* No --> Determine what next header is*/
blind = FALSE; /* Assume not a blind header */
if (equalni(&cc[offset], buf, cclen)) /* Cc: header? */
token = strpbrk(buf," \t");
else if (equalni(&bcc[offset], buf, bcclen)) /* Bcc: header?*/
{
token = strpbrk(buf ," \t");
blind = TRUE;
} /* if */
else /* Unsupported header, exit loop */
token = NULL;
} /* else */
if ( ! blind )
fputs(buf, dataout );
} while (token != NULL );

/*--------------------------------------------------------------------*/
/* Return address list to caller */
/*--------------------------------------------------------------------*/

return addrlist;

} /* Parse822 */

/*--------------------------------------------------------------------*/
/* C o p y T e m p */
/* */
/* Copy the un-parsed parts of a message into the holding file */
/*--------------------------------------------------------------------*/

static boolean CopyTemp( void )
{
boolean header = TRUE;
char buf[BUFSIZ];
boolean newline = TRUE;

while (fgets(buf, BUFSIZ, datain) != NULL)
{
if (header)
{
if (*buf == '\n')
header = FALSE;
else if (equalni(received, buf, receivedlen))
hops++;
}

newline = buf[ strlen( buf ) - 1 ] == '\n';

if (fputs(buf, dataout) == EOF) /* I/O error? */
{
printerr(tempname);
printmsg(0,"I/O error on \"%s\"", tempname);
fclose(dataout);
return FALSE;
} /* if */
} /* while */

if (ferror(datain)) /* Clean end of file on input? */
{
printerr(namein);
Terminate(7);
}

if ( !newline ) /* Is the file terminated properly? */
{
printmsg(0, "rmail: Improperly formed message, adding final newline!");
fputc( '\n', dataout );
}

return header;
} /* CopyTemp */

/*--------------------------------------------------------------------*/
/* D a e m o n M a i l */
/* */
/* Send text in a mailbag file to address(es) specified by address */
/*--------------------------------------------------------------------*/

static boolean DaemonMail( const char *subject,
char **address,
int count )
{
char buf[BUFSIZ];
char *logname;
char *token;
char *moi = NULL;
struct UserTable *userp;
char *header = "To:";
char *cc = "Cc:";
boolean print = TRUE;

/*--------------------------------------------------------------------*/
/* Validate the input */
/*--------------------------------------------------------------------*/

if ( count == 0 )
{
printmsg(0,"rmail: No addresseses to deliver to!");
return FALSE;
}

/*--------------------------------------------------------------------*/
/* Determine our user id */
/*--------------------------------------------------------------------*/

logname = getenv( LOGNAME );
if ( logname == NULL )
logname = E_mailbox;

/*--------------------------------------------------------------------*/
/* Get the name of the user, or make one up */
/*--------------------------------------------------------------------*/

userp = checkuser(logname); /* Locate user id in host table */

if ( (userp != BADUSER) &&
(userp->realname != NULL) &&
!equal(userp->realname, EMPTY_GCOS ))
moi = userp->realname;
else if ( equali(logname, E_postmaster) || equali(logname, POSTMASTER))
moi = "Postmaster";
else if ( equali( logname, "uucp" ))
moi = "Unix to Unix Copy";
else
moi = logname; /* Dummy to ease formatting From: line */

/*--------------------------------------------------------------------*/
/* Add the boilerplate the front: */
/* */
/* Date, From, Organization, and Reply-To */
/*--------------------------------------------------------------------*/

fprintf(dataout,"%-10s by %s (%s %s);\n%-10s %s\n",
"Received:",E_domain,compilep, compilev,
" ", now );

/*--------------------------------------------------------------------*/
/* Generate a message-id */
/*--------------------------------------------------------------------*/

sprintf(buf, "<%lx.%s@%s>", time( NULL ) , E_nodename, E_domain);
PutHead("Message-ID:", buf, dataout , FALSE );
PutHead(NULL, NULL, dataout , FALSE );

PutHead("Date:", arpadate() , dataout, FALSE);

if (bflag[F_BANG])
sprintf(buf, "(%s) %s!%s", moi, E_nodename, logname );
else {
checkname( E_nodename ); /* Force loading of the E_fdomain name */
sprintf(buf, "\"%s\" <%s@%s>", moi, logname , E_fdomain );
}

PutHead("From:", buf, dataout, FALSE );

if (E_organization != NULL )
PutHead("Organization:", E_organization, dataout, FALSE);

/*--------------------------------------------------------------------*/
/* Write the address out */
/*--------------------------------------------------------------------*/

while( (count-- > 0) && print )
{
token = *address++;
if ( *token == '-') /* Option flag? */
{
if (token[1] == 'c')
{
header = cc;
cc = "";
}
else if (token[1] == 'b')
print = FALSE;
else
printmsg(0,"rmail: Invalid flag \"%s\" ignored!", token);
} /* if ( token == '-') */
else if ( print )
{
if (strpbrk(token,"!@") == nil(char))
{
if (bflag[F_BANG])
sprintf(buf, "%s!%s", E_nodename, token );
else
sprintf(buf, "%s@%s", token , E_fdomain );
token = buf;
}

PutHead(header , token, dataout, FALSE);
header = ""; /* Continue same field by default */
}
} /* while( (count-- > 0) && print ) */

/*--------------------------------------------------------------------*/
/* Handle the subject, if any */
/*--------------------------------------------------------------------*/

if (subject != NULL)
PutHead("Subject:", subject, dataout, FALSE);

PutHead(NULL, "", dataout, FALSE); /* Terminate the header line */
PutHead(NULL, "", dataout, FALSE); /* Terminate the header file */

/*--------------------------------------------------------------------*/
/* Return to caller */
/*--------------------------------------------------------------------*/

uuser = ruser = strncpy(fromuser, logname, sizeof fromuser);
/* Define user for UUCP From line */
fromuser[ sizeof fromuser - 1 ] = '\0';
rnode = bflag[F_BANG] ? E_nodename : E_fdomain;
/* Use full domain address, if possible */

strcpy(fromnode, E_nodename);/* Declare as local system */
return TRUE;

} /*DaemonMail*/

/*--------------------------------------------------------------------*/
/* P u t H e a d */
/* */
/* Write one line of an RFC-822 header */
/*--------------------------------------------------------------------*/

static void PutHead( const char *label,
const char *operand,
FILE *stream,
const boolean resent)
{
static boolean terminate = TRUE;

if (label == NULL ) /* Terminate call? */
{ /* Yes --> Reset Flag and return */
fputc('\n', stream); /* Terminate the current line */
terminate = TRUE;
return;
} /* if */

if (strlen(label)) /* First line of a header? */
{
if (!terminate) /* Terminate previous line? */
fputc('\n', stream);

if (resent)
fprintf(stream,"Resent-%s %s",label, operand);
else
fprintf(stream,"%-10s %s",label, operand);
terminate = FALSE; /* Flag that we did not end file */
} /* if */
else /* Continuing line */
fprintf(stream,",\n%-10s %s",label, operand);
} /* PutHead */

/*--------------------------------------------------------------------*/
/* u s a g e */
/* */
/* Report how the program works */
/*--------------------------------------------------------------------*/

static void usage( void )
{

static char syntax[] =
"Usage:\tRMAIL\t-t [-x debug] [-f | -F file]\n"
"\t\t-w [-x debug] [-f | -F file] [-s subject] addr1 [-c] addr2 [-b] addr3 ...\n"
"\t\t[-x debug] [-f | -F file] addr1 addr2 addr3 ...\n";

puts( syntax );
exit(3);
}


  3 Responses to “Category : UNIX Files
Archive   : UUPC11YS.ZIP
Filename : RMAIL.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/