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

« back to all changes in this revision

Viewing changes to camel/providers/imapx/camel-imapx-store.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2015-07-20 13:34:59 UTC
  • mfrom: (1.1.126) (1.2.48 sid)
  • Revision ID: package-import@ubuntu.com-20150720133459-g6y46hnu5ewtoz08
Tags: 3.16.4-0ubuntu2
debian/patches/0001-Bug-752373-Monthly-events-do-not-recur-correctly.patch:
Cherry-pick patch from upstream to fix events not recurring correctly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
 
/* camel-imap-store.c : class for a imap store */
3
 
/*
4
 
 * Authors: Michael Zucchi <notzed@ximian.com>
 
2
/* camel-imap-store.c : class for a imap store
5
3
 *
6
4
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
7
5
 *
8
 
 * This library is free software; you can redistribute it and/or modify it
 
6
 * This library is free software: you can redistribute it and/or modify it
9
7
 * under the terms of the GNU Lesser General Public License as published by
10
8
 * the Free Software Foundation.
11
9
 *
12
10
 * This library is distributed in the hope that it will be useful, but
13
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
12
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15
13
 * for more details.
16
14
 *
17
15
 * You should have received a copy of the GNU Lesser General Public License
18
 
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
 
16
 * along with this library. If not, see <http://www.gnu.org/licenses/>.
 
17
 *
 
18
 * Authors: Michael Zucchi <notzed@ximian.com>
19
19
 */
20
20
 
21
21
#ifdef HAVE_CONFIG_H
468
468
        fi = imapx_store_build_folder_info (store, folder_path, flags);
469
469
 
470
470
        /* Figure out which signals to emit, if any. */
471
 
        if (use_subscriptions) {
 
471
        if (use_subscriptions || camel_imapx_namespace_get_category (camel_imapx_mailbox_get_namespace (mailbox)) != CAMEL_IMAPX_NAMESPACE_PERSONAL) {
472
472
                /* If we are honoring folder subscriptions, then
473
473
                 * subscription changes are equivalent to folder
474
474
                 * creation / deletion as far as we're concerned. */
704
704
        priv = CAMEL_IMAPX_STORE_GET_PRIVATE (object);
705
705
 
706
706
        g_mutex_clear (&priv->get_finfo_lock);
707
 
 
708
707
        g_mutex_clear (&priv->server_lock);
709
708
 
710
709
        g_hash_table_destroy (priv->quota_info);
775
774
        CamelIMAPXServer *imapx_server;
776
775
        gboolean success;
777
776
 
 
777
        /* Chain up to parent's method. */
 
778
        if (!CAMEL_SERVICE_CLASS (camel_imapx_store_parent_class)->connect_sync (service, cancellable, error))
 
779
                return FALSE;
 
780
 
778
781
        imapx_store = CAMEL_IMAPX_STORE (service);
779
782
 
780
783
        imapx_server = camel_imapx_store_ref_server (imapx_store, NULL, FALSE, cancellable, error);
804
807
 
805
808
        g_mutex_unlock (&priv->server_lock);
806
809
 
807
 
        return TRUE;
 
810
        /* Chain up to parent's method. */
 
811
        return CAMEL_SERVICE_CLASS (camel_imapx_store_parent_class)->disconnect_sync (service, clean, cancellable, error);
808
812
}
809
813
 
810
814
static CamelAuthenticationResult
1080
1084
                if (!si_is_match)
1081
1085
                        continue;
1082
1086
 
 
1087
                if (!use_subscriptions && !(si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) &&
 
1088
                    !(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST)) {
 
1089
                        CamelIMAPXMailbox *mailbox;
 
1090
 
 
1091
                        mailbox = camel_imapx_store_ref_mailbox (imapx_store, ((CamelIMAPXStoreInfo *) si)->mailbox_name);
 
1092
                        if (!mailbox || camel_imapx_namespace_get_category (camel_imapx_mailbox_get_namespace (mailbox)) != CAMEL_IMAPX_NAMESPACE_PERSONAL) {
 
1093
                                /* Skip unsubscribed mailboxes which are not in the Personal namespace */
 
1094
                                g_clear_object (&mailbox);
 
1095
                                continue;
 
1096
                        }
 
1097
 
 
1098
                        g_clear_object (&mailbox);
 
1099
                }
 
1100
 
1083
1101
                fi = imapx_store_build_folder_info (
1084
1102
                        imapx_store, folder_path, 0);
1085
1103
                fi->unread = si->unread;
1418
1436
}
1419
1437
 
1420
1438
static gboolean
 
1439
imapx_store_mailbox_is_unknown (CamelIMAPXStore *imapx_store,
 
1440
                                GPtrArray *store_infos,
 
1441
                                const CamelIMAPXStoreInfo *to_check)
 
1442
{
 
1443
        CamelIMAPXMailbox *mailbox;
 
1444
        gboolean is_unknown;
 
1445
 
 
1446
        g_return_val_if_fail (CAMEL_IS_IMAPX_STORE (imapx_store), FALSE);
 
1447
        g_return_val_if_fail (store_infos != NULL, FALSE);
 
1448
 
 
1449
        if (!to_check || !to_check->mailbox_name || !*to_check->mailbox_name)
 
1450
                return FALSE;
 
1451
 
 
1452
        mailbox = camel_imapx_store_ref_mailbox (imapx_store, to_check->mailbox_name);
 
1453
 
 
1454
        is_unknown = mailbox && camel_imapx_mailbox_get_state (mailbox) == CAMEL_IMAPX_MAILBOX_STATE_UNKNOWN;
 
1455
 
 
1456
        if (!mailbox && to_check->separator) {
 
1457
                CamelSettings *settings;
 
1458
                gboolean use_subscriptions;
 
1459
                gchar *mailbox_with_separator;
 
1460
                gint ii;
 
1461
 
 
1462
                settings = camel_service_ref_settings (CAMEL_SERVICE (imapx_store));
 
1463
                use_subscriptions = camel_imapx_settings_get_use_subscriptions (CAMEL_IMAPX_SETTINGS (settings));
 
1464
                g_object_unref (settings);
 
1465
 
 
1466
                mailbox_with_separator = g_strdup_printf ("%s%c", to_check->mailbox_name, to_check->separator);
 
1467
 
 
1468
                for (ii = 0; ii < store_infos->len; ii++) {
 
1469
                        CamelIMAPXStoreInfo *si;
 
1470
 
 
1471
                        si = g_ptr_array_index (store_infos, ii);
 
1472
 
 
1473
                        if (si->mailbox_name && g_str_has_prefix (si->mailbox_name, mailbox_with_separator) && (
 
1474
                            !use_subscriptions || (((CamelStoreInfo *) si)->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) != 0)) {
 
1475
                                /* This can be a 'virtual' parent folder of some subscribed subfolder */
 
1476
                                break;
 
1477
                        }
 
1478
                }
 
1479
 
 
1480
                is_unknown = ii == store_infos->len;
 
1481
 
 
1482
                g_free (mailbox_with_separator);
 
1483
        }
 
1484
 
 
1485
        g_clear_object (&mailbox);
 
1486
 
 
1487
        return is_unknown;
 
1488
}
 
1489
 
 
1490
static gboolean
1421
1491
sync_folders (CamelIMAPXStore *imapx_store,
1422
1492
              const gchar *root_folder_path,
1423
1493
              CamelStoreGetFolderInfoFlags flags,
1427
1497
{
1428
1498
        CamelIMAPXServer *server;
1429
1499
        GHashTable *folder_info_results;
1430
 
        GPtrArray *array;
1431
 
        guint ii;
 
1500
        gboolean update_folder_list;
1432
1501
        gboolean success;
1433
1502
 
1434
1503
        server = camel_imapx_store_ref_server (imapx_store, NULL, FALSE, cancellable, error);
1446
1515
         * in imapx_store_process_mailbox_attributes(). */
1447
1516
        g_atomic_int_inc (&imapx_store->priv->syncing_folders);
1448
1517
 
1449
 
        if (!initial_setup && (!root_folder_path || !*root_folder_path)) {
 
1518
        update_folder_list = !initial_setup && (!root_folder_path || !*root_folder_path);
 
1519
 
 
1520
        if (update_folder_list) {
1450
1521
                g_mutex_lock (&imapx_store->priv->mailboxes_lock);
1451
1522
                g_hash_table_foreach (imapx_store->priv->mailboxes, imapx_store_mark_mailbox_unknown_cb, imapx_store);
1452
1523
                g_mutex_unlock (&imapx_store->priv->mailboxes_lock);
1459
1530
        } else {
1460
1531
                gboolean have_folder_info_for_inbox;
1461
1532
 
1462
 
                /* XXX We only fetch personal mailboxes at this time. */
1463
1533
                success = fetch_folder_info_for_namespace_category (
1464
 
                        imapx_store, server, CAMEL_IMAPX_NAMESPACE_PERSONAL, flags,
 
1534
                        imapx_store, server, CAMEL_IMAPX_NAMESPACE_PERSONAL, flags |
 
1535
                        (update_folder_list ? CAMEL_STORE_FOLDER_INFO_SUBSCRIBED : 0),
1465
1536
                        folder_info_results, cancellable, error);
1466
1537
 
1467
1538
                have_folder_info_for_inbox =
1482
1553
        if (!success)
1483
1554
                goto exit;
1484
1555
 
1485
 
        if (!initial_setup && (!root_folder_path || !*root_folder_path)) {
 
1556
        if (update_folder_list) {
1486
1557
                g_mutex_lock (&imapx_store->priv->mailboxes_lock);
1487
1558
                g_hash_table_foreach_remove (imapx_store->priv->mailboxes, imapx_store_remove_unknown_mailboxes_cb, imapx_store);
1488
1559
                g_mutex_unlock (&imapx_store->priv->mailboxes_lock);
1489
1560
        }
1490
1561
 
1491
 
        array = camel_store_summary_array (imapx_store->summary);
1492
 
 
1493
 
        for (ii = 0; ii < array->len; ii++) {
1494
 
                CamelStoreInfo *si;
1495
 
                CamelFolderInfo *fi;
1496
 
                const gchar *mailbox_name;
1497
 
                const gchar *si_path;
1498
 
                gboolean pattern_match;
1499
 
 
1500
 
                si = g_ptr_array_index (array, ii);
1501
 
                si_path = camel_store_info_path (imapx_store->summary, si);
1502
 
 
1503
 
                mailbox_name = ((CamelIMAPXStoreInfo *) si)->mailbox_name;
1504
 
                if (mailbox_name == NULL || *mailbox_name == '\0')
1505
 
                        continue;
1506
 
 
1507
 
                pattern_match =
1508
 
                        (root_folder_path == NULL) ||
1509
 
                        (*root_folder_path == '\0') ||
1510
 
                        (g_str_has_prefix (si_path, root_folder_path));
1511
 
                if (!pattern_match)
1512
 
                        continue;
1513
 
 
1514
 
                fi = g_hash_table_lookup (folder_info_results, mailbox_name);
1515
 
 
1516
 
                if (fi == NULL) {
1517
 
                        gchar *dup_folder_path = g_strdup (si_path);
1518
 
 
1519
 
                        if (dup_folder_path != NULL) {
1520
 
                                /* Do not unsubscribe from it, it influences UI for non-subscribable folders */
1521
 
                                imapx_delete_folder_from_cache (
1522
 
                                        imapx_store, dup_folder_path, FALSE);
1523
 
                                g_free (dup_folder_path);
1524
 
                        } else {
1525
 
                                camel_store_summary_remove (
1526
 
                                        imapx_store->summary, si);
 
1562
        if (!root_folder_path || !*root_folder_path) {
 
1563
                GPtrArray *array;
 
1564
                guint ii;
 
1565
 
 
1566
                /* Finally update store's summary */
 
1567
                array = camel_store_summary_array (imapx_store->summary);
 
1568
                for (ii = 0; array && ii < array->len; ii++) {
 
1569
                        CamelStoreInfo *si;
 
1570
                        const gchar *si_path;
 
1571
 
 
1572
                        si = g_ptr_array_index (array, ii);
 
1573
                        si_path = camel_store_info_path (imapx_store->summary, si);
 
1574
 
 
1575
                        if (imapx_store_mailbox_is_unknown (imapx_store, array, (CamelIMAPXStoreInfo *) si)) {
 
1576
                                gchar *dup_folder_path = g_strdup (si_path);
 
1577
 
 
1578
                                if (dup_folder_path != NULL) {
 
1579
                                        /* Do not unsubscribe from it, it influences UI for non-subscribable folders */
 
1580
                                        imapx_delete_folder_from_cache (imapx_store, dup_folder_path, FALSE);
 
1581
                                        g_free (dup_folder_path);
 
1582
                                } else {
 
1583
                                        camel_store_summary_remove (imapx_store->summary, si);
 
1584
                                }
1527
1585
                        }
1528
1586
                }
 
1587
 
 
1588
                camel_store_summary_array_free (imapx_store->summary, array);
1529
1589
        }
1530
1590
 
1531
 
        camel_store_summary_array_free (imapx_store->summary, array);
1532
1591
        camel_store_summary_save (imapx_store->summary);
1533
1592
 
1534
1593
exit:
1552
1611
        display_name = camel_service_get_display_name (service);
1553
1612
 
1554
1613
        camel_operation_push_message (
1555
 
                cancellable, _("Retrieving folder list for %s"),
 
1614
                cancellable, _("Retrieving folder list for '%s'"),
1556
1615
                display_name);
1557
1616
 
1558
1617
        if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (store)))
1645
1704
        res = store_class->can_refresh_folder (store, info, &local_error) ||
1646
1705
                check_all || (check_subscribed && subscribed);
1647
1706
 
 
1707
        if (!res && !local_error) {
 
1708
                CamelFolder *folder;
 
1709
 
 
1710
                folder = camel_store_get_folder_sync (store, info->full_name, 0, NULL, &local_error);
 
1711
                if (folder && CAMEL_IS_IMAPX_FOLDER (folder))
 
1712
                        res = camel_imapx_folder_get_check_folder (CAMEL_IMAPX_FOLDER (folder));
 
1713
 
 
1714
                g_clear_object (&folder);
 
1715
        }
 
1716
 
1648
1717
        if (local_error != NULL)
1649
1718
                g_propagate_error (error, local_error);
1650
1719
 
1774
1843
        }
1775
1844
 
1776
1845
        /* XXX I don't know why the SUBSCRIBED flag matters here. */
1777
 
        if (!initial_setup && flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) {
 
1846
        if (!initial_setup && (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) != 0) {
1778
1847
                time_t time_since_last_refresh;
1779
1848
 
1780
1849
                time_since_last_refresh =
1782
1851
 
1783
1852
                if (time_since_last_refresh > FINFO_REFRESH_INTERVAL) {
1784
1853
                        CamelSession *session;
 
1854
                        gchar *description;
1785
1855
 
1786
1856
                        imapx_store->priv->last_refresh_time = time (NULL);
1787
1857
 
1788
1858
                        session = camel_service_ref_session (service);
 
1859
                        description = g_strdup_printf (_("Retrieving folder list for '%s'"), camel_service_get_display_name (service));
1789
1860
 
1790
1861
                        camel_session_submit_job (
1791
 
                                session, (CamelSessionCallback)
 
1862
                                session, description, (CamelSessionCallback)
1792
1863
                                imapx_refresh_finfo,
1793
1864
                                g_object_ref (store),
1794
1865
                                (GDestroyNotify) g_object_unref);
1795
1866
 
1796
1867
                        g_object_unref (session);
 
1868
                        g_free (description);
1797
1869
                }
1798
1870
        }
1799
1871
 
2778
2850
                                CAMEL_SERVICE_ERROR_UNAVAILABLE,
2779
2851
                                _("You must be working online to complete this operation"));
2780
2852
                } else {
2781
 
                        local_error->domain = CAMEL_SERVICE_ERROR;
2782
 
                        local_error->code = CAMEL_SERVICE_ERROR_UNAVAILABLE;
 
2853
                        g_set_error (
 
2854
                                error, CAMEL_SERVICE_ERROR,
 
2855
                                CAMEL_SERVICE_ERROR_UNAVAILABLE,
 
2856
                                _("You must be working online to complete this operation (%s)"),
 
2857
                                local_error->message);
 
2858
 
 
2859
                        g_clear_error (&local_error);
2783
2860
                }
2784
2861
        }
2785
2862
 
2854
2931
 *
2855
2932
 * Returns: a #CamelIMAPXNamespaceResponse
2856
2933
 *
2857
 
 * Since: 3.12.2
 
2934
 * Since: 3.16
2858
2935
 **/
2859
2936
CamelIMAPXNamespaceResponse *
2860
2937
camel_imapx_store_ref_namespaces (CamelIMAPXStore *imapx_store)
3200
3277
 *
3201
3278
 * Returns: a #CamelIMAPXMailbox, or %NULL
3202
3279
 *
3203
 
 * Since: 3.12.2
 
3280
 * Since: 3.16
3204
3281
 **/
3205
3282
CamelIMAPXMailbox *
3206
3283
camel_imapx_store_ref_mailbox (CamelIMAPXStore *imapx_store,
3243
3320
 *
3244
3321
 * Returns: a list of #CamelIMAPXMailbox instances
3245
3322
 *
3246
 
 * Since: 3.12.2
 
3323
 * Since: 3.16
3247
3324
 **/
3248
3325
GList *
3249
3326
camel_imapx_store_list_mailboxes (CamelIMAPXStore *imapx_store,