Corrected my oversights and bugs introduce last time. Keyboard quotas expired.
Showing
5 changed files
with
120 additions
and
90 deletions
... | @@ -2,8 +2,7 @@ | ... | @@ -2,8 +2,7 @@ |
2 | 2 | ||
3 | AUTOMAKE_OPTIONS = ../lib/ansi2knr | 3 | AUTOMAKE_OPTIONS = ../lib/ansi2knr |
4 | 4 | ||
5 | INCLUDES = -I${srcdir}/include/public \ | 5 | INCLUDES = -I${srcdir}/include -I${srcdir}/include -I${srcdir}/lib |
6 | -I${srcdir}/include/private | ||
7 | CFLAGS = -Wall -pedantic -g -DTESTING | 6 | CFLAGS = -Wall -pedantic -g -DTESTING |
8 | 7 | ||
9 | SUBDIRS = include | 8 | SUBDIRS = include | ... | ... |
... | @@ -111,8 +111,8 @@ attribute_set_seen (attribute_t attr) | ... | @@ -111,8 +111,8 @@ attribute_set_seen (attribute_t attr) |
111 | int status = 0; | 111 | int status = 0; |
112 | if (attr == NULL) | 112 | if (attr == NULL) |
113 | return EINVAL; | 113 | return EINVAL; |
114 | if (attr->_get_flags) | 114 | if (attr->_set_flags) |
115 | status = attr->_get_flags (attr, &(attr->flags)); | 115 | status = attr->_set_flags (attr, MU_ATTRIBUTE_SEEN); |
116 | attr->flags |= MU_ATTRIBUTE_SEEN; | 116 | attr->flags |= MU_ATTRIBUTE_SEEN; |
117 | return 0; | 117 | return 0; |
118 | } | 118 | } |
... | @@ -123,8 +123,8 @@ attribute_set_answered (attribute_t attr) | ... | @@ -123,8 +123,8 @@ attribute_set_answered (attribute_t attr) |
123 | int status = 0; | 123 | int status = 0; |
124 | if (attr == NULL) | 124 | if (attr == NULL) |
125 | return EINVAL; | 125 | return EINVAL; |
126 | if (attr->_get_flags) | 126 | if (attr->_set_flags) |
127 | status = attr->_get_flags (attr, &(attr->flags)); | 127 | status = attr->_set_flags (attr, MU_ATTRIBUTE_ANSWERED); |
128 | attr->flags |= MU_ATTRIBUTE_ANSWERED; | 128 | attr->flags |= MU_ATTRIBUTE_ANSWERED; |
129 | return 0; | 129 | return 0; |
130 | } | 130 | } |
... | @@ -135,8 +135,8 @@ attribute_set_flagged (attribute_t attr) | ... | @@ -135,8 +135,8 @@ attribute_set_flagged (attribute_t attr) |
135 | int status = 0; | 135 | int status = 0; |
136 | if (attr == NULL) | 136 | if (attr == NULL) |
137 | return EINVAL; | 137 | return EINVAL; |
138 | if (attr->_get_flags) | 138 | if (attr->_set_flags) |
139 | status = attr->_get_flags (attr, &(attr->flags)); | 139 | status = attr->_set_flags (attr, MU_ATTRIBUTE_FLAGGED); |
140 | attr->flags |= MU_ATTRIBUTE_FLAGGED; | 140 | attr->flags |= MU_ATTRIBUTE_FLAGGED; |
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
... | @@ -147,8 +147,8 @@ attribute_set_read (attribute_t attr) | ... | @@ -147,8 +147,8 @@ attribute_set_read (attribute_t attr) |
147 | int status = 0; | 147 | int status = 0; |
148 | if (attr == NULL) | 148 | if (attr == NULL) |
149 | return EINVAL; | 149 | return EINVAL; |
150 | if (attr->_get_flags) | 150 | if (attr->_set_flags) |
151 | status = attr->_get_flags (attr, &(attr->flags)); | 151 | status = attr->_set_flags (attr, MU_ATTRIBUTE_READ); |
152 | attr->flags |= MU_ATTRIBUTE_READ; | 152 | attr->flags |= MU_ATTRIBUTE_READ; |
153 | return 0; | 153 | return 0; |
154 | } | 154 | } |
... | @@ -159,8 +159,8 @@ attribute_set_deleted (attribute_t attr) | ... | @@ -159,8 +159,8 @@ attribute_set_deleted (attribute_t attr) |
159 | int status = 0; | 159 | int status = 0; |
160 | if (attr == NULL) | 160 | if (attr == NULL) |
161 | return EINVAL; | 161 | return EINVAL; |
162 | if (attr->_get_flags) | 162 | if (attr->_set_flags) |
163 | status = attr->_get_flags (attr, &(attr->flags)); | 163 | status = attr->_set_flags (attr, MU_ATTRIBUTE_DELETED); |
164 | attr->flags |= MU_ATTRIBUTE_DELETED; | 164 | attr->flags |= MU_ATTRIBUTE_DELETED; |
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
... | @@ -171,8 +171,8 @@ attribute_set_draft (attribute_t attr) | ... | @@ -171,8 +171,8 @@ attribute_set_draft (attribute_t attr) |
171 | int status = 0; | 171 | int status = 0; |
172 | if (attr == NULL) | 172 | if (attr == NULL) |
173 | return EINVAL; | 173 | return EINVAL; |
174 | if (attr->_get_flags) | 174 | if (attr->_set_flags) |
175 | status = attr->_get_flags (attr, &(attr->flags)); | 175 | status = attr->_set_flags (attr, MU_ATTRIBUTE_DRAFT); |
176 | attr->flags |= MU_ATTRIBUTE_DRAFT; | 176 | attr->flags |= MU_ATTRIBUTE_DRAFT; |
177 | return 0; | 177 | return 0; |
178 | } | 178 | } |
... | @@ -183,15 +183,17 @@ attribute_set_recent (attribute_t attr) | ... | @@ -183,15 +183,17 @@ attribute_set_recent (attribute_t attr) |
183 | int status = 0; | 183 | int status = 0; |
184 | if (attr == NULL) | 184 | if (attr == NULL) |
185 | return EINVAL; | 185 | return EINVAL; |
186 | if (attr->_get_flags) | 186 | if (attr->_unset_flags) |
187 | status = attr->_get_flags (attr, &(attr->flags)); | 187 | { |
188 | status = attr->_unset_flags (attr, MU_ATTRIBUTE_READ); | ||
189 | status = attr->_unset_flags (attr, MU_ATTRIBUTE_SEEN); | ||
190 | } | ||
188 | if (attr == NULL) | 191 | if (attr == NULL) |
189 | { | 192 | { |
190 | attr->flags &= ~MU_ATTRIBUTE_READ; | 193 | attr->flags &= ~MU_ATTRIBUTE_READ; |
191 | attr->flags &= ~MU_ATTRIBUTE_SEEN; | 194 | attr->flags &= ~MU_ATTRIBUTE_SEEN; |
192 | return 0; | ||
193 | } | 195 | } |
194 | return EACCES; | 196 | return 0; |
195 | } | 197 | } |
196 | 198 | ||
197 | int | 199 | int | ... | ... |
... | @@ -32,21 +32,23 @@ static int header_read (stream_t is, char *buf, size_t buflen, | ... | @@ -32,21 +32,23 @@ static int header_read (stream_t is, char *buf, size_t buflen, |
32 | off_t off, size_t *pnread); | 32 | off_t off, size_t *pnread); |
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 | static int fill_blurb (header_t header); | ||
35 | 36 | ||
36 | int | 37 | int |
37 | header_create (header_t *ph, const char *blurb, size_t len, void *owner) | 38 | header_create (header_t *ph, const char *blurb, size_t len, void *owner) |
38 | { | 39 | { |
39 | header_t h; | 40 | header_t h; |
41 | int status = 0; | ||
40 | h = calloc (1, sizeof (*h)); | 42 | h = calloc (1, sizeof (*h)); |
41 | if (h == NULL) | 43 | if (h == NULL) |
42 | return ENOMEM; | 44 | return ENOMEM; |
43 | h->owner = owner; | 45 | h->owner = owner; |
44 | 46 | ||
45 | /* Ignore the return value. */ | 47 | /* Ignore the return value. */ |
46 | header_parse (h, blurb, len); | 48 | status = header_parse (h, blurb, len); |
47 | 49 | ||
48 | *ph = h; | 50 | *ph = h; |
49 | return 0; | 51 | return status; |
50 | } | 52 | } |
51 | 53 | ||
52 | void | 54 | void |
... | @@ -196,10 +198,17 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) | ... | @@ -196,10 +198,17 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) |
196 | if (header == NULL || fn == NULL || fv == NULL) | 198 | if (header == NULL || fn == NULL || fv == NULL) |
197 | return EINVAL; | 199 | return EINVAL; |
198 | 200 | ||
199 | /* Try to fill out the buffer, if we know how. */ | ||
200 | if (header->_set_value != NULL) | 201 | if (header->_set_value != NULL) |
201 | return header->_set_value (header, fn, fv, replace); | 202 | return header->_set_value (header, fn, fv, replace); |
202 | 203 | ||
204 | /* Try to fill out the buffer, if we know how. */ | ||
205 | if (header->blurb == NULL) | ||
206 | { | ||
207 | int err = fill_blurb (header); | ||
208 | if (err != 0) | ||
209 | return err; | ||
210 | } | ||
211 | |||
203 | /* Easy approach: if replace, overwrite the field-{name,value} and readjust | 212 | /* Easy approach: if replace, overwrite the field-{name,value} and readjust |
204 | the pointers by calling header_parse () this is wastefull, we're just | 213 | 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 | 214 | fragmenting the memory it can be done better. But that may imply a |
... | @@ -265,39 +274,9 @@ header_get_value (header_t header, const char *name, char *buffer, | ... | @@ -265,39 +274,9 @@ header_get_value (header_t header, const char *name, char *buffer, |
265 | /* Try to fill out the buffer, if we know how. */ | 274 | /* Try to fill out the buffer, if we know how. */ |
266 | if (header->blurb == NULL) | 275 | if (header->blurb == NULL) |
267 | { | 276 | { |
268 | stream_t is; | 277 | err = fill_blurb (header); |
269 | err = header_get_stream (header, &is); | ||
270 | if (err != 0) | 278 | if (err != 0) |
271 | return err; | 279 | 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 | } | 280 | } |
302 | 281 | ||
303 | /* We set the threshold to be 1 less for the null. */ | 282 | /* We set the threshold to be 1 less for the null. */ |
... | @@ -362,6 +341,14 @@ header_lines (header_t header, size_t *plines) | ... | @@ -362,6 +341,14 @@ header_lines (header_t header, size_t *plines) |
362 | if (header == NULL) | 341 | if (header == NULL) |
363 | return EINVAL; | 342 | return EINVAL; |
364 | 343 | ||
344 | /* Try to fill out the buffer, if we know how. */ | ||
345 | if (header->blurb == NULL) | ||
346 | { | ||
347 | int err = fill_blurb (header); | ||
348 | if (err != 0) | ||
349 | return err; | ||
350 | } | ||
351 | |||
365 | for (n = header->blurb_len - 1; n >= 0; n--) | 352 | for (n = header->blurb_len - 1; n >= 0; n--) |
366 | { | 353 | { |
367 | if (header->blurb[n] == '\n') | 354 | if (header->blurb[n] == '\n') |
... | @@ -378,6 +365,14 @@ header_size (header_t header, size_t *pnum) | ... | @@ -378,6 +365,14 @@ header_size (header_t header, size_t *pnum) |
378 | if (header == NULL) | 365 | if (header == NULL) |
379 | return EINVAL; | 366 | return EINVAL; |
380 | 367 | ||
368 | /* Try to fill out the buffer, if we know how. */ | ||
369 | if (header->blurb == NULL) | ||
370 | { | ||
371 | int err = fill_blurb (header); | ||
372 | if (err != 0) | ||
373 | return err; | ||
374 | } | ||
375 | |||
381 | if (pnum) | 376 | if (pnum) |
382 | *pnum = header->blurb_len; | 377 | *pnum = header->blurb_len; |
383 | return 0; | 378 | return 0; |
... | @@ -420,6 +415,54 @@ header_set_stream (header_t header, stream_t stream, void *owner) | ... | @@ -420,6 +415,54 @@ header_set_stream (header_t header, stream_t stream, void *owner) |
420 | return 0; | 415 | return 0; |
421 | } | 416 | } |
422 | 417 | ||
418 | static int | ||
419 | fill_blurb (header_t header) | ||
420 | { | ||
421 | stream_t is; | ||
422 | int status; | ||
423 | char buf[1024]; | ||
424 | char *tbuf; | ||
425 | size_t nread = 0; | ||
426 | |||
427 | status = header_get_stream (header, &is); | ||
428 | if (status != 0) | ||
429 | return status; | ||
430 | |||
431 | do | ||
432 | { | ||
433 | status = stream_read (is, buf, sizeof (buf), header->temp_blurb_len, | ||
434 | &nread); | ||
435 | if (status != 0) | ||
436 | { | ||
437 | if (status != EAGAIN || status != EINTR) | ||
438 | { | ||
439 | free (header->temp_blurb); | ||
440 | header->temp_blurb = NULL; | ||
441 | header->temp_blurb_len = 0; | ||
442 | } | ||
443 | return status; | ||
444 | } | ||
445 | tbuf = realloc (header->temp_blurb, header->temp_blurb_len + nread); | ||
446 | if (tbuf == NULL) | ||
447 | { | ||
448 | free (header->temp_blurb); | ||
449 | header->temp_blurb = NULL; | ||
450 | header->temp_blurb_len = 0; | ||
451 | return ENOMEM; | ||
452 | } | ||
453 | header->temp_blurb = tbuf; | ||
454 | memcpy (header->temp_blurb + header->temp_blurb_len, buf, nread); | ||
455 | header->temp_blurb_len += nread; | ||
456 | } | ||
457 | while (nread != 0); | ||
458 | |||
459 | /* parse it. */ | ||
460 | status = header_parse (header, header->temp_blurb, header->temp_blurb_len); | ||
461 | free (header->temp_blurb); | ||
462 | header->temp_blurb = NULL; | ||
463 | header->temp_blurb_len = 0; | ||
464 | return status; | ||
465 | } | ||
423 | 466 | ||
424 | static int | 467 | static int |
425 | header_write (stream_t os, const char *buf, size_t buflen, | 468 | header_write (stream_t os, const char *buf, size_t buflen, | ... | ... |
... | @@ -347,8 +347,8 @@ unix_open (mailbox_t mbox, int flags) | ... | @@ -347,8 +347,8 @@ unix_open (mailbox_t mbox, int flags) |
347 | { | 347 | { |
348 | /* FIXME: for small mbox we shout try to mmap (). */ | 348 | /* FIXME: for small mbox we shout try to mmap (). */ |
349 | 349 | ||
350 | int trymap = (flags & MU_STREAM_CREAT) || (flags & MU_STREAM_APPEND); | 350 | status = (flags & MU_STREAM_CREAT) || (flags & MU_STREAM_APPEND); |
351 | if (trymap == 0) | 351 | if (status == 0) |
352 | status = mapfile_stream_create (&(mbox->stream)); | 352 | status = mapfile_stream_create (&(mbox->stream)); |
353 | if (status != 0) | 353 | if (status != 0) |
354 | { | 354 | { |
... | @@ -1154,11 +1154,6 @@ unix_append_message (mailbox_t mbox, message_t msg) | ... | @@ -1154,11 +1154,6 @@ unix_append_message (mailbox_t mbox, message_t msg) |
1154 | unix_lock (mbox, MU_LOCKER_WRLOCK); | 1154 | unix_lock (mbox, MU_LOCKER_WRLOCK); |
1155 | { | 1155 | { |
1156 | off_t size; | 1156 | off_t size; |
1157 | char buffer[BUFSIZ]; | ||
1158 | size_t nread = 0; | ||
1159 | off_t off = 0; | ||
1160 | stream_t is; | ||
1161 | header_t hdr; | ||
1162 | int status; | 1157 | int status; |
1163 | size_t n = 0; | 1158 | size_t n = 0; |
1164 | char nl = '\n'; | 1159 | char nl = '\n'; |
... | @@ -1170,8 +1165,7 @@ unix_append_message (mailbox_t mbox, message_t msg) | ... | @@ -1170,8 +1165,7 @@ unix_append_message (mailbox_t mbox, message_t msg) |
1170 | unix_unlock (mbox); | 1165 | unix_unlock (mbox); |
1171 | return status; | 1166 | return status; |
1172 | } | 1167 | } |
1173 | /* Header. */ | 1168 | |
1174 | message_get_header (msg, &hdr); | ||
1175 | /* Generate a "From " separator. */ | 1169 | /* Generate a "From " separator. */ |
1176 | { | 1170 | { |
1177 | char from[128]; | 1171 | char from[128]; |
... | @@ -1180,14 +1174,14 @@ unix_append_message (mailbox_t mbox, message_t msg) | ... | @@ -1180,14 +1174,14 @@ unix_append_message (mailbox_t mbox, message_t msg) |
1180 | size_t f = 0, d = 0; | 1174 | size_t f = 0, d = 0; |
1181 | *date = *from = '\0'; | 1175 | *date = *from = '\0'; |
1182 | message_from (msg, from, sizeof (from), &f); | 1176 | message_from (msg, from, sizeof (from), &f); |
1183 | s = memchr (from, '\n', f); | 1177 | s = memchr (from, nl, f); |
1184 | if (s) | 1178 | if (s) |
1185 | { | 1179 | { |
1186 | *s = '\0'; | 1180 | *s = '\0'; |
1187 | f--; | 1181 | f--; |
1188 | } | 1182 | } |
1189 | message_received (msg, date, sizeof (date), &d); | 1183 | message_received (msg, date, sizeof (date), &d); |
1190 | s = memchr (date, '\n', d); | 1184 | s = memchr (date, nl, d); |
1191 | if (s) | 1185 | if (s) |
1192 | { | 1186 | { |
1193 | *s = '\0'; | 1187 | *s = '\0'; |
... | @@ -1200,31 +1194,23 @@ unix_append_message (mailbox_t mbox, message_t msg) | ... | @@ -1200,31 +1194,23 @@ unix_append_message (mailbox_t mbox, message_t msg) |
1200 | stream_write (mbox->stream, &nl , 1, size, &n); size += n; | 1194 | stream_write (mbox->stream, &nl , 1, size, &n); size += n; |
1201 | } | 1195 | } |
1202 | 1196 | ||
1203 | header_get_stream (hdr, &is); | 1197 | /* Append the Message. */ |
1204 | do { | 1198 | { |
1205 | status = stream_read (is, buffer, sizeof (buffer), off, &nread); | 1199 | char buffer[BUFSIZ]; |
1206 | if (status != 0) | 1200 | size_t nread = 0; |
1207 | return status; | 1201 | off_t off = 0; |
1208 | if (nread == 0) | 1202 | stream_t is; |
1209 | break; | 1203 | message_get_stream (msg, &is); |
1210 | stream_write (mbox->stream, buffer, nread, size, &n); | 1204 | do |
1211 | off += nread; | 1205 | { |
1212 | size += n; | 1206 | stream_read (is, buffer, sizeof (buffer), off, &nread); |
1213 | } while (nread > 0); | 1207 | stream_write (mbox->stream, buffer, nread, size, &n); |
1214 | 1208 | off += nread; | |
1215 | *buffer = '\0'; | 1209 | size += n; |
1216 | /* Separator. */ | 1210 | } |
1217 | /*fputc ('\n', mud->file);*/ | 1211 | while (nread > 0); |
1218 | 1212 | stream_write (mbox->stream, &nl, 1, size, &n); | |
1219 | /* Body. */ | 1213 | } |
1220 | message_get_stream (msg, &is); | ||
1221 | do { | ||
1222 | stream_read (is, buffer, sizeof (buffer), off, &nread); | ||
1223 | stream_write (mbox->stream, buffer, nread, size, &n); | ||
1224 | off += nread; | ||
1225 | size += n; | ||
1226 | } while (nread > 0); | ||
1227 | stream_write (mbox->stream, &nl, 1, size, &n); | ||
1228 | } | 1214 | } |
1229 | stream_flush (mbox->stream); | 1215 | stream_flush (mbox->stream); |
1230 | unix_unlock (mbox); | 1216 | unix_unlock (mbox); | ... | ... |
... | @@ -533,8 +533,8 @@ message_read (stream_t is, char *buf, size_t buflen, | ... | @@ -533,8 +533,8 @@ message_read (stream_t is, char *buf, size_t buflen, |
533 | body_size (msg->body, &bsize); | 533 | body_size (msg->body, &bsize); |
534 | 534 | ||
535 | /* On some remote sever (POP) the size of the header and body is not known | 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 | 536 | until you start reading them. So by checking hsize == bsize == 0, |
537 | This kludge of a way of detecting the anomalie and start by the | 537 | this kludge is a way of detecting the anomalie and start by the |
538 | header. */ | 538 | header. */ |
539 | if ((size_t)off <= hsize || (hsize == 0 && bsize == 0)) | 539 | if ((size_t)off <= hsize || (hsize == 0 && bsize == 0)) |
540 | { | 540 | { | ... | ... |
-
Please register or sign in to post a comment