"Fossies" - the Fresh Open Source Software Archive

Member "libspf2-1.2.10/src/libspf2/spf_response.c" (28 Jan 2012, 6963 Bytes) of package /linux/privat/libspf2-1.2.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "spf_response.c" see the Fossies "Dox" file reference documentation.

    1 /* 
    2  * This program is free software; you can redistribute it and/or modify
    3  * it under the terms of either:
    4  * 
    5  *   a) The GNU Lesser General Public License as published by the Free
    6  *      Software Foundation; either version 2.1, or (at your option) any
    7  *      later version, 
    8  * 
    9  *   OR
   10  * 
   11  *   b) The two-clause BSD license.
   12  *
   13  * These licenses can be found with the distribution in the file LICENSES
   14  */
   15 
   16 #include "spf_sys_config.h"
   17 
   18 #ifdef STDC_HEADERS
   19 # include <stdio.h>        /* stdin / stdout */
   20 # include <stdlib.h>       /* malloc / free */
   21 #endif
   22 
   23 #ifdef HAVE_STRING_H
   24 # include <string.h>       /* strstr / strdup */
   25 #else
   26 # ifdef HAVE_STRINGS_H
   27 #  include <strings.h>       /* strstr / strdup */
   28 # endif
   29 #endif
   30 
   31 
   32 #include "spf.h"
   33 #include "spf_dns.h"
   34 #include "spf_response.h"
   35 
   36 SPF_response_t *
   37 SPF_response_new(SPF_request_t *spf_request)
   38 {
   39     SPF_response_t  *rp;
   40 
   41     rp = (SPF_response_t *)malloc(sizeof(SPF_response_t));
   42     if (! rp)
   43         return rp;
   44     memset(rp, 0, sizeof(SPF_response_t));
   45 
   46     rp->spf_request = spf_request;
   47     rp->result = SPF_RESULT_INVALID;
   48 
   49     return rp;
   50 }
   51 
   52 void
   53 SPF_response_free(SPF_response_t *rp)
   54 {
   55     int  i;
   56 
   57     if (rp->received_spf)
   58         free(rp->received_spf);
   59     /* Don't free received_spf_value - it points into received_spf */
   60     if (rp->header_comment)
   61         free(rp->header_comment);
   62     if (rp->smtp_comment)
   63         free(rp->smtp_comment);
   64     if (rp->explanation)
   65         free(rp->explanation);
   66 
   67     if (rp->errors) {
   68         for (i = 0; i < rp->errors_length; i++) {
   69             free(rp->errors[i].message);
   70         }
   71         free(rp->errors);
   72     }
   73 
   74     free(rp);
   75 }
   76 
   77 static SPF_response_t *
   78 SPF_response_choose(SPF_response_t *yes, SPF_response_t *no)
   79 {
   80     SPF_response_free(no);
   81     return yes;
   82 }
   83 
   84 /*
   85  * This is rather a guess-and-fiddle routine which tries to pick
   86  * the best of both worlds. It doesn't currently deal with error
   87  * messages at all.
   88  */
   89 SPF_response_t *
   90 SPF_response_combine(SPF_response_t *main, SPF_response_t *r2mx)
   91 {
   92     switch (SPF_response_result(main)) {
   93         case SPF_RESULT_INVALID:
   94             /* If the main failed entirely, use the secondary */
   95             return SPF_response_choose(r2mx, main);
   96 
   97         case SPF_RESULT_PASS:
   98             /* If the main passed, use main */
   99             return SPF_response_choose(main, r2mx);
  100 
  101         case SPF_RESULT_NEUTRAL:
  102             /* If the main is neutral: */
  103             switch (SPF_response_result(r2mx)) {
  104                 case SPF_RESULT_PASS:
  105                     /* Use the secondary if it passed */
  106                     return SPF_response_choose(r2mx, main);
  107                 default:
  108                     /* Otherwise just use the main */
  109                     return SPF_response_choose(main, r2mx);
  110             }
  111 
  112         case SPF_RESULT_FAIL:
  113             /* If the main failed, use the secondary */
  114             return SPF_response_choose(r2mx, main);
  115 
  116         case SPF_RESULT_TEMPERROR:
  117         case SPF_RESULT_PERMERROR:
  118         case SPF_RESULT_SOFTFAIL:
  119         default:
  120             /* If the main is peculiar, including softfail: */
  121             switch (SPF_response_result(r2mx)) {
  122                 case SPF_RESULT_PASS:
  123                 case SPF_RESULT_NEUTRAL:
  124                 case SPF_RESULT_SOFTFAIL:
  125                     /* Use the secondary if it didn't fail */
  126                     return SPF_response_choose(r2mx, main);
  127                 default:
  128                     /* Otherwise just use the main */
  129                     return SPF_response_choose(main, r2mx);
  130             }
  131     }
  132 }
  133 
  134 SPF_result_t
  135 SPF_response_result(SPF_response_t *rp)
  136 {
  137     return rp->result;
  138 }
  139 
  140 SPF_reason_t
  141 SPF_response_reason(SPF_response_t *rp)
  142 {
  143     return rp->reason;
  144 }
  145 
  146 SPF_errcode_t
  147 SPF_response_errcode(SPF_response_t *rp)
  148 {
  149     return rp->err;
  150 }
  151 
  152 const char *
  153 SPF_response_get_received_spf(SPF_response_t *rp)
  154 {
  155     return rp->received_spf;
  156 }
  157 
  158 const char *
  159 SPF_response_get_received_spf_value(SPF_response_t *rp)
  160 {
  161     return rp->received_spf_value;
  162 }
  163 
  164 const char *
  165 SPF_response_get_header_comment(SPF_response_t *rp)
  166 {
  167     return rp->header_comment;
  168 }
  169 
  170 const char *
  171 SPF_response_get_smtp_comment(SPF_response_t *rp)
  172 {
  173     return rp->smtp_comment;
  174 }
  175 
  176 const char *
  177 SPF_response_get_explanation(SPF_response_t *rp)
  178 {
  179     return rp->explanation;
  180 }
  181 
  182 /* Error manipulation functions */
  183 
  184 #define SPF_ERRMSGSIZE      4096
  185 
  186 static SPF_errcode_t
  187 SPF_response_add_error_v(SPF_response_t *rp,
  188                 SPF_errcode_t code, int is_error,
  189                 const char *text, int idx,
  190                 const char *format, va_list ap)
  191 {
  192     SPF_error_t *tmp;
  193     char         buf[SPF_ERRMSGSIZE];
  194     int          size;
  195 
  196     /* TODO: Use text and idx */
  197 
  198     if (!format)
  199         format = SPF_strerror(code);
  200     size = vsnprintf(buf, sizeof(buf), format, ap);
  201     if (text != NULL) {
  202         snprintf(&buf[size], sizeof(buf) - size,
  203                 " near '%.12s'", &text[idx]);
  204     }
  205     buf[SPF_ERRMSGSIZE - 1] = '\0';
  206 
  207     if (rp->errors_length == rp->errors_size) {
  208         size = rp->errors_size + (rp->errors_size / 4) + 4;
  209         tmp = (SPF_error_t *)realloc(rp->errors, size * sizeof(SPF_error_t));
  210         if (! tmp) {
  211             SPF_error("Failed to allocate memory for extra response error");
  212             return code;
  213         }
  214         rp->errors = tmp;
  215         rp->errors_size = size;
  216     }
  217 
  218     rp->errors[rp->errors_length].code = code;
  219     rp->errors[rp->errors_length].is_error = is_error;
  220     /* If we are a memory error, this might fail. */
  221     rp->errors[rp->errors_length].message = strdup(buf);
  222     rp->errors_length++;
  223 
  224     return code;
  225 }
  226 
  227 #define SPF_ADD_ERROR(_ise, _txt, _ix) \
  228     va_list  ap; va_start(ap, format); \
  229     SPF_response_add_error_v(rp, code, _ise, _txt, _ix, format, ap); \
  230     rp->num_errors++; \
  231     va_end(ap); return code;
  232 #define SPF_ADD_WARN(_ise, _txt, _ix) \
  233     va_list  ap; va_start(ap, format); \
  234     SPF_response_add_error_v(rp, code, _ise, _txt, _ix, format, ap); \
  235     va_end(ap); return code;
  236 
  237 SPF_errcode_t
  238 SPF_response_add_error_ptr(SPF_response_t *rp,
  239                 SPF_errcode_t code,
  240                 const char *text, const char *tptr,
  241                 const char *format, ...)
  242 {
  243     SPF_ADD_ERROR(1, text ? text : tptr, text ? (tptr - text) : 0);
  244 }
  245 
  246 SPF_errcode_t
  247 SPF_response_add_error_idx(SPF_response_t *rp,
  248                 SPF_errcode_t code,
  249                 const char *text, int idx,
  250                 const char *format, ...)
  251 {
  252     SPF_ADD_ERROR(1, text, idx);
  253 }
  254 
  255 SPF_errcode_t
  256 SPF_response_add_error(SPF_response_t *rp,
  257                 SPF_errcode_t code,
  258                 const char *format, ...)
  259 {
  260     SPF_ADD_ERROR(1, NULL, 0);
  261 }
  262 
  263 SPF_errcode_t
  264 SPF_response_add_warn_ptr(SPF_response_t *rp,
  265                 SPF_errcode_t code,
  266                 const char *text, const char *tptr,
  267                 const char *format, ...)
  268 {
  269     SPF_ADD_WARN(0, text ? text : tptr, text ? (tptr - text) : 0);
  270 }
  271 
  272 SPF_errcode_t
  273 SPF_response_add_warn_idx(SPF_response_t *rp,
  274                 SPF_errcode_t code,
  275                 const char *text, int idx,
  276                 const char *format, ...)
  277 {
  278     SPF_ADD_WARN(0, text, idx);
  279 }
  280 
  281 SPF_errcode_t
  282 SPF_response_add_warn(SPF_response_t *rp,
  283                 SPF_errcode_t code,
  284                 const char *format, ...)
  285 {
  286     SPF_ADD_WARN(0, NULL, 0);
  287 }
  288 
  289 int
  290 SPF_response_messages(SPF_response_t *rp)
  291 {
  292     return rp->errors_length;
  293 }
  294 
  295 int
  296 SPF_response_errors(SPF_response_t *rp)
  297 {
  298     return rp->num_errors;
  299 }
  300 
  301 int
  302 SPF_response_warnings(SPF_response_t *rp)
  303 {
  304     return rp->errors_length - rp->num_errors;
  305 }
  306 
  307 SPF_error_t *
  308 SPF_response_message(SPF_response_t *rp, int idx)
  309 {
  310     return &rp->errors[idx];
  311 }
  312 
  313 SPF_errcode_t   
  314 SPF_error_code(SPF_error_t *err)
  315 {
  316     return err->code;
  317 }
  318 
  319 const char *
  320 SPF_error_message(SPF_error_t *err)
  321 {
  322     return err->message;
  323 }
  324 
  325 char
  326 SPF_error_errorp(SPF_error_t *err)
  327 {
  328     return err->is_error;
  329 }