[exim-cvs] cvs commit: exim/exim-src/OS os.h-cygwin exim/ex…

Góra strony
Delete this message
Reply to this message
Autor: Tom Kistner
Data:  
Dla: exim-cvs
Temat: [exim-cvs] cvs commit: exim/exim-src/OS os.h-cygwin exim/exim-src/src deliver.c demime.c drtables.c globals.c globals.h malware.c readconf.c regex.c spf.c spf.h spool_mbox.c srs.c structs.h verify
tom 2005/05/24 09:15:02 BST

  Modified files:
    exim-src/OS          os.h-cygwin 
    exim-src/src         deliver.c demime.c drtables.c globals.c 
                         globals.h malware.c readconf.c regex.c 
                         spf.c spf.h spool_mbox.c srs.c structs.h 
                         verify.c 
    exim-src/src/auths   auth-spa.h 
    exim-src/src/routers redirect.c redirect.h 
  Log:
  SPF: rewrote code to work with 1.2.x libsfp2 series. SRS: upgraded to latest patch from Miles Wilton. Misc: remove some tabs and whitespace.


  Revision  Changes    Path
  1.2       +1 -1      exim/exim-src/OS/os.h-cygwin
  1.4       +20 -20    exim/exim-src/src/auths/auth-spa.h
  1.15      +21 -4     exim/exim-src/src/deliver.c
  1.5       +1 -1      exim/exim-src/src/demime.c
  1.3       +1 -1      exim/exim-src/src/drtables.c
  1.27      +9 -0      exim/exim-src/src/globals.c
  1.19      +6 -0      exim/exim-src/src/globals.h
  1.8       +321 -321  exim/exim-src/src/malware.c
  1.9       +6 -0      exim/exim-src/src/readconf.c
  1.5       +1 -1      exim/exim-src/src/regex.c
  1.11      +78 -48    exim/exim-src/src/routers/redirect.c
  1.5       +3 -2      exim/exim-src/src/routers/redirect.h
  1.4       +30 -46    exim/exim-src/src/spf.c
  1.4       +5 -0      exim/exim-src/src/spf.h
  1.5       +13 -13    exim/exim-src/src/spool_mbox.c
  1.5       +70 -45    exim/exim-src/src/srs.c
  1.6       +4 -0      exim/exim-src/src/structs.h
  1.17      +4 -0      exim/exim-src/src/verify.c


  Index: os.h-cygwin
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/OS/os.h-cygwin,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- os.h-cygwin    6 Oct 2004 15:07:39 -0000    1.1
  +++ os.h-cygwin    24 May 2005 08:15:01 -0000    1.2
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/OS/os.h-cygwin,v 1.1 2004/10/06 15:07:39 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/OS/os.h-cygwin,v 1.2 2005/05/24 08:15:01 tom Exp $ */


/* Exim: OS-specific C header file for Cygwin */

@@ -27,7 +27,7 @@
extern unsigned int cygwin_WinVersion;

   #define BASE_62 36  /* Windows aliases lower and upper cases in filenames.
  -               Consider reducing MAX_LOCALHOST_NUMBER */
  +           Consider reducing MAX_LOCALHOST_NUMBER */
   #define CRYPT_H
   #define HAVE_MMAP
   #define HAVE_SYS_VFS_H


  Index: deliver.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/deliver.c,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- deliver.c    28 Apr 2005 13:06:32 -0000    1.14
  +++ deliver.c    24 May 2005 08:15:02 -0000    1.15
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/deliver.c,v 1.14 2005/04/28 13:06:32 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/deliver.c,v 1.15 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -878,6 +878,11 @@
     if ((log_extra_selector & LX_sender_on_delivery) != 0)
       s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">");


  +  #ifdef EXPERIMENTAL_SRS
  +  if(addr->p.srs_sender)
  +    s = string_append(s, &size, &ptr, 3, US" SRS=<", addr->p.srs_sender, US">");
  +  #endif
  +
     /* You might think that the return path must always be set for a successful
     delivery; indeed, I did for some time, until this statement crashed. The case
     when it is not set is for a delivery to /dev/null which is optimised by not
  @@ -1537,8 +1542,14 @@
   /* Set up the return path from the errors or sender address. If the transport
   has its own return path setting, expand it and replace the existing value. */


-return_path = (addr->p.errors_address != NULL)?
- addr->p.errors_address : sender_address;
+if(addr->p.errors_address != NULL)
+ return_path = addr->p.errors_address;
+#ifdef EXPERIMENTAL_SRS
+else if(addr->p.srs_sender != NULL)
+ return_path = addr->p.srs_sender;
+#endif
+else
+ return_path = sender_address;

   if (tp->return_path != NULL)
     {
  @@ -3528,8 +3539,14 @@
     /* Compute the return path, expanding a new one if required. The old one
     must be set first, as it might be referred to in the expansion. */


  -  return_path = (addr->p.errors_address != NULL)?
  -    addr->p.errors_address : sender_address;
  +  if(addr->p.errors_address != NULL)
  +    return_path = addr->p.errors_address;
  +#ifdef EXPERIMENTAL_SRS
  +  else if(addr->p.srs_sender != NULL)
  +    return_path = addr->p.srs_sender;
  +#endif
  +  else
  +    return_path = sender_address;


     if (tp->return_path != NULL)
       {


  Index: demime.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/demime.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- demime.c    17 Feb 2005 11:58:26 -0000    1.4
  +++ demime.c    24 May 2005 08:15:02 -0000    1.5
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/demime.c,v 1.4 2005/02/17 11:58:26 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/demime.c,v 1.5 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -452,7 +452,7 @@
       for (i = 2; i < Ustrlen(line); i++) {
         if ((line[i] != ' ') && (line[i] != '\t')) {
           workbuf[j] = line[i];
  -          j++;
  +        j++;
         };
       };
       workbuf[j+1]='\0';


  Index: drtables.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/drtables.c,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- drtables.c    4 Jan 2005 10:00:42 -0000    1.2
  +++ drtables.c    24 May 2005 08:15:02 -0000    1.3
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/drtables.c,v 1.2 2005/01/04 10:00:42 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/drtables.c,v 1.3 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -536,7 +536,7 @@


   #ifdef AUTH_CYRUS_SASL
     {
  -  US"cyrus_sasl",                 /* lookup name */
  +  US"cyrus_sasl",           /* lookup name */
     auth_cyrus_sasl_options,
     &auth_cyrus_sasl_options_count,
     &auth_cyrus_sasl_option_defaults,


  Index: globals.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/globals.c,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- globals.c    23 May 2005 16:58:56 -0000    1.26
  +++ globals.c    24 May 2005 08:15:02 -0000    1.27
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/globals.c,v 1.26 2005/05/23 16:58:56 fanf2 Exp $ */
  +/* $Cambridge: exim/exim-src/src/globals.c,v 1.27 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -282,6 +282,9 @@
       NULL,               /* errors_address */
       NULL,               /* extra_headers */
       NULL,               /* remove_headers */
  +#ifdef EXPERIMENTAL_SRS
  +    NULL,               /* srs_sender */
  +#endif
     }
   };


  @@ -1049,10 +1052,16 @@
   uschar *srs_config             = NULL;
   uschar *srs_db_address         = NULL;
   uschar *srs_db_key             = NULL;
  +int     srs_hashlength         = 6;
  +int     srs_hashmin            = -1;
  +int     srs_maxage             = 31;
   uschar *srs_orig_recipient     = NULL;
   uschar *srs_orig_sender        = NULL;
   uschar *srs_recipient          = NULL;
  +uschar *srs_secrets            = NULL;
   uschar *srs_status             = NULL;
  +BOOL    srs_usehash            = TRUE;
  +BOOL    srs_usetimestamp       = TRUE;
   #endif
   int     string_datestamp_offset= -1;
   BOOL    strip_excess_angle_brackets = FALSE;


  Index: globals.h
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/globals.h,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- globals.h    23 May 2005 16:58:56 -0000    1.18
  +++ globals.h    24 May 2005 08:15:02 -0000    1.19
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/globals.h,v 1.18 2005/05/23 16:58:56 fanf2 Exp $ */
  +/* $Cambridge: exim/exim-src/src/globals.h,v 1.19 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -656,10 +656,16 @@
   extern uschar *srs_config;             /* SRS config secret:max age:hash length:use timestamp:use hash */
   extern uschar *srs_db_address;         /* SRS db address */
   extern uschar *srs_db_key;             /* SRS db key */
  +extern int     srs_hashlength;         /* SRS hash length */
  +extern int     srs_hashmin;            /* SRS minimum hash length */
  +extern int     srs_maxage;             /* SRS max age */
   extern uschar *srs_orig_sender;        /* SRS original sender */
   extern uschar *srs_orig_recipient;     /* SRS original recipient */
   extern uschar *srs_recipient;          /* SRS recipient */
  +extern uschar *srs_secrets;            /* SRS secrets list */
   extern uschar *srs_status;             /* SRS staus */
  +extern BOOL    srs_usehash;            /* SRS use hash flag */
  +extern BOOL    srs_usetimestamp;       /* SRS use timestamp flag */
   #endif
   extern int     string_datestamp_offset;/* After insertion by string_format */
   extern BOOL    strip_excess_angle_brackets; /* Surrounding route-addrs */


  Index: malware.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/malware.c,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- malware.c    17 Feb 2005 11:58:26 -0000    1.7
  +++ malware.c    24 May 2005 08:15:02 -0000    1.8
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/malware.c,v 1.7 2005/02/17 11:58:26 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/malware.c,v 1.8 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -135,273 +135,273 @@
         return DEFER;
       };


  -    /* "drweb" scanner type ----------------------------------------------- */
  -    /* v0.1 - added support for tcp sockets                    */
  -    /* v0.0 - initial release -- support for unix sockets            */
  -    if (strcmpic(scanner_name,US"drweb") == 0) {
  -        uschar *drweb_options;
  -        uschar drweb_options_buffer[1024];
  -        uschar drweb_options_default[] = "/usr/local/drweb/run/drwebd.sock";
  -        struct sockaddr_un server;
  -        int sock, result, ovector[30];
  -        unsigned int port, fsize;
  -        uschar tmpbuf[1024], *drweb_fbuf;
  -        uschar scanrequest[1024];
  -        uschar drweb_match_string[128];
  -        int drweb_rc, drweb_cmd, drweb_flags = 0x0000, drweb_fd,
  -            drweb_vnum, drweb_slen, drweb_fin = 0x0000;
  -        unsigned long bread;
  -        uschar hostname[256];
  -        struct hostent *he;
  -        struct in_addr in;
  -        pcre *drweb_re;
  -
  -        if ((drweb_options = string_nextinlist(&av_scanner_work, &sep,
  -            drweb_options_buffer, sizeof(drweb_options_buffer))) == NULL) {
  -            /* no options supplied, use default options */
  -            drweb_options = drweb_options_default;
  -        };
  -
  -        if (*drweb_options != '/') {
  -
  -            /* extract host and port part */
  -            if( sscanf(CS drweb_options, "%s %u", hostname, &port) != 2 ) {
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: invalid socket '%s'", drweb_options);
  -                return DEFER;
  -            }
  -
  -            /* Lookup the host */
  -            if((he = gethostbyname(CS hostname)) == 0) {
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: failed to lookup host '%s'", hostname);
  -                return DEFER;
  -            }
  -
  -            in = *(struct in_addr *) he->h_addr_list[0];
  -
  -            /* Open the drwebd TCP socket */
  -            if ( (sock = ip_socket(SOCK_STREAM, AF_INET)) < 0) {
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: unable to acquire socket (%s)",
  -                    strerror(errno));
  -                return DEFER;
  -            }
  -
  -            if (ip_connect(sock, AF_INET, (uschar*)inet_ntoa(in), port, 5) < 0) {
  -                close(sock);
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: connection to %s, port %u failed (%s)",
  -                    inet_ntoa(in), port, strerror(errno));
  -                return DEFER;
  -            }
  -
  -            /* prepare variables */
  -            drweb_cmd = htonl(DRWEBD_SCAN_CMD);
  -            drweb_flags = htonl(DRWEBD_RETURN_VIRUSES | DRWEBD_IS_MAIL);
  -            snprintf(CS scanrequest, 1024,CS"%s/scan/%s/%s.eml",
  -                    spool_directory, message_id, message_id);
  -
  -            /* calc file size */
  -            drweb_fd = open(CS scanrequest, O_RDONLY);
  -            if (drweb_fd == -1) {
  -                close(sock);
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: can't open spool file %s: %s",
  -                    scanrequest, strerror(errno));
  -                return DEFER;
  -            }
  -            fsize = lseek(drweb_fd, 0, SEEK_END);
  -            if (fsize == -1) {
  -                close(sock);
  -                close(drweb_fd);
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: can't seek spool file %s: %s",
  -                    scanrequest, strerror(errno));
  -                return DEFER;
  -            }
  -            drweb_slen = htonl(fsize);
  -            lseek(drweb_fd, 0, SEEK_SET);
  -
  -            /* send scan request */
  -            if ((send(sock, &drweb_cmd, sizeof(drweb_cmd), 0) < 0) ||
  -                (send(sock, &drweb_flags, sizeof(drweb_flags), 0) < 0) ||
  -                (send(sock, &drweb_fin, sizeof(drweb_fin), 0) < 0) ||
  -                (send(sock, &drweb_slen, sizeof(drweb_slen), 0) < 0)) {
  -                close(sock);
  -                close(drweb_fd);
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: unable to send commands to socket (%s)", drweb_options);
  -                return DEFER;
  -            }
  -
  -            drweb_fbuf = (uschar *) malloc (fsize);
  -            if (!drweb_fbuf) {
  -                close(sock);
  -                close(drweb_fd);
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: unable to allocate memory %u for file (%s)",
  -                    fsize, scanrequest);
  -                return DEFER;
  -            }
  -
  -            result = read (drweb_fd, drweb_fbuf, fsize);
  -            if (result == -1) {
  -                close(sock);
  -                close(drweb_fd);
  -                free(drweb_fbuf);
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: can't read spool file %s: %s",
  -                    scanrequest, strerror(errno));
  -                return DEFER;
  -            }
  -            close(drweb_fd);
  -
  -            /* send file body to socket */
  -            if (send(sock, drweb_fbuf, fsize, 0) < 0) {
  -                close(sock);
  -                free(drweb_fbuf);
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: unable to send file body to socket (%s)", drweb_options);
  -                return DEFER;
  -            }
  -            close(drweb_fd);
  -        }
  -        else {
  -            /* open the drwebd UNIX socket */
  -            sock = socket(AF_UNIX, SOCK_STREAM, 0);
  -            if (sock < 0) {
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: can't open UNIX socket");
  -                return DEFER;
  -            }
  -            server.sun_family = AF_UNIX;
  -            Ustrcpy(server.sun_path, drweb_options);
  -            if (connect(sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
  -                close(sock);
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: unable to connect to socket (%s). errno=%d", drweb_options, errno);
  -                return DEFER;
  -            }
  -
  -            /* prepare variables */
  -            drweb_cmd = htonl(DRWEBD_SCAN_CMD);
  -            drweb_flags = htonl(DRWEBD_RETURN_VIRUSES | DRWEBD_IS_MAIL);
  -            snprintf(CS scanrequest, 1024,CS"%s/scan/%s/%s.eml", spool_directory, message_id, message_id);
  -            drweb_slen = htonl(Ustrlen(scanrequest));
  -
  -            /* send scan request */
  -            if ((send(sock, &drweb_cmd, sizeof(drweb_cmd), 0) < 0) ||
  -                (send(sock, &drweb_flags, sizeof(drweb_flags), 0) < 0) ||
  -                (send(sock, &drweb_slen, sizeof(drweb_slen), 0) < 0) ||
  -                (send(sock, scanrequest, Ustrlen(scanrequest), 0) < 0) ||
  -                (send(sock, &drweb_fin, sizeof(drweb_fin), 0) < 0)) {
  -                close(sock);
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: unable to send commands to socket (%s)", drweb_options);
  -                return DEFER;
  -            }
  -        }
  -
  -        /* wait for result */
  -        if ((bread = recv(sock, &drweb_rc, sizeof(drweb_rc), 0) != sizeof(drweb_rc))) {
  -            close(sock);
  -            log_write(0, LOG_MAIN|LOG_PANIC,
  -                "malware acl condition: drweb: unable to read return code");
  -            return DEFER;
  -        }
  -        drweb_rc = ntohl(drweb_rc);
  -
  -        if ((bread = recv(sock, &drweb_vnum, sizeof(drweb_vnum), 0) != sizeof(drweb_vnum))) {
  -            close(sock);
  -            log_write(0, LOG_MAIN|LOG_PANIC,
  -                "malware acl condition: drweb: unable to read the number of viruses");
  -            return DEFER;
  -        }
  -        drweb_vnum = ntohl(drweb_vnum);
  -
  -        /* "virus(es) found" if virus number is > 0 */
  -        if (drweb_vnum)
  -        {
  -            int i;
  -            uschar pre_malware_nb[256];
  -
  -            malware_name = malware_name_buffer;
  -
  -            /* setup default virus name */
  -            Ustrcpy(malware_name_buffer,"unknown");
  -
  -            /* read and concatenate virus names into one string */
  -            for (i=0;i<drweb_vnum;i++)
  -            {
  -                /* read the size of report */
  -                if ((bread = recv(sock, &drweb_slen, sizeof(drweb_slen), 0) != sizeof(drweb_slen))) {
  -                    close(sock);
  -                    log_write(0, LOG_MAIN|LOG_PANIC,
  -                        "malware acl condition: drweb: cannot read report size");
  -                    return DEFER;
  -                };
  -                drweb_slen = ntohl(drweb_slen);
  -
  -                /* read report body */
  -                if ((bread = recv(sock, tmpbuf, drweb_slen, 0)) != drweb_slen) {
  -                    close(sock);
  -                    log_write(0, LOG_MAIN|LOG_PANIC,
  -                        "malware acl condition: drweb: cannot read report string");
  -                    return DEFER;
  -                };
  -                tmpbuf[drweb_slen] = '\0';
  -
  -                /* set up match regex, depends on retcode */
  -                Ustrcpy(drweb_match_string, "infected\\swith\\s*(.+?)$");
  -
  -                drweb_re = pcre_compile( CS drweb_match_string,
  -                    PCRE_COPT,
  -                    (const char **)&rerror,
  -                    &roffset,
  -                    NULL );
  -
  -                /* try matcher on the line, grab substring */
  -                result = pcre_exec(drweb_re, NULL, CS tmpbuf, Ustrlen(tmpbuf), 0, 0, ovector, 30);
  -                if (result >= 2) {
  -                    pcre_copy_substring(CS tmpbuf, ovector, result, 1, CS pre_malware_nb, 255);
  -                }
  -                /* the first name we just copy to malware_name */
  -                if (i==0)
  -                    Ustrcpy(CS malware_name_buffer, CS pre_malware_nb);
  -                else {
  -                    /* concatenate each new virus name to previous */
  -                    int slen = Ustrlen(malware_name_buffer);
  -                    if (slen < (slen+Ustrlen(pre_malware_nb))) {
  -                        Ustrcat(malware_name_buffer, "/");
  -                        Ustrcat(malware_name_buffer, pre_malware_nb);
  -                    }
  -                }
  -            }
  -        }
  -        else {
  -            char *drweb_s = NULL;
  -
  -            if (drweb_rc & DERR_READ_ERR) drweb_s = "read error";
  -            if (drweb_rc & DERR_NOMEMORY) drweb_s = "no memory";
  -            if (drweb_rc & DERR_TIMEOUT)  drweb_s = "timeout";
  -            if (drweb_rc & DERR_BAD_CALL) drweb_s = "wrong command";
  -            /* retcodes DERR_SYMLINK, DERR_NO_REGFILE, DERR_SKIPPED.
  -             * DERR_TOO_BIG, DERR_TOO_COMPRESSED, DERR_SPAM,
  -             * DERR_CRC_ERROR, DERR_READSOCKET, DERR_WRITE_ERR
  -             * and others are ignored */
  -            if (drweb_s) {
  -                log_write(0, LOG_MAIN|LOG_PANIC,
  -                    "malware acl condition: drweb: drweb daemon retcode 0x%x (%s)", drweb_rc, drweb_s);
  -                close(sock);
  -                return DEFER;
  -            }
  -            /* no virus found */
  -            malware_name = NULL;
  -        };
  -        close(sock);
  -    }
  -    /* ----------------------------------------------------------------------- */
  +  /* "drweb" scanner type ----------------------------------------------- */
  +  /* v0.1 - added support for tcp sockets          */
  +  /* v0.0 - initial release -- support for unix sockets      */
  +  if (strcmpic(scanner_name,US"drweb") == 0) {
  +    uschar *drweb_options;
  +    uschar drweb_options_buffer[1024];
  +    uschar drweb_options_default[] = "/usr/local/drweb/run/drwebd.sock";
  +    struct sockaddr_un server;
  +    int sock, result, ovector[30];
  +    unsigned int port, fsize;
  +    uschar tmpbuf[1024], *drweb_fbuf;
  +    uschar scanrequest[1024];
  +    uschar drweb_match_string[128];
  +    int drweb_rc, drweb_cmd, drweb_flags = 0x0000, drweb_fd,
  +        drweb_vnum, drweb_slen, drweb_fin = 0x0000;
  +    unsigned long bread;
  +    uschar hostname[256];
  +    struct hostent *he;
  +    struct in_addr in;
  +    pcre *drweb_re;
  +
  +    if ((drweb_options = string_nextinlist(&av_scanner_work, &sep,
  +      drweb_options_buffer, sizeof(drweb_options_buffer))) == NULL) {
  +      /* no options supplied, use default options */
  +      drweb_options = drweb_options_default;
  +    };
  +
  +    if (*drweb_options != '/') {
  +
  +      /* extract host and port part */
  +      if( sscanf(CS drweb_options, "%s %u", hostname, &port) != 2 ) {
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: invalid socket '%s'", drweb_options);
  +        return DEFER;
  +      }
  +
  +      /* Lookup the host */
  +      if((he = gethostbyname(CS hostname)) == 0) {
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: failed to lookup host '%s'", hostname);
  +        return DEFER;
  +      }
  +
  +      in = *(struct in_addr *) he->h_addr_list[0];
  +
  +      /* Open the drwebd TCP socket */
  +      if ( (sock = ip_socket(SOCK_STREAM, AF_INET)) < 0) {
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: unable to acquire socket (%s)",
  +          strerror(errno));
  +        return DEFER;
  +      }
  +
  +      if (ip_connect(sock, AF_INET, (uschar*)inet_ntoa(in), port, 5) < 0) {
  +        close(sock);
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: connection to %s, port %u failed (%s)",
  +          inet_ntoa(in), port, strerror(errno));
  +        return DEFER;
  +      }
  +
  +      /* prepare variables */
  +      drweb_cmd = htonl(DRWEBD_SCAN_CMD);
  +      drweb_flags = htonl(DRWEBD_RETURN_VIRUSES | DRWEBD_IS_MAIL);
  +      snprintf(CS scanrequest, 1024,CS"%s/scan/%s/%s.eml",
  +            spool_directory, message_id, message_id);
  +
  +      /* calc file size */
  +      drweb_fd = open(CS scanrequest, O_RDONLY);
  +      if (drweb_fd == -1) {
  +        close(sock);
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: can't open spool file %s: %s",
  +          scanrequest, strerror(errno));
  +        return DEFER;
  +      }
  +      fsize = lseek(drweb_fd, 0, SEEK_END);
  +      if (fsize == -1) {
  +        close(sock);
  +        close(drweb_fd);
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: can't seek spool file %s: %s",
  +          scanrequest, strerror(errno));
  +        return DEFER;
  +      }
  +      drweb_slen = htonl(fsize);
  +      lseek(drweb_fd, 0, SEEK_SET);
  +
  +      /* send scan request */
  +      if ((send(sock, &drweb_cmd, sizeof(drweb_cmd), 0) < 0) ||
  +          (send(sock, &drweb_flags, sizeof(drweb_flags), 0) < 0) ||
  +          (send(sock, &drweb_fin, sizeof(drweb_fin), 0) < 0) ||
  +          (send(sock, &drweb_slen, sizeof(drweb_slen), 0) < 0)) {
  +        close(sock);
  +        close(drweb_fd);
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: unable to send commands to socket (%s)", drweb_options);
  +        return DEFER;
  +      }
  +
  +      drweb_fbuf = (uschar *) malloc (fsize);
  +      if (!drweb_fbuf) {
  +        close(sock);
  +        close(drweb_fd);
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: unable to allocate memory %u for file (%s)",
  +          fsize, scanrequest);
  +        return DEFER;
  +      }
  +
  +      result = read (drweb_fd, drweb_fbuf, fsize);
  +      if (result == -1) {
  +        close(sock);
  +        close(drweb_fd);
  +        free(drweb_fbuf);
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: can't read spool file %s: %s",
  +          scanrequest, strerror(errno));
  +        return DEFER;
  +      }
  +      close(drweb_fd);
  +
  +      /* send file body to socket */
  +      if (send(sock, drweb_fbuf, fsize, 0) < 0) {
  +        close(sock);
  +        free(drweb_fbuf);
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: unable to send file body to socket (%s)", drweb_options);
  +        return DEFER;
  +      }
  +      close(drweb_fd);
  +    }
  +    else {
  +      /* open the drwebd UNIX socket */
  +      sock = socket(AF_UNIX, SOCK_STREAM, 0);
  +      if (sock < 0) {
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: can't open UNIX socket");
  +        return DEFER;
  +      }
  +      server.sun_family = AF_UNIX;
  +      Ustrcpy(server.sun_path, drweb_options);
  +      if (connect(sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
  +        close(sock);
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: unable to connect to socket (%s). errno=%d", drweb_options, errno);
  +        return DEFER;
  +      }
  +
  +      /* prepare variables */
  +      drweb_cmd = htonl(DRWEBD_SCAN_CMD);
  +      drweb_flags = htonl(DRWEBD_RETURN_VIRUSES | DRWEBD_IS_MAIL);
  +      snprintf(CS scanrequest, 1024,CS"%s/scan/%s/%s.eml", spool_directory, message_id, message_id);
  +      drweb_slen = htonl(Ustrlen(scanrequest));
  +
  +      /* send scan request */
  +      if ((send(sock, &drweb_cmd, sizeof(drweb_cmd), 0) < 0) ||
  +          (send(sock, &drweb_flags, sizeof(drweb_flags), 0) < 0) ||
  +          (send(sock, &drweb_slen, sizeof(drweb_slen), 0) < 0) ||
  +          (send(sock, scanrequest, Ustrlen(scanrequest), 0) < 0) ||
  +          (send(sock, &drweb_fin, sizeof(drweb_fin), 0) < 0)) {
  +        close(sock);
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: unable to send commands to socket (%s)", drweb_options);
  +        return DEFER;
  +      }
  +    }
  +
  +    /* wait for result */
  +    if ((bread = recv(sock, &drweb_rc, sizeof(drweb_rc), 0) != sizeof(drweb_rc))) {
  +      close(sock);
  +      log_write(0, LOG_MAIN|LOG_PANIC,
  +        "malware acl condition: drweb: unable to read return code");
  +      return DEFER;
  +    }
  +    drweb_rc = ntohl(drweb_rc);
  +
  +    if ((bread = recv(sock, &drweb_vnum, sizeof(drweb_vnum), 0) != sizeof(drweb_vnum))) {
  +      close(sock);
  +      log_write(0, LOG_MAIN|LOG_PANIC,
  +        "malware acl condition: drweb: unable to read the number of viruses");
  +      return DEFER;
  +    }
  +    drweb_vnum = ntohl(drweb_vnum);
  +
  +    /* "virus(es) found" if virus number is > 0 */
  +    if (drweb_vnum)
  +    {
  +      int i;
  +      uschar pre_malware_nb[256];
  +
  +      malware_name = malware_name_buffer;
  +
  +      /* setup default virus name */
  +      Ustrcpy(malware_name_buffer,"unknown");
  +
  +      /* read and concatenate virus names into one string */
  +      for (i=0;i<drweb_vnum;i++)
  +      {
  +        /* read the size of report */
  +        if ((bread = recv(sock, &drweb_slen, sizeof(drweb_slen), 0) != sizeof(drweb_slen))) {
  +          close(sock);
  +          log_write(0, LOG_MAIN|LOG_PANIC,
  +            "malware acl condition: drweb: cannot read report size");
  +          return DEFER;
  +        };
  +        drweb_slen = ntohl(drweb_slen);
  +
  +        /* read report body */
  +        if ((bread = recv(sock, tmpbuf, drweb_slen, 0)) != drweb_slen) {
  +          close(sock);
  +          log_write(0, LOG_MAIN|LOG_PANIC,
  +            "malware acl condition: drweb: cannot read report string");
  +          return DEFER;
  +        };
  +        tmpbuf[drweb_slen] = '\0';
  +
  +        /* set up match regex, depends on retcode */
  +        Ustrcpy(drweb_match_string, "infected\\swith\\s*(.+?)$");
  +
  +        drweb_re = pcre_compile( CS drweb_match_string,
  +          PCRE_COPT,
  +          (const char **)&rerror,
  +          &roffset,
  +          NULL );
  +
  +        /* try matcher on the line, grab substring */
  +        result = pcre_exec(drweb_re, NULL, CS tmpbuf, Ustrlen(tmpbuf), 0, 0, ovector, 30);
  +        if (result >= 2) {
  +          pcre_copy_substring(CS tmpbuf, ovector, result, 1, CS pre_malware_nb, 255);
  +        }
  +        /* the first name we just copy to malware_name */
  +        if (i==0)
  +          Ustrcpy(CS malware_name_buffer, CS pre_malware_nb);
  +        else {
  +          /* concatenate each new virus name to previous */
  +          int slen = Ustrlen(malware_name_buffer);
  +          if (slen < (slen+Ustrlen(pre_malware_nb))) {
  +            Ustrcat(malware_name_buffer, "/");
  +            Ustrcat(malware_name_buffer, pre_malware_nb);
  +          }
  +        }
  +      }
  +    }
  +    else {
  +      char *drweb_s = NULL;
  +
  +      if (drweb_rc & DERR_READ_ERR) drweb_s = "read error";
  +      if (drweb_rc & DERR_NOMEMORY) drweb_s = "no memory";
  +      if (drweb_rc & DERR_TIMEOUT)  drweb_s = "timeout";
  +      if (drweb_rc & DERR_BAD_CALL) drweb_s = "wrong command";
  +      /* retcodes DERR_SYMLINK, DERR_NO_REGFILE, DERR_SKIPPED.
  +       * DERR_TOO_BIG, DERR_TOO_COMPRESSED, DERR_SPAM,
  +       * DERR_CRC_ERROR, DERR_READSOCKET, DERR_WRITE_ERR
  +       * and others are ignored */
  +      if (drweb_s) {
  +        log_write(0, LOG_MAIN|LOG_PANIC,
  +          "malware acl condition: drweb: drweb daemon retcode 0x%x (%s)", drweb_rc, drweb_s);
  +        close(sock);
  +        return DEFER;
  +      }
  +      /* no virus found */
  +      malware_name = NULL;
  +    };
  +    close(sock);
  +  }
  +  /* ----------------------------------------------------------------------- */
       else if (strcmpic(scanner_name,US"aveserver") == 0) {
         uschar *kav_options;
         uschar kav_options_buffer[1024];
  @@ -1107,57 +1107,57 @@
               return DEFER;
             }


  -      snprintf(CS scanrequest, 1024,CS"%s/scan/%s/%s.eml",
  -        spool_directory, message_id, message_id);
  +    snprintf(CS scanrequest, 1024,CS"%s/scan/%s/%s.eml",
  +      spool_directory, message_id, message_id);


  -      /* calc file size */
  -      clam_fd = open(CS scanrequest, O_RDONLY);
  -      if (clam_fd == -1) {
  -        log_write(0, LOG_MAIN|LOG_PANIC,
  -            "malware acl condition: clamd: can't open spool file %s: %s",
  -            scanrequest, strerror(errno));
  -        return DEFER;
  -      }
  -      fsize = lseek(clam_fd, 0, SEEK_END);
  -      if (fsize == -1) {
  -        log_write(0, LOG_MAIN|LOG_PANIC,
  -            "malware acl condition: clamd: can't seek spool file %s: %s",
  -            scanrequest, strerror(errno));
  -        return DEFER;
  -      }
  -      lseek(clam_fd, 0, SEEK_SET);
  -
  -      clamav_fbuf = (uschar *) malloc (fsize);
  -      if (!clamav_fbuf) {
  -        close(sockData);
  -        close(clam_fd);
  -        log_write(0, LOG_MAIN|LOG_PANIC,
  -            "malware acl condition: clamd: unable to allocate memory %u for file (%s)",
  -            fsize, scanrequest);
  -        return DEFER;
  -      }
  -
  -      result = read (clam_fd, clamav_fbuf, fsize);
  -      if (result == -1) {
  -        close(sockData);
  -        close(clam_fd);
  -        free(clamav_fbuf);
  -        log_write(0, LOG_MAIN|LOG_PANIC,
  -            "malware acl condition: clamd: can't read spool file %s: %s",
  -            scanrequest, strerror(errno));
  -        return DEFER;
  -      }
  -      close(clam_fd);
  -
  -      /* send file body to socket */
  -      if (send(sockData, clamav_fbuf, fsize, 0) < 0) {
  -        close(sockData);
  -        free(clamav_fbuf);
  -        log_write(0, LOG_MAIN|LOG_PANIC,
  -          "malware acl condition: clamd: unable to send file body to socket (%s:%u)", hostname, port);
  -        return DEFER;
  -      }
  -      free(clamav_fbuf);
  +    /* calc file size */
  +    clam_fd = open(CS scanrequest, O_RDONLY);
  +    if (clam_fd == -1) {
  +      log_write(0, LOG_MAIN|LOG_PANIC,
  +        "malware acl condition: clamd: can't open spool file %s: %s",
  +        scanrequest, strerror(errno));
  +      return DEFER;
  +    }
  +    fsize = lseek(clam_fd, 0, SEEK_END);
  +    if (fsize == -1) {
  +      log_write(0, LOG_MAIN|LOG_PANIC,
  +        "malware acl condition: clamd: can't seek spool file %s: %s",
  +        scanrequest, strerror(errno));
  +      return DEFER;
  +    }
  +    lseek(clam_fd, 0, SEEK_SET);
  +
  +    clamav_fbuf = (uschar *) malloc (fsize);
  +    if (!clamav_fbuf) {
  +      close(sockData);
  +      close(clam_fd);
  +      log_write(0, LOG_MAIN|LOG_PANIC,
  +        "malware acl condition: clamd: unable to allocate memory %u for file (%s)",
  +        fsize, scanrequest);
  +      return DEFER;
  +    }
  +
  +    result = read (clam_fd, clamav_fbuf, fsize);
  +    if (result == -1) {
  +      close(sockData);
  +      close(clam_fd);
  +      free(clamav_fbuf);
  +      log_write(0, LOG_MAIN|LOG_PANIC,
  +        "malware acl condition: clamd: can't read spool file %s: %s",
  +        scanrequest, strerror(errno));
  +      return DEFER;
  +    }
  +    close(clam_fd);
  +
  +    /* send file body to socket */
  +    if (send(sockData, clamav_fbuf, fsize, 0) < 0) {
  +      close(sockData);
  +      free(clamav_fbuf);
  +      log_write(0, LOG_MAIN|LOG_PANIC,
  +        "malware acl condition: clamd: unable to send file body to socket (%s:%u)", hostname, port);
  +      return DEFER;
  +    }
  +    free(clamav_fbuf);
             close(sockData);
           }
         }
  @@ -1223,7 +1223,7 @@
         /* Check the result. ClamAV Returns
            infected: -> "<filename>: <virusname> FOUND"
            not-infected: -> "<filename>: OK"
  -        error: -> "<filename>: <errcode> ERROR */
  +    error: -> "<filename>: <errcode> ERROR */


         if (!(*av_buffer)) {
           log_write(0, LOG_MAIN|LOG_PANIC,
  @@ -1287,8 +1287,8 @@
                                               mksd_options_buffer,
                                               sizeof(mksd_options_buffer))) != NULL) {
           mksd_maxproc = (int) strtol(CS mksd_options, &mksd_options_end, 10);
  -          if ((*mksd_options == '\0') || (*mksd_options_end != '\0') ||
  -          (mksd_maxproc < 1) || (mksd_maxproc > 32)) {
  +        if ((*mksd_options == '\0') || (*mksd_options_end != '\0') ||
  +      (mksd_maxproc < 1) || (mksd_maxproc > 32)) {
             log_write(0, LOG_MAIN|LOG_PANIC,
                       "malware acl condition: mksd: invalid option '%s'", mksd_options);
             return DEFER;
  @@ -1444,7 +1444,7 @@
             if (((p = strchr (line+4, ' ')) != NULL) && ((p-line) > 4)) {
               (*p) = '\0';
               Ustrcpy (malware_name_buffer, line+4);
  -        malware_name = malware_name_buffer;
  +      malware_name = malware_name_buffer;
               return OK;
             }
         }


  Index: readconf.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/readconf.c,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- readconf.c    10 May 2005 10:19:11 -0000    1.8
  +++ readconf.c    24 May 2005 08:15:02 -0000    1.9
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/readconf.c,v 1.8 2005/05/10 10:19:11 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/readconf.c,v 1.9 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -339,6 +339,12 @@
     { "spool_directory",          opt_stringptr,   &spool_directory },
   #ifdef EXPERIMENTAL_SRS
     { "srs_config",               opt_stringptr,   &srs_config },
  +  { "srs_hashlength",           opt_int,         &srs_hashlength },
  +  { "srs_hashmin",              opt_int,         &srs_hashmin },
  +  { "srs_maxage",               opt_int,         &srs_maxage },
  +  { "srs_secrets",              opt_stringptr,   &srs_secrets },
  +  { "srs_usehash",              opt_bool,        &srs_usehash },
  +  { "srs_usetimestamp",         opt_bool,        &srs_usetimestamp },
   #endif
     { "strip_excess_angle_brackets", opt_bool,     &strip_excess_angle_brackets },
     { "strip_trailing_dot",       opt_bool,        &strip_trailing_dot },


  Index: regex.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/regex.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- regex.c    17 Feb 2005 11:58:26 -0000    1.4
  +++ regex.c    24 May 2005 08:15:02 -0000    1.5
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/regex.c,v 1.4 2005/02/17 11:58:26 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/regex.c,v 1.5 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -113,7 +113,7 @@
       do {
         /* try matcher on the line */
         if (pcre_exec(re_list_item->re, NULL, CS linebuffer,
  -            (int)Ustrlen(linebuffer), 0, 0, NULL, 0) >= 0) {
  +      (int)Ustrlen(linebuffer), 0, 0, NULL, 0) >= 0) {
           Ustrncpy(regex_match_string_buffer, re_list_item->pcre_text, 1023);
           regex_match_string = regex_match_string_buffer;
           if (mime_stream == NULL)


  Index: spf.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/spf.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- spf.c    17 Feb 2005 11:58:26 -0000    1.3
  +++ spf.c    24 May 2005 08:15:02 -0000    1.4
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/spf.c,v 1.3 2005/02/17 11:58:26 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/spf.c,v 1.4 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -13,12 +13,10 @@
   #include "exim.h"
   #ifdef EXPERIMENTAL_SPF


  -/* #include "spf.h" */
  -
  -SPF_config_t        spfcid = NULL;
  -SPF_dns_config_t    spfdcid_resolv = NULL;
  -SPF_dns_config_t    spfdcid = NULL;
  -
  +SPF_server_t    *spf_server = NULL;
  +SPF_request_t   *spf_request = NULL;
  +SPF_response_t  *spf_response = NULL;
  +SPF_response_t  *spf_response_2mx = NULL;


   /* spf_init sets up a context that can be re-used for several
      messages on the same SMTP connection (that come from the
  @@ -27,40 +25,27 @@
   int spf_init(uschar *spf_helo_domain, uschar *spf_remote_addr) {
     uschar *p;


  -  /* paranoia */
  -  spfcid = NULL;
  -  spfdcid_resolv = NULL;
  -  spfdcid = NULL;
  -
  -  spfcid = SPF_create_config();
  -  if ( spfcid == NULL ) {
  -    debug_printf("spf: SPF_create_config() failed.\n");
  -      return 0;
  -  }
  +  spf_server = SPF_server_new(SPF_DNS_CACHE, 1);


  -  /* set up resolver */
  -  spfdcid_resolv = SPF_dns_create_config_resolv(NULL, 0);
  -  spfdcid = SPF_dns_create_config_cache(spfdcid_resolv, 8, 0);
  -
  -  if (spfdcid == NULL) {
  -    debug_printf("spf: SPF_dns_create_config_cache() failed.\n");
  -    spfcid = NULL;
  -    spfdcid_resolv = NULL;
  -      return 0;
  +  if ( spf_server == NULL ) {
  +    debug_printf("spf: SPF_server_new() failed.\n");
  +    return 0;
     }


  -  if (SPF_set_ip_str(spfcid, spf_remote_addr)) {
  -    debug_printf("spf: SPF_set_ip_str() failed.\n");
  -    spfcid = NULL;
  -    spfdcid_resolv = NULL;
  -      return 0;
  +  spf_request = SPF_request_new(spf_server);
  +
  +  if (SPF_request_set_ipv4_str(spf_request, spf_remote_addr)) {
  +    debug_printf("spf: SPF_request_set_ipv4_str() failed.\n");
  +    spf_server = NULL;
  +    spf_request = NULL;
  +    return 0;
     }


  -  if (SPF_set_helo_dom(spfcid, spf_helo_domain)) {
  +  if (SPF_request_set_helo_dom(spf_request, spf_helo_domain)) {
       debug_printf("spf: SPF_set_helo_dom() failed.\n");
  -    spfcid = NULL;
  -    spfdcid_resolv = NULL;
  -      return 0;
  +    spf_server = NULL;
  +    spf_request = NULL;
  +    return 0;
     }


     return 1;
  @@ -76,31 +61,30 @@
     uschar *list = *listptr;
     uschar *spf_result_id;
     uschar spf_result_id_buffer[128];
  -  SPF_output_t spf_output;
  -  int rc = SPF_RESULT_ERROR;
  +  int rc = SPF_RESULT_PERMERROR;


  -  if (!(spfcid && spfdcid)) {
  +  if (!(spf_server && spf_request)) {
       /* no global context, assume temp error and skip to evaluation */
  -    rc = SPF_RESULT_ERROR;
  +    rc = SPF_RESULT_PERMERROR;
       goto SPF_EVALUATE;
     };


  -  if (SPF_set_env_from(spfcid, spf_envelope_sender)) {
  +  if (SPF_request_set_env_from(spf_request, spf_envelope_sender)) {
       /* Invalid sender address. This should be a real rare occurence */
  -    rc = SPF_RESULT_ERROR;
  +    rc = SPF_RESULT_PERMERROR;
       goto SPF_EVALUATE;
     }


     /* get SPF result */
  -  spf_output = SPF_result(spfcid, spfdcid);
  +  SPF_request_query_mailfrom(spf_request, &spf_response);


     /* set up expansion items */
  -  spf_header_comment     = spf_output.header_comment ? (uschar *)spf_output.header_comment : NULL;
  -  spf_received           = spf_output.received_spf ? (uschar *)spf_output.received_spf : NULL;
  -  spf_result             = (uschar *)SPF_strresult(spf_output.result);
  -  spf_smtp_comment       = spf_output.smtp_comment ? (uschar *)spf_output.smtp_comment : NULL;
  +  spf_header_comment     = (uschar *)SPF_response_get_header_comment(spf_response);
  +  spf_received           = (uschar *)SPF_response_get_received_spf(spf_response);
  +  spf_result             = (uschar *)SPF_strresult(SPF_response_result(spf_response));
  +  spf_smtp_comment       = (uschar *)SPF_response_get_smtp_comment(spf_response);


- rc = spf_output.result;
+ rc = SPF_response_result(spf_response);

     /* We got a result. Now see if we should return OK or FAIL for it */
     SPF_EVALUATE:


  Index: spf.h
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/spf.h,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- spf.h    17 Feb 2005 11:58:26 -0000    1.3
  +++ spf.h    24 May 2005 08:15:02 -0000    1.4
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/spf.h,v 1.3 2005/02/17 11:58:26 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/spf.h,v 1.4 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -10,9 +10,14 @@


#ifdef EXPERIMENTAL_SPF

+/* Yes, we do have ns_type. spf.h redefines it if we don't set this. Doh */
+#define HAVE_NS_TYPE
#include <spf2/spf.h>
+
+
#include <spf2/spf_dns_resolv.h>
#include <spf2/spf_dns_cache.h>
+

   typedef struct spf_result_id {
     uschar *name;


  Index: spool_mbox.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/spool_mbox.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- spool_mbox.c    17 Feb 2005 11:58:26 -0000    1.4
  +++ spool_mbox.c    24 May 2005 08:15:02 -0000    1.5
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/spool_mbox.c,v 1.4 2005/02/17 11:58:26 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/spool_mbox.c,v 1.5 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -150,23 +150,23 @@


         snprintf(CS mbox_path, 1024, "%s/scan/%s", spool_directory, spooled_message_id);


  -    tempdir = opendir(CS mbox_path);
  -    /* loop thru dir & delete entries */
  -    n = 0;
  -    do {
  -      entry = readdir(tempdir);
  -      if (entry == NULL) break;
  -      snprintf(CS file_path, 1024,"%s/scan/%s/%s", spool_directory, spooled_message_id, entry->d_name);
  -      if ( (Ustrcmp(entry->d_name,"..") != 0) && (Ustrcmp(entry->d_name,".") != 0) ) {
  -        debug_printf("unspool_mbox(): unlinking '%s'\n", file_path);
  +  tempdir = opendir(CS mbox_path);
  +  /* loop thru dir & delete entries */
  +  n = 0;
  +  do {
  +    entry = readdir(tempdir);
  +    if (entry == NULL) break;
  +    snprintf(CS file_path, 1024,"%s/scan/%s/%s", spool_directory, spooled_message_id, entry->d_name);
  +    if ( (Ustrcmp(entry->d_name,"..") != 0) && (Ustrcmp(entry->d_name,".") != 0) ) {
  +      debug_printf("unspool_mbox(): unlinking '%s'\n", file_path);
                 n = unlink(CS file_path);
               };
  -    } while (n > -1);
  +  } while (n > -1);


  -    closedir(tempdir);
  +  closedir(tempdir);


  -    /* remove directory */
  -    n = rmdir(CS mbox_path);
  +  /* remove directory */
  +  n = rmdir(CS mbox_path);
       };
     };
   }


  Index: srs.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/srs.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- srs.c    17 Feb 2005 11:58:26 -0000    1.4
  +++ srs.c    24 May 2005 08:15:02 -0000    1.5
  @@ -1,11 +1,14 @@
  -/* $Cambridge: exim/exim-src/src/srs.c,v 1.4 2005/02/17 11:58:26 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/srs.c,v 1.5 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
   *************************************************/


   /* SRS - Sender rewriting scheme support
  -  ©2004 Miles Wilton <miles@???>
  +  (C)2004 Miles Wilton <miles@???>
  +
  +  SRS Support Version: 1.0a
  +
     License: GPL */


#include "exim.h"
@@ -24,72 +27,87 @@

   int eximsrs_init()
   {
  -  int co;
     uschar *list = srs_config;
  -  char secret_buf[SRS_MAX_SECRET_LENGTH];
  -  char *secret;
  -  char sbuf[4];
  -  char *sbufp;
  -  int hashlen, maxage;
  +  uschar secret_buf[SRS_MAX_SECRET_LENGTH];
  +  uschar *secret;
  +  uschar sbuf[4];
  +  uschar *sbufp;


  -
  -  if(!srs)
  +  // Check if this instance of Exim has not initialized SRS
  +  if(srs == NULL)
     {
  -    /* Check config */
  -    if(!srs_config)
  +    int co = 0;
  +    int hashlen, maxage;
  +    BOOL usetimestamp, usehash;
  +
  +    /* Copy config vars */
  +    hashlen = srs_hashlength;
  +    maxage = srs_maxage;
  +    usetimestamp = srs_usetimestamp;
  +    usehash = srs_usehash;
  +
  +    /* Pass srs_config var (overrides new config vars) */
  +    co = 0;
  +    if(srs_config != NULL)
       {
  -      log_write(0, LOG_MAIN | LOG_PANIC,
  -          "SRS Configuration Error");
  -      return DEFER;
  +      secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH);
  +
  +      if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
  +        maxage = atoi(sbuf);
  +
  +      if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
  +        hashlen = atoi(sbuf);
  +
  +      if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
  +        usetimestamp = atoi(sbuf);
  +
  +      if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
  +        usehash = atoi(sbuf);
       }


  -    /* Get config */
  +    if(srs_hashmin == -1)
  +      srs_hashmin = hashlen;
  +
  +    /* First secret specified in secrets? */
       co = 0;
  -    if((secret = string_nextinlist(&list, &co, secret_buf,
  -                                   SRS_MAX_SECRET_LENGTH)) == NULL)
  +    list = srs_secrets;
  +    if(secret == NULL)
       {
  -      log_write(0, LOG_MAIN | LOG_PANIC,
  -          "SRS Configuration Error: No secret specified");
  -      return DEFER;
  +      if((secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH)) == NULL)
  +      {
  +        log_write(0, LOG_MAIN | LOG_PANIC,
  +            "SRS Configuration Error: No secret specified");
  +        return DEFER;
  +      }
       }


  -    if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) == NULL)
  -      maxage = 31;
  -    else
  -      maxage = atoi(sbuf);
  +    /* Check config */
       if(maxage < 0 || maxage > 365)
       {
         log_write(0, LOG_MAIN | LOG_PANIC,
             "SRS Configuration Error: Invalid maximum timestamp age");
         return DEFER;
       }
  -
  -    if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) == NULL)
  -      hashlen = 6;
  -    else
  -      hashlen = atoi(sbuf);
  -    if(hashlen < 1 || hashlen > 20)
  +    if(hashlen < 1 || hashlen > 20 || srs_hashmin < 1 || srs_hashmin > 20)
       {
         log_write(0, LOG_MAIN | LOG_PANIC,
             "SRS Configuration Error: Invalid hash length");
         return DEFER;
       }


  -
  -    if((srs = srs_open(secret, strnlen(secret, SRS_MAX_SECRET_LENGTH),
  -                      maxage, hashlen, hashlen)) == NULL)
  +    if((srs = srs_open(secret, Ustrlen(secret), maxage, hashlen, srs_hashmin)) == NULL)
       {
         log_write(0, LOG_MAIN | LOG_PANIC,
             "Failed to allocate SRS memory");
         return DEFER;
       }


  +    srs_set_option(srs, SRS_OPTION_USETIMESTAMP, usetimestamp);
  +    srs_set_option(srs, SRS_OPTION_USEHASH, usehash);


  -    if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
  -      srs_set_option(srs, SRS_OPTION_USETIMESTAMP, atoi(sbuf));
  -
  -    if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
  -      srs_set_option(srs, SRS_OPTION_USEHASH, atoi(sbuf));
  +    /* Extra secrets? */
  +    while((secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH)) != NULL)
  +        srs_add_secret(srs, secret, strnlen(secret, SRS_MAX_SECRET_LENGTH));


       DEBUG(D_any)
         debug_printf("SRS initialized\n");
  @@ -101,7 +119,7 @@


   int eximsrs_done()
   {
  -  if(srs)
  +  if(srs != NULL)
       srs_close(srs);


     srs = NULL;
  @@ -151,11 +169,12 @@
   int eximsrs_db_set(BOOL reverse, uschar *srs_db)
   {
     if(reverse)
  -    srs_db_reverse = string_copy(srs_db);
  +    srs_db_reverse = (srs_db == NULL ? NULL : string_copy(srs_db));
     else
  -    srs_db_forward = string_copy(srs_db);
  +    srs_db_forward = (srs_db == NULL ? NULL : string_copy(srs_db));


  -  if(srs_set_db_functions(srs, eximsrs_db_insert, eximsrs_db_lookup) * SRS_RESULT_FAIL)
  +  if(srs_set_db_functions(srs, (srs_db_forward ? eximsrs_db_insert : NULL),
  +                               (srs_db_reverse ? eximsrs_db_lookup : NULL)) & SRS_RESULT_FAIL)
       return DEFER;


     return OK;
  @@ -165,11 +184,14 @@
   srs_result eximsrs_db_insert(srs_t *srs, char *data, uint data_len, char *result, uint result_len)
   {
     uschar *res;
  -  char buf[64];
  +  uschar buf[64];
  +
  +  if(srs_db_forward == NULL)
  +    return SRS_RESULT_DBERROR;


     srs_db_address = string_copyn(data, data_len);
     if(srs_generate_unique_id(srs, srs_db_address, buf, 64) & SRS_RESULT_FAIL)
  -    return DEFER;
  +    return SRS_RESULT_DBERROR;


     srs_db_key = string_copyn(buf, 16);


  @@ -179,7 +201,7 @@
     if(result_len < 17)
       return SRS_RESULT_DBERROR;


- strncpy(result, srs_db_key, result_len);
+ Ustrncpy(result, srs_db_key, result_len);

     return SRS_RESULT_OK;
   }
  @@ -188,6 +210,9 @@
   srs_result eximsrs_db_lookup(srs_t *srs, char *data, uint data_len, char *result, uint result_len)
   {
     uschar *res;
  +
  +  if(srs_db_reverse == NULL)
  +    return SRS_RESULT_DBERROR;


     srs_db_key = string_copyn(data, data_len);
     if((res = expand_string(srs_db_reverse)) == NULL)


  Index: structs.h
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/structs.h,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- structs.h    28 Apr 2005 13:06:32 -0000    1.5
  +++ structs.h    24 May 2005 08:15:02 -0000    1.6
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/structs.h,v 1.5 2005/04/28 13:06:32 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/structs.h,v 1.6 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -469,6 +469,10 @@
     uschar *errors_address;         /* where to send errors (NULL => sender) */
     header_line *extra_headers;     /* additional headers */
     uschar *remove_headers;         /* list of those to remove */
  +
  +  #ifdef EXPERIMENTAL_SRS
  +  uschar *srs_sender;             /* Change return path when delivering */
  +  #endif
   } address_item_propagated;


/* Bits for the flags field below */

  Index: verify.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/verify.c,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- verify.c    6 Apr 2005 16:26:42 -0000    1.16
  +++ verify.c    24 May 2005 08:15:02 -0000    1.17
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/verify.c,v 1.16 2005/04/06 16:26:42 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/verify.c,v 1.17 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -1229,6 +1229,10 @@
       addr_list = addr->next;


       fprintf(f, "%s", CS addr->address);
  +#ifdef EXPERIMENTAL_SRS
  +    if(addr->p.srs_sender)
  +      fprintf(f, "    [srs = %s]", addr->p.srs_sender);
  +#endif
       while (p != NULL)
         {
         fprintf(f, "\n    <-- %s", p->address);


  Index: auth-spa.h
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/auths/auth-spa.h,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- auth-spa.h    17 Feb 2005 11:58:27 -0000    1.3
  +++ auth-spa.h    24 May 2005 08:15:02 -0000    1.4
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/auths/auth-spa.h,v 1.3 2005/02/17 11:58:27 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/auths/auth-spa.h,v 1.4 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -32,49 +32,49 @@


   typedef struct
   {
  -       uint16x           len;
  -       uint16x           maxlen;
  -       uint32x           offset;
  +       uint16x         len;
  +       uint16x         maxlen;
  +       uint32x         offset;
   } SPAStrHeader;


   typedef struct
   {
  -       char           ident[8];
  -       uint32x           msgType;
  +       char         ident[8];
  +       uint32x         msgType;
          SPAStrHeader    uDomain;
  -       uint32x           flags;
  -       uint8x           challengeData[8];
  -       uint8x           reserved[8];
  +       uint32x         flags;
  +       uint8x         challengeData[8];
  +       uint8x         reserved[8];
          SPAStrHeader    emptyString;
  -       uint8x           buffer[1024];
  -       uint32x           bufIndex;
  +       uint8x         buffer[1024];
  +       uint32x         bufIndex;
   } SPAAuthChallenge;



   typedef struct
   {
  -       char           ident[8];
  -       uint32x           msgType;
  -       uint32x           flags;
  +       char         ident[8];
  +       uint32x         msgType;
  +       uint32x         flags;
          SPAStrHeader    user;
          SPAStrHeader    domain;
  -       uint8x           buffer[1024];
  -       uint32x           bufIndex;
  +       uint8x         buffer[1024];
  +       uint32x         bufIndex;
   } SPAAuthRequest;


   typedef struct
   {
  -       char           ident[8];
  -       uint32x           msgType;
  +       char         ident[8];
  +       uint32x         msgType;
          SPAStrHeader    lmResponse;
          SPAStrHeader    ntResponse;
          SPAStrHeader    uDomain;
          SPAStrHeader    uUser;
          SPAStrHeader    uWks;
          SPAStrHeader    sessionKey;
  -       uint32x           flags;
  -       uint8x           buffer[1024];
  -       uint32x           bufIndex;
  +       uint32x         flags;
  +       uint8x         buffer[1024];
  +       uint32x         bufIndex;
   } SPAAuthResponse;


#define spa_request_length(ptr) (((ptr)->buffer - (uint8x*)(ptr)) + (ptr)->bufIndex)

  Index: redirect.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/routers/redirect.c,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- redirect.c    28 Apr 2005 13:06:32 -0000    1.10
  +++ redirect.c    24 May 2005 08:15:02 -0000    1.11
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/routers/redirect.c,v 1.10 2005/04/28 13:06:32 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/routers/redirect.c,v 1.11 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -112,8 +112,10 @@
         (void *)offsetof(redirect_router_options_block, srs_alias) },
     { "srs_condition",      opt_stringptr,
         (void *)offsetof(redirect_router_options_block, srs_condition) },
  -  { "srs_db",             opt_stringptr,
  -      (void *)offsetof(redirect_router_options_block, srs_db) },
  +  { "srs_dbinsert",       opt_stringptr,
  +      (void *)offsetof(redirect_router_options_block, srs_dbinsert) },
  +  { "srs_dbselect",       opt_stringptr,
  +      (void *)offsetof(redirect_router_options_block, srs_dbselect) },
   #endif
     { "syntax_errors_text", opt_stringptr,
         (void *)offsetof(redirect_router_options_block, syntax_errors_text) },
  @@ -152,9 +154,10 @@
     NULL,        /* owngroups */
   #ifdef EXPERIMENTAL_SRS
     NULL,        /* srs */
  -  NULL,        /* srs_condition */
  -  NULL,        /* srs_db */
     NULL,        /* srs_alias */
  +  NULL,        /* srs_condition */
  +  NULL,        /* srs_dbinsert */
  +  NULL,        /* srs_dbselect */
   #endif
     022,         /* modemask */
     RDO_REWRITE, /* bit_options */
  @@ -529,6 +532,10 @@
   addr_prop.extra_headers = NULL;
   addr_prop.remove_headers = NULL;


+#ifdef EXPERIMENTAL_SRS
+addr_prop.srs_sender = NULL;
+#endif
+
/* When verifying and testing addresses, the "logwrite" command in filters
must be bypassed. */

  @@ -555,8 +562,8 @@
     }


   #ifdef EXPERIMENTAL_SRS
  -  /* For reverse SRS, fill the srs_recipient expandsion variable,
  -  on failure, return decline/fail as relevant */
  +  /* Perform SRS on recipient/return-path as required  */
  +
     if(ob->srs != NULL)
     {
       BOOL usesrs = TRUE;
  @@ -565,22 +572,78 @@
         usesrs = expand_check_condition(ob->srs_condition, "srs_condition expansion failed", NULL);


       if(usesrs)
  -      if(Ustrcmp(ob->srs, "reverse") == 0 || Ustrcmp(ob->srs, "reverseandforward") == 0)
  +    {
  +      int srs_action, n_srs;
  +      uschar *res;
  +      uschar *usedomain;
  +
  +      /* What are we doing? */
  +      if(Ustrcmp(ob->srs, "forward") == 0)
  +        srs_action = 1;
  +      else if(Ustrcmp(ob->srs, "reverseandforward") == 0)
         {
  -        uschar *res;
  -        int n_srs;
  +        srs_action = 3;


  +        if((ob->srs_dbinsert == NULL) ^ (ob->srs_dbselect == NULL))
  +          return DEFER;
  +      }
  +      else if(Ustrcmp(ob->srs, "reverse") == 0)
  +        srs_action = 2;
  +
  +      /* Reverse SRS */
  +      if(srs_action & 2)
  +      {
           srs_orig_recipient = addr->address;
  +
           eximsrs_init();
  -        if(ob->srs_db)
  -          eximsrs_db_set(TRUE, ob->srs_db);
  -        if((n_srs = eximsrs_reverse(&res, addr->address)) != OK)
  +        if(ob->srs_dbselect)
  +          eximsrs_db_set(TRUE, ob->srs_dbselect);
  +// Comment this out for now...
  +//        else
  +//          eximsrs_db_set(TRUE, NULL);
  +
  +        if((n_srs = eximsrs_reverse(&res, addr->address)) == OK)
  +        {
  +          srs_recipient = res;
  +          DEBUG(D_any)
  +            debug_printf("SRS (reverse): Recipient '%s' rewritten to '%s'\n", srs_orig_recipient, srs_recipient);
  +        }
  +
  +        eximsrs_done();
  +
  +        if(n_srs != OK)
             return n_srs;
  -        srs_recipient = res;
  +      }
  +
  +      /* Forward SRS */
  +      /* No point in actually performing SRS if we are just verifying a recipient */
  +      if((srs_action & 1) && !verify && (sender_address ? sender_address[0] != 0 : FALSE))
  +      {
  +
  +        srs_orig_sender = sender_address;
  +        eximsrs_init();
  +        if(ob->srs_dbinsert)
  +          eximsrs_db_set(FALSE, ob->srs_dbinsert);
  +// Comment this out for now...
  +//        else
  +//          eximsrs_db_set(FALSE, NULL);
  +
  +        if(ob->srs_alias != NULL ? (usedomain = expand_string(ob->srs_alias)) == NULL : 1)
  +          usedomain = deliver_domain;
  +
  +        if((n_srs = eximsrs_forward(&res, sender_address, usedomain)) == OK)
  +        {
  +          addr_prop.srs_sender = res;
  +          DEBUG(D_any)
  +            debug_printf("SRS (forward): Sender '%s' rewritten to '%s'\n", srs_orig_sender, res);
  +        }
  +
           eximsrs_done();
  -        DEBUG(D_any)
  -          debug_printf("SRS: Recipient '%s' rewritten to '%s'\n", srs_orig_recipient, srs_recipient);
  +
  +        if(n_srs != OK)
  +          return n_srs;
         }
  +    }
     }
   #endif


  @@ -812,39 +875,6 @@
       (addr_prop.errors_address != NULL)? addr_prop.errors_address : US"",
       (addr_prop.errors_address != NULL)? "\n" : "");
     }
  -
  -#ifdef EXPERIMENTAL_SRS
  -  /* On successful redirection, check for SRS forwarding and adjust sender */
  -  if(ob->srs != NULL)
  -  {
  -    BOOL usesrs = TRUE;
  -
  -    if(ob->srs_condition != NULL)
  -      usesrs = expand_check_condition(ob->srs_condition, "srs_condition expansion failed", NULL);
  -
  -    if(usesrs)
  -      if((Ustrcmp(ob->srs, "forward") == 0 || Ustrcmp(ob->srs, "reverseandforward") == 0) && !verify)
  -      {
  -        uschar *res;
  -        uschar *usedomain;
  -        int n_srs;
  -
  -        srs_orig_sender = sender_address;
  -        eximsrs_init();
  -        if(ob->srs_db)
  -          eximsrs_db_set(FALSE, ob->srs_db);
  -
  -        if(ob->srs_alias != NULL ? (usedomain = expand_string(ob->srs_alias)) == NULL : 1)
  -          usedomain = deliver_domain;
  -
  -        if((n_srs = eximsrs_forward(&res, sender_address, usedomain)) != OK)
  -          return n_srs;
  -        sender_address = res;
  -        DEBUG(D_any)
  -          debug_printf("SRS: Sender '%s' rewritten to '%s'\n", srs_orig_sender, sender_address);
  -    }
  -  }
  -#endif


/* Control gets here only when the address has been completely handled. Put the
original address onto the succeed queue so that any retry items that get

  Index: redirect.h
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/routers/redirect.h,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- redirect.h    6 Apr 2005 14:40:24 -0000    1.4
  +++ redirect.h    24 May 2005 08:15:02 -0000    1.5
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/routers/redirect.h,v 1.4 2005/04/06 14:40:24 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/routers/redirect.h,v 1.5 2005/05/24 08:15:02 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -37,9 +37,10 @@


   #ifdef EXPERIMENTAL_SRS
     uschar *srs;
  -  uschar *srs_condition;
  -  uschar *srs_db;
     uschar *srs_alias;
  +  uschar *srs_condition;
  +  uschar *srs_dbinsert;
  +  uschar *srs_dbselect;
   #endif


     int   modemask;