meillo@0: /* MasqMail meillo@0: Copyright (C) 1999-2001 Oliver Kurth meillo@0: meillo@0: This program is free software; you can redistribute it and/or modify meillo@0: it under the terms of the GNU General Public License as published by meillo@0: the Free Software Foundation; either version 2 of the License, or meillo@0: (at your option) any later version. meillo@0: meillo@0: This program is distributed in the hope that it will be useful, meillo@0: but WITHOUT ANY WARRANTY; without even the implied warranty of meillo@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the meillo@0: GNU General Public License for more details. meillo@0: meillo@0: You should have received a copy of the GNU General Public License meillo@0: along with this program; if not, write to the Free Software meillo@0: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. meillo@0: */ meillo@0: meillo@0: #include "masqmail.h" meillo@0: #include meillo@0: meillo@0: address *create_address(gchar *path, gboolean is_rfc821) meillo@0: { meillo@0: address *addr; meillo@0: addr = _create_address(path, NULL, is_rfc821); meillo@0: meillo@0: if(addr != NULL){ meillo@0: addr_unmark_delivered(addr); meillo@0: } meillo@0: return addr; meillo@0: } meillo@0: meillo@0: address *create_address_qualified(gchar *path, gboolean is_rfc821, meillo@0: gchar *domain) meillo@0: { meillo@0: address *addr = create_address(path, is_rfc821); meillo@0: if(addr != NULL){ meillo@0: if(addr->domain == NULL) meillo@0: addr->domain = g_strdup(domain); meillo@0: } meillo@0: meillo@0: return addr; meillo@0: } meillo@0: meillo@0: /* nothing special about pipes here, meillo@0: but its only called for that purpose */ meillo@0: address *create_address_pipe(gchar *path) meillo@0: { meillo@0: address *addr = g_malloc(sizeof(address)); meillo@0: meillo@0: if(addr){ meillo@0: memset(addr, 0, sizeof(address)); meillo@0: addr->address = g_strchomp(g_strdup(path)); meillo@0: addr->local_part = g_strdup(addr->address); meillo@0: meillo@0: addr->domain = g_strdup("localhost"); /* quick hack */ meillo@0: } meillo@0: return addr; meillo@0: } meillo@0: meillo@0: void destroy_address(address *addr) meillo@0: { meillo@0: DEBUG(6) debugf("destroy_address entered\n"); meillo@0: meillo@0: g_free(addr->address); meillo@0: g_free(addr->local_part); meillo@0: g_free(addr->domain); meillo@0: meillo@0: g_free(addr); meillo@0: } meillo@0: meillo@0: address *copy_modify_address(const address *orig, gchar *l_part, gchar *dom) meillo@0: { meillo@0: address *addr = NULL; meillo@0: meillo@0: if(orig){ meillo@0: addr = g_malloc(sizeof(address)); meillo@0: if(addr){ meillo@0: addr->address = g_strdup(orig->address); meillo@0: meillo@0: if(l_part == NULL) meillo@0: addr->local_part = g_strdup(orig->local_part); meillo@0: else meillo@0: addr->local_part = g_strdup(l_part); meillo@0: meillo@0: if(dom == NULL) meillo@0: addr->domain = g_strdup(orig->domain); meillo@0: else meillo@0: addr->domain = g_strdup(dom); meillo@0: meillo@0: addr->flags = 0; meillo@0: addr->children = NULL; meillo@0: addr->parent = NULL; meillo@0: } meillo@0: } meillo@0: return addr; meillo@0: } meillo@0: meillo@0: gboolean addr_isequal(address *addr1, address *addr2) meillo@0: { meillo@0: return meillo@0: (strcmp(addr1->local_part, addr2->local_part) == 0) && meillo@0: (strcasecmp(addr1->domain, addr2->domain) == 0); meillo@0: } meillo@0: meillo@0: /* searches in ancestors of addr1 */ meillo@0: gboolean addr_isequal_parent(address *addr1, address *addr2) meillo@0: { meillo@0: address *addr; meillo@0: meillo@0: for(addr = addr1; addr; addr = addr->parent) meillo@0: if(addr_isequal(addr, addr2)) meillo@0: return TRUE; meillo@0: meillo@0: return FALSE; meillo@0: } meillo@0: meillo@0: /* careful, this is recursive */ meillo@0: /* returns TRUE if ALL children have been delivered */ meillo@0: gboolean addr_is_delivered_children(address *addr) meillo@0: { meillo@0: GList *addr_node; meillo@0: meillo@0: if(addr->children == NULL) return addr_is_delivered(addr); meillo@0: meillo@0: foreach(addr->children, addr_node){ meillo@0: address *addr = (address *)(addr_node->data); meillo@0: if(!addr_is_delivered_children(addr)) meillo@0: return FALSE; meillo@0: } meillo@0: return TRUE; meillo@0: } meillo@0: meillo@0: /* careful, this is recursive */ meillo@0: /* returns TRUE if ALL children have been either delivered or have failed */ meillo@0: gboolean addr_is_finished_children(address *addr) meillo@0: { meillo@0: GList *addr_node; meillo@0: meillo@0: if(addr->children == NULL) return (addr_is_failed(addr) || addr_is_delivered(addr)); meillo@0: meillo@0: foreach(addr->children, addr_node){ meillo@0: address *addr = (address *)(addr_node->data); meillo@0: if(!addr_is_finished_children(addr)) meillo@0: return FALSE; meillo@0: } meillo@0: return TRUE; meillo@0: } meillo@0: meillo@0: /* find original address */ meillo@0: address *addr_find_ancestor(address *addr) meillo@0: { meillo@0: while(addr->parent) addr = addr->parent; meillo@0: return addr; meillo@0: } meillo@0: meillo@0: gchar *addr_string(address *addr) meillo@0: { meillo@0: static gchar *buffer = NULL; meillo@0: meillo@0: if(addr == NULL){ meillo@0: g_free(buffer); meillo@0: buffer = NULL; meillo@0: return NULL; meillo@0: } meillo@0: if(buffer) meillo@0: g_free(buffer); meillo@0: meillo@0: if(addr->local_part[0] == 0){ meillo@0: buffer = g_strdup("<>"); meillo@0: }else{ meillo@0: buffer = g_strdup_printf("<%s@%s>", meillo@0: addr->local_part ? addr->local_part : "", meillo@0: addr->domain ? addr->domain : ""); meillo@0: } meillo@0: return buffer; meillo@0: } meillo@0: meillo@0: gint addr_match(address *addr1, address *addr2) meillo@0: { meillo@0: int res; meillo@0: meillo@0: if((res = fnmatch(addr1->local_part, addr2->local_part, 0)) == 0){ meillo@0: if((res = fnmatch(addr1->domain, addr2->domain, FNM_CASEFOLD)) == 0) meillo@0: return 0; meillo@0: } meillo@0: return res; meillo@0: } meillo@0: