~ubuntu-branches/ubuntu/maverick/evolution-data-server/maverick-proposed

« back to all changes in this revision

Viewing changes to servers/exchange/storage/exchange-hierarchy-somedav.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-05-17 17:02:06 UTC
  • mfrom: (1.1.79 upstream) (1.6.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20100517170206-4ufr52vwrhh26yh0
Tags: 2.30.1-1ubuntu1
* Merge from debian experimental. Remaining change:
  (LP: #42199, #229669, #173703, #360344, #508494)
  + debian/control:
    - add Vcs-Bzr tag
    - don't use libgnome
    - Use Breaks instead of Conflicts against evolution 2.25 and earlier.
  + debian/evolution-data-server.install,
    debian/patches/45_libcamel_providers_version.patch:
    - use the upstream versioning, not a Debian-specific one 
  + debian/libedata-book1.2-dev.install, debian/libebackend-1.2-dev.install,
    debian/libcamel1.2-dev.install, debian/libedataserverui1.2-dev.install:
    - install html documentation
  + debian/rules:
    - don't build documentation it's shipped with the tarball

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
 
 
3
 
/* Copyright (C) 2002-2004 Novell, Inc.
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or
6
 
 * modify it under the terms of version 2 of the GNU Lesser General Public
7
 
 * License as published by the Free Software Foundation.
8
 
 *
9
 
 * This program is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
 * General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU Lesser General Public
15
 
 * License along with this program; if not, write to the
16
 
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
 
 * Boston, MA 02110-1301, USA.
18
 
 */
19
 
 
20
 
/* ExchangeHierarchySomeDAV: class for a hierarchy consisting of a
21
 
 * specific group of WebDAV folders
22
 
 */
23
 
 
24
 
#ifdef HAVE_CONFIG_H
25
 
#include <config.h>
26
 
#endif
27
 
 
28
 
#include "exchange-hierarchy-somedav.h"
29
 
#include "exchange-account.h"
30
 
#include "e-folder-exchange.h"
31
 
#include "e2k-propnames.h"
32
 
#include "e2k-uri.h"
33
 
#include "e2k-utils.h"
34
 
 
35
 
#include <libedataserver/e-xml-hash-utils.h>
36
 
 
37
 
#include <stdlib.h>
38
 
#include <string.h>
39
 
#include <unistd.h>
40
 
 
41
 
struct _ExchangeHierarchySomeDAVPrivate {
42
 
        gboolean scanned;
43
 
};
44
 
 
45
 
enum {
46
 
        HREF_UNREADABLE,
47
 
        LAST_SIGNAL
48
 
};
49
 
 
50
 
static guint signals [LAST_SIGNAL] = { 0 };
51
 
 
52
 
#define PARENT_TYPE EXCHANGE_TYPE_HIERARCHY_WEBDAV
53
 
static ExchangeHierarchyWebDAVClass *parent_class = NULL;
54
 
 
55
 
static ExchangeAccountFolderResult scan_subtree (ExchangeHierarchy *hier,
56
 
                                                 EFolder *folder,
57
 
                                                 gint mode);
58
 
static void finalize (GObject *object);
59
 
 
60
 
static void
61
 
class_init (GObjectClass *object_class)
62
 
{
63
 
        ExchangeHierarchyClass *exchange_hierarchy_class =
64
 
                EXCHANGE_HIERARCHY_CLASS (object_class);
65
 
 
66
 
        parent_class = g_type_class_ref (PARENT_TYPE);
67
 
 
68
 
        /* virtual method override */
69
 
        object_class->finalize = finalize;
70
 
 
71
 
        exchange_hierarchy_class->scan_subtree   = scan_subtree;
72
 
 
73
 
        /* signals */
74
 
        signals[HREF_UNREADABLE] =
75
 
                g_signal_new ("href_unreadable",
76
 
                              G_OBJECT_CLASS_TYPE (object_class),
77
 
                              G_SIGNAL_RUN_LAST,
78
 
                              G_STRUCT_OFFSET (ExchangeHierarchySomeDAVClass, href_unreadable),
79
 
                              NULL, NULL,
80
 
                              g_cclosure_marshal_VOID__STRING,
81
 
                              G_TYPE_NONE, 1,
82
 
                              G_TYPE_STRING);
83
 
}
84
 
 
85
 
static void
86
 
init (GObject *object)
87
 
{
88
 
        ExchangeHierarchySomeDAV *hsd = EXCHANGE_HIERARCHY_SOMEDAV (object);
89
 
 
90
 
        hsd->priv = g_new0 (ExchangeHierarchySomeDAVPrivate, 1);
91
 
}
92
 
 
93
 
static void
94
 
finalize (GObject *object)
95
 
{
96
 
        ExchangeHierarchySomeDAV *hsd = EXCHANGE_HIERARCHY_SOMEDAV (object);
97
 
 
98
 
        g_free (hsd->priv);
99
 
 
100
 
        G_OBJECT_CLASS (parent_class)->finalize (object);
101
 
}
102
 
 
103
 
E2K_MAKE_TYPE (exchange_hierarchy_somedav, ExchangeHierarchySomeDAV, class_init, init, PARENT_TYPE)
104
 
 
105
 
static inline gboolean
106
 
folder_is_unreadable (E2kProperties *props)
107
 
{
108
 
        gchar *access;
109
 
 
110
 
        access = e2k_properties_get_prop (props, PR_ACCESS);
111
 
        return !access || !atoi (access);
112
 
}
113
 
 
114
 
static const gchar *folder_props[] = {
115
 
        E2K_PR_EXCHANGE_FOLDER_CLASS,
116
 
        E2K_PR_HTTPMAIL_UNREAD_COUNT,
117
 
        E2K_PR_DAV_DISPLAY_NAME,
118
 
        PR_ACCESS
119
 
};
120
 
static const gint n_folder_props = sizeof (folder_props) / sizeof (folder_props[0]);
121
 
 
122
 
static ExchangeAccountFolderResult
123
 
scan_subtree (ExchangeHierarchy *hier, EFolder *folder, gint mode)
124
 
{
125
 
        ExchangeHierarchySomeDAV *hsd = EXCHANGE_HIERARCHY_SOMEDAV (hier);
126
 
        GPtrArray *hrefs;
127
 
        E2kResultIter *iter;
128
 
        E2kResult *result;
129
 
        gint folders_returned=0, folders_added=0, i;
130
 
        E2kHTTPStatus status;
131
 
        ExchangeAccountFolderResult folder_result;
132
 
        EFolder *iter_folder = NULL;
133
 
 
134
 
        /* FIXME : Temporarily allow a rescan of the hierarchy. The proper fix
135
 
        is to handle the folder list either in ExchangeAccount or in the
136
 
        plugins/exchange backend separately by listening to signals.
137
 
        if (hsd->priv->scanned || folder != hier->toplevel) */
138
 
        if (folder != hier->toplevel)
139
 
                return EXCHANGE_ACCOUNT_FOLDER_OK;
140
 
        hsd->priv->scanned = TRUE;
141
 
 
142
 
        if (mode == OFFLINE_MODE)
143
 
                return EXCHANGE_ACCOUNT_FOLDER_OK;
144
 
 
145
 
        hrefs = exchange_hierarchy_somedav_get_hrefs (hsd);
146
 
        if (!hrefs)
147
 
                return EXCHANGE_ACCOUNT_FOLDER_OK;
148
 
        if (!hrefs->len) {
149
 
                g_ptr_array_free (hrefs, TRUE);
150
 
                return EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST;
151
 
        }
152
 
 
153
 
        iter = e_folder_exchange_bpropfind_start (hier->toplevel, NULL,
154
 
                                                  (const gchar **)hrefs->pdata,
155
 
                                                  hrefs->len,
156
 
                                                  folder_props,
157
 
                                                  n_folder_props);
158
 
 
159
 
        while ((result = e2k_result_iter_next (iter))) {
160
 
                folders_returned++;
161
 
 
162
 
                /* If you have "folder visible" permission but nothing
163
 
                 * else, you'll be able to fetch properties, but not
164
 
                 * see anything in the folder. In that case, PR_ACCESS
165
 
                 * will be 0, and we ignore the folder.
166
 
                 */
167
 
                if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (result->status) ||
168
 
                    folder_is_unreadable (result->props)) {
169
 
                        exchange_hierarchy_somedav_href_unreadable (hsd, result->href);
170
 
                        continue;
171
 
                }
172
 
 
173
 
                folders_added++;
174
 
                iter_folder = exchange_hierarchy_webdav_parse_folder (
175
 
                        EXCHANGE_HIERARCHY_WEBDAV (hier),
176
 
                        hier->toplevel, result);
177
 
                exchange_hierarchy_new_folder (hier, iter_folder);
178
 
                g_object_unref (iter_folder);
179
 
        }
180
 
        status = e2k_result_iter_free (iter);
181
 
 
182
 
        if (folders_returned == 0)
183
 
                folder_result = EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST;
184
 
        else if (folders_added == 0)
185
 
                folder_result = EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED;
186
 
        else
187
 
                folder_result = exchange_hierarchy_webdav_status_to_folder_result (status);
188
 
 
189
 
        for (i = 0; i < hrefs->len; i++)
190
 
                g_free (hrefs->pdata[i]);
191
 
        g_ptr_array_free (hrefs, TRUE);
192
 
 
193
 
        return folder_result;
194
 
}
195
 
 
196
 
GPtrArray *
197
 
exchange_hierarchy_somedav_get_hrefs (ExchangeHierarchySomeDAV *hsd)
198
 
{
199
 
        g_return_val_if_fail (EXCHANGE_IS_HIERARCHY_SOMEDAV (hsd), NULL);
200
 
 
201
 
        return EXCHANGE_GET_HIERARCHY_SOMEDAV_CLASS (hsd)->get_hrefs (hsd);
202
 
}
203
 
 
204
 
void
205
 
exchange_hierarchy_somedav_href_unreadable (ExchangeHierarchySomeDAV *hsd,
206
 
                                            const gchar *href)
207
 
{
208
 
        g_return_if_fail (EXCHANGE_IS_HIERARCHY_SOMEDAV (hsd));
209
 
        g_return_if_fail (href != NULL);
210
 
 
211
 
        g_signal_emit (hsd, signals[HREF_UNREADABLE], 0, href);
212
 
}
213
 
 
214
 
ExchangeAccountFolderResult
215
 
exchange_hierarchy_somedav_add_folder (ExchangeHierarchySomeDAV *hsd,
216
 
                                       const gchar *uri)
217
 
{
218
 
        ExchangeHierarchyWebDAV *hwd;
219
 
        ExchangeHierarchy *hier;
220
 
        E2kContext *ctx;
221
 
        E2kHTTPStatus status;
222
 
        E2kResult *results;
223
 
        gint nresults = 0;
224
 
        EFolder *folder;
225
 
 
226
 
        g_return_val_if_fail (EXCHANGE_IS_HIERARCHY_SOMEDAV (hsd),
227
 
                                EXCHANGE_ACCOUNT_FOLDER_GENERIC_ERROR);
228
 
        g_return_val_if_fail (uri != NULL,
229
 
                                EXCHANGE_ACCOUNT_FOLDER_GENERIC_ERROR);
230
 
 
231
 
        hwd = EXCHANGE_HIERARCHY_WEBDAV (hsd);
232
 
        hier = EXCHANGE_HIERARCHY (hsd);
233
 
        ctx = exchange_account_get_context (hier->account);
234
 
 
235
 
        status = e2k_context_propfind (ctx, NULL, uri,
236
 
                                       folder_props, n_folder_props,
237
 
                                       &results, &nresults);
238
 
        if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
239
 
                return exchange_hierarchy_webdav_status_to_folder_result (status);
240
 
 
241
 
        if (nresults == 0)
242
 
                return EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST;
243
 
 
244
 
        if (folder_is_unreadable (results[0].props)) {
245
 
                e2k_results_free (results, nresults);
246
 
                return EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED;
247
 
        }
248
 
 
249
 
        folder = exchange_hierarchy_webdav_parse_folder (hwd, hier->toplevel,
250
 
                                                         &results[0]);
251
 
        e2k_results_free (results, nresults);
252
 
 
253
 
        if (!folder)
254
 
                return EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST;
255
 
 
256
 
        exchange_hierarchy_new_folder (hier, folder);
257
 
        g_object_unref (folder);
258
 
        return EXCHANGE_ACCOUNT_FOLDER_OK;
259
 
}