ChangeLog : Updated
doc/mailbox.texi : Why is this always show? I did not touch it. lib/strtok_r.c : Return NULL and save the old pointer. mailbox/folder_imap.c mailbox/mbx_imap.c: Implement FETCH .. ye!!! mailbox/mbx_mbox.c : some comments.
Showing
5 changed files
with
332 additions
and
130 deletions
1 | 2001-02-25 Alain Magloire | ||
2 | |||
3 | * lib/strtok_r.c : If there are no delimiters left save the old string | ||
4 | and return NULL. | ||
5 | |||
6 | * mailbox/folder_imap.c (imap_fetch) : Finish imap FETCH command. | ||
7 | (imap_rfc822) : New Function. | ||
8 | (imap_rfc822_text) : New Function. | ||
9 | (imap_rfc822_size) : New Function. | ||
10 | (imap_rfc822_header) : New Function. | ||
11 | (imap_uid) : New Function. | ||
12 | (imap_body) : New Function. | ||
13 | (imap_bodystructure0) : Save the size. | ||
14 | |||
1 | 2001-02-22 Alain Magloire | 15 | 2001-02-22 Alain Magloire |
2 | 16 | ||
3 | * mailbox/property.c : New file. | 17 | * mailbox/property.c : New file. | ... | ... |
... | @@ -43,7 +43,10 @@ strtok_r (s, delim, save_ptr) | ... | @@ -43,7 +43,10 @@ strtok_r (s, delim, save_ptr) |
43 | /* Scan leading delimiters. */ | 43 | /* Scan leading delimiters. */ |
44 | s += strspn (s, delim); | 44 | s += strspn (s, delim); |
45 | if (*s == '\0') | 45 | if (*s == '\0') |
46 | return NULL; | 46 | { |
47 | *save_ptr = s; | ||
48 | return NULL; | ||
49 | } | ||
47 | 50 | ||
48 | /* Find the end of the token. */ | 51 | /* Find the end of the token. */ |
49 | token = s; | 52 | token = s; | ... | ... |
... | @@ -20,6 +20,7 @@ | ... | @@ -20,6 +20,7 @@ |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #include <stdlib.h> | 22 | #include <stdlib.h> |
23 | #include <ctype.h> | ||
23 | #include <stdarg.h> | 24 | #include <stdarg.h> |
24 | #include <errno.h> | 25 | #include <errno.h> |
25 | #include <string.h> | 26 | #include <string.h> |
... | @@ -62,14 +63,23 @@ static int folder_imap_unsubscribe __P ((folder_t, const char *)); | ... | @@ -62,14 +63,23 @@ static int folder_imap_unsubscribe __P ((folder_t, const char *)); |
62 | 63 | ||
63 | /* Private */ | 64 | /* Private */ |
64 | /* static int imap_readline (f_imap_t); */ | 65 | /* static int imap_readline (f_imap_t); */ |
66 | /* FETCH */ | ||
65 | static int imap_fetch __P ((f_imap_t)); | 67 | static int imap_fetch __P ((f_imap_t)); |
68 | static int imap_rfc822 __P ((f_imap_t, char **)); | ||
69 | static int imap_rfc822_size __P ((f_imap_t, char **)); | ||
70 | static int imap_rfc822_header __P ((f_imap_t, char **)); | ||
71 | static int imap_rfc822_text __P ((f_imap_t, char **)); | ||
66 | static int imap_flags __P ((f_imap_t, char **)); | 72 | static int imap_flags __P ((f_imap_t, char **)); |
67 | static int imap_bodystructure __P ((f_imap_t, char **)); | 73 | static int imap_bodystructure __P ((f_imap_t, char **)); |
74 | static int imap_body __P ((f_imap_t, char **)); | ||
75 | static int imap_uid __P ((f_imap_t, char **)); | ||
76 | |||
77 | /* String. */ | ||
68 | static int imap_literal_string __P ((f_imap_t, char **)); | 78 | static int imap_literal_string __P ((f_imap_t, char **)); |
69 | static int imap_string __P ((f_imap_t, char **)); | 79 | static int imap_string __P ((f_imap_t, char **)); |
70 | static int imap_quoted_string __P ((f_imap_t, char **)); | 80 | static int imap_quoted_string __P ((f_imap_t, char **)); |
71 | #define TOKENLEN 32 | 81 | |
72 | static int imap_token __P ((char *, char **)); | 82 | static int imap_token __P ((char *, size_t, char **)); |
73 | 83 | ||
74 | /* Initialize the concrete IMAP mailbox: overload the folder functions */ | 84 | /* Initialize the concrete IMAP mailbox: overload the folder functions */ |
75 | int | 85 | int |
... | @@ -750,37 +760,37 @@ imap_literal_string (f_imap_t f_imap, char **ptr) | ... | @@ -750,37 +760,37 @@ imap_literal_string (f_imap_t f_imap, char **ptr) |
750 | memcpy (f_imap->callback.buffer + f_imap->callback.total, | 760 | memcpy (f_imap->callback.buffer + f_imap->callback.total, |
751 | f_imap->buffer, x); | 761 | f_imap->buffer, x); |
752 | f_imap->callback.total += x; | 762 | f_imap->callback.total += x; |
753 | } | ||
754 | 763 | ||
755 | /* Depending on the type of request we incremente the xxxx_lines | 764 | /* Depending on the type of request we incremente the xxxx_lines |
756 | and xxxx_sizes. */ | 765 | and xxxx_sizes. */ |
757 | nl = (memchr (f_imap->buffer, '\n', len0)) ? 1 : 0; | 766 | nl = (memchr (f_imap->buffer, '\n', len0)) ? 1 : 0; |
758 | if (f_imap->callback.msg_imap) | 767 | if (f_imap->callback.msg_imap) |
759 | { | ||
760 | switch (f_imap->callback.type) | ||
761 | { | 768 | { |
762 | case IMAP_HEADER: | 769 | switch (f_imap->callback.type) |
763 | f_imap->callback.msg_imap->header_lines += nl; | 770 | { |
764 | f_imap->callback.msg_imap->header_size += f_imap->callback.total; | 771 | case IMAP_HEADER: |
765 | break; | 772 | f_imap->callback.msg_imap->header_lines += nl; |
773 | f_imap->callback.msg_imap->header_size += x; | ||
774 | break; | ||
766 | 775 | ||
767 | case IMAP_BODY: | 776 | case IMAP_BODY: |
768 | f_imap->callback.msg_imap->body_lines += nl; | 777 | f_imap->callback.msg_imap->body_lines += nl; |
769 | f_imap->callback.msg_imap->body_size += f_imap->callback.total; | 778 | f_imap->callback.msg_imap->body_size += x; |
770 | break; | 779 | break; |
771 | 780 | ||
772 | case IMAP_MESSAGE: | 781 | case IMAP_MESSAGE: |
773 | f_imap->callback.msg_imap->message_lines += nl; | 782 | f_imap->callback.msg_imap->message_lines += nl; |
774 | /* The message size is known by sending RFC822.SIZE. */ | 783 | /* The message size is known by sending RFC822.SIZE. */ |
775 | 784 | ||
776 | default: | 785 | default: |
777 | break; | 786 | break; |
787 | } | ||
778 | } | 788 | } |
779 | } | 789 | } |
780 | } | 790 | } |
781 | f_imap->callback.nleft -= total; | 791 | f_imap->callback.nleft -= total; |
782 | /* Move the command buffer, or do a full readline. */ | 792 | /* Move the command buffer, or do a full readline. */ |
783 | if (len == (f_imap->nl - f_imap->buffer)) | 793 | if (len == (size_t)(f_imap->nl - f_imap->buffer)) |
784 | { | 794 | { |
785 | len = 0; | 795 | len = 0; |
786 | status = imap_readline (f_imap); | 796 | status = imap_readline (f_imap); |
... | @@ -843,6 +853,7 @@ imap_string (f_imap_t f_imap, char **ptr) | ... | @@ -843,6 +853,7 @@ imap_string (f_imap_t f_imap, char **ptr) |
843 | /* NIL */ | 853 | /* NIL */ |
844 | case 'N': | 854 | case 'N': |
845 | case 'n': | 855 | case 'n': |
856 | (*ptr)++; /* N|n */ | ||
846 | (*ptr)++; /* I|i */ | 857 | (*ptr)++; /* I|i */ |
847 | (*ptr)++; /* L|l */ | 858 | (*ptr)++; /* L|l */ |
848 | break; | 859 | break; |
... | @@ -992,22 +1003,49 @@ imap_bodystructure0 (msg_imap_t msg_imap, char **ptr) | ... | @@ -992,22 +1003,49 @@ imap_bodystructure0 (msg_imap_t msg_imap, char **ptr) |
992 | int paren = 0; | 1003 | int paren = 0; |
993 | int no_arg = 0; | 1004 | int no_arg = 0; |
994 | int status = 0; | 1005 | int status = 0; |
1006 | int have_size = 0; | ||
995 | 1007 | ||
996 | /* Skip space. */ | 1008 | /* Skip space. */ |
997 | while (**ptr == ' ') | 1009 | while (**ptr == ' ') |
998 | (*ptr)++; | 1010 | (*ptr)++; |
999 | if (**ptr != '(') | ||
1000 | return 0; /* Something is wrong. */ | ||
1001 | |||
1002 | /* Pass lparen. */ | 1011 | /* Pass lparen. */ |
1003 | ++(*ptr); | 1012 | if (**ptr == '(') |
1004 | paren++; | 1013 | { |
1005 | no_arg++; | 1014 | ++(*ptr); |
1006 | for (; **ptr; ++(*ptr)) | 1015 | paren++; |
1016 | no_arg++; | ||
1017 | } | ||
1018 | /* NOTE : this loop has side effects in strtol() and imap_string(), the | ||
1019 | order of the if's are important. */ | ||
1020 | while (**ptr) | ||
1007 | { | 1021 | { |
1022 | /* Skip the string argument. */ | ||
1023 | if (**ptr != '(' && **ptr != ')') | ||
1024 | { | ||
1025 | char *start = *ptr; | ||
1026 | /* FIXME: set the command callback if EAGAIN to resume. */ | ||
1027 | status = imap_string (msg_imap->m_imap->f_imap, ptr); | ||
1028 | if (status != 0) | ||
1029 | return status; | ||
1030 | if (start != *ptr) | ||
1031 | no_arg = 0; | ||
1032 | } | ||
1033 | |||
1034 | if (isdigit (**ptr)) | ||
1035 | { | ||
1036 | char *start = *ptr; | ||
1037 | size_t size = strtoul (*ptr, ptr, 10); | ||
1038 | if (start != *ptr) | ||
1039 | { | ||
1040 | if (!have_size && msg_imap && msg_imap->parent) | ||
1041 | msg_imap->message_size = size; | ||
1042 | have_size = 1; | ||
1043 | no_arg = 0; | ||
1044 | } | ||
1045 | } | ||
1046 | |||
1008 | if (**ptr == '(') | 1047 | if (**ptr == '(') |
1009 | { | 1048 | { |
1010 | paren++; | ||
1011 | if (no_arg) | 1049 | if (no_arg) |
1012 | { | 1050 | { |
1013 | msg_imap_t new_part; | 1051 | msg_imap_t new_part; |
... | @@ -1016,10 +1054,10 @@ imap_bodystructure0 (msg_imap_t msg_imap, char **ptr) | ... | @@ -1016,10 +1054,10 @@ imap_bodystructure0 (msg_imap_t msg_imap, char **ptr) |
1016 | ((msg_imap->num_parts + 1) * sizeof (*tmp))); | 1054 | ((msg_imap->num_parts + 1) * sizeof (*tmp))); |
1017 | if (tmp) | 1055 | if (tmp) |
1018 | { | 1056 | { |
1019 | msg_imap->parts = tmp; | ||
1020 | new_part = calloc (1, sizeof (*new_part)); | 1057 | new_part = calloc (1, sizeof (*new_part)); |
1021 | if (new_part) | 1058 | if (new_part) |
1022 | { | 1059 | { |
1060 | msg_imap->parts = tmp; | ||
1023 | msg_imap->parts[msg_imap->num_parts] = new_part; | 1061 | msg_imap->parts[msg_imap->num_parts] = new_part; |
1024 | new_part->part = ++(msg_imap->num_parts); | 1062 | new_part->part = ++(msg_imap->num_parts); |
1025 | new_part->parent = msg_imap; | 1063 | new_part->parent = msg_imap; |
... | @@ -1027,36 +1065,44 @@ imap_bodystructure0 (msg_imap_t msg_imap, char **ptr) | ... | @@ -1027,36 +1065,44 @@ imap_bodystructure0 (msg_imap_t msg_imap, char **ptr) |
1027 | new_part->m_imap = msg_imap->m_imap; | 1065 | new_part->m_imap = msg_imap->m_imap; |
1028 | new_part->flags = msg_imap->flags; | 1066 | new_part->flags = msg_imap->flags; |
1029 | status = imap_bodystructure0 (new_part, ptr); | 1067 | status = imap_bodystructure0 (new_part, ptr); |
1068 | /* Jump up, the rparen been swallen already. */ | ||
1069 | continue; | ||
1030 | } | 1070 | } |
1031 | else | 1071 | else |
1032 | status = ENOMEM; | 1072 | { |
1073 | status = ENOMEM; | ||
1074 | free (tmp); | ||
1075 | break; | ||
1076 | } | ||
1033 | } | 1077 | } |
1034 | else | 1078 | else |
1035 | status = ENOMEM; | 1079 | { |
1080 | status = ENOMEM; | ||
1081 | break; | ||
1082 | } | ||
1036 | } | 1083 | } |
1084 | paren++; | ||
1037 | } | 1085 | } |
1086 | |||
1038 | if (**ptr == ')') | 1087 | if (**ptr == ')') |
1039 | { | 1088 | { |
1040 | no_arg = 1; | 1089 | no_arg = 1; |
1041 | paren--; | 1090 | paren--; |
1042 | /* Did we reach the same number of close paren ? */ | 1091 | /* Did we reach the same number of close paren ? */ |
1043 | if (paren <= 0) | 1092 | if (paren <= 0) |
1044 | break; | 1093 | { |
1094 | /* Swallow the rparen. */ | ||
1095 | (*ptr)++; | ||
1096 | break; | ||
1097 | } | ||
1045 | } | 1098 | } |
1046 | /* Skip the rests */ | ||
1047 | else | ||
1048 | { | ||
1049 | /* FIXME: set the command callback if EAGAIN to resume. */ | ||
1050 | status = imap_string (msg_imap->m_imap->f_imap, ptr); | ||
1051 | if (status != 0) | ||
1052 | return status; | ||
1053 | no_arg = 0; | ||
1054 | } | ||
1055 | 1099 | ||
1056 | if (**ptr == '\0') | 1100 | if (**ptr == '\0') |
1057 | break; | 1101 | break; |
1102 | |||
1103 | (*ptr)++; | ||
1058 | } | 1104 | } |
1059 | return 0; | 1105 | return status; |
1060 | } | 1106 | } |
1061 | 1107 | ||
1062 | static int | 1108 | static int |
... | @@ -1164,14 +1210,39 @@ imap_flags (f_imap_t f_imap, char **ptr) | ... | @@ -1164,14 +1210,39 @@ imap_flags (f_imap_t f_imap, char **ptr) |
1164 | static int | 1210 | static int |
1165 | imap_body (f_imap_t f_imap, char **ptr) | 1211 | imap_body (f_imap_t f_imap, char **ptr) |
1166 | { | 1212 | { |
1167 | char *sep; | 1213 | int status; |
1214 | |||
1168 | while (**ptr && **ptr == ' ') | 1215 | while (**ptr && **ptr == ' ') |
1169 | (*ptr)++; | 1216 | (*ptr)++; |
1217 | |||
1170 | if (**ptr == '[') | 1218 | if (**ptr == '[') |
1171 | { | 1219 | { |
1172 | sep = strchr (*ptr, ']'); | 1220 | char *sep = strchr (*ptr, ']'); |
1173 | if (sep) | 1221 | if (sep) |
1174 | { | 1222 | { |
1223 | size_t len = sep - *ptr; | ||
1224 | char *section = alloca (len + 1); | ||
1225 | char *p = section; | ||
1226 | strncpy (section, *ptr, len); | ||
1227 | section[len] = '\0'; | ||
1228 | /* strupper. */ | ||
1229 | for (; *p; p++) | ||
1230 | if (isalpha((unsigned)*p)) | ||
1231 | *p = toupper ((unsigned)*p); | ||
1232 | /* Check to see the callback type to update the line count. */ | ||
1233 | if (strstr (section, "MIME") | ||
1234 | || (strstr (section, "HEADER") && ! strstr (section, "FIELD"))) | ||
1235 | { | ||
1236 | f_imap->callback.type = IMAP_HEADER; | ||
1237 | } | ||
1238 | else if (strstr (section, "TEXT")) | ||
1239 | { | ||
1240 | f_imap->callback.type = IMAP_BODY; | ||
1241 | } | ||
1242 | else if (len == 1) /* body[] */ | ||
1243 | { | ||
1244 | f_imap->callback.type = IMAP_MESSAGE; | ||
1245 | } | ||
1175 | sep++; | 1246 | sep++; |
1176 | *ptr = sep; | 1247 | *ptr = sep; |
1177 | } | 1248 | } |
... | @@ -1180,14 +1251,16 @@ imap_body (f_imap_t f_imap, char **ptr) | ... | @@ -1180,14 +1251,16 @@ imap_body (f_imap_t f_imap, char **ptr) |
1180 | (*ptr)++; | 1251 | (*ptr)++; |
1181 | if (**ptr == '<') | 1252 | if (**ptr == '<') |
1182 | { | 1253 | { |
1183 | sep = strchr (*ptr, '>'); | 1254 | char *sep = strchr (*ptr, '>'); |
1184 | if (sep) | 1255 | if (sep) |
1185 | { | 1256 | { |
1186 | sep++; | 1257 | sep++; |
1187 | *ptr = sep; | 1258 | *ptr = sep; |
1188 | } | 1259 | } |
1189 | } | 1260 | } |
1190 | return imap_string (f_imap, ptr); | 1261 | status = imap_string (f_imap, ptr); |
1262 | f_imap->callback.type = IMAP_MESSAGE; | ||
1263 | return status; | ||
1191 | } | 1264 | } |
1192 | 1265 | ||
1193 | static int | 1266 | static int |
... | @@ -1196,15 +1269,80 @@ imap_internaldate (f_imap_t f_imap, char **ptr) | ... | @@ -1196,15 +1269,80 @@ imap_internaldate (f_imap_t f_imap, char **ptr) |
1196 | return imap_string (f_imap, ptr); | 1269 | return imap_string (f_imap, ptr); |
1197 | } | 1270 | } |
1198 | 1271 | ||
1199 | /* Parse imap unfortunately FETCH is use as response for many commands. */ | 1272 | static int |
1273 | imap_uid (f_imap_t f_imap, char **ptr) | ||
1274 | { | ||
1275 | char token[128]; | ||
1276 | imap_token (token, sizeof (token), ptr); | ||
1277 | if (f_imap->callback.msg_imap) | ||
1278 | f_imap->callback.msg_imap->uid = strtoul (token, NULL, 10); | ||
1279 | return 0; | ||
1280 | } | ||
1281 | |||
1282 | static int | ||
1283 | imap_rfc822 (f_imap_t f_imap, char **ptr) | ||
1284 | { | ||
1285 | int status; | ||
1286 | f_imap->callback.type = IMAP_MESSAGE; | ||
1287 | status = imap_body (f_imap, ptr); | ||
1288 | f_imap->callback.type = 0; | ||
1289 | return status; | ||
1290 | } | ||
1291 | |||
1292 | static int | ||
1293 | imap_rfc822_size (f_imap_t f_imap, char **ptr) | ||
1294 | { | ||
1295 | char token[128]; | ||
1296 | imap_token (token, sizeof (token), ptr); | ||
1297 | if (f_imap->callback.msg_imap) | ||
1298 | f_imap->callback.msg_imap->message_size = strtoul (token, NULL, 10); | ||
1299 | return 0; | ||
1300 | } | ||
1301 | |||
1302 | static int | ||
1303 | imap_rfc822_header (f_imap_t f_imap, char **ptr) | ||
1304 | { | ||
1305 | int status; | ||
1306 | f_imap->callback.type = IMAP_HEADER; | ||
1307 | status = imap_string (f_imap, ptr); | ||
1308 | f_imap->callback.type = 0; | ||
1309 | return status; | ||
1310 | } | ||
1311 | |||
1312 | static int | ||
1313 | imap_rfc822_text (f_imap_t f_imap, char **ptr) | ||
1314 | { | ||
1315 | int status; | ||
1316 | f_imap->callback.type = IMAP_HEADER; | ||
1317 | status = imap_string (f_imap, ptr); | ||
1318 | f_imap->callback.type = 0; | ||
1319 | return status; | ||
1320 | } | ||
1321 | |||
1322 | /* Parse imap unfortunately FETCH is use as response for many commands. | ||
1323 | We just use a small set an ignore the other ones : | ||
1324 | not use : ALL | ||
1325 | use : BODY | ||
1326 | not use : BODY[<section>]<<partial>> | ||
1327 | use : BODY.PEEK[<section>]<<partial>> | ||
1328 | not use : BODYSTRUCTURE | ||
1329 | not use : ENVELOPE | ||
1330 | not use : FAST | ||
1331 | use : FLAGS | ||
1332 | not use : FULL | ||
1333 | use : INTERNALDATE | ||
1334 | not use : RFC822 | ||
1335 | not use : RFC822.HEADER | ||
1336 | use : RFC822.SIZE | ||
1337 | not use : RFC822.TEXT | ||
1338 | not use : UID | ||
1339 | */ | ||
1200 | static int | 1340 | static int |
1201 | imap_fetch (f_imap_t f_imap) | 1341 | imap_fetch (f_imap_t f_imap) |
1202 | { | 1342 | { |
1203 | char command[128]; | 1343 | char token[128]; |
1204 | size_t msgno = 0; | 1344 | size_t msgno = 0; |
1205 | size_t len = f_imap->nl - f_imap->buffer; | ||
1206 | m_imap_t m_imap = f_imap->selected; | 1345 | m_imap_t m_imap = f_imap->selected; |
1207 | const char *delim = " "; | ||
1208 | int status = 0; | 1346 | int status = 0; |
1209 | char *sp = NULL; | 1347 | char *sp = NULL; |
1210 | 1348 | ||
... | @@ -1215,12 +1353,12 @@ imap_fetch (f_imap_t f_imap) | ... | @@ -1215,12 +1353,12 @@ imap_fetch (f_imap_t f_imap) |
1215 | sp = f_imap->buffer; | 1353 | sp = f_imap->buffer; |
1216 | 1354 | ||
1217 | /* Skip untag '*'. */ | 1355 | /* Skip untag '*'. */ |
1218 | imap_token (command, &sp); | 1356 | imap_token (token, sizeof (token), &sp); |
1219 | /* Get msgno. */ | 1357 | /* Get msgno. */ |
1220 | imap_token (command, &sp); | 1358 | imap_token (token, sizeof (token), &sp); |
1221 | msgno = strtol (command, NULL, 10); | 1359 | msgno = strtol (token, NULL, 10); |
1222 | /* Skip FETCH . */ | 1360 | /* Skip FETCH . */ |
1223 | imap_token (command, &sp); | 1361 | imap_token (token, sizeof (token), &sp); |
1224 | 1362 | ||
1225 | /* It is actually possible, but higly unlikely that we do not have the | 1363 | /* It is actually possible, but higly unlikely that we do not have the |
1226 | message yet, for example a "FETCH (FLAGS (\Recent))" notification | 1364 | message yet, for example a "FETCH (FLAGS (\Recent))" notification |
... | @@ -1239,73 +1377,81 @@ imap_fetch (f_imap_t f_imap) | ... | @@ -1239,73 +1377,81 @@ imap_fetch (f_imap_t f_imap) |
1239 | } | 1377 | } |
1240 | } | 1378 | } |
1241 | } | 1379 | } |
1242 | // assert (msg_imap != NULL); | ||
1243 | |||
1244 | #if 0 | ||
1245 | /* skip to '(' */ | ||
1246 | while (*sp && *sp != '(') | ||
1247 | sp++; | ||
1248 | #endif | ||
1249 | 1380 | ||
1250 | /* Get the commands. */ | ||
1251 | while (*sp && *sp != ')') | 1381 | while (*sp && *sp != ')') |
1252 | { | 1382 | { |
1253 | imap_token (command, &sp); | 1383 | /* Get the token. */ |
1254 | if (strncmp (command, "FLAGS", 5) == 0) | 1384 | imap_token (token, sizeof (token), &sp); |
1385 | |||
1386 | if (strncmp (token, "FLAGS", 5) == 0) | ||
1255 | { | 1387 | { |
1256 | status = imap_flags (f_imap, &sp); | 1388 | status = imap_flags (f_imap, &sp); |
1257 | } | 1389 | } |
1258 | else if (strcasecmp (command, "BODY") == 0 | 1390 | else if (strcasecmp (token, "BODY") == 0) |
1259 | || strcasecmp (command, "BODYSTRUCTURE") == 0) | ||
1260 | { | 1391 | { |
1261 | if (*sp == '[') | 1392 | if (*sp == '[') |
1262 | status = imap_body (f_imap, &sp); | 1393 | status = imap_body (f_imap, &sp); |
1263 | else | 1394 | else |
1264 | status = imap_bodystructure (f_imap, &sp); | 1395 | status = imap_bodystructure (f_imap, &sp); |
1265 | } | 1396 | } |
1266 | else if (strncmp (command, "INTERNALDATE", 12) == 0) | 1397 | else if (strcasecmp (token, "BODYSTRUCTURE") == 0) |
1398 | { | ||
1399 | status = imap_bodystructure (f_imap, &sp); | ||
1400 | } | ||
1401 | else if (strncmp (token, "INTERNALDATE", 12) == 0) | ||
1267 | { | 1402 | { |
1268 | status = imap_internaldate (f_imap, &sp); | 1403 | status = imap_internaldate (f_imap, &sp); |
1269 | } | 1404 | } |
1270 | else if (strncmp (command, "RFC822", 10) == 0) | 1405 | else if (strncmp (token, "RFC822", 10) == 0) |
1271 | { | 1406 | { |
1272 | if (*sp == '.') | 1407 | if (*sp == '.') |
1273 | { | 1408 | { |
1274 | sp++; | 1409 | sp++; |
1275 | imap_token (command, &sp); | 1410 | imap_token (token, sizeof (token), &sp); |
1276 | if (strcasecmp (command, "SIZE") == 0) | 1411 | if (strcasecmp (token, "SIZE") == 0) |
1412 | { | ||
1413 | status = imap_rfc822_size (f_imap, &sp); | ||
1414 | } | ||
1415 | else if (strcasecmp (token, "TEXT") == 0) | ||
1416 | { | ||
1417 | status = imap_rfc822_text (f_imap, &sp); | ||
1418 | } | ||
1419 | else if (strcasecmp (token, "HEADER") == 0) | ||
1277 | { | 1420 | { |
1278 | imap_token (command, &sp); | 1421 | status = imap_rfc822_header (f_imap, &sp); |
1279 | if (f_imap->callback.msg_imap) | ||
1280 | f_imap->callback.msg_imap->message_size = | ||
1281 | strtoul (command, NULL, 10); | ||
1282 | } | 1422 | } |
1423 | /* else fprintf (stderr, "not supported RFC822 option\n"); */ | ||
1424 | } | ||
1425 | else | ||
1426 | { | ||
1427 | status = imap_rfc822 (f_imap, &sp); | ||
1283 | } | 1428 | } |
1284 | } | 1429 | } |
1285 | else if (strncmp (command, "UID", 3) == 0) | 1430 | else if (strncmp (token, "UID", 3) == 0) |
1286 | { | 1431 | { |
1287 | imap_token (command, &sp); | 1432 | status = imap_uid (f_imap, &sp); |
1288 | if (f_imap->callback.msg_imap) | ||
1289 | f_imap->callback.msg_imap->uid = strtoul (command, NULL, 10); | ||
1290 | } | 1433 | } |
1434 | /* else fprintf (stderr, "not supported FETCH command\n"); */ | ||
1291 | } | 1435 | } |
1292 | return status; | 1436 | return status; |
1293 | } | 1437 | } |
1294 | 1438 | ||
1295 | static int | 1439 | static int |
1296 | imap_token (char *buf, char **ptr) | 1440 | imap_token (char *buf, size_t len, char **ptr) |
1297 | { | 1441 | { |
1298 | char *start = *ptr; | 1442 | char *start = *ptr; |
1443 | size_t i; | ||
1299 | /* Skip leading space. */ | 1444 | /* Skip leading space. */ |
1300 | while (**ptr && **ptr == ' ') | 1445 | while (**ptr && **ptr == ' ') |
1301 | (*ptr)++; | 1446 | (*ptr)++; |
1302 | for (; **ptr; (*ptr)++, buf++) | 1447 | for (i = 1; **ptr && i < len; (*ptr)++, buf++, i++) |
1303 | { | 1448 | { |
1304 | if (**ptr == ' ' || **ptr == '.' | 1449 | if (**ptr == ' ' || **ptr == '.' |
1305 | || **ptr == '(' || **ptr == ')' | 1450 | || **ptr == '(' || **ptr == ')' |
1306 | || **ptr == '[' || **ptr == ']' | 1451 | || **ptr == '[' || **ptr == ']' |
1307 | || **ptr == '<' || **ptr == '>') | 1452 | || **ptr == '<' || **ptr == '>') |
1308 | { | 1453 | { |
1454 | /* Advance. */ | ||
1309 | if (start == (*ptr)) | 1455 | if (start == (*ptr)) |
1310 | (*ptr)++; | 1456 | (*ptr)++; |
1311 | break; | 1457 | break; |
... | @@ -1313,7 +1459,7 @@ imap_token (char *buf, char **ptr) | ... | @@ -1313,7 +1459,7 @@ imap_token (char *buf, char **ptr) |
1313 | *buf = **ptr; | 1459 | *buf = **ptr; |
1314 | } | 1460 | } |
1315 | *buf = '\0'; | 1461 | *buf = '\0'; |
1316 | /* Skip tail space. */ | 1462 | /* Skip trailing space. */ |
1317 | while (**ptr && **ptr == ' ') | 1463 | while (**ptr && **ptr == ' ') |
1318 | (*ptr)++; | 1464 | (*ptr)++; |
1319 | return *ptr - start;; | 1465 | return *ptr - start;; |
... | @@ -1498,8 +1644,10 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1498,8 +1644,10 @@ imap_parse (f_imap_t f_imap) |
1498 | { | 1644 | { |
1499 | break; | 1645 | break; |
1500 | } | 1646 | } |
1647 | #if 0 | ||
1501 | /* Comment out to see all reading traffic. */ | 1648 | /* Comment out to see all reading traffic. */ |
1502 | /* fprintf (stderr, "\t\t%s", f_imap->buffer); */ | 1649 | fprintf (stderr, "\t\t%s", f_imap->buffer); |
1650 | #endif | ||
1503 | 1651 | ||
1504 | /* We do not want to step over f_imap->buffer since it can be use | 1652 | /* We do not want to step over f_imap->buffer since it can be use |
1505 | further down the chain. */ | 1653 | further down the chain. */ | ... | ... |
... | @@ -80,8 +80,7 @@ static int imap_body_fd (stream_t, int *); | ... | @@ -80,8 +80,7 @@ static int imap_body_fd (stream_t, int *); |
80 | /* Private. */ | 80 | /* Private. */ |
81 | static int imap_get_fd (msg_imap_t, int *); | 81 | static int imap_get_fd (msg_imap_t, int *); |
82 | static int imap_get_message0 (msg_imap_t, message_t *); | 82 | static int imap_get_message0 (msg_imap_t, message_t *); |
83 | static int message_operation (f_imap_t, msg_imap_t, enum imap_state, char *, | 83 | static int message_operation (f_imap_t, msg_imap_t, char *, size_t, size_t *); |
84 | size_t, size_t *); | ||
85 | static void free_subparts (msg_imap_t); | 84 | static void free_subparts (msg_imap_t); |
86 | 85 | ||
87 | static const char *MONTHS[] = | 86 | static const char *MONTHS[] = |
... | @@ -687,8 +686,7 @@ imap_message_read (stream_t stream, char *buffer, size_t buflen, | ... | @@ -687,8 +686,7 @@ imap_message_read (stream_t stream, char *buffer, size_t buflen, |
687 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 686 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
688 | f_imap->state = IMAP_FETCH; | 687 | f_imap->state = IMAP_FETCH; |
689 | } | 688 | } |
690 | return message_operation (f_imap, msg_imap, IMAP_MESSAGE, buffer, buflen, | 689 | return message_operation (f_imap, msg_imap, buffer, buflen, plen); |
691 | plen); | ||
692 | } | 690 | } |
693 | 691 | ||
694 | static int | 692 | static int |
... | @@ -708,6 +706,19 @@ imap_message_size (message_t msg, size_t *psize) | ... | @@ -708,6 +706,19 @@ imap_message_size (message_t msg, size_t *psize) |
708 | f_imap_t f_imap = m_imap->f_imap; | 706 | f_imap_t f_imap = m_imap->f_imap; |
709 | int status; | 707 | int status; |
710 | 708 | ||
709 | /* If there is a parent it means it is a sub message, IMAP does not give | ||
710 | the full size of mime messages, so the message_size was retrieve from | ||
711 | doing a bodystructure and represent rather the body_size. */ | ||
712 | if (msg_imap->parent) | ||
713 | { | ||
714 | if (psize) | ||
715 | { | ||
716 | *psize = (msg_imap->message_size + msg_imap->header_size) | ||
717 | - msg_imap->message_lines; | ||
718 | } | ||
719 | return 0; | ||
720 | } | ||
721 | |||
711 | /* Select first. */ | 722 | /* Select first. */ |
712 | if (f_imap->state == IMAP_NO_STATE) | 723 | if (f_imap->state == IMAP_NO_STATE) |
713 | { | 724 | { |
... | @@ -723,7 +734,7 @@ imap_message_size (message_t msg, size_t *psize) | ... | @@ -723,7 +734,7 @@ imap_message_size (message_t msg, size_t *psize) |
723 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 734 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
724 | f_imap->state = IMAP_FETCH; | 735 | f_imap->state = IMAP_FETCH; |
725 | } | 736 | } |
726 | status = message_operation (f_imap, msg_imap, 0, 0, 0, 0); | 737 | status = message_operation (f_imap, msg_imap, 0, 0, 0); |
727 | if (status == 0) | 738 | if (status == 0) |
728 | { | 739 | { |
729 | if (psize) | 740 | if (psize) |
... | @@ -759,7 +770,7 @@ imap_message_uid (message_t msg, size_t *puid) | ... | @@ -759,7 +770,7 @@ imap_message_uid (message_t msg, size_t *puid) |
759 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 770 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
760 | f_imap->state = IMAP_FETCH; | 771 | f_imap->state = IMAP_FETCH; |
761 | } | 772 | } |
762 | status = message_operation (f_imap, msg_imap, 0, 0, 0, 0); | 773 | status = message_operation (f_imap, msg_imap, 0, 0, 0); |
763 | if (status != 0) | 774 | if (status != 0) |
764 | return status; | 775 | return status; |
765 | *puid = msg_imap->uid; | 776 | *puid = msg_imap->uid; |
... | @@ -796,13 +807,13 @@ imap_is_multipart (message_t msg, int *ismulti) | ... | @@ -796,13 +807,13 @@ imap_is_multipart (message_t msg, int *ismulti) |
796 | if (status != 0) | 807 | if (status != 0) |
797 | return status; | 808 | return status; |
798 | status = imap_writeline (f_imap, | 809 | status = imap_writeline (f_imap, |
799 | "g%d FETCH %d BODY\r\n", | 810 | "g%d FETCH %d BODYSTRUCTURE\r\n", |
800 | f_imap->seq++, msg_imap->num); | 811 | f_imap->seq++, msg_imap->num); |
801 | CHECK_ERROR (f_imap, status); | 812 | CHECK_ERROR (f_imap, status); |
802 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 813 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
803 | f_imap->state = IMAP_FETCH; | 814 | f_imap->state = IMAP_FETCH; |
804 | } | 815 | } |
805 | status = message_operation (f_imap, msg_imap, 0, 0, 0, 0); | 816 | status = message_operation (f_imap, msg_imap, 0, 0, 0); |
806 | if (status != 0) | 817 | if (status != 0) |
807 | return status; | 818 | return status; |
808 | if (ismulti) | 819 | if (ismulti) |
... | @@ -833,6 +844,7 @@ imap_get_part (message_t msg, size_t partno, message_t *pmsg) | ... | @@ -833,6 +844,7 @@ imap_get_part (message_t msg, size_t partno, message_t *pmsg) |
833 | { | 844 | { |
834 | msg_imap_t msg_imap = message_get_owner (msg); | 845 | msg_imap_t msg_imap = message_get_owner (msg); |
835 | int status = 0; | 846 | int status = 0; |
847 | |||
836 | if (msg_imap->num_parts == 0) | 848 | if (msg_imap->num_parts == 0) |
837 | { | 849 | { |
838 | status = imap_get_num_parts (msg, NULL); | 850 | status = imap_get_num_parts (msg, NULL); |
... | @@ -856,7 +868,8 @@ imap_get_part (message_t msg, size_t partno, message_t *pmsg) | ... | @@ -856,7 +868,8 @@ imap_get_part (message_t msg, size_t partno, message_t *pmsg) |
856 | header_t header; | 868 | header_t header; |
857 | message_get_header (message, &header); | 869 | message_get_header (message, &header); |
858 | header_set_get_value (header, NULL, message); | 870 | header_set_get_value (header, NULL, message); |
859 | message_set_size (message, NULL, msg_imap->parts[partno - 1]); | 871 | message_set_stream (message, NULL, msg_imap->parts[partno - 1]); |
872 | //message_set_size (message, NULL, msg_imap->parts[partno - 1]); | ||
860 | msg_imap->parts[partno - 1]->message = message; | 873 | msg_imap->parts[partno - 1]->message = message; |
861 | if (pmsg) | 874 | if (pmsg) |
862 | *pmsg = message; | 875 | *pmsg = message; |
... | @@ -880,6 +893,9 @@ imap_envelope_sender (envelope_t envelope, char *buffer, size_t buflen, | ... | @@ -880,6 +893,9 @@ imap_envelope_sender (envelope_t envelope, char *buffer, size_t buflen, |
880 | header_t header; | 893 | header_t header; |
881 | int status; | 894 | int status; |
882 | 895 | ||
896 | if (buflen == 0) | ||
897 | return 0; | ||
898 | |||
883 | message_get_header (msg, &header); | 899 | message_get_header (msg, &header); |
884 | status = imap_header_get_value (header, MU_HEADER_SENDER, buffer, | 900 | status = imap_header_get_value (header, MU_HEADER_SENDER, buffer, |
885 | buflen, plen); | 901 | buflen, plen); |
... | @@ -897,6 +913,12 @@ imap_envelope_sender (envelope_t envelope, char *buffer, size_t buflen, | ... | @@ -897,6 +913,12 @@ imap_envelope_sender (envelope_t envelope, char *buffer, size_t buflen, |
897 | address_destroy (&address); | 913 | address_destroy (&address); |
898 | } | 914 | } |
899 | } | 915 | } |
916 | else if (status != EAGAIN) | ||
917 | { | ||
918 | strncpy (buffer, "Unknown", buflen)[buflen - 1] = '0'; | ||
919 | if (plen) | ||
920 | *plen = strlen (buffer); | ||
921 | } | ||
900 | return status; | 922 | return status; |
901 | } | 923 | } |
902 | 924 | ||
... | @@ -928,7 +950,7 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, | ... | @@ -928,7 +950,7 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, |
928 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 950 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
929 | f_imap->state = IMAP_FETCH; | 951 | f_imap->state = IMAP_FETCH; |
930 | } | 952 | } |
931 | status = message_operation (f_imap, msg_imap, 0, buffer, buflen, plen); | 953 | status = message_operation (f_imap, msg_imap, buffer, buflen, plen); |
932 | if (status != 0) | 954 | if (status != 0) |
933 | return status; | 955 | return status; |
934 | day = mon = year = hour = min = sec = offt = 0; | 956 | day = mon = year = hour = min = sec = offt = 0; |
... | @@ -994,7 +1016,7 @@ imap_attr_get_flags (attribute_t attribute, int *pflags) | ... | @@ -994,7 +1016,7 @@ imap_attr_get_flags (attribute_t attribute, int *pflags) |
994 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 1016 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
995 | f_imap->state = IMAP_FETCH; | 1017 | f_imap->state = IMAP_FETCH; |
996 | } | 1018 | } |
997 | status = message_operation (f_imap, msg_imap, 0, NULL, 0, NULL); | 1019 | status = message_operation (f_imap, msg_imap, NULL, 0, NULL); |
998 | if (status == 0) | 1020 | if (status == 0) |
999 | { | 1021 | { |
1000 | if (pflags) | 1022 | if (pflags) |
... | @@ -1028,7 +1050,7 @@ imap_attr_set_flags (attribute_t attribute, int flags) | ... | @@ -1028,7 +1050,7 @@ imap_attr_set_flags (attribute_t attribute, int flags) |
1028 | msg_imap->flags |= flags; | 1050 | msg_imap->flags |= flags; |
1029 | f_imap->state = IMAP_FETCH; | 1051 | f_imap->state = IMAP_FETCH; |
1030 | } | 1052 | } |
1031 | return message_operation (f_imap, msg_imap, 0, NULL, 0, NULL); | 1053 | return message_operation (f_imap, msg_imap, NULL, 0, NULL); |
1032 | } | 1054 | } |
1033 | 1055 | ||
1034 | static int | 1056 | static int |
... | @@ -1053,7 +1075,7 @@ imap_attr_unset_flags (attribute_t attribute, int flags) | ... | @@ -1053,7 +1075,7 @@ imap_attr_unset_flags (attribute_t attribute, int flags) |
1053 | msg_imap->flags &= ~flags; | 1075 | msg_imap->flags &= ~flags; |
1054 | f_imap->state = IMAP_FETCH; | 1076 | f_imap->state = IMAP_FETCH; |
1055 | } | 1077 | } |
1056 | return message_operation (f_imap, msg_imap, 0, NULL, 0, NULL); | 1078 | return message_operation (f_imap, msg_imap, NULL, 0, NULL); |
1057 | } | 1079 | } |
1058 | 1080 | ||
1059 | /* Header. */ | 1081 | /* Header. */ |
... | @@ -1094,8 +1116,7 @@ imap_header_get_value (header_t header, const char *field, char * buffer, | ... | @@ -1094,8 +1116,7 @@ imap_header_get_value (header_t header, const char *field, char * buffer, |
1094 | f_imap->state = IMAP_FETCH; | 1116 | f_imap->state = IMAP_FETCH; |
1095 | 1117 | ||
1096 | } | 1118 | } |
1097 | status = message_operation (f_imap, msg_imap, IMAP_HEADER_FIELD, value, len, | 1119 | status = message_operation (f_imap, msg_imap, value, len, &len); |
1098 | &len); | ||
1099 | if (status == 0) | 1120 | if (status == 0) |
1100 | { | 1121 | { |
1101 | char *colon; | 1122 | char *colon; |
... | @@ -1173,8 +1194,7 @@ imap_header_read (header_t header, char *buffer, size_t buflen, off_t offset, | ... | @@ -1173,8 +1194,7 @@ imap_header_read (header_t header, char *buffer, size_t buflen, off_t offset, |
1173 | f_imap->state = IMAP_FETCH; | 1194 | f_imap->state = IMAP_FETCH; |
1174 | 1195 | ||
1175 | } | 1196 | } |
1176 | return message_operation (f_imap, msg_imap, IMAP_HEADER, buffer, buflen, | 1197 | return message_operation (f_imap, msg_imap, buffer, buflen, plen); |
1177 | plen); | ||
1178 | } | 1198 | } |
1179 | 1199 | ||
1180 | /* Body. */ | 1200 | /* Body. */ |
... | @@ -1185,13 +1205,23 @@ imap_body_size (body_t body, size_t *psize) | ... | @@ -1185,13 +1205,23 @@ imap_body_size (body_t body, size_t *psize) |
1185 | msg_imap_t msg_imap = message_get_owner (msg); | 1205 | msg_imap_t msg_imap = message_get_owner (msg); |
1186 | if (psize && msg_imap) | 1206 | if (psize && msg_imap) |
1187 | { | 1207 | { |
1188 | if (msg_imap->body_size) | 1208 | /* If there is a parent it means it is a sub message, IMAP does not give |
1189 | *psize = msg_imap->body_size; | 1209 | the full size of mime messages, so the message_size was retrieve from |
1190 | else if (msg_imap->message_size) | 1210 | doing a bodystructure and represents rather the body_size. */ |
1191 | *psize = msg_imap->message_size | 1211 | if (msg_imap->parent) |
1192 | - (msg_imap->header_size + msg_imap->header_lines); | 1212 | { |
1213 | *psize = msg_imap->message_size - msg_imap->message_lines; | ||
1214 | } | ||
1193 | else | 1215 | else |
1194 | *psize = 0; | 1216 | { |
1217 | if (msg_imap->body_size) | ||
1218 | *psize = msg_imap->body_size; | ||
1219 | else if (msg_imap->message_size) | ||
1220 | *psize = msg_imap->message_size | ||
1221 | - (msg_imap->header_size + msg_imap->header_lines); | ||
1222 | else | ||
1223 | *psize = 0; | ||
1224 | } | ||
1195 | } | 1225 | } |
1196 | return 0; | 1226 | return 0; |
1197 | } | 1227 | } |
... | @@ -1266,7 +1296,7 @@ imap_body_read (stream_t stream, char *buffer, size_t buflen, off_t offset, | ... | @@ -1266,7 +1296,7 @@ imap_body_read (stream_t stream, char *buffer, size_t buflen, off_t offset, |
1266 | f_imap->state = IMAP_FETCH; | 1296 | f_imap->state = IMAP_FETCH; |
1267 | 1297 | ||
1268 | } | 1298 | } |
1269 | status = message_operation (f_imap, msg_imap, IMAP_BODY, buffer, buflen, plen); | 1299 | status = message_operation (f_imap, msg_imap, buffer, buflen, plen); |
1270 | if (oldbuf) | 1300 | if (oldbuf) |
1271 | oldbuf[0] = buffer[0]; | 1301 | oldbuf[0] = buffer[0]; |
1272 | return status; | 1302 | return status; |
... | @@ -1294,8 +1324,8 @@ imap_get_fd (msg_imap_t msg_imap, int *pfd) | ... | @@ -1294,8 +1324,8 @@ imap_get_fd (msg_imap_t msg_imap, int *pfd) |
1294 | } | 1324 | } |
1295 | 1325 | ||
1296 | static int | 1326 | static int |
1297 | message_operation (f_imap_t f_imap, msg_imap_t msg_imap, enum imap_state type, | 1327 | message_operation (f_imap_t f_imap, msg_imap_t msg_imap, char *buffer, |
1298 | char *buffer, size_t buflen, size_t *plen) | 1328 | size_t buflen, size_t *plen) |
1299 | { | 1329 | { |
1300 | int status = 0; | 1330 | int status = 0; |
1301 | 1331 | ||
... | @@ -1308,7 +1338,6 @@ message_operation (f_imap_t f_imap, msg_imap_t msg_imap, enum imap_state type, | ... | @@ -1308,7 +1338,6 @@ message_operation (f_imap_t f_imap, msg_imap_t msg_imap, enum imap_state type, |
1308 | f_imap->callback.buffer = buffer; | 1338 | f_imap->callback.buffer = buffer; |
1309 | f_imap->callback.buflen = buflen; | 1339 | f_imap->callback.buflen = buflen; |
1310 | f_imap->callback.total = 0; | 1340 | f_imap->callback.total = 0; |
1311 | f_imap->callback.type = type; | ||
1312 | f_imap->callback.msg_imap = msg_imap; | 1341 | f_imap->callback.msg_imap = msg_imap; |
1313 | f_imap->state = IMAP_FETCH_ACK; | 1342 | f_imap->state = IMAP_FETCH_ACK; |
1314 | 1343 | ... | ... |
... | @@ -107,8 +107,8 @@ struct _mbox_message | ... | @@ -107,8 +107,8 @@ struct _mbox_message |
107 | off_t body_end; | 107 | off_t body_end; |
108 | 108 | ||
109 | /* Fast header retrieve, we save here the most common header. This will | 109 | /* Fast header retrieve, we save here the most common header. This will |
110 | speed the header search. The header are copied when modified by the | 110 | speed the header search. The entire headers are copied when modified |
111 | header_t object, we should not worry about updating them. */ | 111 | by the header_t object, we do not have to worry about updating them. */ |
112 | char *fhdr[HDRSIZE]; | 112 | char *fhdr[HDRSIZE]; |
113 | 113 | ||
114 | /* IMAP uid. */ | 114 | /* IMAP uid. */ |
... | @@ -205,9 +205,10 @@ static int mbox_tmpfile __P ((mailbox_t, char **pbox)); | ... | @@ -205,9 +205,10 @@ static int mbox_tmpfile __P ((mailbox_t, char **pbox)); |
205 | static void mbox_cleanup __P ((void *)); | 205 | static void mbox_cleanup __P ((void *)); |
206 | #endif | 206 | #endif |
207 | 207 | ||
208 | /* We allocate the mbox_data_t struct, but don't do any parsing on the name or | 208 | /* Allocate the mbox_data_t struct(concrete mailbox), but don't do any |
209 | even test for existence. However we do strip any leading "mbox:" part of | 209 | parsing on the name or even test for existence. However we do strip any |
210 | the name, this is suppose to be the protocol/scheme name. */ | 210 | leading "mbox:" part of the name, this is suppose to be the |
211 | protocol/scheme name. */ | ||
211 | int | 212 | int |
212 | _mailbox_mbox_init (mailbox_t mailbox) | 213 | _mailbox_mbox_init (mailbox_t mailbox) |
213 | { | 214 | { |
... | @@ -251,7 +252,7 @@ _mailbox_mbox_init (mailbox_t mailbox) | ... | @@ -251,7 +252,7 @@ _mailbox_mbox_init (mailbox_t mailbox) |
251 | mailbox->_open = mbox_open; | 252 | mailbox->_open = mbox_open; |
252 | mailbox->_close = mbox_close; | 253 | mailbox->_close = mbox_close; |
253 | 254 | ||
254 | /* Messages. */ | 255 | /* Overloading of the entire mailbox object methods. */ |
255 | mailbox->_get_message = mbox_get_message; | 256 | mailbox->_get_message = mbox_get_message; |
256 | mailbox->_append_message = mbox_append_message; | 257 | mailbox->_append_message = mbox_append_message; |
257 | mailbox->_messages_count = mbox_messages_count; | 258 | mailbox->_messages_count = mbox_messages_count; |
... | @@ -270,7 +271,7 @@ _mailbox_mbox_init (mailbox_t mailbox) | ... | @@ -270,7 +271,7 @@ _mailbox_mbox_init (mailbox_t mailbox) |
270 | return 0; /* okdoke */ | 271 | return 0; /* okdoke */ |
271 | } | 272 | } |
272 | 273 | ||
273 | /* Free all ressources associated with Unix mailbox. */ | 274 | /* Free all ressources associated with Unix concrete mailbox. */ |
274 | static void | 275 | static void |
275 | mbox_destroy (mailbox_t mailbox) | 276 | mbox_destroy (mailbox_t mailbox) |
276 | { | 277 | { |
... | @@ -348,6 +349,8 @@ mbox_open (mailbox_t mailbox, int flags) | ... | @@ -348,6 +349,8 @@ mbox_open (mailbox_t mailbox, int flags) |
348 | /* All failed, bail out. */ | 349 | /* All failed, bail out. */ |
349 | if (status != 0) | 350 | if (status != 0) |
350 | return status; | 351 | return status; |
352 | /* Even on top, of normal FILE *, lets agressively cache. But this | ||
353 | may not be suitable for system tight on memory. */ | ||
351 | stream_setbufsiz (mailbox->stream, BUFSIZ); | 354 | stream_setbufsiz (mailbox->stream, BUFSIZ); |
352 | } | 355 | } |
353 | else | 356 | else |
... | @@ -360,6 +363,7 @@ mbox_open (mailbox_t mailbox, int flags) | ... | @@ -360,6 +363,7 @@ mbox_open (mailbox_t mailbox, int flags) |
360 | MAILBOX_DEBUG2 (mailbox, MU_DEBUG_TRACE, "mbox_open(%s, 0x%x)\n", | 363 | MAILBOX_DEBUG2 (mailbox, MU_DEBUG_TRACE, "mbox_open(%s, 0x%x)\n", |
361 | mud->name, mailbox->flags); | 364 | mud->name, mailbox->flags); |
362 | 365 | ||
366 | /* Not of any use to try authenticate for a file mailbox. Do it anyways. */ | ||
363 | if (mailbox->authority) | 367 | if (mailbox->authority) |
364 | { | 368 | { |
365 | status = authority_authenticate (mailbox->authority); | 369 | status = authority_authenticate (mailbox->authority); |
... | @@ -368,6 +372,7 @@ mbox_open (mailbox_t mailbox, int flags) | ... | @@ -368,6 +372,7 @@ mbox_open (mailbox_t mailbox, int flags) |
368 | } | 372 | } |
369 | 373 | ||
370 | /* Give an appropriate way to file lock. */ | 374 | /* Give an appropriate way to file lock. */ |
375 | /* FIXME: use dotlock external program: we may not be setgid. */ | ||
371 | if (mailbox->locker == NULL) | 376 | if (mailbox->locker == NULL) |
372 | locker_create (&(mailbox->locker), mud->name, strlen (mud->name), | 377 | locker_create (&(mailbox->locker), mud->name, strlen (mud->name), |
373 | MU_LOCKER_PID | MU_LOCKER_FCNTL); | 378 | MU_LOCKER_PID | MU_LOCKER_FCNTL); |
... | @@ -385,7 +390,7 @@ mbox_close (mailbox_t mailbox) | ... | @@ -385,7 +390,7 @@ mbox_close (mailbox_t mailbox) |
385 | 390 | ||
386 | MAILBOX_DEBUG1 (mailbox, MU_DEBUG_TRACE, "mbox_close(%s)\n", mud->name); | 391 | MAILBOX_DEBUG1 (mailbox, MU_DEBUG_TRACE, "mbox_close(%s)\n", mud->name); |
387 | 392 | ||
388 | /* Make sure that we do hold any file locking. */ | 393 | /* Make sure that we do not hold any file locking. */ |
389 | locker_unlock (mailbox->locker); | 394 | locker_unlock (mailbox->locker); |
390 | 395 | ||
391 | monitor_wrlock (mailbox->monitor); | 396 | monitor_wrlock (mailbox->monitor); |
... | @@ -418,6 +423,8 @@ mbox_close (mailbox_t mailbox) | ... | @@ -418,6 +423,8 @@ mbox_close (mailbox_t mailbox) |
418 | /* Mailbox Parsing. Routing was way to ugly to put here. */ | 423 | /* Mailbox Parsing. Routing was way to ugly to put here. */ |
419 | #include "mbx_mboxscan.c" | 424 | #include "mbx_mboxscan.c" |
420 | 425 | ||
426 | /* Cover function that call the real thing, mbox_scan(), with | ||
427 | notification set. */ | ||
421 | static int | 428 | static int |
422 | mbox_scan (mailbox_t mailbox, size_t msgno, size_t *pcount) | 429 | mbox_scan (mailbox_t mailbox, size_t msgno, size_t *pcount) |
423 | { | 430 | { |
... | @@ -427,9 +434,10 @@ mbox_scan (mailbox_t mailbox, size_t msgno, size_t *pcount) | ... | @@ -427,9 +434,10 @@ mbox_scan (mailbox_t mailbox, size_t msgno, size_t *pcount) |
427 | } | 434 | } |
428 | 435 | ||
429 | /* FIXME: How to handle a shrink ? meaning, the &^$^@%#@^& user start two | 436 | /* FIXME: How to handle a shrink ? meaning, the &^$^@%#@^& user start two |
430 | browsers and deleted emails in one. My views is that we should scream | 437 | browsers and deleted emails in one session. My views is that we should |
431 | bloody murder and hunt them with a machette. But for now just play dumb, | 438 | scream bloody murder and hunt them with a machette. But for now just play |
432 | but maybe the best approach is to pack our things and leave .i.e exit(). */ | 439 | dumb, but maybe the best approach is to pack our things and leave |
440 | .i.e exit()/abort(). */ | ||
433 | static int | 441 | static int |
434 | mbox_is_updated (mailbox_t mailbox) | 442 | mbox_is_updated (mailbox_t mailbox) |
435 | { | 443 | { |
... | @@ -440,15 +448,15 @@ mbox_is_updated (mailbox_t mailbox) | ... | @@ -440,15 +448,15 @@ mbox_is_updated (mailbox_t mailbox) |
440 | if (size < mud->size) | 448 | if (size < mud->size) |
441 | { | 449 | { |
442 | observable_notify (mailbox->observable, MU_EVT_MAILBOX_CORRUPT); | 450 | observable_notify (mailbox->observable, MU_EVT_MAILBOX_CORRUPT); |
443 | /* And be verbose. */ | 451 | /* And be verbose. ? */ |
444 | fprintf (stderr, "Mailbox corrupted, shrank size\n"); | 452 | fprintf (stderr, "* BAD : Mailbox corrupted, shrank size\n"); |
445 | /* FIXME: I should crash. */ | 453 | /* FIXME: should I crash. */ |
446 | return 1; | 454 | return 1; |
447 | } | 455 | } |
448 | return (mud->size == size); | 456 | return (mud->size == size); |
449 | } | 457 | } |
450 | 458 | ||
451 | /* Try to create an uniq file. */ | 459 | /* Try to create an uniq file, we no race conditions. */ |
452 | static int | 460 | static int |
453 | mbox_tmpfile (mailbox_t mailbox, char **pbox) | 461 | mbox_tmpfile (mailbox_t mailbox, char **pbox) |
454 | { | 462 | { |
... | @@ -457,7 +465,7 @@ mbox_tmpfile (mailbox_t mailbox, char **pbox) | ... | @@ -457,7 +465,7 @@ mbox_tmpfile (mailbox_t mailbox, char **pbox) |
457 | const char *basename; | 465 | const char *basename; |
458 | mbox_data_t mud = mailbox->data; | 466 | mbox_data_t mud = mailbox->data; |
459 | 467 | ||
460 | /* P_tmpdir should be define in <stdio.h>. */ | 468 | /* P_tmpdir should be in <stdio.h>. */ |
461 | #ifndef P_tmpdir | 469 | #ifndef P_tmpdir |
462 | # define P_tmpdir "/tmp" | 470 | # define P_tmpdir "/tmp" |
463 | #endif | 471 | #endif | ... | ... |
-
Please register or sign in to post a comment