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

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-06-21 14:38:41 UTC
  • mfrom: (1.1.80 upstream)
  • Revision ID: james.westby@ubuntu.com-20100621143841-pdgwume6r8rhzoyo
Tags: 2.30.2-0ubuntu1
* New upstream release:
  - Mail inline parser doesn't always work (Milan Crha) (LP: #219104)
  - Corruption of mailbox and can't expunge trash (Milan Crha)
    (LP: #286497, #325157)
  - WebDAV addressbook is too strict about content-type (Petr Tomasek)
  - Handle server's resource rename on WebDAV PUT response (Milan Crha)
  - Use NSS SQLite database, if available (Craig Ringer)
  - Fix NULL return without exception on krb5-auth-dialog
    failure (David Woodhouse)
  - Categories not translated in menus (Matthew Barnes) (LP: #443215)
  - Fix translation domain for default categories (Gert Michael Kulyk)
  - Mishandling of '@' in WebDAV contacts username (Milan Crha)
    (LP: #497146)
  - Use CRLF in signed & encrypted S/MIME messages
  - Remove superfluous space in flags in APPEND command (David Woodhouse)
  - Crash in gnome_keyring_item_info_free from e-passwords.c (Milan Crha)
  - Fix GSSAPI (and other SASL) authentication for imapx (David Woodhouse)
  - Teach camel_sexp_to_sql_sexp about no-arg (match-all)
    (Matt McCutchen 2)
  - Contacts are not displayed in GW Addressbook (Bharath Acharya)
  - Don't use an unitialized key in folder_changed_remove_uid
    (Claudio Saavedra)
  - Evolution didn't quit due to deadlock (Milan Crha)
  - Crash of e-addressbook-factory on second start of evolution (Milan Crha)
  - Fix translation of birthday and anniversary events (Gert Michael Kulyk)
  - Return formatted address in e_destination_get_address (David Ayers)
    (LP: #229187)
  - Add imap-over-custom-command support for imapx (David Woodhouse)
  - Fix fetch of large mails from broken servers like Exchange
    (David Woodhouse)
  - Fix double command ->complete() in imapx_command_start_next()
    (David Woodhouse)
  - Fix double-free of is->literal in cancel_all_jobs() (David Woodhouse)
  - use 'UID FETCH' instead of 'FETCH' for scan_changes (David Woodhouse)
  - Remove GroupWise debugging messages. (Matthew Barnes)
  - Bump libedataserver soname twice. (Matthew Barnes)
  - Check EBook DBus error names without underscores too (Milan Crha)
  - Create a section in the name selector dialog in its own function
    (Federico Mena Quintero)
  - Create the configdir instead of bailing out if it does not exist
    (Fridrich Štrba)
  -  Don't set a default vertical size for the name selector window
    (Federico Mena Quintero)
  - Fix locking issues in cancel_all_jobs() (David Woodhouse)
  - Fix pointlessly narrow default width in the name selection dialog
  - Name the pointless label at the top, so it can be disabled for MeeGo
    (Michael Meeks)
  - Fix tagprefix for multiple accounts. (David Woodhouse)
  - Fix typo in patch for bug on WebDAV (Milan Crha)
  - Put the name selector's section labels in the same row as the
    treeviews (Federico Mena Quintero)
  - Redo the container hierarchy in the name selector dialog
    (Federico Mena Quintero)
  - Remove an unused label in the name selector dialog
    (Federico Mena Quintero)
  - Remove border_width from the name selector's dialog toplevel
    contents (Federico Mena Quintero)
  - Shrink the spacing between the name selector's sections
    (Federico Mena Quintero)
  - Skip WebDAV responses which don't begin with BEGIN:VCARD (Milan Crha)
  - Specify the executable extension where applicable in the service
    files (Fridrich Štrba)
  - updated translations
* Removed patches from upstream:
  - debian/patches/01_unitialized_key.patch
  - debian/patches/02_fix-warning-in_source_get_uri.patch
  - debian/patches/03_bump-soname-libedataserver.patch
* debian/patches/25_mute-debug-messages.patch updated
* debian/patches/90_autoreconf.patch: refreshed

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include "camel/camel-private.h"
35
35
#include <camel/camel-tcp-stream-ssl.h>
36
36
#include <camel/camel-tcp-stream-raw.h>
 
37
#ifndef G_OS_WIN32
 
38
#include <camel/camel-stream-process.h>
 
39
#endif
37
40
#include <camel/camel-db.h>
38
41
 
39
42
#include <camel/camel-sasl.h>
289
292
                        const gchar *ofolder_name;
290
293
                        const gchar *nfolder_name;
291
294
                } rename_folder;
292
 
                
 
295
 
293
296
                const gchar *folder_name;
294
297
        } u;
295
298
};
617
620
                                        break;
618
621
                                case 'f': /* imap folder name */
619
622
                                        folder = va_arg(ap, CamelFolder *);
620
 
                                        c(printf("got folder '%s'\n", s));
 
623
                                        c(printf("got folder '%s'\n", folder->full_name));
621
624
                                        fname = camel_imapx_store_summary_full_from_path(((CamelIMAPXStore *) folder->parent_store)->summary, folder->full_name);
622
625
                                        if (fname) {
623
626
                                                encoded = camel_utf8_utf7(fname);
862
865
                                return;
863
866
                        }
864
867
                }
865
 
                
 
868
 
866
869
                c(printf("-- Checking job queue\n"));
867
870
                count = 0;
868
871
                ic = (CamelIMAPXCommand *)is->queue.head;
875
878
                                camel_dlist_remove((CamelDListNode *)ic);
876
879
                                imapx_command_start(is, ic);
877
880
                                count++;
878
 
                        } else 
 
881
                        } else
879
882
                                break;
880
883
                        ic = nc;
881
884
                        nc = nc->next;
900
903
                                c(printf("* queueing job %3d '%s'\n", (gint)ic->pri, ic->name));
901
904
                                pri = ic->pri;
902
905
                                camel_dlist_remove((CamelDListNode *)ic);
903
 
                                if (!imapx_command_start(is, ic)) {
904
 
                                        QUEUE_UNLOCK (is);
905
 
                                        ic->complete (is, ic);
906
 
                                        QUEUE_LOCK (is);
907
 
                                }
 
906
                                imapx_command_start(is, ic);
908
907
                                count++;
909
908
                        }
910
909
                        ic = nc;
1335
1334
 
1336
1335
                                        if (!camel_folder_summary_check_uid (job->folder->summary, mi->uid)) {
1337
1336
                                                CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *)job->folder;
1338
 
                                                
 
1337
 
1339
1338
                                                camel_folder_summary_add(job->folder->summary, mi);
1340
1339
                                                imapx_set_message_info_flags_for_new_message (mi, server_flags, server_user_flags, job->folder);
1341
1340
                                                camel_folder_change_info_add_uid (job->u.refresh_info.changes, mi->uid);
1487
1486
        case CAMEL_IMAPX_COMMAND_AUTH: {
1488
1487
                gchar *resp;
1489
1488
                guchar *token;
1490
 
                gint tok;
1491
 
                guint len;
1492
 
 
1493
 
                tok = camel_imapx_stream_token(imap->stream, &token, &len, ex);
 
1489
 
 
1490
                camel_imapx_stream_text (imap->stream, &token, ex);
 
1491
                if (camel_exception_is_set(ex))
 
1492
                        return -1;
 
1493
 
1494
1494
                resp = camel_sasl_challenge_base64((CamelSasl *)cp->ob, (const gchar *) token, ex);
 
1495
                g_free(token);
1495
1496
                if (camel_exception_is_set(ex))
1496
1497
                        return -1;
1497
1498
 
1502
1503
                /* we want to keep getting called until we get a status reponse from the server
1503
1504
                   ignore what sasl tells us */
1504
1505
                newliteral = ic;
1505
 
 
 
1506
                goto noskip;
1506
1507
                break; }
1507
1508
        case CAMEL_IMAPX_COMMAND_FILE: {
1508
1509
                CamelStream *file;
1528
1529
        }
1529
1530
 
1530
1531
        camel_imapx_stream_skip(imap->stream, ex);
1531
 
 
 
1532
 noskip:
1532
1533
        cp = cp->next;
1533
1534
        if (cp->next) {
1534
1535
                ic->current = cp;
1664
1665
        do {
1665
1666
                imapx_step(is, ic->ex);
1666
1667
        } while (ic->status == NULL && !camel_exception_is_set (ic->ex));
 
1668
        if (is->literal == ic)
 
1669
                is->literal = NULL;
1667
1670
 
1668
1671
        QUEUE_LOCK(is);
1669
1672
        camel_dlist_remove((CamelDListNode *)ic);
2104
2107
        imapx_command_start (is, ic);
2105
2108
}
2106
2109
 
 
2110
#ifndef G_OS_WIN32
 
2111
 
 
2112
/* Using custom commands to connect to IMAP servers is not supported on Win32 */
 
2113
 
 
2114
static gboolean
 
2115
connect_to_server_process (CamelIMAPXServer *is, const gchar *cmd, CamelException *ex)
 
2116
{
 
2117
        CamelIMAPXCommand *ic;
 
2118
        CamelStream *cmd_stream;
 
2119
        gint ret, i = 0;
 
2120
        gchar *buf;
 
2121
        gchar *cmd_copy;
 
2122
        gchar *full_cmd;
 
2123
        gchar *child_env[7];
 
2124
        guchar *buffer = NULL;
 
2125
        guint len;
 
2126
 
 
2127
        /* Put full details in the environment, in case the connection
 
2128
           program needs them */
 
2129
        buf = camel_url_to_string(is->url, 0);
 
2130
        child_env[i++] = g_strdup_printf("URL=%s", buf);
 
2131
        g_free(buf);
 
2132
 
 
2133
        child_env[i++] = g_strdup_printf("URLHOST=%s", is->url->host);
 
2134
        if (is->url->port)
 
2135
                child_env[i++] = g_strdup_printf("URLPORT=%d", is->url->port);
 
2136
        if (is->url->user)
 
2137
                child_env[i++] = g_strdup_printf("URLUSER=%s", is->url->user);
 
2138
        if (is->url->passwd)
 
2139
                child_env[i++] = g_strdup_printf("URLPASSWD=%s", is->url->passwd);
 
2140
        if (is->url->path)
 
2141
                child_env[i++] = g_strdup_printf("URLPATH=%s", is->url->path);
 
2142
        child_env[i] = NULL;
 
2143
 
 
2144
        /* Now do %h, %u, etc. substitution in cmd */
 
2145
        buf = cmd_copy = g_strdup(cmd);
 
2146
 
 
2147
        full_cmd = g_strdup("");
 
2148
 
 
2149
        for (;;) {
 
2150
                gchar *pc;
 
2151
                gchar *tmp;
 
2152
                gchar *var;
 
2153
                gint len;
 
2154
 
 
2155
                pc = strchr(buf, '%');
 
2156
        ignore:
 
2157
                if (!pc) {
 
2158
                        tmp = g_strdup_printf("%s%s", full_cmd, buf);
 
2159
                        g_free(full_cmd);
 
2160
                        full_cmd = tmp;
 
2161
                        break;
 
2162
                }
 
2163
 
 
2164
                len = pc - buf;
 
2165
 
 
2166
                var = NULL;
 
2167
 
 
2168
                switch (pc[1]) {
 
2169
                case 'h':
 
2170
                        var = is->url->host;
 
2171
                        break;
 
2172
                case 'u':
 
2173
                        var = is->url->user;
 
2174
                        break;
 
2175
                }
 
2176
                if (!var) {
 
2177
                        /* If there wasn't a valid %-code, with an actual
 
2178
                           variable to insert, pretend we didn't see the % */
 
2179
                        pc = strchr(pc + 1, '%');
 
2180
                        goto ignore;
 
2181
                }
 
2182
                tmp = g_strdup_printf("%s%.*s%s", full_cmd, len, buf, var);
 
2183
                g_free(full_cmd);
 
2184
                full_cmd = tmp;
 
2185
                buf = pc + 2;
 
2186
        }
 
2187
 
 
2188
        g_free(cmd_copy);
 
2189
 
 
2190
        cmd_stream = camel_stream_process_new ();
 
2191
 
 
2192
        ret = camel_stream_process_connect (CAMEL_STREAM_PROCESS(cmd_stream),
 
2193
                                            full_cmd, (const gchar **)child_env);
 
2194
 
 
2195
        while (i)
 
2196
                g_free(child_env[--i]);
 
2197
 
 
2198
        if (ret == -1) {
 
2199
                if (errno == EINTR)
 
2200
                        camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
 
2201
                                             _("Connection cancelled"));
 
2202
                else
 
2203
                        camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
 
2204
                                              _("Could not connect with command \"%s\": %s"),
 
2205
                                              full_cmd, g_strerror (errno));
 
2206
 
 
2207
                camel_object_unref (cmd_stream);
 
2208
                g_free (full_cmd);
 
2209
                return FALSE;
 
2210
        }
 
2211
        g_free (full_cmd);
 
2212
 
 
2213
        is->stream = (CamelIMAPXStream *) camel_imapx_stream_new(cmd_stream);
 
2214
        camel_object_unref(cmd_stream);
 
2215
        is->is_process_stream = TRUE;
 
2216
 
 
2217
        camel_imapx_stream_gets (is->stream, &buffer, &len);
 
2218
        e(printf("Got greeting '%.*s'\n", len, buffer));
 
2219
 
 
2220
        if (!buffer) {
 
2221
                camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
 
2222
                                     "No response from server.\n");
 
2223
                return FALSE;
 
2224
        } else if (!strncmp((gchar *)buffer, "* PREAUTH", 9)) {
 
2225
                is->state = IMAPX_AUTHENTICATED;
 
2226
        } else if (strncmp((gchar *)buffer, "* OK", 4)) {
 
2227
                camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
 
2228
                                     "Unrecognised greeting from server: %.*s\n",
 
2229
                                     len, buffer);
 
2230
                return FALSE;
 
2231
        }
 
2232
 
 
2233
        ic = camel_imapx_command_new("CAPABILITY", NULL, "CAPABILITY");
 
2234
        imapx_command_run(is, ic);
 
2235
 
 
2236
        if (camel_exception_is_set (ic->ex) || ic->status->result != IMAPX_OK) {
 
2237
                if (!camel_exception_is_set (ic->ex))
 
2238
                        camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, "%s", ic->status->text);
 
2239
                else
 
2240
                        camel_exception_xfer (ex, ic->ex);
 
2241
 
 
2242
                camel_imapx_command_free(ic);
 
2243
                return FALSE;
 
2244
        }
 
2245
        camel_imapx_command_free(ic);
 
2246
 
 
2247
        return TRUE;
 
2248
}
 
2249
#endif /* G_OS_WIN32 */
 
2250
 
2107
2251
gboolean
2108
2252
imapx_connect_to_server (CamelIMAPXServer *is, CamelException *ex)
2109
2253
{
2121
2265
        struct addrinfo *ai, hints = { 0 };
2122
2266
        CamelIMAPXCommand *ic;
2123
2267
 
 
2268
#ifndef G_OS_WIN32
 
2269
        const gchar *command;
 
2270
 
 
2271
        if (camel_url_get_param(is->url, "use_command") &&
 
2272
            (command = camel_url_get_param(is->url, "command"))) {
 
2273
                connect_to_server_process(is, command, ex);
 
2274
                goto exit;
 
2275
        }
 
2276
#endif
2124
2277
        if (is->url->port) {
2125
2278
                serv = g_alloca(16);
2126
2279
                sprintf((gchar *) serv, "%d", is->url->port);
2220
2373
 
2221
2374
                ic = camel_imapx_command_new ("STARTTLS", NULL, "STARTTLS");
2222
2375
                imapx_command_run (is, ic);
2223
 
                
 
2376
 
2224
2377
                if (camel_exception_is_set (ic->ex) || ic->status->result != IMAPX_OK) {
2225
2378
                        if (!camel_exception_is_set (ic->ex))
2226
2379
                                camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, "%s", ic->status->text);
2227
2380
                        else
2228
2381
                                camel_exception_xfer (ex, ic->ex);
2229
2382
 
2230
 
 
2231
2383
                        camel_imapx_command_free(ic);
2232
2384
                        goto exit;
2233
2385
                }
2247
2399
                e(printf("Unable to connect %d %s \n", ex->id, ex->desc));
2248
2400
                camel_object_unref (is->stream);
2249
2401
                is->stream = NULL;
2250
 
                
 
2402
 
2251
2403
                if (is->cinfo) {
2252
2404
                        imapx_free_capability(is->cinfo);
2253
2405
                        is->cinfo = NULL;
2268
2420
        CamelService *service = (CamelService *) is->store;
2269
2421
        const gchar *auth_domain = NULL;
2270
2422
        gboolean authenticated = FALSE;
 
2423
        CamelServiceAuthType *authtype = NULL;
2271
2424
 
2272
2425
        while (!authenticated) {
2273
2426
                if (errbuf) {
2282
2435
                if (camel_exception_is_set (ex))
2283
2436
                        goto exception;
2284
2437
 
2285
 
                if (service->url->passwd == NULL) {
 
2438
                if (is->state == IMAPX_AUTHENTICATED)
 
2439
                        break;
 
2440
 
 
2441
                if (!authtype && service->url->authmech) {
 
2442
                        if (is->cinfo && !g_hash_table_lookup (is->cinfo->auth_types, service->url->authmech)) {
 
2443
                                camel_exception_setv (
 
2444
                                        ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
 
2445
                                        _("IMAP server %s does not support requested "
 
2446
                                          "authentication type %s"),
 
2447
                                        service->url->host,
 
2448
                                        service->url->authmech);
 
2449
                                goto exception;
 
2450
                        }
 
2451
 
 
2452
                        authtype = camel_sasl_authtype (service->url->authmech);
 
2453
                        if (!authtype) {
 
2454
                                camel_exception_setv (
 
2455
                                        ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
 
2456
                                        _("No support for authentication type %s"),
 
2457
                                        service->url->authmech);
 
2458
                                goto exception;
 
2459
                        }
 
2460
                }
 
2461
 
 
2462
                if (service->url->passwd == NULL && (!authtype || authtype->need_password)) {
2286
2463
                        gchar *base_prompt;
2287
2464
                        gchar *full_prompt;
2288
2465
 
2311
2488
                        }
2312
2489
                }
2313
2490
 
2314
 
                if (service->url->authmech
2315
 
                                && (sasl = camel_sasl_new("imap", service->url->authmech, NULL))) {
2316
 
                        ic = camel_imapx_command_new("AUTHENTICATE", NULL, "AUTHENTICATE %A", sasl);
 
2491
                if (authtype && (sasl = camel_sasl_new ("imap", authtype->authproto, service))) {
 
2492
                        ic = camel_imapx_command_new ("AUTHENTICATE", NULL, "AUTHENTICATE %A", sasl);
2317
2493
                        camel_object_unref(sasl);
2318
2494
                } else {
2319
2495
                        ic = camel_imapx_command_new("LOGIN", NULL, "LOGIN %s %s", service->url->user, service->url->passwd);
2324
2500
                if (!(camel_exception_is_set (ic->ex) || ic->status->result != IMAPX_OK))
2325
2501
                        authenticated = TRUE;
2326
2502
                else {
2327
 
                        /* If exception is set, it might be mostly due to cancellation and we would get an 
 
2503
                        /* If exception is set, it might be mostly due to cancellation and we would get an
2328
2504
                           io error, else re-prompt. If authentication fails for other reasons ic->status would be
2329
2505
                            set with the error message */
2330
2506
                        if (camel_exception_is_set (ic->ex)) {
2339
2515
                        camel_exception_clear (ex);
2340
2516
 
2341
2517
                }
2342
 
                
 
2518
 
2343
2519
                camel_imapx_command_free(ic);
2344
2520
        }
2345
 
        
 
2521
 
2346
2522
        /* After login we re-capa */
2347
2523
        if (is->cinfo) {
2348
2524
                imapx_free_capability(is->cinfo);
2363
2539
                is->use_idle = TRUE;
2364
2540
        else
2365
2541
                is->use_idle = FALSE;
2366
 
        
 
2542
 
2367
2543
        if (imapx_idle_supported (is))
2368
2544
                imapx_init_idle (is);
2369
2545
 
2401
2577
 
2402
2578
exception:
2403
2579
        imapx_disconnect (is);
2404
 
        
 
2580
 
2405
2581
        if (is->cinfo) {
2406
2582
                imapx_free_capability(is->cinfo);
2407
2583
                is->cinfo = NULL;
2426
2602
                failed = TRUE;
2427
2603
                job->u.get_message.body_len = -1;
2428
2604
        } else  if (job->u.get_message.use_multi_fetch) {
2429
 
 
2430
 
                if (!failed && job->u.get_message.fetch_offset <= job->u.get_message.size) {
 
2605
                gsize really_fetched = CAMEL_SEEKABLE_STREAM(job->u.get_message.stream)->position;
 
2606
                /* Don't automatically stop when we reach the reported message
 
2607
                   size -- some crappy servers (like Microsoft Exchange) have
 
2608
                   a tendency to lie about it. Keep going (one request at a
 
2609
                   time) until the data actually stop coming. */
 
2610
                if (job->u.get_message.fetch_offset < job->u.get_message.size ||
 
2611
                    job->u.get_message.fetch_offset == really_fetched) {
2431
2612
                        camel_imapx_command_free (ic);
2432
2613
                        if (job->op)
2433
2614
                                camel_operation_progress (job->op, (job->u.get_message.fetch_offset *100)/job->u.get_message.size);
2582
2763
        /* TODO copy the summary and cached messages to the new folder. We might need a sorted insert to avoid refreshing the dest folder */
2583
2764
        if (ic->status->condition == IMAPX_COPYUID) {
2584
2765
                gint i;
2585
 
                
 
2766
 
2586
2767
                for (i = 0; i < ic->status->u.copyuid.copied_uids->len; i++) {
2587
2768
                        guint32 uid = GPOINTER_TO_UINT(g_ptr_array_index (ic->status->u.copyuid.copied_uids, i));
2588
2769
                        gchar *str = g_strdup_printf ("%d",uid);
2589
2770
                        CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) job->u.copy_messages.dest;
2590
 
                        
 
2771
 
2591
2772
                        g_hash_table_insert (ifolder->ignore_recent, str, GINT_TO_POINTER (1));
2592
2773
                }
2593
 
                                
 
2774
 
2594
2775
        }
2595
2776
 
2596
2777
        if (i < uids->len) {
3008
3189
        camel_operation_start (job->op, _("Scanning for changed messages in %s"), job->folder->name);
3009
3190
 
3010
3191
        ic = camel_imapx_command_new ("FETCH", job->folder->full_name,
3011
 
                                     "FETCH 1:* (UID FLAGS)");
 
3192
                                     "UID FETCH 1:* (UID FLAGS)");
3012
3193
        ic->job = job;
3013
3194
        ic->complete = imapx_job_scan_changes_done;
3014
3195
        ic->pri = job->pri;
3248
3429
}
3249
3430
/* ********************************************************************** */
3250
3431
 
3251
 
 
3252
3432
static gchar *
3253
3433
imapx_encode_folder_name (CamelIMAPXStore *istore, const gchar *folder_name)
3254
3434
{
3260
3440
                g_free (fname);
3261
3441
        } else
3262
3442
                encoded = camel_utf8_utf7 (folder_name);
3263
 
        
 
3443
 
3264
3444
        return encoded;
3265
3445
}
3266
3446
 
3284
3464
        CamelIMAPXCommand *ic;
3285
3465
        const gchar *str = NULL;
3286
3466
        gchar *encoded_fname = NULL;
3287
 
        
3288
 
        
 
3467
 
3289
3468
        if (job->u.manage_subscriptions.subscribe)
3290
3469
                str = "SUBSCRIBE";
3291
3470
        else
3293
3472
 
3294
3473
        encoded_fname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.manage_subscriptions.folder_name);
3295
3474
        ic = camel_imapx_command_new (str, NULL, "%s %s", str, encoded_fname);
3296
 
        
 
3475
 
3297
3476
        ic->pri = job->pri;
3298
3477
        ic->job = job;
3299
3478
        ic->complete = imapx_command_subscription_done;
3392
3571
 
3393
3572
        en_ofname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.rename_folder.ofolder_name);
3394
3573
        en_nfname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.rename_folder.nfolder_name);
3395
 
        
 
3574
 
3396
3575
        ic = camel_imapx_command_new ("RENAME", "INBOX", "RENAME %s %s", en_ofname, en_nfname);
3397
3576
        ic->pri = job->pri;
3398
3577
        ic->job = job;
3632
3811
static void
3633
3812
cancel_all_jobs (CamelIMAPXServer *is, CamelException *ex)
3634
3813
{
3635
 
        CamelIMAPXCommand *cw, *cn;
 
3814
        CamelIMAPXCommand **cw, *ic;
3636
3815
        gint i = 0;
3637
3816
 
3638
3817
        while (i < 2) {
3639
3818
                QUEUE_LOCK(is);
3640
3819
                if (i == 1)
3641
 
                        cw = (CamelIMAPXCommand *) is->queue.head;
 
3820
                        cw = (CamelIMAPXCommand **) &is->queue.head;
3642
3821
                else
3643
 
                        cw = (CamelIMAPXCommand *) is->active.head;
3644
 
 
3645
 
                cn = cw->next;
 
3822
                        cw = (CamelIMAPXCommand **) &is->active.head;
 
3823
 
 
3824
                while ((*cw)->next) {
 
3825
                        ic = *cw;
 
3826
                        camel_dlist_remove ((CamelDListNode *)ic);
 
3827
                        QUEUE_UNLOCK(is);
 
3828
 
 
3829
                        camel_exception_set (ic->ex, ex->id, ex->desc);
 
3830
                        ic->complete (is, ic);
 
3831
 
 
3832
                        QUEUE_LOCK(is);
 
3833
                }
3646
3834
                QUEUE_UNLOCK(is);
3647
 
 
3648
 
                while (cn) {
3649
 
                        QUEUE_LOCK(is);
3650
 
                        camel_dlist_remove ((CamelDListNode *)cw);
3651
 
                        QUEUE_UNLOCK(is);
3652
 
 
3653
 
                        camel_exception_set (cw->ex, ex->id, ex->desc);
3654
 
 
3655
 
                        cw->complete (is, cw);
3656
 
                        cw = cn;
3657
 
 
3658
 
                        QUEUE_LOCK(is);
3659
 
                        cn = cn->next;
3660
 
                        QUEUE_UNLOCK(is);
3661
 
                }
3662
 
 
3663
3835
                i++;
3664
3836
        }
3665
3837
}
3722
3894
                                errno = EINTR;
3723
3895
                }
3724
3896
#endif
3725
 
 
3726
 
                if (!is->is_ssl_stream) {
 
3897
#ifndef G_OS_WIN32
 
3898
                if (is->is_process_stream)      {
 
3899
                        GPollFD fds[2] = { {0, 0, 0}, {0, 0, 0} };
 
3900
                        gint res;
 
3901
 
 
3902
                        fds[0].fd = ((CamelStreamProcess *)is->stream->source)->sockfd;
 
3903
                        fds[0].events = G_IO_IN;
 
3904
                        fds[1].fd = camel_operation_cancel_fd (op);
 
3905
                        fds[1].events = G_IO_IN;
 
3906
                        res = g_poll(fds, 2, 1000*30);
 
3907
                        if (res == -1)
 
3908
                                g_usleep(1) /* ?? */ ;
 
3909
                        else if (res == 0)
 
3910
                                /* timed out */;
 
3911
                        else if (fds[0].revents & G_IO_IN) {
 
3912
                                parse_contents (is, &ex);
 
3913
                        } else if (fds[1].revents & G_IO_IN)
 
3914
                                errno = EINTR;
 
3915
                }
 
3916
#endif
 
3917
 
 
3918
                if (!is->is_ssl_stream && !is->is_process_stream) {
3727
3919
                        GPollFD fds[2] = { {0, 0, 0}, {0, 0, 0} };
3728
3920
                        gint res;
3729
3921
 
3807
3999
        isclass->tagprefix++;
3808
4000
        if (isclass->tagprefix > 'Z')
3809
4001
                isclass->tagprefix = 'A';
3810
 
        is->tagprefix = 'A';
3811
4002
 
3812
4003
        is->state = IMAPX_DISCONNECTED;
3813
4004
 
3892
4083
                is->select_pending = NULL;
3893
4084
        }
3894
4085
 
3895
 
        if (is->literal) {
3896
 
                camel_imapx_command_free (is->literal);
3897
 
                is->literal = NULL;
3898
 
        }
3899
 
 
3900
4086
        if (is->cinfo) {
3901
4087
                imapx_free_capability(is->cinfo);
3902
 
                is->cinfo = NULL;       
 
4088
                is->cinfo = NULL;
3903
4089
        }
3904
4090
 
3905
4091
        is->state = IMAPX_DISCONNECTED;
3968
4154
 
3969
4155
        if ((job = imapx_is_job_in_queue (is, folder->full_name, IMAPX_JOB_GET_MESSAGE, uid))) {
3970
4156
                flag = g_hash_table_lookup (is->uid_eflags, uid);
3971
 
        
 
4157
 
3972
4158
                if (pri > job->pri)
3973
4159
                        job->pri = pri;
3974
 
        
 
4160
 
3975
4161
                QUEUE_UNLOCK (is);
3976
4162
 
3977
4163
                e_flag_wait (flag);
3978
 
                
 
4164
 
3979
4165
                stream = camel_data_cache_get (ifolder->cache, "cur", uid, NULL);
3980
4166
                if (!stream)
3981
4167
                        camel_exception_set (ex, 1, "Could not retrieve the message");
4017
4203
 
4018
4204
        if (registered)
4019
4205
                imapx_run_job(is, job);
4020
 
        
 
4206
 
4021
4207
        e_flag_set (flag);
4022
4208
        if (!camel_exception_is_set (job->ex))
4023
4209
                stream = job->u.get_message.stream;
4024
 
        
 
4210
 
4025
4211
        g_free(job);
4026
4212
 
4027
4213
        /* HACK FIXME just sleep for sometime so that the other waiting locks gets released by that time. Think of a
4504
4690
camel_imapx_server_manage_subscription (CamelIMAPXServer *is, const gchar *folder_name, gboolean subscribe, CamelException *ex)
4505
4691
{
4506
4692
        CamelIMAPXJob *job;
4507
 
        
 
4693
 
4508
4694
        job = g_malloc0(sizeof(*job));
4509
4695
        job->type = IMAPX_JOB_MANAGE_SUBSCRIPTION;
4510
4696
        job->start = imapx_job_manage_subscription_start;
4512
4698
        job->ex = ex;
4513
4699
        job->u.manage_subscriptions.subscribe = subscribe;
4514
4700
        job->u.manage_subscriptions.folder_name = folder_name;
4515
 
        
 
4701
 
4516
4702
        if (imapx_register_job (is, job))
4517
4703
                imapx_run_job (is, job);
4518
4704
 
4523
4709
camel_imapx_server_create_folder (CamelIMAPXServer *is, const gchar *folder_name, CamelException *ex)
4524
4710
{
4525
4711
        CamelIMAPXJob *job;
4526
 
        
 
4712
 
4527
4713
        job = g_malloc0(sizeof(*job));
4528
4714
        job->type = IMAPX_JOB_CREATE_FOLDER;
4529
4715
        job->start = imapx_job_create_folder_start;
4541
4727
camel_imapx_server_delete_folder (CamelIMAPXServer *is, const gchar *folder_name, CamelException *ex)
4542
4728
{
4543
4729
        CamelIMAPXJob *job;
4544
 
        
 
4730
 
4545
4731
        job = g_malloc0(sizeof(*job));
4546
4732
        job->type = IMAPX_JOB_DELETE_FOLDER;
4547
4733
        job->start = imapx_job_delete_folder_start;
4559
4745
camel_imapx_server_rename_folder (CamelIMAPXServer *is, const gchar *old_name, const gchar *new_name, CamelException *ex)
4560
4746
{
4561
4747
        CamelIMAPXJob *job;
4562
 
        
 
4748
 
4563
4749
        job = g_malloc0(sizeof(*job));
4564
4750
        job->type = IMAPX_JOB_RENAME_FOLDER;
4565
4751
        job->start = imapx_job_rename_folder_start;