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 }