Cleanup again and all of this done with one hand !!!
We're moving closer to cleaning the repository and using autoconf and all. But my keyboard quota is almost expired.
Showing
10 changed files
with
358 additions
and
227 deletions
... | @@ -23,7 +23,7 @@ | ... | @@ -23,7 +23,7 @@ |
23 | #include <errno.h> | 23 | #include <errno.h> |
24 | 24 | ||
25 | int | 25 | int |
26 | attribute_create (attribute_t *pattr) | 26 | attribute_create (attribute_t *pattr, void *owner) |
27 | { | 27 | { |
28 | attribute_t attr; | 28 | attribute_t attr; |
29 | if (pattr == NULL) | 29 | if (pattr == NULL) |
... | @@ -31,16 +31,19 @@ attribute_create (attribute_t *pattr) | ... | @@ -31,16 +31,19 @@ attribute_create (attribute_t *pattr) |
31 | attr = calloc (1, sizeof(*attr)); | 31 | attr = calloc (1, sizeof(*attr)); |
32 | if (attr == NULL) | 32 | if (attr == NULL) |
33 | return ENOMEM; | 33 | return ENOMEM; |
34 | attr->owner = owner; | ||
34 | *pattr = attr; | 35 | *pattr = attr; |
35 | return 0; | 36 | return 0; |
36 | } | 37 | } |
37 | 38 | ||
38 | void | 39 | void |
39 | attribute_destroy (attribute_t *pattr) | 40 | attribute_destroy (attribute_t *pattr, void *owner) |
40 | { | 41 | { |
41 | if (pattr && *pattr) | 42 | if (pattr && *pattr) |
42 | { | 43 | { |
43 | free (*pattr); | 44 | attribute_t attr = *pattr; |
45 | if (attr->owner != owner) | ||
46 | free (*pattr); | ||
44 | /* loose the link */ | 47 | /* loose the link */ |
45 | *pattr = NULL; | 48 | *pattr = NULL; |
46 | } | 49 | } |
... | @@ -48,68 +51,144 @@ attribute_destroy (attribute_t *pattr) | ... | @@ -48,68 +51,144 @@ attribute_destroy (attribute_t *pattr) |
48 | } | 51 | } |
49 | 52 | ||
50 | int | 53 | int |
54 | attribute_get_flags (attribute_t attr, int *pflags) | ||
55 | { | ||
56 | if (attr->_get_flags) | ||
57 | return attr->_get_flags (attr, pflags); | ||
58 | if (pflags) | ||
59 | *pflags = attr->flags; | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | int | ||
64 | attribute_set_flags (attribute_t attr, int flags) | ||
65 | { | ||
66 | if (attr->_set_flags) | ||
67 | return attr->_set_flags (attr, flags); | ||
68 | attr->flags |= flags; | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | int | ||
73 | attribute_set_get_flags (attribute_t attr, int (*_get_flags) | ||
74 | (attribute_t, int *), void *owner) | ||
75 | { | ||
76 | if (attr == NULL) | ||
77 | return EINVAL; | ||
78 | if (attr->owner != owner) | ||
79 | return EACCES; | ||
80 | attr->_get_flags = _get_flags; | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | int | ||
85 | attribute_set_set_flags (attribute_t attr, int (*_set_flags) | ||
86 | (attribute_t, int), void *owner) | ||
87 | { | ||
88 | if (attr == NULL) | ||
89 | return EINVAL; | ||
90 | if (attr->owner != owner) | ||
91 | return EACCES; | ||
92 | attr->_set_flags = _set_flags; | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | int | ||
97 | attribute_set_unset_flags (attribute_t attr, int (*_unset_flags) | ||
98 | (attribute_t, int), void *owner) | ||
99 | { | ||
100 | if (attr == NULL) | ||
101 | return EINVAL; | ||
102 | if (attr->owner != owner) | ||
103 | return EACCES; | ||
104 | attr->_unset_flags = _unset_flags; | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | int | ||
51 | attribute_set_seen (attribute_t attr) | 109 | attribute_set_seen (attribute_t attr) |
52 | { | 110 | { |
111 | int status = 0; | ||
53 | if (attr == NULL) | 112 | if (attr == NULL) |
54 | return EINVAL; | 113 | return EINVAL; |
55 | attr->flag |= MU_ATTRIBUTE_SEEN; | 114 | if (attr->_get_flags) |
115 | status = attr->_get_flags (attr, &(attr->flags)); | ||
116 | attr->flags |= MU_ATTRIBUTE_SEEN; | ||
56 | return 0; | 117 | return 0; |
57 | } | 118 | } |
58 | 119 | ||
59 | int | 120 | int |
60 | attribute_set_answered (attribute_t attr) | 121 | attribute_set_answered (attribute_t attr) |
61 | { | 122 | { |
123 | int status = 0; | ||
62 | if (attr == NULL) | 124 | if (attr == NULL) |
63 | return EINVAL; | 125 | return EINVAL; |
64 | attr->flag |= MU_ATTRIBUTE_ANSWERED; | 126 | if (attr->_get_flags) |
127 | status = attr->_get_flags (attr, &(attr->flags)); | ||
128 | attr->flags |= MU_ATTRIBUTE_ANSWERED; | ||
65 | return 0; | 129 | return 0; |
66 | } | 130 | } |
67 | 131 | ||
68 | int | 132 | int |
69 | attribute_set_flagged (attribute_t attr) | 133 | attribute_set_flagged (attribute_t attr) |
70 | { | 134 | { |
135 | int status = 0; | ||
71 | if (attr == NULL) | 136 | if (attr == NULL) |
72 | return EINVAL; | 137 | return EINVAL; |
73 | attr->flag |= MU_ATTRIBUTE_FLAGGED; | 138 | if (attr->_get_flags) |
139 | status = attr->_get_flags (attr, &(attr->flags)); | ||
140 | attr->flags |= MU_ATTRIBUTE_FLAGGED; | ||
74 | return 0; | 141 | return 0; |
75 | } | 142 | } |
76 | 143 | ||
77 | int | 144 | int |
78 | attribute_set_read (attribute_t attr) | 145 | attribute_set_read (attribute_t attr) |
79 | { | 146 | { |
147 | int status = 0; | ||
80 | if (attr == NULL) | 148 | if (attr == NULL) |
81 | return EINVAL; | 149 | return EINVAL; |
82 | attr->flag |= MU_ATTRIBUTE_READ; | 150 | if (attr->_get_flags) |
151 | status = attr->_get_flags (attr, &(attr->flags)); | ||
152 | attr->flags |= MU_ATTRIBUTE_READ; | ||
83 | return 0; | 153 | return 0; |
84 | } | 154 | } |
85 | 155 | ||
86 | int | 156 | int |
87 | attribute_set_deleted (attribute_t attr) | 157 | attribute_set_deleted (attribute_t attr) |
88 | { | 158 | { |
159 | int status = 0; | ||
89 | if (attr == NULL) | 160 | if (attr == NULL) |
90 | return EINVAL; | 161 | return EINVAL; |
91 | attr->flag |= MU_ATTRIBUTE_DELETED; | 162 | if (attr->_get_flags) |
163 | status = attr->_get_flags (attr, &(attr->flags)); | ||
164 | attr->flags |= MU_ATTRIBUTE_DELETED; | ||
92 | return 0; | 165 | return 0; |
93 | } | 166 | } |
94 | 167 | ||
95 | int | 168 | int |
96 | attribute_set_draft (attribute_t attr) | 169 | attribute_set_draft (attribute_t attr) |
97 | { | 170 | { |
171 | int status = 0; | ||
98 | if (attr == NULL) | 172 | if (attr == NULL) |
99 | return EINVAL; | 173 | return EINVAL; |
100 | attr->flag |= MU_ATTRIBUTE_DRAFT; | 174 | if (attr->_get_flags) |
175 | status = attr->_get_flags (attr, &(attr->flags)); | ||
176 | attr->flags |= MU_ATTRIBUTE_DRAFT; | ||
101 | return 0; | 177 | return 0; |
102 | } | 178 | } |
103 | 179 | ||
104 | int | 180 | int |
105 | attribute_set_recent (attribute_t attr) | 181 | attribute_set_recent (attribute_t attr) |
106 | { | 182 | { |
183 | int status = 0; | ||
107 | if (attr == NULL) | 184 | if (attr == NULL) |
108 | return EINVAL; | 185 | return EINVAL; |
186 | if (attr->_get_flags) | ||
187 | status = attr->_get_flags (attr, &(attr->flags)); | ||
109 | if (attr == NULL) | 188 | if (attr == NULL) |
110 | { | 189 | { |
111 | attr->flag &= ~MU_ATTRIBUTE_READ; | 190 | attr->flags &= ~MU_ATTRIBUTE_READ; |
112 | attr->flag &= ~MU_ATTRIBUTE_SEEN; | 191 | attr->flags &= ~MU_ATTRIBUTE_SEEN; |
113 | return 0; | 192 | return 0; |
114 | } | 193 | } |
115 | return EACCES; | 194 | return EACCES; |
... | @@ -118,131 +197,176 @@ attribute_set_recent (attribute_t attr) | ... | @@ -118,131 +197,176 @@ attribute_set_recent (attribute_t attr) |
118 | int | 197 | int |
119 | attribute_is_seen (attribute_t attr) | 198 | attribute_is_seen (attribute_t attr) |
120 | { | 199 | { |
200 | int status = 0; | ||
121 | if (attr == NULL) | 201 | if (attr == NULL) |
122 | return 0; | 202 | return 0; |
123 | return attr->flag & MU_ATTRIBUTE_SEEN; | 203 | if (attr->_get_flags) |
204 | status = attr->_get_flags (attr, &(attr->flags)); | ||
205 | return attr->flags & MU_ATTRIBUTE_SEEN; | ||
124 | } | 206 | } |
125 | 207 | ||
126 | int | 208 | int |
127 | attribute_is_answered (attribute_t attr) | 209 | attribute_is_answered (attribute_t attr) |
128 | { | 210 | { |
211 | int status = 0; | ||
129 | if (attr == NULL) | 212 | if (attr == NULL) |
130 | return 0; | 213 | return 0; |
131 | return attr->flag & MU_ATTRIBUTE_ANSWERED; | 214 | if (attr->_get_flags) |
215 | status = attr->_get_flags (attr, &(attr->flags)); | ||
216 | return attr->flags & MU_ATTRIBUTE_ANSWERED; | ||
132 | } | 217 | } |
133 | 218 | ||
134 | int | 219 | int |
135 | attribute_is_flagged (attribute_t attr) | 220 | attribute_is_flagged (attribute_t attr) |
136 | { | 221 | { |
222 | int status = 0; | ||
137 | if (attr == NULL) | 223 | if (attr == NULL) |
138 | return 0; | 224 | return 0; |
139 | return attr->flag & MU_ATTRIBUTE_FLAGGED; | 225 | if (attr->_get_flags) |
226 | status = attr->_get_flags (attr, &(attr->flags)); | ||
227 | return attr->flags & MU_ATTRIBUTE_FLAGGED; | ||
140 | } | 228 | } |
141 | 229 | ||
142 | int | 230 | int |
143 | attribute_is_read (attribute_t attr) | 231 | attribute_is_read (attribute_t attr) |
144 | { | 232 | { |
233 | int status = 0; | ||
145 | if (attr == NULL) | 234 | if (attr == NULL) |
146 | return 0; | 235 | return 0; |
147 | return attr->flag & MU_ATTRIBUTE_READ; | 236 | if (attr->_get_flags) |
237 | status = attr->_get_flags (attr, &(attr->flags)); | ||
238 | return attr->flags & MU_ATTRIBUTE_READ; | ||
148 | } | 239 | } |
149 | 240 | ||
150 | int | 241 | int |
151 | attribute_is_deleted (attribute_t attr) | 242 | attribute_is_deleted (attribute_t attr) |
152 | { | 243 | { |
244 | int status = 0; | ||
153 | if (attr == NULL) | 245 | if (attr == NULL) |
154 | return 0; | 246 | return 0; |
155 | return attr->flag & MU_ATTRIBUTE_DELETED; | 247 | if (attr->_get_flags) |
248 | status = attr->_get_flags (attr, &(attr->flags)); | ||
249 | return attr->flags & MU_ATTRIBUTE_DELETED; | ||
156 | } | 250 | } |
157 | 251 | ||
158 | int | 252 | int |
159 | attribute_is_draft (attribute_t attr) | 253 | attribute_is_draft (attribute_t attr) |
160 | { | 254 | { |
255 | int status = 0; | ||
161 | if (attr == NULL) | 256 | if (attr == NULL) |
162 | return 0; | 257 | return 0; |
163 | return attr->flag & MU_ATTRIBUTE_DRAFT; | 258 | if (attr->_get_flags) |
259 | status = attr->_get_flags (attr, &(attr->flags)); | ||
260 | return attr->flags & MU_ATTRIBUTE_DRAFT; | ||
164 | } | 261 | } |
165 | 262 | ||
166 | int | 263 | int |
167 | attribute_is_recent (attribute_t attr) | 264 | attribute_is_recent (attribute_t attr) |
168 | { | 265 | { |
266 | int status = 0; | ||
169 | if (attr == NULL) | 267 | if (attr == NULL) |
170 | return 0; | 268 | return 0; |
269 | if (attr->_get_flags) | ||
270 | status = attr->_get_flags (attr, &(attr->flags)); | ||
171 | /* something is recent when it is not read and not seen. */ | 271 | /* something is recent when it is not read and not seen. */ |
172 | return (attr->flag == 0 | 272 | return (attr->flags == 0 |
173 | || ! ((attr->flag & MU_ATTRIBUTE_SEEN) | 273 | || ! ((attr->flags & MU_ATTRIBUTE_SEEN) |
174 | && (attr->flag & MU_ATTRIBUTE_READ))); | 274 | && (attr->flags & MU_ATTRIBUTE_READ))); |
175 | } | 275 | } |
176 | 276 | ||
177 | int | 277 | int |
178 | attribute_unset_seen (attribute_t attr) | 278 | attribute_unset_seen (attribute_t attr) |
179 | { | 279 | { |
280 | int status = 0; | ||
180 | if (attr == NULL) | 281 | if (attr == NULL) |
181 | return 0; | 282 | return 0; |
182 | attr->flag &= ~MU_ATTRIBUTE_SEEN; | 283 | if (attr->_unset_flags) |
183 | return 0; | 284 | status = attr->_unset_flags (attr, MU_ATTRIBUTE_SEEN); |
285 | attr->flags &= ~MU_ATTRIBUTE_SEEN; | ||
286 | return status; | ||
184 | } | 287 | } |
185 | 288 | ||
186 | int | 289 | int |
187 | attribute_unset_answered (attribute_t attr) | 290 | attribute_unset_answered (attribute_t attr) |
188 | { | 291 | { |
292 | int status = 0; | ||
189 | if (attr == NULL) | 293 | if (attr == NULL) |
190 | return 0; | 294 | return 0; |
191 | attr->flag &= ~MU_ATTRIBUTE_ANSWERED; | 295 | if (attr->_unset_flags) |
192 | return 0; | 296 | status = attr->_unset_flags (attr, MU_ATTRIBUTE_ANSWERED); |
297 | attr->flags &= ~MU_ATTRIBUTE_ANSWERED; | ||
298 | return status; | ||
193 | } | 299 | } |
194 | 300 | ||
195 | int | 301 | int |
196 | attribute_unset_flagged (attribute_t attr) | 302 | attribute_unset_flagged (attribute_t attr) |
197 | { | 303 | { |
304 | int status = 0; | ||
198 | if (attr == NULL) | 305 | if (attr == NULL) |
199 | return 0; | 306 | return 0; |
200 | attr->flag &= ~MU_ATTRIBUTE_FLAGGED; | 307 | if (attr->_unset_flags) |
201 | return 0; | 308 | status = attr->_unset_flags (attr, MU_ATTRIBUTE_FLAGGED); |
309 | attr->flags &= ~MU_ATTRIBUTE_FLAGGED; | ||
310 | return status; | ||
202 | } | 311 | } |
203 | 312 | ||
204 | int | 313 | int |
205 | attribute_unset_read (attribute_t attr) | 314 | attribute_unset_read (attribute_t attr) |
206 | { | 315 | { |
316 | int status = 0; | ||
207 | if (attr == NULL) | 317 | if (attr == NULL) |
208 | return 0; | 318 | return 0; |
209 | attr->flag &= ~MU_ATTRIBUTE_READ; | 319 | if (attr->_unset_flags) |
210 | return 0; | 320 | status = attr->_unset_flags (attr, MU_ATTRIBUTE_READ); |
321 | attr->flags &= ~MU_ATTRIBUTE_READ; | ||
322 | return status; | ||
211 | } | 323 | } |
212 | 324 | ||
213 | int | 325 | int |
214 | attribute_unset_deleted (attribute_t attr) | 326 | attribute_unset_deleted (attribute_t attr) |
215 | { | 327 | { |
328 | int status = 0; | ||
216 | if (attr == NULL) | 329 | if (attr == NULL) |
217 | return 0; | 330 | return 0; |
218 | attr->flag &= ~MU_ATTRIBUTE_DELETED; | 331 | if (attr->_unset_flags) |
219 | return 0; | 332 | status = attr->_unset_flags (attr, MU_ATTRIBUTE_DELETED); |
333 | attr->flags &= ~MU_ATTRIBUTE_DELETED; | ||
334 | return status; | ||
220 | } | 335 | } |
221 | 336 | ||
222 | int | 337 | int |
223 | attribute_unset_draft (attribute_t attr) | 338 | attribute_unset_draft (attribute_t attr) |
224 | { | 339 | { |
340 | int status = 0; | ||
225 | if (attr == NULL) | 341 | if (attr == NULL) |
226 | return 0; | 342 | return 0; |
227 | attr->flag &= ~MU_ATTRIBUTE_DRAFT; | 343 | if (attr->_unset_flags) |
228 | return 0; | 344 | status = attr->_unset_flags (attr, MU_ATTRIBUTE_DRAFT); |
345 | attr->flags &= ~MU_ATTRIBUTE_DRAFT; | ||
346 | return status; | ||
229 | } | 347 | } |
230 | 348 | ||
231 | int | 349 | int |
232 | attribute_unset_recent (attribute_t attr) | 350 | attribute_unset_recent (attribute_t attr) |
233 | { | 351 | { |
352 | int status = 0; | ||
234 | if (attr == NULL) | 353 | if (attr == NULL) |
235 | return 0; | 354 | return 0; |
236 | attr->flag |= MU_ATTRIBUTE_SEEN; | 355 | if (attr->_unset_flags) |
237 | return 0; | 356 | status = attr->_unset_flags (attr, MU_ATTRIBUTE_SEEN); |
357 | attr->flags |= MU_ATTRIBUTE_SEEN; | ||
358 | return status; | ||
238 | } | 359 | } |
239 | 360 | ||
240 | int | 361 | int |
241 | attribute_is_equal (attribute_t attr, attribute_t attr2) | 362 | attribute_is_equal (attribute_t attr, attribute_t attr2) |
242 | { | 363 | { |
364 | int status = 0; | ||
243 | if (attr == NULL || attr2 == NULL) | 365 | if (attr == NULL || attr2 == NULL) |
244 | return 0; | 366 | return 0; |
245 | return attr->flag == attr2->flag; | 367 | if (attr->_get_flags) |
368 | status = attr->_get_flags (attr, &(attr->flags)); | ||
369 | return attr->flags == attr2->flags; | ||
246 | } | 370 | } |
247 | 371 | ||
248 | int | 372 | int |
... | @@ -255,14 +379,12 @@ attribute_copy (attribute_t dest, attribute_t src) | ... | @@ -255,14 +379,12 @@ attribute_copy (attribute_t dest, attribute_t src) |
255 | } | 379 | } |
256 | 380 | ||
257 | int | 381 | int |
258 | string_to_attribute (const char *buffer, attribute_t *pattr) | 382 | string_to_flags (const char *buffer, int *pflags) |
259 | { | 383 | { |
260 | const char *sep; | 384 | const char *sep; |
261 | int status; | ||
262 | 385 | ||
263 | status = attribute_create (pattr); | 386 | if (pflags == NULL) |
264 | if (status != 0) | 387 | return EINVAL; |
265 | return status; | ||
266 | 388 | ||
267 | /* Set the attribute */ | 389 | /* Set the attribute */ |
268 | if (strncasecmp (buffer, "Status:", 7) == 0) | 390 | if (strncasecmp (buffer, "Status:", 7) == 0) |
... | @@ -271,22 +393,22 @@ string_to_attribute (const char *buffer, attribute_t *pattr) | ... | @@ -271,22 +393,22 @@ string_to_attribute (const char *buffer, attribute_t *pattr) |
271 | sep++; | 393 | sep++; |
272 | } | 394 | } |
273 | else | 395 | else |
274 | sep = buffer; | 396 | return EINVAL; |
275 | 397 | ||
276 | while (*sep == ' ') sep++; /* glob spaces */ | 398 | while (*sep == ' ') sep++; /* glob spaces */ |
277 | if (strchr (sep, 'R') != NULL || strchr (sep, 'r') != NULL) | 399 | if (strchr (sep, 'R') != NULL || strchr (sep, 'r') != NULL) |
278 | attribute_set_read (*pattr); | 400 | *pflags |= MU_ATTRIBUTE_READ; |
279 | if (strchr (sep, 'O') != NULL || strchr (sep, 'o') != NULL) | 401 | if (strchr (sep, 'O') != NULL || strchr (sep, 'o') != NULL) |
280 | attribute_set_seen (*pattr); | 402 | *pflags |= MU_ATTRIBUTE_SEEN; |
281 | if (strchr (sep, 'A') != NULL || strchr (sep, 'a') != NULL) | 403 | if (strchr (sep, 'A') != NULL || strchr (sep, 'a') != NULL) |
282 | attribute_set_answered (*pattr); | 404 | *pflags |= MU_ATTRIBUTE_ANSWERED; |
283 | if (strchr (sep, 'F') != NULL || strchr (sep, 'f') != NULL) | 405 | if (strchr (sep, 'F') != NULL || strchr (sep, 'f') != NULL) |
284 | attribute_set_flagged (*pattr); | 406 | *pflags |= MU_ATTRIBUTE_FLAGGED; |
285 | return 0; | 407 | return 0; |
286 | } | 408 | } |
287 | 409 | ||
288 | int | 410 | int |
289 | attribute_to_string (attribute_t attr, char *buffer, size_t len, size_t *pn) | 411 | flags_to_string (int flags, char *buffer, size_t len, size_t *pn) |
290 | { | 412 | { |
291 | char status[32]; | 413 | char status[32]; |
292 | char a[8]; | 414 | char a[8]; |
... | @@ -294,14 +416,16 @@ attribute_to_string (attribute_t attr, char *buffer, size_t len, size_t *pn) | ... | @@ -294,14 +416,16 @@ attribute_to_string (attribute_t attr, char *buffer, size_t len, size_t *pn) |
294 | 416 | ||
295 | *status = *a = '\0'; | 417 | *status = *a = '\0'; |
296 | 418 | ||
297 | if (attribute_is_seen (attr)) | 419 | if (flags & MU_ATTRIBUTE_SEEN) |
298 | strcat (a, "R"); | 420 | strcat (a, "R"); |
299 | if (attribute_is_answered (attr)) | 421 | if (flags & MU_ATTRIBUTE_ANSWERED) |
300 | strcat (a, "A"); | 422 | strcat (a, "A"); |
301 | if (attribute_is_flagged (attr)) | 423 | if (flags & MU_ATTRIBUTE_FLAGGED) |
302 | strcat (a, "F"); | 424 | strcat (a, "F"); |
303 | if (attribute_is_read (attr)) | 425 | if (flags & MU_ATTRIBUTE_READ) |
304 | strcat (a, "O"); | 426 | strcat (a, "O"); |
427 | if (flags & MU_ATTRIBUTE_DELETED) | ||
428 | strcat (a, "d"); | ||
305 | 429 | ||
306 | if (*a != '\0') | 430 | if (*a != '\0') |
307 | { | 431 | { | ... | ... |
... | @@ -20,7 +20,7 @@ | ... | @@ -20,7 +20,7 @@ |
20 | # include "config.h" | 20 | # include "config.h" |
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | #include <header.h> | 23 | #include <header0.h> |
24 | #include <io0.h> | 24 | #include <io0.h> |
25 | #include <string.h> | 25 | #include <string.h> |
26 | #include <stdlib.h> | 26 | #include <stdlib.h> |
... | @@ -33,30 +33,6 @@ static int header_read (stream_t is, char *buf, size_t buflen, | ... | @@ -33,30 +33,6 @@ static int header_read (stream_t is, char *buf, size_t buflen, |
33 | static int header_write (stream_t os, const char *buf, size_t buflen, | 33 | static int header_write (stream_t os, const char *buf, size_t buflen, |
34 | off_t off, size_t *pnwrite); | 34 | off_t off, size_t *pnwrite); |
35 | 35 | ||
36 | struct _hdr | ||
37 | { | ||
38 | char *fn; | ||
39 | char *fn_end; | ||
40 | char *fv; | ||
41 | char *fv_end; | ||
42 | }; | ||
43 | |||
44 | struct _header | ||
45 | { | ||
46 | /* Owner. */ | ||
47 | void *owner; | ||
48 | /* Data. */ | ||
49 | char *blurb; | ||
50 | size_t blurb_len; | ||
51 | size_t hdr_count; | ||
52 | struct _hdr *hdr; | ||
53 | |||
54 | /* Streams. */ | ||
55 | stream_t stream; | ||
56 | int (*_get_value) __P ((header_t, const char *, char *, size_t , size_t *)); | ||
57 | |||
58 | }; | ||
59 | |||
60 | int | 36 | int |
61 | header_create (header_t *ph, const char *blurb, size_t len, void *owner) | 37 | header_create (header_t *ph, const char *blurb, size_t len, void *owner) |
62 | { | 38 | { |
... | @@ -66,6 +42,7 @@ header_create (header_t *ph, const char *blurb, size_t len, void *owner) | ... | @@ -66,6 +42,7 @@ header_create (header_t *ph, const char *blurb, size_t len, void *owner) |
66 | return ENOMEM; | 42 | return ENOMEM; |
67 | h->owner = owner; | 43 | h->owner = owner; |
68 | 44 | ||
45 | /* Ignore the return value. */ | ||
69 | header_parse (h, blurb, len); | 46 | header_parse (h, blurb, len); |
70 | 47 | ||
71 | *ph = h; | 48 | *ph = h; |
... | @@ -83,8 +60,10 @@ header_destroy (header_t *ph, void *owner) | ... | @@ -83,8 +60,10 @@ header_destroy (header_t *ph, void *owner) |
83 | if (h->owner == owner) | 60 | if (h->owner == owner) |
84 | { | 61 | { |
85 | stream_destroy (&(h->stream), h); | 62 | stream_destroy (&(h->stream), h); |
86 | free (h->hdr); | 63 | if (h->hdr) |
87 | free (h->blurb); | 64 | free (h->hdr); |
65 | if (h->blurb) | ||
66 | free (h->blurb); | ||
88 | free (h); | 67 | free (h); |
89 | } | 68 | } |
90 | *ph = NULL; | 69 | *ph = NULL; |
... | @@ -207,8 +186,7 @@ header_parse (header_t header, const char *blurb, int len) | ... | @@ -207,8 +186,7 @@ header_parse (header_t header, const char *blurb, int len) |
207 | } | 186 | } |
208 | 187 | ||
209 | /* FIXME: grossly inneficient, to many copies and reallocating. | 188 | /* FIXME: grossly inneficient, to many copies and reallocating. |
210 | * This all header business need a good rewrite. | 189 | This all header business need a good rewrite. */ |
211 | */ | ||
212 | int | 190 | int |
213 | header_set_value (header_t header, const char *fn, const char *fv, int replace) | 191 | header_set_value (header_t header, const char *fn, const char *fv, int replace) |
214 | { | 192 | { |
... | @@ -218,11 +196,14 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) | ... | @@ -218,11 +196,14 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) |
218 | if (header == NULL || fn == NULL || fv == NULL) | 196 | if (header == NULL || fn == NULL || fv == NULL) |
219 | return EINVAL; | 197 | return EINVAL; |
220 | 198 | ||
221 | /* Easy approach: if replace, overwrite the field-{namve,value} | 199 | /* Try to fill out the buffer, if we know how. */ |
222 | and readjust the pointers by calling header_parse () | 200 | if (header->_set_value != NULL) |
223 | this is wastefull, we're just fragmenting the memory | 201 | return header->_set_value (header, fn, fv, replace); |
224 | it can be done better. But that may imply a rewite of the headers | 202 | |
225 | So for another day. */ | 203 | /* Easy approach: if replace, overwrite the field-{name,value} and readjust |
204 | the pointers by calling header_parse () this is wastefull, we're just | ||
205 | fragmenting the memory it can be done better. But that may imply a | ||
206 | rewite of the headers So for another day. */ | ||
226 | if (replace) | 207 | if (replace) |
227 | { | 208 | { |
228 | size_t name_len; | 209 | size_t name_len; |
... | @@ -251,8 +232,8 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) | ... | @@ -251,8 +232,8 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) |
251 | } | 232 | } |
252 | } | 233 | } |
253 | 234 | ||
254 | /* Replacing was taking care of above now just add to | 235 | /* Replacing was taking care of above now just add to the end the new |
255 | the end the new header. Really not cute. */ | 236 | header. Really not cute. */ |
256 | len = strlen (fn) + strlen (fv) + 1 + 1 + 1 + 1; | 237 | len = strlen (fn) + strlen (fv) + 1 + 1 + 1 + 1; |
257 | blurb = calloc (header->blurb_len + len, 1); | 238 | blurb = calloc (header->blurb_len + len, 1); |
258 | if (blurb == NULL) | 239 | if (blurb == NULL) |
... | @@ -266,20 +247,6 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) | ... | @@ -266,20 +247,6 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) |
266 | } | 247 | } |
267 | 248 | ||
268 | int | 249 | int |
269 | header_set_get_value (header_t header, int (*_get_value) | ||
270 | (header_t, const char *, char *, size_t, size_t *), | ||
271 | void *owner) | ||
272 | { | ||
273 | if (header == NULL) | ||
274 | return EINVAL; | ||
275 | if (header->owner != owner) | ||
276 | return EACCES; | ||
277 | |||
278 | header->_get_value = _get_value; | ||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | int | ||
283 | header_get_value (header_t header, const char *name, char *buffer, | 250 | header_get_value (header_t header, const char *name, char *buffer, |
284 | size_t buflen, size_t *pn) | 251 | size_t buflen, size_t *pn) |
285 | { | 252 | { |
... | @@ -287,20 +254,61 @@ header_get_value (header_t header, const char *name, char *buffer, | ... | @@ -287,20 +254,61 @@ header_get_value (header_t header, const char *name, char *buffer, |
287 | size_t name_len; | 254 | size_t name_len; |
288 | size_t total = 0, fn_len = 0, fv_len = 0; | 255 | size_t total = 0, fn_len = 0, fv_len = 0; |
289 | int threshold; | 256 | int threshold; |
257 | int err = 0; | ||
290 | 258 | ||
291 | if (header == NULL || name == NULL) | 259 | if (header == NULL || name == NULL) |
292 | return EINVAL; | 260 | return EINVAL; |
293 | 261 | ||
262 | if (header->_get_value != NULL) | ||
263 | return header->_get_value (header, name, buffer, buflen, pn); | ||
264 | |||
265 | /* Try to fill out the buffer, if we know how. */ | ||
266 | if (header->blurb == NULL) | ||
267 | { | ||
268 | stream_t is; | ||
269 | err = header_get_stream (header, &is); | ||
270 | if (err != 0) | ||
271 | return err; | ||
272 | else | ||
273 | { | ||
274 | char buf[1024]; | ||
275 | char *tbuf; | ||
276 | size_t nread = 0; | ||
277 | do | ||
278 | { | ||
279 | err = stream_read (is, buf, sizeof (buf), header->temp_blurb_len, | ||
280 | &nread); | ||
281 | if (err != 0 | ||
282 | || (tbuf = realloc (header->temp_blurb, | ||
283 | header->temp_blurb_len + nread)) == NULL) | ||
284 | { | ||
285 | free (header->temp_blurb); | ||
286 | header->temp_blurb = NULL; | ||
287 | header->temp_blurb_len = 0; | ||
288 | return err; | ||
289 | } | ||
290 | else | ||
291 | header->temp_blurb = tbuf; | ||
292 | memcpy (header->temp_blurb + header->temp_blurb_len, buf, nread); | ||
293 | header->temp_blurb_len += nread; | ||
294 | } while (nread != 0); | ||
295 | /* parse it. */ | ||
296 | header_parse (header, header->temp_blurb, header->temp_blurb_len); | ||
297 | free (header->temp_blurb); | ||
298 | header->temp_blurb = NULL; | ||
299 | header->temp_blurb_len = 0; | ||
300 | } | ||
301 | } | ||
302 | |||
294 | /* We set the threshold to be 1 less for the null. */ | 303 | /* We set the threshold to be 1 less for the null. */ |
295 | threshold = --buflen; | 304 | threshold = --buflen; |
296 | 305 | ||
297 | /* Caution: We may have more then one value for a field | 306 | /* Caution: We may have more then one value for a field name, for example |
298 | name, for example a "Received" field-name is added by | 307 | a "Received" field-name is added by each passing MTA. The way that the |
299 | each passing MTA. The way that the parsing (_parse()) | 308 | parsing (_parse()) is done it's not take to account. So we just stuff |
300 | is done it's not take to account. So we just stuff in | 309 | in the buffer all the field-values to a corresponding field-name. |
301 | the buffer all the field-values to a corresponding field-name. | 310 | FIXME: Should we kosher the output ? meaning replace occurences of |
302 | FIXME: Should we kosher the output ? meaning replace | 311 | " \t\r\n" for spaces ? for now we don't. */ |
303 | occurences of " \t\r\n" for spaces ? for now we don't. */ | ||
304 | for (name_len = strlen (name), i = 0; i < header->hdr_count; i++) | 312 | for (name_len = strlen (name), i = 0; i < header->hdr_count; i++) |
305 | { | 313 | { |
306 | fn_len = header->hdr[i].fn_end - header->hdr[i].fn; | 314 | fn_len = header->hdr[i].fn_end - header->hdr[i].fn; |
... | @@ -332,48 +340,35 @@ header_get_value (header_t header, const char *name, char *buffer, | ... | @@ -332,48 +340,35 @@ header_get_value (header_t header, const char *name, char *buffer, |
332 | *buffer = '\0'; /* Null terminated. */ | 340 | *buffer = '\0'; /* Null terminated. */ |
333 | if (pn) | 341 | if (pn) |
334 | *pn = total; | 342 | *pn = total; |
343 | |||
344 | /* Check if they provided a hook. */ | ||
335 | if (total == 0) | 345 | if (total == 0) |
336 | { | 346 | { |
337 | int err = ENOENT; | 347 | err = ENOENT; |
338 | /* Check if they provided a hook. */ | ||
339 | if (header->_get_value != NULL) | 348 | if (header->_get_value != NULL) |
340 | err = header->_get_value (header, name, buffer, buflen, pn); | 349 | err = header->_get_value (header, name, buffer, buflen, pn); |
341 | /* Cache it locally. */ | 350 | /* Success. Cache it locally. */ |
342 | if (err == 0) | 351 | if (err == 0) |
343 | header_set_value (header, name, buffer, 0); | 352 | header_set_value (header, name, buffer, 0); |
344 | return err; | ||
345 | } | 353 | } |
346 | return 0; | 354 | return err; |
347 | } | ||
348 | |||
349 | int | ||
350 | header_entry_count (header_t header, size_t *pnum) | ||
351 | { | ||
352 | if (header == NULL) | ||
353 | { | ||
354 | if (pnum) | ||
355 | *pnum = 0; | ||
356 | return EINVAL; | ||
357 | } | ||
358 | if (pnum) | ||
359 | *pnum = header->hdr_count; | ||
360 | return 0; | ||
361 | } | 355 | } |
362 | 356 | ||
363 | int | 357 | int |
364 | header_lines (header_t header, size_t *plines) | 358 | header_lines (header_t header, size_t *plines) |
365 | { | 359 | { |
366 | int n; | 360 | int n; |
367 | size_t t = 0; | 361 | size_t lines = 0; |
368 | if (header == NULL) | 362 | if (header == NULL) |
369 | return EINVAL; | 363 | return EINVAL; |
364 | |||
370 | for (n = header->blurb_len - 1; n >= 0; n--) | 365 | for (n = header->blurb_len - 1; n >= 0; n--) |
371 | { | 366 | { |
372 | if (header->blurb[n] == '\n') | 367 | if (header->blurb[n] == '\n') |
373 | t++; | 368 | lines++; |
374 | } | 369 | } |
375 | if (plines) | 370 | if (plines) |
376 | *plines = t; | 371 | *plines = lines; |
377 | return 0; | 372 | return 0; |
378 | } | 373 | } |
379 | 374 | ||
... | @@ -382,57 +377,50 @@ header_size (header_t header, size_t *pnum) | ... | @@ -382,57 +377,50 @@ header_size (header_t header, size_t *pnum) |
382 | { | 377 | { |
383 | if (header == NULL) | 378 | if (header == NULL) |
384 | return EINVAL; | 379 | return EINVAL; |
380 | |||
385 | if (pnum) | 381 | if (pnum) |
386 | *pnum = header->blurb_len; | 382 | *pnum = header->blurb_len; |
387 | return 0; | 383 | return 0; |
388 | } | 384 | } |
389 | 385 | ||
390 | int | 386 | int |
391 | header_entry_name (header_t header, size_t num, char *buf, | 387 | header_set_get_value (header_t header, int (*_get_value) |
392 | size_t buflen, size_t *nwritten) | 388 | (header_t, const char *, char *, size_t, size_t *), |
389 | void *owner) | ||
393 | { | 390 | { |
394 | size_t len; | ||
395 | if (header == NULL) | 391 | if (header == NULL) |
396 | return EINVAL; | 392 | return EINVAL; |
397 | if (header->hdr_count == 0 || num > header->hdr_count) | 393 | if (header->owner != owner) |
398 | return ENOENT; | 394 | return EACCES; |
399 | len = header->hdr[num].fn_end - header->hdr[num].fn; | 395 | header->_get_value = _get_value; |
400 | /* save one for the null */ | ||
401 | --buflen; | ||
402 | if (buf && buflen > 0) | ||
403 | { | ||
404 | buflen = (len > buflen) ? buflen : len; | ||
405 | memcpy (buf, header->hdr[num].fn, buflen); | ||
406 | buf[buflen] = '\0'; | ||
407 | } | ||
408 | if (nwritten) | ||
409 | *nwritten = len; | ||
410 | return 0; | 396 | return 0; |
411 | } | 397 | } |
412 | 398 | ||
413 | int | 399 | int |
414 | header_entry_value (header_t header, size_t num, char *buf, | 400 | header_set_set_value (header_t header, int (*_set_value) |
415 | size_t buflen, size_t *nwritten) | 401 | (header_t , const char *, const char *, int), |
402 | void *owner) | ||
416 | { | 403 | { |
417 | size_t len; | ||
418 | if (header == NULL) | 404 | if (header == NULL) |
419 | return EINVAL; | 405 | return EINVAL; |
420 | if (header->hdr_count == 0 || num > header->hdr_count) | 406 | if (header->owner != owner) |
421 | return ENOENT; | 407 | return EACCES; |
422 | len = header->hdr[num].fv_end - header->hdr[num].fv; | 408 | header->_set_value = _set_value; |
423 | /* Save one for the null. */ | ||
424 | --buflen; | ||
425 | if (buf && buflen > 0) | ||
426 | { | ||
427 | buflen = (len > buflen) ? buflen : len; | ||
428 | memcpy (buf, header->hdr[num].fv, buflen); | ||
429 | buf[buflen] = '\0'; | ||
430 | } | ||
431 | if (nwritten) | ||
432 | *nwritten = len; | ||
433 | return 0; | 409 | return 0; |
434 | } | 410 | } |
435 | 411 | ||
412 | int | ||
413 | header_set_stream (header_t header, stream_t stream, void *owner) | ||
414 | { | ||
415 | if (header == NULL) | ||
416 | return EINVAL; | ||
417 | if (header->owner != owner) | ||
418 | return EACCES; | ||
419 | header->stream = stream; | ||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | |||
436 | static int | 424 | static int |
437 | header_write (stream_t os, const char *buf, size_t buflen, | 425 | header_write (stream_t os, const char *buf, size_t buflen, |
438 | off_t off, size_t *pnwrite) | 426 | off_t off, size_t *pnwrite) | ... | ... |
... | @@ -34,17 +34,13 @@ extern "C" { | ... | @@ -34,17 +34,13 @@ extern "C" { |
34 | 34 | ||
35 | struct _attribute | 35 | struct _attribute |
36 | { | 36 | { |
37 | size_t flag; | 37 | void *owner; |
38 | size_t flags; | ||
39 | int (*_get_flags) __P ((attribute_t, int *)); | ||
40 | int (*_set_flags) __P ((attribute_t, int)); | ||
41 | int (*_unset_flags) __P ((attribute_t, int)); | ||
38 | }; | 42 | }; |
39 | 43 | ||
40 | #define MU_ATTRIBUTE_ANSWERED 0x01 | ||
41 | #define MU_ATTRIBUTE_FLAGGED 0x02 | ||
42 | #define MU_ATTRIBUTE_DELETED 0x04 | ||
43 | #define MU_ATTRIBUTE_DRAFT 0x08 | ||
44 | #define MU_ATTRIBUTE_SEEN 0x10 | ||
45 | #define MU_ATTRIBUTE_READ 0x20 | ||
46 | #define MU_ATTRIBUTE_RECENT 0x00 | ||
47 | |||
48 | #ifdef __cplusplus | 44 | #ifdef __cplusplus |
49 | } | 45 | } |
50 | #endif | 46 | #endif | ... | ... |
... | @@ -35,8 +35,16 @@ extern "C" { | ... | @@ -35,8 +35,16 @@ extern "C" { |
35 | struct _attribute; | 35 | struct _attribute; |
36 | typedef struct _attribute * attribute_t; | 36 | typedef struct _attribute * attribute_t; |
37 | 37 | ||
38 | extern int attribute_create __P ((attribute_t *)); | 38 | #define MU_ATTRIBUTE_ANSWERED 0x01 |
39 | extern void attribute_destroy __P ((attribute_t *)); | 39 | #define MU_ATTRIBUTE_FLAGGED 0x02 |
40 | #define MU_ATTRIBUTE_DELETED 0x04 | ||
41 | #define MU_ATTRIBUTE_DRAFT 0x08 | ||
42 | #define MU_ATTRIBUTE_SEEN 0x10 | ||
43 | #define MU_ATTRIBUTE_READ 0x20 | ||
44 | #define MU_ATTRIBUTE_RECENT 0x00 | ||
45 | |||
46 | extern int attribute_create __P ((attribute_t *, void *)); | ||
47 | extern void attribute_destroy __P ((attribute_t *, void *)); | ||
40 | 48 | ||
41 | extern int attribute_is_seen __P ((attribute_t)); | 49 | extern int attribute_is_seen __P ((attribute_t)); |
42 | extern int attribute_is_answered __P ((attribute_t)); | 50 | extern int attribute_is_answered __P ((attribute_t)); |
... | @@ -62,14 +70,22 @@ extern int attribute_unset_draft __P ((attribute_t)); | ... | @@ -62,14 +70,22 @@ extern int attribute_unset_draft __P ((attribute_t)); |
62 | extern int attribute_unset_recent __P ((attribute_t)); | 70 | extern int attribute_unset_recent __P ((attribute_t)); |
63 | extern int attribute_unset_read __P ((attribute_t)); | 71 | extern int attribute_unset_read __P ((attribute_t)); |
64 | 72 | ||
73 | extern int attribute_get_flags __P ((attribute_t, int *)); | ||
74 | extern int attribute_set_flags __P ((attribute_t, int)); | ||
75 | |||
76 | extern int attribute_set_set_flags __P ((attribute_t, int (*_set_flags) | ||
77 | __P ((attribute_t, int)), void *)); | ||
78 | extern int attribute_set_unset_flags __P ((attribute_t, int (*_unset_flags) | ||
79 | __P ((attribute_t, int)), void *)); | ||
80 | extern int attribute_set_get_flags __P ((attribute_t, int (*_get_flags) | ||
81 | __P ((attribute_t, int *)), void *)); | ||
65 | extern int attribute_is_equal __P ((attribute_t att1, attribute_t att2)); | 82 | extern int attribute_is_equal __P ((attribute_t att1, attribute_t att2)); |
66 | 83 | ||
67 | extern int attribute_copy __P ((attribute_t dst, | 84 | extern int attribute_copy __P ((attribute_t dst, |
68 | attribute_t src)); | 85 | attribute_t src)); |
69 | 86 | ||
70 | extern int string_to_attribute __P ((const char *buf, | 87 | extern int string_to_flags __P ((const char *buf, int *pattr)); |
71 | attribute_t *pattr)); | 88 | extern int flags_to_string __P ((int flags, char *buf, |
72 | extern int attribute_to_string __P ((attribute_t attr, char *buf, | ||
73 | size_t len, size_t *)); | 89 | size_t len, size_t *)); |
74 | 90 | ||
75 | #ifdef __cplusplus | 91 | #ifdef __cplusplus | ... | ... |
... | @@ -67,27 +67,27 @@ extern "C" { | ... | @@ -67,27 +67,27 @@ extern "C" { |
67 | struct _header; | 67 | struct _header; |
68 | typedef struct _header * header_t; | 68 | typedef struct _header * header_t; |
69 | 69 | ||
70 | extern int header_create __P ((header_t *, const char *blurb, | 70 | extern int header_create __P ((header_t *, const char *, |
71 | size_t ln, void *owner)); | 71 | size_t, void *)); |
72 | extern void header_destroy __P ((header_t *, void *owner)); | 72 | extern void header_destroy __P ((header_t *, void *)); |
73 | extern int header_set_value __P ((header_t, const char *, | ||
74 | const char *, int)); | ||
75 | extern int header_get_value __P ((header_t, const char *, char *, | ||
76 | size_t, size_t *)); | ||
77 | extern int header_get_stream __P ((header_t, stream_t *)); | ||
78 | extern int header_size __P ((header_t, size_t *)); | ||
79 | extern int header_lines __P ((header_t, size_t *)); | ||
73 | 80 | ||
74 | extern int header_set_value __P ((header_t, const char *fn, | 81 | extern int header_set_stream __P ((header_t, stream_t, void *)); |
75 | const char *fv, int replace)); | ||
76 | 82 | ||
83 | extern int header_set_set_value __P ((header_t, int (*_set_value) | ||
84 | __P ((header_t, const char *, | ||
85 | const char *, int)), | ||
86 | void *)); | ||
77 | extern int header_set_get_value __P ((header_t, int (*_get_value) | 87 | extern int header_set_get_value __P ((header_t, int (*_get_value) |
78 | __P ((header_t, const char *fn, char *buf, | 88 | __P ((header_t, const char *, |
79 | size_t buflen, size_t *nwritten)), | 89 | char *, size_t, size_t *)), |
80 | void *owner)); | 90 | void *)); |
81 | extern int header_get_value __P ((header_t, const char *fn, char *buf, | ||
82 | size_t buflen, size_t *nwritten)); | ||
83 | extern int header_entry_count __P ((header_t, size_t *num)); | ||
84 | extern int header_entry_name __P ((header_t, size_t num, char *buf, | ||
85 | size_t buflen, size_t *total)); | ||
86 | extern int header_entry_value __P ((header_t, size_t num, char *buf, | ||
87 | size_t buflen, size_t *total)); | ||
88 | extern int header_get_stream __P ((header_t, stream_t *stream)); | ||
89 | extern int header_size __P ((header_t, size_t *size)); | ||
90 | extern int header_lines __P ((header_t, size_t *lines)); | ||
91 | 91 | ||
92 | #ifdef _cplusplus | 92 | #ifdef _cplusplus |
93 | } | 93 | } | ... | ... |
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
... | @@ -173,7 +173,7 @@ do \ | ... | @@ -173,7 +173,7 @@ do \ |
173 | { \ | 173 | { \ |
174 | if (*s == c0 || *s == c1) \ | 174 | if (*s == c0 || *s == c1) \ |
175 | { \ | 175 | { \ |
176 | (mum)->old_attr->flag |= (type); \ | 176 | (mum)->old_flags |= (type); \ |
177 | break; \ | 177 | break; \ |
178 | } \ | 178 | } \ |
179 | } \ | 179 | } \ |
... | @@ -206,16 +206,16 @@ do \ | ... | @@ -206,16 +206,16 @@ do \ |
206 | do \ | 206 | do \ |
207 | { \ | 207 | { \ |
208 | int bailing = 0; \ | 208 | int bailing = 0; \ |
209 | mailbox_unix_iunlock (mbox); \ | 209 | unix_iunlock (mbox); \ |
210 | MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_MSG_ADD, bailing); \ | 210 | MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_MSG_ADD, bailing); \ |
211 | if (bailing != 0) \ | 211 | if (bailing != 0) \ |
212 | { \ | 212 | { \ |
213 | if (pcount) \ | 213 | if (pcount) \ |
214 | *pcount = (mud)->messages_count; \ | 214 | *pcount = (mud)->messages_count; \ |
215 | mailbox_unix_unlock (mbox); \ | 215 | unix_unlock (mbox); \ |
216 | return EINTR; \ | 216 | return EINTR; \ |
217 | } \ | 217 | } \ |
218 | mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); \ | 218 | unix_ilock (mbox, MU_LOCKER_WRLOCK); \ |
219 | } while (0); | 219 | } while (0); |
220 | 220 | ||
221 | /* notification MBX_PROGRESS | 221 | /* notification MBX_PROGRESS |
... | @@ -234,33 +234,38 @@ do \ | ... | @@ -234,33 +234,38 @@ do \ |
234 | { \ | 234 | { \ |
235 | { \ | 235 | { \ |
236 | int bailing = 0; \ | 236 | int bailing = 0; \ |
237 | mailbox_unix_iunlock (mbox); \ | 237 | unix_iunlock (mbox); \ |
238 | mud->messages_count--; \ | 238 | mud->messages_count--; \ |
239 | MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_PROGRESS,bailing); \ | 239 | MAILBOX_NOTIFICATION (mbox, MU_EVT_MBX_PROGRESS,bailing); \ |
240 | if (bailing != 0) \ | 240 | if (bailing != 0) \ |
241 | { \ | 241 | { \ |
242 | if (pcount) \ | 242 | if (pcount) \ |
243 | *pcount = (mud)->messages_count; \ | 243 | *pcount = (mud)->messages_count; \ |
244 | mailbox_unix_unlock (mbox); \ | 244 | unix_unlock (mbox); \ |
245 | return EINTR; \ | 245 | return EINTR; \ |
246 | } \ | 246 | } \ |
247 | mud->messages_count++; \ | 247 | mud->messages_count++; \ |
248 | mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); \ | 248 | unix_ilock (mbox, MU_LOCKER_WRLOCK); \ |
249 | } \ | 249 | } \ |
250 | } while (0) | 250 | } while (0) |
251 | 251 | ||
252 | #if 0 | ||
252 | /* skip a function call, ?? do we gain that much */ | 253 | /* skip a function call, ?? do we gain that much */ |
253 | #define ATTRIBUTE_CREATE(attr,mbox) \ | 254 | #define ATTRIBUTE_CREATE(attr, m, mbox) \ |
254 | do \ | 255 | do \ |
255 | { \ | 256 | { \ |
256 | attr = calloc (1, sizeof(*(attr))); \ | 257 | attr = calloc (1, sizeof(*(attr))); \ |
258 | attr->owner = m; \ | ||
257 | if ((attr) == NULL) \ | 259 | if ((attr) == NULL) \ |
258 | { \ | 260 | { \ |
259 | mailbox_unix_iunlock (mbox); \ | 261 | unix_iunlock (mbox); \ |
260 | mailbox_unix_unlock (mbox); \ | 262 | unix_unlock (mbox); \ |
261 | return ENOMEM; \ | 263 | return ENOMEM; \ |
262 | } \ | 264 | } \ |
263 | } while (0) | 265 | } while (0) |
266 | #else | ||
267 | # define ATTRIBUTE_CREATE | ||
268 | #endif | ||
264 | 269 | ||
265 | /* allocate slots for the new messages */ | 270 | /* allocate slots for the new messages */ |
266 | /* size_t num = 2 * ((mud)->messages_count) + 10; */ | 271 | /* size_t num = 2 * ((mud)->messages_count) + 10; */ |
... | @@ -269,38 +274,37 @@ do \ | ... | @@ -269,38 +274,37 @@ do \ |
269 | { \ | 274 | { \ |
270 | if ((mud)->messages_count >= (mud)->umessages_count) \ | 275 | if ((mud)->messages_count >= (mud)->umessages_count) \ |
271 | { \ | 276 | { \ |
272 | mailbox_unix_message_t *m; \ | 277 | unix_message_t *m; \ |
273 | size_t num = ((mud)->umessages_count) + 1; \ | 278 | size_t num = ((mud)->umessages_count) + 1; \ |
274 | m = realloc ((mud)->umessages, num * sizeof (*m)); \ | 279 | m = realloc ((mud)->umessages, num * sizeof (*m)); \ |
275 | if (m == NULL) \ | 280 | if (m == NULL) \ |
276 | { \ | 281 | { \ |
277 | mailbox_unix_iunlock (mbox); \ | 282 | unix_iunlock (mbox); \ |
278 | mailbox_unix_unlock (mbox); \ | 283 | unix_unlock (mbox); \ |
279 | return ENOMEM; \ | 284 | return ENOMEM; \ |
280 | } \ | 285 | } \ |
281 | (mud)->umessages = m; \ | 286 | (mud)->umessages = m; \ |
282 | (mud)->umessages[num - 1] = calloc (1, sizeof (*(mum))); \ | 287 | (mud)->umessages[num - 1] = calloc (1, sizeof (*(mum))); \ |
283 | if ((mud)->umessages[num - 1] == NULL) \ | 288 | if ((mud)->umessages[num - 1] == NULL) \ |
284 | { \ | 289 | { \ |
285 | mailbox_unix_iunlock (mbox); \ | 290 | unix_iunlock (mbox); \ |
286 | mailbox_unix_unlock (mbox); \ | 291 | unix_unlock (mbox); \ |
287 | return ENOMEM; \ | 292 | return ENOMEM; \ |
288 | } \ | 293 | } \ |
289 | ATTRIBUTE_CREATE (((mud)->umessages[num - 1])->old_attr, mbox); \ | ||
290 | (mud)->umessages_count = num; \ | 294 | (mud)->umessages_count = num; \ |
291 | } \ | 295 | } \ |
292 | } while (0) | 296 | } while (0) |
293 | 297 | ||
294 | static int | 298 | static int |
295 | mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) | 299 | unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) |
296 | { | 300 | { |
297 | #define MSGLINELEN 1024 | 301 | #define MSGLINELEN 1024 |
298 | char buf[MSGLINELEN]; | 302 | char buf[MSGLINELEN]; |
299 | int inheader; | 303 | int inheader; |
300 | int inbody; | 304 | int inbody; |
301 | off_t total = 0; | 305 | off_t total = 0; |
302 | mailbox_unix_data_t mud; | 306 | unix_data_t mud; |
303 | mailbox_unix_message_t mum = NULL; | 307 | unix_message_t mum = NULL; |
304 | int status = 0; | 308 | int status = 0; |
305 | size_t lines; | 309 | size_t lines; |
306 | int newline; | 310 | int newline; |
... | @@ -311,7 +315,7 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -311,7 +315,7 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) |
311 | 315 | ||
312 | /* sanity */ | 316 | /* sanity */ |
313 | if (mbox == NULL || | 317 | if (mbox == NULL || |
314 | (mud = (mailbox_unix_data_t)mbox->data) == NULL) | 318 | (mud = (unix_data_t)mbox->data) == NULL) |
315 | return EINVAL; | 319 | return EINVAL; |
316 | 320 | ||
317 | /* save the timestamp and size */ | 321 | /* save the timestamp and size */ |
... | @@ -320,8 +324,8 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -320,8 +324,8 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) |
320 | return status; | 324 | return status; |
321 | 325 | ||
322 | /* grab the locks */ | 326 | /* grab the locks */ |
323 | mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); | 327 | unix_ilock (mbox, MU_LOCKER_WRLOCK); |
324 | mailbox_unix_lock (mbox, MU_LOCKER_RDLOCK); | 328 | unix_lock (mbox, MU_LOCKER_RDLOCK); |
325 | 329 | ||
326 | /* seek to the starting point */ | 330 | /* seek to the starting point */ |
327 | if (mud->umessages && msgno > 0 && mud->messages_count > 0 | 331 | if (mud->umessages && msgno > 0 && mud->messages_count > 0 |
... | @@ -403,7 +407,7 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -403,7 +407,7 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) |
403 | 407 | ||
404 | /* every 50 mesgs update the lock, it should be every minute */ | 408 | /* every 50 mesgs update the lock, it should be every minute */ |
405 | if ((mud->messages_count % 50) == 0) | 409 | if ((mud->messages_count % 50) == 0) |
406 | mailbox_unix_touchlock (mbox); | 410 | unix_touchlock (mbox); |
407 | 411 | ||
408 | /* ping them every 1000 lines */ | 412 | /* ping them every 1000 lines */ |
409 | if (do_notif) | 413 | if (do_notif) |
... | @@ -419,8 +423,8 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -419,8 +423,8 @@ mailbox_unix_scan0 (mailbox_t mbox, size_t msgno, size_t *pcount, int do_notif) |
419 | if (do_notif) | 423 | if (do_notif) |
420 | DISPATCH_ADD_MSG(mbox, mud); | 424 | DISPATCH_ADD_MSG(mbox, mud); |
421 | } | 425 | } |
422 | mailbox_unix_iunlock (mbox); | 426 | unix_iunlock (mbox); |
423 | mailbox_unix_unlock (mbox); | 427 | unix_unlock (mbox); |
424 | if (pcount) | 428 | if (pcount) |
425 | *pcount = mud->messages_count; | 429 | *pcount = mud->messages_count; |
426 | return status; | 430 | return status; | ... | ... |
... | @@ -68,7 +68,7 @@ message_destroy (message_t *pmsg, void *owner) | ... | @@ -68,7 +68,7 @@ message_destroy (message_t *pmsg, void *owner) |
68 | /* header */ | 68 | /* header */ |
69 | header_destroy (&(msg->header), owner); | 69 | header_destroy (&(msg->header), owner); |
70 | /* attribute */ | 70 | /* attribute */ |
71 | attribute_destroy (&(msg->attribute)); | 71 | attribute_destroy (&(msg->attribute), owner); |
72 | /* stream */ | 72 | /* stream */ |
73 | stream_destroy (&(msg->stream), owner); | 73 | stream_destroy (&(msg->stream), owner); |
74 | 74 | ||
... | @@ -325,7 +325,7 @@ message_get_attribute (message_t msg, attribute_t *pattribute) | ... | @@ -325,7 +325,7 @@ message_get_attribute (message_t msg, attribute_t *pattribute) |
325 | if (msg->attribute == NULL) | 325 | if (msg->attribute == NULL) |
326 | { | 326 | { |
327 | attribute_t attribute; | 327 | attribute_t attribute; |
328 | int status = attribute_create (&attribute); | 328 | int status = attribute_create (&attribute, msg); |
329 | if (status != 0) | 329 | if (status != 0) |
330 | return status; | 330 | return status; |
331 | msg->attribute = attribute; | 331 | msg->attribute = attribute; |
... | @@ -341,7 +341,7 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner) | ... | @@ -341,7 +341,7 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner) |
341 | return EINVAL; | 341 | return EINVAL; |
342 | if (msg->owner != owner) | 342 | if (msg->owner != owner) |
343 | return EACCES; | 343 | return EACCES; |
344 | attribute_destroy (&(msg->attribute)); | 344 | attribute_destroy (&(msg->attribute), owner); |
345 | msg->attribute = attribute; | 345 | msg->attribute = attribute; |
346 | return 0; | 346 | return 0; |
347 | } | 347 | } |
... | @@ -532,7 +532,11 @@ message_read (stream_t is, char *buf, size_t buflen, | ... | @@ -532,7 +532,11 @@ message_read (stream_t is, char *buf, size_t buflen, |
532 | header_size (msg->header, &hsize); | 532 | header_size (msg->header, &hsize); |
533 | body_size (msg->body, &bsize); | 533 | body_size (msg->body, &bsize); |
534 | 534 | ||
535 | if ((size_t)off <= hsize) | 535 | /* On some remote sever (POP) the size of the header and body is not known |
536 | until you start reading them. So by checking hsize == bsize == 0, we | ||
537 | This kludge of a way of detecting the anomalie and start by the | ||
538 | header. */ | ||
539 | if ((size_t)off <= hsize || (hsize == 0 && bsize == 0)) | ||
536 | { | 540 | { |
537 | header_get_stream (msg->header, &his); | 541 | header_get_stream (msg->header, &his); |
538 | stream_read (his, buf, buflen, off, &hread); | 542 | stream_read (his, buf, buflen, off, &hread); | ... | ... |
... | @@ -25,13 +25,12 @@ | ... | @@ -25,13 +25,12 @@ |
25 | #include <string.h> | 25 | #include <string.h> |
26 | #include <errno.h> | 26 | #include <errno.h> |
27 | 27 | ||
28 | /* | 28 | /* Builtin mailbox types. A circular list is use for the builtin. |
29 | Builtin mailbox types. | ||
30 | A circular list is use for the builtin. | ||
31 | Proper locking is not done when accessing the list. | 29 | Proper locking is not done when accessing the list. |
32 | FIXME: not thread-safe. */ | 30 | FIXME: not thread-safe. */ |
33 | 31 | ||
34 | static struct _registrar registrar [] = { | 32 | static struct _registrar registrar [] = |
33 | { | ||
35 | { NULL, NULL, 0, ®istrar[1] }, /* sentinel, head list */ | 34 | { NULL, NULL, 0, ®istrar[1] }, /* sentinel, head list */ |
36 | { &_url_file_registrar, &_mailbox_mbox_registrar, 0, ®istrar[2] }, | 35 | { &_url_file_registrar, &_mailbox_mbox_registrar, 0, ®istrar[2] }, |
37 | { &_url_mbox_registrar, &_mailbox_mbox_registrar, 0, ®istrar[3] }, | 36 | { &_url_mbox_registrar, &_mailbox_mbox_registrar, 0, ®istrar[3] }, | ... | ... |
-
Please register or sign in to post a comment