In article <Pine.SOL.4.44.0203061058110.24317-100000@???>,
Philip Hazel <ph10@???> wrote:
>On Wed, 6 Mar 2002, Miquel van Smoorenburg wrote:
>
>> It adds a member "dupbackptr" to struct address_item. For every
>> duplicate found, dupbackptr is set to the struct address_item
>> it is a duplicate from (hmm, perhaps 'dupfrom' is a better name).
>>
>That's certainly one way of achieving what you want. Doing what some
>other people want (not dropping duplicates) would require fundamental
>redesign to incorporate a unique identification for each address
>(currently it's the address itself). I had been thinking of that
>problem when considering how hard this change would be.
Ok, I see. I'm just caring about the Envelope-to: header here.
You know what it's used for; to make it possible to re-deliver
mail already delivered in a mailbox. It has to preserve the
correct envelope-to.
>> - in a .forward file of the following structure:
>>
>> myself
>> other_user
>>
>> which is meant to keep a local copy and send a copy to 'other_user',
>> it would be desireable to set the envelope-to header for the copy
>> delivered to 'other_user' to 'other_user' instead of 'myself' since
>> the message is in fact re-sent.
>
>I disagree with this. Envelope-to is supposed to represent the envelope
>that caused this delivery. Forwarding is redirecting rather than
>resending. If you want to resend, you can use procmail and really resend.
I can see that .. now I've done something that you are probably
going to hate, so please be gentle with me ;) I've added the syntax
!address which is somewhat \address in that it adds a flag to do
something special. It means 'set-envelope-to-header'.
Now if you use !address in a forward or alias file, it means that
for that delivery *that* address is added to the envelope-to header.
So in this situation:
# aliases
testalias1: stuser
testalias2: stuser
# .forward file of "stuser"
stuser
!miquels
if I send mail to testalias1,testalias2 then the Envelope-to in the
'stuser' mailbox will have "testalias1,testalias2" while the
Envelope-to: header in the 'miquels' mailbox will have just 'miquels'.
In other words, that provides control over _just_ the envelope-to header.
It doesn't change anything else in directing or routing.
Even though I think you'll have your reservations I'm still
going to attach the patch ;)
By the way, exim isn't really indented the way I'm used to, yet
it's pretty easy to find my way around it. It's really nicely coded.
diff -ruN o/exim-3.34/src/deliver.c exim-3.34/src/deliver.c
--- o/exim-3.34/src/deliver.c Wed Dec 19 12:50:27 2001
+++ exim-3.34/src/deliver.c Wed Mar 6 00:28:10 2002
@@ -81,6 +81,7 @@
NULL, /* parent */
NULL, /* shadow_parent */
NULL, /* first */
+ NULL, /* dupbackptr */
0, /* flags */
NULL, /* onetime_parent */
NULL, /* orig */
@@ -3679,6 +3680,7 @@
int process_recipients = RECIP_ACCEPT;
open_db dbblock;
open_db *dbm_file;
+tree_node *tnode;
if (queue_run_pid == (pid_t)0)
{
@@ -4396,11 +4398,12 @@
addr->unique = string_sprintf(">%s", addr->unique);
}
- else if (tree_search(tree_duplicates, addr->unique) != NULL)
+ else if ((tnode = tree_search(tree_duplicates, addr->unique)) != NULL)
{
DEBUG(9) debug_printf("%s is a duplicate address: discarded\n",
addr->orig);
addr->next = addr_duplicate;
+ addr->dupbackptr = tnode->data.ptr;
addr_duplicate = addr;
continue;
}
@@ -4419,7 +4422,7 @@
/* Save for checking future duplicates */
- tree_add_duplicate(addr->unique, TRUE);
+ tree_add_duplicate(addr->unique, addr, TRUE);
/* Set local part and domain */
@@ -4630,19 +4633,20 @@
/* Check for duplication. Remember duplicated addresses so they can
be marked "delivered" when the duplicate is delivered. */
- if (tree_search_addr(tree_duplicates, addr->unique,
- testflag(addr, af_pfr)) != NULL)
+ if ((tnode = tree_search_addr(tree_duplicates, addr->unique,
+ testflag(addr, af_pfr))) != NULL)
{
DEBUG(9) debug_printf("%s is a duplicate address: discarded\n",
addr->unique);
addr->next = addr_duplicate;
+ addr->dupbackptr = tnode->data.ptr;
addr_duplicate = addr;
continue;
}
/* Remember the first, to check for subsequent duplicates. */
- tree_add_duplicate(addr->unique, testflag(addr, af_pfr));
+ tree_add_duplicate(addr->unique, addr, testflag(addr, af_pfr));
/* If the address is local, check on directing retry status, and add
either to the directing chain or the defer chain. */
diff -ruN o/exim-3.34/src/functions.h exim-3.34/src/functions.h
--- o/exim-3.34/src/functions.h Wed Dec 19 12:50:28 2001
+++ exim-3.34/src/functions.h Wed Mar 6 00:21:03 2002
@@ -266,7 +266,7 @@
extern BOOL transport_write_string(int, char *, ...);
extern BOOL transport_write_message(address_item *, int, int, int, char *,
char *, char *, char *, rewrite_rule *, int);
-extern void tree_add_duplicate(char *, BOOL);
+extern void tree_add_duplicate(char *, address_item *, BOOL);
extern void tree_add_nonrecipient(char *, BOOL);
extern void tree_add_unusable(host_item *);
extern int tree_insertnode(tree_node **, tree_node *);
diff -ruN o/exim-3.34/src/parse.c exim-3.34/src/parse.c
--- o/exim-3.34/src/parse.c Wed Dec 19 12:50:29 2001
+++ exim-3.34/src/parse.c Wed Mar 6 13:25:05 2002
@@ -1380,6 +1380,7 @@
else
{
int start, end, domain;
+ int extraflag = 0;
char *recipient = NULL;
int save = s[len];
s[len] = 0;
@@ -1398,6 +1399,14 @@
string_sprintf("%s@%s", recipient, incoming_domain);
}
+ /* If it starts with '!' it means 'set envelope-to'. */
+ if (*s == '!')
+ {
+ recipient =
+ parse_extract_address(s+1, error, &start, &end, &domain, FALSE);
+ if (recipient != NULL) extraflag = af_set_envto_hdr;
+ }
+
/* Try parsing the item as an address. */
if (recipient == NULL) recipient =
@@ -1485,6 +1494,7 @@
store_pool = POOL_MAIN;
addr = deliver_make_addr(recipient, TRUE); /* TRUE => copy recipient */
store_pool = pool_reset;
+ if (addr) addr->flags |= extraflag;
}
/* Restore the final character in the original data, and add to the
diff -ruN o/exim-3.34/src/structs.h exim-3.34/src/structs.h
--- o/exim-3.34/src/structs.h Wed Dec 19 12:50:30 2001
+++ exim-3.34/src/structs.h Wed Mar 6 13:25:04 2002
@@ -500,6 +500,7 @@
struct address_item *parent; /* parent address */
struct address_item *shadow_parent; /* parent when shadow delivering */
struct address_item *first; /* point to first after group delivery */
+ struct address_item *dupbackptr; /* if dup, points back to active addr */
unsigned int flags; /* a row of bits, defined below */
char *onetime_parent; /* saved original parent for onetime */
char *orig; /* as read from the spool */
@@ -578,6 +579,7 @@
#define af_rewrite_headers 0x00010000 /* set TRUE by routers that want it done */
#define af_uid_set 0x00020000 /* uid field is set */
#define af_hide_child 0x00040000 /* hide child in bounce/defer msgs */
+#define af_set_envto_hdr 0x00080000 /* set Envelope_to: to this address */
/* Tables of normal and resent- header names consist of items of this type */
diff -ruN o/exim-3.34/src/transport.c exim-3.34/src/transport.c
--- o/exim-3.34/src/transport.c Wed Dec 19 12:50:31 2001
+++ exim-3.34/src/transport.c Wed Mar 6 13:56:43 2002
@@ -536,7 +536,14 @@
struct aci *plist = NULL;
void *reset_point = store_get(0);
- for (pp = p; pp->parent != NULL; pp = pp->parent);
+ /* Loop over all parents, any of them might match a dupbackptr
+ in the add_duplicate list. Yes we should indent this better
+ but the patch is clearer this way, I think ;) */
+
+ for (pp = p; pp->parent != NULL; pp = pp->parent)
+ {
+
+ if (pp->flags & af_set_envto_hdr) break;
/* Scan for any duplicates that relate to this address, and include their
ultimate parents. However, we want to avoid duplication in the list,
@@ -547,19 +554,20 @@
for (dup = addr_duplicate; dup != NULL; dup = dup->next)
{
- if (strcmpic(dup->orig, p->orig) == 0)
+ if (dup->dupbackptr == pp)
{
address_item *dup_orig;
struct aci *ppp;
for (dup_orig = dup; dup_orig->parent != NULL;
- dup_orig = dup_orig->parent);
+ dup_orig = dup_orig->parent)
+ if (dup_orig->flags & af_set_envto_hdr) break;
/* If the parent is the parent of the main address item, skip it.
Otherwise, scan the list of already output parents, and skip if
we've done this one already. */
- if (dup_orig == pp) continue;
+ /*if (dup_orig == pp) continue;*/
for (ppp = plist; ppp != NULL; ppp = ppp->next)
{
if (dup_orig == ppp->ptr) break;
@@ -581,6 +589,7 @@
len = 0;
}
}
+ }
store_reset(reset_point);
diff -ruN o/exim-3.34/src/tree.c exim-3.34/src/tree.c
--- o/exim-3.34/src/tree.c Wed Dec 19 12:50:31 2001
+++ exim-3.34/src/tree.c Wed Mar 6 00:23:57 2002
@@ -85,11 +85,11 @@
*/
void
-tree_add_duplicate(char *s, BOOL pfr)
+tree_add_duplicate(char *s, address_item *a, BOOL pfr)
{
tree_node *node = store_get(sizeof(tree_node) + (int)strlen(s));
strcpy(node->name, pfr? s : address_prepare(s));
-node->data.ptr = NULL;
+node->data.ptr = a;
if (!tree_insertnode(&tree_duplicates, node)) store_reset(node);
}
--
Computers are useless, they only give answers. --Pablo Picasso