masqmail

annotate src/address.c @ 17:6c59dedd06be

fixed delivery with empty or non-existent alias file Thanks to Marcos Dione for the hint where to look. (Closes Debian bug #417842)
author meillo@marmaro.de
date Thu, 06 Nov 2008 09:41:35 +0100
parents 49dab67fe461
children 4a3bc3a7afbe
rev   line source
meillo@0 1 /* MasqMail
meillo@0 2 Copyright (C) 1999-2001 Oliver Kurth
meillo@0 3
meillo@0 4 This program is free software; you can redistribute it and/or modify
meillo@0 5 it under the terms of the GNU General Public License as published by
meillo@0 6 the Free Software Foundation; either version 2 of the License, or
meillo@0 7 (at your option) any later version.
meillo@0 8
meillo@0 9 This program is distributed in the hope that it will be useful,
meillo@0 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
meillo@0 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
meillo@0 12 GNU General Public License for more details.
meillo@0 13
meillo@0 14 You should have received a copy of the GNU General Public License
meillo@0 15 along with this program; if not, write to the Free Software
meillo@0 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
meillo@0 17 */
meillo@0 18
meillo@0 19 #include "masqmail.h"
meillo@0 20 #include <fnmatch.h>
meillo@0 21
meillo@10 22 address*
meillo@10 23 create_address(gchar * path, gboolean is_rfc821)
meillo@0 24 {
meillo@10 25 address *addr;
meillo@10 26 addr = _create_address(path, NULL, is_rfc821);
meillo@10 27
meillo@10 28 if (addr != NULL) {
meillo@10 29 addr_unmark_delivered(addr);
meillo@10 30 }
meillo@10 31 return addr;
meillo@0 32 }
meillo@0 33
meillo@10 34 address*
meillo@10 35 create_address_qualified(gchar * path, gboolean is_rfc821, gchar * domain)
meillo@0 36 {
meillo@10 37 address *addr = create_address(path, is_rfc821);
meillo@10 38 if (addr != NULL) {
meillo@10 39 if (addr->domain == NULL)
meillo@10 40 addr->domain = g_strdup(domain);
meillo@10 41 }
meillo@0 42
meillo@10 43 return addr;
meillo@0 44 }
meillo@0 45
meillo@13 46 /* nothing special about pipes here, but its only called for that purpose */
meillo@10 47 address*
meillo@10 48 create_address_pipe(gchar * path)
meillo@0 49 {
meillo@10 50 address *addr = g_malloc(sizeof(address));
meillo@0 51
meillo@10 52 if (addr) {
meillo@10 53 memset(addr, 0, sizeof(address));
meillo@10 54 addr->address = g_strchomp(g_strdup(path));
meillo@10 55 addr->local_part = g_strdup(addr->address);
meillo@10 56
meillo@10 57 addr->domain = g_strdup("localhost"); /* quick hack */
meillo@10 58 }
meillo@10 59 return addr;
meillo@0 60 }
meillo@0 61
meillo@10 62 void
meillo@10 63 destroy_address(address * addr)
meillo@0 64 {
meillo@10 65 DEBUG(6) debugf("destroy_address entered\n");
meillo@0 66
meillo@10 67 g_free(addr->address);
meillo@10 68 g_free(addr->local_part);
meillo@10 69 g_free(addr->domain);
meillo@0 70
meillo@10 71 g_free(addr);
meillo@0 72 }
meillo@0 73
meillo@10 74 address*
meillo@10 75 copy_modify_address(const address * orig, gchar * l_part, gchar * dom)
meillo@0 76 {
meillo@10 77 address *addr = NULL;
meillo@0 78
meillo@10 79 if (orig) {
meillo@10 80 addr = g_malloc(sizeof(address));
meillo@10 81 if (addr) {
meillo@10 82 addr->address = g_strdup(orig->address);
meillo@0 83
meillo@10 84 if (l_part == NULL)
meillo@10 85 addr->local_part = g_strdup(orig->local_part);
meillo@10 86 else
meillo@10 87 addr->local_part = g_strdup(l_part);
meillo@0 88
meillo@10 89 if (dom == NULL)
meillo@10 90 addr->domain = g_strdup(orig->domain);
meillo@10 91 else
meillo@10 92 addr->domain = g_strdup(dom);
meillo@0 93
meillo@10 94 addr->flags = 0;
meillo@10 95 addr->children = NULL;
meillo@10 96 addr->parent = NULL;
meillo@10 97 }
meillo@10 98 }
meillo@10 99 return addr;
meillo@0 100 }
meillo@0 101
meillo@10 102 gboolean
meillo@10 103 addr_isequal(address * addr1, address * addr2)
meillo@0 104 {
meillo@13 105 return (strcmp(addr1->local_part, addr2->local_part) == 0)
meillo@13 106 && (strcasecmp(addr1->domain, addr2->domain) == 0);
meillo@0 107 }
meillo@0 108
meillo@0 109 /* searches in ancestors of addr1 */
meillo@10 110 gboolean
meillo@10 111 addr_isequal_parent(address * addr1, address * addr2)
meillo@0 112 {
meillo@10 113 address *addr;
meillo@0 114
meillo@10 115 for (addr = addr1; addr; addr = addr->parent)
meillo@10 116 if (addr_isequal(addr, addr2))
meillo@10 117 return TRUE;
meillo@0 118
meillo@10 119 return FALSE;
meillo@0 120 }
meillo@0 121
meillo@0 122 /* careful, this is recursive */
meillo@0 123 /* returns TRUE if ALL children have been delivered */
meillo@10 124 gboolean
meillo@10 125 addr_is_delivered_children(address * addr)
meillo@0 126 {
meillo@10 127 GList *addr_node;
meillo@0 128
meillo@10 129 if (addr->children == NULL)
meillo@10 130 return addr_is_delivered(addr);
meillo@0 131
meillo@10 132 foreach(addr->children, addr_node) {
meillo@10 133 address *addr = (address *) (addr_node->data);
meillo@10 134 if (!addr_is_delivered_children(addr))
meillo@10 135 return FALSE;
meillo@10 136 }
meillo@10 137 return TRUE;
meillo@0 138 }
meillo@0 139
meillo@0 140 /* careful, this is recursive */
meillo@0 141 /* returns TRUE if ALL children have been either delivered or have failed */
meillo@10 142 gboolean
meillo@10 143 addr_is_finished_children(address * addr)
meillo@0 144 {
meillo@10 145 GList *addr_node;
meillo@0 146
meillo@10 147 if (addr->children == NULL)
meillo@10 148 return (addr_is_failed(addr) || addr_is_delivered(addr));
meillo@0 149
meillo@10 150 foreach(addr->children, addr_node) {
meillo@10 151 address *addr = (address *) (addr_node->data);
meillo@10 152 if (!addr_is_finished_children(addr))
meillo@10 153 return FALSE;
meillo@10 154 }
meillo@10 155 return TRUE;
meillo@0 156 }
meillo@0 157
meillo@0 158 /* find original address */
meillo@10 159 address*
meillo@10 160 addr_find_ancestor(address * addr)
meillo@0 161 {
meillo@10 162 while (addr->parent)
meillo@10 163 addr = addr->parent;
meillo@10 164 return addr;
meillo@0 165 }
meillo@0 166
meillo@10 167 gchar*
meillo@10 168 addr_string(address * addr)
meillo@0 169 {
meillo@10 170 static gchar *buffer = NULL;
meillo@0 171
meillo@10 172 if (addr == NULL) {
meillo@10 173 g_free(buffer);
meillo@10 174 buffer = NULL;
meillo@10 175 return NULL;
meillo@10 176 }
meillo@10 177 if (buffer)
meillo@10 178 g_free(buffer);
meillo@0 179
meillo@14 180 if (addr->local_part[0] == '\0') {
meillo@10 181 buffer = g_strdup("<>");
meillo@10 182 } else {
meillo@10 183 buffer = g_strdup_printf("<%s@%s>", addr->local_part ? addr->local_part : "", addr->domain ? addr->domain : "");
meillo@10 184 }
meillo@10 185 return buffer;
meillo@0 186 }
meillo@0 187
meillo@10 188 gint
meillo@10 189 addr_match(address * addr1, address * addr2)
meillo@0 190 {
meillo@10 191 int res;
meillo@0 192
meillo@10 193 if ((res = fnmatch(addr1->local_part, addr2->local_part, 0)) == 0) {
meillo@10 194 if ((res = fnmatch(addr1->domain, addr2->domain, FNM_CASEFOLD)) == 0)
meillo@10 195 return 0;
meillo@10 196 }
meillo@10 197 return res;
meillo@0 198 }