Mercurial > masqmail-0.2
comparison src/header.c @ 0:08114f7dcc23 0.2.21
this is masqmail-0.2.21 from oliver kurth
author | meillo@marmaro.de |
---|---|
date | Fri, 26 Sep 2008 17:05:23 +0200 |
parents | |
children | 26e34ae9a3e3 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:08114f7dcc23 |
---|---|
1 /* MasqMail | |
2 Copyright (C) 2000 Oliver Kurth | |
3 | |
4 This program is free software; you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 2 of the License, or | |
7 (at your option) any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
15 along with this program; if not, write to the Free Software | |
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
17 */ | |
18 #include "masqmail.h" | |
19 | |
20 header_name header_names[] = | |
21 { | |
22 { "From", HEAD_FROM, }, | |
23 { "Sender", HEAD_SENDER, }, | |
24 { "To", HEAD_TO, }, | |
25 { "Cc", HEAD_CC, }, | |
26 { "Bcc", HEAD_BCC, }, | |
27 { "Date", HEAD_DATE, }, | |
28 { "Message-Id", HEAD_MESSAGE_ID, }, | |
29 { "Reply-To", HEAD_REPLY_TO, }, | |
30 { "Subject", HEAD_SUBJECT, }, | |
31 { "Return-Path", HEAD_RETURN_PATH, }, | |
32 { "Envelope-To", HEAD_ENVELOPE_TO, }, | |
33 { "Received", HEAD_RECEIVED }, | |
34 }; | |
35 | |
36 /* this was borrowed from exim and slightly changed */ | |
37 gchar *rec_timestamp() | |
38 { | |
39 static gchar buf[64]; | |
40 int len; | |
41 | |
42 time_t now = time(NULL); | |
43 struct tm *t = localtime(&now); | |
44 | |
45 int diff_hour, diff_min; | |
46 struct tm local; | |
47 struct tm *gmt; | |
48 | |
49 memcpy(&local, t, sizeof(struct tm)); | |
50 gmt = gmtime(&now); | |
51 diff_min = 60*(local.tm_hour - gmt->tm_hour) + local.tm_min - gmt->tm_min; | |
52 if (local.tm_year != gmt->tm_year) | |
53 diff_min += (local.tm_year > gmt->tm_year)? 1440 : -1440; | |
54 else if (local.tm_yday != gmt->tm_yday) | |
55 diff_min += (local.tm_yday > gmt->tm_yday)? 1440 : -1440; | |
56 diff_hour = diff_min/60; | |
57 diff_min = abs(diff_min - diff_hour*60); | |
58 | |
59 len = strftime(buf, sizeof(buf), "%a, ", &local); | |
60 g_snprintf(buf + len, sizeof(buf) - len, "%02d ", local.tm_mday); | |
61 len += strlen(buf + len); | |
62 len += strftime(buf + len, sizeof(buf) - len, "%b %Y %H:%M:%S", &local); | |
63 g_snprintf(buf + len, sizeof(buf) - len, " %+03d%02d", diff_hour, diff_min); | |
64 | |
65 return buf; | |
66 } | |
67 | |
68 /* finds list of headers matching id | |
69 if id == HEAD_UNKNOWN and header == NULL finds all unknown headers | |
70 else finds all headers matching header | |
71 */ | |
72 GList *find_header(GList *hdr_list, header_id id, gchar *hdr_str) | |
73 { | |
74 GList *found_list = NULL; | |
75 GList *node; | |
76 | |
77 if((id != HEAD_UNKNOWN) || (hdr_str == NULL)){ | |
78 foreach(hdr_list, node){ | |
79 header *hdr = (header *)(node->data); | |
80 if(hdr->id == id) | |
81 found_list = g_list_append(found_list, hdr); | |
82 } | |
83 }else{ | |
84 foreach(hdr_list, node){ | |
85 header *hdr = (header *)(node->data); | |
86 gchar buf[64], *q = buf, *p = hdr->header; | |
87 | |
88 while(*p != ':' && q < buf+63 && *p) *(q++) = *(p++); | |
89 *q = 0; | |
90 | |
91 if(strcasecmp(buf, hdr_str) == 0) | |
92 found_list = g_list_append(found_list, hdr); | |
93 } | |
94 } | |
95 return found_list; | |
96 } | |
97 | |
98 void header_unfold(header *hdr) | |
99 { | |
100 gchar *tmp_hdr = g_malloc(strlen(hdr->header)); | |
101 gchar *p = hdr->header, *q = tmp_hdr; | |
102 gboolean flag = FALSE; | |
103 | |
104 while(*p){ | |
105 if(*p != '\n') | |
106 *(q++) = *p; | |
107 else | |
108 flag = TRUE; | |
109 p++; | |
110 } | |
111 *(q++) = '\n'; | |
112 | |
113 if(flag){ | |
114 gchar *new_hdr; | |
115 | |
116 g_free(hdr->header); | |
117 new_hdr = g_strdup(tmp_hdr); | |
118 g_free(tmp_hdr); | |
119 hdr->value = new_hdr + (hdr->value - hdr->header); | |
120 hdr->header = new_hdr; | |
121 } | |
122 } | |
123 | |
124 #define MAX_HDR_LEN 72 | |
125 void header_fold(header *hdr) | |
126 { | |
127 gint len = strlen(hdr->header); | |
128 gchar *p, *q; | |
129 /* size is probably overestimated, but so we are on the safe side */ | |
130 gchar *tmp_hdr = g_malloc(len + 2*len/MAX_HDR_LEN); | |
131 | |
132 p = hdr->header; | |
133 q = tmp_hdr; | |
134 | |
135 if(p[len-1] == '\n') | |
136 p[len-1] = 0; | |
137 | |
138 while(*p){ | |
139 gint i,l; | |
140 gchar *pp; | |
141 | |
142 /* look forward and find potential break points */ | |
143 i = 0; l = -1; | |
144 pp = p; | |
145 while(*pp && (i < MAX_HDR_LEN)){ | |
146 if((*pp == ' ') || (*pp == '\t')) | |
147 l = i; | |
148 pp++; | |
149 i++; | |
150 } | |
151 if(!*pp) l = pp-p; /* take rest, if EOS found */ | |
152 | |
153 if(l == -1){ | |
154 /* no potential break point was found within MAX_HDR_LEN | |
155 so advance further until the next */ | |
156 while(*pp && *pp != ' ' && *pp != '\t'){ | |
157 pp++; | |
158 i++; | |
159 } | |
160 l = i; | |
161 } | |
162 | |
163 /* copy */ | |
164 i = 0; | |
165 while(i < l){ | |
166 *(q++) = *(p++); | |
167 i++; | |
168 } | |
169 *(q++) = '\n'; | |
170 *(q++) = *(p++); /* this is either space, tab or 0 */ | |
171 } | |
172 { | |
173 gchar *new_hdr; | |
174 | |
175 g_free(hdr->header); | |
176 new_hdr = g_strdup(tmp_hdr); | |
177 g_free(tmp_hdr); | |
178 hdr->value = new_hdr + (hdr->value - hdr->header); | |
179 hdr->header = new_hdr; | |
180 } | |
181 } | |
182 | |
183 header *create_header(header_id id, gchar *fmt, ...) | |
184 { | |
185 gchar *p; | |
186 header *hdr; | |
187 va_list args; | |
188 va_start(args, fmt); | |
189 | |
190 if((hdr = g_malloc(sizeof(header)))){ | |
191 | |
192 hdr->id = id; | |
193 hdr->header = g_strdup_vprintf(fmt, args); | |
194 hdr->value = NULL; | |
195 | |
196 p = hdr->header; | |
197 while(*p && *p != ':') p++; | |
198 if(*p) | |
199 hdr->value = p+1; | |
200 } | |
201 | |
202 va_end(args); | |
203 return hdr; | |
204 } | |
205 | |
206 void destroy_header(header *hdr) | |
207 { | |
208 if(hdr){ | |
209 if(hdr->header) g_free(hdr->header); | |
210 g_free(hdr); | |
211 } | |
212 } | |
213 | |
214 header *copy_header(header *hdr) | |
215 { | |
216 header *new_hdr = NULL; | |
217 | |
218 if(hdr){ | |
219 if((new_hdr = g_malloc(sizeof(header)))){ | |
220 new_hdr->id = hdr->id; | |
221 new_hdr->header = g_strdup(hdr->header); | |
222 new_hdr->value = new_hdr->header + (hdr->value - hdr->header); | |
223 } | |
224 } | |
225 return new_hdr; | |
226 } | |
227 | |
228 header *get_header(gchar *line) | |
229 { | |
230 gchar *p = line; | |
231 gchar buf[64], *q = buf; | |
232 gint i; | |
233 header *hdr; | |
234 | |
235 while(*p && (*p != ':') && (q < buf+63)) *(q++) = *(p++); | |
236 *q = 0; | |
237 | |
238 if(*p != ':') return NULL; | |
239 | |
240 hdr = g_malloc(sizeof(header)); | |
241 | |
242 hdr->value = NULL; | |
243 p++; | |
244 | |
245 while(*p && (*p == ' ' || *p == '\t')) p++; | |
246 hdr->value = p; | |
247 | |
248 for(i = 0; i < HEAD_NUM_IDS; i++){ | |
249 if(strcasecmp(header_names[i].header, buf) == 0) | |
250 break; | |
251 } | |
252 hdr->id = (header_id)i; | |
253 hdr->header = g_strdup(line); | |
254 hdr->value = hdr->header + (hdr->value - line); | |
255 | |
256 DEBUG(4) debugf("header: %d = %s", hdr->id, hdr->header); | |
257 | |
258 return hdr; | |
259 } |