📄 rmail.c
字号:
/*--------------------------------------------------------------------*/
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))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -