* mailbox2/include/mailutils/mbox.h: New prototypes.
* mailbox2/include/mailutils/sys/mbox.h: New prototypes. * mailbox2/mbox/*.c: Finish implementation. * mailbox2/attribute.c: Add user flags. * mailbox2/dattribute.c: Add user flags. To be compatible with the old mailbox, all stream read and write take an offset. Removed stream_seek () and add stream_is_seekable() instead. * mailbox2/stream.c: Likewised. * mailbox2/bstream.c: Likewised. * mailbox2/fdstream.c: Likewised. * mailbox2/fstream.c: Likewised. * mailbox2/mapstream.c: Likewised. * mailbox2/memstream.c: Likewised. * mailbox2/tcpstream.c: Likewised. * mailbox2/include/mailutils/error.h: Add EBADFD.
Showing
71 changed files
with
1373 additions
and
631 deletions
... | @@ -81,6 +81,42 @@ attribute_clear_flags (attribute_t attribute) | ... | @@ -81,6 +81,42 @@ attribute_clear_flags (attribute_t attribute) |
81 | return attribute->vtable->clear_flags (attribute); | 81 | return attribute->vtable->clear_flags (attribute); |
82 | } | 82 | } |
83 | 83 | ||
84 | int | ||
85 | attribute_get_userflags (attribute_t attribute, int *puserflags) | ||
86 | { | ||
87 | if (attribute == NULL || attribute->vtable == NULL | ||
88 | || attribute->vtable->get_userflags == NULL) | ||
89 | return MU_ERROR_NOT_SUPPORTED; | ||
90 | return attribute->vtable->get_userflags (attribute, puserflags); | ||
91 | } | ||
92 | |||
93 | int | ||
94 | attribute_set_userflags (attribute_t attribute, int userflags) | ||
95 | { | ||
96 | if (attribute == NULL || attribute->vtable == NULL | ||
97 | || attribute->vtable->set_userflags == NULL) | ||
98 | return MU_ERROR_NOT_SUPPORTED; | ||
99 | return attribute->vtable->set_userflags (attribute, userflags); | ||
100 | } | ||
101 | |||
102 | int | ||
103 | attribute_unset_userflags (attribute_t attribute, int userflags) | ||
104 | { | ||
105 | if (attribute == NULL || attribute->vtable == NULL | ||
106 | || attribute->vtable->unset_userflags == NULL) | ||
107 | return MU_ERROR_NOT_SUPPORTED; | ||
108 | return attribute->vtable->unset_userflags (attribute, userflags); | ||
109 | } | ||
110 | |||
111 | int | ||
112 | attribute_clear_userflags (attribute_t attribute) | ||
113 | { | ||
114 | if (attribute == NULL || attribute->vtable == NULL | ||
115 | || attribute->vtable->clear_userflags == NULL) | ||
116 | return MU_ERROR_NOT_SUPPORTED; | ||
117 | return attribute->vtable->clear_userflags (attribute); | ||
118 | } | ||
119 | |||
84 | 120 | ||
85 | /* Stub helpers for the wellknown flags. */ | 121 | /* Stub helpers for the wellknown flags. */ |
86 | int | 122 | int |
... | @@ -149,6 +185,16 @@ attribute_set_modified (attribute_t attribute) | ... | @@ -149,6 +185,16 @@ attribute_set_modified (attribute_t attribute) |
149 | } | 185 | } |
150 | 186 | ||
151 | int | 187 | int |
188 | attribute_is_userflags (attribute_t attribute, int userflag) | ||
189 | { | ||
190 | int flags = 0; | ||
191 | if (attribute == NULL) | ||
192 | return 0; | ||
193 | attribute_get_userflags (attribute, &flags); | ||
194 | return flags & userflag; | ||
195 | } | ||
196 | |||
197 | int | ||
152 | attribute_is_seen (attribute_t attribute) | 198 | attribute_is_seen (attribute_t attribute) |
153 | { | 199 | { |
154 | int flags = 0; | 200 | int flags = 0; | ... | ... |
... | @@ -44,19 +44,20 @@ _stream_buffer_cleanup (void *arg) | ... | @@ -44,19 +44,20 @@ _stream_buffer_cleanup (void *arg) |
44 | } | 44 | } |
45 | 45 | ||
46 | static int | 46 | static int |
47 | refill (struct _stream_buffer *bs) | 47 | refill (struct _stream_buffer *bs, off_t offset) |
48 | { | 48 | { |
49 | int status; | 49 | int status; |
50 | if (bs->rbuffer.base == NULL) | 50 | if (bs->rbuffer.base == NULL) |
51 | { | 51 | { |
52 | bs->rbuffer.base = calloc (1, bs->rbuffer.bufsize); | 52 | bs->rbuffer.base = calloc (1, bs->rbuffer.bufsize); |
53 | if (bs->rbuffer.base == NULL) | 53 | if (bs->rbuffer.base == NULL) |
54 | return ENOMEM; | 54 | return MU_ERROR_NO_MEMORY; |
55 | } | 55 | } |
56 | bs->rbuffer.ptr = bs->rbuffer.base; | 56 | bs->rbuffer.ptr = bs->rbuffer.base; |
57 | bs->rbuffer.count = 0; | 57 | bs->rbuffer.count = 0; |
58 | bs->rbuffer.offset = offset; | ||
58 | status = stream_read (bs->stream, bs->rbuffer.ptr, bs->rbuffer.bufsize, | 59 | status = stream_read (bs->stream, bs->rbuffer.ptr, bs->rbuffer.bufsize, |
59 | (size_t *)&(bs->rbuffer.count)); | 60 | offset, (size_t *)&(bs->rbuffer.count)); |
60 | return status; | 61 | return status; |
61 | } | 62 | } |
62 | 63 | ||
... | @@ -107,7 +108,8 @@ _stream_buffer_close (stream_t stream) | ... | @@ -107,7 +108,8 @@ _stream_buffer_close (stream_t stream) |
107 | networking. Lots of code between POP and IMAP can be share this way. | 108 | networking. Lots of code between POP and IMAP can be share this way. |
108 | The buffering is on the read only, the writes fall through. */ | 109 | The buffering is on the read only, the writes fall through. */ |
109 | int | 110 | int |
110 | _stream_buffer_read (stream_t stream, void *buf, size_t count, size_t *pnread) | 111 | _stream_buffer_read (stream_t stream, void *buf, size_t count, off_t offset, |
112 | size_t *pnread) | ||
111 | { | 113 | { |
112 | int status = 0; | 114 | int status = 0; |
113 | struct _stream_buffer *bs = (struct _stream_buffer *)stream; | 115 | struct _stream_buffer *bs = (struct _stream_buffer *)stream; |
... | @@ -121,8 +123,8 @@ _stream_buffer_read (stream_t stream, void *buf, size_t count, size_t *pnread) | ... | @@ -121,8 +123,8 @@ _stream_buffer_read (stream_t stream, void *buf, size_t count, size_t *pnread) |
121 | else if (bs->rbuffer.bufsize == 0) | 123 | else if (bs->rbuffer.bufsize == 0) |
122 | { | 124 | { |
123 | /* If rbuffer.bufsize == 0. It means they did not want the buffer | 125 | /* If rbuffer.bufsize == 0. It means they did not want the buffer |
124 | mechanism, then what are we doing here? */ | 126 | mechanism, ... what are we doing here? */ |
125 | status = stream_read (bs->stream, buf, count, pnread); | 127 | status = stream_read (bs->stream, buf, count, offset, pnread); |
126 | } | 128 | } |
127 | else | 129 | else |
128 | { | 130 | { |
... | @@ -139,14 +141,17 @@ _stream_buffer_read (stream_t stream, void *buf, size_t count, size_t *pnread) | ... | @@ -139,14 +141,17 @@ _stream_buffer_read (stream_t stream, void *buf, size_t count, size_t *pnread) |
139 | { | 141 | { |
140 | r = 0; | 142 | r = 0; |
141 | /* Drain our buffer first. */ | 143 | /* Drain our buffer first. */ |
142 | if (bs->rbuffer.count > 0) | 144 | if (bs->rbuffer.count > 0 && offset == bs->rbuffer.offset) |
143 | { | 145 | { |
144 | memcpy(p, bs->rbuffer.ptr, bs->rbuffer.count); | 146 | memcpy(p, bs->rbuffer.ptr, bs->rbuffer.count); |
147 | bs->rbuffer.offset += bs->rbuffer.count; | ||
145 | residue -= bs->rbuffer.count; | 148 | residue -= bs->rbuffer.count; |
146 | p += bs->rbuffer.count; | 149 | p += bs->rbuffer.count; |
150 | offset += bs->rbuffer.count; | ||
147 | } | 151 | } |
148 | bs->rbuffer.count = 0; /* Signal we will need to refill. */ | 152 | bs->rbuffer.count = 0; /* Signal we will need to refill. */ |
149 | status = stream_read (bs->stream, p, residue, &r); | 153 | status = stream_read (bs->stream, p, residue, offset, &r); |
154 | bs->rbuffer.offset += r; | ||
150 | residue -= r; | 155 | residue -= r; |
151 | if (pnread) | 156 | if (pnread) |
152 | *pnread = count - residue; | 157 | *pnread = count - residue; |
... | @@ -164,20 +169,22 @@ _stream_buffer_read (stream_t stream, void *buf, size_t count, size_t *pnread) | ... | @@ -164,20 +169,22 @@ _stream_buffer_read (stream_t stream, void *buf, size_t count, size_t *pnread) |
164 | { | 169 | { |
165 | (void)memcpy (p, bs->rbuffer.ptr, (size_t)r); | 170 | (void)memcpy (p, bs->rbuffer.ptr, (size_t)r); |
166 | bs->rbuffer.ptr += r; | 171 | bs->rbuffer.ptr += r; |
172 | bs->rbuffer.offset += r; | ||
167 | /* bs->rbuffer.count = 0 ... done in refill */ | 173 | /* bs->rbuffer.count = 0 ... done in refill */ |
168 | p += r; | 174 | p += r; |
169 | residue -= r; | 175 | residue -= r; |
170 | status = refill (bs); | 176 | status = refill (bs, bs->rbuffer.offset); |
171 | /* Did we reach the end. */ | 177 | /* Did we reach the end. */ |
172 | if (status != 0 || bs->rbuffer.count == 0) | 178 | if (status != 0 || bs->rbuffer.count == 0) |
173 | { | 179 | { |
174 | /* We have something in the buffer return the error on the | 180 | /* We have something in the buffer return the error on the |
175 | next call . */ | 181 | next call. */ |
176 | if (count != residue) | 182 | if (count != residue) |
177 | status = 0; | 183 | status = 0; |
178 | if (pnread) | 184 | if (pnread) |
179 | *pnread = count - residue; | 185 | *pnread = count - residue; |
180 | done = 1; | 186 | done = 1; |
187 | break; | ||
181 | } | 188 | } |
182 | } | 189 | } |
183 | if (!done) | 190 | if (!done) |
... | @@ -185,6 +192,7 @@ _stream_buffer_read (stream_t stream, void *buf, size_t count, size_t *pnread) | ... | @@ -185,6 +192,7 @@ _stream_buffer_read (stream_t stream, void *buf, size_t count, size_t *pnread) |
185 | memcpy(p, bs->rbuffer.ptr, residue); | 192 | memcpy(p, bs->rbuffer.ptr, residue); |
186 | bs->rbuffer.count -= residue; | 193 | bs->rbuffer.count -= residue; |
187 | bs->rbuffer.ptr += residue; | 194 | bs->rbuffer.ptr += residue; |
195 | bs->rbuffer.offset += residue; | ||
188 | if (pnread) | 196 | if (pnread) |
189 | *pnread = count; | 197 | *pnread = count; |
190 | } | 198 | } |
... | @@ -200,7 +208,8 @@ _stream_buffer_read (stream_t stream, void *buf, size_t count, size_t *pnread) | ... | @@ -200,7 +208,8 @@ _stream_buffer_read (stream_t stream, void *buf, size_t count, size_t *pnread) |
200 | * Stop when a newline has been read, or the count runs out. | 208 | * Stop when a newline has been read, or the count runs out. |
201 | */ | 209 | */ |
202 | int | 210 | int |
203 | _stream_buffer_readline (stream_t stream, char *buf, size_t count, size_t *pnread) | 211 | _stream_buffer_readline (stream_t stream, char *buf, size_t count, |
212 | off_t offset, size_t *pnread) | ||
204 | { | 213 | { |
205 | int status = 0; | 214 | int status = 0; |
206 | struct _stream_buffer *bs = (struct _stream_buffer *)stream; | 215 | struct _stream_buffer *bs = (struct _stream_buffer *)stream; |
... | @@ -214,7 +223,7 @@ _stream_buffer_readline (stream_t stream, char *buf, size_t count, size_t *pnrea | ... | @@ -214,7 +223,7 @@ _stream_buffer_readline (stream_t stream, char *buf, size_t count, size_t *pnrea |
214 | else if (bs->rbuffer.bufsize == 0) | 223 | else if (bs->rbuffer.bufsize == 0) |
215 | { | 224 | { |
216 | /* Use the provided readline. */ | 225 | /* Use the provided readline. */ |
217 | status = stream_readline (bs->stream, buf, count, pnread); | 226 | status = stream_readline (bs->stream, buf, count, offset, pnread); |
218 | } | 227 | } |
219 | else /* Buffered. */ | 228 | else /* Buffered. */ |
220 | { | 229 | { |
... | @@ -234,7 +243,7 @@ _stream_buffer_readline (stream_t stream, char *buf, size_t count, size_t *pnrea | ... | @@ -234,7 +243,7 @@ _stream_buffer_readline (stream_t stream, char *buf, size_t count, size_t *pnrea |
234 | len = bs->rbuffer.count; | 243 | len = bs->rbuffer.count; |
235 | if (len <= 0) | 244 | if (len <= 0) |
236 | { | 245 | { |
237 | status = refill (bs); | 246 | status = refill (bs, offset); |
238 | if (status != 0 || bs->rbuffer.count == 0) | 247 | if (status != 0 || bs->rbuffer.count == 0) |
239 | { | 248 | { |
240 | break; | 249 | break; |
... | @@ -255,6 +264,7 @@ _stream_buffer_readline (stream_t stream, char *buf, size_t count, size_t *pnrea | ... | @@ -255,6 +264,7 @@ _stream_buffer_readline (stream_t stream, char *buf, size_t count, size_t *pnrea |
255 | len = ++nl - p; | 264 | len = ++nl - p; |
256 | bs->rbuffer.count -= len; | 265 | bs->rbuffer.count -= len; |
257 | bs->rbuffer.ptr = nl; | 266 | bs->rbuffer.ptr = nl; |
267 | bs->rbuffer.offset += len; | ||
258 | memcpy (s, p, len); | 268 | memcpy (s, p, len); |
259 | total += len; | 269 | total += len; |
260 | s += len; | 270 | s += len; |
... | @@ -262,6 +272,7 @@ _stream_buffer_readline (stream_t stream, char *buf, size_t count, size_t *pnrea | ... | @@ -262,6 +272,7 @@ _stream_buffer_readline (stream_t stream, char *buf, size_t count, size_t *pnrea |
262 | } | 272 | } |
263 | bs->rbuffer.count -= len; | 273 | bs->rbuffer.count -= len; |
264 | bs->rbuffer.ptr += len; | 274 | bs->rbuffer.ptr += len; |
275 | bs->rbuffer.offset += len; | ||
265 | memcpy(s, p, len); | 276 | memcpy(s, p, len); |
266 | total += len; | 277 | total += len; |
267 | s += len; | 278 | s += len; |
... | @@ -279,10 +290,10 @@ _stream_buffer_readline (stream_t stream, char *buf, size_t count, size_t *pnrea | ... | @@ -279,10 +290,10 @@ _stream_buffer_readline (stream_t stream, char *buf, size_t count, size_t *pnrea |
279 | 290 | ||
280 | int | 291 | int |
281 | _stream_buffer_write (stream_t stream, const void *buf, size_t count, | 292 | _stream_buffer_write (stream_t stream, const void *buf, size_t count, |
282 | size_t *pnwrite) | 293 | off_t offset, size_t *pnwrite) |
283 | { | 294 | { |
284 | struct _stream_buffer *bs = (struct _stream_buffer *)stream; | 295 | struct _stream_buffer *bs = (struct _stream_buffer *)stream; |
285 | return stream_write (bs->stream, buf, count, pnwrite); | 296 | return stream_write (bs->stream, buf, count, offset, pnwrite); |
286 | } | 297 | } |
287 | 298 | ||
288 | int | 299 | int |
... | @@ -328,10 +339,10 @@ _stream_buffer_get_state (stream_t stream, enum stream_state *pstate) | ... | @@ -328,10 +339,10 @@ _stream_buffer_get_state (stream_t stream, enum stream_state *pstate) |
328 | } | 339 | } |
329 | 340 | ||
330 | int | 341 | int |
331 | _stream_buffer_seek (stream_t stream, off_t off, enum stream_whence whence) | 342 | _stream_buffer_is_seekable (stream_t stream) |
332 | { | 343 | { |
333 | struct _stream_buffer *bs = (struct _stream_buffer *)stream; | 344 | struct _stream_buffer *bs = (struct _stream_buffer *)stream; |
334 | return stream_seek (bs->stream, off, whence); | 345 | return stream_is_seekable (bs->stream); |
335 | } | 346 | } |
336 | 347 | ||
337 | int | 348 | int |
... | @@ -390,7 +401,6 @@ static struct _stream_vtable _stream_buffer_vtable = | ... | @@ -390,7 +401,6 @@ static struct _stream_vtable _stream_buffer_vtable = |
390 | _stream_buffer_readline, | 401 | _stream_buffer_readline, |
391 | _stream_buffer_write, | 402 | _stream_buffer_write, |
392 | 403 | ||
393 | _stream_buffer_seek, | ||
394 | _stream_buffer_tell, | 404 | _stream_buffer_tell, |
395 | 405 | ||
396 | _stream_buffer_get_size, | 406 | _stream_buffer_get_size, |
... | @@ -401,6 +411,7 @@ static struct _stream_vtable _stream_buffer_vtable = | ... | @@ -401,6 +411,7 @@ static struct _stream_vtable _stream_buffer_vtable = |
401 | _stream_buffer_get_flags, | 411 | _stream_buffer_get_flags, |
402 | _stream_buffer_get_state, | 412 | _stream_buffer_get_state, |
403 | 413 | ||
414 | _stream_buffer_is_seekable, | ||
404 | _stream_buffer_is_readready, | 415 | _stream_buffer_is_readready, |
405 | _stream_buffer_is_writeready, | 416 | _stream_buffer_is_writeready, |
406 | _stream_buffer_is_exceptionpending, | 417 | _stream_buffer_is_exceptionpending, |
... | @@ -423,10 +434,14 @@ _stream_buffer_ctor (struct _stream_buffer *bs, stream_t stream, | ... | @@ -423,10 +434,14 @@ _stream_buffer_ctor (struct _stream_buffer *bs, stream_t stream, |
423 | } | 434 | } |
424 | 435 | ||
425 | void | 436 | void |
426 | _stream_buffer_dtor (struct _stream_buffer *bs) | 437 | _stream_buffer_dtor (stream_t stream) |
427 | { | 438 | { |
439 | struct _stream_buffer *bs = (struct _stream_buffer *)stream; | ||
440 | if (bs) | ||
441 | { | ||
428 | stream_destroy (&bs->stream); | 442 | stream_destroy (&bs->stream); |
429 | mu_refcount_destroy (&bs->refcount); | 443 | mu_refcount_destroy (&bs->refcount); |
444 | } | ||
430 | } | 445 | } |
431 | 446 | ||
432 | int | 447 | int | ... | ... |
... | @@ -92,6 +92,50 @@ _attribute_default_clear_flags (attribute_t attribute) | ... | @@ -92,6 +92,50 @@ _attribute_default_clear_flags (attribute_t attribute) |
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | int | ||
96 | _attribute_default_get_userflags (attribute_t attribute, int *puserflags) | ||
97 | { | ||
98 | struct _attribute_default *da = (struct _attribute_default *)attribute; | ||
99 | mu_refcount_lock (da->refcount); | ||
100 | if (puserflags) | ||
101 | *puserflags = da->userflags; | ||
102 | mu_refcount_unlock (da->refcount); | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | int | ||
107 | _attribute_default_set_userflags (attribute_t attribute, int userflags) | ||
108 | { | ||
109 | struct _attribute_default *da = (struct _attribute_default *)attribute; | ||
110 | mu_refcount_lock (da->refcount); | ||
111 | da->userflags |= (userflags | MU_ATTRIBUTE_MODIFIED); | ||
112 | mu_refcount_unlock (da->refcount); | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | int | ||
117 | _attribute_default_unset_userflags (attribute_t attribute, int userflags) | ||
118 | { | ||
119 | struct _attribute_default *da = (struct _attribute_default *)attribute; | ||
120 | mu_refcount_lock (da->refcount); | ||
121 | da->userflags &= ~userflags; | ||
122 | /* If Modified was being unset do not reset it. */ | ||
123 | if (!(userflags & MU_ATTRIBUTE_MODIFIED)) | ||
124 | da->userflags |= MU_ATTRIBUTE_MODIFIED; | ||
125 | mu_refcount_unlock (da->refcount); | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | int | ||
130 | _attribute_default_clear_userflags (attribute_t attribute) | ||
131 | { | ||
132 | struct _attribute_default *da = (struct _attribute_default *)attribute; | ||
133 | mu_refcount_lock (da->refcount); | ||
134 | da->userflags = 0; | ||
135 | mu_refcount_unlock (da->refcount); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
95 | static struct _attribute_vtable _attribute_default_vtable = | 139 | static struct _attribute_vtable _attribute_default_vtable = |
96 | { | 140 | { |
97 | _attribute_default_ref, | 141 | _attribute_default_ref, |
... | @@ -100,7 +144,12 @@ static struct _attribute_vtable _attribute_default_vtable = | ... | @@ -100,7 +144,12 @@ static struct _attribute_vtable _attribute_default_vtable = |
100 | _attribute_default_get_flags, | 144 | _attribute_default_get_flags, |
101 | _attribute_default_set_flags, | 145 | _attribute_default_set_flags, |
102 | _attribute_default_unset_flags, | 146 | _attribute_default_unset_flags, |
103 | _attribute_default_clear_flags | 147 | _attribute_default_clear_flags, |
148 | |||
149 | _attribute_default_get_userflags, | ||
150 | _attribute_default_set_userflags, | ||
151 | _attribute_default_unset_userflags, | ||
152 | _attribute_default_clear_userflags | ||
104 | }; | 153 | }; |
105 | 154 | ||
106 | int | 155 | int |
... | @@ -115,8 +164,10 @@ _attribute_default_ctor (struct _attribute_default *da) | ... | @@ -115,8 +164,10 @@ _attribute_default_ctor (struct _attribute_default *da) |
115 | } | 164 | } |
116 | 165 | ||
117 | void | 166 | void |
118 | _attribute_default_dtor (struct _attribute_default *da) | 167 | _attribute_default_dtor (attribute_t attribute) |
119 | { | 168 | { |
169 | struct _attribute_default *da = (struct _attribute_default *)attribute; | ||
170 | if (da) | ||
120 | mu_refcount_destroy (&da->refcount); | 171 | mu_refcount_destroy (&da->refcount); |
121 | } | 172 | } |
122 | 173 | ||
... | @@ -173,22 +224,36 @@ attribute_status_create (attribute_t *pattribute, const char *field) | ... | @@ -173,22 +224,36 @@ attribute_status_create (attribute_t *pattribute, const char *field) |
173 | { | 224 | { |
174 | switch (*field) | 225 | switch (*field) |
175 | { | 226 | { |
176 | case 'r': | ||
177 | case 'R': | ||
178 | attribute_set_read (*pattribute); | ||
179 | break; | ||
180 | case 'O': | 227 | case 'O': |
181 | case 'o': | 228 | case 'o': |
182 | attribute_set_seen (*pattribute); | 229 | attribute_set_seen (*pattribute); |
183 | break; | 230 | break; |
231 | |||
232 | case 'r': | ||
233 | case 'R': | ||
234 | attribute_set_read (*pattribute); | ||
235 | break; | ||
236 | |||
184 | case 'a': | 237 | case 'a': |
185 | case 'A': | 238 | case 'A': |
186 | attribute_set_answered (*pattribute); | 239 | attribute_set_answered (*pattribute); |
187 | break; | 240 | break; |
241 | |||
188 | case 'd': | 242 | case 'd': |
189 | case 'D': | 243 | case 'D': |
190 | attribute_set_deleted (*pattribute); | 244 | attribute_set_deleted (*pattribute); |
191 | break; | 245 | break; |
246 | |||
247 | case 't': | ||
248 | case 'T': | ||
249 | attribute_set_draft (*pattribute); | ||
250 | break; | ||
251 | |||
252 | case 'f': | ||
253 | case 'F': | ||
254 | attribute_set_flagged (*pattribute); | ||
255 | break; | ||
256 | |||
192 | } | 257 | } |
193 | } | 258 | } |
194 | attribute_unset_modified (*pattribute); | 259 | attribute_unset_modified (*pattribute); | ... | ... |
... | @@ -242,11 +242,15 @@ _lockfile_dotlock_ctor (struct _lockfile_dotlock *dotlock, | ... | @@ -242,11 +242,15 @@ _lockfile_dotlock_ctor (struct _lockfile_dotlock *dotlock, |
242 | } | 242 | } |
243 | 243 | ||
244 | void | 244 | void |
245 | _lockfile_dotlock_dtor (struct _lockfile_dotlock *dotlock) | 245 | _lockfile_dotlock_dtor (lockfile_t lockfile) |
246 | { | 246 | { |
247 | struct _lockfile_dotlock *dotlock = (struct _lockfile_dotlock *)lockfile; | ||
248 | if (dotlock) | ||
249 | { | ||
247 | mu_refcount_destroy (&dotlock->refcount); | 250 | mu_refcount_destroy (&dotlock->refcount); |
248 | if (dotlock->fname) | 251 | if (dotlock->fname) |
249 | free (dotlock->fname); | 252 | free (dotlock->fname); |
253 | } | ||
250 | } | 254 | } |
251 | 255 | ||
252 | int | 256 | int | ... | ... |
... | @@ -93,7 +93,7 @@ _stream_fd_get_fd (stream_t stream, int *fd) | ... | @@ -93,7 +93,7 @@ _stream_fd_get_fd (stream_t stream, int *fd) |
93 | { | 93 | { |
94 | struct _stream_fd *fds = (struct _stream_fd *)stream; | 94 | struct _stream_fd *fds = (struct _stream_fd *)stream; |
95 | 95 | ||
96 | if (fd == NULL || fds->fd == -1) | 96 | if (fd == NULL) |
97 | return MU_ERROR_INVALID_PARAMETER; | 97 | return MU_ERROR_INVALID_PARAMETER; |
98 | 98 | ||
99 | *fd = fds->fd; | 99 | *fd = fds->fd; |
... | @@ -101,26 +101,44 @@ _stream_fd_get_fd (stream_t stream, int *fd) | ... | @@ -101,26 +101,44 @@ _stream_fd_get_fd (stream_t stream, int *fd) |
101 | } | 101 | } |
102 | 102 | ||
103 | int | 103 | int |
104 | _stream_fd_read (stream_t stream, void *buf, size_t buf_size, size_t *br) | 104 | _stream_fd_read (stream_t stream, void *buf, size_t buf_size, off_t offset, |
105 | size_t *br) | ||
105 | { | 106 | { |
106 | struct _stream_fd *fds = (struct _stream_fd *)stream; | 107 | struct _stream_fd *fds = (struct _stream_fd *)stream; |
107 | int bytes = 0; | 108 | int bytes = 0; |
108 | int status = 0; | 109 | int status = 0; |
109 | 110 | ||
111 | if (fds->fd < 0) | ||
112 | { | ||
113 | if (br) | ||
114 | *br = 0; | ||
115 | return MU_ERROR_BAD_FILE_DESCRIPTOR; | ||
116 | } | ||
117 | |||
110 | fds->state = MU_STREAM_STATE_READ; | 118 | fds->state = MU_STREAM_STATE_READ; |
119 | if (fds->offset != offset) | ||
120 | { | ||
121 | lseek (fds->fd, offset, SEEK_SET); | ||
122 | fds->offset = offset; | ||
123 | } | ||
124 | |||
111 | bytes = read (fds->fd, buf, buf_size); | 125 | bytes = read (fds->fd, buf, buf_size); |
112 | if (bytes == -1) | 126 | if (bytes == -1) |
113 | { | 127 | { |
114 | bytes = 0; | 128 | bytes = 0; |
115 | status = errno; | 129 | status = errno; |
116 | } | 130 | } |
131 | else | ||
132 | fds->offset += bytes; | ||
133 | |||
117 | if (br) | 134 | if (br) |
118 | *br = bytes; | 135 | *br = bytes; |
119 | return status; | 136 | return status; |
120 | } | 137 | } |
121 | 138 | ||
122 | int | 139 | int |
123 | _stream_fd_readline (stream_t stream, char *buf, size_t buf_size, size_t *br) | 140 | _stream_fd_readline (stream_t stream, char *buf, size_t buflen, |
141 | off_t offset, size_t *br) | ||
124 | { | 142 | { |
125 | struct _stream_fd *fds = (struct _stream_fd *)stream; | 143 | struct _stream_fd *fds = (struct _stream_fd *)stream; |
126 | int status = 0; | 144 | int status = 0; |
... | @@ -128,9 +146,22 @@ _stream_fd_readline (stream_t stream, char *buf, size_t buf_size, size_t *br) | ... | @@ -128,9 +146,22 @@ _stream_fd_readline (stream_t stream, char *buf, size_t buf_size, size_t *br) |
128 | int nr = 0; | 146 | int nr = 0; |
129 | char c; | 147 | char c; |
130 | 148 | ||
149 | if (fds->fd < 0) | ||
150 | { | ||
151 | if (br) | ||
152 | *br = 0; | ||
153 | return MU_ERROR_BAD_FILE_DESCRIPTOR; | ||
154 | } | ||
155 | |||
131 | fds->state = MU_STREAM_STATE_READ; | 156 | fds->state = MU_STREAM_STATE_READ; |
157 | if (fds->offset != offset) | ||
158 | { | ||
159 | lseek (fds->fd, offset, SEEK_SET); | ||
160 | fds->offset = offset; | ||
161 | } | ||
162 | |||
132 | /* Grossly inefficient hopefully they override this */ | 163 | /* Grossly inefficient hopefully they override this */ |
133 | for (n = 1; n < buf_size; n++) | 164 | for (n = 1; n < buflen; n++) |
134 | { | 165 | { |
135 | nr = read (fds->fd, &c, 1); | 166 | nr = read (fds->fd, &c, 1); |
136 | if (nr == -1) /* Error. */ | 167 | if (nr == -1) /* Error. */ |
... | @@ -151,20 +182,38 @@ _stream_fd_readline (stream_t stream, char *buf, size_t buf_size, size_t *br) | ... | @@ -151,20 +182,38 @@ _stream_fd_readline (stream_t stream, char *buf, size_t buf_size, size_t *br) |
151 | break; /* EOF, some data was read. */ | 182 | break; /* EOF, some data was read. */ |
152 | } | 183 | } |
153 | } | 184 | } |
185 | |||
186 | if (buf) | ||
154 | *buf = '\0'; | 187 | *buf = '\0'; |
188 | fds->offset = (n == buflen) ? n - 1: n; | ||
189 | |||
155 | if (br) | 190 | if (br) |
156 | *br = (n == buf_size) ? n - 1: n; | 191 | *br = (n == buflen) ? n - 1: n; |
157 | return status; | 192 | return status; |
158 | } | 193 | } |
159 | 194 | ||
160 | int | 195 | int |
161 | _stream_fd_write (stream_t stream, const void *buf, size_t buf_size, size_t *bw) | 196 | _stream_fd_write (stream_t stream, const void *buf, size_t buf_size, |
197 | off_t offset, size_t *bw) | ||
162 | { | 198 | { |
163 | struct _stream_fd *fds = (struct _stream_fd *)stream; | 199 | struct _stream_fd *fds = (struct _stream_fd *)stream; |
164 | int bytes = 0; | 200 | int bytes = 0; |
165 | int status = 0; | 201 | int status = 0; |
166 | 202 | ||
203 | if (fds->fd < 0) | ||
204 | { | ||
205 | if (bw) | ||
206 | *bw = 0; | ||
207 | return MU_ERROR_BAD_FILE_DESCRIPTOR; | ||
208 | } | ||
209 | |||
167 | fds->state = MU_STREAM_STATE_WRITE; | 210 | fds->state = MU_STREAM_STATE_WRITE; |
211 | if (fds->offset != offset) | ||
212 | { | ||
213 | lseek (fds->fd, offset, SEEK_SET); | ||
214 | fds->offset = offset; | ||
215 | } | ||
216 | |||
168 | bytes = write (fds->fd, buf, buf_size); | 217 | bytes = write (fds->fd, buf, buf_size); |
169 | if (bytes == -1) | 218 | if (bytes == -1) |
170 | { | 219 | { |
... | @@ -177,38 +226,24 @@ _stream_fd_write (stream_t stream, const void *buf, size_t buf_size, size_t *bw) | ... | @@ -177,38 +226,24 @@ _stream_fd_write (stream_t stream, const void *buf, size_t buf_size, size_t *bw) |
177 | } | 226 | } |
178 | 227 | ||
179 | int | 228 | int |
180 | _stream_fd_seek (stream_t stream, off_t off, enum stream_whence whence) | 229 | _stream_fd_is_seekable (stream_t stream) |
181 | { | 230 | { |
182 | struct _stream_fd *fds = (struct _stream_fd *)stream; | 231 | off_t off; |
183 | int err = 0; | 232 | return _stream_fd_tell (stream, &off) == 0; |
184 | if (fds->fd) | ||
185 | { | ||
186 | if (whence == MU_STREAM_WHENCE_SET) | ||
187 | off = lseek (fds->fd, off, SEEK_SET); | ||
188 | else if (whence == MU_STREAM_WHENCE_CUR) | ||
189 | off = lseek (fds->fd, off, SEEK_CUR); | ||
190 | else if (whence == MU_STREAM_WHENCE_END) | ||
191 | off = lseek (fds->fd, off, SEEK_END); | ||
192 | else | ||
193 | err = MU_ERROR_INVALID_PARAMETER; | ||
194 | if (err == -1) | ||
195 | err = errno; | ||
196 | } | ||
197 | return err; | ||
198 | } | 233 | } |
199 | 234 | ||
200 | int | 235 | int |
201 | _stream_fd_tell (stream_t stream, off_t *off) | 236 | _stream_fd_tell (stream_t stream, off_t *poff) |
202 | { | 237 | { |
203 | struct _stream_fd *fds = (struct _stream_fd *)stream; | 238 | struct _stream_fd *fds = (struct _stream_fd *)stream; |
204 | int err = 0; | 239 | int err = 0; |
205 | if (off) | 240 | if (poff) |
206 | { | 241 | { |
207 | *off = lseek (fds->fd, 0, SEEK_CUR); | 242 | *poff = lseek (fds->fd, 0, SEEK_CUR); |
208 | if (*off == -1) | 243 | if (*poff == -1) |
209 | { | 244 | { |
210 | err = errno; | 245 | err = errno; |
211 | *off = 0; | 246 | *poff = 0; |
212 | } | 247 | } |
213 | } | 248 | } |
214 | return err; | 249 | return err; |
... | @@ -356,7 +391,6 @@ static struct _stream_vtable _stream_fd_vtable = | ... | @@ -356,7 +391,6 @@ static struct _stream_vtable _stream_fd_vtable = |
356 | _stream_fd_readline, | 391 | _stream_fd_readline, |
357 | _stream_fd_write, | 392 | _stream_fd_write, |
358 | 393 | ||
359 | _stream_fd_seek, | ||
360 | _stream_fd_tell, | 394 | _stream_fd_tell, |
361 | 395 | ||
362 | _stream_fd_get_size, | 396 | _stream_fd_get_size, |
... | @@ -367,6 +401,7 @@ static struct _stream_vtable _stream_fd_vtable = | ... | @@ -367,6 +401,7 @@ static struct _stream_vtable _stream_fd_vtable = |
367 | _stream_fd_get_flags, | 401 | _stream_fd_get_flags, |
368 | _stream_fd_get_state, | 402 | _stream_fd_get_state, |
369 | 403 | ||
404 | _stream_fd_is_seekable, | ||
370 | _stream_fd_is_readready, | 405 | _stream_fd_is_readready, |
371 | _stream_fd_is_writeready, | 406 | _stream_fd_is_writeready, |
372 | _stream_fd_is_exceptionpending, | 407 | _stream_fd_is_exceptionpending, |
... | @@ -387,8 +422,10 @@ _stream_fd_ctor (struct _stream_fd *fds, int fd) | ... | @@ -387,8 +422,10 @@ _stream_fd_ctor (struct _stream_fd *fds, int fd) |
387 | } | 422 | } |
388 | 423 | ||
389 | void | 424 | void |
390 | _stream_fd_dtor (struct _stream_fd *fds) | 425 | _stream_fd_dtor (stream_t stream) |
391 | { | 426 | { |
427 | struct _stream_fd *fds = (struct _stream_fd *)stream; | ||
428 | if (fds) | ||
392 | mu_refcount_destroy (&fds->refcount); | 429 | mu_refcount_destroy (&fds->refcount); |
393 | } | 430 | } |
394 | 431 | ... | ... |
... | @@ -53,21 +53,33 @@ _stream_stdio_destroy (stream_t *pstream) | ... | @@ -53,21 +53,33 @@ _stream_stdio_destroy (stream_t *pstream) |
53 | } | 53 | } |
54 | 54 | ||
55 | int | 55 | int |
56 | _stream_stdio_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) | 56 | _stream_stdio_read (stream_t stream, void *optr, size_t osize, |
57 | off_t offset,size_t *nbytes) | ||
57 | { | 58 | { |
58 | struct _stream_stdio *fs = (struct _stream_stdio *)stream; | 59 | struct _stream_stdio *fs = (struct _stream_stdio *)stream; |
59 | size_t n = 0; | 60 | size_t n = 0; |
60 | int err = 0; | 61 | int err = 0; |
61 | 62 | ||
62 | if (fs->file) | 63 | if (!fs->file) |
63 | { | 64 | { |
65 | if (nbytes) | ||
66 | *nbytes = 0; | ||
67 | return MU_ERROR_BAD_FILE_DESCRIPTOR; | ||
68 | } | ||
69 | |||
70 | if (fs->offset != offset) | ||
71 | { | ||
72 | if (fseek (fs->file, offset, SEEK_SET) != 0) | ||
73 | return errno; | ||
74 | fs->offset = offset; | ||
75 | } | ||
76 | |||
64 | n = fread (optr, 1, osize, fs->file); | 77 | n = fread (optr, 1, osize, fs->file); |
65 | if (n == 0) | 78 | if (n == 0) |
66 | { | 79 | { |
67 | if (ferror(fs->file)) | 80 | if (ferror(fs->file)) |
68 | err = MU_ERROR_IO; | 81 | err = MU_ERROR_IO; |
69 | } | 82 | } |
70 | } | ||
71 | 83 | ||
72 | if (nbytes) | 84 | if (nbytes) |
73 | *nbytes = n; | 85 | *nbytes = n; |
... | @@ -75,24 +87,41 @@ _stream_stdio_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) | ... | @@ -75,24 +87,41 @@ _stream_stdio_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) |
75 | } | 87 | } |
76 | 88 | ||
77 | int | 89 | int |
78 | _stream_stdio_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes) | 90 | _stream_stdio_readline (stream_t stream, char *optr, size_t osize, |
91 | off_t offset, size_t *nbytes) | ||
79 | { | 92 | { |
80 | struct _stream_stdio *fs = (struct _stream_stdio *)stream; | 93 | struct _stream_stdio *fs = (struct _stream_stdio *)stream; |
81 | size_t n = 0; | 94 | size_t n = 0; |
82 | int err = 0; | 95 | int err = 0; |
83 | 96 | ||
84 | if (fs->file) | 97 | if (!fs->file) |
85 | { | 98 | { |
99 | if (nbytes) | ||
100 | *nbytes = 0; | ||
101 | return MU_ERROR_BAD_FILE_DESCRIPTOR; | ||
102 | } | ||
103 | |||
104 | if (fs->offset != offset) | ||
105 | { | ||
106 | if (fseek (fs->file, offset, SEEK_SET) != 0) | ||
107 | return errno; | ||
108 | fs->offset = offset; | ||
109 | } | ||
110 | |||
86 | if (fgets (optr, osize, fs->file) != NULL) | 111 | if (fgets (optr, osize, fs->file) != NULL) |
87 | { | 112 | { |
88 | n = strlen (optr); | 113 | n = strlen (optr); |
114 | /* Oh My!! */ | ||
115 | if (n == 0) | ||
116 | n++; | ||
117 | else | ||
118 | fs->offset += n; | ||
89 | } | 119 | } |
90 | else | 120 | else |
91 | { | 121 | { |
92 | if (ferror (fs->file)) | 122 | if (ferror (fs->file)) |
93 | err = MU_ERROR_IO; | 123 | err = MU_ERROR_IO; |
94 | } | 124 | } |
95 | } | ||
96 | 125 | ||
97 | if (nbytes) | 126 | if (nbytes) |
98 | *nbytes = n; | 127 | *nbytes = n; |
... | @@ -100,14 +129,27 @@ _stream_stdio_readline (stream_t stream, char *optr, size_t osize, size_t *nbyte | ... | @@ -100,14 +129,27 @@ _stream_stdio_readline (stream_t stream, char *optr, size_t osize, size_t *nbyte |
100 | } | 129 | } |
101 | 130 | ||
102 | int | 131 | int |
103 | _stream_stdio_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes) | 132 | _stream_stdio_write (stream_t stream, const void *iptr, size_t isize, |
133 | off_t offset, size_t *nbytes) | ||
104 | { | 134 | { |
105 | struct _stream_stdio *fs = (struct _stream_stdio *)stream; | 135 | struct _stream_stdio *fs = (struct _stream_stdio *)stream; |
106 | size_t n = 0; | 136 | size_t n = 0; |
107 | int err = 0; | 137 | int err = 0; |
108 | 138 | ||
109 | if (fs->file) | 139 | if (!fs->file) |
140 | { | ||
141 | if (nbytes) | ||
142 | *nbytes = 0; | ||
143 | return MU_ERROR_BAD_FILE_DESCRIPTOR; | ||
144 | } | ||
145 | |||
146 | if (fs->offset != offset) | ||
110 | { | 147 | { |
148 | if (fseek (fs->file, offset, SEEK_SET) != 0) | ||
149 | return errno; | ||
150 | fs->offset = offset; | ||
151 | } | ||
152 | |||
111 | n = fwrite (iptr, 1, isize, fs->file); | 153 | n = fwrite (iptr, 1, isize, fs->file); |
112 | if (n != isize) | 154 | if (n != isize) |
113 | { | 155 | { |
... | @@ -116,7 +158,8 @@ _stream_stdio_write (stream_t stream, const void *iptr, size_t isize, size_t *nb | ... | @@ -116,7 +158,8 @@ _stream_stdio_write (stream_t stream, const void *iptr, size_t isize, size_t *nb |
116 | clearerr(fs->file); | 158 | clearerr(fs->file); |
117 | n = 0; | 159 | n = 0; |
118 | } | 160 | } |
119 | } | 161 | else |
162 | fs->offset += n; | ||
120 | 163 | ||
121 | if (nbytes) | 164 | if (nbytes) |
122 | *nbytes = n; | 165 | *nbytes = n; |
... | @@ -168,40 +211,37 @@ _stream_stdio_get_fd (stream_t stream, int *pfd) | ... | @@ -168,40 +211,37 @@ _stream_stdio_get_fd (stream_t stream, int *pfd) |
168 | if (fs->file) | 211 | if (fs->file) |
169 | *pfd = fileno (fs->file); | 212 | *pfd = fileno (fs->file); |
170 | else | 213 | else |
171 | status = MU_ERROR_INVALID_PARAMETER; | 214 | status = MU_ERROR_BAD_FILE_DESCRIPTOR; |
172 | } | 215 | } |
173 | return status; | 216 | return status; |
174 | } | 217 | } |
175 | 218 | ||
176 | int | 219 | int |
177 | _stream_stdio_seek (stream_t stream, off_t off, enum stream_whence whence) | 220 | _stream_stdio_is_seekable (stream_t stream) |
178 | { | 221 | { |
179 | struct _stream_stdio *fs = (struct _stream_stdio *)stream; | 222 | off_t off; |
180 | int err = 0; | 223 | return _stream_stdio_tell (stream, &off) == 0; |
181 | if (fs->file) | ||
182 | { | ||
183 | if (whence == MU_STREAM_WHENCE_SET) | ||
184 | err = fseek (fs->file, off, SEEK_SET); | ||
185 | else if (whence == MU_STREAM_WHENCE_CUR) | ||
186 | err = fseek (fs->file, off, SEEK_CUR); | ||
187 | else if (whence == MU_STREAM_WHENCE_END) | ||
188 | err = fseek (fs->file, off, SEEK_END); | ||
189 | else | ||
190 | err = MU_ERROR_INVALID_PARAMETER; | ||
191 | if (err == -1) | ||
192 | err = errno; | ||
193 | } | ||
194 | return err; | ||
195 | } | 224 | } |
196 | 225 | ||
197 | int | 226 | int |
198 | _stream_stdio_tell (stream_t stream, off_t *off) | 227 | _stream_stdio_tell (stream_t stream, off_t *off) |
199 | { | 228 | { |
200 | struct _stream_stdio *fs = (struct _stream_stdio *)stream; | 229 | struct _stream_stdio *fs = (struct _stream_stdio *)stream; |
230 | int status = 0; | ||
201 | if (off == NULL) | 231 | if (off == NULL) |
202 | return MU_ERROR_INVALID_PARAMETER; | 232 | return MU_ERROR_INVALID_PARAMETER; |
203 | *off = (fs->file) ? ftell (fs->file) : 0; | 233 | if (fs->file) |
204 | return 0; | 234 | { |
235 | *off = ftell (fs->file); | ||
236 | if (*off == -1) | ||
237 | { | ||
238 | *off = 0; | ||
239 | status = errno; | ||
240 | } | ||
241 | } | ||
242 | else | ||
243 | status = MU_ERROR_BAD_FILE_DESCRIPTOR; | ||
244 | return status; | ||
205 | } | 245 | } |
206 | 246 | ||
207 | int | 247 | int |
... | @@ -380,7 +420,6 @@ static struct _stream_vtable _stream_stdio_vtable = | ... | @@ -380,7 +420,6 @@ static struct _stream_vtable _stream_stdio_vtable = |
380 | _stream_stdio_readline, | 420 | _stream_stdio_readline, |
381 | _stream_stdio_write, | 421 | _stream_stdio_write, |
382 | 422 | ||
383 | _stream_stdio_seek, | ||
384 | _stream_stdio_tell, | 423 | _stream_stdio_tell, |
385 | 424 | ||
386 | _stream_stdio_get_size, | 425 | _stream_stdio_get_size, |
... | @@ -391,6 +430,7 @@ static struct _stream_vtable _stream_stdio_vtable = | ... | @@ -391,6 +430,7 @@ static struct _stream_vtable _stream_stdio_vtable = |
391 | _stream_stdio_get_flags, | 430 | _stream_stdio_get_flags, |
392 | _stream_stdio_get_state, | 431 | _stream_stdio_get_state, |
393 | 432 | ||
433 | _stream_stdio_is_seekable, | ||
394 | _stream_stdio_is_readready, | 434 | _stream_stdio_is_readready, |
395 | _stream_stdio_is_writeready, | 435 | _stream_stdio_is_writeready, |
396 | _stream_stdio_is_exceptionpending, | 436 | _stream_stdio_is_exceptionpending, |
... | @@ -411,11 +451,15 @@ _stream_stdio_ctor (struct _stream_stdio *fs, FILE *fp) | ... | @@ -411,11 +451,15 @@ _stream_stdio_ctor (struct _stream_stdio *fs, FILE *fp) |
411 | } | 451 | } |
412 | 452 | ||
413 | void | 453 | void |
414 | _stream_stdio_dtor (struct _stream_stdio *fs) | 454 | _stream_stdio_dtor (stream_t stream) |
415 | { | 455 | { |
456 | struct _stream_stdio *fs = (struct _stream_stdio *)stream; | ||
457 | if (fs) | ||
458 | { | ||
416 | mu_refcount_destroy (&fs->refcount); | 459 | mu_refcount_destroy (&fs->refcount); |
417 | /* We may leak if they did not close the FILE * */ | 460 | /* We may leak if they did not close the FILE * */ |
418 | fs->file = NULL; | 461 | fs->file = NULL; |
462 | } | ||
419 | } | 463 | } |
420 | 464 | ||
421 | int | 465 | int | ... | ... |
... | @@ -33,14 +33,14 @@ extern "C" { | ... | @@ -33,14 +33,14 @@ extern "C" { |
33 | struct _attribute; | 33 | struct _attribute; |
34 | typedef struct _attribute * attribute_t; | 34 | typedef struct _attribute * attribute_t; |
35 | 35 | ||
36 | #define MU_ATTRIBUTE_ANSWERED 0x00001 | 36 | #define MU_ATTRIBUTE_ANSWERED 0x000001 |
37 | #define MU_ATTRIBUTE_FLAGGED 0x00002 | 37 | #define MU_ATTRIBUTE_FLAGGED 0x000002 |
38 | #define MU_ATTRIBUTE_DELETED 0x00004 | 38 | #define MU_ATTRIBUTE_DELETED 0x000004 |
39 | #define MU_ATTRIBUTE_DRAFT 0x00008 | 39 | #define MU_ATTRIBUTE_DRAFT 0x000008 |
40 | #define MU_ATTRIBUTE_SEEN 0x00010 | 40 | #define MU_ATTRIBUTE_SEEN 0x000010 |
41 | #define MU_ATTRIBUTE_READ 0x00020 | 41 | #define MU_ATTRIBUTE_READ 0x000020 |
42 | #define MU_ATTRIBUTE_MODIFIED 0x10000 | 42 | #define MU_ATTRIBUTE_MODIFIED 0x100000 |
43 | #define MU_ATTRIBUTE_RECENT 0x00000 | 43 | #define MU_ATTRIBUTE_RECENT 0x000000 |
44 | 44 | ||
45 | extern int attribute_ref __P ((attribute_t)); | 45 | extern int attribute_ref __P ((attribute_t)); |
46 | extern void attribute_destroy __P ((attribute_t *)); | 46 | extern void attribute_destroy __P ((attribute_t *)); |
... | @@ -72,6 +72,12 @@ extern int attribute_unset_recent __P ((attribute_t)); | ... | @@ -72,6 +72,12 @@ extern int attribute_unset_recent __P ((attribute_t)); |
72 | extern int attribute_unset_read __P ((attribute_t)); | 72 | extern int attribute_unset_read __P ((attribute_t)); |
73 | extern int attribute_unset_modified __P ((attribute_t)); | 73 | extern int attribute_unset_modified __P ((attribute_t)); |
74 | 74 | ||
75 | extern int attribute_is_userflags __P ((attribute_t, int)); | ||
76 | extern int attribute_set_userflags __P ((attribute_t, int)); | ||
77 | extern int attribute_unset_userflags __P ((attribute_t, int)); | ||
78 | extern int attribute_get_userflags __P ((attribute_t, int *)); | ||
79 | extern int attribute_clear_userflags __P ((attribute_t)); | ||
80 | |||
75 | 81 | ||
76 | extern int attribute_get_flags __P ((attribute_t, int *)); | 82 | extern int attribute_get_flags __P ((attribute_t, int *)); |
77 | extern int attribute_set_flags __P ((attribute_t, int)); | 83 | extern int attribute_set_flags __P ((attribute_t, int)); | ... | ... |
... | @@ -142,6 +142,11 @@ extern "C" { | ... | @@ -142,6 +142,11 @@ extern "C" { |
142 | # define MU_ERROR_NO_DIRECTORY (MU_ERROR_RANGE + 17) | 142 | # define MU_ERROR_NO_DIRECTORY (MU_ERROR_RANGE + 17) |
143 | #endif | 143 | #endif |
144 | 144 | ||
145 | #if defined (EBADFD) | ||
146 | # define MU_ERROR_BAD_FILE_DESCRIPTOR EBADFD | ||
147 | #else | ||
148 | # define MU_ERROR_BAD_FILE_DESCRIPTOR (MU_ERROR_RANGE + 18) | ||
149 | #endif | ||
145 | 150 | ||
146 | #ifdef __cplusplus | 151 | #ifdef __cplusplus |
147 | } | 152 | } | ... | ... |
... | @@ -20,6 +20,7 @@ | ... | @@ -20,6 +20,7 @@ |
20 | 20 | ||
21 | #include <mailutils/stream.h> | 21 | #include <mailutils/stream.h> |
22 | #include <mailutils/attribute.h> | 22 | #include <mailutils/attribute.h> |
23 | #include <mailutils/debug.h> | ||
23 | 24 | ||
24 | #ifdef __cplusplus | 25 | #ifdef __cplusplus |
25 | extern "C" { | 26 | extern "C" { |
... | @@ -46,12 +47,6 @@ extern int mbox_get_uidnext __P ((mbox_t, unsigned long *)); | ... | @@ -46,12 +47,6 @@ extern int mbox_get_uidnext __P ((mbox_t, unsigned long *)); |
46 | extern int mbox_open __P ((mbox_t, const char *, int)); | 47 | extern int mbox_open __P ((mbox_t, const char *, int)); |
47 | extern int mbox_close __P ((mbox_t)); | 48 | extern int mbox_close __P ((mbox_t)); |
48 | 49 | ||
49 | extern int mbox_get_attribute __P ((mbox_t, unsigned int, attribute_t *)); | ||
50 | extern int mbox_get_uid __P ((mbox_t, unsigned int, unsigned long *)); | ||
51 | |||
52 | extern int mbox_get_separator __P ((mbox_t, unsigned int, char **)); | ||
53 | extern int mbox_set_separator __P ((mbox_t, unsigned int, const char *)); | ||
54 | |||
55 | extern int mbox_get_hstream __P ((mbox_t, unsigned int, stream_t *)); | 50 | extern int mbox_get_hstream __P ((mbox_t, unsigned int, stream_t *)); |
56 | extern int mbox_set_hstream __P ((mbox_t, unsigned int, stream_t)); | 51 | extern int mbox_set_hstream __P ((mbox_t, unsigned int, stream_t)); |
57 | extern int mbox_get_hsize __P ((mbox_t, unsigned int, unsigned int *)); | 52 | extern int mbox_get_hsize __P ((mbox_t, unsigned int, unsigned int *)); |
... | @@ -62,44 +57,42 @@ extern int mbox_set_bstream __P ((mbox_t, unsigned int, stream_t)); | ... | @@ -62,44 +57,42 @@ extern int mbox_set_bstream __P ((mbox_t, unsigned int, stream_t)); |
62 | extern int mbox_get_bsize __P ((mbox_t, unsigned int, unsigned int *)); | 57 | extern int mbox_get_bsize __P ((mbox_t, unsigned int, unsigned int *)); |
63 | extern int mbox_get_blines __P ((mbox_t, unsigned int, unsigned int *)); | 58 | extern int mbox_get_blines __P ((mbox_t, unsigned int, unsigned int *)); |
64 | 59 | ||
60 | extern int mbox_get_attribute __P ((mbox_t, unsigned int, attribute_t *)); | ||
61 | extern int mbox_get_uid __P ((mbox_t, unsigned int, unsigned long *)); | ||
65 | extern int mbox_get_size __P ((mbox_t, off_t *)); | 62 | extern int mbox_get_size __P ((mbox_t, off_t *)); |
63 | extern int mbox_get_separator __P ((mbox_t, unsigned int, char **)); | ||
64 | extern int mbox_set_separator __P ((mbox_t, unsigned int, const char *)); | ||
66 | 65 | ||
67 | extern int mbox_save_attributes __P ((mbox_t)); | ||
68 | extern int mbox_expunge __P ((mbox_t, int)); | 66 | extern int mbox_expunge __P ((mbox_t, int)); |
69 | extern int mbox_has_newmail __P ((mbox_t)); | 67 | extern int mbox_has_newmail __P ((mbox_t)); |
70 | 68 | ||
71 | extern int mbox_set_progress_cb | 69 | extern int mbox_set_progress_cb __P ((mbox_t, |
72 | __P ((mbox_t, int (*) __P ((int, void *)), void *)); | 70 | int (*) __P ((int, void *)), void *)); |
73 | extern int mbox_set_newmsg_cb | 71 | extern int mbox_set_newmsg_cb __P ((mbox_t, |
74 | __P ((mbox_t, int (*) __P ((int, void *)), void *)); | 72 | int (*) __P ((int, void *)), void *)); |
75 | extern int mbox_newmsg_cb __P ((mbox_t, int)); | 73 | extern int mbox_set_error_cb __P ((mbox_t, |
76 | extern int mbox_progress_cb __P ((mbox_t, int)); | 74 | int (*) __P ((int, void *)), void *)); |
77 | 75 | ||
78 | extern int mbox_scan __P ((mbox_t, unsigned int, unsigned int *, int)); | 76 | extern int mbox_scan __P ((mbox_t, unsigned int, |
79 | extern int mbox_messages_count __P ((mbox_t, unsigned int *)); | 77 | unsigned int *, int)); |
80 | 78 | ||
81 | extern int mbox_append __P ((mbox_t, const char *, attribute_t, stream_t)); | 79 | extern int mbox_append __P ((mbox_t, const char *, attribute_t, |
82 | extern int mbox_append_hb | 80 | stream_t)); |
83 | __P ((mbox_t, const char *, attribute_t, stream_t, stream_t)); | 81 | extern int mbox_append_hb __P ((mbox_t, const char *, attribute_t, |
84 | extern int mbox_append_hb0 | 82 | stream_t, stream_t)); |
85 | __P ((mbox_t, const char *, attribute_t, int, stream_t, stream_t)); | ||
86 | 83 | ||
87 | extern int mbox_get_carrier __P ((mbox_t, stream_t *)); | 84 | extern int mbox_get_carrier __P ((mbox_t, stream_t *)); |
88 | extern int mbox_set_carrier __P ((mbox_t, stream_t)); | 85 | extern int mbox_set_carrier __P ((mbox_t, stream_t)); |
89 | 86 | ||
90 | extern int mbox_set_hcache __P ((mbox_t, const char **, size_t)); | 87 | extern int mbox_set_hcache __P ((mbox_t, const char **, size_t)); |
91 | extern int mbox_set_hcache_default __P ((mbox_t)); | 88 | extern int mbox_add_hcache __P ((mbox_t, const char **, size_t)); |
92 | extern void mbox_hcache_free __P ((mbox_t, unsigned int)); | ||
93 | extern int mbox_hcache_append __P ((mbox_t, unsigned int, const char *, | ||
94 | const char *)); | ||
95 | 89 | ||
96 | extern int mbox_header_get_value __P ((mbox_t, unsigned int, const char *, | 90 | extern int mbox_value_hcache __P ((mbox_t, unsigned int, const char *, |
97 | char *, size_t, size_t *)); | 91 | char *, size_t, size_t *)); |
98 | 92 | ||
99 | extern int stream_mbox_create __P ((stream_t *, mbox_t, unsigned int, int)); | 93 | extern int mbox_get_debug __P ((mbox_t, mu_debug_t *)); |
100 | extern int attribute_mbox_create __P ((attribute_t *, mbox_t, unsigned int)); | 94 | extern int mbox_set_debug __P ((mbox_t, mu_debug_t)); |
101 | extern int mbox_attribute_to_status | 95 | |
102 | __P ((attribute_t, char *, size_t, size_t *)); | ||
103 | 96 | ||
104 | #ifdef __cplusplus | 97 | #ifdef __cplusplus |
105 | } | 98 | } | ... | ... |
... | @@ -32,13 +32,6 @@ extern "C" { | ... | @@ -32,13 +32,6 @@ extern "C" { |
32 | #define MU_STREAM_CREAT 0x00000008 | 32 | #define MU_STREAM_CREAT 0x00000008 |
33 | #define MU_STREAM_NONBLOCK 0x00000010 | 33 | #define MU_STREAM_NONBLOCK 0x00000010 |
34 | 34 | ||
35 | enum stream_whence | ||
36 | { | ||
37 | MU_STREAM_WHENCE_SET, | ||
38 | MU_STREAM_WHENCE_CUR, | ||
39 | MU_STREAM_WHENCE_END | ||
40 | }; | ||
41 | |||
42 | enum stream_state | 35 | enum stream_state |
43 | { | 36 | { |
44 | MU_STREAM_NO_STATE, | 37 | MU_STREAM_NO_STATE, |
... | @@ -57,11 +50,10 @@ extern void stream_destroy __P ((stream_t *)); | ... | @@ -57,11 +50,10 @@ extern void stream_destroy __P ((stream_t *)); |
57 | extern int stream_open __P ((stream_t, const char *, int, int)); | 50 | extern int stream_open __P ((stream_t, const char *, int, int)); |
58 | extern int stream_close __P ((stream_t)); | 51 | extern int stream_close __P ((stream_t)); |
59 | 52 | ||
60 | extern int stream_read __P ((stream_t, void *, size_t, size_t *)); | 53 | extern int stream_read __P ((stream_t, void *, size_t, off_t, size_t *)); |
61 | extern int stream_readline __P ((stream_t, char *, size_t, size_t *)); | 54 | extern int stream_readline __P ((stream_t, char *, size_t, off_t, size_t *)); |
62 | extern int stream_write __P ((stream_t, const void *, size_t, size_t*)); | 55 | extern int stream_write __P ((stream_t, const void *, size_t, off_t, size_t*)); |
63 | 56 | ||
64 | extern int stream_seek __P ((stream_t, off_t, enum stream_whence)); | ||
65 | extern int stream_tell __P ((stream_t, off_t *)); | 57 | extern int stream_tell __P ((stream_t, off_t *)); |
66 | 58 | ||
67 | extern int stream_get_size __P ((stream_t, off_t *)); | 59 | extern int stream_get_size __P ((stream_t, off_t *)); |
... | @@ -72,6 +64,7 @@ extern int stream_get_fd __P ((stream_t , int *)); | ... | @@ -72,6 +64,7 @@ extern int stream_get_fd __P ((stream_t , int *)); |
72 | extern int stream_get_flags __P ((stream_t, int *)); | 64 | extern int stream_get_flags __P ((stream_t, int *)); |
73 | extern int stream_get_state __P ((stream_t, enum stream_state *)); | 65 | extern int stream_get_state __P ((stream_t, enum stream_state *)); |
74 | 66 | ||
67 | extern int stream_is_seekable __P ((stream_t)); | ||
75 | extern int stream_is_readready __P ((stream_t, int)); | 68 | extern int stream_is_readready __P ((stream_t, int)); |
76 | extern int stream_is_writeready __P ((stream_t, int)); | 69 | extern int stream_is_writeready __P ((stream_t, int)); |
77 | extern int stream_is_exceptionpending __P ((stream_t, int)); | 70 | extern int stream_is_exceptionpending __P ((stream_t, int)); | ... | ... |
... | @@ -45,6 +45,11 @@ struct _attribute_vtable | ... | @@ -45,6 +45,11 @@ struct _attribute_vtable |
45 | int (*set_flags) __P ((attribute_t, int)); | 45 | int (*set_flags) __P ((attribute_t, int)); |
46 | int (*unset_flags) __P ((attribute_t, int)); | 46 | int (*unset_flags) __P ((attribute_t, int)); |
47 | int (*clear_flags) __P ((attribute_t)); | 47 | int (*clear_flags) __P ((attribute_t)); |
48 | |||
49 | int (*get_userflags) __P ((attribute_t, int *)); | ||
50 | int (*set_userflags) __P ((attribute_t, int)); | ||
51 | int (*unset_userflags) __P ((attribute_t, int)); | ||
52 | int (*clear_userflags) __P ((attribute_t)); | ||
48 | }; | 53 | }; |
49 | 54 | ||
50 | struct _attribute | 55 | struct _attribute | ... | ... |
... | @@ -18,6 +18,10 @@ | ... | @@ -18,6 +18,10 @@ |
18 | #ifndef MAILUTILS_SYS_BSTREAM_H | 18 | #ifndef MAILUTILS_SYS_BSTREAM_H |
19 | #define MAILUTILS_SYS_BSTREAM_H | 19 | #define MAILUTILS_SYS_BSTREAM_H |
20 | 20 | ||
21 | #ifdef DMALLOC | ||
22 | # include <dmalloc.h> | ||
23 | #endif | ||
24 | |||
21 | #include <mailutils/sys/stream.h> | 25 | #include <mailutils/sys/stream.h> |
22 | #include <mailutils/refcount.h> | 26 | #include <mailutils/refcount.h> |
23 | 27 | ||
... | @@ -31,6 +35,7 @@ struct _rbuffer | ... | @@ -31,6 +35,7 @@ struct _rbuffer |
31 | char *base; | 35 | char *base; |
32 | char *ptr; | 36 | char *ptr; |
33 | int count; | 37 | int count; |
38 | off_t offset; | ||
34 | size_t bufsize; | 39 | size_t bufsize; |
35 | }; | 40 | }; |
36 | 41 | ||
... | @@ -43,22 +48,22 @@ struct _stream_buffer | ... | @@ -43,22 +48,22 @@ struct _stream_buffer |
43 | }; | 48 | }; |
44 | 49 | ||
45 | extern int _stream_buffer_ctor __P ((struct _stream_buffer *, stream_t, size_t)); | 50 | extern int _stream_buffer_ctor __P ((struct _stream_buffer *, stream_t, size_t)); |
46 | extern void _stream_buffer_dtor __P ((struct _stream_buffer *)); | 51 | extern void _stream_buffer_dtor __P ((stream_t)); |
47 | extern int _stream_buffer_ref __P ((stream_t)); | 52 | extern int _stream_buffer_ref __P ((stream_t)); |
48 | extern void _stream_buffer_destroy __P ((stream_t *)); | 53 | extern void _stream_buffer_destroy __P ((stream_t *)); |
49 | extern int _stream_buffer_open __P ((stream_t, const char *, int, int)); | 54 | extern int _stream_buffer_open __P ((stream_t, const char *, int, int)); |
50 | extern int _stream_buffer_close __P ((stream_t)); | 55 | extern int _stream_buffer_close __P ((stream_t)); |
51 | extern int _stream_buffer_read __P ((stream_t, void *, size_t, size_t *)); | 56 | extern int _stream_buffer_read __P ((stream_t, void *, size_t, off_t, size_t *)); |
52 | extern int _stream_buffer_readline __P ((stream_t, char *, size_t, size_t *)); | 57 | extern int _stream_buffer_readline __P ((stream_t, char *, size_t, off_t, size_t *)); |
53 | extern int _stream_buffer_write __P ((stream_t, const void *, size_t, size_t *)); | 58 | extern int _stream_buffer_write __P ((stream_t, const void *, size_t, off_t, size_t *)); |
54 | extern int _stream_buffer_get_fd __P ((stream_t, int *)); | 59 | extern int _stream_buffer_get_fd __P ((stream_t, int *)); |
55 | extern int _stream_buffer_get_flags __P ((stream_t, int *)); | 60 | extern int _stream_buffer_get_flags __P ((stream_t, int *)); |
56 | extern int _stream_buffer_get_size __P ((stream_t, off_t *)); | 61 | extern int _stream_buffer_get_size __P ((stream_t, off_t *)); |
57 | extern int _stream_buffer_truncate __P ((stream_t, off_t)); | 62 | extern int _stream_buffer_truncate __P ((stream_t, off_t)); |
58 | extern int _stream_buffer_flush __P ((stream_t)); | 63 | extern int _stream_buffer_flush __P ((stream_t)); |
59 | extern int _stream_buffer_get_state __P ((stream_t, enum stream_state *)); | 64 | extern int _stream_buffer_get_state __P ((stream_t, enum stream_state *)); |
60 | extern int _stream_buffer_seek __P ((stream_t, off_t, enum stream_whence)); | ||
61 | extern int _stream_buffer_tell __P ((stream_t, off_t *)); | 65 | extern int _stream_buffer_tell __P ((stream_t, off_t *)); |
66 | extern int _stream_buffer_is_seekable __P ((stream_t)); | ||
62 | extern int _stream_buffer_is_readready __P ((stream_t, int )); | 67 | extern int _stream_buffer_is_readready __P ((stream_t, int )); |
63 | extern int _stream_buffer_is_writeready __P ((stream_t, int)); | 68 | extern int _stream_buffer_is_writeready __P ((stream_t, int)); |
64 | extern int _stream_buffer_is_exceptionpending __P ((stream_t, int)); | 69 | extern int _stream_buffer_is_exceptionpending __P ((stream_t, int)); | ... | ... |
... | @@ -35,10 +35,11 @@ struct _attribute_default | ... | @@ -35,10 +35,11 @@ struct _attribute_default |
35 | struct _attribute base; | 35 | struct _attribute base; |
36 | mu_refcount_t refcount; | 36 | mu_refcount_t refcount; |
37 | int flags; | 37 | int flags; |
38 | int userflags; | ||
38 | }; | 39 | }; |
39 | 40 | ||
40 | extern int _attribute_default_ctor __P ((struct _attribute_default *)); | 41 | extern int _attribute_default_ctor __P ((struct _attribute_default *)); |
41 | extern void _attribute_default_dtor __P ((struct _attribute_default *)); | 42 | extern void _attribute_default_dtor __P ((attribute_t)); |
42 | extern int _attribute_default_ref __P ((attribute_t)); | 43 | extern int _attribute_default_ref __P ((attribute_t)); |
43 | extern void _attribute_default_destroy __P ((attribute_t *)); | 44 | extern void _attribute_default_destroy __P ((attribute_t *)); |
44 | 45 | ||
... | @@ -47,6 +48,11 @@ extern int _attribute_default_set_flags __P ((attribute_t, int)); | ... | @@ -47,6 +48,11 @@ extern int _attribute_default_set_flags __P ((attribute_t, int)); |
47 | extern int _attribute_default_unset_flags __P ((attribute_t, int)); | 48 | extern int _attribute_default_unset_flags __P ((attribute_t, int)); |
48 | extern int _attribute_default_clear_flags __P ((attribute_t)); | 49 | extern int _attribute_default_clear_flags __P ((attribute_t)); |
49 | 50 | ||
51 | extern int _attribute_default_get_userflags __P ((attribute_t, int *)); | ||
52 | extern int _attribute_default_set_userflags __P ((attribute_t, int)); | ||
53 | extern int _attribute_default_unset_userflags __P ((attribute_t, int)); | ||
54 | extern int _attribute_default_clear_userflags __P ((attribute_t)); | ||
55 | |||
50 | #ifdef __cplusplus | 56 | #ifdef __cplusplus |
51 | } | 57 | } |
52 | #endif | 58 | #endif | ... | ... |
... | @@ -49,7 +49,7 @@ struct _lockfile_dotlock | ... | @@ -49,7 +49,7 @@ struct _lockfile_dotlock |
49 | }; | 49 | }; |
50 | 50 | ||
51 | extern int _lockfile_dotlock_ctor __P ((struct _lockfile_dotlock *, const char *)); | 51 | extern int _lockfile_dotlock_ctor __P ((struct _lockfile_dotlock *, const char *)); |
52 | extern void _lockfile_dotlock_dtor __P ((struct _lockfile_dotlock *)); | 52 | extern void _lockfile_dotlock_dtor __P ((lockfile_t)); |
53 | extern int _lockfile_dotlock_ref __P ((lockfile_t)); | 53 | extern int _lockfile_dotlock_ref __P ((lockfile_t)); |
54 | extern void _lockfile_dotlock_destroy __P ((lockfile_t *)); | 54 | extern void _lockfile_dotlock_destroy __P ((lockfile_t *)); |
55 | 55 | ... | ... |
... | @@ -18,6 +18,10 @@ | ... | @@ -18,6 +18,10 @@ |
18 | #ifndef MAILUTILS_SYS_FDSTREAM_H | 18 | #ifndef MAILUTILS_SYS_FDSTREAM_H |
19 | #define MAILUTILS_SYS_FDSTREAM_H | 19 | #define MAILUTILS_SYS_FDSTREAM_H |
20 | 20 | ||
21 | #ifdef DMALLOC | ||
22 | # include <dmalloc.h> | ||
23 | #endif | ||
24 | |||
21 | #include <mailutils/refcount.h> | 25 | #include <mailutils/refcount.h> |
22 | #include <mailutils/sys/stream.h> | 26 | #include <mailutils/sys/stream.h> |
23 | 27 | ||
... | @@ -32,27 +36,28 @@ struct _stream_fd | ... | @@ -32,27 +36,28 @@ struct _stream_fd |
32 | int fd; | 36 | int fd; |
33 | int state; | 37 | int state; |
34 | int flags; | 38 | int flags; |
39 | off_t offset; | ||
35 | }; | 40 | }; |
36 | 41 | ||
37 | int _stream_fd_ctor __P ((struct _stream_fd *, int)); | 42 | int _stream_fd_ctor __P ((struct _stream_fd *, int)); |
38 | void _stream_fd_dtor __P ((struct _stream_fd *)); | 43 | void _stream_fd_dtor __P ((stream_t)); |
39 | 44 | ||
40 | int _stream_fd_ref __P ((stream_t)); | 45 | int _stream_fd_ref __P ((stream_t)); |
41 | void _stream_fd_destroy __P ((stream_t *)); | 46 | void _stream_fd_destroy __P ((stream_t *)); |
42 | int _stream_fd_open __P ((stream_t, const char *, int, int)); | 47 | int _stream_fd_open __P ((stream_t, const char *, int, int)); |
43 | int _stream_fd_close __P ((stream_t)); | 48 | int _stream_fd_close __P ((stream_t)); |
44 | int _stream_fd_read __P ((stream_t, void *, size_t, size_t *)); | 49 | int _stream_fd_read __P ((stream_t, void *, size_t, off_t, size_t *)); |
45 | int _stream_fd_readline __P ((stream_t, char *, size_t, size_t *)); | 50 | int _stream_fd_readline __P ((stream_t, char *, size_t, off_t, size_t *)); |
46 | int _stream_fd_write __P ((stream_t, const void *, size_t, size_t *)); | 51 | int _stream_fd_write __P ((stream_t, const void *, size_t, off_t, size_t *)); |
47 | int _stream_fd_get_fd __P ((stream_t, int *)); | 52 | int _stream_fd_get_fd __P ((stream_t, int *)); |
48 | int _stream_fd_get_flags __P ((stream_t, int *)); | 53 | int _stream_fd_get_flags __P ((stream_t, int *)); |
49 | int _stream_fd_get_size __P ((stream_t, off_t *)); | 54 | int _stream_fd_get_size __P ((stream_t, off_t *)); |
50 | int _stream_fd_truncate __P ((stream_t, off_t)); | 55 | int _stream_fd_truncate __P ((stream_t, off_t)); |
51 | int _stream_fd_flush __P ((stream_t)); | 56 | int _stream_fd_flush __P ((stream_t)); |
52 | int _stream_fd_get_state __P ((stream_t, enum stream_state *)); | 57 | int _stream_fd_get_state __P ((stream_t, enum stream_state *)); |
53 | int _stream_fd_seek __P ((stream_t, off_t, enum stream_whence)); | ||
54 | int _stream_fd_tell __P ((stream_t, off_t *)); | 58 | int _stream_fd_tell __P ((stream_t, off_t *)); |
55 | int _stream_fd_is_readready __P ((stream_t, int )); | 59 | int _stream_fd_is_seekable __P ((stream_t)); |
60 | int _stream_fd_is_readready __P ((stream_t, int)); | ||
56 | int _stream_fd_is_writeready __P ((stream_t, int)); | 61 | int _stream_fd_is_writeready __P ((stream_t, int)); |
57 | int _stream_fd_is_exceptionpending __P ((stream_t, int)); | 62 | int _stream_fd_is_exceptionpending __P ((stream_t, int)); |
58 | int _stream_fd_is_open __P ((stream_t)); | 63 | int _stream_fd_is_open __P ((stream_t)); | ... | ... |
... | @@ -18,8 +18,11 @@ | ... | @@ -18,8 +18,11 @@ |
18 | #ifndef _MAILUTILS_SYS_FOLDER_H | 18 | #ifndef _MAILUTILS_SYS_FOLDER_H |
19 | #define _MAILUTILS_SYS_FOLDER_H | 19 | #define _MAILUTILS_SYS_FOLDER_H |
20 | 20 | ||
21 | #include <mailutils/folder.h> | 21 | #ifdef DMALLOC |
22 | # include <dmalloc.h> | ||
23 | #endif | ||
22 | 24 | ||
25 | #include <mailutils/folder.h> | ||
23 | 26 | ||
24 | #ifdef __cplusplus | 27 | #ifdef __cplusplus |
25 | extern "C" { | 28 | extern "C" { | ... | ... |
... | @@ -18,6 +18,10 @@ | ... | @@ -18,6 +18,10 @@ |
18 | #ifndef MAILUTILS_SYS_FSTREAM_H | 18 | #ifndef MAILUTILS_SYS_FSTREAM_H |
19 | #define MAILUTILS_SYS_FSTREAM_H | 19 | #define MAILUTILS_SYS_FSTREAM_H |
20 | 20 | ||
21 | #ifdef DMALLOC | ||
22 | # include <dmalloc.h> | ||
23 | #endif | ||
24 | |||
21 | #include <mailutils/sys/stream.h> | 25 | #include <mailutils/sys/stream.h> |
22 | #include <mailutils/refcount.h> | 26 | #include <mailutils/refcount.h> |
23 | 27 | ||
... | @@ -30,27 +34,28 @@ struct _stream_stdio | ... | @@ -30,27 +34,28 @@ struct _stream_stdio |
30 | struct _stream base; | 34 | struct _stream base; |
31 | mu_refcount_t refcount; | 35 | mu_refcount_t refcount; |
32 | int flags; | 36 | int flags; |
37 | off_t offset; | ||
33 | FILE *file; | 38 | FILE *file; |
34 | }; | 39 | }; |
35 | 40 | ||
36 | extern int _stream_stdio_ctor __P ((struct _stream_stdio *, FILE *)); | 41 | extern int _stream_stdio_ctor __P ((struct _stream_stdio *, FILE *)); |
37 | extern void _stream_stdio_dtor __P ((struct _stream_stdio *)); | 42 | extern void _stream_stdio_dtor __P ((stream_t)); |
38 | extern int _stream_stdio_ref __P ((stream_t)); | 43 | extern int _stream_stdio_ref __P ((stream_t)); |
39 | extern void _stream_stdio_destroy __P ((stream_t *)); | 44 | extern void _stream_stdio_destroy __P ((stream_t *)); |
40 | extern int _stream_stdio_open __P ((stream_t, const char *, int, int)); | 45 | extern int _stream_stdio_open __P ((stream_t, const char *, int, int)); |
41 | extern int _stream_stdio_close __P ((stream_t)); | 46 | extern int _stream_stdio_close __P ((stream_t)); |
42 | extern int _stream_stdio_read __P ((stream_t, void *, size_t, size_t *)); | 47 | extern int _stream_stdio_read __P ((stream_t, void *, size_t, off_t, size_t *)); |
43 | extern int _stream_stdio_readline __P ((stream_t, char *, size_t, size_t *)); | 48 | extern int _stream_stdio_readline __P ((stream_t, char *, size_t, off_t, size_t *)); |
44 | extern int _stream_stdio_write __P ((stream_t, const void *, size_t, size_t *)); | 49 | extern int _stream_stdio_write __P ((stream_t, const void *, size_t, off_t, size_t *)); |
45 | extern int _stream_stdio_get_fd __P ((stream_t, int *)); | 50 | extern int _stream_stdio_get_fd __P ((stream_t, int *)); |
46 | extern int _stream_stdio_get_flags __P ((stream_t, int *)); | 51 | extern int _stream_stdio_get_flags __P ((stream_t, int *)); |
47 | extern int _stream_stdio_get_size __P ((stream_t, off_t *)); | 52 | extern int _stream_stdio_get_size __P ((stream_t, off_t *)); |
48 | extern int _stream_stdio_truncate __P ((stream_t, off_t)); | 53 | extern int _stream_stdio_truncate __P ((stream_t, off_t)); |
49 | extern int _stream_stdio_flush __P ((stream_t)); | 54 | extern int _stream_stdio_flush __P ((stream_t)); |
50 | extern int _stream_stdio_get_state __P ((stream_t, enum stream_state *)); | 55 | extern int _stream_stdio_get_state __P ((stream_t, enum stream_state *)); |
51 | extern int _stream_stdio_seek __P ((stream_t, off_t, enum stream_whence)); | ||
52 | extern int _stream_stdio_tell __P ((stream_t, off_t *)); | 56 | extern int _stream_stdio_tell __P ((stream_t, off_t *)); |
53 | extern int _stream_stdio_is_readready __P ((stream_t, int )); | 57 | extern int _stream_stdio_is_seekable __P ((stream_t)); |
58 | extern int _stream_stdio_is_readready __P ((stream_t, int)); | ||
54 | extern int _stream_stdio_is_writeready __P ((stream_t, int)); | 59 | extern int _stream_stdio_is_writeready __P ((stream_t, int)); |
55 | extern int _stream_stdio_is_exceptionpending __P ((stream_t, int)); | 60 | extern int _stream_stdio_is_exceptionpending __P ((stream_t, int)); |
56 | extern int _stream_stdio_is_open __P ((stream_t)); | 61 | extern int _stream_stdio_is_open __P ((stream_t)); | ... | ... |
... | @@ -18,6 +18,10 @@ | ... | @@ -18,6 +18,10 @@ |
18 | #ifndef _MAILUTILS_SYS_HEADER_H | 18 | #ifndef _MAILUTILS_SYS_HEADER_H |
19 | #define _MAILUTILS_SYS_HEADER_H | 19 | #define _MAILUTILS_SYS_HEADER_H |
20 | 20 | ||
21 | #ifdef DMALLOC | ||
22 | # include <dmalloc.h> | ||
23 | #endif | ||
24 | |||
21 | #include <mailutils/header.h> | 25 | #include <mailutils/header.h> |
22 | 26 | ||
23 | #ifndef __P | 27 | #ifndef __P | ... | ... |
... | @@ -18,6 +18,10 @@ | ... | @@ -18,6 +18,10 @@ |
18 | #ifndef _MAILUTILS_SYS_ITERATOR_H | 18 | #ifndef _MAILUTILS_SYS_ITERATOR_H |
19 | #define _MAILUTILS_SYS_ITERATOR_H | 19 | #define _MAILUTILS_SYS_ITERATOR_H |
20 | 20 | ||
21 | #ifdef DMALLOC | ||
22 | # include <dmalloc.h> | ||
23 | #endif | ||
24 | |||
21 | #include <mailutils/iterator.h> | 25 | #include <mailutils/iterator.h> |
22 | 26 | ||
23 | #ifdef __cplusplus | 27 | #ifdef __cplusplus | ... | ... |
... | @@ -18,6 +18,10 @@ | ... | @@ -18,6 +18,10 @@ |
18 | #ifndef _MAILUTILS_SYS_MAILBOX_H | 18 | #ifndef _MAILUTILS_SYS_MAILBOX_H |
19 | #define _MAILUTILS_SYS_MAILBOX_H | 19 | #define _MAILUTILS_SYS_MAILBOX_H |
20 | 20 | ||
21 | #ifdef DMALLOC | ||
22 | # include <dmalloc.h> | ||
23 | #endif | ||
24 | |||
21 | #include <mailutils/mailbox.h> | 25 | #include <mailutils/mailbox.h> |
22 | 26 | ||
23 | #ifdef __cplusplus | 27 | #ifdef __cplusplus | ... | ... |
... | @@ -20,6 +20,10 @@ | ... | @@ -20,6 +20,10 @@ |
20 | 20 | ||
21 | #include <unistd.h> | 21 | #include <unistd.h> |
22 | 22 | ||
23 | #ifdef DMALLOC | ||
24 | # include <dmalloc.h> | ||
25 | #endif | ||
26 | |||
23 | #include <mailutils/sys/stream.h> | 27 | #include <mailutils/sys/stream.h> |
24 | #include <mailutils/refcount.h> | 28 | #include <mailutils/refcount.h> |
25 | 29 | ||
... | @@ -38,27 +42,26 @@ struct _stream_mmap | ... | @@ -38,27 +42,26 @@ struct _stream_mmap |
38 | int mflags; | 42 | int mflags; |
39 | char *ptr; | 43 | char *ptr; |
40 | size_t size; | 44 | size_t size; |
41 | off_t offset; | ||
42 | }; | 45 | }; |
43 | 46 | ||
44 | extern int _stream_mmap_ctor __P ((struct _stream_mmap *)); | 47 | extern int _stream_mmap_ctor __P ((struct _stream_mmap *)); |
45 | extern void _stream_mmap_dtor __P ((struct _stream_mmap *)); | 48 | extern void _stream_mmap_dtor __P ((stream_t)); |
46 | extern int _stream_mmap_ref __P ((stream_t)); | 49 | extern int _stream_mmap_ref __P ((stream_t)); |
47 | extern void _stream_mmap_destroy __P ((stream_t *)); | 50 | extern void _stream_mmap_destroy __P ((stream_t *)); |
48 | extern int _stream_mmap_open __P ((stream_t, const char *, int, int)); | 51 | extern int _stream_mmap_open __P ((stream_t, const char *, int, int)); |
49 | extern int _stream_mmap_close __P ((stream_t)); | 52 | extern int _stream_mmap_close __P ((stream_t)); |
50 | extern int _stream_mmap_read __P ((stream_t, void *, size_t, size_t *)); | 53 | extern int _stream_mmap_read __P ((stream_t, void *, size_t, off_t, size_t *)); |
51 | extern int _stream_mmap_readline __P ((stream_t, char *, size_t, size_t *)); | 54 | extern int _stream_mmap_readline __P ((stream_t, char *, size_t, off_t, size_t *)); |
52 | extern int _stream_mmap_write __P ((stream_t, const void *, size_t, size_t *)); | 55 | extern int _stream_mmap_write __P ((stream_t, const void *, size_t, off_t, size_t *)); |
53 | extern int _stream_mmap_get_fd __P ((stream_t, int *)); | 56 | extern int _stream_mmap_get_fd __P ((stream_t, int *)); |
54 | extern int _stream_mmap_get_flags __P ((stream_t, int *)); | 57 | extern int _stream_mmap_get_flags __P ((stream_t, int *)); |
55 | extern int _stream_mmap_get_size __P ((stream_t, off_t *)); | 58 | extern int _stream_mmap_get_size __P ((stream_t, off_t *)); |
56 | extern int _stream_mmap_truncate __P ((stream_t, off_t)); | 59 | extern int _stream_mmap_truncate __P ((stream_t, off_t)); |
57 | extern int _stream_mmap_flush __P ((stream_t)); | 60 | extern int _stream_mmap_flush __P ((stream_t)); |
58 | extern int _stream_mmap_get_state __P ((stream_t, enum stream_state *)); | 61 | extern int _stream_mmap_get_state __P ((stream_t, enum stream_state *)); |
59 | extern int _stream_mmap_seek __P ((stream_t, off_t, enum stream_whence)); | ||
60 | extern int _stream_mmap_tell __P ((stream_t, off_t *)); | 62 | extern int _stream_mmap_tell __P ((stream_t, off_t *)); |
61 | extern int _stream_mmap_is_readready __P ((stream_t, int )); | 63 | extern int _stream_mmap_is_seekable __P ((stream_t)); |
64 | extern int _stream_mmap_is_readready __P ((stream_t, int)); | ||
62 | extern int _stream_mmap_is_writeready __P ((stream_t, int)); | 65 | extern int _stream_mmap_is_writeready __P ((stream_t, int)); |
63 | extern int _stream_mmap_is_exceptionpending __P ((stream_t, int)); | 66 | extern int _stream_mmap_is_exceptionpending __P ((stream_t, int)); |
64 | extern int _stream_mmap_is_open __P ((stream_t)); | 67 | extern int _stream_mmap_is_open __P ((stream_t)); | ... | ... |
... | @@ -19,9 +19,18 @@ | ... | @@ -19,9 +19,18 @@ |
19 | #define _MAILUTILS_SYS_MBOX_H | 19 | #define _MAILUTILS_SYS_MBOX_H |
20 | 20 | ||
21 | #include <time.h> | 21 | #include <time.h> |
22 | #include <stdarg.h> | ||
23 | |||
24 | #ifdef DMALLOC | ||
25 | # include <dmalloc.h> | ||
26 | #endif | ||
27 | |||
22 | #include <mailutils/lockfile.h> | 28 | #include <mailutils/lockfile.h> |
23 | #include <mailutils/mbox.h> | 29 | #include <mailutils/mbox.h> |
24 | 30 | ||
31 | #define MU_MBOX_HSTREAM_SET 0x010000 | ||
32 | #define MU_MBOX_BSTREAM_SET 0x001000 | ||
33 | |||
25 | #ifdef __cplusplus | 34 | #ifdef __cplusplus |
26 | extern "C" { | 35 | extern "C" { |
27 | #endif | 36 | #endif |
... | @@ -49,6 +58,7 @@ struct _mbox | ... | @@ -49,6 +58,7 @@ struct _mbox |
49 | stream_t carrier; /* File stream. */ | 58 | stream_t carrier; /* File stream. */ |
50 | 59 | ||
51 | off_t size; /* Size of the mailbox. */ | 60 | off_t size; /* Size of the mailbox. */ |
61 | mu_debug_t debug; | ||
52 | unsigned long uidvalidity; | 62 | unsigned long uidvalidity; |
53 | unsigned long uidnext; | 63 | unsigned long uidnext; |
54 | char *filename; | 64 | char *filename; |
... | @@ -69,7 +79,10 @@ struct _mbox | ... | @@ -69,7 +79,10 @@ struct _mbox |
69 | { | 79 | { |
70 | int (*cb) __P ((int, void *)); | 80 | int (*cb) __P ((int, void *)); |
71 | void *arg; | 81 | void *arg; |
72 | } newmsg, progress, corrupt; | 82 | } newmsg, progress, error; |
83 | |||
84 | /* Hold the offset of the stream when appending. */ | ||
85 | off_t roffset, woffset; | ||
73 | }; | 86 | }; |
74 | 87 | ||
75 | /* Keep the file positions of where the headers and bodies start and end. | 88 | /* Keep the file positions of where the headers and bodies start and end. |
... | @@ -96,9 +109,40 @@ struct _mbox_message | ... | @@ -96,9 +109,40 @@ struct _mbox_message |
96 | /* UID i.e. see IMAP */ | 109 | /* UID i.e. see IMAP */ |
97 | unsigned long uid; | 110 | unsigned long uid; |
98 | unsigned int attr_flags; | 111 | unsigned int attr_flags; |
112 | unsigned int attr_userflags; | ||
99 | attribute_t attribute; /* The attr_flags contains the "Status:" attribute */ | 113 | attribute_t attribute; /* The attr_flags contains the "Status:" attribute */ |
100 | }; | 114 | }; |
101 | 115 | ||
116 | extern int mbox_newmsg_cb __P ((mbox_t, int)); | ||
117 | extern int mbox_progress_cb __P ((mbox_t, int)); | ||
118 | extern int mbox_error_cb __P ((mbox_t, int)); | ||
119 | |||
120 | extern int mbox_append_hb0 __P ((mbox_t, const char *, attribute_t, | ||
121 | stream_t, stream_t, int, unsigned long)); | ||
122 | |||
123 | extern void mbox_release_hcache __P ((mbox_t, unsigned int)); | ||
124 | extern int mbox_append_hcache __P ((mbox_t, unsigned int, const char *, | ||
125 | const char *)); | ||
126 | extern int mbox_set_default_hcache __P ((mbox_t)); | ||
127 | |||
128 | extern int mbox_debug_print __P ((mbox_t, const char *, ...)); | ||
129 | |||
130 | extern int stream_mbox_create __P ((stream_t *, mbox_t, unsigned int, int)); | ||
131 | extern int stream_mbox_msgno __P ((stream_t, unsigned int)); | ||
132 | extern void _stream_mbox_dtor __P ((stream_t)); | ||
133 | |||
134 | extern int attribute_mbox_create __P ((attribute_t *, mbox_t, unsigned int)); | ||
135 | extern int attribute_mbox_msgno __P ((attribute_t, unsigned int)); | ||
136 | extern int mbox_attribute_to_status __P ((attribute_t, char *, size_t, | ||
137 | size_t *)); | ||
138 | extern void _attribute_mbox_dtor __P ((attribute_t)); | ||
139 | |||
140 | extern void mbox_release_separator __P ((mbox_t, unsigned int)); | ||
141 | extern void mbox_release_attribute __P ((mbox_t, unsigned int)); | ||
142 | extern void mbox_release_hstream __P ((mbox_t, unsigned int)); | ||
143 | extern void mbox_release_bstream __P ((mbox_t, unsigned int)); | ||
144 | extern void mbox_release_msg __P ((mbox_t, unsigned int)); | ||
145 | |||
102 | #ifdef __cplusplus | 146 | #ifdef __cplusplus |
103 | } | 147 | } |
104 | #endif | 148 | #endif | ... | ... |
... | @@ -20,6 +20,10 @@ | ... | @@ -20,6 +20,10 @@ |
20 | 20 | ||
21 | #include <sys/types.h> | 21 | #include <sys/types.h> |
22 | 22 | ||
23 | #ifdef DMALLOC | ||
24 | # include <dmalloc.h> | ||
25 | #endif | ||
26 | |||
23 | #include <mailutils/refcount.h> | 27 | #include <mailutils/refcount.h> |
24 | #include <mailutils/sys/stream.h> | 28 | #include <mailutils/sys/stream.h> |
25 | 29 | ||
... | @@ -38,27 +42,26 @@ struct _stream_memory | ... | @@ -38,27 +42,26 @@ struct _stream_memory |
38 | char *ptr; | 42 | char *ptr; |
39 | size_t capacity; | 43 | size_t capacity; |
40 | size_t size; | 44 | size_t size; |
41 | off_t offset; | ||
42 | int flags; | 45 | int flags; |
43 | }; | 46 | }; |
44 | 47 | ||
45 | extern int _stream_memory_ctor __P ((struct _stream_memory *, size_t)); | 48 | extern int _stream_memory_ctor __P ((struct _stream_memory *, size_t)); |
46 | extern void _stream_memory_dtor __P ((struct _stream_memory *)); | 49 | extern void _stream_memory_dtor __P ((stream_t)); |
47 | extern int _stream_memory_ref __P ((stream_t)); | 50 | extern int _stream_memory_ref __P ((stream_t)); |
48 | extern void _stream_memory_destroy __P ((stream_t *)); | 51 | extern void _stream_memory_destroy __P ((stream_t *)); |
49 | extern int _stream_memory_open __P ((stream_t, const char *, int, int)); | 52 | extern int _stream_memory_open __P ((stream_t, const char *, int, int)); |
50 | extern int _stream_memory_close __P ((stream_t)); | 53 | extern int _stream_memory_close __P ((stream_t)); |
51 | extern int _stream_memory_read __P ((stream_t, void *, size_t, size_t *)); | 54 | extern int _stream_memory_read __P ((stream_t, void *, size_t, off_t, size_t *)); |
52 | extern int _stream_memory_readline __P ((stream_t, char *, size_t, size_t *)); | 55 | extern int _stream_memory_readline __P ((stream_t, char *, size_t, off_t, size_t *)); |
53 | extern int _stream_memory_write __P ((stream_t, const void *, size_t, size_t *)); | 56 | extern int _stream_memory_write __P ((stream_t, const void *, size_t, off_t, size_t *)); |
54 | extern int _stream_memory_get_fd __P ((stream_t, int *)); | 57 | extern int _stream_memory_get_fd __P ((stream_t, int *)); |
55 | extern int _stream_memory_get_flags __P ((stream_t, int *)); | 58 | extern int _stream_memory_get_flags __P ((stream_t, int *)); |
56 | extern int _stream_memory_get_size __P ((stream_t, off_t *)); | 59 | extern int _stream_memory_get_size __P ((stream_t, off_t *)); |
57 | extern int _stream_memory_truncate __P ((stream_t, off_t)); | 60 | extern int _stream_memory_truncate __P ((stream_t, off_t)); |
58 | extern int _stream_memory_flush __P ((stream_t)); | 61 | extern int _stream_memory_flush __P ((stream_t)); |
59 | extern int _stream_memory_get_state __P ((stream_t, enum stream_state *)); | 62 | extern int _stream_memory_get_state __P ((stream_t, enum stream_state *)); |
60 | extern int _stream_memory_seek __P ((stream_t, off_t, enum stream_whence)); | ||
61 | extern int _stream_memory_tell __P ((stream_t, off_t *)); | 63 | extern int _stream_memory_tell __P ((stream_t, off_t *)); |
64 | extern int _stream_memory_is_seekable __P ((stream_t)); | ||
62 | extern int _stream_memory_is_readready __P ((stream_t, int )); | 65 | extern int _stream_memory_is_readready __P ((stream_t, int )); |
63 | extern int _stream_memory_is_writeready __P ((stream_t, int)); | 66 | extern int _stream_memory_is_writeready __P ((stream_t, int)); |
64 | extern int _stream_memory_is_exceptionpending __P ((stream_t, int)); | 67 | extern int _stream_memory_is_exceptionpending __P ((stream_t, int)); | ... | ... |
... | @@ -18,6 +18,10 @@ | ... | @@ -18,6 +18,10 @@ |
18 | #ifndef _MAILUTILS_SYS_MESSAGE_H | 18 | #ifndef _MAILUTILS_SYS_MESSAGE_H |
19 | #define _MAILUTILS_SYS_MESSAGE_H | 19 | #define _MAILUTILS_SYS_MESSAGE_H |
20 | 20 | ||
21 | #ifdef DMALLOC | ||
22 | # include <dmalloc.h> | ||
23 | #endif | ||
24 | |||
21 | #include <mailutils/message.h> | 25 | #include <mailutils/message.h> |
22 | 26 | ||
23 | #ifndef __P | 27 | #ifndef __P | ... | ... |
... | @@ -102,6 +102,7 @@ struct _pop3 | ... | @@ -102,6 +102,7 @@ struct _pop3 |
102 | 102 | ||
103 | enum pop3_state state; | 103 | enum pop3_state state; |
104 | stream_t carrier; /* TCP Connection. */ | 104 | stream_t carrier; /* TCP Connection. */ |
105 | off_t offset; /* To synchronise with the buffering. */ | ||
105 | mu_debug_t debug; /* Send the debug info. */ | 106 | mu_debug_t debug; /* Send the debug info. */ |
106 | }; | 107 | }; |
107 | 108 | ... | ... |
... | @@ -18,6 +18,10 @@ | ... | @@ -18,6 +18,10 @@ |
18 | #ifndef _MAILUTILS_SYS_PTICKET_H | 18 | #ifndef _MAILUTILS_SYS_PTICKET_H |
19 | #define _MAILUTILS_SYS_PTICKET_H | 19 | #define _MAILUTILS_SYS_PTICKET_H |
20 | 20 | ||
21 | #ifdef DMALLOC | ||
22 | # include <dmalloc.h> | ||
23 | #endif | ||
24 | |||
21 | #include <mailutils/sys/ticket.h> | 25 | #include <mailutils/sys/ticket.h> |
22 | 26 | ||
23 | #ifdef __cplusplus | 27 | #ifdef __cplusplus |
... | @@ -31,7 +35,7 @@ struct _ticket_prompt | ... | @@ -31,7 +35,7 @@ struct _ticket_prompt |
31 | }; | 35 | }; |
32 | 36 | ||
33 | extern int _ticket_prompt_ctor __P ((struct _ticket_prompt *)); | 37 | extern int _ticket_prompt_ctor __P ((struct _ticket_prompt *)); |
34 | extern void _ticket_prompt_dtor __P ((struct _ticket_prompt *)); | 38 | extern void _ticket_prompt_dtor __P ((ticket_t)); |
35 | extern int _ticket_prompt_ref __P ((ticket_t)); | 39 | extern int _ticket_prompt_ref __P ((ticket_t)); |
36 | extern void _ticket_prompt_destroy __P ((ticket_t *)); | 40 | extern void _ticket_prompt_destroy __P ((ticket_t *)); |
37 | extern int _ticket_prompt_pop __P ((ticket_t, const char *, char **)); | 41 | extern int _ticket_prompt_pop __P ((ticket_t, const char *, char **)); | ... | ... |
... | @@ -34,12 +34,13 @@ struct _mu_debug_stream | ... | @@ -34,12 +34,13 @@ struct _mu_debug_stream |
34 | struct _mu_debug base; | 34 | struct _mu_debug base; |
35 | mu_refcount_t refcount; | 35 | mu_refcount_t refcount; |
36 | int level; | 36 | int level; |
37 | off_t offset; | ||
37 | stream_t stream; | 38 | stream_t stream; |
38 | int close_on_destroy; | 39 | int close_on_destroy; |
39 | }; | 40 | }; |
40 | 41 | ||
41 | int _mu_debug_stream_ctor __P ((struct _mu_debug_stream *)); | 42 | int _mu_debug_stream_ctor __P ((struct _mu_debug_stream *)); |
42 | int _mu_debug_stream_dtor __P ((struct _mu_debug_stream *)); | 43 | int _mu_debug_stream_dtor __P ((mu_debug_t)); |
43 | int _mu_debug_stream_ref __P ((mu_debug_t)); | 44 | int _mu_debug_stream_ref __P ((mu_debug_t)); |
44 | void _mu_debug_stream_destroy __P ((mu_debug_t *)); | 45 | void _mu_debug_stream_destroy __P ((mu_debug_t *)); |
45 | int _mu_debug_stream_set_level __P ((mu_debug_t, size_t)); | 46 | int _mu_debug_stream_set_level __P ((mu_debug_t, size_t)); | ... | ... |
... | @@ -18,6 +18,10 @@ | ... | @@ -18,6 +18,10 @@ |
18 | #ifndef _MAILUTILS_SYS_STREAM_H | 18 | #ifndef _MAILUTILS_SYS_STREAM_H |
19 | #define _MAILUTILS_SYS_STREAM_H | 19 | #define _MAILUTILS_SYS_STREAM_H |
20 | 20 | ||
21 | #ifdef DMALLOC | ||
22 | # include <dmalloc.h> | ||
23 | #endif | ||
24 | |||
21 | #include <mailutils/stream.h> | 25 | #include <mailutils/stream.h> |
22 | 26 | ||
23 | #ifdef __cplusplus | 27 | #ifdef __cplusplus |
... | @@ -32,11 +36,10 @@ struct _stream_vtable | ... | @@ -32,11 +36,10 @@ struct _stream_vtable |
32 | int (*open) __P ((stream_t, const char *, int, int)); | 36 | int (*open) __P ((stream_t, const char *, int, int)); |
33 | int (*close) __P ((stream_t)); | 37 | int (*close) __P ((stream_t)); |
34 | 38 | ||
35 | int (*read) __P ((stream_t, void *, size_t, size_t *)); | 39 | int (*read) __P ((stream_t, void *, size_t, off_t, size_t *)); |
36 | int (*readline) __P ((stream_t, char *, size_t, size_t *)); | 40 | int (*readline) __P ((stream_t, char *, size_t, off_t, size_t *)); |
37 | int (*write) __P ((stream_t, const void *, size_t, size_t *)); | 41 | int (*write) __P ((stream_t, const void *, size_t, off_t, size_t *)); |
38 | 42 | ||
39 | int (*seek) __P ((stream_t, off_t, enum stream_whence)); | ||
40 | int (*tell) __P ((stream_t, off_t *)); | 43 | int (*tell) __P ((stream_t, off_t *)); |
41 | 44 | ||
42 | int (*get_size) __P ((stream_t, off_t *)); | 45 | int (*get_size) __P ((stream_t, off_t *)); |
... | @@ -47,6 +50,7 @@ struct _stream_vtable | ... | @@ -47,6 +50,7 @@ struct _stream_vtable |
47 | int (*get_flags) __P ((stream_t, int *)); | 50 | int (*get_flags) __P ((stream_t, int *)); |
48 | int (*get_state) __P ((stream_t, enum stream_state *)); | 51 | int (*get_state) __P ((stream_t, enum stream_state *)); |
49 | 52 | ||
53 | int (*is_seekable) __P ((stream_t)); | ||
50 | int (*is_readready) __P ((stream_t, int)); | 54 | int (*is_readready) __P ((stream_t, int)); |
51 | int (*is_writeready) __P ((stream_t, int)); | 55 | int (*is_writeready) __P ((stream_t, int)); |
52 | int (*is_exceptionpending) __P ((stream_t, int)); | 56 | int (*is_exceptionpending) __P ((stream_t, int)); | ... | ... |
... | @@ -18,6 +18,10 @@ | ... | @@ -18,6 +18,10 @@ |
18 | #ifndef MAILUTILS_SYS_TCP_H | 18 | #ifndef MAILUTILS_SYS_TCP_H |
19 | #define MAILUTILS_SYS_TCP_H | 19 | #define MAILUTILS_SYS_TCP_H |
20 | 20 | ||
21 | #ifdef DMALLOC | ||
22 | # include <dmalloc.h> | ||
23 | #endif | ||
24 | |||
21 | #include <mailutils/refcount.h> | 25 | #include <mailutils/refcount.h> |
22 | #include <mailutils/sys/fdstream.h> | 26 | #include <mailutils/sys/fdstream.h> |
23 | 27 | ... | ... |
... | @@ -171,7 +171,7 @@ mu_list_remove (mu_list_t list, void *item) | ... | @@ -171,7 +171,7 @@ mu_list_remove (mu_list_t list, void *item) |
171 | } | 171 | } |
172 | 172 | ||
173 | int | 173 | int |
174 | mu_list_get (mu_list_t list, size_t index, void **pitem) | 174 | mu_list_get (mu_list_t list, size_t indx, void **pitem) |
175 | { | 175 | { |
176 | struct mu_list_data *current; | 176 | struct mu_list_data *current; |
177 | size_t count; | 177 | size_t count; |
... | @@ -182,7 +182,7 @@ mu_list_get (mu_list_t list, size_t index, void **pitem) | ... | @@ -182,7 +182,7 @@ mu_list_get (mu_list_t list, size_t index, void **pitem) |
182 | for (current = list->head.next, count = 0; current != &(list->head); | 182 | for (current = list->head.next, count = 0; current != &(list->head); |
183 | current = current->next, count++) | 183 | current = current->next, count++) |
184 | { | 184 | { |
185 | if (count == index) | 185 | if (count == indx) |
186 | { | 186 | { |
187 | *pitem = current->item; | 187 | *pitem = current->item; |
188 | status = 0; | 188 | status = 0; | ... | ... |
... | @@ -59,7 +59,8 @@ _stream_mmap_destroy (stream_t *pstream) | ... | @@ -59,7 +59,8 @@ _stream_mmap_destroy (stream_t *pstream) |
59 | } | 59 | } |
60 | 60 | ||
61 | int | 61 | int |
62 | _stream_mmap_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) | 62 | _stream_mmap_read (stream_t stream, void *optr, size_t osize, |
63 | off_t offset, size_t *nbytes) | ||
63 | { | 64 | { |
64 | struct _stream_mmap *ms = (struct _stream_mmap *)stream; | 65 | struct _stream_mmap *ms = (struct _stream_mmap *)stream; |
65 | size_t n = 0; | 66 | size_t n = 0; |
... | @@ -67,12 +68,10 @@ _stream_mmap_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) | ... | @@ -67,12 +68,10 @@ _stream_mmap_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) |
67 | mu_refcount_lock (ms->refcount); | 68 | mu_refcount_lock (ms->refcount); |
68 | if (ms->ptr != MAP_FAILED && ms->ptr) | 69 | if (ms->ptr != MAP_FAILED && ms->ptr) |
69 | { | 70 | { |
70 | if (ms->offset < (off_t)ms->size) | 71 | if (offset < (off_t)ms->size) |
71 | { | 72 | { |
72 | n = ((ms->offset + osize) > ms->size) ? | 73 | n = ((offset + osize) > ms->size) ? ms->size - offset : osize; |
73 | ms->size - ms->offset : osize; | 74 | memcpy (optr, ms->ptr + offset, n); |
74 | memcpy (optr, ms->ptr + ms->offset, n); | ||
75 | ms->offset += n; | ||
76 | } | 75 | } |
77 | } | 76 | } |
78 | mu_refcount_unlock (ms->refcount); | 77 | mu_refcount_unlock (ms->refcount); |
... | @@ -83,7 +82,8 @@ _stream_mmap_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) | ... | @@ -83,7 +82,8 @@ _stream_mmap_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) |
83 | } | 82 | } |
84 | 83 | ||
85 | int | 84 | int |
86 | _stream_mmap_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes) | 85 | _stream_mmap_readline (stream_t stream, char *optr, size_t osize, |
86 | off_t offset, size_t *nbytes) | ||
87 | { | 87 | { |
88 | struct _stream_mmap *ms = (struct _stream_mmap *)stream; | 88 | struct _stream_mmap *ms = (struct _stream_mmap *)stream; |
89 | size_t n = 0; | 89 | size_t n = 0; |
... | @@ -91,17 +91,17 @@ _stream_mmap_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes | ... | @@ -91,17 +91,17 @@ _stream_mmap_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes |
91 | mu_refcount_lock (ms->refcount); | 91 | mu_refcount_lock (ms->refcount); |
92 | if (ms->ptr != MAP_FAILED && ms->ptr) | 92 | if (ms->ptr != MAP_FAILED && ms->ptr) |
93 | { | 93 | { |
94 | if (ms->offset < (off_t)ms->size) | 94 | if (offset < (off_t)ms->size) |
95 | { | 95 | { |
96 | /* Save space for the null byte. */ | 96 | /* Save space for the null byte. */ |
97 | char *nl; | 97 | char *nl; |
98 | osize--; | 98 | osize--; |
99 | nl = memchr (ms->ptr + ms->offset, '\n', ms->size - ms->offset); | 99 | nl = memchr (ms->ptr + offset, '\n', ms->size - offset); |
100 | n = (nl) ? nl - (ms->ptr + ms->offset) + 1 : ms->size - ms->offset; | 100 | n = (nl) ? (size_t)(nl - (ms->ptr + offset) + 1) : ms->size - offset; |
101 | n = (n > osize) ? osize : n; | 101 | n = (n > osize) ? osize : n; |
102 | memcpy (optr, ms->ptr + ms->offset, n); | 102 | memcpy (optr, ms->ptr + offset, n); |
103 | optr[n] = '\0'; | 103 | optr[n] = '\0'; |
104 | ms->offset += n; | 104 | offset += n; |
105 | } | 105 | } |
106 | } | 106 | } |
107 | mu_refcount_unlock (ms->refcount); | 107 | mu_refcount_unlock (ms->refcount); |
... | @@ -112,7 +112,8 @@ _stream_mmap_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes | ... | @@ -112,7 +112,8 @@ _stream_mmap_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes |
112 | } | 112 | } |
113 | 113 | ||
114 | int | 114 | int |
115 | _stream_mmap_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes) | 115 | _stream_mmap_write (stream_t stream, const void *iptr, size_t isize, |
116 | off_t offset, size_t *nbytes) | ||
116 | { | 117 | { |
117 | struct _stream_mmap *ms = (struct _stream_mmap *)stream; | 118 | struct _stream_mmap *ms = (struct _stream_mmap *)stream; |
118 | int err = 0; | 119 | int err = 0; |
... | @@ -122,17 +123,17 @@ _stream_mmap_write (stream_t stream, const void *iptr, size_t isize, size_t *nby | ... | @@ -122,17 +123,17 @@ _stream_mmap_write (stream_t stream, const void *iptr, size_t isize, size_t *nby |
122 | if (ms->mflags & PROT_WRITE) | 123 | if (ms->mflags & PROT_WRITE) |
123 | { | 124 | { |
124 | /* Bigger we have to remmap. */ | 125 | /* Bigger we have to remmap. */ |
125 | if (ms->size < (ms->offset + isize)) | 126 | if (ms->size < (offset + isize)) |
126 | { | 127 | { |
127 | if (ms->ptr != MAP_FAILED && munmap (ms->ptr, ms->size) == 0) | 128 | if (ms->ptr != MAP_FAILED && munmap (ms->ptr, ms->size) == 0) |
128 | { | 129 | { |
129 | ms->ptr = MAP_FAILED; | 130 | ms->ptr = MAP_FAILED; |
130 | if (ftruncate (ms->fd, ms->offset + isize) == 0) | 131 | if (ftruncate (ms->fd, offset + isize) == 0) |
131 | { | 132 | { |
132 | ms->ptr = mmap (0, ms->offset + isize, ms->mflags, | 133 | ms->ptr = mmap (0, offset + isize, ms->mflags, |
133 | MAP_SHARED, ms->fd, 0); | 134 | MAP_SHARED, ms->fd, 0); |
134 | if (ms->ptr != MAP_FAILED) | 135 | if (ms->ptr != MAP_FAILED) |
135 | ms->size = ms->offset + isize; | 136 | ms->size = offset + isize; |
136 | } | 137 | } |
137 | } | 138 | } |
138 | } | 139 | } |
... | @@ -140,8 +141,7 @@ _stream_mmap_write (stream_t stream, const void *iptr, size_t isize, size_t *nby | ... | @@ -140,8 +141,7 @@ _stream_mmap_write (stream_t stream, const void *iptr, size_t isize, size_t *nby |
140 | if (ms->ptr != MAP_FAILED) | 141 | if (ms->ptr != MAP_FAILED) |
141 | { | 142 | { |
142 | if (isize > 0) | 143 | if (isize > 0) |
143 | memcpy (ms->ptr + ms->offset, iptr, isize); | 144 | memcpy (ms->ptr + offset, iptr, isize); |
144 | ms->offset += isize; | ||
145 | n = isize; | 145 | n = isize; |
146 | } | 146 | } |
147 | else | 147 | else |
... | @@ -274,38 +274,26 @@ _stream_mmap_get_state (stream_t stream, enum stream_state *state) | ... | @@ -274,38 +274,26 @@ _stream_mmap_get_state (stream_t stream, enum stream_state *state) |
274 | } | 274 | } |
275 | 275 | ||
276 | int | 276 | int |
277 | _stream_mmap_seek (stream_t stream, off_t off, enum stream_whence whence) | 277 | _stream_mmap_is_seekable (stream_t stream) |
278 | { | 278 | { |
279 | struct _stream_mmap *ms = (struct _stream_mmap *)stream; | 279 | off_t off; |
280 | off_t noff = ms->offset; | 280 | return _stream_mmap_tell (stream, &off) == 0; |
281 | int err = 0; | ||
282 | if (whence == MU_STREAM_WHENCE_SET) | ||
283 | noff = off; | ||
284 | else if (whence == MU_STREAM_WHENCE_CUR) | ||
285 | noff += off; | ||
286 | else if (whence == MU_STREAM_WHENCE_END) | ||
287 | noff = ms->size + off; | ||
288 | else | ||
289 | noff = -1; /* error. */ | ||
290 | if (noff >= 0) | ||
291 | { | ||
292 | if (noff > ms->offset) | ||
293 | _stream_mmap_truncate (stream, noff); | ||
294 | ms->offset = noff; | ||
295 | } | ||
296 | else | ||
297 | err = MU_ERROR_INVALID_PARAMETER; | ||
298 | return err; | ||
299 | } | 281 | } |
300 | 282 | ||
301 | int | 283 | int |
302 | _stream_mmap_tell (stream_t stream, off_t *off) | 284 | _stream_mmap_tell (stream_t stream, off_t *off) |
303 | { | 285 | { |
304 | struct _stream_mmap *ms = (struct _stream_mmap *)stream; | 286 | struct _stream_mmap *ms = (struct _stream_mmap *)stream; |
287 | int status = 0; | ||
305 | if (off == NULL) | 288 | if (off == NULL) |
306 | return MU_ERROR_INVALID_PARAMETER; | 289 | return MU_ERROR_INVALID_PARAMETER; |
307 | *off = ms->offset; | 290 | *off = lseek (ms->fd, 0, SEEK_SET); |
308 | return 0; | 291 | if (*off == -1) |
292 | { | ||
293 | status = errno; | ||
294 | *off = 0; | ||
295 | } | ||
296 | return status; | ||
309 | } | 297 | } |
310 | 298 | ||
311 | int | 299 | int |
... | @@ -451,7 +439,6 @@ static struct _stream_vtable _stream_mmap_vtable = | ... | @@ -451,7 +439,6 @@ static struct _stream_vtable _stream_mmap_vtable = |
451 | _stream_mmap_readline, | 439 | _stream_mmap_readline, |
452 | _stream_mmap_write, | 440 | _stream_mmap_write, |
453 | 441 | ||
454 | _stream_mmap_seek, | ||
455 | _stream_mmap_tell, | 442 | _stream_mmap_tell, |
456 | 443 | ||
457 | _stream_mmap_get_size, | 444 | _stream_mmap_get_size, |
... | @@ -462,6 +449,7 @@ static struct _stream_vtable _stream_mmap_vtable = | ... | @@ -462,6 +449,7 @@ static struct _stream_vtable _stream_mmap_vtable = |
462 | _stream_mmap_get_flags, | 449 | _stream_mmap_get_flags, |
463 | _stream_mmap_get_state, | 450 | _stream_mmap_get_state, |
464 | 451 | ||
452 | _stream_mmap_is_seekable, | ||
465 | _stream_mmap_is_readready, | 453 | _stream_mmap_is_readready, |
466 | _stream_mmap_is_writeready, | 454 | _stream_mmap_is_writeready, |
467 | _stream_mmap_is_exceptionpending, | 455 | _stream_mmap_is_exceptionpending, |
... | @@ -476,7 +464,6 @@ _stream_mmap_ctor (struct _stream_mmap *ms) | ... | @@ -476,7 +464,6 @@ _stream_mmap_ctor (struct _stream_mmap *ms) |
476 | if (ms->refcount == NULL) | 464 | if (ms->refcount == NULL) |
477 | return MU_ERROR_NO_MEMORY; | 465 | return MU_ERROR_NO_MEMORY; |
478 | ms->fd = -1; | 466 | ms->fd = -1; |
479 | ms->offset = -1; | ||
480 | ms->flags = 0; | 467 | ms->flags = 0; |
481 | ms->mflags = 0; | 468 | ms->mflags = 0; |
482 | ms->base.vtable = &_stream_mmap_vtable; | 469 | ms->base.vtable = &_stream_mmap_vtable; |
... | @@ -484,13 +471,16 @@ _stream_mmap_ctor (struct _stream_mmap *ms) | ... | @@ -484,13 +471,16 @@ _stream_mmap_ctor (struct _stream_mmap *ms) |
484 | } | 471 | } |
485 | 472 | ||
486 | void | 473 | void |
487 | _stream_mmap_dtor (struct _stream_mmap *ms) | 474 | _stream_mmap_dtor (stream_t stream) |
488 | { | 475 | { |
476 | struct _stream_mmap *ms = (struct _stream_mmap *)stream; | ||
477 | if (ms) | ||
478 | { | ||
489 | mu_refcount_destroy (&ms->refcount); | 479 | mu_refcount_destroy (&ms->refcount); |
490 | ms->fd = -1; | 480 | ms->fd = -1; |
491 | ms->offset = -1; | ||
492 | ms->mflags = 0; | 481 | ms->mflags = 0; |
493 | ms->ptr = MAP_FAILED; | 482 | ms->ptr = MAP_FAILED; |
483 | } | ||
494 | } | 484 | } |
495 | 485 | ||
496 | #endif /* _POSIX_MAPPED_FILES */ | 486 | #endif /* _POSIX_MAPPED_FILES */ | ... | ... |
... | @@ -16,15 +16,16 @@ libmbox_la_SOURCES = \ | ... | @@ -16,15 +16,16 @@ libmbox_la_SOURCES = \ |
16 | mbox_bstream.c \ | 16 | mbox_bstream.c \ |
17 | mbox_carrier.c \ | 17 | mbox_carrier.c \ |
18 | mbox_cb.c \ | 18 | mbox_cb.c \ |
19 | mbox_newmail.c \ | ||
20 | mbox_close.c \ | 19 | mbox_close.c \ |
21 | mbox_create.c \ | 20 | mbox_create.c \ |
21 | mbox_debug.c \ | ||
22 | mbox_destroy.c \ | 22 | mbox_destroy.c \ |
23 | mbox_expunge.c \ | 23 | mbox_expunge.c \ |
24 | mbox_hcache.c \ | 24 | mbox_hcache.c \ |
25 | mbox_hlines.c \ | 25 | mbox_hlines.c \ |
26 | mbox_hsize.c \ | 26 | mbox_hsize.c \ |
27 | mbox_hstream.c \ | 27 | mbox_hstream.c \ |
28 | mbox_newmail.c \ | ||
28 | mbox_open.c \ | 29 | mbox_open.c \ |
29 | mbox_scan.c \ | 30 | mbox_scan.c \ |
30 | mbox_separator.c \ | 31 | mbox_separator.c \ | ... | ... |
... | @@ -94,7 +94,10 @@ | ... | @@ -94,7 +94,10 @@ |
94 | - Refuse to append if the mailbox is change on disk. | 94 | - Refuse to append if the mailbox is change on disk. |
95 | */ | 95 | */ |
96 | 96 | ||
97 | /* Assuming that the file is lock. */ | 97 | /* Assuming that the file is lock: |
98 | Add the unix separtor the form is: | ||
99 | From user cdate_format\n | ||
100 | */ | ||
98 | static int | 101 | static int |
99 | mbox_append_separator (mbox_t mbox, const char *sep) | 102 | mbox_append_separator (mbox_t mbox, const char *sep) |
100 | { | 103 | { |
... | @@ -123,93 +126,102 @@ mbox_append_separator (mbox_t mbox, const char *sep) | ... | @@ -123,93 +126,102 @@ mbox_append_separator (mbox_t mbox, const char *sep) |
123 | len = strlen (sep); | 126 | len = strlen (sep); |
124 | 127 | ||
125 | /* Write the separator. */ | 128 | /* Write the separator. */ |
126 | status = stream_write (mbox->carrier, sep, len, NULL); | 129 | status = stream_write (mbox->carrier, sep, len, mbox->woffset, &len); |
127 | if (status != 0) | 130 | if (status != 0) |
128 | return status; | 131 | return status; |
132 | mbox->woffset += len; | ||
129 | 133 | ||
130 | /* Add the trailing newline. */ | 134 | /* Add the trailing newline. */ |
131 | if (len && sep[len - 1] != '\n') | 135 | if (len && sep[len - 1] != '\n') |
132 | status = stream_write (mbox->carrier, &nl, 1, NULL); | 136 | { |
137 | status = stream_write (mbox->carrier, &nl, 1, mbox->woffset, &len); | ||
138 | if (status != 0) | ||
139 | return status; | ||
140 | mbox->woffset += len; | ||
141 | } | ||
133 | return status; | 142 | return status; |
134 | } | 143 | } |
135 | 144 | ||
136 | /* Assuming that the file is lock. */ | 145 | /* Assuming that the file is lock. |
146 | Strip away Content-Length in the header add add the separating | ||
147 | newline between the header and the body. | ||
148 | */ | ||
137 | static int | 149 | static int |
138 | mbox_append_header (mbox_t mbox, attribute_t attribute, int save_uidvalidity, | 150 | mbox_append_header (mbox_t mbox, attribute_t attribute, stream_t hstream, |
139 | stream_t hstream) | 151 | int save_uidvalidity, unsigned long uid) |
140 | { | 152 | { |
141 | char buffer[1024]; | 153 | char buf[1024]; |
154 | size_t n = 0; | ||
142 | size_t nread = 0; | 155 | size_t nread = 0; |
143 | int status = 0; | 156 | int status = 0; |
144 | const char nl = '\n'; | 157 | const char nl = '\n'; |
145 | 158 | ||
146 | do | 159 | do |
147 | { | 160 | { |
148 | status = stream_readline (hstream, buffer, sizeof buffer, &nread); | 161 | status = stream_readline (hstream, buf, sizeof buf, mbox->roffset, &nread); |
149 | if (status != 0) | 162 | if (status != 0) |
150 | return status; | 163 | return status; |
151 | 164 | ||
165 | mbox->roffset += nread; | ||
166 | |||
152 | /* A newline means the start of the body. */ | 167 | /* A newline means the start of the body. */ |
153 | if (*buffer == '\n') | 168 | if (*buf == '\n') |
154 | break; | 169 | break; |
155 | 170 | ||
156 | if (IS_X_IMAPBASE (buffer)) | 171 | /* Skip X-IMAPBase it has special meaning for us. */ |
157 | { | 172 | /* Skip X-UID. A new one will be provided. */ |
158 | /* Skip the X-IMAPBase it has special meaning for us. */ | 173 | /* Skip Status, use the attribute. */ |
174 | /* Skip Content-Length, too often bad. */ | ||
175 | if (IS_X_IMAPBASE (buf) || IS_X_UID (buf) | ||
176 | || IS_STATUS (buf) || IS_CONTENT_LENGTH (buf)) | ||
159 | continue; | 177 | continue; |
160 | } | ||
161 | else if (IS_X_UID (buffer)) | ||
162 | { | ||
163 | /* Skip the X-UID. A new one will be provided. */ | ||
164 | continue; | ||
165 | } | ||
166 | else if (IS_STATUS (buffer)) | ||
167 | { | ||
168 | /* Skip, use the attribute. */ | ||
169 | continue; | ||
170 | } | ||
171 | else if (IS_CONTENT_LENGTH (buffer)) | ||
172 | { | ||
173 | /* Ignore this, too often bad. */ | ||
174 | continue; | ||
175 | } | ||
176 | 178 | ||
177 | status = stream_write (mbox->carrier, buffer, nread, NULL); | 179 | status = stream_write (mbox->carrier, buf, nread, mbox->woffset, &n); |
178 | if (status != 0) | 180 | if (status != 0) |
179 | return status; | 181 | return status; |
182 | mbox->woffset += n; | ||
180 | } | 183 | } |
181 | while (nread > 0); | 184 | while (nread > 0); |
182 | 185 | ||
183 | /* Rewrite the X-IMAPbase marker If necesary. */ | 186 | /* Rewrite the X-IMAPbase, if necesary, and only for the first msg. */ |
184 | if (mbox->uidnext < 2 && save_uidvalidity) | 187 | if (mbox->uidnext < 2 && save_uidvalidity) |
185 | { | 188 | { |
186 | nread = snprintf (buffer, sizeof buffer, "X-IMAPbase: %lu %lu\n", | 189 | n = snprintf (buf, sizeof buf, "X-IMAPbase: %lu %lu\n", |
187 | mbox->uidvalidity, mbox->uidnext); | 190 | mbox->uidvalidity, mbox->uidnext); |
188 | status = stream_write (mbox->carrier, buffer, nread, NULL); | 191 | status = stream_write (mbox->carrier, buf, n, mbox->woffset, &n); |
189 | if (status != 0) | 192 | if (status != 0) |
190 | return status; | 193 | return status; |
194 | mbox->woffset += n; | ||
191 | } | 195 | } |
192 | 196 | ||
193 | /* Rewrite the Status for the attribute. */ | 197 | /* Rewrite the Status for the attribute. */ |
194 | if (attribute) | 198 | if (attribute) |
195 | { | 199 | { |
196 | mbox_attribute_to_status (attribute, buffer, sizeof buffer, &nread); | 200 | mbox_attribute_to_status (attribute, buf, sizeof buf, &n); |
197 | status = stream_write (mbox->carrier, buffer, nread, NULL); | 201 | status = stream_write (mbox->carrier, buf, n, mbox->woffset, &n); |
198 | if (status != 0) | 202 | if (status != 0) |
199 | return status; | 203 | return status; |
204 | mbox->woffset += n; | ||
200 | } | 205 | } |
201 | 206 | ||
202 | /* Rewrite the X-UID marker . */ | 207 | /* Rewrite the X-UID marker . */ |
203 | nread = snprintf (buffer, sizeof buffer, "X-UID: %lu\n", mbox->uidnext); | 208 | n = snprintf (buf, sizeof buf, "X-UID: %lu\n", (uid) ? uid : mbox->uidnext); |
204 | status = stream_write (mbox->carrier, buffer, nread, NULL); | 209 | status = stream_write (mbox->carrier, buf, n, mbox->woffset, &n); |
205 | if (status != 0) | 210 | if (status != 0) |
206 | return status; | 211 | return status; |
212 | mbox->woffset += n; | ||
207 | 213 | ||
208 | /* New line separator of the Header. */ | 214 | /* New line separator of the Header. */ |
209 | return stream_write (mbox->carrier, &nl , 1, NULL); | 215 | status = stream_write (mbox->carrier, &nl , 1, mbox->woffset, &n); |
216 | if (status != 0) | ||
217 | return status; | ||
218 | mbox->woffset += n; | ||
219 | return status; | ||
210 | } | 220 | } |
211 | 221 | ||
212 | /* Assuming that the file is lock. */ | 222 | /* Assuming that the file is lock. |
223 | Do the mangling, line startin with "From " is mangle to ">From " | ||
224 | */ | ||
213 | static int | 225 | static int |
214 | mbox_append_body (mbox_t mbox, stream_t bstream) | 226 | mbox_append_body (mbox_t mbox, stream_t bstream) |
215 | { | 227 | { |
... | @@ -219,6 +231,7 @@ mbox_append_body (mbox_t mbox, stream_t bstream) | ... | @@ -219,6 +231,7 @@ mbox_append_body (mbox_t mbox, stream_t bstream) |
219 | size_t nread = 0; | 231 | size_t nread = 0; |
220 | const char nl = '\n'; | 232 | const char nl = '\n'; |
221 | int status; | 233 | int status; |
234 | size_t n = 0; | ||
222 | 235 | ||
223 | /* For "From " mangling. */ | 236 | /* For "From " mangling. */ |
224 | *buffer = '>'; | 237 | *buffer = '>'; |
... | @@ -226,9 +239,11 @@ mbox_append_body (mbox_t mbox, stream_t bstream) | ... | @@ -226,9 +239,11 @@ mbox_append_body (mbox_t mbox, stream_t bstream) |
226 | do | 239 | do |
227 | { | 240 | { |
228 | buf = buffer + 1; | 241 | buf = buffer + 1; |
229 | status = stream_readline (bstream, buf, sizeof (buffer) - 1, &nread); | 242 | status = stream_readline (bstream, buf, sizeof (buffer) - 1, |
243 | mbox->roffset, &nread); | ||
230 | if (status != 0) | 244 | if (status != 0) |
231 | return status; | 245 | return status; |
246 | mbox->roffset += nread; | ||
232 | 247 | ||
233 | /* Unix Mbox: | 248 | /* Unix Mbox: |
234 | Since it's possibpe for a message to contain lines that looks | 249 | Since it's possibpe for a message to contain lines that looks |
... | @@ -252,9 +267,10 @@ mbox_append_body (mbox_t mbox, stream_t bstream) | ... | @@ -252,9 +267,10 @@ mbox_append_body (mbox_t mbox, stream_t bstream) |
252 | nread++; | 267 | nread++; |
253 | } | 268 | } |
254 | } | 269 | } |
255 | status = stream_write (mbox->carrier, buf, nread, NULL); | 270 | status = stream_write (mbox->carrier, buf, nread, mbox->woffset, &n); |
256 | if (status != 0) | 271 | if (status != 0) |
257 | return status ; | 272 | return status ; |
273 | mbox->woffset += n; | ||
258 | 274 | ||
259 | /* Register if we read a complete line. */ | 275 | /* Register if we read a complete line. */ |
260 | was_complete_line = (nread && buf[nread - 1] == '\n') ? 1 : 0; | 276 | was_complete_line = (nread && buf[nread - 1] == '\n') ? 1 : 0; |
... | @@ -262,15 +278,22 @@ mbox_append_body (mbox_t mbox, stream_t bstream) | ... | @@ -262,15 +278,22 @@ mbox_append_body (mbox_t mbox, stream_t bstream) |
262 | while (nread > 0); | 278 | while (nread > 0); |
263 | 279 | ||
264 | /* New line separator for the next message. */ | 280 | /* New line separator for the next message. */ |
265 | return stream_write (mbox->carrier, &nl, 1, NULL); | 281 | status = stream_write (mbox->carrier, &nl, 1, mbox->woffset, &n); |
282 | if (status != 0) | ||
283 | return status; | ||
284 | mbox->woffset += n; | ||
285 | return status; | ||
266 | } | 286 | } |
267 | 287 | ||
268 | int | 288 | int |
269 | mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, | 289 | mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, |
270 | int save_uidvalidity, stream_t hstream, stream_t bstream) | 290 | stream_t hstream, stream_t bstream, |
291 | int save_uidvalidity, unsigned long uid) | ||
271 | { | 292 | { |
272 | int status = 0; | 293 | int status = 0; |
273 | 294 | ||
295 | mbox_debug_print (mbox, "append_hb0(uid=%lu)", uid); | ||
296 | |||
274 | if (mbox == NULL || hstream == NULL || bstream == NULL) | 297 | if (mbox == NULL || hstream == NULL || bstream == NULL) |
275 | return MU_ERROR_INVALID_PARAMETER; | 298 | return MU_ERROR_INVALID_PARAMETER; |
276 | 299 | ||
... | @@ -278,7 +301,6 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, | ... | @@ -278,7 +301,6 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, |
278 | { | 301 | { |
279 | case MU_MBOX_NO_STATE: | 302 | case MU_MBOX_NO_STATE: |
280 | { | 303 | { |
281 | off_t size = 0; | ||
282 | unsigned long uidvalidity; | 304 | unsigned long uidvalidity; |
283 | unsigned long uidnext; | 305 | unsigned long uidnext; |
284 | 306 | ||
... | @@ -291,10 +313,10 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, | ... | @@ -291,10 +313,10 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, |
291 | if (status != 0) | 313 | if (status != 0) |
292 | break; | 314 | break; |
293 | 315 | ||
316 | mbox->woffset = mbox->roffset = 0; | ||
294 | /* Move to the end of the stream. */ | 317 | /* Move to the end of the stream. */ |
295 | if ((status = stream_get_size (mbox->carrier, &size)) != 0 | 318 | status = stream_get_size (mbox->carrier, &mbox->woffset); |
296 | || (status = stream_seek (mbox->carrier, size, | 319 | if (status != 0) |
297 | MU_STREAM_WHENCE_SET) != 0)) | ||
298 | break; | 320 | break; |
299 | mbox->state = MU_MBOX_STATE_APPEND_SEPARATOR; | 321 | mbox->state = MU_MBOX_STATE_APPEND_SEPARATOR; |
300 | } | 322 | } |
... | @@ -309,7 +331,8 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, | ... | @@ -309,7 +331,8 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, |
309 | 331 | ||
310 | case MU_MBOX_STATE_APPEND_HEADER: | 332 | case MU_MBOX_STATE_APPEND_HEADER: |
311 | { | 333 | { |
312 | status = mbox_append_header (mbox, attribute, save_uidvalidity, hstream); | 334 | status = mbox_append_header (mbox, attribute, hstream, |
335 | save_uidvalidity, uid); | ||
313 | if (status != 0) | 336 | if (status != 0) |
314 | break; | 337 | break; |
315 | mbox->state = MU_MBOX_STATE_APPEND_BODY; | 338 | mbox->state = MU_MBOX_STATE_APPEND_BODY; |
... | @@ -317,6 +340,9 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, | ... | @@ -317,6 +340,9 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, |
317 | 340 | ||
318 | case MU_MBOX_STATE_APPEND_BODY: | 341 | case MU_MBOX_STATE_APPEND_BODY: |
319 | { | 342 | { |
343 | /* Hack it the same stream. do not reset the mbox->roffset. */ | ||
344 | if (hstream != bstream) | ||
345 | mbox->roffset = 0; | ||
320 | status = mbox_append_body (mbox, bstream); | 346 | status = mbox_append_body (mbox, bstream); |
321 | if (status != 0) | 347 | if (status != 0) |
322 | break; | 348 | break; |
... | @@ -324,6 +350,7 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, | ... | @@ -324,6 +350,7 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, |
324 | } | 350 | } |
325 | 351 | ||
326 | default: | 352 | default: |
353 | mbox->woffset = mbox->roffset = 0; | ||
327 | break; | 354 | break; |
328 | } | 355 | } |
329 | 356 | ||
... | @@ -333,6 +360,7 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, | ... | @@ -333,6 +360,7 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, |
333 | if (status != MU_ERROR_TRY_AGAIN) | 360 | if (status != MU_ERROR_TRY_AGAIN) |
334 | { | 361 | { |
335 | mbox->state = MU_MBOX_NO_STATE; | 362 | mbox->state = MU_MBOX_NO_STATE; |
363 | mbox->woffset = mbox->roffset = 0; | ||
336 | lockfile_unlock (mbox->lockfile); | 364 | lockfile_unlock (mbox->lockfile); |
337 | } | 365 | } |
338 | } | 366 | } |
... | @@ -347,15 +375,15 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, | ... | @@ -347,15 +375,15 @@ mbox_append_hb0 (mbox_t mbox, const char *sep, attribute_t attribute, |
347 | } | 375 | } |
348 | 376 | ||
349 | int | 377 | int |
350 | mbox_append (mbox_t mbox, const char *sep, attribute_t attribute, | 378 | mbox_append_hb (mbox_t mbox, const char *sep, attribute_t attribute, |
351 | stream_t stream) | 379 | stream_t hstream, stream_t bstream) |
352 | { | 380 | { |
353 | return mbox_append_hb (mbox, sep, attribute, stream, stream); | 381 | return mbox_append_hb0 (mbox, sep, attribute, hstream, bstream, 1, 0); |
354 | } | 382 | } |
355 | 383 | ||
356 | int | 384 | int |
357 | mbox_append_hb (mbox_t mbox, const char *sep, attribute_t attribute, | 385 | mbox_append (mbox_t mbox, const char *sep, attribute_t attribute, |
358 | stream_t hstream, stream_t bstream) | 386 | stream_t stream) |
359 | { | 387 | { |
360 | return mbox_append_hb0 (mbox, sep, attribute, 1, hstream, bstream); | 388 | return mbox_append_hb (mbox, sep, attribute, stream, stream); |
361 | } | 389 | } | ... | ... |
... | @@ -48,14 +48,15 @@ _attribute_mbox_destroy (attribute_t *pattribute) | ... | @@ -48,14 +48,15 @@ _attribute_mbox_destroy (attribute_t *pattribute) |
48 | struct _attribute_mbox *ma = (struct _attribute_mbox *)*pattribute; | 48 | struct _attribute_mbox *ma = (struct _attribute_mbox *)*pattribute; |
49 | if (mu_refcount_dec (ma->refcount) == 0) | 49 | if (mu_refcount_dec (ma->refcount) == 0) |
50 | { | 50 | { |
51 | mu_refcount_destroy (&ma->refcount); | ||
51 | if (ma->msgno <= ma->mbox->messages_count) | 52 | if (ma->msgno <= ma->mbox->messages_count) |
52 | { | 53 | { |
53 | /* If it is the attribute save in the mailbox structure. */ | 54 | /* If it is the attribute save in the mailbox structure. */ |
54 | if (ma == (struct _attribute_mbox *)(ma->mbox->umessages[ma->msgno - 1]->attribute)) | 55 | if (ma == (struct _attribute_mbox *) |
56 | (ma->mbox->umessages[ma->msgno - 1]->attribute)) | ||
55 | ma->mbox->umessages[ma->msgno - 1]->attribute = NULL; | 57 | ma->mbox->umessages[ma->msgno - 1]->attribute = NULL; |
56 | mu_refcount_destroy (&ma->refcount); | ||
57 | free (ma); | ||
58 | } | 58 | } |
59 | free (ma); | ||
59 | } | 60 | } |
60 | } | 61 | } |
61 | 62 | ||
... | @@ -66,10 +67,8 @@ _attribute_mbox_get_flags (attribute_t attribute, int *pflags) | ... | @@ -66,10 +67,8 @@ _attribute_mbox_get_flags (attribute_t attribute, int *pflags) |
66 | if (pflags) | 67 | if (pflags) |
67 | { | 68 | { |
68 | if (ma->msgno <= ma->mbox->messages_count) | 69 | if (ma->msgno <= ma->mbox->messages_count) |
69 | { | ||
70 | *pflags = ma->mbox->umessages[ma->msgno - 1]->attr_flags; | 70 | *pflags = ma->mbox->umessages[ma->msgno - 1]->attr_flags; |
71 | } | 71 | } |
72 | } | ||
73 | return 0; | 72 | return 0; |
74 | } | 73 | } |
75 | 74 | ||
... | @@ -78,9 +77,8 @@ _attribute_mbox_set_flags (attribute_t attribute, int flags) | ... | @@ -78,9 +77,8 @@ _attribute_mbox_set_flags (attribute_t attribute, int flags) |
78 | { | 77 | { |
79 | struct _attribute_mbox *ma = (struct _attribute_mbox *)attribute; | 78 | struct _attribute_mbox *ma = (struct _attribute_mbox *)attribute; |
80 | if (ma->msgno <= ma->mbox->messages_count) | 79 | if (ma->msgno <= ma->mbox->messages_count) |
81 | { | 80 | ma->mbox->umessages[ma->msgno - 1]->attr_flags |= |
82 | ma->mbox->umessages[ma->msgno - 1]->attr_flags |= (flags | MU_ATTRIBUTE_MODIFIED); | 81 | (flags | MU_ATTRIBUTE_MODIFIED); |
83 | } | ||
84 | return 0; | 82 | return 0; |
85 | } | 83 | } |
86 | 84 | ||
... | @@ -93,7 +91,8 @@ _attribute_mbox_unset_flags (attribute_t attribute, int flags) | ... | @@ -93,7 +91,8 @@ _attribute_mbox_unset_flags (attribute_t attribute, int flags) |
93 | ma->mbox->umessages[ma->msgno - 1]->attr_flags &= ~flags; | 91 | ma->mbox->umessages[ma->msgno - 1]->attr_flags &= ~flags; |
94 | /* If Modified was being unset do not reset it. */ | 92 | /* If Modified was being unset do not reset it. */ |
95 | if (!(flags & MU_ATTRIBUTE_MODIFIED)) | 93 | if (!(flags & MU_ATTRIBUTE_MODIFIED)) |
96 | ma->mbox->umessages[ma->msgno - 1]->attr_flags |= MU_ATTRIBUTE_MODIFIED; | 94 | ma->mbox->umessages[ma->msgno - 1]->attr_flags |= |
95 | MU_ATTRIBUTE_MODIFIED; | ||
97 | } | 96 | } |
98 | return 0; | 97 | return 0; |
99 | } | 98 | } |
... | @@ -103,12 +102,56 @@ _attribute_mbox_clear_flags (attribute_t attribute) | ... | @@ -103,12 +102,56 @@ _attribute_mbox_clear_flags (attribute_t attribute) |
103 | { | 102 | { |
104 | struct _attribute_mbox *ma = (struct _attribute_mbox *)attribute; | 103 | struct _attribute_mbox *ma = (struct _attribute_mbox *)attribute; |
105 | if (ma->msgno <= ma->mbox->messages_count) | 104 | if (ma->msgno <= ma->mbox->messages_count) |
106 | { | ||
107 | ma->mbox->umessages[ma->msgno - 1]->attr_flags = 0; | 105 | ma->mbox->umessages[ma->msgno - 1]->attr_flags = 0; |
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int | ||
110 | _attribute_mbox_get_userflags (attribute_t attribute, int *puserflags) | ||
111 | { | ||
112 | struct _attribute_mbox *ma = (struct _attribute_mbox *)attribute; | ||
113 | if (puserflags) | ||
114 | { | ||
115 | if (ma->msgno <= ma->mbox->messages_count) | ||
116 | *puserflags = ma->mbox->umessages[ma->msgno - 1]->attr_userflags; | ||
108 | } | 117 | } |
109 | return 0; | 118 | return 0; |
110 | } | 119 | } |
111 | 120 | ||
121 | static int | ||
122 | _attribute_mbox_set_userflags (attribute_t attribute, int userflags) | ||
123 | { | ||
124 | struct _attribute_mbox *ma = (struct _attribute_mbox *)attribute; | ||
125 | if (ma->msgno <= ma->mbox->messages_count) | ||
126 | ma->mbox->umessages[ma->msgno - 1]->attr_userflags |= | ||
127 | (userflags | MU_ATTRIBUTE_MODIFIED); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static int | ||
132 | _attribute_mbox_unset_userflags (attribute_t attribute, int userflags) | ||
133 | { | ||
134 | struct _attribute_mbox *ma = (struct _attribute_mbox *)attribute; | ||
135 | if (ma->msgno <= ma->mbox->messages_count) | ||
136 | { | ||
137 | ma->mbox->umessages[ma->msgno - 1]->attr_userflags &= ~userflags; | ||
138 | /* If Modified was being unset do not reset it. */ | ||
139 | if (!(userflags & MU_ATTRIBUTE_MODIFIED)) | ||
140 | ma->mbox->umessages[ma->msgno - 1]->attr_userflags |= | ||
141 | MU_ATTRIBUTE_MODIFIED; | ||
142 | } | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static int | ||
147 | _attribute_mbox_clear_userflags (attribute_t attribute) | ||
148 | { | ||
149 | struct _attribute_mbox *ma = (struct _attribute_mbox *)attribute; | ||
150 | if (ma->msgno <= ma->mbox->messages_count) | ||
151 | ma->mbox->umessages[ma->msgno - 1]->attr_userflags = 0; | ||
152 | return 0; | ||
153 | } | ||
154 | |||
112 | static struct _attribute_vtable _attribute_mbox_vtable = | 155 | static struct _attribute_vtable _attribute_mbox_vtable = |
113 | { | 156 | { |
114 | _attribute_mbox_ref, | 157 | _attribute_mbox_ref, |
... | @@ -117,7 +160,12 @@ static struct _attribute_vtable _attribute_mbox_vtable = | ... | @@ -117,7 +160,12 @@ static struct _attribute_vtable _attribute_mbox_vtable = |
117 | _attribute_mbox_get_flags, | 160 | _attribute_mbox_get_flags, |
118 | _attribute_mbox_set_flags, | 161 | _attribute_mbox_set_flags, |
119 | _attribute_mbox_unset_flags, | 162 | _attribute_mbox_unset_flags, |
120 | _attribute_mbox_clear_flags | 163 | _attribute_mbox_clear_flags, |
164 | |||
165 | _attribute_mbox_get_userflags, | ||
166 | _attribute_mbox_set_userflags, | ||
167 | _attribute_mbox_unset_userflags, | ||
168 | _attribute_mbox_clear_userflags | ||
121 | }; | 169 | }; |
122 | 170 | ||
123 | static int | 171 | static int |
... | @@ -133,12 +181,19 @@ _attribute_mbox_ctor (struct _attribute_mbox *ma, mbox_t mbox, | ... | @@ -133,12 +181,19 @@ _attribute_mbox_ctor (struct _attribute_mbox *ma, mbox_t mbox, |
133 | return 0; | 181 | return 0; |
134 | } | 182 | } |
135 | 183 | ||
136 | /* | 184 | void |
137 | static int | 185 | _attribute_mbox_dtor (attribute_t attribute) |
138 | _attribute_mbox_dtor (struct _attribute_mbox *ma) | ||
139 | { | 186 | { |
187 | struct _attribute_mbox *ma = (struct _attribute_mbox *)attribute; | ||
188 | mu_refcount_destroy (&ma->refcount); | ||
189 | if (ma->msgno <= ma->mbox->messages_count) | ||
190 | { | ||
191 | /* If it is the attribute save in the mailbox structure. */ | ||
192 | if (ma == (struct _attribute_mbox *) | ||
193 | (ma->mbox->umessages[ma->msgno - 1]->attribute)) | ||
194 | ma->mbox->umessages[ma->msgno - 1]->attribute = NULL; | ||
195 | } | ||
140 | } | 196 | } |
141 | */ | ||
142 | 197 | ||
143 | int | 198 | int |
144 | attribute_mbox_create (attribute_t *pattribute, mbox_t mbox, | 199 | attribute_mbox_create (attribute_t *pattribute, mbox_t mbox, |
... | @@ -162,9 +217,21 @@ attribute_mbox_create (attribute_t *pattribute, mbox_t mbox, | ... | @@ -162,9 +217,21 @@ attribute_mbox_create (attribute_t *pattribute, mbox_t mbox, |
162 | } | 217 | } |
163 | 218 | ||
164 | int | 219 | int |
220 | attribute_mbox_msgno (attribute_t attribute, unsigned int msgno) | ||
221 | { | ||
222 | struct _attribute_mbox *ma = (struct _attribute_mbox *)attribute; | ||
223 | if (ma) | ||
224 | ma->msgno = msgno; | ||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | int | ||
165 | mbox_get_attribute (mbox_t mbox, unsigned int msgno, attribute_t *pattribute) | 229 | mbox_get_attribute (mbox_t mbox, unsigned int msgno, attribute_t *pattribute) |
166 | { | 230 | { |
167 | int status = 0; | 231 | int status = 0; |
232 | |||
233 | mbox_debug_print (mbox, "attribute(%d)", msgno); | ||
234 | |||
168 | if (mbox == NULL || msgno == 0 || pattribute == NULL) | 235 | if (mbox == NULL || msgno == 0 || pattribute == NULL) |
169 | return MU_ERROR_INVALID_PARAMETER; | 236 | return MU_ERROR_INVALID_PARAMETER; |
170 | 237 | ||
... | @@ -198,16 +265,18 @@ mbox_attribute_to_status (attribute_t attribute, char *buf, size_t buflen, | ... | @@ -198,16 +265,18 @@ mbox_attribute_to_status (attribute_t attribute, char *buf, size_t buflen, |
198 | 265 | ||
199 | if (attribute) | 266 | if (attribute) |
200 | { | 267 | { |
201 | if (attribute_is_read (attribute)) | ||
202 | strcat (a, "R"); | ||
203 | if (attribute_is_seen (attribute)) | 268 | if (attribute_is_seen (attribute)) |
204 | strcat (a, "O"); | 269 | strcat (a, "O"); |
270 | if (attribute_is_read (attribute)) | ||
271 | strcat (a, "R"); | ||
205 | if (attribute_is_answered (attribute)) | 272 | if (attribute_is_answered (attribute)) |
206 | strcat (a, "A"); | 273 | strcat (a, "A"); |
207 | if (attribute_is_deleted (attribute)) | 274 | if (attribute_is_deleted (attribute)) |
208 | strcat (a, "d"); | 275 | strcat (a, "d"); |
209 | if (attribute_is_flagged (attribute)) | 276 | if (attribute_is_flagged (attribute)) |
210 | strcat (a, "F"); | 277 | strcat (a, "F"); |
278 | if (attribute_is_draft (attribute)) | ||
279 | strcat (a, "T"); | ||
211 | } | 280 | } |
212 | 281 | ||
213 | if (*a != '\0') | 282 | if (*a != '\0') | ... | ... |
... | @@ -27,6 +27,7 @@ int | ... | @@ -27,6 +27,7 @@ int |
27 | mbox_get_blines (mbox_t mbox, unsigned int msgno, unsigned int *plines) | 27 | mbox_get_blines (mbox_t mbox, unsigned int msgno, unsigned int *plines) |
28 | { | 28 | { |
29 | unsigned int lines = 0; | 29 | unsigned int lines = 0; |
30 | mbox_debug_print (mbox, "get_blines(%u)", msgno); | ||
30 | if (mbox && msgno) | 31 | if (mbox && msgno) |
31 | { | 32 | { |
32 | msgno--; | 33 | msgno--; | ... | ... |
... | @@ -27,6 +27,7 @@ int | ... | @@ -27,6 +27,7 @@ int |
27 | mbox_get_bsize (mbox_t mbox, unsigned int msgno, unsigned int *psize) | 27 | mbox_get_bsize (mbox_t mbox, unsigned int msgno, unsigned int *psize) |
28 | { | 28 | { |
29 | unsigned int size = 0; | 29 | unsigned int size = 0; |
30 | mbox_debug_print (mbox, "get_bsize(%u)", msgno); | ||
30 | if (mbox && msgno) | 31 | if (mbox && msgno) |
31 | { | 32 | { |
32 | msgno--; | 33 | msgno--; | ... | ... |
... | @@ -28,6 +28,8 @@ int | ... | @@ -28,6 +28,8 @@ int |
28 | mbox_get_bstream (mbox_t mbox, unsigned int msgno, stream_t *pstream) | 28 | mbox_get_bstream (mbox_t mbox, unsigned int msgno, stream_t *pstream) |
29 | { | 29 | { |
30 | int status = 0; | 30 | int status = 0; |
31 | |||
32 | mbox_debug_print (mbox, "get_bstream(%u)", msgno); | ||
31 | if (mbox == NULL || msgno == 0 || pstream == NULL) | 33 | if (mbox == NULL || msgno == 0 || pstream == NULL) |
32 | return MU_ERROR_INVALID_PARAMETER; | 34 | return MU_ERROR_INVALID_PARAMETER; |
33 | 35 | ||
... | @@ -58,10 +60,11 @@ mbox_set_bstream (mbox_t mbox, unsigned int msgno, stream_t stream) | ... | @@ -58,10 +60,11 @@ mbox_set_bstream (mbox_t mbox, unsigned int msgno, stream_t stream) |
58 | if (msgno > mbox->umessages_count) | 60 | if (msgno > mbox->umessages_count) |
59 | return MU_ERROR_INVALID_PARAMETER; | 61 | return MU_ERROR_INVALID_PARAMETER; |
60 | 62 | ||
61 | msgno--; | 63 | if (mbox->umessages[msgno - 1]->body.stream) |
62 | if (mbox->umessages[msgno]->body.stream) | 64 | mbox_release_bstream (mbox, msgno); |
63 | stream_destroy (&mbox->umessages[msgno]->body.stream); | ||
64 | 65 | ||
65 | mbox->umessages[msgno]->body.stream = stream; | 66 | mbox->umessages[msgno - 1]->attr_flags |= MU_MBOX_BSTREAM_SET; |
67 | mbox->umessages[msgno - 1]->attr_flags |= MU_ATTRIBUTE_MODIFIED; | ||
68 | mbox->umessages[msgno - 1]->body.stream = stream; | ||
66 | return 0; | 69 | return 0; |
67 | } | 70 | } | ... | ... |
... | @@ -27,6 +27,7 @@ | ... | @@ -27,6 +27,7 @@ |
27 | int | 27 | int |
28 | mbox_set_carrier (mbox_t mbox, stream_t carrier) | 28 | mbox_set_carrier (mbox_t mbox, stream_t carrier) |
29 | { | 29 | { |
30 | mbox_debug_print (mbox, "set_carrier"); | ||
30 | if (mbox == NULL) | 31 | if (mbox == NULL) |
31 | return MU_ERROR_INVALID_PARAMETER; | 32 | return MU_ERROR_INVALID_PARAMETER; |
32 | 33 | ||
... | @@ -42,6 +43,7 @@ mbox_set_carrier (mbox_t mbox, stream_t carrier) | ... | @@ -42,6 +43,7 @@ mbox_set_carrier (mbox_t mbox, stream_t carrier) |
42 | int | 43 | int |
43 | mbox_get_carrier (mbox_t mbox, stream_t *pcarrier) | 44 | mbox_get_carrier (mbox_t mbox, stream_t *pcarrier) |
44 | { | 45 | { |
46 | mbox_debug_print (mbox, "get_carrier"); | ||
45 | if (mbox == NULL || pcarrier == NULL) | 47 | if (mbox == NULL || pcarrier == NULL) |
46 | return MU_ERROR_INVALID_PARAMETER; | 48 | return MU_ERROR_INVALID_PARAMETER; |
47 | 49 | ... | ... |
... | @@ -43,6 +43,16 @@ mbox_set_newmsg_cb (mbox_t mbox, int (*cb) __P ((int, void *)), void *arg) | ... | @@ -43,6 +43,16 @@ mbox_set_newmsg_cb (mbox_t mbox, int (*cb) __P ((int, void *)), void *arg) |
43 | } | 43 | } |
44 | 44 | ||
45 | int | 45 | int |
46 | mbox_set_error_cb (mbox_t mbox, int (*cb) __P ((int, void *)), void *arg) | ||
47 | { | ||
48 | if (mbox) | ||
49 | return MU_ERROR_INVALID_PARAMETER; | ||
50 | mbox->error.cb = cb; | ||
51 | mbox->error.arg = arg; | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | int | ||
46 | mbox_newmsg_cb (mbox_t mbox, int info) | 56 | mbox_newmsg_cb (mbox_t mbox, int info) |
47 | { | 57 | { |
48 | if (mbox) | 58 | if (mbox) |
... | @@ -61,3 +71,13 @@ mbox_progress_cb (mbox_t mbox, int info) | ... | @@ -61,3 +71,13 @@ mbox_progress_cb (mbox_t mbox, int info) |
61 | return mbox->progress.cb (info, mbox->progress.arg); | 71 | return mbox->progress.cb (info, mbox->progress.arg); |
62 | return 0; | 72 | return 0; |
63 | } | 73 | } |
74 | |||
75 | int | ||
76 | mbox_error_cb (mbox_t mbox, int info) | ||
77 | { | ||
78 | if (mbox) | ||
79 | return MU_ERROR_INVALID_PARAMETER; | ||
80 | if (mbox->error.cb) | ||
81 | return mbox->error.cb (info, mbox->error.arg); | ||
82 | return 0; | ||
83 | } | ... | ... |
... | @@ -29,6 +29,8 @@ mbox_close (mbox_t mbox) | ... | @@ -29,6 +29,8 @@ mbox_close (mbox_t mbox) |
29 | { | 29 | { |
30 | size_t i; | 30 | size_t i; |
31 | 31 | ||
32 | mbox_debug_print (mbox, "close"); | ||
33 | |||
32 | if (mbox == NULL) | 34 | if (mbox == NULL) |
33 | return MU_ERROR_INVALID_PARAMETER; | 35 | return MU_ERROR_INVALID_PARAMETER; |
34 | 36 | ||
... | @@ -44,31 +46,21 @@ mbox_close (mbox_t mbox) | ... | @@ -44,31 +46,21 @@ mbox_close (mbox_t mbox) |
44 | - to prepare for another scan. */ | 46 | - to prepare for another scan. */ |
45 | for (i = 0; i < mbox->umessages_count; i++) | 47 | for (i = 0; i < mbox->umessages_count; i++) |
46 | { | 48 | { |
47 | mbox_message_t mum = mbox->umessages[i]; | 49 | /* Destroy the attach streams and attribute. */ |
48 | /* Destroy the attach messages. */ | 50 | if (mbox->umessages[i]) |
49 | if (mum) | 51 | mbox_release_msg (mbox, i + 1); |
50 | { | ||
51 | mbox_hcache_free (mbox, i + 1); | ||
52 | if (mum->header.stream) | ||
53 | stream_destroy (&(mum->header.stream)); | ||
54 | if (mum->body.stream) | ||
55 | stream_destroy (&(mum->body.stream)); | ||
56 | if (mum->separator) | ||
57 | free (mum->separator); | ||
58 | if (mum->attribute) | ||
59 | attribute_destroy (&mum->attribute); | ||
60 | free (mum); | ||
61 | } | ||
62 | } | 52 | } |
63 | if (mbox->umessages) | 53 | if (mbox->umessages) |
64 | free (mbox->umessages); | 54 | free (mbox->umessages); |
65 | mbox->umessages = NULL; | 55 | mbox->umessages = NULL; |
66 | mbox->umessages_count = 0; | 56 | mbox->umessages_count = 0; |
57 | mbox->messages_count = 0; | ||
67 | mbox->size = 0; | 58 | mbox->size = 0; |
68 | mbox->uidvalidity = 0; | 59 | mbox->uidvalidity = 0; |
69 | mbox->uidnext = 0; | 60 | mbox->uidnext = 0; |
70 | if (mbox->filename) | 61 | if (mbox->filename) |
71 | free (mbox->filename); | 62 | free (mbox->filename); |
72 | mbox->filename = NULL; | 63 | mbox->filename = NULL; |
64 | |||
73 | return stream_close (mbox->carrier); | 65 | return stream_close (mbox->carrier); |
74 | } | 66 | } | ... | ... |
mailbox2/mbox/mbox_debug.c
0 → 100644
1 | /* GNU mailutils - a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Library Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | 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 Library General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Library General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | |||
22 | #include <string.h> | ||
23 | |||
24 | #include <stdio.h> | ||
25 | #include <stdarg.h> | ||
26 | #include <mailutils/error.h> | ||
27 | #include <mailutils/sys/mbox.h> | ||
28 | |||
29 | int | ||
30 | mbox_get_debug (mbox_t mbox, mu_debug_t *pdebug) | ||
31 | { | ||
32 | if (mbox == NULL || pdebug == NULL) | ||
33 | return MU_ERROR_INVALID_PARAMETER; | ||
34 | |||
35 | |||
36 | if (mbox->debug == NULL) | ||
37 | { | ||
38 | stream_t stream; | ||
39 | int status = stream_stdio_create (&stream, stderr); | ||
40 | if (status == 0) | ||
41 | status = mu_debug_stream_create (&mbox->debug, stream, 0); | ||
42 | if (status != 0) | ||
43 | return status; | ||
44 | } | ||
45 | mu_debug_ref (mbox->debug); | ||
46 | *pdebug = mbox->debug; | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | int | ||
51 | mbox_set_debug (mbox_t mbox, mu_debug_t debug) | ||
52 | { | ||
53 | if (mbox == NULL) | ||
54 | return MU_ERROR_INVALID_PARAMETER; | ||
55 | |||
56 | if (mbox->debug) | ||
57 | mu_debug_destroy (&mbox->debug); | ||
58 | mbox->debug = debug; | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | int | ||
63 | mbox_debug_print (mbox_t mbox, const char *fmt, ...) | ||
64 | { | ||
65 | if (mbox && mbox->debug) | ||
66 | { | ||
67 | char buf[128]; | ||
68 | va_list ap; | ||
69 | snprintf (buf, sizeof buf, "mbox(%s)_", | ||
70 | (mbox->filename) ? mbox->filename : ""); | ||
71 | mu_debug_print (mbox->debug, MU_DEBUG_TRACE, buf); | ||
72 | if (fmt) | ||
73 | { | ||
74 | va_start (ap, fmt); | ||
75 | vsnprintf (buf, sizeof buf, fmt, ap); | ||
76 | va_end (ap); | ||
77 | } | ||
78 | mu_debug_print (mbox->debug, MU_DEBUG_TRACE, buf); | ||
79 | mu_debug_print (mbox->debug, MU_DEBUG_TRACE, "\n"); | ||
80 | } | ||
81 | return 0; | ||
82 | } |
... | @@ -24,12 +24,109 @@ | ... | @@ -24,12 +24,109 @@ |
24 | #include <mailutils/sys/mbox.h> | 24 | #include <mailutils/sys/mbox.h> |
25 | 25 | ||
26 | void | 26 | void |
27 | mbox_release_separator (mbox_t mbox, unsigned int msgno) | ||
28 | { | ||
29 | if (mbox == NULL || msgno == 0) | ||
30 | return; | ||
31 | |||
32 | if (msgno > mbox->umessages_count) | ||
33 | return; | ||
34 | |||
35 | if (mbox->umessages[msgno - 1]->separator) | ||
36 | free (mbox->umessages[msgno - 1]->separator); | ||
37 | mbox->umessages[msgno - 1]->separator = NULL; | ||
38 | } | ||
39 | |||
40 | void | ||
41 | mbox_release_attribute (mbox_t mbox, unsigned int msgno) | ||
42 | { | ||
43 | if (mbox == NULL || msgno == 0) | ||
44 | return; | ||
45 | |||
46 | if (msgno > mbox->umessages_count) | ||
47 | return; | ||
48 | |||
49 | if (mbox->umessages[msgno - 1]->attribute) | ||
50 | _attribute_mbox_dtor (mbox->umessages[msgno - 1]->attribute); | ||
51 | mbox->umessages[msgno - 1]->attribute = NULL; | ||
52 | } | ||
53 | |||
54 | void | ||
55 | mbox_release_hstream (mbox_t mbox, unsigned int msgno) | ||
56 | { | ||
57 | if (mbox == NULL || msgno == 0) | ||
58 | return; | ||
59 | |||
60 | if (msgno > mbox->umessages_count) | ||
61 | return; | ||
62 | |||
63 | if (mbox->umessages[msgno - 1]->header.stream) | ||
64 | { | ||
65 | if (mbox->umessages[msgno - 1]->attr_userflags & MU_MBOX_HSTREAM_SET) | ||
66 | { | ||
67 | stream_destroy (&mbox->umessages[msgno - 1]->header.stream); | ||
68 | mbox->umessages[msgno - 1]->attr_userflags &= ~MU_MBOX_HSTREAM_SET; | ||
69 | } | ||
70 | else | ||
71 | _stream_mbox_dtor (mbox->umessages[msgno - 1]->header.stream); | ||
72 | } | ||
73 | mbox->umessages[msgno - 1]->header.stream = NULL; | ||
74 | } | ||
75 | |||
76 | void | ||
77 | mbox_release_bstream (mbox_t mbox, unsigned int msgno) | ||
78 | { | ||
79 | if (mbox == NULL || msgno == 0) | ||
80 | return; | ||
81 | |||
82 | if (msgno > mbox->umessages_count) | ||
83 | return; | ||
84 | |||
85 | if (mbox->umessages[msgno - 1]->body.stream) | ||
86 | { | ||
87 | if (mbox->umessages[msgno - 1]->attr_userflags & MU_MBOX_BSTREAM_SET) | ||
88 | { | ||
89 | stream_destroy (&mbox->umessages[msgno - 1]->body.stream); | ||
90 | mbox->umessages[msgno - 1]->attr_userflags &= ~MU_MBOX_BSTREAM_SET; | ||
91 | } | ||
92 | else | ||
93 | _stream_mbox_dtor (mbox->umessages[msgno - 1]->body.stream); | ||
94 | } | ||
95 | mbox->umessages[msgno - 1]->body.stream = NULL; | ||
96 | } | ||
97 | |||
98 | void | ||
99 | mbox_release_msg (mbox_t mbox, unsigned int msgno) | ||
100 | { | ||
101 | if (mbox == NULL || msgno == 0) | ||
102 | return; | ||
103 | |||
104 | if (msgno > mbox->umessages_count) | ||
105 | return; | ||
106 | |||
107 | mbox_release_hcache (mbox, msgno); | ||
108 | mbox_release_separator (mbox, msgno); | ||
109 | mbox_release_attribute (mbox, msgno); | ||
110 | mbox_release_hstream (mbox, msgno); | ||
111 | mbox_release_bstream (mbox, msgno); | ||
112 | free (mbox->umessages[msgno - 1]); | ||
113 | mbox->umessages[msgno - 1] = NULL; | ||
114 | } | ||
115 | |||
116 | void | ||
27 | mbox_destroy (mbox_t *pmbox) | 117 | mbox_destroy (mbox_t *pmbox) |
28 | { | 118 | { |
29 | if (pmbox && *pmbox) | 119 | if (pmbox && *pmbox) |
30 | { | 120 | { |
31 | mbox_t mbox = *pmbox; | 121 | mbox_t mbox = *pmbox; |
122 | mbox_debug_print (mbox, "destroy"); | ||
123 | /* _close will release all the messages. */ | ||
32 | mbox_close (mbox); | 124 | mbox_close (mbox); |
125 | if (mbox->carrier) | ||
126 | stream_destroy (&mbox->carrier); | ||
127 | if (mbox->debug) | ||
128 | mu_debug_destroy (&mbox->debug); | ||
129 | mbox_release_hcache (mbox, 0); | ||
33 | free (mbox); | 130 | free (mbox); |
34 | } | 131 | } |
35 | } | 132 | } | ... | ... |
... | @@ -128,6 +128,7 @@ mbox_expunge (mbox_t mbox, int remove_deleted) | ... | @@ -128,6 +128,7 @@ mbox_expunge (mbox_t mbox, int remove_deleted) |
128 | off_t tmp_size = 0; | 128 | off_t tmp_size = 0; |
129 | size_t save_uidvalidity = 0; /* uidvalidity is save in the first message. */ | 129 | size_t save_uidvalidity = 0; /* uidvalidity is save in the first message. */ |
130 | 130 | ||
131 | mbox_debug_print (mbox, "expunge, r=%d", remove_deleted); | ||
131 | if (mbox == NULL) | 132 | if (mbox == NULL) |
132 | return MU_ERROR_INVALID_PARAMETER; | 133 | return MU_ERROR_INVALID_PARAMETER; |
133 | 134 | ||
... | @@ -154,7 +155,7 @@ mbox_expunge (mbox_t mbox, int remove_deleted) | ... | @@ -154,7 +155,7 @@ mbox_expunge (mbox_t mbox, int remove_deleted) |
154 | { | 155 | { |
155 | if (tmp_name) | 156 | if (tmp_name) |
156 | free (tmp_name); | 157 | free (tmp_name); |
157 | /* mu_error ("Failed to create temporary file when expunging.\n"); */ | 158 | mbox_error_cb (mbox, errno); |
158 | return errno; | 159 | return errno; |
159 | } | 160 | } |
160 | 161 | ||
... | @@ -193,7 +194,7 @@ mbox_expunge (mbox_t mbox, int remove_deleted) | ... | @@ -193,7 +194,7 @@ mbox_expunge (mbox_t mbox, int remove_deleted) |
193 | mbox_destroy (&tmp_mbox); | 194 | mbox_destroy (&tmp_mbox); |
194 | remove (tmp_name); | 195 | remove (tmp_name); |
195 | free (tmp_name); | 196 | free (tmp_name); |
196 | /* mu_error ("Failed to grab the lock\n"); */ | 197 | mbox_error_cb (mbox, status); |
197 | return status; | 198 | return status; |
198 | } | 199 | } |
199 | 200 | ||
... | @@ -232,32 +233,29 @@ mbox_expunge (mbox_t mbox, int remove_deleted) | ... | @@ -232,32 +233,29 @@ mbox_expunge (mbox_t mbox, int remove_deleted) |
232 | stream_t hstream = NULL, bstream = NULL; | 233 | stream_t hstream = NULL, bstream = NULL; |
233 | attribute_t attribute = NULL; | 234 | attribute_t attribute = NULL; |
234 | char *sep = NULL; | 235 | char *sep = NULL; |
235 | /* The message was not instanciated, probably the dirty flag was | 236 | /* The message was not instanciated, create one here. */ |
236 | set by mbox_scan(), create one here. */ | 237 | if (mum->separator == NULL || mum->attribute |
237 | if (mum->separator == NULL || mum->header.stream == NULL | 238 | || mum->header.stream == NULL || mum->body.stream == NULL) |
238 | || mum->body.stream == NULL || mum->attribute == NULL) | ||
239 | { | 239 | { |
240 | if (mbox_get_hstream (mbox, i + 1, &hstream) != 0 | 240 | if ((status = mbox_get_separator (mbox, i + 1, &sep) != 0) |
241 | || mbox_get_bstream (mbox, i + 1, &bstream) != 0 | 241 | || (status = mbox_get_attribute (mbox, i + 1, &attribute) != 0) |
242 | || mbox_get_separator (mbox, i + 1, &sep) != 0 | 242 | || (status = mbox_get_hstream (mbox, i + 1, &hstream) != 0) |
243 | || mbox_get_attribute (mbox, i + 1, &attribute) != 0) | 243 | || (status = mbox_get_bstream (mbox, i + 1, &bstream) != 0)) |
244 | { | 244 | { |
245 | /* mu_error ("Error expunge:%d", __LINE__); */ | 245 | mbox_error_cb (mbox, status); |
246 | goto bailout0; | 246 | goto bailout0; |
247 | } | 247 | } |
248 | } | 248 | } |
249 | status = mbox_append_hb0 (tmp_mbox, mum->separator, mum->attribute, | 249 | status = mbox_append_hb0 (tmp_mbox, mum->separator, mum->attribute, |
250 | save_uidvalidity, mum->header.stream, | 250 | mum->header.stream, mum->body.stream, |
251 | mum->body.stream); | 251 | save_uidvalidity, mum->uid); |
252 | if (sep) | ||
253 | free (sep); | 252 | free (sep); |
253 | attribute_destroy (&attribute); | ||
254 | stream_destroy (&hstream); | 254 | stream_destroy (&hstream); |
255 | stream_destroy (&bstream); | 255 | stream_destroy (&bstream); |
256 | attribute_destroy (&attribute); | ||
257 | if (status != 0) | 256 | if (status != 0) |
258 | { | 257 | { |
259 | /* mu_error ("Error expunge:%d: %s", __LINE__, | 258 | mbox_error_cb (mbox, status); |
260 | strerror (status)); */ | ||
261 | goto bailout0; | 259 | goto bailout0; |
262 | } | 260 | } |
263 | /* Clear the dirty bits. */ | 261 | /* Clear the dirty bits. */ |
... | @@ -266,10 +264,9 @@ mbox_expunge (mbox_t mbox, int remove_deleted) | ... | @@ -266,10 +264,9 @@ mbox_expunge (mbox_t mbox, int remove_deleted) |
266 | } /* for (;;) */ | 264 | } /* for (;;) */ |
267 | 265 | ||
268 | /* Get the real size of the mailbox. The size maintain in | 266 | /* Get the real size of the mailbox. The size maintain in |
269 | the struct _mailbox { off_t size; } the one return in | 267 | the struct _mailbox { off_t size; }(the one return in |
270 | mailbox_get_size() only return the size that mbox_scan() | 268 | mailbox_get_size()) only returns the size that mbox_scan() |
271 | is aware of not necessary the size of the file after | 269 | is aware of, not necessary the size of the file after an append. */ |
272 | an append. */ | ||
273 | stream_get_size (tmp_mbox->carrier, &tmp_size); | 270 | stream_get_size (tmp_mbox->carrier, &tmp_size); |
274 | 271 | ||
275 | /* Caution: before ftruncate()ing the file see | 272 | /* Caution: before ftruncate()ing the file see |
... | @@ -281,29 +278,28 @@ mbox_expunge (mbox_t mbox, int remove_deleted) | ... | @@ -281,29 +278,28 @@ mbox_expunge (mbox_t mbox, int remove_deleted) |
281 | if (stream_get_size (mbox->carrier, &size) == 0) | 278 | if (stream_get_size (mbox->carrier, &size) == 0) |
282 | { | 279 | { |
283 | off_t len = size - mbox->size; | 280 | off_t len = size - mbox->size; |
284 | char buffer [1024]; | 281 | off_t offset = mbox->size; |
282 | char buf [1024]; | ||
285 | size_t n = 0; | 283 | size_t n = 0; |
286 | if (len > 0) | 284 | if (len > 0) |
287 | { | 285 | { |
288 | stream_seek (mbox->carrier, mbox->size, MU_STREAM_WHENCE_SET); | 286 | while ((status = stream_read (mbox->carrier, buf, sizeof buf, |
289 | stream_seek (tmp_mbox->carrier, tmp_size, MU_STREAM_WHENCE_SET); | 287 | offset, &n)) == 0 && n > 0) |
290 | while ((status = stream_read (mbox->carrier, buffer, | ||
291 | sizeof buffer, &n)) == 0 && n > 0) | ||
292 | { | 288 | { |
293 | status = stream_write (tmp_mbox->carrier, buffer, n, NULL); | 289 | status = stream_write(tmp_mbox->carrier, buf, n, tmp_size, &n); |
294 | if (status != 0) | 290 | if (status != 0) |
295 | { | 291 | { |
296 | /* mu_error ("Error expunge:%d: %s", __LINE__, | 292 | mbox_error_cb (mbox, status); |
297 | strerror (status)); */ | ||
298 | goto bailout0; | 293 | goto bailout0; |
299 | } | 294 | } |
295 | offset += n; | ||
296 | tmp_size += n; | ||
300 | } | 297 | } |
301 | } | 298 | } |
302 | else if (len < 0) | 299 | else if (len < 0) |
303 | { | 300 | { |
304 | /* Corrupted mailbox. */ | 301 | /* Corrupted mailbox. */ |
305 | /* mu_error ("Error expunge:%d: %s", __LINE__, | 302 | mbox_error_cb (mbox, status); |
306 | strerror (status)); */ | ||
307 | goto bailout0; | 303 | goto bailout0; |
308 | } | 304 | } |
309 | } | 305 | } |
... | @@ -312,32 +308,31 @@ mbox_expunge (mbox_t mbox, int remove_deleted) | ... | @@ -312,32 +308,31 @@ mbox_expunge (mbox_t mbox, int remove_deleted) |
312 | /* Seek and rewrite it. */ | 308 | /* Seek and rewrite it. */ |
313 | if (tmp_size > 0) | 309 | if (tmp_size > 0) |
314 | { | 310 | { |
315 | char buffer [1024]; | 311 | char buf [1024]; |
316 | size_t n = 0; | 312 | size_t n = 0; |
313 | off_t tmp_off = 0; | ||
314 | off_t offset = marker; | ||
317 | 315 | ||
318 | stream_seek (mbox->carrier, marker, MU_STREAM_WHENCE_SET); | 316 | while ((status = stream_read (tmp_mbox->carrier, buf, sizeof buf, |
319 | stream_seek (tmp_mbox->carrier, 0, MU_STREAM_WHENCE_SET); | 317 | tmp_off, &n)) == 0 && n > 0) |
320 | while ((status = stream_read (tmp_mbox->carrier, buffer, | ||
321 | sizeof buffer, &n)) == 0 && n > 0) | ||
322 | { | 318 | { |
323 | status = stream_write (mbox->carrier, buffer, n, &n); | 319 | status = stream_write (mbox->carrier, buf, n, offset, &n); |
324 | if (status != 0) | 320 | if (status != 0) |
325 | { | 321 | { |
326 | /* mu_error ("Error expunge:%d: %s\n", __LINE__, | 322 | mbox_error_cb (mbox, status); |
327 | strerror (status)); */ | ||
328 | goto bailout; | 323 | goto bailout; |
329 | } | 324 | } |
325 | tmp_off += n; | ||
326 | offset += n; | ||
330 | } | 327 | } |
331 | } | 328 | } |
332 | 329 | ||
333 | /* Flush/truncation. Need to flush before truncate. */ | 330 | /* Flush/truncation. Need to flush before truncate. */ |
334 | stream_get_size (tmp_mbox->carrier, &tmp_size); | ||
335 | stream_flush (mbox->carrier); | 331 | stream_flush (mbox->carrier); |
336 | status = stream_truncate (mbox->carrier, tmp_size + marker); | 332 | status = stream_truncate (mbox->carrier, tmp_size + marker); |
337 | if (status != 0) | 333 | if (status != 0) |
338 | { | 334 | { |
339 | /* mu_error ("Error expunging:%d: %s\n", __LINE__, | 335 | mbox_error_cb (mbox, status); |
340 | strerror (status)); */ | ||
341 | goto bailout; | 336 | goto bailout; |
342 | } | 337 | } |
343 | 338 | ||
... | @@ -346,7 +341,6 @@ mbox_expunge (mbox_t mbox, int remove_deleted) | ... | @@ -346,7 +341,6 @@ mbox_expunge (mbox_t mbox, int remove_deleted) |
346 | remove (tmp_name); | 341 | remove (tmp_name); |
347 | 342 | ||
348 | bailout: | 343 | bailout: |
349 | |||
350 | free (tmp_name); | 344 | free (tmp_name); |
351 | /* Release the File lock. */ | 345 | /* Release the File lock. */ |
352 | lockfile_unlock (mbox->lockfile); | 346 | lockfile_unlock (mbox->lockfile); |
... | @@ -366,47 +360,41 @@ mbox_expunge (mbox_t mbox, int remove_deleted) | ... | @@ -366,47 +360,41 @@ mbox_expunge (mbox_t mbox, int remove_deleted) |
366 | size_t dlast; | 360 | size_t dlast; |
367 | for (j = dirty, dlast = mbox->messages_count - 1; j <= dlast; j++) | 361 | for (j = dirty, dlast = mbox->messages_count - 1; j <= dlast; j++) |
368 | { | 362 | { |
369 | /* Clear all the references to streams. */ | ||
370 | mum = mbox->umessages[j]; | 363 | mum = mbox->umessages[j]; |
364 | /* Clear all the references to streams. */ | ||
371 | if (remove_deleted && ATTRIBUTE_IS_DELETED (mum->attr_flags)) | 365 | if (remove_deleted && ATTRIBUTE_IS_DELETED (mum->attr_flags)) |
372 | { | 366 | { |
373 | if (mum->separator) | 367 | mbox_release_msg (mbox, j + 1); |
374 | free (mum->separator); | ||
375 | mum->separator = NULL; | ||
376 | if (mum->attribute) | ||
377 | attribute_destroy (&mum->attribute); | ||
378 | if (mum->header.stream) | ||
379 | stream_destroy (&mum->header.stream); | ||
380 | if (mum->body.stream) | ||
381 | stream_destroy (&mum->body.stream); | ||
382 | mbox_hcache_free (mbox, i + 1); | ||
383 | /* memset (mum, 0, sizeof (*mum)); */ | ||
384 | |||
385 | if ((j + 1) <= dlast) | 368 | if ((j + 1) <= dlast) |
386 | { | 369 | { |
387 | /* Move all the pointers up. So the message pointer | 370 | /* Move all the pointers up. So the message pointers |
388 | part of mum will be at the right position. */ | 371 | will be at the right position. */ |
389 | memmove (mbox->umessages + j, mbox->umessages + j + 1, | 372 | memmove (mbox->umessages + j, mbox->umessages + j + 1, |
390 | (dlast - j) * sizeof (mum)); | 373 | (dlast - j) * sizeof mum); |
391 | #if 1 | ||
392 | mum->from_ = mum->header.start = 0; | ||
393 | mum->body.start = mum->body.end = 0; | ||
394 | mum->header.lines = mum->body.lines = 0; | ||
395 | #endif | ||
396 | /* We are not free()ing the useless mum, but instead | ||
397 | we put it back in the pool, to be reuse. */ | ||
398 | mbox->umessages[dlast] = mum; | ||
399 | dlast--; | 374 | dlast--; |
400 | /* Set mum to the new value after the memmove so it | ||
401 | gets cleared to. */ | ||
402 | mum = mbox->umessages[j]; | ||
403 | } | 375 | } |
376 | mbox->umessages_count--; | ||
377 | mbox->messages_count--; | ||
404 | } | 378 | } |
379 | else | ||
380 | { | ||
381 | /* Readjust the offsets and attach objects. */ | ||
405 | mum->from_ = mum->header.start = 0; | 382 | mum->from_ = mum->header.start = 0; |
406 | mum->body.start = mum->body.end = 0; | 383 | mum->body.start = mum->body.end = 0; |
407 | mum->header.lines = mum->body.lines = 0; | 384 | mum->header.lines = mum->body.lines = 0; |
385 | stream_mbox_msgno (mum->header.stream, j + 1); | ||
386 | stream_mbox_msgno (mum->body.stream, j + 1); | ||
387 | attribute_mbox_msgno (mum->attribute, j + 1); | ||
388 | } | ||
408 | } | 389 | } |
409 | /* This is should reset the messages_count, the last argument 0 means | 390 | |
391 | /* Must Realloc the right size before the scan. some slots | ||
392 | in the umessages may be NULL after remove_deleted. */ | ||
393 | mbox->umessages = realloc (mbox->umessages, | ||
394 | mbox->umessages_count | ||
395 | * sizeof (*(mbox->umessages))); | ||
396 | |||
397 | /* This should reset the messages_count, the last argument 0 means | ||
410 | not to send event notification. */ | 398 | not to send event notification. */ |
411 | mbox_scan (mbox, dirty, NULL, 0); | 399 | mbox_scan (mbox, dirty, NULL, 0); |
412 | } | 400 | } | ... | ... |
... | @@ -21,10 +21,15 @@ | ... | @@ -21,10 +21,15 @@ |
21 | 21 | ||
22 | #include <stdlib.h> | 22 | #include <stdlib.h> |
23 | #include <string.h> | 23 | #include <string.h> |
24 | #include <ctype.h> | ||
24 | 25 | ||
25 | #include <mailutils/error.h> | 26 | #include <mailutils/error.h> |
26 | #include <mailutils/sys/mbox.h> | 27 | #include <mailutils/sys/mbox.h> |
27 | 28 | ||
29 | #undef min | ||
30 | #define min(a,b) ((a) < (b) ? (a) : (b)) | ||
31 | |||
32 | |||
28 | static const char *hcache_default[] = | 33 | static const char *hcache_default[] = |
29 | { | 34 | { |
30 | "Bcc", | 35 | "Bcc", |
... | @@ -35,9 +40,10 @@ static const char *hcache_default[] = | ... | @@ -35,9 +40,10 @@ static const char *hcache_default[] = |
35 | "Date", | 40 | "Date", |
36 | "From", | 41 | "From", |
37 | "In-Reply-To", | 42 | "In-Reply-To", |
43 | "Mail-Followup-To", | ||
38 | "Message-ID", | 44 | "Message-ID", |
39 | "Reply-To", | 45 | "Reply-To", |
40 | "Reply-To", | 46 | "Return-Path", |
41 | "Sender", | 47 | "Sender", |
42 | "Subject", | 48 | "Subject", |
43 | "To", | 49 | "To", |
... | @@ -45,7 +51,7 @@ static const char *hcache_default[] = | ... | @@ -45,7 +51,7 @@ static const char *hcache_default[] = |
45 | }; | 51 | }; |
46 | 52 | ||
47 | void | 53 | void |
48 | mbox_hcache_free (mbox_t mbox, unsigned int msgno) | 54 | mbox_release_hcache (mbox_t mbox, unsigned int msgno) |
49 | { | 55 | { |
50 | struct _hcache *hc; | 56 | struct _hcache *hc; |
51 | 57 | ||
... | @@ -76,36 +82,51 @@ mbox_hcache_free (mbox_t mbox, unsigned int msgno) | ... | @@ -76,36 +82,51 @@ mbox_hcache_free (mbox_t mbox, unsigned int msgno) |
76 | int | 82 | int |
77 | mbox_set_hcache (mbox_t mbox, const char **array, size_t len) | 83 | mbox_set_hcache (mbox_t mbox, const char **array, size_t len) |
78 | { | 84 | { |
85 | int status = 0; | ||
86 | |||
79 | if (mbox == NULL) | 87 | if (mbox == NULL) |
80 | return MU_ERROR_INVALID_PARAMETER; | 88 | return MU_ERROR_INVALID_PARAMETER; |
81 | 89 | ||
82 | mbox_hcache_free (mbox, 0); | 90 | mbox_release_hcache (mbox, 0); |
83 | 91 | ||
84 | if (array && len) | 92 | if (array && len) |
85 | { | 93 | status = mbox_add_hcache (mbox, array, len); |
86 | unsigned int i; | ||
87 | 94 | ||
88 | mbox->hcache.values = calloc (len, sizeof (*(mbox->hcache.values))); | 95 | return status; |
96 | } | ||
89 | 97 | ||
90 | if (mbox->hcache.values == NULL) | 98 | int |
91 | return MU_ERROR_NO_MEMORY; | 99 | mbox_add_hcache (mbox_t mbox, const char **array, size_t len) |
100 | { | ||
101 | size_t i; | ||
102 | int status = 0; | ||
103 | |||
104 | if (mbox == NULL || array == NULL || len == 0) | ||
105 | return MU_ERROR_INVALID_PARAMETER; | ||
92 | 106 | ||
93 | for (i = 0; i < len; i++) | 107 | for (i = 0; i < len; i++) |
94 | { | 108 | { |
95 | mbox->hcache.values[i] = strdup (array[i]); | 109 | char **values; |
96 | if (mbox->hcache.values[i] == NULL) | 110 | if (array[i] == NULL || array[i][0] == '\0') |
111 | continue; | ||
112 | values = realloc (mbox->hcache.values, | ||
113 | (mbox->hcache.size + 1) * sizeof (*values)); | ||
114 | if (values == NULL) | ||
97 | { | 115 | { |
98 | mbox_set_hcache (mbox, NULL, 0); | 116 | status = MU_ERROR_NO_MEMORY; |
99 | return MU_ERROR_NO_MEMORY; | 117 | break; |
100 | } | 118 | } |
119 | mbox->hcache.values = values; | ||
120 | mbox->hcache.values[mbox->hcache.size] = strdup (array[i]); | ||
121 | mbox->hcache.values[mbox->hcache.size][0] = | ||
122 | toupper (mbox->hcache.values[mbox->hcache.size][0]); | ||
101 | mbox->hcache.size++; | 123 | mbox->hcache.size++; |
102 | } | 124 | } |
103 | } | 125 | return status; |
104 | return 0; | ||
105 | } | 126 | } |
106 | 127 | ||
107 | int | 128 | int |
108 | mbox_hcache_append (mbox_t mbox, unsigned int msgno, const char *name, | 129 | mbox_append_hcache (mbox_t mbox, unsigned int msgno, const char *name, |
109 | const char *value) | 130 | const char *value) |
110 | { | 131 | { |
111 | struct _hcache *hc; | 132 | struct _hcache *hc; |
... | @@ -133,7 +154,9 @@ mbox_hcache_append (mbox_t mbox, unsigned int msgno, const char *name, | ... | @@ -133,7 +154,9 @@ mbox_hcache_append (mbox_t mbox, unsigned int msgno, const char *name, |
133 | 154 | ||
134 | for (i = 0; i < mbox->hcache.size; i++) | 155 | for (i = 0; i < mbox->hcache.size; i++) |
135 | { | 156 | { |
136 | if (strcasecmp (mbox->hcache.values[i], name) == 0) | 157 | if (mbox->hcache.values[i] |
158 | && toupper (*name) == mbox->hcache.values[i][0] | ||
159 | && strcasecmp (mbox->hcache.values[i], name) == 0) | ||
137 | { | 160 | { |
138 | if (value == NULL) | 161 | if (value == NULL) |
139 | { | 162 | { |
... | @@ -164,8 +187,52 @@ mbox_hcache_append (mbox_t mbox, unsigned int msgno, const char *name, | ... | @@ -164,8 +187,52 @@ mbox_hcache_append (mbox_t mbox, unsigned int msgno, const char *name, |
164 | } | 187 | } |
165 | 188 | ||
166 | int | 189 | int |
167 | mbox_set_hcache_default (mbox_t mbox) | 190 | mbox_set_default_hcache (mbox_t mbox) |
168 | { | 191 | { |
169 | return mbox_set_hcache (mbox, hcache_default, | 192 | return mbox_set_hcache (mbox, hcache_default, |
170 | sizeof (hcache_default) / sizeof (*hcache_default)); | 193 | (sizeof hcache_default) / sizeof (*hcache_default)); |
194 | } | ||
195 | |||
196 | int | ||
197 | mbox_value_hcache (mbox_t mbox, unsigned int msgno, const char *name, | ||
198 | char *buf, size_t buflen, size_t *pn) | ||
199 | { | ||
200 | mbox_message_t mum; | ||
201 | size_t i; | ||
202 | size_t n = 0; | ||
203 | int status = MU_ERROR_ENTRY_NOT_EXIST; | ||
204 | |||
205 | mbox_debug_print (mbox, "value_hcache(%d)", msgno); | ||
206 | |||
207 | if (mbox == NULL || msgno == 0 || name == NULL || *name == '\0') | ||
208 | return MU_ERROR_INVALID_PARAMETER; | ||
209 | |||
210 | if (msgno > mbox->umessages_count) | ||
211 | return MU_ERROR_INVALID_PARAMETER; | ||
212 | |||
213 | mum = mbox->umessages[msgno - 1]; | ||
214 | for (i = 0; i < mbox->hcache.size; i++) | ||
215 | { | ||
216 | if (mbox->hcache.values[i] | ||
217 | && toupper (*name) == mbox->hcache.values[i][0] | ||
218 | && strcasecmp (mbox->hcache.values[i], name) == 0) | ||
219 | { | ||
220 | if (mum->hcache.size == mbox->hcache.size) | ||
221 | { | ||
222 | n = strlen (mum->hcache.values[i]); | ||
223 | if (buf && buflen) | ||
224 | { | ||
225 | buflen--; | ||
226 | n = min (buflen, n); | ||
227 | memcpy (buf, mum->hcache.values[i], n); | ||
228 | buf[n] = '\0'; | ||
229 | } | ||
230 | status = 0; | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | |||
235 | if (pn) | ||
236 | *pn = n; | ||
237 | return status; | ||
171 | } | 238 | } | ... | ... |
... | @@ -27,6 +27,8 @@ int | ... | @@ -27,6 +27,8 @@ int |
27 | mbox_get_hlines (mbox_t mbox, unsigned int msgno, unsigned int *plines) | 27 | mbox_get_hlines (mbox_t mbox, unsigned int msgno, unsigned int *plines) |
28 | { | 28 | { |
29 | unsigned int lines = 0; | 29 | unsigned int lines = 0; |
30 | |||
31 | mbox_debug_print (mbox, "get_lines(%u)", msgno); | ||
30 | if (mbox && msgno) | 32 | if (mbox && msgno) |
31 | { | 33 | { |
32 | msgno--; | 34 | msgno--; | ... | ... |
... | @@ -27,6 +27,8 @@ int | ... | @@ -27,6 +27,8 @@ int |
27 | mbox_get_hsize (mbox_t mbox, unsigned int msgno, unsigned int *psize) | 27 | mbox_get_hsize (mbox_t mbox, unsigned int msgno, unsigned int *psize) |
28 | { | 28 | { |
29 | unsigned int size = 0; | 29 | unsigned int size = 0; |
30 | |||
31 | mbox_debug_print (mbox, "get_hsize(%d)", msgno); | ||
30 | if (mbox && msgno) | 32 | if (mbox && msgno) |
31 | { | 33 | { |
32 | msgno--; | 34 | msgno--; | ... | ... |
... | @@ -28,6 +28,8 @@ int | ... | @@ -28,6 +28,8 @@ int |
28 | mbox_get_hstream (mbox_t mbox, unsigned int msgno, stream_t *pstream) | 28 | mbox_get_hstream (mbox_t mbox, unsigned int msgno, stream_t *pstream) |
29 | { | 29 | { |
30 | int status = 0; | 30 | int status = 0; |
31 | |||
32 | mbox_debug_print (mbox, "get_hstream(%u)", msgno); | ||
31 | if (mbox == NULL || msgno == 0 || pstream == NULL) | 33 | if (mbox == NULL || msgno == 0 || pstream == NULL) |
32 | return MU_ERROR_INVALID_PARAMETER; | 34 | return MU_ERROR_INVALID_PARAMETER; |
33 | 35 | ||
... | @@ -58,10 +60,11 @@ mbox_set_hstream (mbox_t mbox, unsigned int msgno, stream_t stream) | ... | @@ -58,10 +60,11 @@ mbox_set_hstream (mbox_t mbox, unsigned int msgno, stream_t stream) |
58 | if (msgno > mbox->umessages_count) | 60 | if (msgno > mbox->umessages_count) |
59 | return MU_ERROR_INVALID_PARAMETER; | 61 | return MU_ERROR_INVALID_PARAMETER; |
60 | 62 | ||
61 | msgno--; | 63 | if (mbox->umessages[msgno - 1]->header.stream) |
62 | if (mbox->umessages[msgno]->header.stream) | 64 | mbox_release_hstream (mbox, msgno); |
63 | stream_destroy (&mbox->umessages[msgno]->header.stream); | ||
64 | 65 | ||
65 | mbox->umessages[msgno]->header.stream = stream; | 66 | mbox->umessages[msgno - 1]->attr_flags |= MU_MBOX_HSTREAM_SET; |
67 | mbox->umessages[msgno - 1]->attr_flags |= MU_ATTRIBUTE_MODIFIED; | ||
68 | mbox->umessages[msgno - 1]->header.stream = stream; | ||
66 | return 0; | 69 | return 0; |
67 | } | 70 | } | ... | ... |
... | @@ -25,14 +25,16 @@ | ... | @@ -25,14 +25,16 @@ |
25 | #include <mailutils/sys/mbox.h> | 25 | #include <mailutils/sys/mbox.h> |
26 | 26 | ||
27 | int | 27 | int |
28 | mbox_changed_on_disk (mbox_t mbox) | 28 | mbox_has_newmail (mbox_t mbox) |
29 | { | 29 | { |
30 | int changed = 0; | 30 | int newmail = 0; |
31 | |||
32 | mbox_debug_print (mbox, "has_newmail"); | ||
31 | 33 | ||
32 | /* If the modification time is greater then the access time, the file has | 34 | /* If the modification time is greater then the access time, the file has |
33 | been modified since the last time it was accessed. This typically means | 35 | been modified since the last time it was accessed. This typically means |
34 | new mail or someone tempered with the mailbox. */ | 36 | new mail or someone tempered with the mailbox. */ |
35 | if (mbox->carrier) | 37 | if (mbox && mbox->carrier) |
36 | { | 38 | { |
37 | int fd = -1; | 39 | int fd = -1; |
38 | if (stream_get_fd (mbox->carrier, &fd) == 0) | 40 | if (stream_get_fd (mbox->carrier, &fd) == 0) |
... | @@ -41,9 +43,9 @@ mbox_changed_on_disk (mbox_t mbox) | ... | @@ -41,9 +43,9 @@ mbox_changed_on_disk (mbox_t mbox) |
41 | if (fstat (fd, &statbuf) == 0) | 43 | if (fstat (fd, &statbuf) == 0) |
42 | { | 44 | { |
43 | if (difftime (statbuf.st_mtime, statbuf.st_atime) > 0) | 45 | if (difftime (statbuf.st_mtime, statbuf.st_atime) > 0) |
44 | changed = 1; | 46 | newmail = 1; |
45 | } | 47 | } |
46 | } | 48 | } |
47 | } | 49 | } |
48 | return changed; | 50 | return newmail; |
49 | } | 51 | } | ... | ... |
... | @@ -31,6 +31,8 @@ mbox_open (mbox_t mbox, const char *filename, int flags) | ... | @@ -31,6 +31,8 @@ mbox_open (mbox_t mbox, const char *filename, int flags) |
31 | char from[12]; | 31 | char from[12]; |
32 | size_t n = 0; | 32 | size_t n = 0; |
33 | 33 | ||
34 | mbox_debug_print (mbox, "open(%s,%d)", (filename) ? filename : "", flags); | ||
35 | |||
34 | if (mbox == NULL) | 36 | if (mbox == NULL) |
35 | return MU_ERROR_INVALID_PARAMETER; | 37 | return MU_ERROR_INVALID_PARAMETER; |
36 | 38 | ||
... | @@ -49,12 +51,11 @@ mbox_open (mbox_t mbox, const char *filename, int flags) | ... | @@ -49,12 +51,11 @@ mbox_open (mbox_t mbox, const char *filename, int flags) |
49 | return status; | 51 | return status; |
50 | 52 | ||
51 | /* We need to be able to seek on the stream. */ | 53 | /* We need to be able to seek on the stream. */ |
52 | status = stream_seek (mbox->carrier, 0, MU_STREAM_WHENCE_SET); | 54 | if (!stream_is_seekable (mbox->carrier)) |
53 | if (status != 0) | 55 | return MU_ERROR_NOT_SUPPORTED; |
54 | return status; | ||
55 | 56 | ||
56 | /* Check if it is indeed a mbox format. */ | 57 | /* Check if it is indeed a mbox format. */ |
57 | stream_readline (mbox->carrier, from, sizeof from, &n); | 58 | stream_readline (mbox->carrier, from, sizeof from, 0, &n); |
58 | if (status != 0) | 59 | if (status != 0) |
59 | return status; | 60 | return status; |
60 | 61 | ... | ... |
... | @@ -75,18 +75,32 @@ mbox_parse_status (mbox_message_t mum, char *buf, size_t n) | ... | @@ -75,18 +75,32 @@ mbox_parse_status (mbox_message_t mum, char *buf, size_t n) |
75 | case 'R': | 75 | case 'R': |
76 | mum->attr_flags |= MU_ATTRIBUTE_READ; | 76 | mum->attr_flags |= MU_ATTRIBUTE_READ; |
77 | break; | 77 | break; |
78 | |||
78 | case 'O': | 79 | case 'O': |
79 | case 'o': | 80 | case 'o': |
80 | mum->attr_flags |= MU_ATTRIBUTE_SEEN; | 81 | mum->attr_flags |= MU_ATTRIBUTE_SEEN; |
81 | break; | 82 | break; |
83 | |||
82 | case 'a': | 84 | case 'a': |
83 | case 'A': | 85 | case 'A': |
84 | mum->attr_flags |= MU_ATTRIBUTE_ANSWERED; | 86 | mum->attr_flags |= MU_ATTRIBUTE_ANSWERED; |
85 | break; | 87 | break; |
88 | |||
86 | case 'd': | 89 | case 'd': |
87 | case 'D': | 90 | case 'D': |
88 | mum->attr_flags |= MU_ATTRIBUTE_DELETED; | 91 | mum->attr_flags |= MU_ATTRIBUTE_DELETED; |
89 | break; | 92 | break; |
93 | |||
94 | case 't': | ||
95 | case 'T': | ||
96 | mum->attr_flags |= MU_ATTRIBUTE_DRAFT; | ||
97 | break; | ||
98 | |||
99 | case 'f': | ||
100 | case 'F': | ||
101 | mum->attr_flags |= MU_ATTRIBUTE_FLAGGED; | ||
102 | break; | ||
103 | |||
90 | } | 104 | } |
91 | } | 105 | } |
92 | } | 106 | } |
... | @@ -96,8 +110,6 @@ mbox_parse_status (mbox_message_t mum, char *buf, size_t n) | ... | @@ -96,8 +110,6 @@ mbox_parse_status (mbox_message_t mum, char *buf, size_t n) |
96 | static int | 110 | static int |
97 | mbox_alloc_umessages (mbox_t mbox) | 111 | mbox_alloc_umessages (mbox_t mbox) |
98 | { | 112 | { |
99 | mbox_message_t mum; | ||
100 | unsigned int msgno = 0; | ||
101 | if (mbox->messages_count >= mbox->umessages_count) | 113 | if (mbox->messages_count >= mbox->umessages_count) |
102 | { | 114 | { |
103 | mbox_message_t *m; | 115 | mbox_message_t *m; |
... | @@ -115,11 +127,6 @@ mbox_alloc_umessages (mbox_t mbox) | ... | @@ -115,11 +127,6 @@ mbox_alloc_umessages (mbox_t mbox) |
115 | return MU_ERROR_NO_MEMORY; | 127 | return MU_ERROR_NO_MEMORY; |
116 | } | 128 | } |
117 | } | 129 | } |
118 | if (mum->separator) | ||
119 | free (mum->separator); | ||
120 | mum->separator = 0; | ||
121 | |||
122 | mbox_hcache_free (mbox, msgno + 1); | ||
123 | return 0; | 130 | return 0; |
124 | } | 131 | } |
125 | 132 | ||
... | @@ -148,6 +155,8 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) | ... | @@ -148,6 +155,8 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) |
148 | int zn, isfrom = 0; | 155 | int zn, isfrom = 0; |
149 | char *temp; | 156 | char *temp; |
150 | 157 | ||
158 | mbox_debug_print (mbox, "scan(%u,%d)", msgno, do_notif); | ||
159 | |||
151 | if (mbox == NULL) | 160 | if (mbox == NULL) |
152 | return MU_ERROR_INVALID_PARAMETER; | 161 | return MU_ERROR_INVALID_PARAMETER; |
153 | 162 | ||
... | @@ -170,14 +179,18 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) | ... | @@ -170,14 +179,18 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) |
170 | 179 | ||
171 | /* Move along, move along nothing to see. */ | 180 | /* Move along, move along nothing to see. */ |
172 | if (!mbox_has_newmail (mbox) && mbox->size == file_size) | 181 | if (!mbox_has_newmail (mbox) && mbox->size == file_size) |
182 | { | ||
183 | if (pcount) | ||
184 | *pcount = mbox->messages_count; | ||
173 | return 0; | 185 | return 0; |
186 | } | ||
174 | 187 | ||
175 | /* Bailout early on error. */ | 188 | /* Bailout early on error. */ |
176 | if (status != 0) | 189 | if (status != 0) |
177 | return status; | 190 | return status; |
178 | 191 | ||
179 | if (mbox->hcache.size == 0) | 192 | if (mbox->hcache.size == 0) |
180 | mbox_set_hcache_default (mbox); | 193 | mbox_set_default_hcache (mbox); |
181 | 194 | ||
182 | /* Lock the mbox before starting. */ | 195 | /* Lock the mbox before starting. */ |
183 | /* FIXME: Check error.. */ | 196 | /* FIXME: Check error.. */ |
... | @@ -199,15 +212,8 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) | ... | @@ -199,15 +212,8 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) |
199 | errno = lines = inheader = inbody = 0; | 212 | errno = lines = inheader = inbody = 0; |
200 | mum = NULL; | 213 | mum = NULL; |
201 | 214 | ||
202 | status = stream_seek (mbox->carrier, total, MU_STREAM_WHENCE_SET); | 215 | while ((status = stream_readline (mbox->carrier, buf, sizeof buf, |
203 | if (status != 0) | 216 | total, &n)) == 0 && n > 0) |
204 | { | ||
205 | lockfile_unlock (mbox->lockfile); | ||
206 | return status; | ||
207 | } | ||
208 | |||
209 | while ((status = stream_readline (mbox->carrier, buf, sizeof buf, &n)) == 0 | ||
210 | && n > 0) | ||
211 | { | 217 | { |
212 | int nl; | 218 | int nl; |
213 | total += n; | 219 | total += n; |
... | @@ -242,7 +248,6 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) | ... | @@ -242,7 +248,6 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) |
242 | lockfile_unlock (mbox->lockfile); | 248 | lockfile_unlock (mbox->lockfile); |
243 | return status; | 249 | return status; |
244 | } | 250 | } |
245 | stream_seek (mbox->carrier, total, MU_STREAM_WHENCE_SET); | ||
246 | } | 251 | } |
247 | } | 252 | } |
248 | /* Allocate_msgs will initialize mum. */ | 253 | /* Allocate_msgs will initialize mum. */ |
... | @@ -287,7 +292,7 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) | ... | @@ -287,7 +292,7 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) |
287 | { | 292 | { |
288 | if (buf[n - 1] == '\n') | 293 | if (buf[n - 1] == '\n') |
289 | buf[n - 1] = 0; | 294 | buf[n - 1] = 0; |
290 | mbox_hcache_append (mbox, mbox->messages_count, sfield, buf); | 295 | mbox_append_hcache (mbox, mbox->messages_count, sfield, buf); |
291 | } | 296 | } |
292 | else | 297 | else |
293 | { | 298 | { |
... | @@ -299,9 +304,10 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) | ... | @@ -299,9 +304,10 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) |
299 | { | 304 | { |
300 | *s = '\0'; | 305 | *s = '\0'; |
301 | s++; | 306 | s++; |
307 | while (*s == ' ') s++; | ||
302 | if (buf[n - 1] == '\n') | 308 | if (buf[n - 1] == '\n') |
303 | buf[n - 1] = 0; | 309 | buf[n - 1] = 0; |
304 | mbox_hcache_append (mbox, mbox->messages_count, buf, s); | 310 | mbox_append_hcache (mbox, mbox->messages_count, buf, s); |
305 | sfield = strdup (buf); | 311 | sfield = strdup (buf); |
306 | } | 312 | } |
307 | } | 313 | } |
... | @@ -341,7 +347,7 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) | ... | @@ -341,7 +347,7 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) |
341 | 347 | ||
342 | if (mum) | 348 | if (mum) |
343 | { | 349 | { |
344 | mum->body.end = total - newline; | 350 | mum->body.end = total; |
345 | mum->body.lines = lines - newline; | 351 | mum->body.lines = lines - newline; |
346 | if (do_notif) | 352 | if (do_notif) |
347 | mbox_newmsg_cb (mbox, mbox->messages_count); | 353 | mbox_newmsg_cb (mbox, mbox->messages_count); |
... | @@ -358,10 +364,12 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) | ... | @@ -358,10 +364,12 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) |
358 | { | 364 | { |
359 | mbox->uidvalidity = (unsigned long)time (NULL); | 365 | mbox->uidvalidity = (unsigned long)time (NULL); |
360 | mbox->uidnext = mbox->messages_count + 1; | 366 | mbox->uidnext = mbox->messages_count + 1; |
361 | /* Tell that we have been modified for expunging. */ | 367 | /* The uidvalidity was not save, flag it to be save |
368 | when expunging. */ | ||
362 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; | 369 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; |
363 | } | 370 | } |
364 | } | 371 | } |
372 | |||
365 | /* Reset the IMAP uids, if necessary. UID according to IMAP RFC is a 32 bit | 373 | /* Reset the IMAP uids, if necessary. UID according to IMAP RFC is a 32 bit |
366 | ascending number for each messages */ | 374 | ascending number for each messages */ |
367 | { | 375 | { |
... | @@ -376,7 +384,8 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) | ... | @@ -376,7 +384,8 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) |
376 | { | 384 | { |
377 | uid = ouid + 1; | 385 | uid = ouid + 1; |
378 | mum->uid = ouid = uid; | 386 | mum->uid = ouid = uid; |
379 | /* Note that modification for when expunging. */ | 387 | /* UID was not ascentind, clear this when expunging by |
388 | setting modification flag. */ | ||
380 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; | 389 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; |
381 | } | 390 | } |
382 | else | 391 | else |
... | @@ -386,8 +395,26 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) | ... | @@ -386,8 +395,26 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif) |
386 | { | 395 | { |
387 | mum = mbox->umessages[0]; | 396 | mum = mbox->umessages[0]; |
388 | mbox->uidnext = uid + 1; | 397 | mbox->uidnext = uid + 1; |
398 | /* The uidnext was wrong rewrite it when expunging. */ | ||
389 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; | 399 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; |
390 | } | 400 | } |
391 | } | 401 | } |
402 | |||
403 | /* If reserved more memory then scan messages, realloc not | ||
404 | to waste memory. */ | ||
405 | if (mbox->messages_count && mbox->messages_count < mbox->umessages_count) | ||
406 | { | ||
407 | size_t i; | ||
408 | for (i = mbox->messages_count; i < mbox->umessages_count; i++) | ||
409 | { | ||
410 | if (mbox->umessages[i]) | ||
411 | mbox_release_msg (mbox, i + 1); | ||
412 | } | ||
413 | mbox->umessages = realloc (mbox->umessages, | ||
414 | mbox->messages_count | ||
415 | * sizeof (*(mbox->umessages))); | ||
416 | mbox->umessages_count = mbox->messages_count; | ||
417 | } | ||
418 | lockfile_unlock (mbox->lockfile); | ||
392 | return status; | 419 | return status; |
393 | } | 420 | } | ... | ... |
... | @@ -32,6 +32,8 @@ int | ... | @@ -32,6 +32,8 @@ int |
32 | mbox_get_separator (mbox_t mbox, unsigned int msgno, char **psep) | 32 | mbox_get_separator (mbox_t mbox, unsigned int msgno, char **psep) |
33 | { | 33 | { |
34 | 34 | ||
35 | mbox_debug_print (mbox, "get_separator(%u)", msgno); | ||
36 | |||
35 | if (mbox == NULL || msgno == 0 || psep == NULL) | 37 | if (mbox == NULL || msgno == 0 || psep == NULL) |
36 | return MU_ERROR_INVALID_PARAMETER; | 38 | return MU_ERROR_INVALID_PARAMETER; |
37 | 39 | ||
... | @@ -48,6 +50,7 @@ mbox_get_separator (mbox_t mbox, unsigned int msgno, char **psep) | ... | @@ -48,6 +50,7 @@ mbox_get_separator (mbox_t mbox, unsigned int msgno, char **psep) |
48 | char *p = NULL; | 50 | char *p = NULL; |
49 | int len = 0 ; | 51 | int len = 0 ; |
50 | size_t n = 0; | 52 | size_t n = 0; |
53 | off_t offset = mbox->umessages[msgno]->from_; | ||
51 | 54 | ||
52 | len = 2; | 55 | len = 2; |
53 | p = malloc (len); | 56 | p = malloc (len); |
... | @@ -57,8 +60,6 @@ mbox_get_separator (mbox_t mbox, unsigned int msgno, char **psep) | ... | @@ -57,8 +60,6 @@ mbox_get_separator (mbox_t mbox, unsigned int msgno, char **psep) |
57 | do | 60 | do |
58 | { | 61 | { |
59 | char *s; | 62 | char *s; |
60 | stream_seek (mbox->carrier, mbox->umessages[msgno]->from_, | ||
61 | MU_STREAM_WHENCE_SET); | ||
62 | len += 128; | 63 | len += 128; |
63 | s = realloc (p, len); | 64 | s = realloc (p, len); |
64 | if (s == NULL) | 65 | if (s == NULL) |
... | @@ -67,7 +68,8 @@ mbox_get_separator (mbox_t mbox, unsigned int msgno, char **psep) | ... | @@ -67,7 +68,8 @@ mbox_get_separator (mbox_t mbox, unsigned int msgno, char **psep) |
67 | return MU_ERROR_NO_MEMORY; | 68 | return MU_ERROR_NO_MEMORY; |
68 | } | 69 | } |
69 | p = s ; | 70 | p = s ; |
70 | stream_readline (mbox->carrier, p + strlen (p), len, &n); | 71 | stream_readline (mbox->carrier, p + strlen (p), len, offset, &n); |
72 | offset += n; | ||
71 | n = strlen (p); | 73 | n = strlen (p); |
72 | } while (n && p[n - 1] != '\n'); | 74 | } while (n && p[n - 1] != '\n'); |
73 | 75 | ||
... | @@ -95,5 +97,6 @@ mbox_set_separator (mbox_t mbox, unsigned int msgno, const char *sep) | ... | @@ -95,5 +97,6 @@ mbox_set_separator (mbox_t mbox, unsigned int msgno, const char *sep) |
95 | if (mbox->umessages[msgno]->separator) | 97 | if (mbox->umessages[msgno]->separator) |
96 | free (mbox->umessages[msgno]->separator); | 98 | free (mbox->umessages[msgno]->separator); |
97 | mbox->umessages[msgno]->separator = (sep) ? strdup (sep) : NULL; | 99 | mbox->umessages[msgno]->separator = (sep) ? strdup (sep) : NULL; |
100 | mbox->umessage[msgno]->attr_flags |= MU_ATTRIBUTE_MODIFIED; | ||
98 | return 0; | 101 | return 0; |
99 | } | 102 | } | ... | ... |
... | @@ -25,6 +25,7 @@ | ... | @@ -25,6 +25,7 @@ |
25 | int | 25 | int |
26 | mbox_get_size (mbox_t mbox, off_t *size) | 26 | mbox_get_size (mbox_t mbox, off_t *size) |
27 | { | 27 | { |
28 | mbox_debug_print (mbox, "get_size"); | ||
28 | if (mbox && size) | 29 | if (mbox && size) |
29 | *size = mbox->size; | 30 | *size = mbox->size; |
30 | return 0; | 31 | return 0; | ... | ... |
... | @@ -36,7 +36,6 @@ struct _stream_mbox | ... | @@ -36,7 +36,6 @@ struct _stream_mbox |
36 | mbox_t mbox; | 36 | mbox_t mbox; |
37 | unsigned int msgno; | 37 | unsigned int msgno; |
38 | int is_header; | 38 | int is_header; |
39 | off_t offset; | ||
40 | }; | 39 | }; |
41 | 40 | ||
42 | static int | 41 | static int |
... | @@ -52,21 +51,23 @@ _stream_mbox_destroy (stream_t *pstream) | ... | @@ -52,21 +51,23 @@ _stream_mbox_destroy (stream_t *pstream) |
52 | struct _stream_mbox *ms = (struct _stream_mbox *)*pstream; | 51 | struct _stream_mbox *ms = (struct _stream_mbox *)*pstream; |
53 | if (mu_refcount_dec (ms->refcount) == 0) | 52 | if (mu_refcount_dec (ms->refcount) == 0) |
54 | { | 53 | { |
55 | if (ms->msgno <= ms->mbox->messages_count) | ||
56 | { | ||
57 | mu_refcount_destroy (&ms->refcount); | 54 | mu_refcount_destroy (&ms->refcount); |
58 | if (ms->is_header) | 55 | if (ms->mbox && ms->msgno && ms->msgno <= ms->mbox->messages_count) |
56 | { | ||
57 | /* Loose the reference only if it is the same that we saved | ||
58 | on the mailbox. */ | ||
59 | if (ms->is_header && ms == (struct _stream_mbox *) | ||
60 | (ms->mbox->umessages[ms->msgno - 1]->header.stream)) | ||
59 | { | 61 | { |
60 | if (ms == (struct _stream_mbox *)ms->mbox->umessages[ms->msgno - 1]->header.stream) | ||
61 | ms->mbox->umessages[ms->msgno - 1]->header.stream = NULL; | 62 | ms->mbox->umessages[ms->msgno - 1]->header.stream = NULL; |
62 | } | 63 | } |
63 | else | 64 | else if (ms == (struct _stream_mbox *) |
65 | (ms->mbox->umessages[ms->msgno - 1]->body.stream)) | ||
64 | { | 66 | { |
65 | if (ms == (struct _stream_mbox *)ms->mbox->umessages[ms->msgno - 1]->body.stream) | ||
66 | ms->mbox->umessages[ms->msgno - 1]->body.stream = NULL; | 67 | ms->mbox->umessages[ms->msgno - 1]->body.stream = NULL; |
67 | } | 68 | } |
68 | free (ms); | ||
69 | } | 69 | } |
70 | free (ms); | ||
70 | } | 71 | } |
71 | } | 72 | } |
72 | 73 | ||
... | @@ -85,44 +86,59 @@ _stream_mbox_close (stream_t stream) | ... | @@ -85,44 +86,59 @@ _stream_mbox_close (stream_t stream) |
85 | } | 86 | } |
86 | 87 | ||
87 | static int | 88 | static int |
88 | _stream_mbox_read (stream_t stream, void *buf, size_t buflen, size_t *pnread) | 89 | _stream_mbox_read0 (stream_t carrier, void *buf, size_t buflen, off_t off, |
90 | size_t *pn, off_t start, off_t end) | ||
91 | { | ||
92 | off_t ln = end - (start + off); | ||
93 | int status = 0; | ||
94 | if (ln > 0) | ||
95 | { | ||
96 | size_t n = min ((size_t)ln, buflen); | ||
97 | status = stream_read (carrier, buf, n, start + off, pn); | ||
98 | } | ||
99 | return status; | ||
100 | } | ||
101 | |||
102 | static int | ||
103 | _stream_mbox_read (stream_t stream, void *buf, size_t buflen, off_t off, | ||
104 | size_t *pnread) | ||
89 | { | 105 | { |
90 | int status = 0; | 106 | int status = 0; |
91 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; | 107 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; |
92 | size_t nread = 0; | 108 | size_t n = 0; |
93 | 109 | ||
94 | if (buf && buflen) | 110 | if (buf && buflen) |
95 | { | 111 | { |
96 | if (ms->msgno <= ms->mbox->messages_count) | 112 | if (ms->mbox && ms->msgno && ms->msgno <= ms->mbox->messages_count) |
97 | { | 113 | { |
98 | off_t ln; | 114 | mbox_message_t mum = ms->mbox->umessages[ms->msgno - 1]; |
99 | mbox_message_t umessage = ms->mbox->umessages[ms->msgno - 1]; | ||
100 | if (ms->is_header) | 115 | if (ms->is_header) |
101 | ln = umessage->header.end - (umessage->header.start + ms->offset); | 116 | status = _stream_mbox_read0 (ms->mbox->carrier, buf, buflen, off, |
117 | &n, mum->header.start, | ||
118 | mum->header.end); | ||
102 | else | 119 | else |
103 | ln = umessage->body.end - (umessage->body.start + ms->offset); | 120 | status = _stream_mbox_read0 (ms->mbox->carrier, buf, buflen, off, |
121 | &n, mum->header.start, | ||
122 | mum->header.end); | ||
123 | } | ||
124 | } | ||
104 | 125 | ||
126 | if (pnread) | ||
127 | *pnread = n; | ||
128 | return status; | ||
129 | } | ||
130 | |||
131 | static int | ||
132 | _stream_mbox_readline0 (stream_t carrier, char *buf, size_t buflen, off_t off, | ||
133 | size_t *pn, off_t start, off_t end) | ||
134 | { | ||
135 | off_t ln = end - (start + off); | ||
136 | int status = 0; | ||
105 | if (ln > 0) | 137 | if (ln > 0) |
106 | { | 138 | { |
107 | size_t n = min ((size_t)ln, buflen); | 139 | size_t n = min ((size_t)ln, buflen); |
108 | /* Position the file pointer. */ | 140 | status = stream_readline (carrier, buf, n, start + off, pn); |
109 | if (ms->is_header) | ||
110 | status = stream_seek (ms->mbox->carrier, umessage->header.start | ||
111 | + ms->offset, MU_STREAM_WHENCE_SET); | ||
112 | else | ||
113 | status = stream_seek (ms->mbox->carrier, umessage->body.start | ||
114 | + ms->offset, MU_STREAM_WHENCE_SET); | ||
115 | if (status == 0) | ||
116 | { | ||
117 | status = stream_read (ms->mbox->carrier, buf, n, &nread); | ||
118 | ms->offset += nread; | ||
119 | } | 141 | } |
120 | } | ||
121 | } | ||
122 | } | ||
123 | |||
124 | if (pnread) | ||
125 | *pnread = nread; | ||
126 | return status; | 142 | return status; |
127 | } | 143 | } |
128 | 144 | ||
... | @@ -131,7 +147,7 @@ _stream_mbox_read (stream_t stream, void *buf, size_t buflen, size_t *pnread) | ... | @@ -131,7 +147,7 @@ _stream_mbox_read (stream_t stream, void *buf, size_t buflen, size_t *pnread) |
131 | * Stop when a newline has been read, or the count runs out. | 147 | * Stop when a newline has been read, or the count runs out. |
132 | */ | 148 | */ |
133 | static int | 149 | static int |
134 | _stream_mbox_readline (stream_t stream, char *buf, size_t buflen, | 150 | _stream_mbox_readline (stream_t stream, char *buf, size_t buflen, off_t off, |
135 | size_t *pnread) | 151 | size_t *pnread) |
136 | { | 152 | { |
137 | int status = 0; | 153 | int status = 0; |
... | @@ -140,31 +156,17 @@ _stream_mbox_readline (stream_t stream, char *buf, size_t buflen, | ... | @@ -140,31 +156,17 @@ _stream_mbox_readline (stream_t stream, char *buf, size_t buflen, |
140 | 156 | ||
141 | if (buf && buflen) | 157 | if (buf && buflen) |
142 | { | 158 | { |
143 | if (ms->msgno <= ms->mbox->messages_count) | 159 | if (ms->mbox && ms->msgno && ms->msgno <= ms->mbox->messages_count) |
144 | { | 160 | { |
145 | off_t ln; | 161 | mbox_message_t mum = ms->mbox->umessages[ms->msgno - 1]; |
146 | mbox_message_t umessage = ms->mbox->umessages[ms->msgno - 1]; | ||
147 | if (ms->is_header) | 162 | if (ms->is_header) |
148 | ln = umessage->header.end - (umessage->header.start + ms->offset); | 163 | status = _stream_mbox_readline0 (ms->mbox->carrier, buf, buflen, |
164 | off, &nread, mum->header.start, | ||
165 | mum->header.end); | ||
149 | else | 166 | else |
150 | ln = umessage->body.end - (umessage->body.start + ms->offset); | 167 | status = _stream_mbox_readline0 (ms->mbox->carrier, buf, buflen, |
151 | 168 | off, &nread, mum->body.start, | |
152 | if (ln > 0) | 169 | mum->body.end); |
153 | { | ||
154 | size_t n = min ((size_t)ln, buflen); | ||
155 | /* Position the stream. */ | ||
156 | if (ms->is_header) | ||
157 | status = stream_seek (ms->mbox->carrier, umessage->header.start | ||
158 | + ms->offset, MU_STREAM_WHENCE_SET); | ||
159 | else | ||
160 | status = stream_seek (ms->mbox->carrier, umessage->body.start | ||
161 | + ms->offset, MU_STREAM_WHENCE_SET); | ||
162 | if (status == 0) | ||
163 | { | ||
164 | status = stream_readline (ms->mbox->carrier, buf, n, &nread); | ||
165 | ms->offset += nread; | ||
166 | } | ||
167 | } | ||
168 | } | 170 | } |
169 | } | 171 | } |
170 | 172 | ||
... | @@ -174,10 +176,10 @@ _stream_mbox_readline (stream_t stream, char *buf, size_t buflen, | ... | @@ -174,10 +176,10 @@ _stream_mbox_readline (stream_t stream, char *buf, size_t buflen, |
174 | } | 176 | } |
175 | 177 | ||
176 | static int | 178 | static int |
177 | _stream_mbox_write (stream_t stream, const void *buf, size_t count, | 179 | _stream_mbox_write (stream_t stream, const void *buf, size_t buflen, off_t off, |
178 | size_t *pnwrite) | 180 | size_t *pnwrite) |
179 | { | 181 | { |
180 | (void)stream; (void)buf; (void)count; (void)pnwrite; | 182 | (void)stream; (void)buf; (void)buflen; (void)off, (void)pnwrite; |
181 | return MU_ERROR_IO; | 183 | return MU_ERROR_IO; |
182 | } | 184 | } |
183 | 185 | ||
... | @@ -185,14 +187,18 @@ static int | ... | @@ -185,14 +187,18 @@ static int |
185 | _stream_mbox_get_fd (stream_t stream, int *pfd) | 187 | _stream_mbox_get_fd (stream_t stream, int *pfd) |
186 | { | 188 | { |
187 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; | 189 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; |
190 | if (ms->mbox) | ||
188 | return stream_get_fd (ms->mbox->carrier, pfd); | 191 | return stream_get_fd (ms->mbox->carrier, pfd); |
192 | return MU_ERROR_IO; | ||
189 | } | 193 | } |
190 | 194 | ||
191 | static int | 195 | static int |
192 | _stream_mbox_get_flags (stream_t stream, int *pfl) | 196 | _stream_mbox_get_flags (stream_t stream, int *pfl) |
193 | { | 197 | { |
194 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; | 198 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; |
199 | if (ms->mbox) | ||
195 | return stream_get_flags (ms->mbox->carrier, pfl); | 200 | return stream_get_flags (ms->mbox->carrier, pfl); |
201 | return MU_ERROR_IO; | ||
196 | } | 202 | } |
197 | 203 | ||
198 | static int | 204 | static int |
... | @@ -202,7 +208,7 @@ _stream_mbox_get_size (stream_t stream, off_t *psize) | ... | @@ -202,7 +208,7 @@ _stream_mbox_get_size (stream_t stream, off_t *psize) |
202 | 208 | ||
203 | if (psize) | 209 | if (psize) |
204 | { | 210 | { |
205 | if (ms->msgno <= ms->mbox->messages_count) | 211 | if (ms->mbox && ms->msgno && ms->msgno <= ms->mbox->messages_count) |
206 | { | 212 | { |
207 | if (ms->is_header) | 213 | if (ms->is_header) |
208 | *psize = ms->mbox->umessages[ms->msgno - 1]->header.end | 214 | *psize = ms->mbox->umessages[ms->msgno - 1]->header.end |
... | @@ -211,6 +217,8 @@ _stream_mbox_get_size (stream_t stream, off_t *psize) | ... | @@ -211,6 +217,8 @@ _stream_mbox_get_size (stream_t stream, off_t *psize) |
211 | *psize = ms->mbox->umessages[ms->msgno - 1]->body.end | 217 | *psize = ms->mbox->umessages[ms->msgno - 1]->body.end |
212 | - ms->mbox->umessages[ms->msgno - 1]->body.start; | 218 | - ms->mbox->umessages[ms->msgno - 1]->body.start; |
213 | } | 219 | } |
220 | else | ||
221 | *psize = 0; | ||
214 | } | 222 | } |
215 | return 0; | 223 | return 0; |
216 | } | 224 | } |
... | @@ -233,49 +241,36 @@ static int | ... | @@ -233,49 +241,36 @@ static int |
233 | _stream_mbox_get_state (stream_t stream, enum stream_state *pstate) | 241 | _stream_mbox_get_state (stream_t stream, enum stream_state *pstate) |
234 | { | 242 | { |
235 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; | 243 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; |
244 | if (ms->mbox) | ||
236 | return stream_get_state (ms->mbox->carrier, pstate); | 245 | return stream_get_state (ms->mbox->carrier, pstate); |
246 | return MU_ERROR_IO; | ||
237 | } | 247 | } |
238 | 248 | ||
239 | static int | 249 | static int |
240 | _stream_mbox_seek (stream_t stream, off_t off, enum stream_whence whence) | 250 | _stream_mbox_is_seekable (stream_t stream) |
241 | { | 251 | { |
242 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; | 252 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; |
243 | off_t noff = ms->offset; | 253 | if (ms->mbox) |
244 | int err = 0; | 254 | return stream_is_seekable (ms->mbox->carrier); |
245 | if (whence == MU_STREAM_WHENCE_SET) | 255 | return MU_ERROR_IO; |
246 | noff = off; | ||
247 | else if (whence == MU_STREAM_WHENCE_CUR) | ||
248 | noff += off; | ||
249 | else if (whence == MU_STREAM_WHENCE_END) | ||
250 | { | ||
251 | off_t size = 0; | ||
252 | _stream_mbox_get_size (stream, &size); | ||
253 | noff = size + off; | ||
254 | } | ||
255 | else | ||
256 | noff = -1; /* error. */ | ||
257 | if (noff >= 0) | ||
258 | ms->offset = noff; | ||
259 | else | ||
260 | err = MU_ERROR_INVALID_PARAMETER; | ||
261 | return err; | ||
262 | } | 256 | } |
263 | 257 | ||
264 | static int | 258 | static int |
265 | _stream_mbox_tell (stream_t stream, off_t *off) | 259 | _stream_mbox_tell (stream_t stream, off_t *off) |
266 | { | 260 | { |
267 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; | 261 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; |
268 | if (off == NULL) | 262 | if (ms->mbox) |
269 | return MU_ERROR_INVALID_PARAMETER; | 263 | return stream_tell (ms->mbox->carrier, off); |
270 | *off = ms->offset; | 264 | return MU_ERROR_IO; |
271 | return 0; | ||
272 | } | 265 | } |
273 | 266 | ||
274 | static int | 267 | static int |
275 | _stream_mbox_is_readready (stream_t stream, int timeout) | 268 | _stream_mbox_is_readready (stream_t stream, int timeout) |
276 | { | 269 | { |
277 | (void)timeout; | 270 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; |
278 | return stream_is_open (stream); | 271 | if (ms->mbox) |
272 | return stream_is_readready (ms->mbox->carrier, timeout); | ||
273 | return MU_ERROR_IO; | ||
279 | } | 274 | } |
280 | 275 | ||
281 | static int | 276 | static int |
... | @@ -296,7 +291,9 @@ static int | ... | @@ -296,7 +291,9 @@ static int |
296 | _stream_mbox_is_open (stream_t stream) | 291 | _stream_mbox_is_open (stream_t stream) |
297 | { | 292 | { |
298 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; | 293 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; |
294 | if (ms->mbox) | ||
299 | return stream_is_open (ms->mbox->carrier); | 295 | return stream_is_open (ms->mbox->carrier); |
296 | return MU_ERROR_IO; | ||
300 | } | 297 | } |
301 | 298 | ||
302 | 299 | ||
... | @@ -312,7 +309,6 @@ static struct _stream_vtable _stream_mbox_vtable = | ... | @@ -312,7 +309,6 @@ static struct _stream_vtable _stream_mbox_vtable = |
312 | _stream_mbox_readline, | 309 | _stream_mbox_readline, |
313 | _stream_mbox_write, | 310 | _stream_mbox_write, |
314 | 311 | ||
315 | _stream_mbox_seek, | ||
316 | _stream_mbox_tell, | 312 | _stream_mbox_tell, |
317 | 313 | ||
318 | _stream_mbox_get_size, | 314 | _stream_mbox_get_size, |
... | @@ -323,6 +319,7 @@ static struct _stream_vtable _stream_mbox_vtable = | ... | @@ -323,6 +319,7 @@ static struct _stream_vtable _stream_mbox_vtable = |
323 | _stream_mbox_get_flags, | 319 | _stream_mbox_get_flags, |
324 | _stream_mbox_get_state, | 320 | _stream_mbox_get_state, |
325 | 321 | ||
322 | _stream_mbox_is_seekable, | ||
326 | _stream_mbox_is_readready, | 323 | _stream_mbox_is_readready, |
327 | _stream_mbox_is_writeready, | 324 | _stream_mbox_is_writeready, |
328 | _stream_mbox_is_exceptionpending, | 325 | _stream_mbox_is_exceptionpending, |
... | @@ -334,24 +331,50 @@ static int | ... | @@ -334,24 +331,50 @@ static int |
334 | _stream_mbox_ctor (struct _stream_mbox *ms, mbox_t mbox, unsigned int msgno, | 331 | _stream_mbox_ctor (struct _stream_mbox *ms, mbox_t mbox, unsigned int msgno, |
335 | int is_header) | 332 | int is_header) |
336 | { | 333 | { |
337 | mu_refcount_create (&(ms->refcount)); | 334 | mu_refcount_create (&ms->refcount); |
338 | if (ms->refcount == NULL) | 335 | if (ms->refcount == NULL) |
339 | return MU_ERROR_NO_MEMORY; | 336 | return MU_ERROR_NO_MEMORY; |
340 | 337 | ||
341 | ms->mbox = mbox; | 338 | ms->mbox = mbox; |
342 | ms->msgno = msgno; | 339 | ms->msgno = msgno; |
343 | ms->offset = 0; | ||
344 | ms->is_header = is_header; | 340 | ms->is_header = is_header; |
345 | ms->base.vtable = &_stream_mbox_vtable; | 341 | ms->base.vtable = &_stream_mbox_vtable; |
346 | return 0; | 342 | return 0; |
347 | } | 343 | } |
348 | 344 | ||
349 | /* | 345 | void |
350 | static void | 346 | _stream_mbox_dtor (stream_t stream) |
351 | _stream_mbox_dtor (struct _stream_mbox *ms) | ||
352 | { | 347 | { |
348 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; | ||
349 | mu_refcount_destroy (&ms->refcount); | ||
350 | if (ms->mbox && ms->msgno && ms->msgno <= ms->mbox->messages_count) | ||
351 | { | ||
352 | /* Loose the reference only if it is the same that we saved | ||
353 | on the mailbox. */ | ||
354 | if (ms->is_header && ms == (struct _stream_mbox *) | ||
355 | (ms->mbox->umessages[ms->msgno - 1]->header.stream)) | ||
356 | { | ||
357 | ms->mbox->umessages[ms->msgno - 1]->header.stream = NULL; | ||
358 | } | ||
359 | else if (ms == (struct _stream_mbox *) | ||
360 | (ms->mbox->umessages[ms->msgno - 1]->body.stream)) | ||
361 | { | ||
362 | ms->mbox->umessages[ms->msgno - 1]->body.stream = NULL; | ||
363 | } | ||
364 | } | ||
365 | ms->mbox = NULL; | ||
366 | ms->msgno = 0; | ||
367 | ms->is_header = 0; | ||
368 | } | ||
369 | |||
370 | int | ||
371 | stream_mbox_msgno (stream_t stream, unsigned int msgno) | ||
372 | { | ||
373 | struct _stream_mbox *ms = (struct _stream_mbox *)stream; | ||
374 | if (ms) | ||
375 | ms->msgno = msgno; | ||
376 | return 0; | ||
353 | } | 377 | } |
354 | */ | ||
355 | 378 | ||
356 | int | 379 | int |
357 | stream_mbox_create (stream_t *pstream, mbox_t mbox, unsigned int msgno, | 380 | stream_mbox_create (stream_t *pstream, mbox_t mbox, unsigned int msgno, | ... | ... |
... | @@ -26,6 +26,8 @@ int | ... | @@ -26,6 +26,8 @@ int |
26 | mbox_get_uid (mbox_t mbox, unsigned int msgno, unsigned long *puid) | 26 | mbox_get_uid (mbox_t mbox, unsigned int msgno, unsigned long *puid) |
27 | { | 27 | { |
28 | 28 | ||
29 | mbox_debug_print (mbox, "get_uid(%u)", msgno); | ||
30 | |||
29 | if (mbox == NULL || msgno == 0 || puid == NULL) | 31 | if (mbox == NULL || msgno == 0 || puid == NULL) |
30 | return MU_ERROR_INVALID_PARAMETER; | 32 | return MU_ERROR_INVALID_PARAMETER; |
31 | 33 | ... | ... |
... | @@ -26,6 +26,8 @@ int | ... | @@ -26,6 +26,8 @@ int |
26 | mbox_get_uidnext (mbox_t mbox, unsigned long *puidnext) | 26 | mbox_get_uidnext (mbox_t mbox, unsigned long *puidnext) |
27 | { | 27 | { |
28 | 28 | ||
29 | mbox_debug_print (mbox, "get_uidnext"); | ||
30 | |||
29 | if (mbox == NULL || puidnext == NULL) | 31 | if (mbox == NULL || puidnext == NULL) |
30 | return MU_ERROR_INVALID_PARAMETER; | 32 | return MU_ERROR_INVALID_PARAMETER; |
31 | 33 | ... | ... |
... | @@ -25,6 +25,9 @@ | ... | @@ -25,6 +25,9 @@ |
25 | int | 25 | int |
26 | mbox_get_uidvalidity (mbox_t mbox, unsigned long *puidvalidity) | 26 | mbox_get_uidvalidity (mbox_t mbox, unsigned long *puidvalidity) |
27 | { | 27 | { |
28 | |||
29 | mbox_debug_print (mbox, "get_uidvalidity"); | ||
30 | |||
28 | if (mbox == NULL || puidvalidity == NULL) | 31 | if (mbox == NULL || puidvalidity == NULL) |
29 | return MU_ERROR_INVALID_PARAMETER; | 32 | return MU_ERROR_INVALID_PARAMETER; |
30 | 33 | ... | ... |
... | @@ -117,10 +117,10 @@ MD5_CTX *context; /* context */ | ... | @@ -117,10 +117,10 @@ MD5_CTX *context; /* context */ |
117 | unsigned char *input; /* input block */ | 117 | unsigned char *input; /* input block */ |
118 | unsigned int inputLen; /* length of input block */ | 118 | unsigned int inputLen; /* length of input block */ |
119 | { | 119 | { |
120 | unsigned int i, index, partLen; | 120 | unsigned int i, indx, partLen; |
121 | 121 | ||
122 | /* Compute number of bytes mod 64 */ | 122 | /* Compute number of bytes mod 64 */ |
123 | index = (unsigned int)((context->count[0] >> 3) & 0x3F); | 123 | indx = (unsigned int)((context->count[0] >> 3) & 0x3F); |
124 | 124 | ||
125 | /* Update number of bits */ | 125 | /* Update number of bits */ |
126 | if ((context->count[0] += ((UINT4)inputLen << 3)) | 126 | if ((context->count[0] += ((UINT4)inputLen << 3)) |
... | @@ -128,26 +128,26 @@ unsigned int inputLen; /* length of input block */ | ... | @@ -128,26 +128,26 @@ unsigned int inputLen; /* length of input block */ |
128 | context->count[1]++; | 128 | context->count[1]++; |
129 | context->count[1] += ((UINT4)inputLen >> 29); | 129 | context->count[1] += ((UINT4)inputLen >> 29); |
130 | 130 | ||
131 | partLen = 64 - index; | 131 | partLen = 64 - indx; |
132 | 132 | ||
133 | /* Transform as many times as possible. | 133 | /* Transform as many times as possible. |
134 | */ | 134 | */ |
135 | if (inputLen >= partLen) { | 135 | if (inputLen >= partLen) { |
136 | MD5_memcpy | 136 | MD5_memcpy |
137 | ((POINTER)&context->buffer[index], (POINTER)input, partLen); | 137 | ((POINTER)&context->buffer[indx], (POINTER)input, partLen); |
138 | MD5Transform (context->state, context->buffer); | 138 | MD5Transform (context->state, context->buffer); |
139 | 139 | ||
140 | for (i = partLen; i + 63 < inputLen; i += 64) | 140 | for (i = partLen; i + 63 < inputLen; i += 64) |
141 | MD5Transform (context->state, &input[i]); | 141 | MD5Transform (context->state, &input[i]); |
142 | 142 | ||
143 | index = 0; | 143 | indx = 0; |
144 | } | 144 | } |
145 | else | 145 | else |
146 | i = 0; | 146 | i = 0; |
147 | 147 | ||
148 | /* Buffer remaining input */ | 148 | /* Buffer remaining input */ |
149 | MD5_memcpy | 149 | MD5_memcpy |
150 | ((POINTER)&context->buffer[index], (POINTER)&input[i], | 150 | ((POINTER)&context->buffer[indx], (POINTER)&input[i], |
151 | inputLen-i); | 151 | inputLen-i); |
152 | } | 152 | } |
153 | 153 | ||
... | @@ -159,15 +159,15 @@ unsigned char digest[16]; /* message digest */ | ... | @@ -159,15 +159,15 @@ unsigned char digest[16]; /* message digest */ |
159 | MD5_CTX *context; /* context */ | 159 | MD5_CTX *context; /* context */ |
160 | { | 160 | { |
161 | unsigned char bits[8]; | 161 | unsigned char bits[8]; |
162 | unsigned int index, padLen; | 162 | unsigned int indx, padLen; |
163 | 163 | ||
164 | /* Save number of bits */ | 164 | /* Save number of bits */ |
165 | Encode (bits, context->count, 8); | 165 | Encode (bits, context->count, 8); |
166 | 166 | ||
167 | /* Pad out to 56 mod 64. | 167 | /* Pad out to 56 mod 64. |
168 | */ | 168 | */ |
169 | index = (unsigned int)((context->count[0] >> 3) & 0x3f); | 169 | indx = (unsigned int)((context->count[0] >> 3) & 0x3f); |
170 | padLen = (index < 56) ? (56 - index) : (120 - index); | 170 | padLen = (indx < 56) ? (56 - indx) : (120 - indx); |
171 | MD5Update (context, PADDING, padLen); | 171 | MD5Update (context, PADDING, padLen); |
172 | 172 | ||
173 | /* Append length (before padding) */ | 173 | /* Append length (before padding) */ | ... | ... |
... | @@ -29,6 +29,9 @@ | ... | @@ -29,6 +29,9 @@ |
29 | #include <mailutils/error.h> | 29 | #include <mailutils/error.h> |
30 | #include <mailutils/sys/memstream.h> | 30 | #include <mailutils/sys/memstream.h> |
31 | 31 | ||
32 | #undef min | ||
33 | #define min(a,b) ((a) < (b) ? (a) : (b)) | ||
34 | |||
32 | int | 35 | int |
33 | _stream_memory_ref (stream_t stream) | 36 | _stream_memory_ref (stream_t stream) |
34 | { | 37 | { |
... | @@ -48,18 +51,18 @@ _stream_memory_destroy (stream_t *pstream) | ... | @@ -48,18 +51,18 @@ _stream_memory_destroy (stream_t *pstream) |
48 | } | 51 | } |
49 | 52 | ||
50 | int | 53 | int |
51 | _stream_memory_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) | 54 | _stream_memory_read (stream_t stream, void *optr, size_t osize, |
55 | off_t offset, size_t *nbytes) | ||
52 | { | 56 | { |
53 | struct _stream_memory *mem = (struct _stream_memory *)stream; | 57 | struct _stream_memory *mem = (struct _stream_memory *)stream; |
54 | size_t n = 0; | 58 | size_t n = 0; |
55 | 59 | ||
56 | mu_refcount_lock (mem->refcount); | 60 | mu_refcount_lock (mem->refcount); |
57 | if (mem->ptr != NULL && (mem->offset < (off_t)mem->size)) | 61 | if (mem->ptr != NULL && (offset < (off_t)mem->size)) |
58 | { | 62 | { |
59 | n = ((mem->offset + osize) > mem->size) ? | 63 | n = ((offset + osize) > mem->size) ? |
60 | mem->size - mem->offset : osize; | 64 | mem->size - offset : osize; |
61 | memcpy (optr, mem->ptr + mem->offset, n); | 65 | memcpy (optr, mem->ptr + offset, n); |
62 | mem->offset += n; | ||
63 | } | 66 | } |
64 | mu_refcount_unlock (mem->refcount); | 67 | mu_refcount_unlock (mem->refcount); |
65 | if (nbytes) | 68 | if (nbytes) |
... | @@ -68,22 +71,22 @@ _stream_memory_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) | ... | @@ -68,22 +71,22 @@ _stream_memory_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) |
68 | } | 71 | } |
69 | 72 | ||
70 | int | 73 | int |
71 | _stream_memory_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes) | 74 | _stream_memory_readline (stream_t stream, char *optr, size_t osize, |
75 | off_t offset, size_t *nbytes) | ||
72 | { | 76 | { |
73 | struct _stream_memory *mem = (struct _stream_memory *)stream; | 77 | struct _stream_memory *mem = (struct _stream_memory *)stream; |
74 | char *nl; | 78 | char *nl; |
75 | size_t n = 0; | 79 | size_t n = 0; |
76 | mu_refcount_lock (mem->refcount); | 80 | mu_refcount_lock (mem->refcount); |
77 | if (mem->ptr && (mem->offset < (off_t)mem->size)) | 81 | if (mem->ptr && (offset < (off_t)mem->size)) |
78 | { | 82 | { |
79 | /* Save space for the null byte. */ | 83 | /* Save space for the null byte. */ |
80 | osize--; | 84 | osize--; |
81 | nl = memchr (mem->ptr + mem->offset, '\n', mem->size - mem->offset); | 85 | nl = memchr (mem->ptr + offset, '\n', mem->size - offset); |
82 | n = (nl) ? nl - (mem->ptr + mem->offset) + 1 : mem->size - mem->offset; | 86 | n = (nl) ? (size_t)(nl - (mem->ptr + offset) + 1) : mem->size - offset; |
83 | n = (n > osize) ? osize : n; | 87 | n = min (n, osize); |
84 | memcpy (optr, mem->ptr + mem->offset, n); | 88 | memcpy (optr, mem->ptr + offset, n); |
85 | optr[n] = '\0'; | 89 | optr[n] = '\0'; |
86 | mem->offset += n; | ||
87 | } | 90 | } |
88 | mu_refcount_unlock (mem->refcount); | 91 | mu_refcount_unlock (mem->refcount); |
89 | if (nbytes) | 92 | if (nbytes) |
... | @@ -93,27 +96,26 @@ _stream_memory_readline (stream_t stream, char *optr, size_t osize, size_t *nbyt | ... | @@ -93,27 +96,26 @@ _stream_memory_readline (stream_t stream, char *optr, size_t osize, size_t *nbyt |
93 | 96 | ||
94 | int | 97 | int |
95 | _stream_memory_write (stream_t stream, const void *iptr, size_t isize, | 98 | _stream_memory_write (stream_t stream, const void *iptr, size_t isize, |
96 | size_t *nbytes) | 99 | off_t offset, size_t *nbytes) |
97 | { | 100 | { |
98 | struct _stream_memory *mem = (struct _stream_memory *)stream; | 101 | struct _stream_memory *mem = (struct _stream_memory *)stream; |
99 | 102 | ||
100 | mu_refcount_lock (mem->refcount); | 103 | mu_refcount_lock (mem->refcount); |
101 | /* Bigger we have to realloc. */ | 104 | /* Bigger we have to realloc. */ |
102 | if (mem->capacity < (mem->offset + isize)) | 105 | if (mem->capacity < (offset + isize)) |
103 | { | 106 | { |
104 | /* Realloc by blocks of 512. */ | 107 | /* Realloc by blocks of 512. */ |
105 | int newsize = MU_STREAM_MEMORY_BLOCKSIZE * | 108 | int newsize = MU_STREAM_MEMORY_BLOCKSIZE * |
106 | (((mem->offset + isize)/MU_STREAM_MEMORY_BLOCKSIZE) + 1); | 109 | (((offset + isize)/MU_STREAM_MEMORY_BLOCKSIZE) + 1); |
107 | char *tmp = realloc (mem->ptr, newsize); | 110 | char *tmp = realloc (mem->ptr, newsize); |
108 | if (tmp == NULL) | 111 | if (tmp == NULL) |
109 | return ENOMEM; | 112 | return ENOMEM; |
110 | mem->ptr = tmp; | 113 | mem->ptr = tmp; |
111 | mem->size = mem->offset + isize; | 114 | mem->size = offset + isize; |
112 | mem->capacity = newsize; | 115 | mem->capacity = newsize; |
113 | } | 116 | } |
114 | 117 | ||
115 | memcpy (mem->ptr + mem->offset, iptr, isize); | 118 | memcpy (mem->ptr + offset, iptr, isize); |
116 | mem->offset += isize; | ||
117 | mu_refcount_unlock (mem->refcount); | 119 | mu_refcount_unlock (mem->refcount); |
118 | if (nbytes) | 120 | if (nbytes) |
119 | *nbytes = isize; | 121 | *nbytes = isize; |
... | @@ -140,7 +142,6 @@ _stream_memory_truncate (stream_t stream, off_t len) | ... | @@ -140,7 +142,6 @@ _stream_memory_truncate (stream_t stream, off_t len) |
140 | } | 142 | } |
141 | mem->capacity = len; | 143 | mem->capacity = len; |
142 | mem->size = len; | 144 | mem->size = len; |
143 | mem->offset = len; | ||
144 | mu_refcount_unlock (mem->refcount); | 145 | mu_refcount_unlock (mem->refcount); |
145 | return 0; | 146 | return 0; |
146 | } | 147 | } |
... | @@ -166,7 +167,6 @@ _stream_memory_close (stream_t stream) | ... | @@ -166,7 +167,6 @@ _stream_memory_close (stream_t stream) |
166 | mem->ptr = NULL; | 167 | mem->ptr = NULL; |
167 | mem->capacity = 0; | 168 | mem->capacity = 0; |
168 | mem->size = 0; | 169 | mem->size = 0; |
169 | mem->offset = 0; | ||
170 | mu_refcount_unlock (mem->refcount); | 170 | mu_refcount_unlock (mem->refcount); |
171 | return 0; | 171 | return 0; |
172 | } | 172 | } |
... | @@ -206,37 +206,19 @@ _stream_memory_get_state (stream_t stream, enum stream_state *state) | ... | @@ -206,37 +206,19 @@ _stream_memory_get_state (stream_t stream, enum stream_state *state) |
206 | } | 206 | } |
207 | 207 | ||
208 | int | 208 | int |
209 | _stream_memory_seek (stream_t stream, off_t off, enum stream_whence whence) | 209 | _stream_memory_is_seekable (stream_t stream) |
210 | { | 210 | { |
211 | struct _stream_memory *mem = (struct _stream_memory *)stream; | 211 | (void)stream; |
212 | off_t noff = mem->offset; | 212 | return 1; |
213 | int err = 0; | ||
214 | if (whence == MU_STREAM_WHENCE_SET) | ||
215 | noff = off; | ||
216 | else if (whence == MU_STREAM_WHENCE_CUR) | ||
217 | noff += off; | ||
218 | else if (whence == MU_STREAM_WHENCE_END) | ||
219 | noff = mem->size + off; | ||
220 | else | ||
221 | noff = -1; /* error. */ | ||
222 | if (noff >= 0) | ||
223 | { | ||
224 | if (noff > mem->offset) | ||
225 | _stream_memory_truncate (stream, noff); | ||
226 | mem->offset = noff; | ||
227 | } | ||
228 | else | ||
229 | err = MU_ERROR_INVALID_PARAMETER; | ||
230 | return err; | ||
231 | } | 213 | } |
232 | 214 | ||
233 | int | 215 | int |
234 | _stream_memory_tell (stream_t stream, off_t *off) | 216 | _stream_memory_tell (stream_t stream, off_t *off) |
235 | { | 217 | { |
236 | struct _stream_memory *mem = (struct _stream_memory *)stream; | 218 | (void)stream; |
237 | if (off == NULL) | 219 | if (off == NULL) |
238 | return MU_ERROR_INVALID_PARAMETER; | 220 | return MU_ERROR_INVALID_PARAMETER; |
239 | *off = mem->offset; | 221 | *off = 0; |
240 | return 0; | 222 | return 0; |
241 | } | 223 | } |
242 | 224 | ||
... | @@ -288,7 +270,6 @@ _stream_memory_open (stream_t stream, const char *filename, int port, | ... | @@ -288,7 +270,6 @@ _stream_memory_open (stream_t stream, const char *filename, int port, |
288 | mem->ptr = NULL; | 270 | mem->ptr = NULL; |
289 | mem->capacity = 0; | 271 | mem->capacity = 0; |
290 | mem->size = 0; | 272 | mem->size = 0; |
291 | mem->offset = 0; | ||
292 | mem->flags = flags; | 273 | mem->flags = flags; |
293 | if (filename) | 274 | if (filename) |
294 | { | 275 | { |
... | @@ -341,7 +322,6 @@ static struct _stream_vtable _stream_memory_vtable = | ... | @@ -341,7 +322,6 @@ static struct _stream_vtable _stream_memory_vtable = |
341 | _stream_memory_readline, | 322 | _stream_memory_readline, |
342 | _stream_memory_write, | 323 | _stream_memory_write, |
343 | 324 | ||
344 | _stream_memory_seek, | ||
345 | _stream_memory_tell, | 325 | _stream_memory_tell, |
346 | 326 | ||
347 | _stream_memory_get_size, | 327 | _stream_memory_get_size, |
... | @@ -352,6 +332,7 @@ static struct _stream_vtable _stream_memory_vtable = | ... | @@ -352,6 +332,7 @@ static struct _stream_vtable _stream_memory_vtable = |
352 | _stream_memory_get_flags, | 332 | _stream_memory_get_flags, |
353 | _stream_memory_get_state, | 333 | _stream_memory_get_state, |
354 | 334 | ||
335 | _stream_memory_is_seekable, | ||
355 | _stream_memory_is_readready, | 336 | _stream_memory_is_readready, |
356 | _stream_memory_is_writeready, | 337 | _stream_memory_is_writeready, |
357 | _stream_memory_is_exceptionpending, | 338 | _stream_memory_is_exceptionpending, |
... | @@ -378,21 +359,23 @@ _stream_memory_ctor (struct _stream_memory *mem, size_t capacity) | ... | @@ -378,21 +359,23 @@ _stream_memory_ctor (struct _stream_memory *mem, size_t capacity) |
378 | else | 359 | else |
379 | mem->capacity = 0; | 360 | mem->capacity = 0; |
380 | mem->size = 0; | 361 | mem->size = 0; |
381 | mem->offset = 0; | ||
382 | mem->flags = 0; | 362 | mem->flags = 0; |
383 | mem->base.vtable = &_stream_memory_vtable; | 363 | mem->base.vtable = &_stream_memory_vtable; |
384 | return 0; | 364 | return 0; |
385 | } | 365 | } |
386 | 366 | ||
387 | void | 367 | void |
388 | _stream_memory_dtor (struct _stream_memory *mem) | 368 | _stream_memory_dtor (stream_t stream) |
389 | { | 369 | { |
370 | struct _stream_memory *mem = (struct _stream_memory *)stream; | ||
371 | if (mem) | ||
372 | { | ||
390 | mu_refcount_destroy (&mem->refcount); | 373 | mu_refcount_destroy (&mem->refcount); |
391 | mem->ptr = NULL; | 374 | mem->ptr = NULL; |
392 | mem->capacity = 0; | 375 | mem->capacity = 0; |
393 | mem->size = 0; | 376 | mem->size = 0; |
394 | mem->offset = 0; | ||
395 | mem->flags = 0; | 377 | mem->flags = 0; |
378 | } | ||
396 | } | 379 | } |
397 | 380 | ||
398 | int | 381 | int | ... | ... |
... | @@ -63,6 +63,8 @@ pop3_get_carrier (pop3_t pop3, stream_t *pcarrier) | ... | @@ -63,6 +63,8 @@ pop3_get_carrier (pop3_t pop3, stream_t *pcarrier) |
63 | return status; | 63 | return status; |
64 | } | 64 | } |
65 | } | 65 | } |
66 | /* Since we expose the stream incremente the reference count. */ | ||
67 | stream_ref (pop3->carrier); | ||
66 | *pcarrier = pop3->carrier; | 68 | *pcarrier = pop3->carrier; |
67 | return 0; | 69 | return 0; |
68 | } | 70 | } | ... | ... |
... | @@ -60,6 +60,8 @@ pop3_connect (pop3_t pop3, const char *host, unsigned int port) | ... | @@ -60,6 +60,8 @@ pop3_connect (pop3_t pop3, const char *host, unsigned int port) |
60 | stream_t carrier; | 60 | stream_t carrier; |
61 | status = pop3_get_carrier (pop3, &carrier); | 61 | status = pop3_get_carrier (pop3, &carrier); |
62 | POP3_CHECK_ERROR (pop3, status); | 62 | POP3_CHECK_ERROR (pop3, status); |
63 | /* An stream_ref was done in po3_get_carrier (). */ | ||
64 | stream_destroy (&carrier); | ||
63 | } | 65 | } |
64 | else | 66 | else |
65 | { | 67 | { | ... | ... |
... | @@ -44,6 +44,7 @@ pop3_get_debug (pop3_t pop3, mu_debug_t *pdebug) | ... | @@ -44,6 +44,7 @@ pop3_get_debug (pop3_t pop3, mu_debug_t *pdebug) |
44 | if (status != 0) | 44 | if (status != 0) |
45 | return status; | 45 | return status; |
46 | } | 46 | } |
47 | mu_debug_ref (pop3->debug); | ||
47 | *pdebug = pop3->debug; | 48 | *pdebug = pop3->debug; |
48 | return 0; | 49 | return 0; |
49 | } | 50 | } | ... | ... |
... | @@ -50,9 +50,10 @@ pop3_getline (pop3_t pop3) | ... | @@ -50,9 +50,10 @@ pop3_getline (pop3_t pop3) |
50 | } | 50 | } |
51 | 51 | ||
52 | status = stream_readline (pop3->carrier, pop3->io.buf + total, | 52 | status = stream_readline (pop3->carrier, pop3->io.buf + total, |
53 | pop3->io.len - total, &n); | 53 | pop3->io.len - total, pop3->offset, &n); |
54 | if (status != 0) | 54 | if (status != 0) |
55 | return status; | 55 | return status; |
56 | pop3->offset += n; | ||
56 | 57 | ||
57 | /* The server went away: It maybe a timeout and some pop server | 58 | /* The server went away: It maybe a timeout and some pop server |
58 | does not send the -ERR. Consider this like an error. */ | 59 | does not send the -ERR. Consider this like an error. */ |
... | @@ -118,7 +119,7 @@ pop3_readline (pop3_t pop3, char *buffer, size_t buflen, size_t *pnread) | ... | @@ -118,7 +119,7 @@ pop3_readline (pop3_t pop3, char *buffer, size_t buflen, size_t *pnread) |
118 | { | 119 | { |
119 | size_t nread = 0; | 120 | size_t nread = 0; |
120 | size_t n = 0; | 121 | size_t n = 0; |
121 | int status; | 122 | int status = 0; |
122 | 123 | ||
123 | /* Do we need to fill up? Yes if no NL or the buffer is empty. */ | 124 | /* Do we need to fill up? Yes if no NL or the buffer is empty. */ |
124 | if (pop3->carrier && (pop3->io.nl == NULL || pop3->io.ptr == pop3->io.buf)) | 125 | if (pop3->carrier && (pop3->io.nl == NULL || pop3->io.ptr == pop3->io.buf)) | ... | ... |
... | @@ -54,7 +54,7 @@ pop3_send (pop3_t pop3) | ... | @@ -54,7 +54,7 @@ pop3_send (pop3_t pop3) |
54 | return MU_ERROR_TIMEOUT; | 54 | return MU_ERROR_TIMEOUT; |
55 | } | 55 | } |
56 | 56 | ||
57 | status = stream_write (pop3->carrier, pop3->io.buf, len, &n); | 57 | status = stream_write (pop3->carrier, pop3->io.buf, len, 0, &n); |
58 | if (n) | 58 | if (n) |
59 | { | 59 | { |
60 | /* Consume what we sent. */ | 60 | /* Consume what we sent. */ | ... | ... |
... | @@ -34,11 +34,10 @@ static void p_destroy __P ((stream_t *)); | ... | @@ -34,11 +34,10 @@ static void p_destroy __P ((stream_t *)); |
34 | static int p_open __P ((stream_t, const char *, int, int)); | 34 | static int p_open __P ((stream_t, const char *, int, int)); |
35 | static int p_close __P ((stream_t)); | 35 | static int p_close __P ((stream_t)); |
36 | 36 | ||
37 | static int p_read __P ((stream_t, void *, size_t, size_t *)); | 37 | static int p_read __P ((stream_t, void *, size_t, off_t, size_t *)); |
38 | static int p_readline __P ((stream_t, char *, size_t, size_t *)); | 38 | static int p_readline __P ((stream_t, char *, size_t, off_t, size_t *)); |
39 | static int p_write __P ((stream_t, const void *, size_t, size_t *)); | 39 | static int p_write __P ((stream_t, const void *, size_t, off_t, size_t *)); |
40 | 40 | ||
41 | static int p_seek __P ((stream_t, off_t, enum stream_whence)); | ||
42 | static int p_tell __P ((stream_t, off_t *)); | 41 | static int p_tell __P ((stream_t, off_t *)); |
43 | 42 | ||
44 | static int p_get_size __P ((stream_t, off_t *)); | 43 | static int p_get_size __P ((stream_t, off_t *)); |
... | @@ -49,6 +48,7 @@ static int p_get_fd __P ((stream_t, int *)); | ... | @@ -49,6 +48,7 @@ static int p_get_fd __P ((stream_t, int *)); |
49 | static int p_get_flags __P ((stream_t, int *)); | 48 | static int p_get_flags __P ((stream_t, int *)); |
50 | static int p_get_state __P ((stream_t, enum stream_state *)); | 49 | static int p_get_state __P ((stream_t, enum stream_state *)); |
51 | 50 | ||
51 | static int p_is_seekable __P ((stream_t)); | ||
52 | static int p_is_readready __P ((stream_t, int timeout)); | 52 | static int p_is_readready __P ((stream_t, int timeout)); |
53 | static int p_is_writeready __P ((stream_t, int timeout)); | 53 | static int p_is_writeready __P ((stream_t, int timeout)); |
54 | static int p_is_exceptionpending __P ((stream_t, int timeout)); | 54 | static int p_is_exceptionpending __P ((stream_t, int timeout)); |
... | @@ -67,7 +67,6 @@ static struct _stream_vtable p_s_vtable = | ... | @@ -67,7 +67,6 @@ static struct _stream_vtable p_s_vtable = |
67 | p_readline, | 67 | p_readline, |
68 | p_write, | 68 | p_write, |
69 | 69 | ||
70 | p_seek, | ||
71 | p_tell, | 70 | p_tell, |
72 | 71 | ||
73 | p_get_size, | 72 | p_get_size, |
... | @@ -78,6 +77,7 @@ static struct _stream_vtable p_s_vtable = | ... | @@ -78,6 +77,7 @@ static struct _stream_vtable p_s_vtable = |
78 | p_get_flags, | 77 | p_get_flags, |
79 | p_get_state, | 78 | p_get_state, |
80 | 79 | ||
80 | p_is_seekable, | ||
81 | p_is_readready, | 81 | p_is_readready, |
82 | p_is_writeready, | 82 | p_is_writeready, |
83 | p_is_exceptionpending, | 83 | p_is_exceptionpending, |
... | @@ -151,12 +151,14 @@ p_close (stream_t stream) | ... | @@ -151,12 +151,14 @@ p_close (stream_t stream) |
151 | } | 151 | } |
152 | 152 | ||
153 | static int | 153 | static int |
154 | p_read (stream_t stream, void *buf, size_t buflen, size_t *pn) | 154 | p_read (stream_t stream, void *buf, size_t buflen, off_t offset, size_t *pn) |
155 | { | 155 | { |
156 | struct p_stream *p_stream = (struct p_stream *)stream; | 156 | struct p_stream *p_stream = (struct p_stream *)stream; |
157 | size_t n = 0; | 157 | size_t n = 0; |
158 | int status = 0; | 158 | int status = 0; |
159 | char *p = buf; | 159 | char *p = buf; |
160 | |||
161 | (void)offset; | ||
160 | if (p_stream) | 162 | if (p_stream) |
161 | { | 163 | { |
162 | mu_refcount_lock (p_stream->refcount); | 164 | mu_refcount_lock (p_stream->refcount); |
... | @@ -202,11 +204,14 @@ p_read (stream_t stream, void *buf, size_t buflen, size_t *pn) | ... | @@ -202,11 +204,14 @@ p_read (stream_t stream, void *buf, size_t buflen, size_t *pn) |
202 | } | 204 | } |
203 | 205 | ||
204 | static int | 206 | static int |
205 | p_readline (stream_t stream, char *buf, size_t buflen, size_t *pn) | 207 | p_readline (stream_t stream, char *buf, size_t buflen, off_t offset, |
208 | size_t *pn) | ||
206 | { | 209 | { |
207 | struct p_stream *p_stream = (struct p_stream *)stream; | 210 | struct p_stream *p_stream = (struct p_stream *)stream; |
208 | size_t n = 0; | 211 | size_t n = 0; |
209 | int status = 0; | 212 | int status = 0; |
213 | |||
214 | (void)offset; | ||
210 | if (p_stream) | 215 | if (p_stream) |
211 | { | 216 | { |
212 | mu_refcount_lock (p_stream->refcount); | 217 | mu_refcount_lock (p_stream->refcount); |
... | @@ -227,17 +232,18 @@ p_readline (stream_t stream, char *buf, size_t buflen, size_t *pn) | ... | @@ -227,17 +232,18 @@ p_readline (stream_t stream, char *buf, size_t buflen, size_t *pn) |
227 | } | 232 | } |
228 | 233 | ||
229 | static int | 234 | static int |
230 | p_write (stream_t stream, const void *buf, size_t buflen, size_t *pn) | 235 | p_write (stream_t stream, const void *buf, size_t buflen, off_t offset, |
236 | size_t *pn) | ||
231 | { | 237 | { |
232 | struct p_stream *p_stream = (struct p_stream *)stream; | 238 | struct p_stream *p_stream = (struct p_stream *)stream; |
233 | return stream_write (p_stream->pop3->carrier, buf, buflen, pn); | 239 | return stream_write (p_stream->pop3->carrier, buf, buflen, offset, pn); |
234 | } | 240 | } |
235 | 241 | ||
236 | static int | 242 | static int |
237 | p_seek (stream_t stream, off_t offset, enum stream_whence whence) | 243 | p_is_seekable (stream_t stream) |
238 | { | 244 | { |
239 | struct p_stream *p_stream = (struct p_stream *)stream; | 245 | struct p_stream *p_stream = (struct p_stream *)stream; |
240 | return stream_seek (p_stream->pop3->carrier, offset, whence); | 246 | return stream_is_seekable (p_stream->pop3->carrier); |
241 | } | 247 | } |
242 | 248 | ||
243 | static int | 249 | static int | ... | ... |
... | @@ -60,15 +60,22 @@ pop3_uidl (pop3_t pop3, unsigned msgno, char **uidl) | ... | @@ -60,15 +60,22 @@ pop3_uidl (pop3_t pop3, unsigned msgno, char **uidl) |
60 | *uidl = NULL; | 60 | *uidl = NULL; |
61 | { | 61 | { |
62 | char *space; | 62 | char *space; |
63 | /* Format: +OK msgno uidlstring */ | ||
64 | |||
63 | /* Pass the "+OK". */ | 65 | /* Pass the "+OK". */ |
64 | space = strchr (pop3->ack.buf, ' '); | 66 | space = strchr (pop3->ack.buf, ' '); |
65 | if (space) | 67 | if (space) |
66 | { | 68 | { |
69 | /* Skip spaces. */ | ||
70 | while (*space == ' ') space++; | ||
67 | /* Pass the number. */ | 71 | /* Pass the number. */ |
68 | space = strchr (space, ' '); | 72 | space = strchr (space, ' '); |
69 | if (space) | 73 | if (space) |
70 | { | 74 | { |
71 | size_t len = strlen (space); | 75 | size_t len; |
76 | /* Skip spaces between msgno and uidlstring */ | ||
77 | while (*space == ' ') space++; | ||
78 | len = strlen (space); | ||
72 | if (space[len - 1] == '\n') | 79 | if (space[len - 1] == '\n') |
73 | { | 80 | { |
74 | space[len - 1] = '\0'; | 81 | space[len - 1] = '\0'; | ... | ... |
... | @@ -83,17 +83,16 @@ pop3_uidl_current (iterator_t iterator, unsigned int *pno, char **puidl) | ... | @@ -83,17 +83,16 @@ pop3_uidl_current (iterator_t iterator, unsigned int *pno, char **puidl) |
83 | { | 83 | { |
84 | char *space; | 84 | char *space; |
85 | unsigned int msgno = 0; | 85 | unsigned int msgno = 0; |
86 | |||
86 | /* The format is: msgno uidlstring */ | 87 | /* The format is: msgno uidlstring */ |
87 | space = strchr (buf, ' '); | 88 | msgno = strtoul (buf, &space, 10); |
88 | if (space) | ||
89 | { | ||
90 | *space++ = '\0'; | ||
91 | msgno = strtoul (buf, NULL, 10); | ||
92 | } | ||
93 | if (space && space[strlen (space) - 1] == '\n') | 89 | if (space && space[strlen (space) - 1] == '\n') |
94 | space[strlen (space) - 1] = '\0'; | 90 | space[strlen (space) - 1] = '\0'; |
91 | |||
92 | /* Oops. */ | ||
95 | if (space == NULL) | 93 | if (space == NULL) |
96 | space = (char *)""; | 94 | space = (char *)""; |
95 | |||
97 | if (pno) | 96 | if (pno) |
98 | *pno = msgno; | 97 | *pno = msgno; |
99 | if (puidl) | 98 | if (puidl) | ... | ... |
... | @@ -90,6 +90,7 @@ pop3_t pop3; | ... | @@ -90,6 +90,7 @@ pop3_t pop3; |
90 | /* When non-zero, this global means the user is done using this program. */ | 90 | /* When non-zero, this global means the user is done using this program. */ |
91 | int done; | 91 | int done; |
92 | 92 | ||
93 | #if 0 | ||
93 | void * | 94 | void * |
94 | xmalloc (size_t size) | 95 | xmalloc (size_t size) |
95 | { | 96 | { |
... | @@ -101,6 +102,7 @@ xmalloc (size_t size) | ... | @@ -101,6 +102,7 @@ xmalloc (size_t size) |
101 | } | 102 | } |
102 | return m; | 103 | return m; |
103 | } | 104 | } |
105 | #endif | ||
104 | 106 | ||
105 | char * | 107 | char * |
106 | dupstr (const char *s) | 108 | dupstr (const char *s) |
... | @@ -371,6 +373,7 @@ com_uidl (char *arg) | ... | @@ -371,6 +373,7 @@ com_uidl (char *arg) |
371 | unsigned int msgno = strtoul (arg, NULL, 10); | 373 | unsigned int msgno = strtoul (arg, NULL, 10); |
372 | if (pop3_uidl (pop3, msgno, &uidl) == 0) | 374 | if (pop3_uidl (pop3, msgno, &uidl) == 0) |
373 | printf ("Msg: %d UIDL: %s\n", msgno, (uidl) ? uidl : ""); | 375 | printf ("Msg: %d UIDL: %s\n", msgno, (uidl) ? uidl : ""); |
376 | free (uidl); | ||
374 | } | 377 | } |
375 | return 0; | 378 | return 0; |
376 | } | 379 | } |
... | @@ -549,7 +552,7 @@ com_top (char *arg) | ... | @@ -549,7 +552,7 @@ com_top (char *arg) |
549 | { | 552 | { |
550 | size_t n = 0; | 553 | size_t n = 0; |
551 | char buf[128]; | 554 | char buf[128]; |
552 | while ((stream_readline (stream, buf, sizeof buf, &n) == 0) && n) | 555 | while ((stream_readline (stream, buf, sizeof buf, 0, &n) == 0) && n) |
553 | printf ("%s", buf); | 556 | printf ("%s", buf); |
554 | stream_destroy (&stream); | 557 | stream_destroy (&stream); |
555 | } | 558 | } |
... | @@ -573,7 +576,7 @@ com_retr (char *arg) | ... | @@ -573,7 +576,7 @@ com_retr (char *arg) |
573 | { | 576 | { |
574 | size_t n = 0; | 577 | size_t n = 0; |
575 | char buf[128]; | 578 | char buf[128]; |
576 | while ((stream_readline (stream, buf, sizeof buf, &n) == 0) && n) | 579 | while ((stream_readline (stream, buf, sizeof buf, 0, &n) == 0) && n) |
577 | printf ("%s", buf); | 580 | printf ("%s", buf); |
578 | stream_destroy (&stream); | 581 | stream_destroy (&stream); |
579 | } | 582 | } |
... | @@ -600,6 +603,7 @@ com_connect (char *arg) | ... | @@ -600,6 +603,7 @@ com_connect (char *arg) |
600 | mu_debug_t debug; | 603 | mu_debug_t debug; |
601 | pop3_get_debug (pop3, &debug); | 604 | pop3_get_debug (pop3, &debug); |
602 | mu_debug_set_level (debug, MU_DEBUG_PROT); | 605 | mu_debug_set_level (debug, MU_DEBUG_PROT); |
606 | mu_debug_destroy (&debug); | ||
603 | pop3_connect (pop3, host, port); | 607 | pop3_connect (pop3, host, port); |
604 | } | 608 | } |
605 | else | 609 | else | ... | ... |
... | @@ -110,8 +110,10 @@ _ticket_prompt_ctor (struct _ticket_prompt *prompt) | ... | @@ -110,8 +110,10 @@ _ticket_prompt_ctor (struct _ticket_prompt *prompt) |
110 | } | 110 | } |
111 | 111 | ||
112 | void | 112 | void |
113 | _ticket_prompt_dtor (struct _ticket_prompt *prompt) | 113 | _ticket_prompt_dtor (ticket_t ticket) |
114 | { | 114 | { |
115 | struct _ticket_prompt *prompt = (struct _ticket_prompt *)ticket; | ||
116 | if (prompt) | ||
115 | mu_refcount_destroy (&prompt->refcount); | 117 | mu_refcount_destroy (&prompt->refcount); |
116 | } | 118 | } |
117 | 119 | ... | ... |
... | @@ -76,6 +76,8 @@ int | ... | @@ -76,6 +76,8 @@ int |
76 | _mu_debug_stream_print (mu_debug_t debug, size_t level, const char *mesg) | 76 | _mu_debug_stream_print (mu_debug_t debug, size_t level, const char *mesg) |
77 | { | 77 | { |
78 | struct _mu_debug_stream *sdebug = (struct _mu_debug_stream *)debug; | 78 | struct _mu_debug_stream *sdebug = (struct _mu_debug_stream *)debug; |
79 | size_t n = 0; | ||
80 | int status; | ||
79 | 81 | ||
80 | if (mesg == NULL) | 82 | if (mesg == NULL) |
81 | return MU_ERROR_INVALID_PARAMETER; | 83 | return MU_ERROR_INVALID_PARAMETER; |
... | @@ -83,7 +85,10 @@ _mu_debug_stream_print (mu_debug_t debug, size_t level, const char *mesg) | ... | @@ -83,7 +85,10 @@ _mu_debug_stream_print (mu_debug_t debug, size_t level, const char *mesg) |
83 | if (!(sdebug->level & level)) | 85 | if (!(sdebug->level & level)) |
84 | return 0; | 86 | return 0; |
85 | 87 | ||
86 | return stream_write (sdebug->stream, mesg, strlen (mesg), NULL); | 88 | status = stream_write (sdebug->stream, mesg, strlen (mesg), sdebug->offset, |
89 | &n); | ||
90 | sdebug->offset += n; | ||
91 | return status; | ||
87 | } | 92 | } |
88 | 93 | ||
89 | static struct _mu_debug_vtable _mu_debug_stream_vtable = | 94 | static struct _mu_debug_vtable _mu_debug_stream_vtable = |
... | @@ -117,6 +122,7 @@ mu_debug_stream_create (mu_debug_t *pdebug, stream_t stream, | ... | @@ -117,6 +122,7 @@ mu_debug_stream_create (mu_debug_t *pdebug, stream_t stream, |
117 | } | 122 | } |
118 | 123 | ||
119 | sdebug->level = 0; | 124 | sdebug->level = 0; |
125 | sdebug->offset = 0; | ||
120 | sdebug->stream = stream; | 126 | sdebug->stream = stream; |
121 | sdebug->close_on_destroy = close_on_destroy; | 127 | sdebug->close_on_destroy = close_on_destroy; |
122 | sdebug->base.vtable = &_mu_debug_stream_vtable; | 128 | sdebug->base.vtable = &_mu_debug_stream_vtable; | ... | ... |
... | @@ -63,39 +63,30 @@ stream_close (stream_t stream) | ... | @@ -63,39 +63,30 @@ stream_close (stream_t stream) |
63 | } | 63 | } |
64 | 64 | ||
65 | int | 65 | int |
66 | stream_read (stream_t stream, void *buf, size_t buflen, size_t *n) | 66 | stream_read (stream_t stream, void *buf, size_t buflen, off_t o, size_t *n) |
67 | { | 67 | { |
68 | if (stream == NULL || stream->vtable == NULL | 68 | if (stream == NULL || stream->vtable == NULL |
69 | || stream->vtable->read == NULL) | 69 | || stream->vtable->read == NULL) |
70 | return MU_ERROR_NOT_SUPPORTED; | 70 | return MU_ERROR_NOT_SUPPORTED; |
71 | return stream->vtable->read (stream, buf, buflen, n); | 71 | return stream->vtable->read (stream, buf, buflen, o, n); |
72 | } | 72 | } |
73 | 73 | ||
74 | int | 74 | int |
75 | stream_readline (stream_t stream, char *buf, size_t buflen, size_t *n) | 75 | stream_readline (stream_t stream, char *buf, size_t buflen, off_t o, size_t *n) |
76 | { | 76 | { |
77 | if (stream == NULL || stream->vtable == NULL | 77 | if (stream == NULL || stream->vtable == NULL |
78 | || stream->vtable->readline == NULL) | 78 | || stream->vtable->readline == NULL) |
79 | return MU_ERROR_NOT_SUPPORTED; | 79 | return MU_ERROR_NOT_SUPPORTED; |
80 | return stream->vtable->readline (stream, buf, buflen, n); | 80 | return stream->vtable->readline (stream, buf, buflen, o, n); |
81 | } | 81 | } |
82 | 82 | ||
83 | int | 83 | int |
84 | stream_write (stream_t stream, const void *buf, size_t buflen, size_t *n) | 84 | stream_write (stream_t stream, const void *buf, size_t buflen, off_t o, size_t *n) |
85 | { | 85 | { |
86 | if (stream == NULL || stream->vtable == NULL | 86 | if (stream == NULL || stream->vtable == NULL |
87 | || stream->vtable->write == NULL) | 87 | || stream->vtable->write == NULL) |
88 | return MU_ERROR_NOT_SUPPORTED; | 88 | return MU_ERROR_NOT_SUPPORTED; |
89 | return stream->vtable->write (stream, buf, buflen, n); | 89 | return stream->vtable->write (stream, buf, buflen, o, n); |
90 | } | ||
91 | |||
92 | int | ||
93 | stream_seek (stream_t stream, off_t off, enum stream_whence whence) | ||
94 | { | ||
95 | if (stream == NULL || stream->vtable == NULL | ||
96 | || stream->vtable->seek == NULL) | ||
97 | return MU_ERROR_NOT_SUPPORTED; | ||
98 | return stream->vtable->seek (stream, off, whence); | ||
99 | } | 90 | } |
100 | 91 | ||
101 | int | 92 | int |
... | @@ -162,6 +153,15 @@ stream_get_state (stream_t stream, enum stream_state *state) | ... | @@ -162,6 +153,15 @@ stream_get_state (stream_t stream, enum stream_state *state) |
162 | } | 153 | } |
163 | 154 | ||
164 | int | 155 | int |
156 | stream_is_seekable (stream_t stream) | ||
157 | { | ||
158 | if (stream == NULL || stream->vtable == NULL | ||
159 | || stream->vtable->is_seekable == NULL) | ||
160 | return MU_ERROR_NOT_SUPPORTED; | ||
161 | return stream->vtable->is_seekable (stream); | ||
162 | } | ||
163 | |||
164 | int | ||
165 | stream_is_readready (stream_t stream, int timeout) | 165 | stream_is_readready (stream_t stream, int timeout) |
166 | { | 166 | { |
167 | if (stream == NULL || stream->vtable == NULL | 167 | if (stream == NULL || stream->vtable == NULL | ... | ... |
... | @@ -55,7 +55,7 @@ _stream_tcp_destroy (stream_t *pstream) | ... | @@ -55,7 +55,7 @@ _stream_tcp_destroy (stream_t *pstream) |
55 | struct _stream_tcp *tcp = (struct _stream_tcp *)*pstream; | 55 | struct _stream_tcp *tcp = (struct _stream_tcp *)*pstream; |
56 | if (mu_refcount_dec (tcp->base.refcount) == 0) | 56 | if (mu_refcount_dec (tcp->base.refcount) == 0) |
57 | { | 57 | { |
58 | _stream_fd_dtor (&tcp->base); | 58 | _stream_fd_dtor (*pstream); |
59 | if (tcp->host) | 59 | if (tcp->host) |
60 | free (tcp->host); | 60 | free (tcp->host); |
61 | free (tcp); | 61 | free (tcp); | ... | ... |
-
Please register or sign in to post a comment