* mailbox/message.c (message_get_uid) : Add message_get_uid() for
the UID of the message (IMAP definition) and message_get_uidl() for the POP3 definition. * mailbox/attachment.c : Indentation fixes. * mailbox/file_stream.c : Make sure that the FILE* is close before opening. * mailbox/folder_imap.c : Use strcasecmp() not strcmp(). * mailbox/mailbox.c : Added mailbox_uidnext() and mailbox_uidvalidity. * mailbox/mapfile_stream.c : When munmap() failed we should check against MAP_FAILED, not NULL. * mailbox/mbx_imap.c : Implement imap_uidnext(), imap_uidvalidity() imap_message_uid(). * mailbox/mbx_mbox.c : Implement mbox_uidnext(), mbox_uidvalidity() mbox_message_uid(). * mailbox/mbx_mboxscan.c : Implement uidvalidity, it is save int the header of the first message, "X-IMAPbase: 127673838 123", a la c-client. Save UID, it is save in "X-UID". * mailbox/mbx_pop.c : Implement pop_messages_recent(), pop_message_unseen() and pop_uid(). * mailbox/trans_stream.c : Indentation fixes.
Showing
14 changed files
with
441 additions
and
191 deletions
... | @@ -31,6 +31,9 @@ | ... | @@ -31,6 +31,9 @@ |
31 | #define MAX_HDR_LEN 256 | 31 | #define MAX_HDR_LEN 256 |
32 | #define BUF_SIZE 2048 | 32 | #define BUF_SIZE 2048 |
33 | 33 | ||
34 | /* FIXME: this should be in a public header. */ | ||
35 | extern int message_attachment_filename __P ((message_t, const char **filename)); | ||
36 | |||
34 | struct _msg_info { | 37 | struct _msg_info { |
35 | char *buf; | 38 | char *buf; |
36 | size_t nbytes; | 39 | size_t nbytes; |
... | @@ -174,7 +177,7 @@ static char *_header_get_param(char *field_body, const char *param, size_t *len) | ... | @@ -174,7 +177,7 @@ static char *_header_get_param(char *field_body, const char *param, size_t *len) |
174 | return NULL; | 177 | return NULL; |
175 | } | 178 | } |
176 | 179 | ||
177 | int message_attachment_filename(message_t msg, char **filename) | 180 | int message_attachment_filename(message_t msg, const char **filename) |
178 | { | 181 | { |
179 | char *pTmp, *fname = NULL; | 182 | char *pTmp, *fname = NULL; |
180 | header_t hdr; | 183 | header_t hdr; |
... | @@ -219,7 +222,8 @@ int message_save_attachment(message_t msg, const char *filename, void **data) | ... | @@ -219,7 +222,8 @@ int message_save_attachment(message_t msg, const char *filename, void **data) |
219 | size_t size; | 222 | size_t size; |
220 | size_t nbytes; | 223 | size_t nbytes; |
221 | header_t hdr; | 224 | header_t hdr; |
222 | const char *content_encoding, *fname = NULL; | 225 | char *content_encoding; |
226 | const char *fname = NULL; | ||
223 | 227 | ||
224 | if ( msg == NULL || filename == NULL) | 228 | if ( msg == NULL || filename == NULL) |
225 | return EINVAL; | 229 | return EINVAL; |
... | @@ -240,7 +244,7 @@ int message_save_attachment(message_t msg, const char *filename, void **data) | ... | @@ -240,7 +244,7 @@ int message_save_attachment(message_t msg, const char *filename, void **data) |
240 | ret = ENOMEM; | 244 | ret = ENOMEM; |
241 | header_get_value(hdr, "Content-Transfer-Encoding", content_encoding, size+1, 0); | 245 | header_get_value(hdr, "Content-Transfer-Encoding", content_encoding, size+1, 0); |
242 | } else | 246 | } else |
243 | content_encoding = "7bit"; | 247 | content_encoding = (char *)"7bit"; |
244 | ret = decoder_stream_create(&info->ostream, fstream, content_encoding); | 248 | ret = decoder_stream_create(&info->ostream, fstream, content_encoding); |
245 | } | 249 | } |
246 | } | 250 | } | ... | ... |
... | @@ -227,6 +227,12 @@ _file_open (stream_t stream, const char *filename, int port, int flags) | ... | @@ -227,6 +227,12 @@ _file_open (stream_t stream, const char *filename, int port, int flags) |
227 | if (fs == NULL) | 227 | if (fs == NULL) |
228 | return EINVAL; | 228 | return EINVAL; |
229 | 229 | ||
230 | if (fs->file) | ||
231 | { | ||
232 | fclose (fs->file); | ||
233 | fs->file = NULL; | ||
234 | } | ||
235 | |||
230 | /* Map the flags to the system equivalent. */ | 236 | /* Map the flags to the system equivalent. */ |
231 | if (flags & MU_STREAM_WRITE) | 237 | if (flags & MU_STREAM_WRITE) |
232 | flg = O_WRONLY; | 238 | flg = O_WRONLY; | ... | ... |
... | @@ -1155,35 +1155,35 @@ imap_flags (f_imap_t f_imap) | ... | @@ -1155,35 +1155,35 @@ imap_flags (f_imap_t f_imap) |
1155 | msg_imap_t msg_imap = f_imap->callback.msg_imap; | 1155 | msg_imap_t msg_imap = f_imap->callback.msg_imap; |
1156 | while ((flag = strtok_r (flags, " ()", &sp)) != NULL) | 1156 | while ((flag = strtok_r (flags, " ()", &sp)) != NULL) |
1157 | { | 1157 | { |
1158 | if (strcmp (flag, "\\Seen") == 0) | 1158 | if (strcasecmp (flag, "\\Seen") == 0) |
1159 | { | 1159 | { |
1160 | if (msg_imap) | 1160 | if (msg_imap) |
1161 | msg_imap->flags |= MU_ATTRIBUTE_SEEN; | 1161 | msg_imap->flags |= MU_ATTRIBUTE_SEEN; |
1162 | else | 1162 | else |
1163 | f_imap->flags |= MU_ATTRIBUTE_SEEN; | 1163 | f_imap->flags |= MU_ATTRIBUTE_SEEN; |
1164 | } | 1164 | } |
1165 | else if (strcmp (flag, "\\Answered") == 0) | 1165 | else if (strcasecmp (flag, "\\Answered") == 0) |
1166 | { | 1166 | { |
1167 | if (msg_imap) | 1167 | if (msg_imap) |
1168 | msg_imap->flags |= MU_ATTRIBUTE_ANSWERED; | 1168 | msg_imap->flags |= MU_ATTRIBUTE_ANSWERED; |
1169 | else | 1169 | else |
1170 | f_imap->flags |= MU_ATTRIBUTE_ANSWERED; | 1170 | f_imap->flags |= MU_ATTRIBUTE_ANSWERED; |
1171 | } | 1171 | } |
1172 | else if (strcmp (flag, "\\Flagged") == 0) | 1172 | else if (strcasecmp (flag, "\\Flagged") == 0) |
1173 | { | 1173 | { |
1174 | if (msg_imap) | 1174 | if (msg_imap) |
1175 | msg_imap->flags |= MU_ATTRIBUTE_FLAGGED; | 1175 | msg_imap->flags |= MU_ATTRIBUTE_FLAGGED; |
1176 | else | 1176 | else |
1177 | f_imap->flags |= MU_ATTRIBUTE_FLAGGED; | 1177 | f_imap->flags |= MU_ATTRIBUTE_FLAGGED; |
1178 | } | 1178 | } |
1179 | else if (strcmp (flag, "\\Deleted") == 0) | 1179 | else if (strcasecmp (flag, "\\Deleted") == 0) |
1180 | { | 1180 | { |
1181 | if (msg_imap) | 1181 | if (msg_imap) |
1182 | msg_imap->flags |= MU_ATTRIBUTE_DELETED; | 1182 | msg_imap->flags |= MU_ATTRIBUTE_DELETED; |
1183 | else | 1183 | else |
1184 | f_imap->flags |= MU_ATTRIBUTE_DELETED; | 1184 | f_imap->flags |= MU_ATTRIBUTE_DELETED; |
1185 | } | 1185 | } |
1186 | else if (strcmp (flag, "\\Draft") == 0) | 1186 | else if (strcasecmp (flag, "\\Draft") == 0) |
1187 | { | 1187 | { |
1188 | if (msg_imap) | 1188 | if (msg_imap) |
1189 | msg_imap->flags |= MU_ATTRIBUTE_DRAFT; | 1189 | msg_imap->flags |= MU_ATTRIBUTE_DRAFT; |
... | @@ -1256,8 +1256,7 @@ imap_fetch (f_imap_t f_imap) | ... | @@ -1256,8 +1256,7 @@ imap_fetch (f_imap_t f_imap) |
1256 | { | 1256 | { |
1257 | status = imap_flags (f_imap); | 1257 | status = imap_flags (f_imap); |
1258 | } | 1258 | } |
1259 | /* This the short form for BODYSTRUCTURE. */ | 1259 | else if (strcasecmp (command, "BODY") == 0) |
1260 | else if (strcmp (command, "BODY") == 0) | ||
1261 | { | 1260 | { |
1262 | status = imap_bodystructure (f_imap); | 1261 | status = imap_bodystructure (f_imap); |
1263 | } | 1262 | } |
... | @@ -1269,12 +1268,18 @@ imap_fetch (f_imap_t f_imap) | ... | @@ -1269,12 +1268,18 @@ imap_fetch (f_imap_t f_imap) |
1269 | { | 1268 | { |
1270 | command = strtok_r (NULL, " ()\n", &sp); | 1269 | command = strtok_r (NULL, " ()\n", &sp); |
1271 | if (f_imap->callback.msg_imap) | 1270 | if (f_imap->callback.msg_imap) |
1272 | f_imap->callback.msg_imap->message_size = strtol (command, NULL, 10); | 1271 | f_imap->callback.msg_imap->message_size = strtoul (command, NULL, 10); |
1273 | } | 1272 | } |
1274 | else if (strncmp (command, "BODY", 4) == 0) | 1273 | else if (strncmp (command, "BODY", 4) == 0) |
1275 | { | 1274 | { |
1276 | status = imap_string (f_imap); | 1275 | status = imap_string (f_imap); |
1277 | } | 1276 | } |
1277 | else if (strncmp (command, "UID", 3) == 0) | ||
1278 | { | ||
1279 | command = strtok_r (NULL, " ()\n", &sp); | ||
1280 | if (f_imap->callback.msg_imap) | ||
1281 | f_imap->callback.msg_imap->uid = strtoul (command, NULL, 10); | ||
1282 | } | ||
1278 | return status; | 1283 | return status; |
1279 | } | 1284 | } |
1280 | 1285 | ||
... | @@ -1483,7 +1488,7 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1483,7 +1488,7 @@ imap_parse (f_imap_t f_imap) |
1483 | { | 1488 | { |
1484 | 1489 | ||
1485 | /* Is it a Status Response. */ | 1490 | /* Is it a Status Response. */ |
1486 | if (strcmp (response, "OK") == 0) | 1491 | if (strcasecmp (response, "OK") == 0) |
1487 | { | 1492 | { |
1488 | /* Check for status response [code]. */ | 1493 | /* Check for status response [code]. */ |
1489 | if (*remainder == '[') | 1494 | if (*remainder == '[') |
... | @@ -1496,13 +1501,14 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1496,13 +1501,14 @@ imap_parse (f_imap_t f_imap) |
1496 | subtag = strtok_r (cruft, " ", &sp); | 1501 | subtag = strtok_r (cruft, " ", &sp); |
1497 | if (!subtag) subtag = empty; | 1502 | if (!subtag) subtag = empty; |
1498 | 1503 | ||
1499 | if (strcmp (subtag, "ALERT") == 0) | 1504 | if (strcasecmp (subtag, "ALERT") == 0) |
1500 | { | 1505 | { |
1501 | /* The human-readable text contains a special alert that | 1506 | /* The human-readable text contains a special alert that |
1502 | MUST be presented to the user in a fashion that calls | 1507 | MUST be presented to the user in a fashion that calls |
1503 | the user's attention to the message. */ | 1508 | the user's attention to the message. */ |
1509 | fprintf (stderr, "ALERT: %s\n", (sp) ? sp : ""); | ||
1504 | } | 1510 | } |
1505 | else if (strcmp (subtag, "BADCHARSET") == 0) | 1511 | else if (strcasecmp (subtag, "BADCHARSET") == 0) |
1506 | { | 1512 | { |
1507 | /* Optionally followed by a parenthesized list of | 1513 | /* Optionally followed by a parenthesized list of |
1508 | charsets. A SEARCH failed because the given charset | 1514 | charsets. A SEARCH failed because the given charset |
... | @@ -1510,7 +1516,7 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1510,7 +1516,7 @@ imap_parse (f_imap_t f_imap) |
1510 | optional list of charsets is given, this lists the | 1516 | optional list of charsets is given, this lists the |
1511 | charsets that are supported by this implementation. */ | 1517 | charsets that are supported by this implementation. */ |
1512 | } | 1518 | } |
1513 | else if (strcmp (subtag, "CAPABILITY") == 0) | 1519 | else if (strcasecmp (subtag, "CAPABILITY") == 0) |
1514 | { | 1520 | { |
1515 | /* Followed by a list of capabilities. This can appear | 1521 | /* Followed by a list of capabilities. This can appear |
1516 | in the initial OK or PREAUTH response to transmit an | 1522 | in the initial OK or PREAUTH response to transmit an |
... | @@ -1521,7 +1527,7 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1521,7 +1527,7 @@ imap_parse (f_imap_t f_imap) |
1521 | free (f_imap->capa); | 1527 | free (f_imap->capa); |
1522 | f_imap->capa = strdup (cruft); | 1528 | f_imap->capa = strdup (cruft); |
1523 | } | 1529 | } |
1524 | else if (strcmp (subtag, "NEWNAME") == 0) | 1530 | else if (strcasecmp (subtag, "NEWNAME") == 0) |
1525 | { | 1531 | { |
1526 | /* Followed by a mailbox name and a new mailbox name. A | 1532 | /* Followed by a mailbox name and a new mailbox name. A |
1527 | SELECT or EXAMINE failed because the target mailbox | 1533 | SELECT or EXAMINE failed because the target mailbox |
... | @@ -1530,13 +1536,13 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1530,13 +1536,13 @@ imap_parse (f_imap_t f_imap) |
1530 | operation can succeed if the SELECT or EXAMINE is | 1536 | operation can succeed if the SELECT or EXAMINE is |
1531 | reissued with the new mailbox name. */ | 1537 | reissued with the new mailbox name. */ |
1532 | } | 1538 | } |
1533 | else if (strcmp (subtag, "PARSE") == 0) | 1539 | else if (strcasecmp (subtag, "PARSE") == 0) |
1534 | { | 1540 | { |
1535 | /* The human-readable text represents an error in | 1541 | /* The human-readable text represents an error in |
1536 | parsing the [RFC-822] header or [MIME-IMB] headers | 1542 | parsing the [RFC-822] header or [MIME-IMB] headers |
1537 | of a message in the mailbox. */ | 1543 | of a message in the mailbox. */ |
1538 | } | 1544 | } |
1539 | else if (strcmp (subtag, "PERMANENTFLAGS") == 0) | 1545 | else if (strcasecmp (subtag, "PERMANENTFLAGS") == 0) |
1540 | { | 1546 | { |
1541 | /* Followed by a parenthesized list of flags, indicates | 1547 | /* Followed by a parenthesized list of flags, indicates |
1542 | which of the known flags that the client can change | 1548 | which of the known flags that the client can change |
... | @@ -1551,19 +1557,19 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1551,19 +1557,19 @@ imap_parse (f_imap_t f_imap) |
1551 | that it is possible to create new keywords by | 1557 | that it is possible to create new keywords by |
1552 | attempting to store those flags in the mailbox. */ | 1558 | attempting to store those flags in the mailbox. */ |
1553 | } | 1559 | } |
1554 | else if (strcmp (subtag, "READ-ONLY") == 0) | 1560 | else if (strcasecmp (subtag, "READ-ONLY") == 0) |
1555 | { | 1561 | { |
1556 | /* The mailbox is selected read-only, or its access | 1562 | /* The mailbox is selected read-only, or its access |
1557 | while selected has changed from read-write to | 1563 | while selected has changed from read-write to |
1558 | read-only. */ | 1564 | read-only. */ |
1559 | } | 1565 | } |
1560 | else if (strcmp (subtag, "READ-WRITE") == 0) | 1566 | else if (strcasecmp (subtag, "READ-WRITE") == 0) |
1561 | { | 1567 | { |
1562 | /* The mailbox is selected read-write, or its access | 1568 | /* The mailbox is selected read-write, or its access |
1563 | while selected has changed from read-only to | 1569 | while selected has changed from read-only to |
1564 | read-write. */ | 1570 | read-write. */ |
1565 | } | 1571 | } |
1566 | else if (strcmp (subtag, "TRYCREATE") == 0) | 1572 | else if (strcasecmp (subtag, "TRYCREATE") == 0) |
1567 | { | 1573 | { |
1568 | /* An APPEND or COPY attempt is failing because the | 1574 | /* An APPEND or COPY attempt is failing because the |
1569 | target mailbox does not exist (as opposed to some | 1575 | target mailbox does not exist (as opposed to some |
... | @@ -1571,13 +1577,15 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1571,13 +1577,15 @@ imap_parse (f_imap_t f_imap) |
1571 | the operation can succeed if the mailbox is first | 1577 | the operation can succeed if the mailbox is first |
1572 | created by the CREATE command. */ | 1578 | created by the CREATE command. */ |
1573 | } | 1579 | } |
1574 | else if (strcmp (subtag, "UIDNEXT") == 0) | 1580 | else if (strcasecmp (subtag, "UIDNEXT") == 0) |
1575 | { | 1581 | { |
1576 | /* Followed by a decimal number, indicates the next | 1582 | /* Followed by a decimal number, indicates the next |
1577 | unique identifier value. Refer to section 2.3.1.1 | 1583 | unique identifier value. Refer to section 2.3.1.1 |
1578 | for more information. */ | 1584 | for more information. */ |
1585 | char *value = strtok_r (NULL, " ", &sp); | ||
1586 | f_imap->selected->uidnext = strtol (value, NULL, 10); | ||
1579 | } | 1587 | } |
1580 | else if (strcmp (subtag, "UIDVALIDITY") == 0) | 1588 | else if (strcasecmp (subtag, "UIDVALIDITY") == 0) |
1581 | { | 1589 | { |
1582 | /* Followed by a decimal number, indicates the unique | 1590 | /* Followed by a decimal number, indicates the unique |
1583 | identifier validity value. Refer to section 2.3.1.1 | 1591 | identifier validity value. Refer to section 2.3.1.1 |
... | @@ -1585,7 +1593,7 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1585,7 +1593,7 @@ imap_parse (f_imap_t f_imap) |
1585 | char *value = strtok_r (NULL, " ", &sp); | 1593 | char *value = strtok_r (NULL, " ", &sp); |
1586 | f_imap->selected->uidvalidity = strtol (value, NULL, 10); | 1594 | f_imap->selected->uidvalidity = strtol (value, NULL, 10); |
1587 | } | 1595 | } |
1588 | else if (strcmp (subtag, "UNSEEN") == 0) | 1596 | else if (strcasecmp (subtag, "UNSEEN") == 0) |
1589 | { | 1597 | { |
1590 | /* Followed by a decimal number, indicates the number of | 1598 | /* Followed by a decimal number, indicates the number of |
1591 | the first message without the \Seen flag set. */ | 1599 | the first message without the \Seen flag set. */ |
... | @@ -1608,66 +1616,66 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1608,66 +1616,66 @@ imap_parse (f_imap_t f_imap) |
1608 | printf("Untagged OK: %s\n", remainder); | 1616 | printf("Untagged OK: %s\n", remainder); |
1609 | } | 1617 | } |
1610 | } | 1618 | } |
1611 | else if (strcmp (response, "NO") == 0) | 1619 | else if (strcasecmp (response, "NO") == 0) |
1612 | { | 1620 | { |
1613 | /* This does not mean failure but rather a strong warning. */ | 1621 | /* This does not mean failure but rather a strong warning. */ |
1614 | printf ("Untagged NO: %s\n", remainder); | 1622 | printf ("Untagged NO: %s\n", remainder); |
1615 | } | 1623 | } |
1616 | else if (strcmp (response, "BAD") == 0) | 1624 | else if (strcasecmp (response, "BAD") == 0) |
1617 | { | 1625 | { |
1618 | /* We're dead, protocol/syntax error. */ | 1626 | /* We're dead, protocol/syntax error. */ |
1619 | printf ("Untagged BAD: %s\n", remainder); | 1627 | printf ("Untagged BAD: %s\n", remainder); |
1620 | } | 1628 | } |
1621 | else if (strcmp (response, "PREAUTH") == 0) | 1629 | else if (strcasecmp (response, "PREAUTH") == 0) |
1622 | { | 1630 | { |
1623 | } | 1631 | } |
1624 | else if (strcmp (response, "BYE") == 0) | 1632 | else if (strcasecmp (response, "BYE") == 0) |
1625 | { | 1633 | { |
1626 | /* We should close the stream. This is not recoverable. */ | 1634 | /* We should close the stream. This is not recoverable. */ |
1627 | done = 1; | 1635 | done = 1; |
1628 | f_imap->isopen = 0; | 1636 | f_imap->isopen = 0; |
1629 | stream_close (f_imap->folder->stream); | 1637 | stream_close (f_imap->folder->stream); |
1630 | } | 1638 | } |
1631 | else if (strcmp (response, "CAPABILITY") == 0) | 1639 | else if (strcasecmp (response, "CAPABILITY") == 0) |
1632 | { | 1640 | { |
1633 | if (f_imap->capa) | 1641 | if (f_imap->capa) |
1634 | free (f_imap->capa); | 1642 | free (f_imap->capa); |
1635 | f_imap->capa = strdup (remainder); | 1643 | f_imap->capa = strdup (remainder); |
1636 | } | 1644 | } |
1637 | else if (strcmp (remainder, "EXISTS") == 0) | 1645 | else if (strcasecmp (remainder, "EXISTS") == 0) |
1638 | { | 1646 | { |
1639 | f_imap->selected->messages_count = strtol (response, NULL, 10); | 1647 | f_imap->selected->messages_count = strtol (response, NULL, 10); |
1640 | } | 1648 | } |
1641 | else if (strcmp (remainder, "EXPUNGE") == 0) | 1649 | else if (strcasecmp (remainder, "EXPUNGE") == 0) |
1642 | { | 1650 | { |
1643 | } | 1651 | } |
1644 | else if (strncmp (remainder, "FETCH", 5) == 0) | 1652 | else if (strncasecmp (remainder, "FETCH", 5) == 0) |
1645 | { | 1653 | { |
1646 | status = imap_fetch (f_imap); | 1654 | status = imap_fetch (f_imap); |
1647 | if (status != 0) | 1655 | if (status != 0) |
1648 | break; | 1656 | break; |
1649 | } | 1657 | } |
1650 | else if (strcmp (response, "FLAGS") == 0) | 1658 | else if (strcasecmp (response, "FLAGS") == 0) |
1651 | { | 1659 | { |
1652 | /* Flags define on the mailbox not a message flags. */ | 1660 | /* Flags define on the mailbox not a message flags. */ |
1653 | status = imap_flags (f_imap); | 1661 | status = imap_flags (f_imap); |
1654 | } | 1662 | } |
1655 | else if (strcmp (response, "LIST") == 0) | 1663 | else if (strcasecmp (response, "LIST") == 0) |
1656 | { | 1664 | { |
1657 | status = imap_list (f_imap); | 1665 | status = imap_list (f_imap); |
1658 | } | 1666 | } |
1659 | else if (strcmp (response, "LSUB") == 0) | 1667 | else if (strcasecmp (response, "LSUB") == 0) |
1660 | { | 1668 | { |
1661 | status = imap_list (f_imap); | 1669 | status = imap_list (f_imap); |
1662 | } | 1670 | } |
1663 | else if (strcmp (remainder, "RECENT") == 0) | 1671 | else if (strcasecmp (remainder, "RECENT") == 0) |
1664 | { | 1672 | { |
1665 | f_imap->selected->recent = strtol (response, NULL, 10); | 1673 | f_imap->selected->recent = strtol (response, NULL, 10); |
1666 | } | 1674 | } |
1667 | else if (strcmp (response, "SEARCH") == 0) | 1675 | else if (strcasecmp (response, "SEARCH") == 0) |
1668 | { | 1676 | { |
1669 | } | 1677 | } |
1670 | else if (strcmp (response, "STATUS") == 0) | 1678 | else if (strcasecmp (response, "STATUS") == 0) |
1671 | { | 1679 | { |
1672 | } | 1680 | } |
1673 | else | 1681 | else |
... | @@ -1686,12 +1694,12 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1686,12 +1694,12 @@ imap_parse (f_imap_t f_imap) |
1686 | { | 1694 | { |
1687 | /* Every transaction ends with a tagged response. */ | 1695 | /* Every transaction ends with a tagged response. */ |
1688 | done = 1; | 1696 | done = 1; |
1689 | if (strcmp (response, "OK") == 0) | 1697 | if (strcasecmp (response, "OK") == 0) |
1690 | { | 1698 | { |
1691 | } | 1699 | } |
1692 | else /* NO and BAD */ | 1700 | else /* NO and BAD */ |
1693 | { | 1701 | { |
1694 | if (strncmp (remainder, "LOGIN", 5) == 0) | 1702 | if (strncasecmp (remainder, "LOGIN", 5) == 0) |
1695 | { | 1703 | { |
1696 | observable_t observable = NULL; | 1704 | observable_t observable = NULL; |
1697 | folder_get_observable (f_imap->folder, &observable); | 1705 | folder_get_observable (f_imap->folder, &observable); | ... | ... |
... | @@ -166,7 +166,8 @@ struct _m_imap | ... | @@ -166,7 +166,8 @@ struct _m_imap |
166 | msg_imap_t *imessages; | 166 | msg_imap_t *imessages; |
167 | size_t recent; | 167 | size_t recent; |
168 | size_t unseen; | 168 | size_t unseen; |
169 | size_t uidvalidity; | 169 | unsigned long uidvalidity; |
170 | size_t uidnext; | ||
170 | char *name; | 171 | char *name; |
171 | }; | 172 | }; |
172 | 173 | ||
... | @@ -181,7 +182,7 @@ struct _msg_imap | ... | @@ -181,7 +182,7 @@ struct _msg_imap |
181 | msg_imap_t *parts; | 182 | msg_imap_t *parts; |
182 | msg_imap_t parent; | 183 | msg_imap_t parent; |
183 | int flags; | 184 | int flags; |
184 | char *uid; | 185 | size_t uid; |
185 | 186 | ||
186 | size_t message_size; | 187 | size_t message_size; |
187 | size_t message_lines; | 188 | size_t message_lines; | ... | ... |
... | @@ -69,8 +69,11 @@ struct _mailbox | ... | @@ -69,8 +69,11 @@ struct _mailbox |
69 | int (*_get_message) __P ((mailbox_t, size_t msgno, message_t *msg)); | 69 | int (*_get_message) __P ((mailbox_t, size_t msgno, message_t *msg)); |
70 | int (*_append_message) __P ((mailbox_t, message_t msg)); | 70 | int (*_append_message) __P ((mailbox_t, message_t msg)); |
71 | int (*_messages_count) __P ((mailbox_t, size_t *num)); | 71 | int (*_messages_count) __P ((mailbox_t, size_t *num)); |
72 | int (*_unseen_count) __P ((mailbox_t, size_t *num)); | 72 | int (*_messages_recent) __P ((mailbox_t, size_t *num)); |
73 | int (*_message_unseen) __P ((mailbox_t, size_t *num)); | ||
73 | int (*_expunge) __P ((mailbox_t)); | 74 | int (*_expunge) __P ((mailbox_t)); |
75 | int (*_uidvalidity) __P ((mailbox_t, unsigned long *num)); | ||
76 | int (*_uidnext) __P ((mailbox_t, size_t *num)); | ||
74 | 77 | ||
75 | int (*_scan) __P ((mailbox_t, size_t msgno, size_t *count)); | 78 | int (*_scan) __P ((mailbox_t, size_t msgno, size_t *count)); |
76 | int (*_is_updated) __P ((mailbox_t)); | 79 | int (*_is_updated) __P ((mailbox_t)); | ... | ... |
1 | /* GNU mailutils - a suite of utilities for electronic mail | 1 | /* GNU mailutils - a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This program is free software; you can redistribute it and/or modify | 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 | 5 | it under the terms of the GNU General Library Public License as published by |
... | @@ -65,7 +65,8 @@ struct _message | ... | @@ -65,7 +65,8 @@ struct _message |
65 | size_t hdr_buflen; | 65 | size_t hdr_buflen; |
66 | int hdr_done; | 66 | int hdr_done; |
67 | 67 | ||
68 | int (*_get_uid) __P ((message_t, char *, size_t, size_t *)); | 68 | int (*_get_uidl) __P ((message_t, char *, size_t, size_t *)); |
69 | int (*_get_uid) __P ((message_t, size_t *)); | ||
69 | int (*_get_num_parts) __P ((message_t, size_t *)); | 70 | int (*_get_num_parts) __P ((message_t, size_t *)); |
70 | int (*_get_part) __P ((message_t, size_t, message_t *)); | 71 | int (*_get_part) __P ((message_t, size_t, message_t *)); |
71 | int (*_is_multipart) __P ((message_t, int *)); | 72 | int (*_is_multipart) __P ((message_t, int *)); | ... | ... |
... | @@ -220,11 +220,18 @@ mailbox_messages_count (mailbox_t mbox, size_t *num) | ... | @@ -220,11 +220,18 @@ mailbox_messages_count (mailbox_t mbox, size_t *num) |
220 | } | 220 | } |
221 | 221 | ||
222 | int | 222 | int |
223 | mailbox_unseen_count (mailbox_t mbox, size_t *num) | 223 | mailbox_messages_recent (mailbox_t mbox, size_t *num) |
224 | { | 224 | { |
225 | if (mbox && mbox->_unseen_count) | 225 | if (mbox == NULL || mbox->_messages_recent == NULL) |
226 | return mbox->_unseen_count (mbox, num); | 226 | return ENOSYS; |
227 | return mailbox_messages_count (mbox, num); | 227 | return mbox->_messages_recent (mbox, num); |
228 | } | ||
229 | int | ||
230 | mailbox_message_unseen (mailbox_t mbox, size_t *num) | ||
231 | { | ||
232 | if (mbox == NULL || mbox->_message_unseen == NULL) | ||
233 | return ENOSYS; | ||
234 | return mbox->_message_unseen (mbox, num); | ||
228 | } | 235 | } |
229 | 236 | ||
230 | int | 237 | int |
... | @@ -259,6 +266,22 @@ mailbox_size (mailbox_t mbox, off_t *psize) | ... | @@ -259,6 +266,22 @@ mailbox_size (mailbox_t mbox, off_t *psize) |
259 | return mbox->_size (mbox, psize); | 266 | return mbox->_size (mbox, psize); |
260 | } | 267 | } |
261 | 268 | ||
269 | int | ||
270 | mailbox_uidvalidity (mailbox_t mbox, unsigned long *pvalid) | ||
271 | { | ||
272 | if (mbox == NULL || mbox->_uidvalidity == NULL) | ||
273 | return 0; | ||
274 | return mbox->_uidvalidity (mbox, pvalid); | ||
275 | } | ||
276 | |||
277 | int | ||
278 | mailbox_uidnext (mailbox_t mbox, size_t *puidnext) | ||
279 | { | ||
280 | if (mbox == NULL || mbox->_uidnext == NULL) | ||
281 | return 0; | ||
282 | return mbox->_uidnext (mbox, puidnext); | ||
283 | } | ||
284 | |||
262 | /* locking */ | 285 | /* locking */ |
263 | int | 286 | int |
264 | mailbox_set_locker (mailbox_t mbox, locker_t locker) | 287 | mailbox_set_locker (mailbox_t mbox, locker_t locker) | ... | ... |
... | @@ -48,7 +48,7 @@ _mapfile_destroy (stream_t stream) | ... | @@ -48,7 +48,7 @@ _mapfile_destroy (stream_t stream) |
48 | { | 48 | { |
49 | struct _mapfile_stream *mfs = stream_get_owner (stream); | 49 | struct _mapfile_stream *mfs = stream_get_owner (stream); |
50 | 50 | ||
51 | if (mfs && mfs->ptr) | 51 | if (mfs && mfs->ptr != MAP_FAILED) |
52 | { | 52 | { |
53 | munmap (mfs->ptr, mfs->size); | 53 | munmap (mfs->ptr, mfs->size); |
54 | close (mfs->fd); | 54 | close (mfs->fd); |
... | @@ -63,7 +63,7 @@ _mapfile_read (stream_t stream, char *optr, size_t osize, | ... | @@ -63,7 +63,7 @@ _mapfile_read (stream_t stream, char *optr, size_t osize, |
63 | struct _mapfile_stream *mfs = stream_get_owner (stream); | 63 | struct _mapfile_stream *mfs = stream_get_owner (stream); |
64 | size_t n; | 64 | size_t n; |
65 | 65 | ||
66 | if (mfs == NULL || mfs->ptr == NULL) | 66 | if (mfs == NULL || mfs->ptr == MAP_FAILED) |
67 | return EINVAL; | 67 | return EINVAL; |
68 | 68 | ||
69 | if (offset >= (off_t)mfs->size) | 69 | if (offset >= (off_t)mfs->size) |
... | @@ -89,7 +89,7 @@ _mapfile_readline (stream_t stream, char *optr, size_t osize, | ... | @@ -89,7 +89,7 @@ _mapfile_readline (stream_t stream, char *optr, size_t osize, |
89 | char *nl; | 89 | char *nl; |
90 | size_t n = 0; | 90 | size_t n = 0; |
91 | 91 | ||
92 | if (mfs == NULL || mfs->ptr == NULL) | 92 | if (mfs == NULL || mfs->ptr == MAP_FAILED) |
93 | return EINVAL; | 93 | return EINVAL; |
94 | /* Save space for the null byte. */ | 94 | /* Save space for the null byte. */ |
95 | osize--; | 95 | osize--; |
... | @@ -116,7 +116,7 @@ _mapfile_write (stream_t stream, const char *iptr, size_t isize, | ... | @@ -116,7 +116,7 @@ _mapfile_write (stream_t stream, const char *iptr, size_t isize, |
116 | { | 116 | { |
117 | struct _mapfile_stream *mfs = stream_get_owner (stream); | 117 | struct _mapfile_stream *mfs = stream_get_owner (stream); |
118 | 118 | ||
119 | if (mfs == NULL || mfs->ptr == NULL) | 119 | if (mfs == NULL || mfs->ptr == MAP_FAILED) |
120 | return EINVAL; | 120 | return EINVAL; |
121 | 121 | ||
122 | if (! (mfs->flags & PROT_WRITE)) | 122 | if (! (mfs->flags & PROT_WRITE)) |
... | @@ -155,7 +155,7 @@ static int | ... | @@ -155,7 +155,7 @@ static int |
155 | _mapfile_truncate (stream_t stream, off_t len) | 155 | _mapfile_truncate (stream_t stream, off_t len) |
156 | { | 156 | { |
157 | struct _mapfile_stream *mfs = stream_get_owner (stream); | 157 | struct _mapfile_stream *mfs = stream_get_owner (stream); |
158 | if (mfs == NULL || mfs->ptr == NULL) | 158 | if (mfs == NULL || mfs->ptr == MAP_FAILED) |
159 | return EINVAL; | 159 | return EINVAL; |
160 | /* Remap. */ | 160 | /* Remap. */ |
161 | if (munmap (mfs->ptr, mfs->size) != 0) | 161 | if (munmap (mfs->ptr, mfs->size) != 0) |
... | @@ -185,7 +185,7 @@ _mapfile_size (stream_t stream, off_t *psize) | ... | @@ -185,7 +185,7 @@ _mapfile_size (stream_t stream, off_t *psize) |
185 | struct stat stbuf; | 185 | struct stat stbuf; |
186 | int err = 0; | 186 | int err = 0; |
187 | 187 | ||
188 | if (mfs == NULL || mfs->ptr == NULL) | 188 | if (mfs == NULL || mfs->ptr == MAP_FAILED) |
189 | return EINVAL; | 189 | return EINVAL; |
190 | msync (mfs->ptr, mfs->size, MS_SYNC); | 190 | msync (mfs->ptr, mfs->size, MS_SYNC); |
191 | if (fstat(mfs->fd, &stbuf) != 0) | 191 | if (fstat(mfs->fd, &stbuf) != 0) |
... | @@ -204,7 +204,7 @@ _mapfile_size (stream_t stream, off_t *psize) | ... | @@ -204,7 +204,7 @@ _mapfile_size (stream_t stream, off_t *psize) |
204 | } | 204 | } |
205 | if (err != 0) | 205 | if (err != 0) |
206 | { | 206 | { |
207 | mfs->ptr = NULL; | 207 | mfs->ptr = MAP_FAILED; |
208 | close (mfs->fd); | 208 | close (mfs->fd); |
209 | mfs->fd = -1; | 209 | mfs->fd = -1; |
210 | } | 210 | } |
... | @@ -241,13 +241,13 @@ _mapfile_close (stream_t stream) | ... | @@ -241,13 +241,13 @@ _mapfile_close (stream_t stream) |
241 | { | 241 | { |
242 | struct _mapfile_stream *mfs = stream_get_owner (stream); | 242 | struct _mapfile_stream *mfs = stream_get_owner (stream); |
243 | int err = 0; | 243 | int err = 0; |
244 | if (mfs && mfs->ptr) | 244 | if (mfs && mfs->ptr != MAP_FAILED) |
245 | { | 245 | { |
246 | if (munmap (mfs->ptr, mfs->size) != 0) | 246 | if (munmap (mfs->ptr, mfs->size) != 0) |
247 | err = errno; | 247 | err = errno; |
248 | if (close (mfs->fd) != 0) | 248 | if (close (mfs->fd) != 0) |
249 | err = errno; | 249 | err = errno; |
250 | mfs->ptr = NULL; | 250 | mfs->ptr = MAP_FAILED; |
251 | mfs->fd = -1; | 251 | mfs->fd = -1; |
252 | } | 252 | } |
253 | return err; | 253 | return err; |
... | @@ -265,6 +265,17 @@ _mapfile_open (stream_t stream, const char *filename, int port, int flags) | ... | @@ -265,6 +265,17 @@ _mapfile_open (stream_t stream, const char *filename, int port, int flags) |
265 | if (mfs == NULL) | 265 | if (mfs == NULL) |
266 | return EINVAL; | 266 | return EINVAL; |
267 | 267 | ||
268 | /* Close any previous file. */ | ||
269 | if (mfs->ptr != MAP_FAILED) | ||
270 | { | ||
271 | munmap (mfs->ptr, mfs->size); | ||
272 | mfs->ptr = MAP_FAILED; | ||
273 | } | ||
274 | if (mfs->fd != -1) | ||
275 | { | ||
276 | close (mfs->fd); | ||
277 | mfs->fd = -1; | ||
278 | } | ||
268 | /* Map the flags to the system equivalent */ | 279 | /* Map the flags to the system equivalent */ |
269 | if (flags & MU_STREAM_WRITE) | 280 | if (flags & MU_STREAM_WRITE) |
270 | { | 281 | { |
... | @@ -299,7 +310,7 @@ _mapfile_open (stream_t stream, const char *filename, int port, int flags) | ... | @@ -299,7 +310,7 @@ _mapfile_open (stream_t stream, const char *filename, int port, int flags) |
299 | { | 310 | { |
300 | int err = errno; | 311 | int err = errno; |
301 | close (mfs->fd); | 312 | close (mfs->fd); |
302 | mfs->ptr = NULL; | 313 | mfs->ptr = MAP_FAILED; |
303 | return err; | 314 | return err; |
304 | } | 315 | } |
305 | mfs->flags = mflag; | 316 | mfs->flags = mflag; |
... | @@ -325,6 +336,9 @@ mapfile_stream_create (stream_t *stream) | ... | @@ -325,6 +336,9 @@ mapfile_stream_create (stream_t *stream) |
325 | if (fs == NULL) | 336 | if (fs == NULL) |
326 | return ENOMEM; | 337 | return ENOMEM; |
327 | 338 | ||
339 | fs->fd = -1; | ||
340 | fs->ptr = MAP_FAILED; | ||
341 | |||
328 | ret = stream_create (stream, MU_STREAM_NO_CHECK, fs); | 342 | ret = stream_create (stream, MU_STREAM_NO_CHECK, fs); |
329 | if (ret != 0) | 343 | if (ret != 0) |
330 | { | 344 | { | ... | ... |
... | @@ -33,10 +33,13 @@ | ... | @@ -33,10 +33,13 @@ |
33 | static void mailbox_imap_destroy (mailbox_t); | 33 | static void mailbox_imap_destroy (mailbox_t); |
34 | static int mailbox_imap_open (mailbox_t, int); | 34 | static int mailbox_imap_open (mailbox_t, int); |
35 | static int mailbox_imap_close (mailbox_t); | 35 | static int mailbox_imap_close (mailbox_t); |
36 | static int imap_uidvalidity (mailbox_t, unsigned long *); | ||
37 | static int imap_uidnext (mailbox_t, size_t *); | ||
36 | static int imap_expunge (mailbox_t); | 38 | static int imap_expunge (mailbox_t); |
37 | static int imap_get_message (mailbox_t, size_t, message_t *); | 39 | static int imap_get_message (mailbox_t, size_t, message_t *); |
38 | static int imap_messages_count (mailbox_t, size_t *); | 40 | static int imap_messages_count (mailbox_t, size_t *); |
39 | static int imap_unseen_count (mailbox_t, size_t *); | 41 | static int imap_messages_recent (mailbox_t, size_t *); |
42 | static int imap_message_unseen (mailbox_t, size_t *); | ||
40 | static int imap_scan (mailbox_t, size_t, size_t *); | 43 | static int imap_scan (mailbox_t, size_t, size_t *); |
41 | static int imap_is_updated (mailbox_t); | 44 | static int imap_is_updated (mailbox_t); |
42 | static int imap_append_message (mailbox_t, message_t); | 45 | static int imap_append_message (mailbox_t, message_t); |
... | @@ -47,7 +50,7 @@ static int imap_message_size (message_t, size_t *); | ... | @@ -47,7 +50,7 @@ static int imap_message_size (message_t, size_t *); |
47 | static int imap_message_lines (message_t, size_t *); | 50 | static int imap_message_lines (message_t, size_t *); |
48 | static int imap_message_fd (stream_t, int *); | 51 | static int imap_message_fd (stream_t, int *); |
49 | static int imap_message_read (stream_t , char *, size_t, off_t, size_t *); | 52 | static int imap_message_read (stream_t , char *, size_t, off_t, size_t *); |
50 | static int imap_message_uid (message_t, char *, size_t, size_t *); | 53 | static int imap_message_uid (message_t, size_t *); |
51 | 54 | ||
52 | /* Mime handling. */ | 55 | /* Mime handling. */ |
53 | static int imap_is_multipart (message_t, int *); | 56 | static int imap_is_multipart (message_t, int *); |
... | @@ -66,7 +69,6 @@ static int imap_attr_unset_flags (attribute_t, int); | ... | @@ -66,7 +69,6 @@ static int imap_attr_unset_flags (attribute_t, int); |
66 | /* Header. */ | 69 | /* Header. */ |
67 | static int imap_header_read (header_t, char*, size_t, off_t, size_t *); | 70 | static int imap_header_read (header_t, char*, size_t, off_t, size_t *); |
68 | static int imap_header_get_value (header_t, const char*, char *, size_t, size_t *); | 71 | static int imap_header_get_value (header_t, const char*, char *, size_t, size_t *); |
69 | static int imap_header_fd (stream_t, int *); | ||
70 | 72 | ||
71 | /* Body. */ | 73 | /* Body. */ |
72 | static int imap_body_read (stream_t, char *, size_t, off_t, size_t *); | 74 | static int imap_body_read (stream_t, char *, size_t, off_t, size_t *); |
... | @@ -116,8 +118,11 @@ _mailbox_imap_init (mailbox_t mailbox) | ... | @@ -116,8 +118,11 @@ _mailbox_imap_init (mailbox_t mailbox) |
116 | mailbox->_get_message = imap_get_message; | 118 | mailbox->_get_message = imap_get_message; |
117 | mailbox->_append_message = imap_append_message; | 119 | mailbox->_append_message = imap_append_message; |
118 | mailbox->_messages_count = imap_messages_count; | 120 | mailbox->_messages_count = imap_messages_count; |
119 | mailbox->_unseen_count = imap_unseen_count; | 121 | mailbox->_messages_recent = imap_messages_recent; |
122 | mailbox->_message_unseen = imap_message_unseen; | ||
120 | mailbox->_expunge = imap_expunge; | 123 | mailbox->_expunge = imap_expunge; |
124 | mailbox->_uidvalidity = imap_uidvalidity; | ||
125 | mailbox->_uidnext = imap_uidnext; | ||
121 | 126 | ||
122 | mailbox->_scan = imap_scan; | 127 | mailbox->_scan = imap_scan; |
123 | mailbox->_is_updated = imap_is_updated; | 128 | mailbox->_is_updated = imap_is_updated; |
... | @@ -142,8 +147,6 @@ free_subparts (msg_imap_t msg_imap) | ... | @@ -142,8 +147,6 @@ free_subparts (msg_imap_t msg_imap) |
142 | 147 | ||
143 | if (msg_imap->message) | 148 | if (msg_imap->message) |
144 | message_destroy (&(msg_imap->message), msg_imap); | 149 | message_destroy (&(msg_imap->message), msg_imap); |
145 | if (msg_imap->uid) | ||
146 | free (msg_imap->uid); | ||
147 | if (msg_imap->parts) | 150 | if (msg_imap->parts) |
148 | free (msg_imap->parts); | 151 | free (msg_imap->parts); |
149 | free(msg_imap); | 152 | free(msg_imap); |
... | @@ -411,7 +414,7 @@ imap_get_message0 (msg_imap_t msg_imap, message_t *pmsg) | ... | @@ -411,7 +414,7 @@ imap_get_message0 (msg_imap_t msg_imap, message_t *pmsg) |
411 | message_set_get_num_parts (msg, imap_get_num_parts, msg_imap); | 414 | message_set_get_num_parts (msg, imap_get_num_parts, msg_imap); |
412 | message_set_get_part (msg, imap_get_part, msg_imap); | 415 | message_set_get_part (msg, imap_get_part, msg_imap); |
413 | 416 | ||
414 | /* Set the UIDL call on the message. */ | 417 | /* Set the UID on the message. */ |
415 | message_set_uid (msg, imap_message_uid, msg_imap); | 418 | message_set_uid (msg, imap_message_uid, msg_imap); |
416 | 419 | ||
417 | *pmsg = msg; | 420 | *pmsg = msg; |
... | @@ -419,12 +422,37 @@ imap_get_message0 (msg_imap_t msg_imap, message_t *pmsg) | ... | @@ -419,12 +422,37 @@ imap_get_message0 (msg_imap_t msg_imap, message_t *pmsg) |
419 | } | 422 | } |
420 | 423 | ||
421 | static int | 424 | static int |
422 | imap_unseen_count (mailbox_t mailbox, size_t *pnum) | 425 | imap_message_unseen (mailbox_t mailbox, size_t *punseen) |
423 | { | 426 | { |
424 | m_imap_t m_imap = mailbox->data; | 427 | m_imap_t m_imap = mailbox->data; |
425 | *pnum = m_imap->unseen; | 428 | *punseen = m_imap->unseen; |
426 | return 0; | 429 | return 0; |
427 | } | 430 | } |
431 | |||
432 | static int | ||
433 | imap_messages_recent (mailbox_t mailbox, size_t *precent) | ||
434 | { | ||
435 | m_imap_t m_imap = mailbox->data; | ||
436 | *precent = m_imap->recent; | ||
437 | return 0; | ||
438 | } | ||
439 | |||
440 | static int | ||
441 | imap_uidvalidity (mailbox_t mailbox, unsigned long *puidvalidity) | ||
442 | { | ||
443 | m_imap_t m_imap = mailbox->data; | ||
444 | *puidvalidity = m_imap->uidvalidity; | ||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | static int | ||
449 | imap_uidnext (mailbox_t mailbox, size_t *puidnext) | ||
450 | { | ||
451 | m_imap_t m_imap = mailbox->data; | ||
452 | *puidnext = m_imap->uidnext; | ||
453 | return 0; | ||
454 | } | ||
455 | |||
428 | /* There is no explicit call to get the message count. The count is send on | 456 | /* There is no explicit call to get the message count. The count is send on |
429 | a SELECT/EXAMINE command it is also sent async, meaning it will be piggy | 457 | a SELECT/EXAMINE command it is also sent async, meaning it will be piggy |
430 | back on other server response as an untag "EXIST" response. But we still | 458 | back on other server response as an untag "EXIST" response. But we still |
... | @@ -687,12 +715,37 @@ imap_message_size (message_t msg, size_t *psize) | ... | @@ -687,12 +715,37 @@ imap_message_size (message_t msg, size_t *psize) |
687 | } | 715 | } |
688 | 716 | ||
689 | static int | 717 | static int |
690 | imap_message_uid (message_t msg, char *buffer, size_t buflen, size_t *pnwriten) | 718 | imap_message_uid (message_t msg, size_t *puid) |
691 | { | 719 | { |
692 | (void)msg; (void)buffer; (void)buflen; | 720 | msg_imap_t msg_imap = message_get_owner (msg); |
693 | if (pnwriten) | 721 | m_imap_t m_imap = msg_imap->m_imap; |
694 | *pnwriten = 0; | 722 | f_imap_t f_imap = m_imap->f_imap; |
695 | return ENOSYS; | 723 | int status; |
724 | |||
725 | if (puid) | ||
726 | return 0; | ||
727 | /* Select first. */ | ||
728 | if (f_imap->state == IMAP_NO_STATE) | ||
729 | { | ||
730 | if (msg_imap->uid) | ||
731 | { | ||
732 | *puid = msg_imap->uid; | ||
733 | return 0; | ||
734 | } | ||
735 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
736 | if (status != 0) | ||
737 | return status; | ||
738 | status = imap_writeline (f_imap, "g%d FETCH %d UID\r\n", | ||
739 | f_imap->seq++, msg_imap->num); | ||
740 | CHECK_ERROR (f_imap, status); | ||
741 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | ||
742 | f_imap->state = IMAP_FETCH; | ||
743 | } | ||
744 | status = message_operation (f_imap, msg_imap, 0, 0, 0, 0); | ||
745 | if (status != 0) | ||
746 | return status; | ||
747 | *puid = msg_imap->uid; | ||
748 | return 0; | ||
696 | } | 749 | } |
697 | 750 | ||
698 | static int | 751 | static int |
... | @@ -1057,16 +1110,6 @@ imap_header_read (header_t header, char *buffer, size_t buflen, off_t offset, | ... | @@ -1057,16 +1110,6 @@ imap_header_read (header_t header, char *buffer, size_t buflen, off_t offset, |
1057 | plen); | 1110 | plen); |
1058 | } | 1111 | } |
1059 | 1112 | ||
1060 | static int | ||
1061 | imap_header_fd (stream_t stream, int *pfd) | ||
1062 | { | ||
1063 | header_t header = stream_get_owner (stream); | ||
1064 | message_t msg = header_get_owner (header); | ||
1065 | msg_imap_t msg_imap = message_get_owner (msg); | ||
1066 | return imap_get_fd (msg_imap, pfd); | ||
1067 | } | ||
1068 | |||
1069 | |||
1070 | /* Body. */ | 1113 | /* Body. */ |
1071 | static int | 1114 | static int |
1072 | imap_body_size (body_t body, size_t *psize) | 1115 | imap_body_size (body_t body, size_t *psize) | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -156,7 +156,7 @@ do \ | ... | @@ -156,7 +156,7 @@ do \ |
156 | { \ | 156 | { \ |
157 | if (*s == c0 || *s == c1) \ | 157 | if (*s == c0 || *s == c1) \ |
158 | { \ | 158 | { \ |
159 | (mum)->old_flags |= (type); \ | 159 | (mum)->attr_flags |= (type); \ |
160 | break; \ | 160 | break; \ |
161 | } \ | 161 | } \ |
162 | } \ | 162 | } \ |
... | @@ -220,6 +220,19 @@ do \ | ... | @@ -220,6 +220,19 @@ do \ |
220 | && (buf[1] == 'O' || buf[1] == 'o') \ | 220 | && (buf[1] == 'O' || buf[1] == 'o') \ |
221 | && (buf[2] == ':' || buf[2] == ' ' || buf[2] == '\t')) | 221 | && (buf[2] == ':' || buf[2] == ' ' || buf[2] == '\t')) |
222 | 222 | ||
223 | #define ISX_IMAPBASE(buf) (\ | ||
224 | (buf[0] == 'X' || buf[0] == 'x') \ | ||
225 | && (buf[1] == '-') \ | ||
226 | && (buf[2] == 'I' || buf[2] == 'i') \ | ||
227 | && (buf[3] == 'M' || buf[3] == 'm') \ | ||
228 | && (buf[4] == 'A' || buf[4] == 'a') \ | ||
229 | && (buf[5] == 'P' || buf[5] == 'p') \ | ||
230 | && (buf[6] == 'B' || buf[6] == 'b') \ | ||
231 | && (buf[7] == 'A' || buf[7] == 'a') \ | ||
232 | && (buf[8] == 'S' || buf[8] == 's') \ | ||
233 | && (buf[9] == 'E' || buf[9] == 'e') \ | ||
234 | && (buf[10] == ':' || buf[10] == ' ' || buf[10] == '\t')) | ||
235 | |||
223 | #define ISX_UIDL(buf) (\ | 236 | #define ISX_UIDL(buf) (\ |
224 | (buf[0] == 'X' || buf[0] == 'x') \ | 237 | (buf[0] == 'X' || buf[0] == 'x') \ |
225 | && (buf[1] == '-') \ | 238 | && (buf[1] == '-') \ |
... | @@ -268,8 +281,6 @@ do { \ | ... | @@ -268,8 +281,6 @@ do { \ |
268 | } \ | 281 | } \ |
269 | } while (0) | 282 | } while (0) |
270 | 283 | ||
271 | //fprintf (stderr, "%d %d <%s> <%s>\n", i, l, (i)?field:"", p); | ||
272 | |||
273 | #define FAST_HCONTENT_TYPE(mum,sf,buf,n) \ | 284 | #define FAST_HCONTENT_TYPE(mum,sf,buf,n) \ |
274 | FAST_HEADER(mum->fhdr[HCONTENT_TYPE],buf,n); \ | 285 | FAST_HEADER(mum->fhdr[HCONTENT_TYPE],buf,n); \ |
275 | sf = &(mum->fhdr[HCONTENT_TYPE]) | 286 | sf = &(mum->fhdr[HCONTENT_TYPE]) |
... | @@ -294,6 +305,10 @@ sf = &(mum->fhdr[HSUBJECT]) | ... | @@ -294,6 +305,10 @@ sf = &(mum->fhdr[HSUBJECT]) |
294 | FAST_HEADER(mum->fhdr[HTO],buf,n); \ | 305 | FAST_HEADER(mum->fhdr[HTO],buf,n); \ |
295 | sf = &(mum->fhdr[HTO]) | 306 | sf = &(mum->fhdr[HTO]) |
296 | 307 | ||
308 | #define FAST_HX_IMAPBASE(mum,sf,buf,n) \ | ||
309 | FAST_HEADER(mum->fhdr[HX_IMAPBASE],buf,n); \ | ||
310 | sf = &(mum->fhdr[HX_UID]) | ||
311 | |||
297 | #define FAST_HX_UIDL(mum,sf,buf,n) \ | 312 | #define FAST_HX_UIDL(mum,sf,buf,n) \ |
298 | FAST_HEADER(mum->fhdr[HX_UIDL],buf,n); \ | 313 | FAST_HEADER(mum->fhdr[HX_UIDL],buf,n); \ |
299 | sf = &(mum->fhdr[HX_UIDL]) | 314 | sf = &(mum->fhdr[HX_UIDL]) |
... | @@ -483,45 +498,47 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -483,45 +498,47 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
483 | mum->fhdr[j] = NULL; | 498 | mum->fhdr[j] = NULL; |
484 | } | 499 | } |
485 | } | 500 | } |
486 | else if (/*(n > 7) && */ ISSTATUS(buf)) | 501 | else if (ISSTATUS(buf)) |
487 | { | 502 | { |
488 | mum->header_status = total - n; | ||
489 | mum->header_status_end = total; | ||
490 | ATTRIBUTE_SET(buf, mum, 'r', 'R', MU_ATTRIBUTE_READ); | 503 | ATTRIBUTE_SET(buf, mum, 'r', 'R', MU_ATTRIBUTE_READ); |
491 | ATTRIBUTE_SET(buf, mum, 'o', 'O', MU_ATTRIBUTE_SEEN); | 504 | ATTRIBUTE_SET(buf, mum, 'o', 'O', MU_ATTRIBUTE_SEEN); |
492 | ATTRIBUTE_SET(buf, mum, 'a', 'A', MU_ATTRIBUTE_ANSWERED); | 505 | ATTRIBUTE_SET(buf, mum, 'a', 'A', MU_ATTRIBUTE_ANSWERED); |
493 | ATTRIBUTE_SET(buf, mum, 'd', 'D', MU_ATTRIBUTE_DELETED); | 506 | ATTRIBUTE_SET(buf, mum, 'd', 'D', MU_ATTRIBUTE_DELETED); |
494 | sfield = NULL; | 507 | sfield = NULL; |
495 | } | 508 | } |
496 | else if (/*(n > 12) && */ ISCONTENT_TYPE(buf)) | 509 | else if (ISCONTENT_TYPE(buf)) |
497 | { | 510 | { |
498 | FAST_HCONTENT_TYPE(mum, sfield, buf, n); | 511 | FAST_HCONTENT_TYPE(mum, sfield, buf, n); |
499 | } | 512 | } |
500 | else if (/*(n > 3) && */ ISCC(buf)) | 513 | else if (ISCC(buf)) |
501 | { | 514 | { |
502 | FAST_HCC(mum, sfield, buf, n); | 515 | FAST_HCC(mum, sfield, buf, n); |
503 | } | 516 | } |
504 | else if (/*(n > 5) && */ ISDATE(buf)) | 517 | else if (ISDATE(buf)) |
505 | { | 518 | { |
506 | FAST_HDATE(mum, sfield, buf, n); | 519 | FAST_HDATE(mum, sfield, buf, n); |
507 | } | 520 | } |
508 | else if (/*(n > 5) && */ ISFROM(buf)) | 521 | else if (ISFROM(buf)) |
509 | { | 522 | { |
510 | FAST_HFROM(mum, sfield, buf, n); | 523 | FAST_HFROM(mum, sfield, buf, n); |
511 | } | 524 | } |
512 | else if (/*(n > 8) && */ ISSUBJECT(buf)) | 525 | else if (ISSUBJECT(buf)) |
513 | { | 526 | { |
514 | FAST_HSUBJECT (mum, sfield, buf, n); | 527 | FAST_HSUBJECT (mum, sfield, buf, n); |
515 | } | 528 | } |
516 | else if (/*(n > 3) && */ ISTO(buf)) | 529 | else if (ISTO(buf)) |
517 | { | 530 | { |
518 | FAST_HTO (mum, sfield, buf, n); | 531 | FAST_HTO (mum, sfield, buf, n); |
519 | } | 532 | } |
520 | else if (/*(n > 7) && */ ISX_UIDL(buf)) | 533 | else if (ISX_IMAPBASE(buf)) |
534 | { | ||
535 | FAST_HX_IMAPBASE (mum, sfield, buf, n); | ||
536 | } | ||
537 | else if (ISX_UIDL(buf)) | ||
521 | { | 538 | { |
522 | FAST_HX_UIDL (mum, sfield, buf, n); | 539 | FAST_HX_UIDL (mum, sfield, buf, n); |
523 | } | 540 | } |
524 | else if (/*(n > 6) && */ ISX_UID(buf)) | 541 | else if (ISX_UID(buf)) |
525 | { | 542 | { |
526 | FAST_HX_UID (mum, sfield, buf, n); | 543 | FAST_HX_UID (mum, sfield, buf, n); |
527 | } | 544 | } |
... | @@ -551,11 +568,11 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -551,11 +568,11 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
551 | 568 | ||
552 | newline = nl; | 569 | newline = nl; |
553 | 570 | ||
554 | /* Every 50 mesgs update the lock, it should be every minute. */ | 571 | /* Every 100 mesgs update the lock, it should be every minute. */ |
555 | if ((mud->messages_count % 50) == 0) | 572 | if ((mud->messages_count % 100) == 0) |
556 | locker_touchlock (mailbox->locker); | 573 | locker_touchlock (mailbox->locker); |
557 | 574 | ||
558 | /* Ping them every 1000 lines. */ | 575 | /* Ping them every 1000 lines. Should be tunable. */ |
559 | if (do_notif) | 576 | if (do_notif) |
560 | if (((lines +1) % 1000) == 0) | 577 | if (((lines +1) % 1000) == 0) |
561 | DISPATCH_PROGRESS(mailbox, mud); | 578 | DISPATCH_PROGRESS(mailbox, mud); |
... | @@ -574,6 +591,72 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -574,6 +591,72 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
574 | locker_unlock (mailbox->locker); | 591 | locker_unlock (mailbox->locker); |
575 | monitor_unlock (mailbox->monitor); | 592 | monitor_unlock (mailbox->monitor); |
576 | 593 | ||
594 | /* Reset the uidvalidity. */ | ||
595 | if (mud->messages_count > 0) | ||
596 | { | ||
597 | mum = mud->umessages[0]; | ||
598 | if (mum->fhdr[HX_IMAPBASE]) | ||
599 | { | ||
600 | char *s = mum->fhdr[HX_IMAPBASE]; | ||
601 | while (*s && !isdigit (*s)) s++; | ||
602 | mud->uidvalidity = strtoul (s, &s, 10); | ||
603 | mud->uidnext = strtoul (s, NULL, 10); | ||
604 | } | ||
605 | if (mud->uidvalidity == 0) | ||
606 | { | ||
607 | char u[64]; | ||
608 | mud->uidvalidity = (unsigned long)time (NULL); | ||
609 | mud->uidnext = mud->messages_count + 1; | ||
610 | if (mum->fhdr[HX_IMAPBASE]) | ||
611 | free (mum->fhdr[HX_IMAPBASE]); | ||
612 | sprintf (u, "%lu %u", mud->uidvalidity, mud->uidnext); | ||
613 | mum->fhdr[HX_IMAPBASE] = strdup (u); | ||
614 | /* Tell that we have been modified for expunging. */ | ||
615 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; | ||
616 | } | ||
617 | } | ||
618 | /* Reset the IMAP uids, if necessary. */ | ||
619 | { | ||
620 | size_t uid; | ||
621 | size_t ouid; | ||
622 | size_t i; | ||
623 | for (uid = ouid = i = 0; i < mud->messages_count; i++) | ||
624 | { | ||
625 | char *s; | ||
626 | mum = mud->umessages[i]; | ||
627 | s = mum->fhdr[HX_UID]; | ||
628 | if (s) | ||
629 | { | ||
630 | while (*s && !isdigit (*s)) s++; | ||
631 | uid = strtoul (s, &s, 10); | ||
632 | } | ||
633 | else | ||
634 | uid = 0; | ||
635 | if (uid <= ouid) | ||
636 | { | ||
637 | char u[64]; | ||
638 | uid = ouid + 1; | ||
639 | sprintf (u, "%d", uid); | ||
640 | if (mum->fhdr[HX_UID]) | ||
641 | free (mum->fhdr[HX_UID]); | ||
642 | mum->fhdr[HX_UID] = strdup (u); | ||
643 | /* Note that we have modified for expunging. */ | ||
644 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; | ||
645 | } | ||
646 | mum->uid = ouid = uid; | ||
647 | } | ||
648 | if (uid > mud->messages_count) | ||
649 | { | ||
650 | char u[64]; | ||
651 | mud->uidnext = uid + 1; | ||
652 | mum = mud->umessages[0]; | ||
653 | if (mum->fhdr[HX_IMAPBASE]) | ||
654 | free (mum->fhdr[HX_IMAPBASE]); | ||
655 | sprintf (u, "%lu %u", mud->uidvalidity, uid + 1); | ||
656 | mum->fhdr[HX_IMAPBASE] = strdup (u); | ||
657 | mum->attr_flags |= MU_ATTRIBUTE_MODIFIED; | ||
658 | } | ||
659 | } | ||
577 | #ifdef WITH_PTHREAD | 660 | #ifdef WITH_PTHREAD |
578 | pthread_cleanup_pop (0); | 661 | pthread_cleanup_pop (0); |
579 | #endif | 662 | #endif | ... | ... |
... | @@ -70,39 +70,42 @@ enum pop_state | ... | @@ -70,39 +70,42 @@ enum pop_state |
70 | POP_AUTH_PASS, POP_AUTH_PASS_ACK | 70 | POP_AUTH_PASS, POP_AUTH_PASS_ACK |
71 | }; | 71 | }; |
72 | 72 | ||
73 | static void pop_destroy __P ((mailbox_t)); | 73 | static void pop_destroy __P ((mailbox_t)); |
74 | 74 | ||
75 | /* Functions/Methods that implements the mailbox_t API. */ | 75 | /* Functions/Methods that implements the mailbox_t API. */ |
76 | static int pop_open __P ((mailbox_t, int)); | 76 | static int pop_open __P ((mailbox_t, int)); |
77 | static int pop_close __P ((mailbox_t)); | 77 | static int pop_close __P ((mailbox_t)); |
78 | static int pop_get_message __P ((mailbox_t, size_t, message_t *)); | 78 | static int pop_get_message __P ((mailbox_t, size_t, message_t *)); |
79 | static int pop_messages_count __P ((mailbox_t, size_t *)); | 79 | static int pop_messages_count __P ((mailbox_t, size_t *)); |
80 | static int pop_expunge __P ((mailbox_t)); | 80 | static int pop_messages_recent __P ((mailbox_t, size_t *)); |
81 | static int pop_scan __P ((mailbox_t, size_t, size_t *)); | 81 | static int pop_message_unseen __P ((mailbox_t, size_t *)); |
82 | static int pop_is_updated __P ((mailbox_t)); | 82 | static int pop_expunge __P ((mailbox_t)); |
83 | static int pop_scan __P ((mailbox_t, size_t, size_t *)); | ||
84 | static int pop_is_updated __P ((mailbox_t)); | ||
83 | 85 | ||
84 | /* The implementation of message_t */ | 86 | /* The implementation of message_t */ |
85 | static int pop_user __P ((authority_t)); | 87 | static int pop_user __P ((authority_t)); |
86 | static int pop_size __P ((mailbox_t, off_t *)); | 88 | static int pop_size __P ((mailbox_t, off_t *)); |
87 | /* We use pop_top for retreiving headers. */ | 89 | /* We use pop_top for retreiving headers. */ |
88 | /* static int pop_header_read (header_t, char *, size_t, off_t, size_t *); */ | 90 | /* static int pop_header_read (header_t, char *, size_t, off_t, size_t *); */ |
89 | static int pop_body_fd __P ((stream_t, int *)); | 91 | static int pop_body_fd __P ((stream_t, int *)); |
90 | static int pop_body_size __P ((body_t, size_t *)); | 92 | static int pop_body_size __P ((body_t, size_t *)); |
91 | static int pop_body_lines __P ((body_t, size_t *)); | 93 | static int pop_body_lines __P ((body_t, size_t *)); |
92 | static int pop_body_read __P ((stream_t, char *, size_t, off_t, size_t *)); | 94 | static int pop_body_read __P ((stream_t, char *, size_t, off_t, size_t *)); |
93 | static int pop_message_read __P ((stream_t, char *, size_t, off_t, size_t *)); | 95 | static int pop_message_read __P ((stream_t, char *, size_t, off_t, size_t *)); |
94 | static int pop_message_size __P ((message_t, size_t *)); | 96 | static int pop_message_size __P ((message_t, size_t *)); |
95 | static int pop_message_fd __P ((stream_t, int *)); | 97 | static int pop_message_fd __P ((stream_t, int *)); |
96 | static int pop_top __P ((header_t, char *, size_t, off_t, size_t *)); | 98 | static int pop_top __P ((header_t, char *, size_t, off_t, size_t *)); |
97 | static int pop_retr __P ((pop_message_t, char *, size_t, off_t, size_t *)); | 99 | static int pop_retr __P ((pop_message_t, char *, size_t, off_t, size_t *)); |
98 | static int pop_get_fd __P ((pop_message_t, int *)); | 100 | static int pop_get_fd __P ((pop_message_t, int *)); |
99 | static int pop_attr_flags __P ((attribute_t, int *)); | 101 | static int pop_attr_flags __P ((attribute_t, int *)); |
100 | static int pop_uid __P ((message_t, char *, size_t, size_t *)); | 102 | static int pop_uidl __P ((message_t, char *, size_t, size_t *)); |
101 | static int fill_buffer __P ((pop_data_t, char *, size_t)); | 103 | static int pop_uid __P ((message_t, size_t *)); |
102 | static int pop_readline __P ((pop_data_t)); | 104 | static int fill_buffer __P ((pop_data_t, char *, size_t)); |
103 | static int pop_read_ack __P ((pop_data_t)); | 105 | static int pop_readline __P ((pop_data_t)); |
104 | static int pop_writeline __P ((pop_data_t, const char *, ...)); | 106 | static int pop_read_ack __P ((pop_data_t)); |
105 | static int pop_write __P ((pop_data_t)); | 107 | static int pop_writeline __P ((pop_data_t, const char *, ...)); |
108 | static int pop_write __P ((pop_data_t)); | ||
106 | 109 | ||
107 | /* This structure holds the info for a message. The pop_message_t | 110 | /* This structure holds the info for a message. The pop_message_t |
108 | type, will serve as the owner of the message_t and contains the command to | 111 | type, will serve as the owner of the message_t and contains the command to |
... | @@ -122,7 +125,7 @@ struct _pop_message | ... | @@ -122,7 +125,7 @@ struct _pop_message |
122 | size_t header_lines; | 125 | size_t header_lines; |
123 | size_t message_size; | 126 | size_t message_size; |
124 | size_t num; | 127 | size_t num; |
125 | char *uid; /* Cache the uid string. */ | 128 | char *uidl; /* Cache the uidl string. */ |
126 | message_t message; | 129 | message_t message; |
127 | pop_data_t mpd; /* Back pointer. */ | 130 | pop_data_t mpd; /* Back pointer. */ |
128 | }; | 131 | }; |
... | @@ -280,6 +283,8 @@ _mailbox_pop_init (mailbox_t mbox) | ... | @@ -280,6 +283,8 @@ _mailbox_pop_init (mailbox_t mbox) |
280 | /* Messages. */ | 283 | /* Messages. */ |
281 | mbox->_get_message = pop_get_message; | 284 | mbox->_get_message = pop_get_message; |
282 | mbox->_messages_count = pop_messages_count; | 285 | mbox->_messages_count = pop_messages_count; |
286 | mbox->_messages_recent = pop_messages_recent; | ||
287 | mbox->_message_unseen = pop_message_unseen; | ||
283 | mbox->_expunge = pop_expunge; | 288 | mbox->_expunge = pop_expunge; |
284 | 289 | ||
285 | mbox->_scan = pop_scan; | 290 | mbox->_scan = pop_scan; |
... | @@ -306,8 +311,8 @@ pop_destroy (mailbox_t mbox) | ... | @@ -306,8 +311,8 @@ pop_destroy (mailbox_t mbox) |
306 | { | 311 | { |
307 | message_destroy (&(mpd->pmessages[i]->message), | 312 | message_destroy (&(mpd->pmessages[i]->message), |
308 | mpd->pmessages[i]); | 313 | mpd->pmessages[i]); |
309 | if (mpd->pmessages[i]->uid) | 314 | if (mpd->pmessages[i]->uidl) |
310 | free (mpd->pmessages[i]->uid); | 315 | free (mpd->pmessages[i]->uidl); |
311 | free (mpd->pmessages[i]); | 316 | free (mpd->pmessages[i]); |
312 | mpd->pmessages[i] = NULL; | 317 | mpd->pmessages[i] = NULL; |
313 | } | 318 | } |
... | @@ -624,8 +629,8 @@ pop_close (mailbox_t mbox) | ... | @@ -624,8 +629,8 @@ pop_close (mailbox_t mbox) |
624 | { | 629 | { |
625 | message_destroy (&(mpd->pmessages[i]->message), | 630 | message_destroy (&(mpd->pmessages[i]->message), |
626 | mpd->pmessages[i]); | 631 | mpd->pmessages[i]); |
627 | if (mpd->pmessages[i]->uid) | 632 | if (mpd->pmessages[i]->uidl) |
628 | free (mpd->pmessages[i]->uid); | 633 | free (mpd->pmessages[i]->uidl); |
629 | free (mpd->pmessages[i]); | 634 | free (mpd->pmessages[i]); |
630 | mpd->pmessages[i] = NULL; | 635 | mpd->pmessages[i] = NULL; |
631 | } | 636 | } |
... | @@ -753,6 +758,9 @@ pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) | ... | @@ -753,6 +758,9 @@ pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) |
753 | } | 758 | } |
754 | 759 | ||
755 | /* Set the UIDL call on the message. */ | 760 | /* Set the UIDL call on the message. */ |
761 | message_set_uidl (msg, pop_uidl, mpm); | ||
762 | |||
763 | /* Set the UID on the message. */ | ||
756 | message_set_uid (msg, pop_uid, mpm); | 764 | message_set_uid (msg, pop_uid, mpm); |
757 | 765 | ||
758 | /* Add it to the list. */ | 766 | /* Add it to the list. */ |
... | @@ -780,6 +788,30 @@ pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) | ... | @@ -780,6 +788,30 @@ pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) |
780 | return 0; | 788 | return 0; |
781 | } | 789 | } |
782 | 790 | ||
791 | /* There is no such thing in pop all messages should be consider recent. | ||
792 | FIXME: We could cheat and peek at the status if it was not strip | ||
793 | by the server ... */ | ||
794 | static int | ||
795 | pop_messages_recent (mailbox_t mbox, size_t *precent) | ||
796 | { | ||
797 | return pop_messages_count (mbox, precent); | ||
798 | } | ||
799 | |||
800 | /* There is no such thing in pop all messages should be consider unseen. | ||
801 | FIXME: We could cheat and peek at the status if it was not strip | ||
802 | by the server ... */ | ||
803 | static int | ||
804 | pop_message_unseen (mailbox_t mbox, size_t *punseen) | ||
805 | { | ||
806 | size_t count = 0; | ||
807 | int status = pop_messages_count (mbox, &count); | ||
808 | if (status != 0) | ||
809 | return status; | ||
810 | if (punseen) | ||
811 | *punseen = (count > 0) ? 1 : 0; | ||
812 | return 0; | ||
813 | } | ||
814 | |||
783 | /* How many messages we have. Done with STAT. */ | 815 | /* How many messages we have. Done with STAT. */ |
784 | static int | 816 | static int |
785 | pop_messages_count (mailbox_t mbox, size_t *pcount) | 817 | pop_messages_count (mailbox_t mbox, size_t *pcount) |
... | @@ -1025,7 +1057,7 @@ pop_message_size (message_t msg, size_t *psize) | ... | @@ -1025,7 +1057,7 @@ pop_message_size (message_t msg, size_t *psize) |
1025 | 1057 | ||
1026 | default: | 1058 | default: |
1027 | /* | 1059 | /* |
1028 | fprintf (stderr, "pop_uid state\n"); | 1060 | fprintf (stderr, "pop_message_size state\n"); |
1029 | */ | 1061 | */ |
1030 | break; | 1062 | break; |
1031 | } | 1063 | } |
... | @@ -1141,19 +1173,28 @@ pop_get_fd (pop_message_t mpm, int *pfd) | ... | @@ -1141,19 +1173,28 @@ pop_get_fd (pop_message_t mpm, int *pfd) |
1141 | return EINVAL; | 1173 | return EINVAL; |
1142 | } | 1174 | } |
1143 | 1175 | ||
1176 | static int | ||
1177 | pop_uid (message_t msg, size_t *puid) | ||
1178 | { | ||
1179 | pop_message_t mpm = message_get_owner (msg); | ||
1180 | if (puid) | ||
1181 | *puid = mpm->num; | ||
1182 | return 0; | ||
1183 | } | ||
1184 | |||
1144 | /* Get the UIDL. Client should be prepare since it may fail. UIDL is | 1185 | /* Get the UIDL. Client should be prepare since it may fail. UIDL is |
1145 | optional on many POP servers. | 1186 | optional on many POP servers. |
1146 | FIXME: We should check this with CAPA and fall back to a md5 scheme ? | 1187 | FIXME: We should check this with CAPA and fall back to a md5 scheme ? |
1147 | Or maybe check for "X-UIDL" a la Qpopper ? */ | 1188 | Or maybe check for "X-UIDL" a la Qpopper ? */ |
1148 | static int | 1189 | static int |
1149 | pop_uid (message_t msg, char *buffer, size_t buflen, size_t *pnwriten) | 1190 | pop_uidl (message_t msg, char *buffer, size_t buflen, size_t *pnwriten) |
1150 | { | 1191 | { |
1151 | pop_message_t mpm = message_get_owner (msg); | 1192 | pop_message_t mpm = message_get_owner (msg); |
1152 | pop_data_t mpd; | 1193 | pop_data_t mpd; |
1153 | int status = 0; | 1194 | int status = 0; |
1154 | void *func = (void *)pop_uid; | 1195 | void *func = (void *)pop_uidl; |
1155 | size_t num; | 1196 | size_t num; |
1156 | /* According to the RFC uid's are no longer then 70 chars. Still playit | 1197 | /* According to the RFC uidl's are no longer then 70 chars. Still playit |
1157 | safe */ | 1198 | safe */ |
1158 | char uniq[128]; | 1199 | char uniq[128]; |
1159 | 1200 | ||
... | @@ -1161,14 +1202,14 @@ pop_uid (message_t msg, char *buffer, size_t buflen, size_t *pnwriten) | ... | @@ -1161,14 +1202,14 @@ pop_uid (message_t msg, char *buffer, size_t buflen, size_t *pnwriten) |
1161 | return EINVAL; | 1202 | return EINVAL; |
1162 | 1203 | ||
1163 | /* Is it cache ? */ | 1204 | /* Is it cache ? */ |
1164 | if (mpm->uid) | 1205 | if (mpm->uidl) |
1165 | { | 1206 | { |
1166 | size_t len = strlen (mpm->uid); | 1207 | size_t len = strlen (mpm->uidl); |
1167 | if (buffer) | 1208 | if (buffer) |
1168 | { | 1209 | { |
1169 | buflen--; /* Leave space for the null. */ | 1210 | buflen--; /* Leave space for the null. */ |
1170 | buflen = (len > buflen) ? buflen : len; | 1211 | buflen = (len > buflen) ? buflen : len; |
1171 | memcpy (buffer, mpm->uid, buflen); | 1212 | memcpy (buffer, mpm->uidl, buflen); |
1172 | buffer[buflen] = '\0'; | 1213 | buffer[buflen] = '\0'; |
1173 | } | 1214 | } |
1174 | else | 1215 | else |
... | @@ -1207,7 +1248,7 @@ pop_uid (message_t msg, char *buffer, size_t buflen, size_t *pnwriten) | ... | @@ -1207,7 +1248,7 @@ pop_uid (message_t msg, char *buffer, size_t buflen, size_t *pnwriten) |
1207 | 1248 | ||
1208 | default: | 1249 | default: |
1209 | /* | 1250 | /* |
1210 | fprintf (stderr, "pop_uid state\n"); | 1251 | fprintf (stderr, "pop_uidl state\n"); |
1211 | */ | 1252 | */ |
1212 | break; | 1253 | break; |
1213 | } | 1254 | } |
... | @@ -1233,7 +1274,7 @@ pop_uid (message_t msg, char *buffer, size_t buflen, size_t *pnwriten) | ... | @@ -1233,7 +1274,7 @@ pop_uid (message_t msg, char *buffer, size_t buflen, size_t *pnwriten) |
1233 | } | 1274 | } |
1234 | else | 1275 | else |
1235 | buflen = num - 1; /* Do not count newline. */ | 1276 | buflen = num - 1; /* Do not count newline. */ |
1236 | mpm->uid = strdup (uniq); | 1277 | mpm->uidl = strdup (uniq); |
1237 | status = 0; | 1278 | status = 0; |
1238 | } | 1279 | } |
1239 | 1280 | ... | ... |
... | @@ -411,9 +411,19 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner) | ... | @@ -411,9 +411,19 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner) |
411 | return 0; | 411 | return 0; |
412 | } | 412 | } |
413 | 413 | ||
414 | /* FIXME: not nonblocking safe. */ | ||
415 | int | 414 | int |
416 | message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) | 415 | message_get_uid (message_t msg, size_t *puid) |
416 | { | ||
417 | if (msg == NULL) | ||
418 | return EINVAL; | ||
419 | if (msg->_get_uid) | ||
420 | return msg->_get_uid (msg, puid); | ||
421 | *puid = 0; | ||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | int | ||
426 | message_get_uidl (message_t msg, char *buffer, size_t buflen, size_t *pwriten) | ||
417 | { | 427 | { |
418 | header_t header = NULL; | 428 | header_t header = NULL; |
419 | size_t n = 0; | 429 | size_t n = 0; |
... | @@ -424,9 +434,9 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) | ... | @@ -424,9 +434,9 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) |
424 | 434 | ||
425 | buffer[0] = '\0'; | 435 | buffer[0] = '\0'; |
426 | /* Try the function overload if error fallback. */ | 436 | /* Try the function overload if error fallback. */ |
427 | if (msg->_get_uid) | 437 | if (msg->_get_uidl) |
428 | { | 438 | { |
429 | status = msg->_get_uid (msg, buffer, buflen, pwriten); | 439 | status = msg->_get_uidl (msg, buffer, buflen, pwriten); |
430 | if (status == 0) | 440 | if (status == 0) |
431 | return status; | 441 | return status; |
432 | } | 442 | } |
... | @@ -458,7 +468,7 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) | ... | @@ -458,7 +468,7 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) |
458 | } | 468 | } |
459 | else | 469 | else |
460 | { | 470 | { |
461 | static unsigned long seq; | 471 | size_t uid = 0; |
462 | struct md5_ctx md5context; | 472 | struct md5_ctx md5context; |
463 | stream_t stream = NULL; | 473 | stream_t stream = NULL; |
464 | char buf[1024]; | 474 | char buf[1024]; |
... | @@ -466,6 +476,7 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) | ... | @@ -466,6 +476,7 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) |
466 | unsigned char md5digest[16]; | 476 | unsigned char md5digest[16]; |
467 | char *tmp; | 477 | char *tmp; |
468 | n = 0; | 478 | n = 0; |
479 | message_get_uid (msg, &uid); | ||
469 | message_get_stream (msg, &stream); | 480 | message_get_stream (msg, &stream); |
470 | md5_init_ctx (&md5context); | 481 | md5_init_ctx (&md5context); |
471 | while (stream_read (stream, buf, sizeof (buf), offset, &n) == 0 | 482 | while (stream_read (stream, buf, sizeof (buf), offset, &n) == 0 |
... | @@ -479,10 +490,8 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) | ... | @@ -479,10 +490,8 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) |
479 | for (n = 0; n < 16; n++, tmp += 2) | 490 | for (n = 0; n < 16; n++, tmp += 2) |
480 | sprintf (tmp, "%02x", md5digest[n]); | 491 | sprintf (tmp, "%02x", md5digest[n]); |
481 | *tmp = '\0'; | 492 | *tmp = '\0'; |
482 | /* Access to sequence is not thread-safe, but that is not a problem. */ | ||
483 | seq++; | ||
484 | /* POP3 rfc says that an UID should not be longer than 70. */ | 493 | /* POP3 rfc says that an UID should not be longer than 70. */ |
485 | snprintf (buf + 32, 70, ".%lu.%lu", (unsigned long)time (NULL), seq); | 494 | snprintf (buf + 32, 70, ".%lu.%u", (unsigned long)time (NULL), uid); |
486 | 495 | ||
487 | header_set_value (header, "X-UIDL", buf, 1); | 496 | header_set_value (header, "X-UIDL", buf, 1); |
488 | buflen--; /* leave space for the NULL. */ | 497 | buflen--; /* leave space for the NULL. */ |
... | @@ -492,8 +501,8 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) | ... | @@ -492,8 +501,8 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) |
492 | } | 501 | } |
493 | 502 | ||
494 | int | 503 | int |
495 | message_set_uid (message_t msg, int (* _get_uid) | 504 | message_set_uid (message_t msg, int (*_get_uid) __P ((message_t, size_t *)), |
496 | __P ((message_t, char *, size_t, size_t *)), void *owner) | 505 | void *owner) |
497 | { | 506 | { |
498 | if (msg == NULL) | 507 | if (msg == NULL) |
499 | return EINVAL; | 508 | return EINVAL; |
... | @@ -504,6 +513,18 @@ message_set_uid (message_t msg, int (* _get_uid) | ... | @@ -504,6 +513,18 @@ message_set_uid (message_t msg, int (* _get_uid) |
504 | } | 513 | } |
505 | 514 | ||
506 | int | 515 | int |
516 | message_set_uidl (message_t msg, int (* _get_uidl) | ||
517 | __P ((message_t, char *, size_t, size_t *)), void *owner) | ||
518 | { | ||
519 | if (msg == NULL) | ||
520 | return EINVAL; | ||
521 | if (msg->owner != owner) | ||
522 | return EACCES; | ||
523 | msg->_get_uidl = _get_uidl; | ||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | int | ||
507 | message_set_is_multipart (message_t msg, int (*_is_multipart) | 528 | message_set_is_multipart (message_t msg, int (*_is_multipart) |
508 | __P ((message_t, int *)), void *owner) | 529 | __P ((message_t, int *)), void *owner) |
509 | { | 530 | { | ... | ... |
1 | /* GNU mailutils - a suite of utilities for electronic mail | 1 | /* GNU mailutils - a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This program is free software; you can redistribute it and/or modify | 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 | 5 | it under the terms of the GNU General Library Public License as published by |
... | @@ -16,9 +16,9 @@ | ... | @@ -16,9 +16,9 @@ |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
17 | 17 | ||
18 | /* Notes: | 18 | /* Notes: |
19 | 19 | ||
20 | */ | 20 | */ |
21 | 21 | ||
22 | 22 | ||
23 | #ifdef HAVE_CONFIG_H | 23 | #ifdef HAVE_CONFIG_H |
24 | # include <config.h> | 24 | # include <config.h> |
... | @@ -39,22 +39,22 @@ struct _trans_stream | ... | @@ -39,22 +39,22 @@ struct _trans_stream |
39 | { | 39 | { |
40 | stream_t stream; /* encoder/decoder read/writes data to/from here */ | 40 | stream_t stream; /* encoder/decoder read/writes data to/from here */ |
41 | int t_offset; | 41 | int t_offset; |
42 | 42 | ||
43 | int min_size; | 43 | int min_size; |
44 | int s_offset; | 44 | int s_offset; |
45 | char *s_buf; /* used when read it not big enough to handle min_size for decoder/encoder */ | 45 | char *s_buf; /* used when read it not big enough to handle min_size for decoder/encoder */ |
46 | 46 | ||
47 | int offset; /* current stream offset */ | 47 | int offset; /* current stream offset */ |
48 | int line_len; | 48 | int line_len; |
49 | 49 | ||
50 | int w_rhd; /* working buffer read head */ | 50 | int w_rhd; /* working buffer read head */ |
51 | int w_whd; /* working buffer write head */ | 51 | int w_whd; /* working buffer write head */ |
52 | char w_buf[MU_TRANS_BSIZE]; /* working source/dest buffer */ | 52 | char w_buf[MU_TRANS_BSIZE]; /* working source/dest buffer */ |
53 | 53 | ||
54 | int (*transcoder)(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nbytes, int *line_len); | 54 | int (*transcoder)(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nbytes, int *line_len); |
55 | }; | 55 | }; |
56 | 56 | ||
57 | struct _ts_desc | 57 | struct _ts_desc |
58 | { | 58 | { |
59 | const char *encoding; | 59 | const char *encoding; |
60 | 60 | ||
... | @@ -72,14 +72,15 @@ static int _qp_decode(const char *iptr, size_t isize, char *optr, size_t osize, | ... | @@ -72,14 +72,15 @@ static int _qp_decode(const char *iptr, size_t isize, char *optr, size_t osize, |
72 | static int _qp_encode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nbytes, int *line_len); | 72 | static int _qp_encode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nbytes, int *line_len); |
73 | 73 | ||
74 | #define NUM_TRANSCODERS 5 | 74 | #define NUM_TRANSCODERS 5 |
75 | struct _ts_desc tslist[NUM_TRANSCODERS] = { { "base64", _base64_init, _base64_decode, _base64_encode}, | 75 | struct _ts_desc tslist[NUM_TRANSCODERS] = { |
76 | { "quoted-printable", _qp_init, _qp_decode, _qp_encode}, | 76 | { "base64", _base64_init, _base64_decode, _base64_encode}, |
77 | { "7bit", NULL}, | 77 | { "quoted-printable", _qp_init, _qp_decode, _qp_encode}, |
78 | { "8bit", NULL}, | 78 | { "7bit", NULL, NULL, NULL}, |
79 | { "binary", NULL} | 79 | { "8bit", NULL, NULL, NULL}, |
80 | }; | 80 | { "binary", NULL, NULL, NULL} |
81 | 81 | }; | |
82 | static void | 82 | |
83 | static void | ||
83 | _trans_destroy(stream_t stream) | 84 | _trans_destroy(stream_t stream) |
84 | { | 85 | { |
85 | struct _trans_stream *ts = stream_get_owner(stream); | 86 | struct _trans_stream *ts = stream_get_owner(stream); |
... | @@ -88,13 +89,13 @@ _trans_destroy(stream_t stream) | ... | @@ -88,13 +89,13 @@ _trans_destroy(stream_t stream) |
88 | free(ts); | 89 | free(ts); |
89 | } | 90 | } |
90 | 91 | ||
91 | static int | 92 | static int |
92 | _trans_read(stream_t stream, char *optr, size_t osize, off_t offset, size_t *nbytes) | 93 | _trans_read(stream_t stream, char *optr, size_t osize, off_t offset, size_t *nbytes) |
93 | { | 94 | { |
94 | struct _trans_stream *ts = stream_get_owner(stream); | 95 | struct _trans_stream *ts = stream_get_owner(stream); |
95 | size_t obytes, wbytes; | 96 | size_t obytes, wbytes; |
96 | int ret = 0, i; | 97 | int ret = 0, i; |
97 | 98 | ||
98 | if ( nbytes == NULL || optr == NULL || osize == 0 ) | 99 | if ( nbytes == NULL || optr == NULL || osize == 0 ) |
99 | return EINVAL; | 100 | return EINVAL; |
100 | 101 | ||
... | @@ -107,7 +108,7 @@ _trans_read(stream_t stream, char *optr, size_t osize, off_t offset, size_t *nby | ... | @@ -107,7 +108,7 @@ _trans_read(stream_t stream, char *optr, size_t osize, off_t offset, size_t *nby |
107 | 108 | ||
108 | if ( offset == 0 ) | 109 | if ( offset == 0 ) |
109 | ts->s_offset = ts->t_offset = ts->w_whd = ts->w_rhd = ts->offset = ts->line_len = 0; | 110 | ts->s_offset = ts->t_offset = ts->w_whd = ts->w_rhd = ts->offset = ts->line_len = 0; |
110 | 111 | ||
111 | while ( *nbytes < osize ) { | 112 | while ( *nbytes < osize ) { |
112 | if ( ( ts->w_rhd + ts->min_size ) >= ts->w_whd ) { | 113 | if ( ( ts->w_rhd + ts->min_size ) >= ts->w_whd ) { |
113 | memmove(ts->w_buf, ts->w_buf + ts->w_rhd, ts->w_whd - ts->w_rhd); | 114 | memmove(ts->w_buf, ts->w_buf + ts->w_rhd, ts->w_whd - ts->w_rhd); |
... | @@ -149,11 +150,10 @@ _trans_read(stream_t stream, char *optr, size_t osize, off_t offset, size_t *nby | ... | @@ -149,11 +150,10 @@ _trans_read(stream_t stream, char *optr, size_t osize, off_t offset, size_t *nby |
149 | } | 150 | } |
150 | 151 | ||
151 | 152 | ||
152 | static int | 153 | static int |
153 | _trans_write(stream_t stream, const char *iptr, size_t isize, off_t offset, size_t *nbytes) | 154 | _trans_write(stream_t stream, const char *iptr, size_t isize, off_t offset, size_t *nbytes) |
154 | { | 155 | { |
155 | struct _trans_stream *ts = stream_get_owner(stream); | 156 | struct _trans_stream *ts = stream_get_owner(stream); |
156 | int ret = 0; | ||
157 | 157 | ||
158 | if ( nbytes == NULL || iptr == NULL || isize == 0 ) | 158 | if ( nbytes == NULL || iptr == NULL || isize == 0 ) |
159 | return EINVAL; | 159 | return EINVAL; |
... | @@ -171,7 +171,7 @@ _trans_write(stream_t stream, const char *iptr, size_t isize, off_t offset, size | ... | @@ -171,7 +171,7 @@ _trans_write(stream_t stream, const char *iptr, size_t isize, off_t offset, size |
171 | return EINVAL; | 171 | return EINVAL; |
172 | } | 172 | } |
173 | 173 | ||
174 | static int | 174 | static int |
175 | _trans_open (stream_t stream, const char *filename, int port, int flags) | 175 | _trans_open (stream_t stream, const char *filename, int port, int flags) |
176 | { | 176 | { |
177 | struct _trans_stream *ts = stream_get_owner(stream); | 177 | struct _trans_stream *ts = stream_get_owner(stream); |
... | @@ -179,7 +179,7 @@ _trans_open (stream_t stream, const char *filename, int port, int flags) | ... | @@ -179,7 +179,7 @@ _trans_open (stream_t stream, const char *filename, int port, int flags) |
179 | return stream_open(ts->stream, filename, port, flags); | 179 | return stream_open(ts->stream, filename, port, flags); |
180 | } | 180 | } |
181 | 181 | ||
182 | static int | 182 | static int |
183 | _trans_truncate (stream_t stream, off_t len) | 183 | _trans_truncate (stream_t stream, off_t len) |
184 | { | 184 | { |
185 | struct _trans_stream *ts = stream_get_owner(stream); | 185 | struct _trans_stream *ts = stream_get_owner(stream); |
... | @@ -187,22 +187,22 @@ _trans_truncate (stream_t stream, off_t len) | ... | @@ -187,22 +187,22 @@ _trans_truncate (stream_t stream, off_t len) |
187 | return stream_truncate(ts->stream, len); | 187 | return stream_truncate(ts->stream, len); |
188 | } | 188 | } |
189 | 189 | ||
190 | static int | 190 | static int |
191 | _trans_size (stream_t stream, off_t *psize) | 191 | _trans_size (stream_t stream, off_t *psize) |
192 | { | 192 | { |
193 | struct _trans_stream *ts = stream_get_owner(stream); | 193 | struct _trans_stream *ts = stream_get_owner(stream); |
194 | 194 | ||
195 | return stream_size(ts->stream, psize); | 195 | return stream_size(ts->stream, psize); |
196 | } | 196 | } |
197 | 197 | ||
198 | static int | 198 | static int |
199 | _trans_flush (stream_t stream) | 199 | _trans_flush (stream_t stream) |
200 | { | 200 | { |
201 | struct _trans_stream *ts = stream_get_owner(stream); | 201 | struct _trans_stream *ts = stream_get_owner(stream); |
202 | 202 | ||
203 | return stream_flush(ts->stream); | 203 | return stream_flush(ts->stream); |
204 | } | 204 | } |
205 | static int | 205 | static int |
206 | _trans_get_fd (stream_t stream, int *pfd) | 206 | _trans_get_fd (stream_t stream, int *pfd) |
207 | { | 207 | { |
208 | struct _trans_stream *ts = stream_get_owner(stream); | 208 | struct _trans_stream *ts = stream_get_owner(stream); |
... | @@ -210,7 +210,7 @@ _trans_get_fd (stream_t stream, int *pfd) | ... | @@ -210,7 +210,7 @@ _trans_get_fd (stream_t stream, int *pfd) |
210 | return stream_get_fd(ts->stream, pfd); | 210 | return stream_get_fd(ts->stream, pfd); |
211 | } | 211 | } |
212 | 212 | ||
213 | static int | 213 | static int |
214 | _trans_close (stream_t stream) | 214 | _trans_close (stream_t stream) |
215 | { | 215 | { |
216 | struct _trans_stream *ts = stream_get_owner(stream); | 216 | struct _trans_stream *ts = stream_get_owner(stream); |
... | @@ -222,7 +222,7 @@ _trans_close (stream_t stream) | ... | @@ -222,7 +222,7 @@ _trans_close (stream_t stream) |
222 | * base64 encode/decode | 222 | * base64 encode/decode |
223 | *----------------------------------------------------*/ | 223 | *----------------------------------------------------*/ |
224 | 224 | ||
225 | static int | 225 | static int |
226 | _b64_input(char c) | 226 | _b64_input(char c) |
227 | { | 227 | { |
228 | const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 228 | const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
... | @@ -235,7 +235,7 @@ _b64_input(char c) | ... | @@ -235,7 +235,7 @@ _b64_input(char c) |
235 | return -1; | 235 | return -1; |
236 | } | 236 | } |
237 | 237 | ||
238 | static int | 238 | static int |
239 | _base64_init(struct _trans_stream *ts, int type) | 239 | _base64_init(struct _trans_stream *ts, int type) |
240 | { | 240 | { |
241 | ts->min_size = 4; | 241 | ts->min_size = 4; |
... | @@ -244,7 +244,7 @@ _base64_init(struct _trans_stream *ts, int type) | ... | @@ -244,7 +244,7 @@ _base64_init(struct _trans_stream *ts, int type) |
244 | return 0; | 244 | return 0; |
245 | } | 245 | } |
246 | 246 | ||
247 | static int | 247 | static int |
248 | _base64_decode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nbytes, int *line_len) | 248 | _base64_decode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nbytes, int *line_len) |
249 | { | 249 | { |
250 | int i = 0, tmp = 0, pad = 0; | 250 | int i = 0, tmp = 0, pad = 0; |
... | @@ -281,13 +281,13 @@ _base64_decode(const char *iptr, size_t isize, char *optr, size_t osize, size_t | ... | @@ -281,13 +281,13 @@ _base64_decode(const char *iptr, size_t isize, char *optr, size_t osize, size_t |
281 | } | 281 | } |
282 | 282 | ||
283 | #define BASE64_LINE_MAX 77 | 283 | #define BASE64_LINE_MAX 77 |
284 | static int | 284 | static int |
285 | _base64_encode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nbytes, int *line_len) | 285 | _base64_encode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nbytes, int *line_len) |
286 | { | 286 | { |
287 | size_t consumed = 0; | 287 | size_t consumed = 0; |
288 | int pad = 0; | 288 | int pad = 0; |
289 | const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 289 | const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
290 | 290 | ||
291 | *nbytes = 0; | 291 | *nbytes = 0; |
292 | if ( isize <= 3 ) | 292 | if ( isize <= 3 ) |
293 | pad = 1; | 293 | pad = 1; |
... | @@ -317,7 +317,7 @@ _base64_encode(const char *iptr, size_t isize, char *optr, size_t osize, size_t | ... | @@ -317,7 +317,7 @@ _base64_encode(const char *iptr, size_t isize, char *optr, size_t osize, size_t |
317 | *------------------------------------------------------*/ | 317 | *------------------------------------------------------*/ |
318 | static const char _hexdigits[16] = "0123456789ABCDEF"; | 318 | static const char _hexdigits[16] = "0123456789ABCDEF"; |
319 | 319 | ||
320 | static int | 320 | static int |
321 | _qp_init(struct _trans_stream *ts, int type) | 321 | _qp_init(struct _trans_stream *ts, int type) |
322 | { | 322 | { |
323 | ts->min_size = 4; | 323 | ts->min_size = 4; |
... | @@ -326,7 +326,8 @@ _qp_init(struct _trans_stream *ts, int type) | ... | @@ -326,7 +326,8 @@ _qp_init(struct _trans_stream *ts, int type) |
326 | return 0; | 326 | return 0; |
327 | } | 327 | } |
328 | 328 | ||
329 | static int | 329 | #if 0 |
330 | static int | ||
330 | _ishex(int c) | 331 | _ishex(int c) |
331 | { | 332 | { |
332 | int i; | 333 | int i; |
... | @@ -340,8 +341,9 @@ _ishex(int c) | ... | @@ -340,8 +341,9 @@ _ishex(int c) |
340 | 341 | ||
341 | return 0; | 342 | return 0; |
342 | } | 343 | } |
344 | #endif | ||
343 | 345 | ||
344 | static int | 346 | static int |
345 | _qp_decode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nbytes, int *line_len) | 347 | _qp_decode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nbytes, int *line_len) |
346 | { | 348 | { |
347 | char c; | 349 | char c; |
... | @@ -403,7 +405,7 @@ _qp_decode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nby | ... | @@ -403,7 +405,7 @@ _qp_decode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nby |
403 | } | 405 | } |
404 | 406 | ||
405 | 407 | ||
406 | static int | 408 | static int |
407 | _qp_encode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nbytes, int *line_len) | 409 | _qp_encode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nbytes, int *line_len) |
408 | { | 410 | { |
409 | #define QP_LINE_MAX 76 | 411 | #define QP_LINE_MAX 76 |
... | @@ -449,7 +451,7 @@ _qp_encode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nby | ... | @@ -449,7 +451,7 @@ _qp_encode(const char *iptr, size_t isize, char *optr, size_t osize, size_t *nby |
449 | return consumed; | 451 | return consumed; |
450 | } | 452 | } |
451 | 453 | ||
452 | int | 454 | int |
453 | encoder_stream_create(stream_t *stream, stream_t iostream, const char *encoding) | 455 | encoder_stream_create(stream_t *stream, stream_t iostream, const char *encoding) |
454 | { | 456 | { |
455 | struct _trans_stream *ts; | 457 | struct _trans_stream *ts; |
... | @@ -479,7 +481,7 @@ encoder_stream_create(stream_t *stream, stream_t iostream, const char *encoding) | ... | @@ -479,7 +481,7 @@ encoder_stream_create(stream_t *stream, stream_t iostream, const char *encoding) |
479 | stream_set_flush(*stream, _trans_flush, ts ); | 481 | stream_set_flush(*stream, _trans_flush, ts ); |
480 | ts->stream = iostream; | 482 | ts->stream = iostream; |
481 | if ( tslist[i]._init != NULL && (ret = tslist[i]._init(ts, MU_TRANS_ENCODE)) != 0 ) | 483 | if ( tslist[i]._init != NULL && (ret = tslist[i]._init(ts, MU_TRANS_ENCODE)) != 0 ) |
482 | stream_destroy(stream, NULL); | 484 | stream_destroy(stream, NULL); |
483 | else { | 485 | else { |
484 | stream_set_read(*stream, _trans_read, ts ); | 486 | stream_set_read(*stream, _trans_read, ts ); |
485 | stream_set_write(*stream, _trans_write, ts ); | 487 | stream_set_write(*stream, _trans_write, ts ); |
... | @@ -488,7 +490,7 @@ encoder_stream_create(stream_t *stream, stream_t iostream, const char *encoding) | ... | @@ -488,7 +490,7 @@ encoder_stream_create(stream_t *stream, stream_t iostream, const char *encoding) |
488 | return ret; | 490 | return ret; |
489 | } | 491 | } |
490 | 492 | ||
491 | int | 493 | int |
492 | decoder_stream_create(stream_t *stream, stream_t iostream, const char *encoding) | 494 | decoder_stream_create(stream_t *stream, stream_t iostream, const char *encoding) |
493 | { | 495 | { |
494 | struct _trans_stream *ts; | 496 | struct _trans_stream *ts; |
... | @@ -519,7 +521,7 @@ decoder_stream_create(stream_t *stream, stream_t iostream, const char *encoding) | ... | @@ -519,7 +521,7 @@ decoder_stream_create(stream_t *stream, stream_t iostream, const char *encoding) |
519 | stream_set_flush(*stream, _trans_flush, ts ); | 521 | stream_set_flush(*stream, _trans_flush, ts ); |
520 | ts->stream = iostream; | 522 | ts->stream = iostream; |
521 | if ( tslist[i]._init != NULL && (ret = tslist[i]._init(ts, MU_TRANS_DECODE)) != 0 ) | 523 | if ( tslist[i]._init != NULL && (ret = tslist[i]._init(ts, MU_TRANS_DECODE)) != 0 ) |
522 | stream_destroy(stream, NULL); | 524 | stream_destroy(stream, NULL); |
523 | else { | 525 | else { |
524 | stream_set_read(*stream, _trans_read, ts ); | 526 | stream_set_read(*stream, _trans_read, ts ); |
525 | stream_set_write(*stream, _trans_write, ts ); | 527 | stream_set_write(*stream, _trans_write, ts ); | ... | ... |
-
Please register or sign in to post a comment