Commit d9044ffe d9044ffe99b447598e649b24f5ed49ccb110e15e by Sergey Poznyakoff

Bugfix

* libmailutils/base/amd.c: Add more debugging info.  Always check the
return from amd_pool_open and amd_check_message (which returns int now)
and act accordingly.
1 parent a8001bb2
...@@ -167,7 +167,7 @@ io_sendf (const char *format, ...) ...@@ -167,7 +167,7 @@ io_sendf (const char *format, ...)
167 } 167 }
168 168
169 /* Send NIL if empty string, change the quoted string to a literal if the 169 /* Send NIL if empty string, change the quoted string to a literal if the
170 string contains: double quotes, CR, LF, and '/'. CR, LF will be change 170 string contains: double quotes, CR, LF, and '/'. CR, LF will be changed
171 to spaces. */ 171 to spaces. */
172 int 172 int
173 io_send_qstring (const char *buffer) 173 io_send_qstring (const char *buffer)
......
...@@ -1458,53 +1458,69 @@ amd_scan_message (struct _amd_message *mhm) ...@@ -1458,53 +1458,69 @@ amd_scan_message (struct _amd_message *mhm)
1458 /* Check if the message was modified after the last scan */ 1458 /* Check if the message was modified after the last scan */
1459 status = mhm->amd->cur_msg_file_name (mhm, &msg_name); 1459 status = mhm->amd->cur_msg_file_name (mhm, &msg_name);
1460 if (status) 1460 if (status)
1461 return status; 1461 {
1462 1462 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
1463 ("amd_scan_message: cur_msg_file_name=%s",
1464 mu_strerror (status)));
1465 return status;
1466 }
1467
1463 if (stat (msg_name, &st) == 0 && st.st_mtime == mhm->mtime) 1468 if (stat (msg_name, &st) == 0 && st.st_mtime == mhm->mtime)
1464 { 1469 {
1465 /* Nothing to do */ 1470 /* Nothing to do */
1466 free (msg_name); 1471 free (msg_name);
1467 return 0; 1472 return 0;
1468 } 1473 }
1469 free (msg_name);
1470 1474
1471 off = 0; 1475 off = 0;
1472 status = mu_stream_seek (stream, 0, MU_SEEK_SET, NULL); 1476 status = mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
1473 if (status == 0) 1477 if (status)
1474 while ((status = mu_stream_readline (stream, buf, sizeof (buf), &n)) == 0 1478 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
1475 && n != 0) 1479 ("amd_scan_message(%s): mu_stream_seek=%s",
1476 { 1480 msg_name, mu_strerror (status)));
1477 if (in_header) 1481 else
1478 { 1482 {
1479 if (buf[0] == '\n') 1483 while ((status = mu_stream_readline (stream, buf, sizeof (buf), &n)) == 0
1480 { 1484 && n != 0)
1481 in_header = 0; 1485 {
1482 body_start = off + 1; 1486 if (in_header)
1483 } 1487 {
1484 if (buf[n - 1] == '\n') 1488 if (buf[0] == '\n')
1485 hlines++; 1489 {
1486 1490 in_header = 0;
1487 /* Process particular attributes */ 1491 body_start = off + 1;
1488 if (mu_c_strncasecmp (buf, "status:", 7) == 0) 1492 }
1489 { 1493 if (buf[n - 1] == '\n')
1490 int deleted = mhm->attr_flags & MU_ATTRIBUTE_DELETED; 1494 hlines++;
1491 mu_string_to_flags (buf, &mhm->attr_flags); 1495
1492 mhm->attr_flags |= deleted; 1496 /* Process particular attributes */
1493 } 1497 if (mu_c_strncasecmp (buf, "status:", 7) == 0)
1494 else if (mu_c_strncasecmp (buf, "x-imapbase:", 11) == 0) 1498 {
1495 { 1499 int deleted = mhm->attr_flags & MU_ATTRIBUTE_DELETED;
1496 char *p; 1500 mu_string_to_flags (buf, &mhm->attr_flags);
1497 mhm->amd->uidvalidity = strtoul (buf + 11, &p, 10); 1501 mhm->attr_flags |= deleted;
1498 /* second number is next uid. Ignored */ 1502 }
1499 } 1503 else if (mu_c_strncasecmp (buf, "x-imapbase:", 11) == 0)
1500 } 1504 {
1501 else 1505 char *p;
1502 { 1506 mhm->amd->uidvalidity = strtoul (buf + 11, &p, 10);
1503 if (buf[n - 1] == '\n') 1507 /* second number is next uid. Ignored */
1504 blines++; 1508 }
1505 } 1509 }
1506 off += n; 1510 else
1507 } 1511 {
1512 if (buf[n - 1] == '\n')
1513 blines++;
1514 }
1515 off += n;
1516 }
1517 if (status)
1518 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
1519 ("amd_scan_message(%s): %s",
1520 msg_name, mu_strerror (status)));
1521 }
1522
1523 free (msg_name);
1508 1524
1509 if (status == 0) 1525 if (status == 0)
1510 { 1526 {
...@@ -1606,14 +1622,19 @@ amd_pool_open (struct _amd_message *mhm) ...@@ -1606,14 +1622,19 @@ amd_pool_open (struct _amd_message *mhm)
1606 struct _amd_data *amd = mhm->amd; 1622 struct _amd_data *amd = mhm->amd;
1607 if (amd_pool_lookup (mhm)) 1623 if (amd_pool_lookup (mhm))
1608 return 0; 1624 return 0;
1609 if (amd_pool_open_count(amd) == MAX_OPEN_STREAMS-1) 1625 if (amd_pool_open_count (amd) == MAX_OPEN_STREAMS-1)
1610 { 1626 {
1611 amd_message_stream_close (amd->msg_pool[amd->pool_first++]); 1627 amd_message_stream_close (amd->msg_pool[amd->pool_first++]);
1612 amd->pool_first %= MAX_OPEN_STREAMS; 1628 amd->pool_first %= MAX_OPEN_STREAMS;
1613 } 1629 }
1614 status = amd_message_stream_open (mhm); 1630 status = amd_message_stream_open (mhm);
1615 if (status) 1631 if (status)
1616 return status; 1632 {
1633 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
1634 ("amd_pool_open: amd_message_stream_open=%s",
1635 mu_strerror (status)));
1636 return status;
1637 }
1617 amd->msg_pool[amd->pool_last++] = mhm; 1638 amd->msg_pool[amd->pool_last++] = mhm;
1618 amd->pool_last %= MAX_OPEN_STREAMS; 1639 amd->pool_last %= MAX_OPEN_STREAMS;
1619 return 0; 1640 return 0;
...@@ -1646,14 +1667,23 @@ amd_message_stream_open (struct _amd_message *mhm) ...@@ -1646,14 +1667,23 @@ amd_message_stream_open (struct _amd_message *mhm)
1646 1667
1647 status = amd->cur_msg_file_name (mhm, &filename); 1668 status = amd->cur_msg_file_name (mhm, &filename);
1648 if (status) 1669 if (status)
1649 return status; 1670 {
1650 1671 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
1672 ("amd_message_stream_open: cur_msg_file_name=%s",
1673 mu_strerror (status)));
1674 return status;
1675 }
1676
1651 /* The message should be at least readable */ 1677 /* The message should be at least readable */
1652 if (amd->mailbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND)) 1678 if (amd->mailbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))
1653 flags |= MU_STREAM_RDWR; 1679 flags |= MU_STREAM_RDWR;
1654 else 1680 else
1655 flags |= MU_STREAM_READ; 1681 flags |= MU_STREAM_READ;
1656 status = mu_file_stream_create (&mhm->stream, filename, flags); 1682 status = mu_file_stream_create (&mhm->stream, filename, flags);
1683 if (status)
1684 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
1685 ("amd_message_stream_open: mu_file_stream_create(%s)=%s",
1686 filename, mu_strerror (status)));
1657 1687
1658 free (filename); 1688 free (filename);
1659 1689
...@@ -1664,7 +1694,11 @@ amd_message_stream_open (struct _amd_message *mhm) ...@@ -1664,7 +1694,11 @@ amd_message_stream_open (struct _amd_message *mhm)
1664 mu_stream_set_buffer (mhm->stream, mu_buffer_full, 16384); 1694 mu_stream_set_buffer (mhm->stream, mu_buffer_full, 16384);
1665 1695
1666 status = amd_scan_message (mhm); 1696 status = amd_scan_message (mhm);
1667 1697 if (status)
1698 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
1699 ("amd_message_stream_open: amd_scan_message=%s",
1700 mu_strerror (status)));
1701
1668 return status; 1702 return status;
1669 } 1703 }
1670 1704
...@@ -1679,11 +1713,12 @@ amd_message_stream_close (struct _amd_message *mhm) ...@@ -1679,11 +1713,12 @@ amd_message_stream_close (struct _amd_message *mhm)
1679 } 1713 }
1680 } 1714 }
1681 1715
1682 void 1716 int
1683 amd_check_message (struct _amd_message *mhm) 1717 amd_check_message (struct _amd_message *mhm)
1684 { 1718 {
1685 if (mhm->body_end == 0) 1719 if (mhm->body_end == 0)
1686 amd_pool_open (mhm); 1720 return amd_pool_open (mhm);
1721 return 0;
1687 } 1722 }
1688 1723
1689 /* Reading functions */ 1724 /* Reading functions */
...@@ -1699,7 +1734,9 @@ amd_body_stream_read (mu_stream_t is, char *buffer, size_t buflen, ...@@ -1699,7 +1734,9 @@ amd_body_stream_read (mu_stream_t is, char *buffer, size_t buflen,
1699 int status = 0; 1734 int status = 0;
1700 mu_off_t ln; 1735 mu_off_t ln;
1701 1736
1702 amd_pool_open (mhm); 1737 status = amd_pool_open (mhm);
1738 if (status)
1739 return status;
1703 1740
1704 if (buffer == NULL || buflen == 0) 1741 if (buffer == NULL || buflen == 0)
1705 { 1742 {
...@@ -1748,7 +1785,9 @@ amd_body_stream_readdelim (mu_stream_t is, char *buffer, size_t buflen, ...@@ -1748,7 +1785,9 @@ amd_body_stream_readdelim (mu_stream_t is, char *buffer, size_t buflen,
1748 struct _amd_message *mhm = mu_message_get_owner (msg); 1785 struct _amd_message *mhm = mu_message_get_owner (msg);
1749 int status = 0; 1786 int status = 0;
1750 1787
1751 amd_pool_open (mhm); 1788 status = amd_pool_open (mhm);
1789 if (status)
1790 return status;
1752 1791
1753 if (buffer == NULL || buflen == 0) 1792 if (buffer == NULL || buflen == 0)
1754 { 1793 {
...@@ -1825,11 +1864,14 @@ amd_body_stream_size (mu_stream_t stream, mu_off_t *psize) ...@@ -1825,11 +1864,14 @@ amd_body_stream_size (mu_stream_t stream, mu_off_t *psize)
1825 static int 1864 static int
1826 amd_body_size (mu_body_t body, size_t *psize) 1865 amd_body_size (mu_body_t body, size_t *psize)
1827 { 1866 {
1867 int status;
1828 mu_message_t msg = mu_body_get_owner (body); 1868 mu_message_t msg = mu_body_get_owner (body);
1829 struct _amd_message *mhm = mu_message_get_owner (msg); 1869 struct _amd_message *mhm = mu_message_get_owner (msg);
1830 if (mhm == NULL) 1870 if (mhm == NULL)
1831 return EINVAL; 1871 return EINVAL;
1832 amd_check_message (mhm); 1872 status = amd_check_message (mhm);
1873 if (status)
1874 return status;
1833 if (psize) 1875 if (psize)
1834 *psize = mhm->body_end - mhm->body_start; 1876 *psize = mhm->body_end - mhm->body_start;
1835 return 0; 1877 return 0;
...@@ -1838,11 +1880,14 @@ amd_body_size (mu_body_t body, size_t *psize) ...@@ -1838,11 +1880,14 @@ amd_body_size (mu_body_t body, size_t *psize)
1838 static int 1880 static int
1839 amd_body_lines (mu_body_t body, size_t *plines) 1881 amd_body_lines (mu_body_t body, size_t *plines)
1840 { 1882 {
1883 int status;
1841 mu_message_t msg = mu_body_get_owner (body); 1884 mu_message_t msg = mu_body_get_owner (body);
1842 struct _amd_message *mhm = mu_message_get_owner (msg); 1885 struct _amd_message *mhm = mu_message_get_owner (msg);
1843 if (mhm == NULL) 1886 if (mhm == NULL)
1844 return EINVAL; 1887 return EINVAL;
1845 amd_check_message (mhm); 1888 status = amd_check_message (mhm);
1889 if (status)
1890 return status;
1846 if (plines) 1891 if (plines)
1847 *plines = mhm->body_lines; 1892 *plines = mhm->body_lines;
1848 return 0; 1893 return 0;
......