masqmail
diff src/alias.c @ 387:a408411ff8df
Added a glob-pattern aliasing facility.
One use-case is virtual hosting another catch-all maildrops, but you may
use it as a more flexible aliasing mechanism as well.
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Sat, 18 Feb 2012 12:35:12 +0100 |
parents | 028bc124d744 |
children | 68ae9182059c |
line diff
1.1 --- a/src/alias.c Sat Feb 18 11:43:06 2012 +0100 1.2 +++ b/src/alias.c Sat Feb 18 12:35:12 2012 +0100 1.3 @@ -104,11 +104,28 @@ 1.4 return list; 1.5 } 1.6 1.7 +static int 1.8 +globaliascmp(const char *pattern, const char *addr) 1.9 +{ 1.10 + if (conf.localpartcmp==strcasecmp) { 1.11 + return fnmatch(pattern, addr, FNM_CASEFOLD); 1.12 + } else if (strncasecmp(addr, "postmaster", 10)==0) { 1.13 + /* 1.14 + ** postmaster must always be matched caseless 1.15 + ** see RFC 822 and RFC 5321 1.16 + */ 1.17 + return fnmatch(pattern, addr, FNM_CASEFOLD); 1.18 + } else { 1.19 + /* case-sensitive */ 1.20 + return fnmatch(pattern, addr, 0); 1.21 + } 1.22 +} 1.23 + 1.24 /* 1.25 ** addr is assumed to be local and no pipe address nor not-to-expand 1.26 */ 1.27 static GList* 1.28 -expand_one(GList *alias_table, address *addr) 1.29 +expand_one(GList *alias_table, address *addr, int doglob) 1.30 { 1.31 GList *val_list; 1.32 GList *val_node; 1.33 @@ -117,24 +134,33 @@ 1.34 gchar *val; 1.35 1.36 /* expand the local alias */ 1.37 - DEBUG(6) debugf("alias: '%s' is local and will get expanded\n", addr->local_part); 1.38 + DEBUG(6) debugf("alias: '%s' is local and will get expanded\n", 1.39 + doglob ? addr->address : addr->local_part); 1.40 1.41 - if (strcasecmp(addr->local_part, "postmaster") == 0) { 1.42 + if (doglob) { 1.43 + val = (gchar *) table_find_func(alias_table, addr->address, 1.44 + globaliascmp); 1.45 + 1.46 + } else if (strcasecmp(addr->local_part, "postmaster") == 0) { 1.47 /* 1.48 ** postmaster must always be matched caseless 1.49 ** see RFC 822 and RFC 5321 1.50 */ 1.51 - val = (gchar *) table_find_func(alias_table, addr->local_part, strcasecmp); 1.52 + val = (gchar *) table_find_func(alias_table, addr->local_part, 1.53 + strcasecmp); 1.54 } else { 1.55 - val = (gchar *) table_find_func(alias_table, addr->local_part, conf.localpartcmp); 1.56 + val = (gchar *) table_find_func(alias_table, addr->local_part, 1.57 + conf.localpartcmp); 1.58 } 1.59 if (!val) { 1.60 - DEBUG(5) debugf("alias: '%s' is fully expanded, hence completed\n", 1.61 - addr->local_part); 1.62 + DEBUG(5) debugf("alias: '%s' is fully expanded, hence " 1.63 + "completed\n", 1.64 + doglob ? addr->address : addr->local_part); 1.65 return g_list_append(NULL, addr); 1.66 } 1.67 1.68 - DEBUG(5) debugf("alias: '%s' -> '%s'\n", addr->local_part, val); 1.69 + DEBUG(5) debugf("alias: '%s' -> '%s'\n", 1.70 + doglob ? addr->address : addr->local_part, val); 1.71 val_list = parse_list(val); 1.72 alias_list = NULL; 1.73 1.74 @@ -149,7 +175,7 @@ 1.75 alias_addr = create_address_qualified(val+1, TRUE, conf.host_name); 1.76 g_free(val); 1.77 DEBUG(6) debugf("alias: address generated: '%s'\n", 1.78 - alias_addr->local_part); 1.79 + alias_addr->address); 1.80 alias_list = g_list_append(alias_list, alias_addr); 1.81 continue; 1.82 } 1.83 @@ -168,8 +194,8 @@ 1.84 g_free(val); 1.85 1.86 if (!addr_is_local(alias_addr)) { 1.87 - DEBUG(5) debugf("alias: '%s@%s' is non-local, hence completed\n", 1.88 - alias_addr->local_part, alias_addr->domain); 1.89 + DEBUG(5) debugf("alias: '%s' is non-local, hence completed\n", 1.90 + alias_addr->address); 1.91 alias_list = g_list_append(alias_list, alias_addr); 1.92 continue; 1.93 } 1.94 @@ -186,7 +212,7 @@ 1.95 1.96 /* recurse */ 1.97 DEBUG(6) debugf("alias: >>\n"); 1.98 - alias_node = expand_one(alias_table, alias_addr); 1.99 + alias_node = expand_one(alias_table, alias_addr, doglob); 1.100 DEBUG(6) debugf("alias: <<\n"); 1.101 if (alias_node) { 1.102 alias_list = g_list_concat(alias_list, alias_node); 1.103 @@ -199,7 +225,8 @@ 1.104 } 1.105 1.106 GList* 1.107 -alias_expand(GList *alias_table, GList *rcpt_list, GList *non_rcpt_list) 1.108 +alias_expand(GList *alias_table, GList *rcpt_list, GList *non_rcpt_list, 1.109 + int doglob) 1.110 { 1.111 GList *rcpt_node = NULL; 1.112 GList *alias_list = NULL; 1.113 @@ -214,14 +241,14 @@ 1.114 addr = (address *) (rcpt_node->data); 1.115 if (addr_is_local(addr)) { 1.116 DEBUG(5) debugf("alias: (orig rcpt addr) expand local '%s'\n", 1.117 - addr->local_part); 1.118 - alias_list = expand_one(alias_table, addr); 1.119 + doglob ? addr->address : addr->local_part); 1.120 + alias_list = expand_one(alias_table, addr, doglob); 1.121 if (alias_list) { 1.122 done_list = g_list_concat(done_list, alias_list); 1.123 } 1.124 } else { 1.125 - DEBUG(5) debugf("alias: (orig rcpt addr) don't expand non-local '%s@%s'\n", 1.126 - addr->local_part, addr->domain); 1.127 + DEBUG(5) debugf("alias: (orig rcpt addr) don't expand non-local '%s'\n", 1.128 + addr->address); 1.129 done_list = g_list_append(done_list, addr); 1.130 } 1.131 }