📄 deliver.c
字号:
/*--------------------------------------------------------------------*/
/* d e l i v e r . c */
/* */
/* UUPC/extended mail delivery subroutines */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* Changes Copyright (c) 1989-1993 by Kendra Electronic */
/* Wonderworks. */
/* */
/* All rights reserved except those explicitly granted by the */
/* UUPC/extended license agreement. */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* RCS Information */
/*--------------------------------------------------------------------*/
/*
* $Id: deliver.c 1.16 1993/09/23 03:26:51 ahd Exp $
*
* $Log: deliver.c $
* Revision 1.16 1993/09/23 03:26:51 ahd
* Alter bounce message for "no path to host" error
*
* Revision 1.15 1993/09/20 04:41:54 ahd
* OS/2 2.x support
*
* Revision 1.14 1993/08/02 03:24:59 ahd
* Further changes in support of Robert Denny's Windows 3.x support
*
* Revision 1.13 1993/07/31 16:26:01 ahd
* Changes in support of Robert Denny's Windows support
*
* Revision 1.12 1993/06/21 02:17:31 ahd
* Correct errors in mail routing via HOSTPATH
*
* Revision 1.11 1993/06/13 14:06:00 ahd
* Save invoked program name and use it for recursive calls
* Loosen up bounced mail copy loop to avoid NT crashes
*
* Revision 1.10 1993/05/30 00:01:47 ahd
* Expand path of system alias files to allow userid references
*
* Revision 1.9 1993/05/06 03:41:48 ahd
* Don't rebounce mail to the postmaster
* Change directories as needed to provide reasonable default drives
* Do not use possibly invalid home directory to push directory on
* system aliases
*
* Revision 1.8 1993/05/03 02:41:57 ahd
* Make deliver not rebounce mail to the postmonstor
*
* Revision 1.7 1993/04/16 12:55:36 dmwatt
* Windows/NT sound support
*
* Revision 1.6 1993/04/15 03:17:21 ahd
* Basic bounce support
*
* Revision 1.5 1993/04/11 00:33:05 ahd
* Global edits for year, TEXT, etc.
*
* Revision 1.4 1992/12/18 13:05:18 ahd
* Use one token on request line for UUCP
*
* Revision 1.3 1992/12/05 23:38:43 ahd
* Skip blanks as well as unprintable characters
*
* Revision 1.2 1992/12/04 01:00:27 ahd
* Add system alias support
*
*/
/*--------------------------------------------------------------------*/
/* Embedded Japanese support provided by Kenji Rikitake */
/* 28-AUG-1991 */
/* */
/* On Japanese support: */
/* */
/* Japanese MS-DOS uses a 2byte Kanji (Japanese ideogram) code */
/* called "Shift-JIS". This cannot be delivered via SMTP since */
/* Shift-JIS maps its first byte from 0x80-0x9f and 0xe0-0xfc. */
/* JUNET requests all hosts to send Kanji in a 7bit subset of */
/* ISO2022. This is commonly called "JIS 7bit". */
/* */
/* To provide Japanese functionality, you need to convert all */
/* remote delivery messages to JIS 7bit, and all local delivery */
/* messages to Shift-JIS. */
/*--------------------------------------------------------------------*/
#define INCLUDE ":include:"
/*--------------------------------------------------------------------*/
/* System include files */
/*--------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <ctype.h>
#include <sys/types.h>
#include <string.h>
#include <process.h>
#include <limits.h>
/*--------------------------------------------------------------------*/
/* UUPC/extended include files */
/*--------------------------------------------------------------------*/
#include "lib.h"
#include "address.h"
#include "deliver.h"
#include "expath.h"
#include "execute.h"
#include "getseq.h"
#include "kanjicnv.h"
#include "hlib.h"
#include "hostable.h"
#include "import.h"
#include "pushpop.h"
#include "security.h"
#include "stater.h"
#include "usertabl.h"
#include "sysalias.h"
#include "timestmp.h"
#include "trumpet.h"
/*--------------------------------------------------------------------*/
/* Define current file name for panic() and printerr() */
/*--------------------------------------------------------------------*/
currentfile();
/*--------------------------------------------------------------------*/
/* Internal prototypes */
/*--------------------------------------------------------------------*/
static size_t DeliverLocal( const char *input, /* Input file name */
char *user, /* Target address */
const boolean sysalias,
/* Already sys alias */
boolean validate); /* Validate/forward
local mail */
static int DeliverFile( const char *input,
const char *mboxname,
const long start,
const long end,
boolean *announce,
struct UserTable *userp,
const boolean sysalias, /* Already sys alias */
const boolean validate,
const char *user );
static size_t DeliverRemote( const char *input, /* Input file name */
const char *address, /* Target address */
const char *path);
static size_t DeliverGateway( const char *input,
const char *user,
const char *node,
const struct HostTable *hostp,
const boolean validate );
static int CopyData( const boolean remotedelivery,
const char *input,
FILE *mbox);
static char *stats( const char *fname );
size_t Bounce( const char *input,
const char *text,
const char *data,
const char *address,
const boolean validate );
/*--------------------------------------------------------------------*/
/* Global (set by rmail.c) for number of hops this mail has seen */
/*--------------------------------------------------------------------*/
KEWSHORT hops = 0;
boolean remoteMail = FALSE;
char *ruser = NULL;
char *rnode = NULL;
char *uuser = NULL;
/*--------------------------------------------------------------------*/
/* D e l i v e r */
/* */
/* Deliver mail to one user */
/*--------------------------------------------------------------------*/
size_t Deliver( const char *input, /* Input file name */
char *address, /* Target address */
const boolean sysalias, /* Already sys alias */
boolean validate) /* Validate/forward
local mail */
{
char node[MAXADDR];
char path[MAXADDR];
char user[MAXADDR];
char *token;
struct HostTable *hostp;
if ( strlen( address ) >= MAXADDR )
return Bounce( input,
"Excessive address length",
address,
address,
validate );
user_at_node(address, path, node, user);
/*--------------------------------------------------------------------*/
/* Handle local delivery */
/*--------------------------------------------------------------------*/
if (equal(path, E_nodename)) /* Local node? */
{
struct HostTable *hostx = checkname( node );
if (hostx->hstatus == localhost) /* Really the local node? */
return DeliverLocal( input, user, sysalias, validate );
/* Yes! */
else
return Bounce( input,
"No known delivery path for host",
address,
address,
validate );
} /* if */
/*--------------------------------------------------------------------*/
/* Do we need loop protection? */
/*--------------------------------------------------------------------*/
if (hops > E_maxhops)
return Bounce(input,
"Excessive number of hops",
address,
address,
validate );
/*--------------------------------------------------------------------*/
/* Deliver to a gateway if needed */
/*--------------------------------------------------------------------*/
hostp = checkname( path );
if ( (hostp != BADHOST) && (hostp->hstatus == gatewayed))
return DeliverGateway( input, user, node, hostp, validate );
/*--------------------------------------------------------------------*/
/* Deliver mail to a system directory connected to us */
/*--------------------------------------------------------------------*/
if (equal(path,node)) /* Directly connected system? */
return DeliverRemote( input, user, path); /* Yes */
/*--------------------------------------------------------------------*/
/* Default delivery; strip any this node and the directly */
/* connected system from the address, then deliver to the next */
/* hop on the route */
/*--------------------------------------------------------------------*/
strcpy(node,address);
token = strtok(node,"!"); /* Get first host in path */
if (equal( HostAlias(token), E_nodename)) /* Local system? */
{
token = strtok(NULL,""); /* Yes --> Get rest of addr */
strcpy(address, token); /* Use it for address */
token = strtok(token,"!"); /* Get next host in path */
} /* if */
if (equal( HostAlias(token), path )) /* Next system? */
{
token = strtok(NULL,""); /* Yes --> Get rest of addr */
strcpy(address, token); /* Use it for address */
} /* if */
if (!strpbrk(address,"!@")) /* Any host delimiters? */
{ /* No --> Check for % routing */
token = strrchr(address,'%'); /* Get last percent sign */
if (token != NULL)
*token = '@'; /* Make it an RFC-822 address */
else
printmsg(0,"Deliver: Cannot find node in \"%s\"",
address); /* That's odd, it should not */
/* be a local address! */
} /* if */
return DeliverRemote( input, address, path );
} /* Deliver */
/*--------------------------------------------------------------------*/
/* D e l i v e r L o c a l */
/* */
/* Handle local delivery, including optional forwarding */
/*--------------------------------------------------------------------*/
static size_t DeliverLocal( const char *input,
/* Input file name */
char *user, /* Target address */
const boolean sysalias,
/* Already sys alias */
boolean validate) /* TRUE = validate,
forward user's mail */
{
char mboxname[FILENAME_MAX];
struct UserTable *userp = NULL;
ALIASTABLE *aliasp = NULL;
int delivered = 0;
boolean announce = FALSE;
FILE *mbox;
/*--------------------------------------------------------------------*/
/* If the parameter is the postmaster, use the configuration */
/* defined value for the postmaster */
/*--------------------------------------------------------------------*/
if (equali(user, POSTMASTER))
user = E_postmaster;
/*--------------------------------------------------------------------*/
/* Validate user id and check for forwarding */
/*--------------------------------------------------------------------*/
if (validate)
{
validate = strcmp( E_postmaster , user);
/* Don't loop delivering to postmast*/
userp = checkuser(user); /* Locate user id in host table */
/*--------------------------------------------------------------------*/
/* Process any system aliases */
/*--------------------------------------------------------------------*/
if ( ! sysalias )
{
aliasp = checkalias( user ); /* System alias? */
if ( aliasp != NULL )
{
delivered += DeliverFile( input,
SysAliases,
aliasp->start,
aliasp->end,
&announce ,
userp,
TRUE,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -