|  | @@ -140,12 +140,24 @@ static char* url_encode (char* buf, size_t len, const char *input)
 | 
		
	
		
			
			| 140 | 140 |    return buf;
 | 
		
	
		
			
			| 141 | 141 |  }
 | 
		
	
		
			
			| 142 | 142 |  
 | 
		
	
		
			
			| 143 |  | -static void handle_forward (srs_t *srs, FILE *fp, const char *address, const char *domain)
 | 
		
	
		
			
			|  | 143 | +static void handle_forward (srs_t *srs, FILE *fp, const char *address, const char *domain, const char **excludes)
 | 
		
	
		
			
			| 144 | 144 |  {
 | 
		
	
		
			
			| 145 | 145 |    int result;
 | 
		
	
		
			
			|  | 146 | +  size_t addrlen;
 | 
		
	
		
			
			| 146 | 147 |    char value[1024];
 | 
		
	
		
			
			| 147 | 148 |    char outputbuf[1024], *output;
 | 
		
	
		
			
			| 148 | 149 |  
 | 
		
	
		
			
			|  | 150 | +  addrlen = strlen(address);
 | 
		
	
		
			
			|  | 151 | +  for(; *excludes; excludes++) {
 | 
		
	
		
			
			|  | 152 | +    size_t len;
 | 
		
	
		
			
			|  | 153 | +    len = strlen(*excludes);
 | 
		
	
		
			
			|  | 154 | +    if (len >= addrlen) continue;
 | 
		
	
		
			
			|  | 155 | +    if (strcasecmp(*excludes, &address[addrlen - len]) == 0 && (**excludes == '.' || address[addrlen - len - 1] == '@')) {
 | 
		
	
		
			
			|  | 156 | +      fputs ("500 Domain excluded from SRS\n", fp);
 | 
		
	
		
			
			|  | 157 | +      fflush (fp);
 | 
		
	
		
			
			|  | 158 | +      return;
 | 
		
	
		
			
			|  | 159 | +    }
 | 
		
	
		
			
			|  | 160 | +  }
 | 
		
	
		
			
			| 149 | 161 |    result = srs_forward(srs, value, sizeof(value), address, domain);
 | 
		
	
		
			
			| 150 | 162 |    if (result == SRS_SUCCESS) {
 | 
		
	
		
			
			| 151 | 163 |      output = url_encode(outputbuf, sizeof(outputbuf), value);
 | 
		
	
	
		
			
			|  | @@ -159,7 +171,7 @@ static void handle_forward (srs_t *srs, FILE *fp, const char *address, const cha
 | 
		
	
		
			
			| 159 | 171 |    fflush (fp);
 | 
		
	
		
			
			| 160 | 172 |  }
 | 
		
	
		
			
			| 161 | 173 |  
 | 
		
	
		
			
			| 162 |  | -static void handle_reverse (srs_t *srs, FILE *fp, const char *address, const char *domain)
 | 
		
	
		
			
			|  | 174 | +static void handle_reverse (srs_t *srs, FILE *fp, const char *address, const char *domain, const char **excludes)
 | 
		
	
		
			
			| 163 | 175 |  {
 | 
		
	
		
			
			| 164 | 176 |    int result;
 | 
		
	
		
			
			| 165 | 177 |    char value[1024];
 | 
		
	
	
		
			
			|  | @@ -197,6 +209,7 @@ static void show_help ()
 | 
		
	
		
			
			| 197 | 209 |      "   -c<dir>        chroot to <dir> (default: none)\n"
 | 
		
	
		
			
			| 198 | 210 |      "   -u<user>       switch user id after port bind (default: none)\n"
 | 
		
	
		
			
			| 199 | 211 |      "   -t<seconds>    timeout for idle client connections (default: 1800)\n"
 | 
		
	
		
			
			|  | 212 | +    "   -X<domain>     exclude additional domain from address rewriting\n"
 | 
		
	
		
			
			| 200 | 213 |      "   -D             fork into background\n"
 | 
		
	
		
			
			| 201 | 214 |      "   -4             force IPv4 socket (default: any)\n"
 | 
		
	
		
			
			| 202 | 215 |      "   -6             force IPv6 socket (default: any)\n"
 | 
		
	
	
		
			
			|  | @@ -207,7 +220,7 @@ static void show_help ()
 | 
		
	
		
			
			| 207 | 220 |    );
 | 
		
	
		
			
			| 208 | 221 |  }
 | 
		
	
		
			
			| 209 | 222 |  
 | 
		
	
		
			
			| 210 |  | -typedef void(*handle_t)(srs_t*, FILE*, const char*, const char*);
 | 
		
	
		
			
			|  | 223 | +typedef void(*handle_t)(srs_t*, FILE*, const char*, const char*, const char**);
 | 
		
	
		
			
			| 211 | 224 |  
 | 
		
	
		
			
			| 212 | 225 |  int main (int argc, char **argv)
 | 
		
	
		
			
			| 213 | 226 |  {
 | 
		
	
	
		
			
			|  | @@ -223,12 +236,15 @@ int main (int argc, char **argv)
 | 
		
	
		
			
			| 223 | 236 |    char *tmp;
 | 
		
	
		
			
			| 224 | 237 |    srs_t *srs;
 | 
		
	
		
			
			| 225 | 238 |    struct pollfd fds[3];
 | 
		
	
		
			
			|  | 239 | +  const char **excludes;
 | 
		
	
		
			
			|  | 240 | +  size_t s1 = 0, s2 = 1;
 | 
		
	
		
			
			| 226 | 241 |    handle_t handler[2] = { handle_forward, handle_reverse };
 | 
		
	
		
			
			| 227 | 242 |  
 | 
		
	
		
			
			|  | 243 | +  excludes = (const char**)calloc(1, sizeof(char*));
 | 
		
	
		
			
			| 228 | 244 |    tmp = strrchr(argv[0], '/');
 | 
		
	
		
			
			| 229 | 245 |    if (tmp) self = strdup(tmp + 1); else self = strdup(argv[0]);
 | 
		
	
		
			
			| 230 | 246 |  
 | 
		
	
		
			
			| 231 |  | -  while ((opt = getopt(argc, argv, "46d:f:r:s:u:t:p:c:Dhv")) != -1) {
 | 
		
	
		
			
			|  | 247 | +  while ((opt = getopt(argc, argv, "46d:f:r:s:u:t:p:c:X::Dhv")) != -1) {
 | 
		
	
		
			
			| 232 | 248 |      switch (opt) {
 | 
		
	
		
			
			| 233 | 249 |        case '?':
 | 
		
	
		
			
			| 234 | 250 |          return EXIT_FAILURE;
 | 
		
	
	
		
			
			|  | @@ -268,6 +284,24 @@ int main (int argc, char **argv)
 | 
		
	
		
			
			| 268 | 284 |        case 'h':
 | 
		
	
		
			
			| 269 | 285 |          show_help();
 | 
		
	
		
			
			| 270 | 286 |          return EXIT_SUCCESS;
 | 
		
	
		
			
			|  | 287 | +      case 'X':
 | 
		
	
		
			
			|  | 288 | +        if (optarg != NULL) {
 | 
		
	
		
			
			|  | 289 | +          tmp = strtok(optarg, ",; \t\r\n");
 | 
		
	
		
			
			|  | 290 | +          while (tmp) {
 | 
		
	
		
			
			|  | 291 | +            if (s1 + 1 >= s2) {
 | 
		
	
		
			
			|  | 292 | +              s2 *= 2;
 | 
		
	
		
			
			|  | 293 | +              excludes = (const char **)realloc(excludes, s2 * sizeof(char*));
 | 
		
	
		
			
			|  | 294 | +              if (excludes == NULL) {
 | 
		
	
		
			
			|  | 295 | +                fprintf (stderr, "%s: Out of memory\n\n", self);
 | 
		
	
		
			
			|  | 296 | +                return EXIT_FAILURE;
 | 
		
	
		
			
			|  | 297 | +              }
 | 
		
	
		
			
			|  | 298 | +            }
 | 
		
	
		
			
			|  | 299 | +            excludes[s1++] = strdup(tmp);
 | 
		
	
		
			
			|  | 300 | +            tmp = strtok(NULL, ",; \t\r\n");
 | 
		
	
		
			
			|  | 301 | +          }
 | 
		
	
		
			
			|  | 302 | +          excludes[s1] = NULL;
 | 
		
	
		
			
			|  | 303 | +        }
 | 
		
	
		
			
			|  | 304 | +        break;
 | 
		
	
		
			
			| 271 | 305 |        case 'v':
 | 
		
	
		
			
			| 272 | 306 |          fprintf (stdout, "%s\n", VERSION);
 | 
		
	
		
			
			| 273 | 307 |          return EXIT_SUCCESS;
 | 
		
	
	
		
			
			|  | @@ -415,7 +449,7 @@ int main (int argc, char **argv)
 | 
		
	
		
			
			| 415 | 449 |              }
 | 
		
	
		
			
			| 416 | 450 |              key = url_decode(keybuf, sizeof(keybuf), token);
 | 
		
	
		
			
			| 417 | 451 |              if (!key) break;
 | 
		
	
		
			
			| 418 |  | -            handler[i](srs, fp, key, domain);
 | 
		
	
		
			
			|  | 452 | +            handler[i](srs, fp, key, domain, excludes);
 | 
		
	
		
			
			| 419 | 453 |              if (poll(&fds[2], 1, timeout * 1000) <= 0) break;
 | 
		
	
		
			
			| 420 | 454 |              line = fgets(linebuf, sizeof(linebuf), fp);
 | 
		
	
		
			
			| 421 | 455 |            }
 |