📄 rmail.c
字号:
/*--------------------------------------------------------------------*/
/* 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.13 1993/09/20 04:39:51 ahd Exp $
*
* $Log: rmail.c $
* Revision 1.13 1993/09/20 04:39:51 ahd
* OS/2 2.x support
*
* Revision 1.12 1993/07/31 16:22:16 ahd
* Changes in support of Robert Denny's Windows 3.x support
*
* Revision 1.11 1993/07/24 03:40:55 ahd
* Make usage() return code unique
*
* Revision 1.10 1993/06/13 14:06:00 ahd
* Save invoked program name and use it for recursive calls
*
* Revision 1.9 1993/05/09 03:41:47 ahd
* Don't use debuglevel -1, it suppresses important configuration errors
*
* 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 <stdio.h>
#include <ctype.h>
#include <io.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#ifdef _Windows
#include <windows.h>
#endif
/*--------------------------------------------------------------------*/
/* 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"
#ifdef _Windows
#include "winutil.h"
#endif
/*--------------------------------------------------------------------*/
/* 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 */
char *myProgramName = NULL; // Name for recursive invocation
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 */
int user_debug = -1;
boolean header = TRUE;
boolean DeleteInput = FALSE;
boolean daemon = FALSE;
char *subject = NULL;
myProgramName = newstr( argv[0] ); // Copy before banner() mangles it
/*--------------------------------------------------------------------*/
/* Make a copy of the Borland copyright for debugging purposes */
/*--------------------------------------------------------------------*/
#if defined(__CORE__)
copywrong = strdup(copyright);
checkref(copywrong);
#endif
logfile = stderr; // Prevent redirection of error
// messages during configuration
banner( argv);
now = arpadate(); /* Set the current date */
debuglevel = 0;
/*--------------------------------------------------------------------*/
/* 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':
user_debug = 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);
}
#if defined(_Windows)
atexit( CloseEasyWin ); // Auto-close EasyWin on exit
#endif
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 (( user_debug == -1 ) && (debuglevel == 0))
{
if (remoteMail)
debuglevel = 1;
else
debuglevel = (int) bflag[F_VERBOSE];
}
/*--------------------------------------------------------------------*/
/* Verify we have input stream available */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -