* mail/mail.c: Possibility to enable debuging output.
It should probably be a runtime option via set debug=1 or something for now it is disable between if (0) {...}. More cleanup in the IMAP code. A memory stream buffer is use to save the string literal sended by the IMAP server. The allocation is handle by the memory_stream which simplifies the code. * folder_imap.c (folder_imap.c): Create a memory stream to hold the literal or quoted string send by the IMAP server. (folder_imap_list folder_imap_lsub): There is no callback field the struct folder_list is in struct _f_imap now. (imap_literal_string imap_quoted_string imap_string): Use the memory string stream to save the result. (imap_body): Still need to be clean, but creates the cache header when doing the scan. (imap_parse): Do not use alloca().
Showing
7 changed files
with
148 additions
and
39 deletions
1 | 2001-10-13 Jeff Bailey <jbailey@outpost.dnsalias.org> | 1 | 2001-10-13 Alain Malgoire |
2 | |||
3 | * mail/mail.c: Possibility to enable debuging output. | ||
4 | It should probably be a runtime option via set debug=1 or something | ||
5 | for now it is disable between if (0) {...}. | ||
6 | |||
7 | More cleanup in the IMAP code. A memory stream buffer is | ||
8 | use to save the string literal sended by the IMAP server. | ||
9 | The allocation is handle by the memory_stream which simplifies | ||
10 | the code. | ||
11 | |||
12 | * folder_imap.c (folder_imap.c): Create a memory stream to | ||
13 | hold the literal or quoted string send by the IMAP server. | ||
14 | (folder_imap_list folder_imap_lsub): There is no callback | ||
15 | field the struct folder_list is in struct _f_imap now. | ||
16 | (imap_literal_string imap_quoted_string imap_string): Use the | ||
17 | memory string stream to save the result. | ||
18 | (imap_body): Still need to be clean, but creates the cache | ||
19 | header when doing the scan. | ||
20 | (imap_parse): Do not use alloca(). | ||
21 | |||
22 | 2001-10-13 Jeff Bailey | ||
2 | 23 | ||
3 | * guimb/Makefile.am: Remove GNU Makeism. | 24 | * guimb/Makefile.am: Remove GNU Makeism. |
4 | 25 | ||
5 | * libmu_scm/Makefile.am: Remove GNU Makeism. | 26 | * libmu_scm/Makefile.am: Remove GNU Makeism. |
6 | 27 | ||
7 | 2001-10-12 Jeff Bailey <jbailey@outpost.dnsalias.org> | 28 | 2001-10-12 Jeff Bailey |
8 | 29 | ||
9 | * libmu_scm/Makefile.am: Fixes for RO srcdir. | 30 | * libmu_scm/Makefile.am: Fixes for RO srcdir. |
10 | 31 | ... | ... |
... | @@ -345,6 +345,14 @@ main (int argc, char **argv) | ... | @@ -345,6 +345,14 @@ main (int argc, char **argv) |
345 | exit (EXIT_FAILURE); | 345 | exit (EXIT_FAILURE); |
346 | } | 346 | } |
347 | 347 | ||
348 | /* Could we enable this at runtime, via the a set environment? */ | ||
349 | if (0) | ||
350 | { | ||
351 | mu_debug_t debug = NULL; | ||
352 | mailbox_get_debug (mbox, &debug); | ||
353 | mu_debug_set_level (debug, MU_DEBUG_TRACE|MU_DEBUG_PROT); | ||
354 | } | ||
355 | |||
348 | if (mailbox_open (mbox, MU_STREAM_RDWR) != 0) | 356 | if (mailbox_open (mbox, MU_STREAM_RDWR) != 0) |
349 | { | 357 | { |
350 | util_error ("Can not open mailbox"); | 358 | util_error ("Can not open mailbox"); | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -140,10 +140,24 @@ struct _f_imap | ... | @@ -140,10 +140,24 @@ struct _f_imap |
140 | size_t seq; /* Sequence number to build a tag. */ | 140 | size_t seq; /* Sequence number to build a tag. */ |
141 | char *capa; /* Cabilities of the server. */ | 141 | char *capa; /* Cabilities of the server. */ |
142 | size_t flags; | 142 | size_t flags; |
143 | struct literal_string callback; | 143 | |
144 | /* IO use to hold the literal and quoted strings send by | ||
145 | the IMAP server. */ | ||
146 | struct | ||
147 | { | ||
148 | stream_t stream; | ||
149 | off_t offset; | ||
150 | size_t nleft; /* nleft to read in the literal. */ | ||
151 | msg_imap_t msg_imap; | ||
152 | enum imap_state type; | ||
153 | } string; | ||
154 | |||
155 | /* Use for LIST and LSUB. */ | ||
156 | struct folder_list flist; | ||
144 | 157 | ||
145 | int isopen; | 158 | int isopen; |
146 | /* Buffer I/O */ | 159 | |
160 | /* Server channel buffer I/O */ | ||
147 | size_t buflen; | 161 | size_t buflen; |
148 | char *buffer; | 162 | char *buffer; |
149 | char *ptr; | 163 | char *ptr; |
... | @@ -155,7 +169,6 @@ struct _f_imap | ... | @@ -155,7 +169,6 @@ struct _f_imap |
155 | /* Login */ | 169 | /* Login */ |
156 | char *user; | 170 | char *user; |
157 | char *passwd; | 171 | char *passwd; |
158 | |||
159 | }; | 172 | }; |
160 | 173 | ||
161 | struct _m_imap | 174 | struct _m_imap |
... | @@ -187,6 +200,7 @@ struct _msg_imap | ... | @@ -187,6 +200,7 @@ struct _msg_imap |
187 | size_t uid; | 200 | size_t uid; |
188 | 201 | ||
189 | header_t fheader; | 202 | header_t fheader; |
203 | char *internal_date; | ||
190 | 204 | ||
191 | size_t message_size; | 205 | size_t message_size; |
192 | size_t message_lines; | 206 | size_t message_lines; | ... | ... |
... | @@ -174,6 +174,8 @@ free_subparts (msg_imap_t msg_imap) | ... | @@ -174,6 +174,8 @@ free_subparts (msg_imap_t msg_imap) |
174 | free (msg_imap->parts); | 174 | free (msg_imap->parts); |
175 | if (msg_imap->fheader) | 175 | if (msg_imap->fheader) |
176 | header_destroy (&msg_imap->fheader, NULL); | 176 | header_destroy (&msg_imap->fheader, NULL); |
177 | if (msg_imap->internal_date) | ||
178 | free (msg_imap->internal_date); | ||
177 | free(msg_imap); | 179 | free(msg_imap); |
178 | } | 180 | } |
179 | 181 | ||
... | @@ -672,9 +674,15 @@ imap_expunge (mailbox_t mailbox) | ... | @@ -672,9 +674,15 @@ imap_expunge (mailbox_t mailbox) |
672 | { | 674 | { |
673 | case IMAP_NO_STATE: | 675 | case IMAP_NO_STATE: |
674 | { | 676 | { |
675 | char *set; | 677 | char *set = NULL; |
676 | status = delete_to_string (m_imap, &set); | 678 | status = delete_to_string (m_imap, &set); |
677 | CHECK_ERROR (f_imap, status); | 679 | CHECK_ERROR (f_imap, status); |
680 | if (set == NULL || *set == '\0') | ||
681 | { | ||
682 | if (set) | ||
683 | free (set); | ||
684 | return 0; | ||
685 | } | ||
678 | status = imap_writeline (f_imap, | 686 | status = imap_writeline (f_imap, |
679 | "g%d STORE %s +FLAGS.SILENT (\\Deleted)\r\n", | 687 | "g%d STORE %s +FLAGS.SILENT (\\Deleted)\r\n", |
680 | f_imap->seq++, set); | 688 | f_imap->seq++, set); |
... | @@ -1224,6 +1232,9 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, | ... | @@ -1224,6 +1232,9 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, |
1224 | const char** datep = &date; | 1232 | const char** datep = &date; |
1225 | /* reserve as much space as we need for internal-date */ | 1233 | /* reserve as much space as we need for internal-date */ |
1226 | int status; | 1234 | int status; |
1235 | |||
1236 | if (msg_imap->internal_date == NULL) | ||
1237 | { | ||
1227 | if (f_imap->state == IMAP_NO_STATE) | 1238 | if (f_imap->state == IMAP_NO_STATE) |
1228 | { | 1239 | { |
1229 | /* Select first. */ | 1240 | /* Select first. */ |
... | @@ -1237,9 +1248,17 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, | ... | @@ -1237,9 +1248,17 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, |
1237 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 1248 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
1238 | f_imap->state = IMAP_FETCH; | 1249 | f_imap->state = IMAP_FETCH; |
1239 | } | 1250 | } |
1240 | status = fetch_operation (f_imap, msg_imap, datebuf, sizeof datebuf, NULL); | 1251 | status = fetch_operation (f_imap, msg_imap, datebuf, |
1252 | sizeof datebuf, NULL); | ||
1241 | if (status != 0) | 1253 | if (status != 0) |
1242 | return status; | 1254 | return status; |
1255 | msg_imap->internal_date = strdup (datebuf); | ||
1256 | } | ||
1257 | else | ||
1258 | { | ||
1259 | date = msg_imap->internal_date; | ||
1260 | datep = &date; | ||
1261 | } | ||
1243 | 1262 | ||
1244 | if (mu_parse_imap_date_time(datep, &tm, &tz) != 0) | 1263 | if (mu_parse_imap_date_time(datep, &tm, &tz) != 0) |
1245 | now = (time_t)-1; | 1264 | now = (time_t)-1; |
... | @@ -1323,6 +1342,10 @@ imap_attr_set_flags (attribute_t attribute, int flag) | ... | @@ -1323,6 +1342,10 @@ imap_attr_set_flags (attribute_t attribute, int flag) |
1323 | f_imap_t f_imap = m_imap->f_imap; | 1342 | f_imap_t f_imap = m_imap->f_imap; |
1324 | int status = 0; | 1343 | int status = 0; |
1325 | 1344 | ||
1345 | /* If already set don't bother. */ | ||
1346 | if (msg_imap->flags & flag) | ||
1347 | return 0; | ||
1348 | |||
1326 | /* The delete FLAG is not pass yet but only on the expunge. */ | 1349 | /* The delete FLAG is not pass yet but only on the expunge. */ |
1327 | if (flag & MU_ATTRIBUTE_DELETED) | 1350 | if (flag & MU_ATTRIBUTE_DELETED) |
1328 | { | 1351 | { |
... | @@ -1705,13 +1728,11 @@ fetch_operation (f_imap_t f_imap, msg_imap_t msg_imap, char *buffer, | ... | @@ -1705,13 +1728,11 @@ fetch_operation (f_imap_t f_imap, msg_imap_t msg_imap, char *buffer, |
1705 | case IMAP_FETCH: | 1728 | case IMAP_FETCH: |
1706 | status = imap_send (f_imap); | 1729 | status = imap_send (f_imap); |
1707 | CHECK_EAGAIN (f_imap, status); | 1730 | CHECK_EAGAIN (f_imap, status); |
1708 | if (f_imap->callback.buffer) | 1731 | stream_truncate (f_imap->string.stream, 0); |
1709 | free (f_imap->callback.buffer); | 1732 | f_imap->string.offset = 0; |
1710 | f_imap->callback.buffer = NULL; | 1733 | f_imap->string.nleft = 0; |
1711 | f_imap->callback.buflen = 0; | 1734 | f_imap->string.type = IMAP_NO_STATE; |
1712 | f_imap->callback.total = 0; | 1735 | f_imap->string.msg_imap = msg_imap; |
1713 | f_imap->callback.nleft = 0; | ||
1714 | f_imap->callback.msg_imap = msg_imap; | ||
1715 | f_imap->state = IMAP_FETCH_ACK; | 1736 | f_imap->state = IMAP_FETCH_ACK; |
1716 | 1737 | ||
1717 | case IMAP_FETCH_ACK: | 1738 | case IMAP_FETCH_ACK: |
... | @@ -1725,25 +1746,21 @@ fetch_operation (f_imap_t f_imap, msg_imap_t msg_imap, char *buffer, | ... | @@ -1725,25 +1746,21 @@ fetch_operation (f_imap_t f_imap, msg_imap_t msg_imap, char *buffer, |
1725 | break; | 1746 | break; |
1726 | } | 1747 | } |
1727 | 1748 | ||
1728 | if (status == 0 && f_imap->isopen == 0 && f_imap->callback.total == 0) | 1749 | f_imap->state = IMAP_NO_STATE; |
1750 | |||
1751 | /* The server may have timeout any case connection is gone away. */ | ||
1752 | if (status == 0 && f_imap->isopen == 0 && f_imap->string.offset == 0) | ||
1729 | status = EBADF; | 1753 | status = EBADF; |
1730 | 1754 | ||
1731 | buflen = min (buflen, f_imap->callback.total); | ||
1732 | if (f_imap->callback.buffer) | ||
1733 | { | ||
1734 | if (buffer) | 1755 | if (buffer) |
1735 | memcpy (buffer, f_imap->callback.buffer, buflen); | 1756 | stream_read (f_imap->string.stream, buffer, buflen, 0, plen); |
1736 | free (f_imap->callback.buffer); | 1757 | else if (plen) |
1737 | } | 1758 | *plen = 0; |
1738 | if (plen) | 1759 | stream_truncate (f_imap->string.stream, 0); |
1739 | *plen = buflen; | 1760 | f_imap->string.offset = 0; |
1740 | f_imap->callback.buffer = NULL; | 1761 | f_imap->string.nleft = 0; |
1741 | f_imap->callback.buflen = 0; | 1762 | f_imap->string.type = IMAP_NO_STATE; |
1742 | f_imap->callback.total = 0; | 1763 | f_imap->string.msg_imap = NULL; |
1743 | f_imap->callback.nleft = 0; | ||
1744 | f_imap->callback.type = 0; | ||
1745 | f_imap->callback.msg_imap = NULL; | ||
1746 | f_imap->state = IMAP_NO_STATE; | ||
1747 | return status; | 1764 | return status; |
1748 | } | 1765 | } |
1749 | 1766 | ... | ... |
... | @@ -22,15 +22,24 @@ | ... | @@ -22,15 +22,24 @@ |
22 | #include <errno.h> | 22 | #include <errno.h> |
23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | #include <string.h> | 24 | #include <string.h> |
25 | #include <sys/stat.h> | ||
26 | #include <unistd.h> | ||
27 | #include <stdio.h> | ||
25 | 28 | ||
26 | #include <sys/types.h> | 29 | #include <sys/types.h> |
27 | 30 | ||
28 | #include <mailutils/stream.h> | 31 | #include <mailutils/stream.h> |
29 | 32 | ||
33 | #undef min | ||
34 | #define min(a,b) ((a) < (b) ? (a) : (b)) | ||
35 | |||
36 | #define MU_STREAM_MEMORY_BLOCKSIZE 128 | ||
37 | |||
30 | struct _memory_stream | 38 | struct _memory_stream |
31 | { | 39 | { |
32 | char *ptr; | 40 | char *ptr; |
33 | size_t size; | 41 | size_t size; |
42 | size_t capacity; | ||
34 | }; | 43 | }; |
35 | 44 | ||
36 | static void | 45 | static void |
... | @@ -71,7 +80,7 @@ _memory_readline (stream_t stream, char *optr, size_t osize, | ... | @@ -71,7 +80,7 @@ _memory_readline (stream_t stream, char *optr, size_t osize, |
71 | osize--; | 80 | osize--; |
72 | nl = memchr (mfs->ptr + offset, '\n', mfs->size - offset); | 81 | nl = memchr (mfs->ptr + offset, '\n', mfs->size - offset); |
73 | n = (nl) ? (size_t)(nl - (mfs->ptr + offset) + 1) : mfs->size - offset; | 82 | n = (nl) ? (size_t)(nl - (mfs->ptr + offset) + 1) : mfs->size - offset; |
74 | n = (n > osize) ? osize : n; | 83 | n = min (n, osize); |
75 | memcpy (optr, mfs->ptr + offset, n); | 84 | memcpy (optr, mfs->ptr + offset, n); |
76 | optr[n] = '\0'; | 85 | optr[n] = '\0'; |
77 | } | 86 | } |
... | @@ -87,13 +96,17 @@ _memory_write (stream_t stream, const char *iptr, size_t isize, | ... | @@ -87,13 +96,17 @@ _memory_write (stream_t stream, const char *iptr, size_t isize, |
87 | struct _memory_stream *mfs = stream_get_owner (stream); | 96 | struct _memory_stream *mfs = stream_get_owner (stream); |
88 | 97 | ||
89 | /* Bigger we have to realloc. */ | 98 | /* Bigger we have to realloc. */ |
90 | if (mfs->size < (offset + isize)) | 99 | if (mfs->capacity < (offset + isize)) |
91 | { | 100 | { |
92 | char *tmp = realloc (mfs->ptr, offset + isize); | 101 | /* Realloc by fixed blocks of 128. */ |
102 | int newsize = MU_STREAM_MEMORY_BLOCKSIZE * | ||
103 | (((offset + isize)/MU_STREAM_MEMORY_BLOCKSIZE) + 1); | ||
104 | char *tmp = realloc (mfs->ptr, newsize); | ||
93 | if (tmp == NULL) | 105 | if (tmp == NULL) |
94 | return ENOMEM; | 106 | return ENOMEM; |
95 | mfs->ptr = tmp; | 107 | mfs->ptr = tmp; |
96 | mfs->size = offset + isize; | 108 | mfs->size = offset + isize; |
109 | mfs->capacity = newsize; | ||
97 | } | 110 | } |
98 | 111 | ||
99 | memcpy (mfs->ptr + offset, iptr, isize); | 112 | memcpy (mfs->ptr + offset, iptr, isize); |
... | @@ -109,6 +122,7 @@ _memory_truncate (stream_t stream, off_t len) | ... | @@ -109,6 +122,7 @@ _memory_truncate (stream_t stream, off_t len) |
109 | 122 | ||
110 | if (len == 0) | 123 | if (len == 0) |
111 | { | 124 | { |
125 | if (mfs->ptr) | ||
112 | free (mfs->ptr); | 126 | free (mfs->ptr); |
113 | mfs->ptr = NULL; | 127 | mfs->ptr = NULL; |
114 | } | 128 | } |
... | @@ -120,6 +134,7 @@ _memory_truncate (stream_t stream, off_t len) | ... | @@ -120,6 +134,7 @@ _memory_truncate (stream_t stream, off_t len) |
120 | mfs->ptr = tmp; | 134 | mfs->ptr = tmp; |
121 | } | 135 | } |
122 | mfs->size = len; | 136 | mfs->size = len; |
137 | mfs->capacity = len; | ||
123 | return 0; | 138 | return 0; |
124 | } | 139 | } |
125 | 140 | ||
... | @@ -137,11 +152,10 @@ _memory_close (stream_t stream) | ... | @@ -137,11 +152,10 @@ _memory_close (stream_t stream) |
137 | { | 152 | { |
138 | struct _memory_stream *mfs = stream_get_owner (stream); | 153 | struct _memory_stream *mfs = stream_get_owner (stream); |
139 | if (mfs->ptr) | 154 | if (mfs->ptr) |
140 | { | ||
141 | free (mfs->ptr); | 155 | free (mfs->ptr); |
142 | mfs->ptr = NULL; | 156 | mfs->ptr = NULL; |
143 | mfs->size = 0; | 157 | mfs->size = 0; |
144 | } | 158 | mfs->capacity = 0; |
145 | return 0; | 159 | return 0; |
146 | } | 160 | } |
147 | 161 | ||
... | @@ -149,6 +163,7 @@ static int | ... | @@ -149,6 +163,7 @@ static int |
149 | _memory_open (stream_t stream, const char *filename, int port, int flags) | 163 | _memory_open (stream_t stream, const char *filename, int port, int flags) |
150 | { | 164 | { |
151 | struct _memory_stream *mfs = stream_get_owner (stream); | 165 | struct _memory_stream *mfs = stream_get_owner (stream); |
166 | int status = 0; | ||
152 | 167 | ||
153 | (void)port; /* Ignored. */ | 168 | (void)port; /* Ignored. */ |
154 | (void)filename; /* Ignored. */ | 169 | (void)filename; /* Ignored. */ |
... | @@ -156,13 +171,47 @@ _memory_open (stream_t stream, const char *filename, int port, int flags) | ... | @@ -156,13 +171,47 @@ _memory_open (stream_t stream, const char *filename, int port, int flags) |
156 | 171 | ||
157 | /* Close any previous file. */ | 172 | /* Close any previous file. */ |
158 | if (mfs->ptr) | 173 | if (mfs->ptr) |
174 | free (mfs->ptr); | ||
175 | mfs->ptr = NULL; | ||
176 | mfs->size = 0; | ||
177 | mfs->capacity = 0; | ||
178 | stream_set_flags (stream, flags |MU_STREAM_NO_CHECK); | ||
179 | if (filename) | ||
180 | { | ||
181 | struct stat statbuf; | ||
182 | if (stat (filename, &statbuf) == 0) | ||
183 | { | ||
184 | mfs->ptr = calloc (statbuf.st_size, 1); | ||
185 | if (mfs->ptr) | ||
186 | { | ||
187 | FILE *fp; | ||
188 | mfs->capacity = statbuf.st_size; | ||
189 | mfs->size = statbuf.st_size; | ||
190 | fp = fopen (filename, "r"); | ||
191 | if (fp) | ||
192 | { | ||
193 | size_t r = fread (mfs->ptr, mfs->size, 1, fp); | ||
194 | if (r != mfs->size) | ||
195 | status = EIO; | ||
196 | fclose (fp); | ||
197 | } | ||
198 | else | ||
199 | status = errno; | ||
200 | if (status != 0) | ||
159 | { | 201 | { |
160 | free (mfs->ptr); | 202 | free (mfs->ptr); |
161 | mfs->ptr = NULL; | 203 | mfs->ptr = NULL; |
204 | mfs->capacity = 0; | ||
162 | mfs->size = 0; | 205 | mfs->size = 0; |
163 | } | 206 | } |
164 | stream_set_flags (stream, flags |MU_STREAM_NO_CHECK); | 207 | } |
165 | return 0; | 208 | else |
209 | status = ENOMEM; | ||
210 | } | ||
211 | else | ||
212 | status = EIO; | ||
213 | } | ||
214 | return status; | ||
166 | } | 215 | } |
167 | 216 | ||
168 | int | 217 | int | ... | ... |
... | @@ -60,8 +60,7 @@ _stream_memory_read (stream_t stream, void *optr, size_t osize, | ... | @@ -60,8 +60,7 @@ _stream_memory_read (stream_t stream, void *optr, size_t osize, |
60 | mu_refcount_lock (mem->refcount); | 60 | mu_refcount_lock (mem->refcount); |
61 | if (mem->ptr != NULL && (offset < (off_t)mem->size)) | 61 | if (mem->ptr != NULL && (offset < (off_t)mem->size)) |
62 | { | 62 | { |
63 | n = ((offset + osize) > mem->size) ? | 63 | n = ((offset + osize) > mem->size) ? mem->size - offset : osize; |
64 | mem->size - offset : osize; | ||
65 | memcpy (optr, mem->ptr + offset, n); | 64 | memcpy (optr, mem->ptr + offset, n); |
66 | } | 65 | } |
67 | mu_refcount_unlock (mem->refcount); | 66 | mu_refcount_unlock (mem->refcount); |
... | @@ -130,6 +129,7 @@ _stream_memory_truncate (stream_t stream, off_t len) | ... | @@ -130,6 +129,7 @@ _stream_memory_truncate (stream_t stream, off_t len) |
130 | mu_refcount_lock (mem->refcount); | 129 | mu_refcount_lock (mem->refcount); |
131 | if (len == 0) | 130 | if (len == 0) |
132 | { | 131 | { |
132 | if (mem->ptr) | ||
133 | free (mem->ptr); | 133 | free (mem->ptr); |
134 | mem->ptr = NULL; | 134 | mem->ptr = NULL; |
135 | } | 135 | } | ... | ... |
-
Please register or sign in to post a comment