~ubuntu-branches/ubuntu/saucy/evolution-data-server/saucy

« back to all changes in this revision

Viewing changes to camel/providers/imap/camel-imap-folder.c

  • Committer: Package Import Robot
  • Author(s): Chris Coulson
  • Date: 2012-10-08 12:58:16 UTC
  • mfrom: (181.1.7 quantal)
  • Revision ID: package-import@ubuntu.com-20121008125816-i3n76e8c0m64e7xp
Tags: 3.6.0-0ubuntu2
* Fix LP: #1038047 part 1 - Don't abort in e_source_registry_new* when a
  problem occurs connecting to the Dbus service
  - add debian/patches/dont-abort-in-e_source_registry_new.patch
  - update debian/patches/series
* Fix LP: #1038047 part 2 - libedataserver depends on
  evolution-data-server-common to ensure that the GSettings schemas are
  present
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
86
86
static gchar * imap_get_filename (CamelFolder *folder, const gchar *uid, GError **error);
87
87
 
88
88
/* message manipulation */
 
89
static CamelMimeMessage *imap_get_message_cached (CamelFolder *folder, const gchar *message_uid, GCancellable *cancellable);
89
90
static CamelMimeMessage *imap_get_message_sync (CamelFolder *folder, const gchar *uid, GCancellable *cancellable,
90
91
                                           GError **error);
91
92
static gboolean imap_synchronize_message_sync (CamelFolder *folder, const gchar *uid, GCancellable *cancellable,
158
159
        g_return_if_fail (folder != NULL);
159
160
        g_return_if_fail (CAMEL_IS_IMAP_FOLDER (folder));
160
161
 
161
 
        if ((folder->priv->apply_filters ? 1 : 0) == (apply_filters ? 1 : 0))
 
162
        if (folder->priv->apply_filters == apply_filters)
162
163
                return;
163
164
 
164
165
        folder->priv->apply_filters = apply_filters;
285
286
        CamelFolder *folder;
286
287
        CamelStore *parent_store;
287
288
        const gchar *full_name;
288
 
        const gchar *host;
289
 
        const gchar *user;
290
289
        gchar *description;
 
290
        gchar *host;
 
291
        gchar *user;
291
292
 
292
293
        folder = CAMEL_FOLDER (object);
293
294
        full_name = camel_folder_get_full_name (folder);
294
295
        parent_store = camel_folder_get_parent_store (folder);
295
296
 
296
297
        service = CAMEL_SERVICE (parent_store);
297
 
        settings = camel_service_get_settings (service);
 
298
 
 
299
        settings = camel_service_ref_settings (service);
298
300
 
299
301
        network_settings = CAMEL_NETWORK_SETTINGS (settings);
300
 
        host = camel_network_settings_get_host (network_settings);
301
 
        user = camel_network_settings_get_user (network_settings);
 
302
        host = camel_network_settings_dup_host (network_settings);
 
303
        user = camel_network_settings_dup_user (network_settings);
 
304
 
 
305
        g_object_unref (settings);
302
306
 
303
307
        description = g_strdup_printf (
304
308
                "%s@%s:%s", user, host, full_name);
305
309
        camel_folder_set_description (folder, description);
306
310
        g_free (description);
 
311
 
 
312
        g_free (host);
 
313
        g_free (user);
307
314
}
308
315
 
309
316
static void
332
339
        folder_class->get_filename = imap_get_filename;
333
340
        folder_class->append_message_sync = imap_append_online;
334
341
        folder_class->expunge_sync = imap_expunge_sync;
 
342
        folder_class->get_message_cached = imap_get_message_cached;
335
343
        folder_class->get_message_sync = imap_get_message_sync;
336
344
        folder_class->get_quota_info_sync = imap_get_quota_info_sync;
337
345
        folder_class->refresh_info_sync = imap_refresh_info_sync;
479
487
        }
480
488
 
481
489
        service = CAMEL_SERVICE (parent);
482
 
        settings = camel_service_get_settings (service);
 
490
        settings = camel_service_ref_settings (service);
483
491
 
484
492
        g_object_get (
485
493
                settings,
539
547
                g_free (trash_path);
540
548
        }
541
549
 
 
550
        g_object_unref (settings);
 
551
 
542
552
        imap_folder->search = camel_imap_search_new (folder_dir);
543
553
 
544
554
        camel_store_summary_connect_folder_summary (
566
576
 
567
577
        g_return_if_fail (CAMEL_IS_IMAP_FOLDER (imap_folder));
568
578
 
569
 
        if ((imap_folder->priv->check_folder ? 1 : 0) == (check_folder ? 1 : 0))
 
579
        if (imap_folder->priv->check_folder == check_folder)
570
580
                return;
571
581
 
572
582
        imap_folder->priv->check_folder = check_folder;
1136
1146
                return TRUE;
1137
1147
        }
1138
1148
 
 
1149
        if (!camel_imap_store_connected (CAMEL_IMAP_STORE (parent_store), error)) {
 
1150
                camel_operation_pop_message (cancellable);
 
1151
                camel_folder_summary_free_array (known_uids);
 
1152
                return FALSE;
 
1153
        }
 
1154
 
1139
1155
        ok = camel_imap_command_start (
1140
1156
                store, folder, cancellable, error,
1141
1157
                "UID FETCH 1:%s (FLAGS)", uid);
1223
1239
 
1224
1240
                info = camel_folder_summary_get (folder->summary, uid);
1225
1241
                if (!info) {
1226
 
                        if (g_getenv("CRASH_IMAP")) { /* Debug logs to tackle on hard to get imap crasher */
1227
 
                                printf ("CRASH: %s: %s",
 
1242
                        if (g_getenv ("CRASH_IMAP")) { /* Debug logs to tackle on hard to get imap crasher */
 
1243
                                printf (
 
1244
                                        "CRASH: %s: %s",
1228
1245
                                        camel_folder_get_full_name (folder), uid);
1229
1246
                                g_assert (0);
1230
1247
                        } else
1438
1455
 
1439
1456
                        if (count1 != count2) {
1440
1457
                                g_list_free (list2);
 
1458
                                camel_message_info_free ((CamelMessageInfo *) info);
1441
1459
                                close_range ();
1442
1460
                                continue;
1443
1461
                        }
1449
1467
 
1450
1468
                        if (cmp) {
1451
1469
                                g_list_free (list2);
 
1470
                                camel_message_info_free ((CamelMessageInfo *) info);
1452
1471
                                close_range ();
1453
1472
                                continue;
1454
1473
                        }
1560
1579
        g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
1561
1580
 
1562
1581
        service = CAMEL_SERVICE (store);
1563
 
        settings = camel_service_get_settings (service);
 
1582
 
 
1583
        settings = camel_service_ref_settings (service);
1564
1584
 
1565
1585
        network_settings = CAMEL_NETWORK_SETTINGS (settings);
1566
1586
        host = camel_network_settings_dup_host (network_settings);
1567
1587
 
 
1588
        g_object_unref (settings);
 
1589
 
1568
1590
        is_google =
1569
1591
                (host != NULL) && (
1570
1592
                host_ends_with (host, "gmail.com") ||
1627
1649
        is_gmail = is_google_account (parent_store);
1628
1650
 
1629
1651
        service = CAMEL_SERVICE (parent_store);
1630
 
        settings = camel_service_get_settings (service);
1631
1652
 
1632
1653
        if (folder->permanent_flags == 0 || !camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store))) {
1633
1654
                if (expunge) {
1648
1669
        camel_folder_sort_uids (folder, summary);
1649
1670
        max = summary->len;
1650
1671
 
 
1672
        settings = camel_service_ref_settings (service);
 
1673
 
1651
1674
        /* deleted_uids is NULL when not using real trash */
1652
1675
        folder_path = camel_imap_settings_dup_real_trash_path (
1653
1676
                CAMEL_IMAP_SETTINGS (settings));
1654
 
        if (folder_path != NULL) {
 
1677
        if (folder_path != NULL && *folder_path) {
1655
1678
                if ((folder->folder_flags & CAMEL_FOLDER_IS_TRASH) != 0) {
1656
1679
                        /* syncing the trash, expunge deleted when found any */
1657
1680
                        real_trash = g_object_ref (folder);
1658
1681
                } else {
1659
1682
                        real_trash = camel_store_get_trash_folder_sync (
1660
1683
                                parent_store, cancellable, NULL);
1661
 
 
1662
 
                        if (folder_path == NULL && real_trash) {
1663
 
                                /* failed to open real trash */
1664
 
                                g_object_unref (real_trash);
1665
 
                                real_trash = NULL;
1666
 
                        }
1667
1684
                }
1668
1685
        }
1669
1686
        g_free (folder_path);
1670
1687
 
1671
 
        if (real_trash)
1672
 
                deleted_uids = g_ptr_array_new ();
1673
 
 
1674
1688
        /* junked_uids is NULL when not using real junk */
1675
1689
        folder_path = camel_imap_settings_dup_real_junk_path (
1676
1690
                CAMEL_IMAP_SETTINGS (settings));
1677
 
        if (folder_path != NULL) {
 
1691
        if (folder_path != NULL && *folder_path) {
1678
1692
                if ((folder->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0) {
1679
1693
                        /* syncing the junk, but cannot move
1680
1694
                         * messages to itself, thus do nothing */
1682
1696
                } else {
1683
1697
                        real_junk = camel_store_get_junk_folder_sync (
1684
1698
                                parent_store, cancellable, NULL);
1685
 
 
1686
 
                        if (folder_path == NULL && real_junk) {
1687
 
                                /* failed to open real junk */
1688
 
                                g_object_unref (real_junk);
1689
 
                                real_junk = NULL;
1690
 
                        }
1691
1699
                }
1692
1700
        }
1693
1701
        g_free (folder_path);
1694
1702
 
 
1703
        g_object_unref (settings);
 
1704
 
 
1705
        if (real_trash)
 
1706
                deleted_uids = g_ptr_array_new ();
 
1707
 
1695
1708
        if (real_junk)
1696
1709
                junked_uids = g_ptr_array_new ();
1697
1710
 
1718
1731
                 * loop here to flush all the matching uids because
1719
1732
                 * they will be scooped up later by our parent loop (I
1720
1733
                 * think?). -- Jeff */
1721
 
                matches = get_matching (folder, info->info.flags & (folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED),
1722
 
                                        folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED, (CamelMessageInfo *) info, &set, summary,
1723
 
                                        deleted_uids, junked_uids);
 
1734
                matches = get_matching (
 
1735
                        folder, info->info.flags &
 
1736
                        (folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED),
 
1737
                        folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED,
 
1738
                        (CamelMessageInfo *) info, &set, summary,
 
1739
                        deleted_uids, junked_uids);
1724
1740
                if (matches == NULL) {
1725
1741
                        camel_message_info_free (info);
1726
1742
                        continue;
1730
1746
                if (!camel_imap_store_connected (store, NULL)) {
1731
1747
                        g_free (set);
1732
1748
                        camel_message_info_free (info);
 
1749
                        g_ptr_array_foreach (matches, (GFunc) camel_message_info_free, NULL);
 
1750
                        g_ptr_array_free (matches, TRUE);
1733
1751
                        break;
1734
1752
                }
1735
1753
 
1756
1774
                                g_free (flaglist);
1757
1775
                                flaglist = strdup ("(\\Seen)");
1758
1776
 
1759
 
                                response = camel_imap_command (store, folder, cancellable, &local_error,
1760
 
                                                "UID STORE %s +FLAGS.SILENT %s",
1761
 
                                                set, flaglist);
 
1777
                                response = camel_imap_command (
 
1778
                                        store, folder,
 
1779
                                        cancellable, &local_error,
 
1780
                                        "UID STORE %s +FLAGS.SILENT %s",
 
1781
                                        set, flaglist);
1762
1782
                                if (response)
1763
1783
                                        camel_imap_response_free (store, response);
1764
1784
 
1771
1791
 
1772
1792
                /* Note: to 'unset' flags, use -FLAGS.SILENT (<flag list>) */
1773
1793
                if (local_error == NULL) {
1774
 
                        response = camel_imap_command (store, folder, cancellable, &local_error,
1775
 
                                               "UID STORE %s %sFLAGS.SILENT %s",
1776
 
                                               set, unset ? "-" : "", flaglist);
 
1794
                        response = camel_imap_command (
 
1795
                                store, folder, cancellable, &local_error,
 
1796
                                "UID STORE %s %sFLAGS.SILENT %s",
 
1797
                                set, unset ? "-" : "", flaglist);
1777
1798
                }
1778
1799
 
1779
1800
                g_free (set);
1799
1820
                        camel_folder_summary_touch (folder->summary);
1800
1821
                }
1801
1822
 
1802
 
                for (j = 0; j < matches->len; j++) {
1803
 
                        info = matches->pdata[j];
1804
 
                        camel_message_info_free (&info->info);
1805
 
                }
 
1823
                g_ptr_array_foreach (matches, (GFunc) camel_message_info_free, NULL);
1806
1824
                g_ptr_array_free (matches, TRUE);
1807
1825
 
1808
1826
                /* check for an exception */
1820
1838
                                g_object_unref (real_trash);
1821
1839
                        if (real_junk)
1822
1840
                                g_object_unref (real_junk);
 
1841
 
 
1842
                        g_ptr_array_foreach (summary, (GFunc) camel_pstring_free, NULL);
 
1843
                        g_ptr_array_free (summary, TRUE);
 
1844
 
1823
1845
                        return FALSE;
1824
1846
                }
1825
1847
        }
1896
1918
        changes = camel_folder_change_info_new ();
1897
1919
 
1898
1920
        for (i = 0; i < uids->len; i++) {
1899
 
                camel_folder_summary_remove_uid (folder->summary, uids->pdata[i]);
 
1921
                CamelMessageInfo *mi = camel_folder_summary_peek_loaded (folder->summary, uids->pdata[i]);
 
1922
 
 
1923
                if (mi) {
 
1924
                        camel_folder_summary_remove (folder->summary, mi);
 
1925
                        camel_message_info_free (mi);
 
1926
                } else {
 
1927
                        camel_folder_summary_remove_uid (folder->summary, uids->pdata[i]);
 
1928
                }
 
1929
 
1900
1930
                camel_folder_change_info_remove_uid (changes, uids->pdata[i]);
1901
1931
                list = g_list_prepend (list, (gpointer) uids->pdata[i]);
1902
1932
                /* We intentionally don't remove it from the cache because
1908
1938
        g_list_free (list);
1909
1939
        camel_folder_summary_save_to_db (folder->summary, NULL);
1910
1940
 
1911
 
        camel_imap_journal_log (CAMEL_IMAP_FOLDER (folder)->journal,
1912
 
                               CAMEL_IMAP_JOURNAL_ENTRY_EXPUNGE, uids);
 
1941
        camel_imap_journal_log (
 
1942
                CAMEL_IMAP_FOLDER (folder)->journal,
 
1943
                CAMEL_IMAP_JOURNAL_ENTRY_EXPUNGE, uids);
1913
1944
 
1914
1945
        camel_folder_changed (folder, changes);
1915
1946
        camel_folder_change_info_free (changes);
1940
1971
        store = CAMEL_IMAP_STORE (parent_store);
1941
1972
        full_expunge = (store->capabilities & IMAP_CAPABILITY_UIDPLUS) == 0;
1942
1973
 
 
1974
        if (!camel_imap_store_connected (store, error))
 
1975
                return FALSE;
 
1976
 
1943
1977
        if ((store->capabilities & IMAP_CAPABILITY_UIDPLUS) == 0) {
1944
1978
                if (!CAMEL_FOLDER_GET_CLASS (folder)->synchronize_sync (
1945
1979
                        folder, 0, cancellable, error)) {
1951
1985
 
1952
1986
        while (uid < uids->len) {
1953
1987
                set = imap_uid_array_to_set (folder->summary, uids, uid, UID_SET_LIMIT, &uid);
1954
 
                response = camel_imap_command (store, folder, cancellable, error,
1955
 
                                               "UID STORE %s +FLAGS.SILENT (\\Deleted)",
1956
 
                                               set);
 
1988
                response = camel_imap_command (
 
1989
                        store, folder, cancellable, error,
 
1990
                        "UID STORE %s +FLAGS.SILENT (\\Deleted)", set);
1957
1991
                if (response)
1958
1992
                        camel_imap_response_free (store, response);
1959
1993
                else {
1991
2025
 
1992
2026
        changes = camel_folder_change_info_new ();
1993
2027
        for (i = 0; i < uids->len; i++) {
1994
 
                camel_folder_summary_remove_uid (folder->summary, uids->pdata[i]);
 
2028
                CamelMessageInfo *mi = camel_folder_summary_peek_loaded (folder->summary, uids->pdata[i]);
 
2029
 
 
2030
                if (mi) {
 
2031
                        camel_folder_summary_remove (folder->summary, mi);
 
2032
                        camel_message_info_free (mi);
 
2033
                } else {
 
2034
                        camel_folder_summary_remove_uid (folder->summary, uids->pdata[i]);
 
2035
                }
 
2036
 
1995
2037
                camel_folder_change_info_remove_uid (changes, uids->pdata[i]);
1996
2038
                list = g_list_prepend (list, (gpointer) uids->pdata[i]);
1997
2039
                /* We intentionally don't remove it from the cache because
2082
2124
        if (imap_folder->read_only)
2083
2125
                return TRUE;
2084
2126
 
 
2127
        if (!camel_imap_store_connected (store, error))
 
2128
                return FALSE;
 
2129
 
2085
2130
        if (store->capabilities & IMAP_CAPABILITY_UIDPLUS)
2086
2131
                return imap_expunge_uids_online (
2087
2132
                        folder, uids, cancellable, error);
2115
2160
                /* Parse SEARCH response */
2116
2161
                for (uid = strtok_r (result + 9, " ", &lasts); uid; uid = strtok_r (NULL, " ", &lasts))
2117
2162
                        g_ptr_array_add (keep_uids, uid);
2118
 
                qsort (keep_uids->pdata, keep_uids->len,
2119
 
                       sizeof (gpointer), uid_compar);
 
2163
                qsort (
 
2164
                        keep_uids->pdata, keep_uids->len,
 
2165
                        sizeof (gpointer), uid_compar);
2120
2166
 
2121
2167
                /* Fill in "mark_uids", empty out "keep_uids" as needed */
2122
2168
                for (ei = ki = 0; ei < uids->len; ei++) {
2152
2198
                while (uid < keep_uids->len) {
2153
2199
                        uidset = imap_uid_array_to_set (folder->summary, keep_uids, uid, UID_SET_LIMIT, &uid);
2154
2200
 
2155
 
                        response = camel_imap_command (store, folder, cancellable, error,
2156
 
                                                       "UID STORE %s -FLAGS.SILENT (\\Deleted)",
2157
 
                                                       uidset);
 
2201
                        response = camel_imap_command (
 
2202
                                store, folder, cancellable, error,
 
2203
                                "UID STORE %s -FLAGS.SILENT (\\Deleted)",
 
2204
                                uidset);
2158
2205
 
2159
2206
                        g_free (uidset);
2160
2207
 
2175
2222
                while (uid < mark_uids->len) {
2176
2223
                        uidset = imap_uid_array_to_set (folder->summary, mark_uids, uid, UID_SET_LIMIT, &uid);
2177
2224
 
2178
 
                        response = camel_imap_command (store, folder, cancellable, error,
2179
 
                                                       "UID STORE %s +FLAGS.SILENT (\\Deleted)",
2180
 
                                                       uidset);
 
2225
                        response = camel_imap_command (
 
2226
                                store, folder, cancellable, error,
 
2227
                                "UID STORE %s +FLAGS.SILENT (\\Deleted)",
 
2228
                                uidset);
2181
2229
 
2182
2230
                        g_free (uidset);
2183
2231
 
2206
2254
                while (uid < keep_uids->len) {
2207
2255
                        uidset = imap_uid_array_to_set (folder->summary, keep_uids, uid, UID_SET_LIMIT, &uid);
2208
2256
 
2209
 
                        response = camel_imap_command (store, folder, cancellable, NULL,
2210
 
                                                       "UID STORE %s +FLAGS.SILENT (\\Deleted)",
2211
 
                                                       uidset);
 
2257
                        response = camel_imap_command (
 
2258
                                store, folder, cancellable, NULL,
 
2259
                                "UID STORE %s +FLAGS.SILENT (\\Deleted)",
 
2260
                                uidset);
2212
2261
 
2213
2262
                        g_free (uidset);
2214
2263
                        if (response)
2256
2305
        G_LOCK_DEFINE_STATIC (lock);
2257
2306
 
2258
2307
        G_LOCK (lock);
2259
 
        res = g_strdup_printf ("tempuid-%lx-%d",
2260
 
                               (gulong) time (NULL),
2261
 
                               counter++);
 
2308
        res = g_strdup_printf (
 
2309
                "tempuid-%lx-%d",
 
2310
                (gulong) time (NULL),
 
2311
                counter++);
2262
2312
        G_UNLOCK (lock);
2263
2313
 
2264
2314
        return res;
2289
2339
        camel_folder_changed (folder, changes);
2290
2340
        camel_folder_change_info_free (changes);
2291
2341
 
2292
 
        camel_imap_journal_log (CAMEL_IMAP_FOLDER (folder)->journal,
2293
 
                               CAMEL_IMAP_JOURNAL_ENTRY_APPEND, uid);
 
2342
        camel_imap_journal_log (
 
2343
                CAMEL_IMAP_FOLDER (folder)->journal,
 
2344
                CAMEL_IMAP_JOURNAL_ENTRY_APPEND, uid);
2294
2345
        if (appended_uid)
2295
2346
                *appended_uid = uid;
2296
2347
        else
2456
2507
                        folder, message, info, appended_uid, error);
2457
2508
        }
2458
2509
 
 
2510
        if (!camel_imap_store_connected (store, error))
 
2511
                return FALSE;
 
2512
 
2459
2513
        count = camel_folder_summary_count (folder->summary);
2460
2514
        response = do_append (folder, message, info, &uid, cancellable, error);
2461
2515
        if (!response)
2512
2566
                const gchar *olduid = camel_message_info_uid (info);
2513
2567
 
2514
2568
                CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
2515
 
                camel_imap_message_cache_copy (imap_folder->cache, olduid,
2516
 
                                               imap_folder->cache, uid);
 
2569
                camel_imap_message_cache_copy (
 
2570
                        imap_folder->cache, olduid,
 
2571
                        imap_folder->cache, uid);
2517
2572
                CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
2518
2573
 
2519
2574
                if (appended_uid)
2612
2667
        return TRUE;
2613
2668
}
2614
2669
 
2615
 
/* Call with lock held on destination folder cache */
 
2670
/* Call with lock held on destination and source folder cache */
2616
2671
static void
2617
2672
handle_copyuid (CamelImapResponse *response,
2618
2673
                CamelFolder *source,
2643
2698
        dest = imap_uid_set_to_array (destination->summary, destset);
2644
2699
 
2645
2700
        if (src && dest && src->len == dest->len) {
2646
 
                /* We don't have to worry about deadlocking on the
2647
 
                 * cache locks here, because we've got the store's
2648
 
                 * command lock too, so no one else could be here.
2649
 
                 */
2650
 
                CAMEL_IMAP_FOLDER_REC_LOCK (source, cache_lock);
2651
2701
                for (i = 0; i < src->len; i++) {
2652
 
                        camel_imap_message_cache_copy (scache, src->pdata[i],
2653
 
                                                       dcache, dest->pdata[i]);
 
2702
                        camel_imap_message_cache_copy (
 
2703
                                scache, src->pdata[i],
 
2704
                                dcache, dest->pdata[i]);
2654
2705
 
2655
2706
                        imap_folder_add_ignore_recent (CAMEL_IMAP_FOLDER (destination), dest->pdata[i]);
2656
2707
                }
2657
 
                CAMEL_IMAP_FOLDER_REC_UNLOCK (source, cache_lock);
2658
2708
 
2659
2709
                imap_uid_array_free (src);
2660
2710
                imap_uid_array_free (dest);
2669
2719
        g_warning ("Bad COPYUID response from server");
2670
2720
}
2671
2721
 
2672
 
/* Call with lock held on destination folder cache */
 
2722
/* Call with lock held on destination and source folder cache */
2673
2723
static void
2674
2724
handle_copyuid_copy_user_tags (CamelImapResponse *response,
2675
2725
                               CamelFolder *source,
2711
2761
        dest = imap_uid_set_to_array (destination->summary, destset);
2712
2762
 
2713
2763
        if (src && dest && src->len == dest->len) {
2714
 
                CAMEL_IMAP_FOLDER_REC_LOCK (source, cache_lock);
2715
2764
                for (i = 0; i < src->len; i++) {
2716
2765
                        CamelMessageInfo *mi = camel_folder_get_message_info (source, src->pdata[i]);
2717
2766
 
2726
2775
                                camel_folder_free_message_info (source, mi);
2727
2776
                        }
2728
2777
                }
2729
 
                CAMEL_IMAP_FOLDER_REC_UNLOCK (source, cache_lock);
2730
2778
 
2731
2779
                imap_uid_array_free (src);
2732
2780
                imap_uid_array_free (dest);
2799
2847
        parent_store = camel_folder_get_parent_store (source);
2800
2848
        store = CAMEL_IMAP_STORE (parent_store);
2801
2849
 
 
2850
        if (!camel_imap_store_connected (store, error))
 
2851
                return FALSE;
 
2852
 
2802
2853
        service = CAMEL_SERVICE (parent_store);
2803
 
        settings = camel_service_get_settings (service);
 
2854
 
 
2855
        settings = camel_service_ref_settings (service);
2804
2856
 
2805
2857
        trash_path = camel_imap_settings_dup_real_trash_path (
2806
2858
                CAMEL_IMAP_SETTINGS (settings));
2807
2859
 
 
2860
        g_object_unref (settings);
 
2861
 
2808
2862
        mark_moved = is_google_account (parent_store) && trash_path != NULL;
2809
2863
 
2810
2864
        full_name = camel_folder_get_full_name (destination);
2820
2874
                        /* returns only 'A00012 OK UID XGWMOVE completed' '* 2 XGWMOVE' so nothing useful */
2821
2875
                        camel_imap_response_free (store, response);
2822
2876
                } else {
 
2877
                        CAMEL_IMAP_FOLDER_REC_LOCK (source, cache_lock);
2823
2878
                        CAMEL_IMAP_FOLDER_REC_LOCK (destination, cache_lock);
2824
2879
                        response = camel_imap_command (
2825
2880
                                store, source, cancellable, &local_error,
2832
2887
                                        cancellable);
2833
2888
                        camel_imap_response_free (store, response);
2834
2889
                        CAMEL_IMAP_FOLDER_REC_UNLOCK (destination, cache_lock);
 
2890
                        CAMEL_IMAP_FOLDER_REC_UNLOCK (source, cache_lock);
2835
2891
                }
2836
2892
 
2837
2893
                if (local_error == NULL && delete_originals && (mark_moved || !trash_path)) {
3208
3264
 
3209
3265
        part_spec = content_info_get_part_spec (ci);
3210
3266
 
3211
 
        d(printf("get content '%s' '%s' (frommsg = %d)\n", part_spec, camel_content_type_format(ci->type), frommsg));
 
3267
        d (printf ("get content '%s' '%s' (frommsg = %d)\n", part_spec, camel_content_type_format (ci->type), frommsg));
3212
3268
 
3213
3269
        /* There are three cases: multipart/signed, multipart, message/rfc822, and "other" */
3214
3270
        if (camel_content_type_is (ci->type, "multipart", "signed")) {
3226
3282
 
3227
3283
                spec = g_alloca (strlen (part_spec) + 6);
3228
3284
                if (frommsg)
3229
 
                        sprintf(spec, part_spec[0] ? "%s.TEXT" : "TEXT", part_spec);
 
3285
                        sprintf (spec, part_spec[0] ? "%s.TEXT" : "TEXT", part_spec);
3230
3286
                else
3231
3287
                        strcpy (spec, part_spec);
3232
3288
                g_free (part_spec);
3256
3312
                /* need to set this so it grabs the boundary and other info about the multipart */
3257
3313
                /* we assume that part->content_type is more accurate/full than ci->type */
3258
3314
                camel_data_wrapper_set_mime_type_field (CAMEL_DATA_WRAPPER (body_mp), CAMEL_DATA_WRAPPER (part)->mime_type);
3259
 
                isdigest = camel_content_type_is(((CamelDataWrapper *)part)->mime_type, "multipart", "digest");
 
3315
                isdigest = camel_content_type_is (((CamelDataWrapper *) part)->mime_type, "multipart", "digest");
3260
3316
 
3261
3317
                speclen = strlen (part_spec);
3262
3318
                child_spec = g_malloc (speclen + 17); /* dot + 10 + dot + MIME + nul */
3293
3349
                                return NULL;
3294
3350
                        }
3295
3351
 
3296
 
                        if (camel_debug("imap:folder")) {
 
3352
                        if (camel_debug ("imap:folder")) {
3297
3353
                                gchar *ct = camel_content_type_format (camel_mime_part_get_content_type ((CamelMimePart *) part));
3298
3354
                                gchar *ct2 = camel_content_type_format (ci->type);
3299
3355
 
3300
 
                                printf("Setting part content type to '%s' contentinfo type is '%s'\n", ct, ct2);
 
3356
                                printf ("Setting part content type to '%s' contentinfo type is '%s'\n", ct, ct2);
3301
3357
                                g_free (ct);
3302
3358
                                g_free (ct2);
3303
3359
                        }
3304
3360
 
3305
3361
                        /* if we had no content-type header on a multipart/digest sub-part, then we need to
3306
3362
                         * treat it as message/rfc822 instead */
3307
 
                        if (isdigest && camel_medium_get_header((CamelMedium *)part, "content-type") == NULL) {
3308
 
                                CamelContentType *ct = camel_content_type_new("message", "rfc822");
 
3363
                        if (isdigest && camel_medium_get_header ((CamelMedium *) part, "content-type") == NULL) {
 
3364
                                CamelContentType *ct = camel_content_type_new ("message", "rfc822");
3309
3365
 
3310
3366
                                camel_data_wrapper_set_mime_type_field (content, ct);
3311
3367
                                camel_content_type_unref (ct);
3336
3392
                /* NB: we need this differently to multipart/signed case above on purpose */
3337
3393
                spec = g_alloca (strlen (part_spec) + 6);
3338
3394
                if (frommsg)
3339
 
                        sprintf(spec, part_spec[0] ? "%s.1" : "1", part_spec);
 
3395
                        sprintf (spec, part_spec[0] ? "%s.1" : "1", part_spec);
3340
3396
                else
3341
 
                        strcpy(spec, part_spec[0]?part_spec:"1");
 
3397
                        strcpy (spec, part_spec[0]?part_spec:"1");
3342
3398
 
3343
3399
                enc = ci->encoding ? camel_transfer_encoding_from_string (ci->encoding) : CAMEL_TRANSFER_ENCODING_DEFAULT;
3344
3400
                content = camel_imap_wrapper_new (imap_folder, ci->type, enc, uid, spec, part);
3368
3424
        store = CAMEL_IMAP_STORE (parent_store);
3369
3425
 
3370
3426
        part_spec = content_info_get_part_spec (ci);
3371
 
        d(printf("get message '%s'\n", part_spec));
3372
 
        section_text = g_strdup_printf ("%s%s%s", part_spec, *part_spec ? "." : "",
 
3427
        d (printf ("get message '%s'\n", part_spec));
 
3428
        section_text = g_strdup_printf (
 
3429
                "%s%s%s", part_spec, *part_spec ? "." : "",
3373
3430
                                        store->server_level >= IMAP_LEVEL_IMAP4REV1 ? "HEADER" : "0");
3374
3431
 
3375
3432
        stream = camel_imap_folder_fetch_data (imap_folder, uid, section_text, FALSE, cancellable, error);
3393
3450
                return NULL;
3394
3451
        }
3395
3452
 
3396
 
        if (camel_debug("imap:folder")) {
 
3453
        if (camel_debug ("imap:folder")) {
3397
3454
                gchar *ct = camel_content_type_format (camel_mime_part_get_content_type ((CamelMimePart *) msg));
3398
3455
                gchar *ct2 = camel_content_type_format (ci->type);
3399
3456
 
3400
 
                printf("Setting message content type to '%s' contentinfo type is '%s'\n", ct, ct2);
 
3457
                printf ("Setting message content type to '%s' contentinfo type is '%s'\n", ct, ct2);
3401
3458
                g_free (ct);
3402
3459
                g_free (ct2);
3403
3460
        }
3422
3479
        gboolean success;
3423
3480
 
3424
3481
        if (!stream) {
3425
 
                stream = camel_imap_folder_fetch_data (imap_folder, uid, "",
3426
 
                                                       FALSE, cancellable, error);
 
3482
                stream = camel_imap_folder_fetch_data (
 
3483
                        imap_folder, uid, "",
 
3484
                        FALSE, cancellable, error);
3427
3485
                if (!stream)
3428
3486
                        return NULL;
3429
3487
        }
3476
3534
        return mi;
3477
3535
}
3478
3536
 
 
3537
CamelMimeMessage *
 
3538
imap_get_message_cached (CamelFolder *folder,
 
3539
                         const gchar *message_uid,
 
3540
                         GCancellable *cancellable)
 
3541
{
 
3542
        CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
 
3543
        CamelMimeMessage *msg = NULL;
 
3544
        CamelStream *stream;
 
3545
 
 
3546
        stream = camel_imap_folder_fetch_data (imap_folder, message_uid, "", TRUE, cancellable, NULL);
 
3547
        if (stream != NULL)
 
3548
                msg = get_message_simple (imap_folder, message_uid, stream, cancellable, NULL);
 
3549
 
 
3550
        return msg;
 
3551
}
 
3552
 
3479
3553
static CamelMimeMessage *
3480
3554
imap_get_message_sync (CamelFolder *folder,
3481
3555
                       const gchar *uid,
3487
3561
        CamelImapStore *store;
3488
3562
        CamelImapMessageInfo *mi;
3489
3563
        CamelMimeMessage *msg = NULL;
3490
 
        CamelStream *stream = NULL;
3491
3564
        gint retry;
3492
3565
        GError *local_error = NULL;
3493
3566
 
3496
3569
 
3497
3570
        mi = imap_folder_summary_uid_or_error (folder->summary, uid, error);
3498
3571
        if (!mi)
3499
 
          return NULL;
 
3572
                return NULL;
3500
3573
 
3501
3574
        /* If its cached in full, just get it as is, this is only a shortcut,
3502
3575
         * since we get stuff from the cache anyway.  It affects a busted
3503
3576
         * connection though. */
3504
 
        stream = camel_imap_folder_fetch_data (imap_folder, uid, "", TRUE, cancellable, NULL);
3505
 
        if (stream != NULL) {
3506
 
                msg = get_message_simple (imap_folder, uid, stream, cancellable, NULL);
3507
 
                if (msg != NULL)
3508
 
                        goto done;
3509
 
        }
 
3577
        msg = imap_get_message_cached (folder, uid, cancellable);
 
3578
        if (msg != NULL)
 
3579
                goto done;
 
3580
 
 
3581
        if (!camel_imap_store_connected (store, error))
 
3582
                return NULL;
3510
3583
 
3511
3584
        /* All this mess is so we silently retry a fetch if we fail with
3512
3585
         * service_unavailable, without an (equivalent) mess of gotos */
3580
3653
                                }
3581
3654
                        }
3582
3655
 
3583
 
                        if (camel_debug_start("imap:folder")) {
3584
 
                                printf("Folder get message '%s' folder info ->\n", uid);
 
3656
                        if (camel_debug_start ("imap:folder")) {
 
3657
                                printf ("Folder get message '%s' folder info ->\n", uid);
3585
3658
                                camel_message_info_dump ((CamelMessageInfo *) mi);
3586
3659
                                camel_debug_end ();
3587
3660
                        }
3678
3751
         */
3679
3752
        /* If its cached in full, just get it as is, this is only a shortcut,
3680
3753
         * since we get stuff from the cache anyway.  It affects a busted connection though. */
3681
 
        if ((stream = camel_imap_folder_fetch_data(imap_folder, uid, "", TRUE, cancellable, NULL))) {
 
3754
        if ((stream = camel_imap_folder_fetch_data (imap_folder, uid, "", TRUE, cancellable, NULL))) {
3682
3755
                g_object_unref (stream);
3683
3756
                return TRUE;
3684
3757
        }
3921
3994
        gchar *uid, *resp, *tempuid;
3922
3995
        GData *data;
3923
3996
        gint k = 0, ct;
 
3997
        gboolean success = TRUE;
3924
3998
 
3925
3999
        parent_store = camel_folder_get_parent_store (folder);
3926
4000
        store = CAMEL_IMAP_STORE (parent_store);
3927
4001
        service = CAMEL_SERVICE (parent_store);
3928
 
        settings = camel_service_get_settings (service);
 
4002
 
 
4003
        if (!camel_imap_store_connected (store, error))
 
4004
                return FALSE;
 
4005
 
 
4006
        settings = camel_service_ref_settings (service);
3929
4007
 
3930
4008
        fetch_headers = camel_imap_settings_get_fetch_headers (
3931
4009
                CAMEL_IMAP_SETTINGS (settings));
3933
4011
        extra_headers = camel_imap_settings_dup_fetch_headers_extra (
3934
4012
                CAMEL_IMAP_SETTINGS (settings));
3935
4013
 
 
4014
        g_object_unref (settings);
 
4015
 
3936
4016
        if (store->server_level >= IMAP_LEVEL_IMAP4REV1) {
3937
4017
                if (fetch_headers == CAMEL_FETCH_HEADERS_ALL)
3938
4018
                        header_spec = g_string_new ("HEADER");
3964
4044
 
3965
4045
        g_strfreev (extra_headers);
3966
4046
 
3967
 
        d(printf("Header is : %s", header_spec->str));
 
4047
        d (printf ("Header is : %s", header_spec->str));
3968
4048
 
3969
4049
        /* Figure out if any of the new messages are already cached (which
3970
4050
         * may be the case if we're re-syncing after disconnected operation).
4051
4131
 
4052
4132
        if (type == CAMEL_IMAP_RESPONSE_ERROR || camel_application_is_exiting) {
4053
4133
                g_string_free (header_spec, TRUE);
4054
 
                goto lose;
 
4134
                success = FALSE;
 
4135
                goto finish;
4055
4136
        }
4056
4137
 
4057
4138
        /* Free the final tagged response */
4077
4158
                gchar *uidset;
4078
4159
                gint uid = 0;
4079
4160
 
4080
 
                qsort (needheaders->pdata, needheaders->len,
4081
 
                       sizeof (gpointer), uid_compar);
 
4161
                qsort (
 
4162
                        needheaders->pdata, needheaders->len,
 
4163
                        sizeof (gpointer), uid_compar);
4082
4164
 
4083
4165
                camel_operation_push_message (
4084
4166
                        cancellable,
4091
4173
                                                       "UID FETCH %s BODYSTRUCTURE BODY.PEEK[%s]",
4092
4174
                                                       uidset, header_spec->str)) {
4093
4175
                                g_ptr_array_free (needheaders, TRUE);
4094
 
                                camel_operation_pop_message (cancellable);
4095
4176
                                g_free (uidset);
4096
4177
                                g_string_free (header_spec, TRUE);
4097
 
                                goto lose;
 
4178
                                success = FALSE;
 
4179
                                break;
4098
4180
                        }
4099
4181
                        g_free (uidset);
4100
4182
 
4120
4202
                        if (type == CAMEL_IMAP_RESPONSE_ERROR || camel_application_is_exiting) {
4121
4203
                                g_ptr_array_free (needheaders, TRUE);
4122
4204
                                g_string_free (header_spec, TRUE);
4123
 
                                camel_operation_pop_message (cancellable);
 
4205
                                success = FALSE;
4124
4206
 
4125
 
                                goto lose;
 
4207
                                break;
4126
4208
                        }
4127
4209
                }
4128
4210
                camel_operation_pop_message (cancellable);
4131
4213
        g_ptr_array_free (needheaders, TRUE);
4132
4214
        g_string_free (header_spec, TRUE);
4133
4215
 
 
4216
 finish:
4134
4217
        /* Now finish up summary entries (fix UIDs, set flags and size) */
4135
4218
        for (i = 0; i < fetch_data->len; i++) {
4136
4219
                struct _junk_data jdata;
4214
4297
                        g_set_error (
4215
4298
                                error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
4216
4299
                                _("Incomplete server response: "
4217
 
                                  "no information provided for message %d"),
 
4300
                                "no information provided for message %d"),
4218
4301
                                i + first);
4219
 
                        break;
 
4302
                        continue;
4220
4303
                }
4221
4304
                uid = (gchar *) camel_message_info_uid (mi);
4222
4305
                if (uid[0] == 0) {
4223
 
                        g_warning("Server provided no uid: message %d", i + first);
 
4306
                        g_warning ("Server provided no uid: message %d", i + first);
4224
4307
                        g_set_error (
4225
4308
                                error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
4226
4309
                                _("Incomplete server response: "
4227
 
                                  "no UID provided for message %d"),
 
4310
                                "no UID provided for message %d"),
4228
4311
                                i + first);
4229
 
                        break;
 
4312
                        continue;
4230
4313
                }
4231
4314
 
4232
4315
                /* FIXME: If it enters if (info) it will always match the exception. So stupid */
4260
4343
                imap_folder->priv->ignore_recent = NULL;
4261
4344
        }
4262
4345
 
4263
 
        return TRUE;
 
4346
        return success;
4264
4347
 
4265
4348
 lose:
4266
4349
        if (fetch_data) {
4311
4394
                known_uids = camel_folder_summary_get_array (folder->summary);
4312
4395
                camel_folder_sort_uids (folder, known_uids);
4313
4396
                for (i = 0; i < expunged->len; i++) {
 
4397
                        CamelMessageInfo *mi;
 
4398
 
4314
4399
                        id = g_array_index (expunged, int, i);
4315
4400
                        uid = id - 1 + i >= 0 && id - 1 + i < known_uids->len ? g_ptr_array_index (known_uids, id - 1 + i) : NULL;
4316
4401
                        if (uid == NULL) {
4324
4409
                        CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
4325
4410
                        camel_imap_message_cache_remove (imap_folder->cache, uid);
4326
4411
                        CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
4327
 
                        camel_folder_summary_remove_uid (folder->summary, uid);
 
4412
 
 
4413
                        mi = camel_folder_summary_peek_loaded (folder->summary, uid);
 
4414
                        if (mi) {
 
4415
                                camel_folder_summary_remove (folder->summary, mi);
 
4416
                                camel_message_info_free (mi);
 
4417
                        } else {
 
4418
                                camel_folder_summary_remove_uid (folder->summary, uid);
 
4419
                        }
4328
4420
                }
4329
4421
 
4330
4422
                /* Delete all in one transaction */
4388
4480
        parent_store = camel_folder_get_parent_store (folder);
4389
4481
        store = CAMEL_IMAP_STORE (parent_store);
4390
4482
 
 
4483
        if (!cache_only && !camel_imap_store_connected (store, error))
 
4484
                return NULL;
 
4485
 
4391
4486
        /* EXPUNGE responses have to modify the cache, which means
4392
4487
         * they have to grab the cache_lock while holding the
4393
4488
         * connect_lock.
4595
4690
                        stream = camel_stream_mem_new_with_buffer (body, body_len);
4596
4691
                } else {
4597
4692
                        CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
4598
 
                        stream = camel_imap_message_cache_insert (imap_folder->cache,
4599
 
                                                                  uid, part_spec,
4600
 
                                                                  body, body_len, NULL, NULL);
 
4693
                        stream = camel_imap_message_cache_insert (
 
4694
                                imap_folder->cache,
 
4695
                                uid, part_spec,
 
4696
                                body, body_len, NULL, NULL);
4601
4697
                        CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
4602
4698
                        if (stream == NULL)
4603
4699
                                stream = camel_stream_mem_new_with_buffer (body, body_len);
4604
4700
                }
4605
4701
 
4606
4702
                if (stream)
4607
 
                        g_datalist_set_data_full (&data, "BODY_PART_STREAM", stream,
4608
 
                                                  (GDestroyNotify) g_object_unref);
 
4703
                        g_datalist_set_data_full (
 
4704
                                &data, "BODY_PART_STREAM", stream,
 
4705
                                (GDestroyNotify) g_object_unref);
4609
4706
        }
4610
4707
 
4611
4708
        return data;
4694
4791
                                        }
4695
4792
 
4696
4793
                                        if (skipped)
4697
 
                                                g_debug ("Unexpected quota response '%s'; skipping it...", (const gchar *)response->untagged->pdata[i]);
 
4794
                                                g_debug ("Unexpected quota response '%s'; skipping it...", (const gchar *) response->untagged->pdata[i]);
4698
4795
                                }
4699
4796
                        }
4700
4797
                        camel_imap_response_free (imap_store, response);