Commit 4cd95bc0 4cd95bc05a695c35d4c74e93631b49d13b6bbf8c by Alain Magloire

Corrected my oversights and bugs introduce last time. Keyboard quotas expired.

1 parent 24d3722e
...@@ -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 {
......