Logo Search packages:      
Sourcecode: dcc version File versions  Download package

reply.c

/* Distributed Checksum Clearinghouse
 *
 * SMTP reply strings
 *
 * Copyright (c) 2005 by Rhyolite Software
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE
 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 *
 * Rhyolite Software DCC 1.2.74-1.2 $Revision$
 */


#include "cmn_defs.h"

REPLY rej_reply;
REPLY grey_reply;
REPLY temp_reply;


void
parse_reply_arg(const char *arg)
{
      if (rej_reply.rcode[0] == '\0') {
            parse_reply(&rej_reply, 1,
                      DCC_XCODE, DCC_RCODE, arg);
      } else if (grey_reply.rcode[0] == '\0') {
            parse_reply(&grey_reply, 1,
                      GREY_XCODE, GREY_RCODE, arg);
            if (grey_reply.rcode[0] != '4'
                || grey_reply.xcode[0] != '4') {
                  dcc_error_msg("invalid greylist"
                              " message: %s", arg);
                  grey_reply.rcode[0] = '\0';
            }
      } else {
            dcc_error_msg("more than 2 -r settings");
      }
}



void
finish_replies(void)
{
      parse_reply(&temp_reply, 0,
                "4.7.1", "451", "DCC failure");
      if (rej_reply.rcode[0] == '\0')
            parse_reply(&rej_reply, 1, DCC_XCODE, DCC_RCODE,
                      "mail %s from %s rejected by DCC");
      if (grey_reply.rcode[0] == '\0')
            parse_reply(&grey_reply, 1, GREY_XCODE, GREY_RCODE,
                      "mail %s from %s temporary greylist embargoed");
}



/* Parse a string into RFC 821 and RFC 2034 codes and a pattern to make a
 * message, or generate the codes for a string that has a message
 * without codes.
 * The should be something like "5.7.1 550 spammer go home"
 * or "spammer go home".
 * The pattern can have as many as two "%s" references to the sendmail
 * queue-ID and SMTP client IP address.
 */
void
parse_reply(REPLY *reply,           /* to here */
          u_char pat_ok,
          const char *xcode,        /* default value such as "5.7.1" */
          const char *rcode,        /* default value such as "550" */
          const char *str)          /* from here */
{
      const char *p;
      int dot1, dot2, e;
      char c, *pat;
      int p_cnt;

      p = dcc_parse_word(0, reply->xcode, sizeof(reply->xcode), str,
                     0, 0, 0);
      p = dcc_parse_word(0, reply->rcode, sizeof(reply->rcode), p,
                     0, 0, 0);
      if (!p
          || (reply->rcode[0] != '4' && reply->rcode[0] != '5')
          || reply->rcode[0] != reply->xcode[0]
          || strspn(reply->rcode, "0123456789") != 3
          || (dot1 = strspn(reply->xcode, "0123456789")) == 0
          || reply->xcode[dot1] != '.'
          || (dot2 = strspn(&reply->xcode[dot1+1], "0123456789")) == 0
          || reply->xcode[dot1+1+dot2] != '.'
          || (e = strspn(&reply->xcode[dot1+1+dot2+1], "0123456789")) == 0
          || reply->xcode[dot1+1+dot2+1+e] != '\0') {
            BUFCPY(reply->xcode, xcode);
            BUFCPY(reply->rcode, rcode);
            p = str;
      }

      p += strspn(p, DCC_WHITESPACE);
      if (!strchr(p, '%')) {
            reply->is_pat = 0;
            BUFCPY(reply->pat, p);
      } else {
            reply->is_pat = 1;
            p_cnt = pat_ok ? 0 : 2;
            pat = reply->pat;
            do {
                  c = *p++;
                  if (c == '\0')
                        break;
                  *pat++ = c;
                  if (c == '%') {
                        if (*p != 's' || ++p_cnt > 2)
                              *pat++ = '%';
                  }
            } while (pat < LAST(reply->pat)-2);
            *pat = '\0';
      }
}



void
make_reply(CMN_WORK *cwp, REPLY *reply)
{
      const char *clnt;

      memcpy(cwp->reply.rcode, reply->rcode, sizeof(cwp->reply.rcode));
      memcpy(cwp->reply.xcode, reply->xcode, sizeof(cwp->reply.xcode));
      if (!reply->is_pat) {
            cwp->reply_ptr = reply->pat;
      } else {
            clnt = cwp->clnt_str;
            if (!strncmp("::ffff:", clnt, 7))
                  clnt += 7;  /* strip IPv6 prefix */
            snprintf(cwp->reply_buf, sizeof(cwp->reply_buf),
                   reply->pat, cwp->id, clnt);
            cwp->reply_ptr = cwp->reply_buf;
      }
}

Generated by  Doxygen 1.6.0   Back to index