NetBSD/gnu/dist/postfix/local/delivered.c

145 lines
3.4 KiB
C

/*++
/* NAME
/* delivered 3
/* SUMMARY
/* process Delivered-To: headers
/* SYNOPSIS
/* #include "local.h"
/*
/* HTABLE *delivered_init(attr)
/* DELIVER_ATTR attr;
/*
/* int delivered_find(table, address)
/* HTABLE *table;
/* char *address;
/*
/* void delivered_free(table)
/* HTABLE *table;
/* DESCRIPTION
/* This module processes addresses in Delivered-To: headers.
/* These headers are added by some mail delivery systems, for the
/* purpose of breaking mail forwarding loops. N.B. This solves
/* a different problem than the Received: hop count limit. Hop
/* counts are used to limit the impact of mail routing problems.
/*
/* delivered_init() extracts Delivered-To: header addresses
/* from the specified message, and returns a table with the
/* result.
/*
/* delivered_find() looks up the address in the lookup table,
/* and returns non-zero when the address was found. The
/* address argument must be in internalized form.
/*
/* delivered_free() releases storage that was allocated by
/* delivered_init().
/*
/* Arguments:
/* .IP state
/* The attributes that specify the message, recipient and more.
/* .IP table
/* A table with extracted Delivered-To: addresses.
/* .IP address
/* A recipient address, internal form.
/* DIAGNOSTICS
/* Fatal errors: out of memory.
/* SEE ALSO
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
/* Utility library. */
#include <msg.h>
#include <htable.h>
#include <vstring.h>
#include <vstream.h>
#include <vstring_vstream.h>
#include <stringops.h>
/* Global library. */
#include <record.h>
#include <rec_type.h>
#include <is_header.h>
#include <quote_822_local.h>
#include <header_opts.h>
/* Application-specific. */
#include "local.h"
static VSTRING *buf;
#define STR vstring_str
/* delivered_init - extract delivered-to information from the message */
HTABLE *delivered_init(DELIVER_ATTR attr)
{
char *cp;
HTABLE *table = htable_create(0);
HEADER_OPTS *hdr;
if (buf == 0)
buf = vstring_alloc(10);
if (vstream_fseek(attr.fp, attr.offset, SEEK_SET) < 0)
msg_fatal("seek queue file %s: %m", VSTREAM_PATH(attr.fp));
/*
* XXX Assume that normal mail systems produce headers that fit in a
* REC_TYPE_NORM record. Lowercase the delivered-to addresses for
* consistency.
*/
while (rec_get(attr.fp, buf, 0) == REC_TYPE_NORM) {
if (is_header(STR(buf))) {
if ((hdr = header_opts_find(STR(buf))) != 0
&& hdr->type == HDR_DELIVERED_TO) {
cp = STR(buf) + strlen(hdr->name) + 1;
while (ISSPACE(*cp))
cp++;
lowercase(cp);
if (msg_verbose)
msg_info("delivered_init: %s", cp);
htable_enter(table, cp, (char *) 0);
}
} else if (ISSPACE(STR(buf)[0])) {
continue;
} else {
break;
}
}
return (table);
}
/* delivered_find - look up recipient in delivered table */
int delivered_find(HTABLE *table, char *address)
{
HTABLE_INFO *ht;
/*
* mail_copy() uses quote_822_local() when writing the Delivered-To:
* header. We must therefore apply the same transformation when looking
* up the recipient. Lowercase the delivered-to address for consistency.
*/
quote_822_local(buf, address);
lowercase(STR(buf));
ht = htable_locate(table, STR(buf));
return (ht != 0);
}