"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 }