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  	}