nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

rewrite.c (8025B)


      1 #include "mxf-send.h"
      2 /* this file is too long ----------------------------------------- REWRITING */
      3 
      4 stralloc rwline = {0}; // XXX should be passed into rewrite, not a global
      5 
      6 #define AMNESIAC	(errno = ENOMEM, -1)
      7 /* MXF TODO: change semantics to
      8  * -1 ENOMEM if forgetful,
      9  * -1 ENOENT if can't find channel,
     10  * channel number if going to a channel. currently just 0 for local and 1 for remote
     11  * MXF TODO: if slots are available, callers should automatically
     12  * try to reach that channel to schedule a delivery after calling
     13  * this.
     14  * MXF TODO: callers should barf if -1 and errno isn't enomem or enoent.
     15  */
     16 /* may trash recip. must set up rwline, between a T and a \0. */
     17 int
     18 rewrite(char *recip)
     19 {
     20 	unsigned int i;
     21 	char *x;
     22 	static stralloc addr = TA_ZERO;
     23 	unsigned int at;
     24 
     25 	if (!stralloc_copys(&rwline, "T"))
     26 		return AMNESIAC;
     27 	if (!stralloc_copys(&addr, recip))
     28 		return AMNESIAC;
     29 
     30 	i = byte_rchr(addr.s, addr.len, '@');
     31 	if (i == addr.len) {
     32 		if (!stralloc_cats(&addr, "@"))
     33 			return AMNESIAC;
     34 		if (!stralloc_cat(&addr, &envnoathost))
     35 			return AMNESIAC;
     36 	}
     37 
     38 	/* MXF NOTE: Double tap now if you'd scrunkly the when!
     39 	 * This makes no sense. This is a crock. Nobody actually uses the
     40 	 * percent hack.
     41 	 * A respectable site with UUCP source routing allows local parts
     42 	 * to contain exclamatories.
     43 	 */
     44 	while (constmap(&mappercenthack, addr.s + i + 1, addr.len - i - 1)) {
     45 		unsigned int j = byte_rchr(addr.s, i, '%');
     46 		if (j == i)
     47 			break;
     48 		addr.len = i;
     49 		i = j;
     50 		addr.s[i] = '@';
     51 	}
     52 
     53 	at = byte_rchr(addr.s, addr.len, '@');
     54 
     55 	/* MXF NOTE: so what's happening here is that addr, our static,
     56 	 * the value to the right of @ is being checked against
     57 	 * constmap maplocals. Return 1 if "by land" (local).
     58      */
     59 	if (constmap(&maplocals, addr.s + at + 1, addr.len - at - 1)) {
     60 		if (!stralloc_cat(&rwline, &addr))
     61 			return AMNESIAC;
     62 		if (!stralloc_0(&rwline))
     63 			return AMNESIAC;
     64 		return 0;
     65 	}
     66 
     67 	/* MXF NOTE: so what's happening here is that addr, our static,
     68 	 * if start of addrlen, or if one after the @, or if at end,
     69 	 * or if cursor>at and addr.s[cursor] is an ascii dot,
     70 	 * then if constmap returns anything useful,
     71 	 * prepend the virtual prepend (XXX uses "-" even if different
     72 	 * dash is used), and return 1 since by land (local).
     73 	 * TODO: turn to different channel idea
     74      */
     75 	for (i = 0; i <= addr.len; ++i)
     76 		if (!i || (i == at + 1) || (i == addr.len) || ((i > at) && (addr.s[i] == '.')))
     77 			if ((x = constmap(&mapvdoms, addr.s + i, addr.len - i))) {
     78 				if (!*x)
     79 					break;
     80 				if (!stralloc_cats(&rwline, x))
     81 					return AMNESIAC;
     82 				if (!stralloc_cats(&rwline, "-"))
     83 					return AMNESIAC;
     84 				if (!stralloc_cat(&rwline, &addr))
     85 					return AMNESIAC;
     86 				if (!stralloc_0(&rwline))
     87 					return AMNESIAC;
     88 				return 0;
     89 			}
     90 
     91 	if (!stralloc_cat(&rwline, &addr))
     92 		return AMNESIAC;
     93 	if (!stralloc_0(&rwline))
     94 		return AMNESIAC;
     95 	/* MXF NOTE: it isn't going down channel 0, so it's going down channel 1.
     96 	 */
     97 	return 1;
     98 }
     99 
    100 /* may trash recip. must set up rwline, between a T and a \0.
    101  * masks the global rwline. */
    102 int
    103 rewrite_r(char *recip, stralloc *rwline, stralloc *addr)
    104 {
    105 	unsigned int i;
    106 	char *x;
    107 	unsigned int at;
    108 
    109 	if (!stralloc_copys(rwline, "T"))
    110 		return AMNESIAC;
    111 	if (!stralloc_copys(addr, recip))
    112 		return AMNESIAC;
    113 
    114 	i = byte_rchr(addr.s, addr.len, '@');
    115 	if (i == addr.len) {
    116 		if (!stralloc_cats(addr, "@"))
    117 			return AMNESIAC;
    118 		if (!stralloc_cat(addr, &envnoathost))
    119 			return AMNESIAC;
    120 	}
    121 
    122 	/* MXF NOTE: Double tap now if you'd scrunkly the when!
    123 	 * This makes no sense. This is a crock. Nobody actually uses the
    124 	 * percent hack.
    125 	 * A respectable site with UUCP source routing allows local parts
    126 	 * to contain exclamatories.
    127 	 * I don't know if constmap is threadsafe. I have to assume that it is not.
    128 	 */
    129 	while (constmap(&mappercenthack, addr->s + i + 1, addr->len - i - 1)) {
    130 		unsigned int j = byte_rchr(addr->s, i, '%');
    131 		if (j == i)
    132 			break;
    133 		addr->len = i;
    134 		i = j;
    135 		addr->s[i] = '@';
    136 	}
    137 
    138 	/* MXF NOTE: This value is obscurely named.
    139 	 * This is the position of the at in addr->s.
    140 	 */
    141 	at = byte_rchr(addr->s, addr->len, '@');
    142 
    143 	/* MXF NOTE: so what's happening here is that addr, our static,
    144 	 * the value to the right of @ is being checked against
    145 	 * constmap maplocals. Return 0 if "by land" (local).
    146 	 * Same TS note as above.
    147      */
    148 	if (constmap(&maplocals, addr->s + at + 1, addr->len - at - 1)) {
    149 		if (!stralloc_cat(rwline, addr)) {
    150 			return AMNESIAC;
    151 		}
    152 		if (!stralloc_0(rwline)) {
    153 			return AMNESIAC;
    154 		}
    155 		/* Memory has been malloc'd in addr.s. If we don't free
    156 		 * it now, that's a memory leak. */
    157 		return 0;
    158 	}
    159 
    160 	/* MXF NOTE: so what's happening here is that addr, our static,
    161 	 * if start of addrlen, or if one after the @, or if at end,
    162 	 * or if cursor>at and addr->s[cursor] is an ascii dot,
    163 	 * then if constmap returns anything useful,
    164 	 * prepend the virtual prepend (XXX uses "-" even if different
    165 	 * dash is used), and return 1 since by land (local).
    166 	 * TODO: turn to different channel idea
    167      */
    168 	for (i = 0; i <= addr->len; ++i)
    169 		if (!i || (i == at + 1) || (i == addr->len) || ((i > at) && (addr->s[i] == '.')))
    170 			if ((x = constmap(&mapvdoms, addr->s + i, addr->len - i))) {
    171 				if (!*x)
    172 					break;
    173 				if (!stralloc_cats(rwline, x)) {
    174 					return AMNESIAC;
    175 				}
    176 				if (!stralloc_cats(rwline, "-")) {
    177 					return AMNESIAC;
    178 				}
    179 				if (!stralloc_cat(rwline, addr)) {
    180 					return AMNESIAC;
    181 				}
    182 				if (!stralloc_0(rwline)) {
    183 					return AMNESIAC;
    184 				}
    185 				return 0;
    186 			}
    187 
    188 	if (!stralloc_cat(&rwline, addr)) {
    189 		return AMNESIAC;
    190 	}
    191 	if (!stralloc_0(&rwline)) {
    192 		return AMNESIAC;
    193 	}
    194 	/* MXF NOTE: it isn't going down channel 0, so it's going down channel 1.
    195 	 */
    196 	return 1;
    197 }
    198 
    199 int rewrite_staticaddr(char *recip, stralloc *rwline)
    200 {
    201 	static stralloc addr = TA_ZERO; /* reusable */
    202 	int r = -1;
    203 	r = rewrite_r(recip, rwline, &addr);
    204 	return r;
    205 }
    206 
    207 int rewrite_staticaddr_staticrwline(char *recip)
    208 {
    209 	static stralloc addr = TA_ZERO; /* reusable */
    210 	int r = -1;
    211 	r = rewrite_r(recip, &rwline, &addr); /* There's already a global rwline, remember? */
    212 	return r;
    213 }
    214 
    215 int rewrite_aaddr(char *recip, stralloc *rwline)
    216 {
    217 	stralloc addr = TA_ZERO; /* disposable */
    218 	int r = -1;
    219 	if (!stralloc_readyplus(addr, 257)) return AMNESIAC; /* It'll be overwritten anyway. This is just to create a block of memory for it. With some luck, more won't be needed */
    220 	r = rewrite_r(recip, rwline, &addr);
    221 	free(addr.s);
    222 	return r;
    223 }
    224 
    225 /* 'a' means automatic; i.e. procedure-local. that should be tsafe, but inefficient.
    226  * I (Amelia) expect that a serious MT use of rewrite would have a thread-local pool of strallocs
    227  * for rewrite. */
    228 int rewrite_aaddr_arwline(char *recip)
    229 {
    230 	stralloc addr = TA_ZERO; /* disposable */
    231 	stralloc rwline = TA_ZERO; /* disposable */
    232 	int r = -1;
    233 	if (!stralloc_readyplus(addr, 257)) return AMNESIAC; /* It'll be overwritten anyway. This is just to create a block of memory for it. With some luck, more won't be needed */
    234 	if (!stralloc_readyplus(rwline, 257)) return AMNESIAC; /* It'll be overwritten anyway. This is just to create a block of memory for it. With some luck, more won't be needed */
    235 	r = rewrite_r(recip, &rwline, &addr);
    236 	free(addr.s);
    237 	free(rwline.s);
    238 	return r;
    239 }
    240 
    241 // QUERY should return AMNESIAC?
    242 void
    243 senderadd(stralloc * sa, char *sender, char *recip)
    244 {
    245 	unsigned int i;
    246 
    247 	i = str_len(sender);
    248 	if (i >= 4)
    249 		if (str_equal(sender + i - 4, "-@[]")) {
    250 			unsigned int j = byte_rchr(sender, i - 4, '@');
    251 			unsigned int k = str_rchr(recip, '@');
    252 			if (recip[k] && (j + 5 <= i)) {
    253 				/*
    254 				 * owner-@host-@[] ->
    255 				 * owner-recipbox=reciphost@host
    256 				 */
    257 				while (!stralloc_catb(sa, sender, j))
    258 					nomem();
    259 				while (!stralloc_catb(sa, recip, k))
    260 					nomem();
    261 				while (!stralloc_cats(sa, "="))
    262 					nomem();
    263 				while (!stralloc_cats(sa, recip + k + 1))
    264 					nomem();
    265 				while (!stralloc_cats(sa, "@"))
    266 					nomem();
    267 				while (!stralloc_catb(sa, sender + j + 1, i - 5 - j))
    268 					nomem();
    269 				return;
    270 			}
    271 		}
    272 	while (!stralloc_cats(sa, sender))
    273 		nomem();
    274 }