Changeset 3070

Show
Ignore:
Timestamp:
12/05/07 21:15:28
Author:
pvanhoof
Message:

2007-12-05 Philip Van Hoof <pvanhoof@gnome.org>

        • Merged all of devel/pvanhoof/bs branch back
        • Disabled the bodystruct mime part and fetching for now
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ChangeLog

    r3069 r3070  
     12007-12-05  Philip Van Hoof  <pvanhoof@gnome.org> 
     2 
     3        * Merged all of devel/pvanhoof/bs branch back 
     4        * Disabled the bodystruct mime part and fetching for now 
     5 
    162007-12-04  Jose Dapena Paz  <jdapena@igalia.com> 
    27 
     
    4853        * add a dummy conic device, so libtinymail-maemo does 
    4954          not require libconic anymore 
     55 
     562007-12-02  Philip Van Hoof  <pvanhoof@gnome.org> 
     57 
     58        * Merging with trunk 
     59 
     602007-12-02  Philip Van Hoof  <pvanhoof@gnome.org> 
     61 
     62        * Fixed tny_mime_part_add of TnyCamelMimePart to fully cope with alien 
     63        mime parts 
     64 
     652007-11-30  Philip Van Hoof  <pvanhoof@gnome.org> 
     66 
     67        * Merging with trunk 
     68 
     692007-11-29  Philip Van Hoof  <pvanhoof@gnome.org> 
     70 
     71        * Fixed mime part purging 
     72        * Fixed status information notifying 
     73        * Added TnyGtkExpanderMimePartView 
     74 
     752007-11-28  Philip Van Hoof  <pvanhoof@gnome.org> 
     76 
     77        * Several fixes. in the bodystructure parsing 
     78        * Several fixes in the mime part handling 
     79        * Changed the API of mime part viewers to have a status 
     80        callback. 
     81 
     82        * This was a major API change in libtinymail and libtinymailui 
     83 
     842007-11-27  Philip Van Hoof  <pvanhoof@gnome.org> 
     85 
     86        * Branchpoint bodystructure work 
    5087 
    51882007-11-25  Philip Van Hoof  <pvanhoof@gnome.org> 
  • trunk/config.h.in

    r3027 r3070  
    5858#undef HAVE_UNISTD_H 
    5959 
    60 /* "whether the dummy libconic should be built" */ 
    61 #undef LIBTINYMAIL_MAEMO_WITHOUT_CONIC 
    62  
    6360/* "Whether to hack the TnyMaemoConicDevice to somewhat work in sbox" */ 
    6461#undef MAEMO_CONIC_DUMMY 
     62 
     63/* "whether libconic is available" */ 
     64#undef MAEMO_HAVE_CONIC 
    6565 
    6666/* Detected mozilla engine version for mozembed */ 
  • trunk/configure.ac

    r3010 r3070  
    439439                        AC_DEFINE_UNQUOTED(MAEMO_CONIC_DUMMY,1,["Whether to hack the TnyMaemoConicDevice to somewhat work in sbox"]) 
    440440                fi 
    441         else 
    442                 AC_DEFINE_UNQUOTED(LIBTINYMAIL_MAEMO_WITHOUT_CONIC,1,["whether the dummy libconic should be built"]) 
     441                AC_DEFINE_UNQUOTED(MAEMO_HAVE_CONIC,1,["whether libconic is available"]) 
    443442        fi 
    444443 
     
    513512libtinymail-camel/Makefile 
    514513libtinymail-camel/libtinymail-camel.pc 
     514libtinymail-camel/bs/Makefile 
    515515libtinymail-tp/libtinymail-tp.pc 
    516516libtinymail-tp/Makefile 
  • trunk/libtinymail-camel/Makefile.am

    r2488 r3070  
    1 SUBDIRS = camel-lite
     1SUBDIRS = camel-lite bs
    22 
    33INCLUDES = $(LIBTINYMAIL_CAMEL_CFLAGS)          \ 
     
    3131        tny-camel-send-queue.h \ 
    3232        tny-camel-mem-stream.h \ 
    33         tny-session-camel.h 
     33        tny-session-camel.h \ 
     34        tny-camel-bs-msg.h \ 
     35        tny-camel-bs-mime-part.h \ 
     36        tny-camel-bs-msg-receive-strategy.h 
    3437 
    3538libtinymail_camel_priv_headers = \ 
     
    4952        tny-camel-folder-priv.h \ 
    5053        tny-camel-stream-priv.h \ 
    51         tny-camel-queue-priv.h 
     54        tny-camel-queue-priv.h \ 
     55        tny-camel-bs-msg-priv.h \ 
     56        tny-camel-bs-mime-part-priv.h \ 
     57        tny-camel-bs-msg-header-priv.h 
    5258 
    5359libtinymail_camel_1_0_la_SOURCES = \ 
     
    7985        tny-camel-mem-stream.c \ 
    8086        tny-session-camel.c \ 
    81         tny-camel-queue.c                        
     87        tny-camel-queue.c \ 
     88        tny-camel-bs-msg.c \ 
     89        tny-camel-bs-mime-part.c \ 
     90        tny-camel-bs-msg-receive-strategy.c \ 
     91        tny-camel-bs-msg-header.c 
    8292 
    8393libtinymail_camel_1_0_la_LIBADD = \ 
     
    8595        $(top_builddir)/libtinymail-camel/camel-lite/camel/libcamel-lite-1.2.la \ 
    8696        $(top_builddir)/libtinymail-camel/camel-lite/camel/libcamel-lite-provider-1.2.la \ 
    87         $(top_builddir)/libtinymail/libtinymail-$(API_VERSION).la  
     97        $(top_builddir)/libtinymail/libtinymail-$(API_VERSION).la \ 
     98        $(top_builddir)/libtinymail-camel/bs/libbodystruct.a  
    8899 
    89100libtinymail_camel_1_0_la_LDFLAGS = -export-dynamic -version-info \ 
  • trunk/libtinymail-camel/camel-lite/camel/camel-folder.c

    r2950 r3070  
    4444#include "camel-store.h" 
    4545#include "camel-vtrash-folder.h" 
     46#include "camel-multipart.h" 
    4647 
    4748#define d(x) 
     
    118119static int get_local_size (CamelFolder *folder); 
    119120 
     121 
     122static char * 
     123fetch_structure (CamelFolder *folder, const char *uid, CamelException *ex) 
     124{ 
     125        camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, "No support for BODYSTRUCTURE"); 
     126        return NULL; 
     127} 
     128 
     129char * 
     130camel_folder_fetch_structure (CamelFolder *folder, const char *uid, CamelException *ex) 
     131{ 
     132        return CF_CLASS (folder)->fetch_structure (folder, uid, ex); 
     133} 
     134 
     135static char * 
     136get_cache_filename (CamelFolder *folder, const char *uid, const char *spec, CamelFolderPartState *state) 
     137{ 
     138        *state = CAMEL_FOLDER_PART_STATE_NOT_CACHED; 
     139        return NULL; 
     140} 
     141 
     142char * 
     143camel_folder_get_cache_filename (CamelFolder *folder, const char *uid, const char *spec, CamelFolderPartState *state) 
     144{ 
     145        return CF_CLASS (folder)->get_cache_filename (folder, uid, spec, state); 
     146} 
     147 
     148static char *  
     149fetch (CamelFolder *folder, const char *uid, const char *spec, gboolean *binary, CamelException *ex) 
     150{ 
     151        if (binary) 
     152                *binary = TRUE; 
     153        camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, "No support for BODYSTRUCTURE"); 
     154        return g_strdup ("/dev/null"); 
     155} 
     156 
     157static char *  
     158convert (CamelFolder *folder, const char *uid, const char *spec, const char *cto, CamelException *ex) 
     159{ 
     160        camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, "No support for CONVERT"); 
     161        return g_strdup ("/dev/null"); 
     162} 
     163 
     164char*  
     165camel_folder_convert (CamelFolder *folder, const char *uid, const char *spec, const char *convert_to, CamelException *ex) 
     166{ 
     167        return CF_CLASS (folder)->convert (folder, uid, spec, convert_to, ex); 
     168} 
     169 
     170char *  
     171camel_folder_fetch (CamelFolder *folder, const char *uid, const char *spec, gboolean *binary, CamelException *ex) 
     172{ 
     173        return CF_CLASS (folder)->fetch (folder, uid, spec, binary, ex); 
     174} 
     175 
    120176static void 
    121177delete_attachments (CamelFolder *folder, const char *uid) 
     
    151207 
    152208        /* virtual method definition */ 
     209        camel_folder_class->convert = convert; 
     210        camel_folder_class->get_cache_filename = get_cache_filename; 
     211        camel_folder_class->fetch_structure = fetch_structure; 
     212        camel_folder_class->fetch = fetch; 
    153213        camel_folder_class->get_local_size = get_local_size; 
    154214        camel_folder_class->set_push_email = folder_set_push_email; 
  • trunk/libtinymail-camel/camel-lite/camel/camel-folder.h

    r2950 r3070  
    4040        CAMEL_FOLDER_RECEIVE_PARTIAL = 1<<1, 
    4141        CAMEL_FOLDER_RECEIVE_ANY_OR_FULL = 1<<2, 
    42         CAMEL_FOLDER_RECEIVE_ANY_OR_PARTIAL = 1<<3 
     42        CAMEL_FOLDER_RECEIVE_ANY_OR_PARTIAL = 1<<3, 
     43        CAMEL_FOLDER_RECEIVE_PART_SPEC = 1<<4 
     44}; 
     45 
     46enum _CamelFolderPartState { 
     47        CAMEL_FOLDER_PART_STATE_CACHED_BINARY, 
     48        CAMEL_FOLDER_PART_STATE_CACHED_ENCODED, 
     49        CAMEL_FOLDER_PART_STATE_CACHED_CONVERTED, 
     50        CAMEL_FOLDER_PART_STATE_NOT_CACHED 
    4351}; 
    4452 
    4553typedef enum _CamelFolderReceiveType CamelFolderReceiveType; 
     54typedef enum _CamelFolderPartState CamelFolderPartState; 
    4655 
    4756G_BEGIN_DECLS 
     
    208217        void (*rewrite_cache) (CamelFolder *folder, const char *uid, CamelMimeMessage *msg); 
    209218 
     219        char* (*get_cache_filename) (CamelFolder *folder, const char *uid, const char *spec, CamelFolderPartState *state); 
     220        char* (*fetch) (CamelFolder *folder, const char *uid, const char *spec, gboolean *binary, CamelException *ex); 
     221        char* (*fetch_structure) (CamelFolder *folder, const char *uid, CamelException *ex); 
     222        char* (*convert) (CamelFolder *folder, const char *uid, const char *spec, const char *convert_to, CamelException *ex); 
     223 
    210224} CamelFolderClass; 
    211225 
     
    367381void camel_folder_rewrite_cache (CamelFolder *folder, const char *uid, CamelMimeMessage *msg); 
    368382 
     383char* camel_folder_fetch (CamelFolder *folder, const char *uid, const char *spec, gboolean *binary, CamelException *ex); 
     384char* camel_folder_fetch_structure (CamelFolder *folder, const char *uid, CamelException *ex); 
     385char* camel_folder_get_cache_filename (CamelFolder *folder, const char *uid, const char *spec, CamelFolderPartState *state); 
     386char* camel_folder_convert (CamelFolder *folder, const char *uid, const char *spec, const char *convert_to, CamelException *ex); 
     387 
    369388G_END_DECLS 
    370389 
  • trunk/libtinymail-camel/camel-lite/camel/camel.c

    r2950 r3070  
    5959         * But they shouldn't be necessary as the process is exiting anywy? 
    6060         */ 
    61         NSS_Shutdown (); 
     61        /* NSS_Shutdown (); 
    6262 
    63         PR_Cleanup (); 
     63        PR_Cleanup (); */ 
    6464#endif /* HAVE_NSS */ 
    6565 
  • trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c

    r3045 r3070  
    6060#include <libedataserver/e-time-utils.h> 
    6161 
     62#include "camel-stream-fs.h" 
    6263 
    6364#include "camel-data-wrapper.h" 
     
    125126 
    126127 
     128static char* imap_fetch (CamelFolder *folder, const char *uid, const char *spec, gboolean *binary, CamelException *ex); 
     129static char* imap_get_cache_filename (CamelFolder *folder, const char *uid, const char *spec, CamelFolderPartState *state); 
     130static char* imap_fetch_structure (CamelFolder *folder, const char *uid, CamelException *ex); 
     131static char* imap_convert (CamelFolder *folder, const char *uid, const char *spec, const char *convert_to, CamelException *ex); 
     132 
    127133/* message manipulation */ 
    128134static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid, 
     
    193199        ((CamelObjectClass *)camel_imap_folder_class)->getv = imap_getv; 
    194200 
     201        camel_folder_class->convert = imap_convert; 
     202        camel_folder_class->get_cache_filename = imap_get_cache_filename; 
     203        camel_folder_class->fetch = imap_fetch; 
     204        camel_folder_class->fetch_structure = imap_fetch_structure; 
    195205        camel_folder_class->get_local_size = imap_get_local_size; 
    196206        camel_folder_class->set_push_email = imap_set_push_email; 
     
    43474357} 
    43484358 
    4349 CamelStream * 
    4350 camel_imap_folder_fetch_data (CamelImapFolder *imap_folder, const char *uid, 
    4351                               const char *section_text, gboolean cache_only, 
    4352                               CamelFolderReceiveType type, gint param, CamelException *ex) 
    4353 
    4354         CamelFolder *folder = CAMEL_FOLDER (imap_folder); 
    4355         CamelImapStore *store = NULL; 
    4356         CamelStream *stream = NULL; 
    4357         gboolean connected = FALSE, ctchecker=FALSE; 
    4358         CamelException  tex = CAMEL_EXCEPTION_INITIALISER; 
    4359         ssize_t nread = 0; gboolean amcon = FALSE; 
    4360         gchar *errmessage = NULL; 
    4361         gboolean retry = TRUE; 
    4362         int ex_id = CAMEL_EXCEPTION_FOLDER_INVALID_STATE; 
    4363  
    4364         CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock); 
    4365  
    4366         connected = camel_disco_store_check_online(CAMEL_DISCO_STORE (folder->parent_store), &tex); 
    4367  
    4368         if (connected && ((type & CAMEL_FOLDER_RECEIVE_FULL) && camel_imap_message_cache_is_partial (imap_folder->cache, uid))) 
    4369         { 
    4370  
    4371                 camel_imap_message_cache_remove (imap_folder->cache, uid); 
    4372  
    4373         } else if (connected && ((type & CAMEL_FOLDER_RECEIVE_PARTIAL) 
    4374                         && !camel_imap_message_cache_is_partial (imap_folder->cache, uid))) 
    4375         { 
    4376  
    4377                 camel_imap_message_cache_remove (imap_folder->cache, uid); 
    4378  
    4379         } else { 
    4380                 stream = camel_imap_message_cache_get (imap_folder->cache, uid, section_text, ex); 
    4381                 if (!stream && (!strcmp (section_text, "HEADER") || !strcmp (section_text, "0"))) 
    4382                 { 
    4383                         camel_exception_clear (ex); 
    4384                         stream = camel_imap_message_cache_get (imap_folder->cache, uid, "", ex); 
    4385                 } 
    4386         } 
    4387         CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock); 
    4388  
    4389         if (stream || cache_only) 
    4390                 return stream; 
    4391  
    4392         if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (folder->parent_store), ex)) 
    4393         { 
    4394                 camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, 
    4395                                      _("This message is not currently available")); 
    4396                 CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock); 
    4397                 return NULL; 
    4398         } 
    4399         camel_exception_clear (ex); 
    4400  
    4401         g_static_mutex_lock (&gmsgstore_lock); 
     4359static CamelImapStore *  
     4360create_gmsgstore (CamelImapFolder *imap_folder, gboolean *ctchecker, CamelException *ex) 
     4361
     4362        CamelImapStore *store; 
     4363        CamelFolder *folder = (CamelFolder *) imap_folder; 
     4364        gboolean amcon = FALSE; 
     4365 
     4366        g_static_mutex_lock (&gmsgstore_lock); /* A */ 
     4367 
    44024368        if (imap_folder->gmsgstore) { 
    44034369                imap_debug ("Get-Message service reused\n"); 
    44044370                store = imap_folder->gmsgstore; 
    44054371                imap_folder->gmsgstore_ticks = store->getsrv_sleep; 
    4406                 ctchecker=FALSE; 
     4372                *ctchecker=FALSE; 
    44074373        } else 
    44084374        { 
     
    44504416                imap_folder->gmsgstore = store; 
    44514417                imap_folder->gmsgstore_ticks = store->getsrv_sleep;; 
    4452                 ctchecker=TRUE; 
    4453         } 
     4418                *ctchecker=TRUE; 
     4419        } 
     4420 
     4421        return store; 
     4422
     4423 
     4424static void  
     4425stop_gmsgstore (CamelImapFolder *imap_folder, gboolean ctchecker, gboolean quick) 
     4426
     4427        if (quick) { 
     4428                imap_folder->gmsgstore->clean_exit = FALSE; 
     4429                imap_folder->gmsgstore_ticks = 0; 
     4430                if (ctchecker) { 
     4431                        camel_object_ref (imap_folder); 
     4432                        imap_folder->gmsgstore_signal = g_timeout_add (1, 
     4433                                check_gmsgstore_die, imap_folder); 
     4434                } 
     4435        } else { 
     4436                if (ctchecker) { 
     4437                        camel_object_ref (imap_folder); 
     4438                        imap_folder->gmsgstore_signal = g_timeout_add (1000, 
     4439                                check_gmsgstore_die, imap_folder); 
     4440                } 
     4441        } 
     4442 
     4443        g_static_mutex_unlock (&gmsgstore_lock); /* A */ 
     4444
     4445 
     4446static char * 
     4447imap_get_cache_filename (CamelFolder *folder, const char *uid, const char *spec, CamelFolderPartState *state) 
     4448
     4449        CamelImapFolder *imap_folder = (CamelImapFolder *) folder; 
     4450        gchar *check = NULL; 
     4451 
     4452        *state = CAMEL_FOLDER_PART_STATE_NOT_CACHED; 
     4453 
     4454        check = g_strdup_printf ("%s/%s_%s", imap_folder->cache->path, uid, spec); 
     4455        if (g_file_test (check, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { 
     4456                *state = CAMEL_FOLDER_PART_STATE_CACHED_BINARY; 
     4457                return check; 
     4458        } 
     4459 
     4460        g_free (check); 
     4461        check = g_strdup_printf ("%s/%s_%s_ENCODED", imap_folder->cache->path, uid, spec); 
     4462        if (g_file_test (check, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { 
     4463                *state = CAMEL_FOLDER_PART_STATE_CACHED_ENCODED; 
     4464                return check; 
     4465        } 
     4466 
     4467        g_free (check); 
     4468        check = g_strdup_printf ("%s/%s_%s_CONVERTED", imap_folder->cache->path, uid, spec); 
     4469        if (g_file_test (check, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { 
     4470                *state = CAMEL_FOLDER_PART_STATE_CACHED_CONVERTED; 
     4471                return check; 
     4472        } 
     4473 
     4474        g_free (check); 
     4475        return NULL; 
     4476
     4477 
     4478 
     4479 
     4480static char *  
     4481imap_convert (CamelFolder *folder, const char *uid, const char *spec, const char *convert_to, CamelException *ex) 
     4482
     4483  CamelImapFolder *imap_folder = (CamelImapFolder *) folder; 
     4484  gchar *path = g_strdup_printf ("%s/%s_%s_CONVERTED", imap_folder->cache->path, uid, spec); 
     4485  gboolean retry = TRUE; 
     4486  gint ex_id; 
     4487  gboolean err = FALSE, found = FALSE; 
     4488  gchar *err_message; 
     4489  CamelImapStore *store = NULL; 
     4490  ssize_t nread = 0; 
     4491  FILE *fil = NULL; 
     4492  gboolean ctchecker = FALSE; 
     4493 
     4494  found = g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR); 
     4495 
     4496  if (!found) 
     4497  { 
     4498        if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (folder->parent_store), ex)) { 
     4499 
     4500                camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, 
     4501                                     _("This message is not currently available")); 
     4502                g_free (path); 
     4503                path = NULL; 
     4504                found = FALSE; 
     4505 
     4506        } else { 
     4507                CamelStreamBuffer *server_stream; 
     4508                int fd; 
     4509 
     4510                store = create_gmsgstore (imap_folder, &ctchecker, ex); 
     4511                if (!store) 
     4512                        return NULL; 
     4513 
     4514                camel_operation_start (NULL, _("Retrieving converted message part")); 
     4515 
     4516                fil = fopen (path, "w"); 
     4517 
     4518                if (!fil || fd == -1) { 
     4519                        err = TRUE; 
     4520                        ex_id = CAMEL_EXCEPTION_SERVICE_UNAVAILABLE; 
     4521                        err_message = g_strdup_printf ("Can't write %s", path); 
     4522                        goto convert_errorhandler; 
     4523                } 
     4524 
     4525                fd = fileno (fil); 
     4526 
     4527                if (store->capabilities & IMAP_CAPABILITY_CONVERT) 
     4528                { 
     4529                        gchar line[MAX_LINE_LEN]; 
     4530                        gboolean err = FALSE; 
     4531                        char two_bytes[2]; 
     4532                        char t_str [1024]; 
     4533                        int f = 0; 
     4534                        ssize_t hread = 1; 
     4535                        gint length=0, rec=0; 
     4536                        char *pos, *ppos; 
     4537                        gboolean unsolicited = TRUE; 
     4538 
     4539                        nread = 0; 
     4540 
     4541                        /* Stops idle */ 
     4542                        camel_imap_command_start (store, folder, ex, 
     4543                                "UID CONVERT %s (%s) BINARY[%s]", uid, convert_to, spec); 
     4544 
     4545                        while (unsolicited) 
     4546                        { 
     4547                                two_bytes [0] = ' '; 
     4548                                f = 0; 
     4549                                nread = 1; 
     4550 
     4551                                /* a01 uid fetch 1 BINARY.PEEK[] 
     4552                                 * * Bla bla 
     4553                                 * * 1 FETCH (UID 1 BINARY[] {24693}\r\n 
     4554                                 * Subject: Testing.... 
     4555                                 * )\r\n 
     4556                                 * a01 OK .... \r\n */ 
     4557 
     4558                                /* Read the length in the "\*.*[~|]{<LENGTH>}" */ 
     4559                                while (two_bytes[0] != '\n' && f < 1023 && nread > 0) { 
     4560                                        nread = camel_stream_read (store->ostream, two_bytes, 1); 
     4561                                        line [f] = two_bytes [0]; 
     4562                                        f++; 
     4563                                } 
     4564 
     4565                                line[f] = '\0'; 
     4566 
     4567                                /* The first line is very unlikely going to consume 1023 bytes */ 
     4568                                if (f > 1023 || nread <= 0) { 
     4569                                        err = TRUE; 
     4570                                        ex_id = CAMEL_EXCEPTION_SERVICE_UNAVAILABLE; 
     4571                                        err_message = g_strdup_printf ("Read from service failed: Long " 
     4572                                                " first line during binary fetch for uid=%s", uid); 
     4573                                        goto convert_berrorhander; 
     4574                                } 
     4575 
     4576                                /* If the line doesn't start with "* " */ 
     4577                                if (camel_strstrcase (line, "BAD")) { 
     4578                                        char *ptr = strstr (line, "BAD"); 
     4579                                        if (ptr) 
     4580                                                ptr += 3; 
     4581                                        err = TRUE; 
     4582                                        ex_id = CAMEL_EXCEPTION_SERVICE_UNAVAILABLE; 
     4583                                        err_message = g_strdup_printf ("%s",  
     4584                                                ptr?ptr:"BAD from IMAP server while CONVERT"); 
     4585                                        store->capabilities &= ~IMAP_CAPABILITY_CONVERT; 
     4586                                        goto convert_errorhandler; 
     4587                                } 
     4588 
     4589                                if (*line != '*' || *(line + 1) != ' ') 
     4590                                { 
     4591                                        err = TRUE; 
     4592                                        ex_id = CAMEL_EXCEPTION_SERVICE_UNAVAILABLE; 
     4593                                        err_message = g_strdup_printf ("Read from service failed: Line doesn't start " 
     4594                                                " with \"* \" for uid=%s (in stead it started with %s)", uid, line); 
     4595                                        goto convert_berrorhander; 
     4596                                } 
     4597 
     4598                                pos = strchr (line, '{'); 
     4599 
     4600                                /* If we don't find a '{' character */ 
     4601                                if (!pos) { 
     4602                                        imap_debug ("unsolicited in BINARY: %s\n", line); 
     4603                                        continue; 
     4604                                } 
     4605 
     4606                                /* Set the '}' character to \0 */ 
     4607                                ppos = strchr (pos, '}'); 
     4608                                if (ppos) { 
     4609                                        *ppos = '\0'; 
     4610                                        unsolicited = FALSE; 
     4611                                } 
     4612                        } 
     4613 
     4614                        length = strtol (pos + 1, NULL, 10); 
     4615 
     4616                        /* If strtol failed (it's important enough to check this) */ 
     4617                        if (errno == ERANGE) 
     4618                        { 
     4619                                err = TRUE; 
     4620                                ex_id = CAMEL_EXCEPTION_SERVICE_UNAVAILABLE; 
     4621                                err_message = g_strdup_printf ("Read from service failed: " 
     4622                                        "strtol failed for uid=%s (the line was: %s)", uid, line); 
     4623                                goto convert_berrorhander; 
     4624                        } 
     4625 
     4626                        /* Until we have reached the length, read 1024 at the time */ 
     4627                        while (hread > 0 && rec < length) 
     4628                        { 
     4629                                int wread = (length - rec); 
     4630                                if (wread < 1 || wread > 1024) 
     4631                                        wread = 1024; 
     4632                                hread = camel_stream_read (store->ostream, t_str, wread); 
     4633                                if (hread > 0) 
     4634                                { 
     4635                                        /* And write them too */ 
     4636                                        if (write (fd, t_str, hread) != hread) 
     4637                                        { 
     4638                                                err = TRUE; 
     4639                                                err_message = g_strdup_printf ("Write to cache failed: %s", g_strerror (errno)); 
     4640                                                goto convert_berrorhander; 
     4641                                        } 
     4642                                        rec += hread; 
     4643                                        camel_operation_progress (NULL, rec, length); 
     4644                                } else { 
     4645                                        if (hread != 0) { 
     4646                                                err = TRUE; 
     4647                                                ex_id = CAMEL_EXCEPTION_SERVICE_UNAVAILABLE; 
     4648                                                err_message = g_strdup_printf ("Read from service failed, UID=%s", uid); 
     4649                                                goto convert_berrorhander; 
     4650                                        } 
     4651                                } 
     4652                        } 
     4653 
     4654                        /* Read away the last two lines */ 
     4655                        for (f = 0; f < 2; f++) { 
     4656                                nread = 1; two_bytes[0] = 'x'; 
     4657                                while (two_bytes[0] != '\n' && nread > 0) 
     4658                                        nread = camel_stream_read (store->ostream, two_bytes, 1); 
     4659                        } 
     4660 
     4661convert_berrorhander: 
     4662                        CAMEL_SERVICE_REC_UNLOCK (store, connect_lock); 
     4663 
     4664                        if (err) 
     4665                                goto convert_errorhandler; 
     4666                } else { 
     4667                        err = TRUE; 
     4668                        ex_id = CAMEL_EXCEPTION_SERVICE_UNAVAILABLE; 
     4669                        err_message = g_strdup_printf ("CONVERT not supported on this server"); 
     4670                        goto convert_errorhandler; 
     4671                } 
     4672 
     4673                camel_operation_end (NULL); 
     4674 
     4675                if (fil) 
     4676                        fclose (fil); 
     4677                stop_gmsgstore (imap_folder, ctchecker, FALSE); 
     4678        } 
     4679         
     4680  } 
     4681 
     4682  return path; 
     4683 
     4684convert_errorhandler: 
     4685 
     4686        camel_operation_end (NULL); 
     4687 
     4688        if (fil) 
     4689                fclose (fil); 
     4690 
     4691        if (!err_message) 
     4692                camel_exception_setv (ex, ex_id, "Could not find message body in response."); 
     4693        else { 
     4694                camel_exception_setv (ex, ex_id, err_message); 
     4695                g_free (err_message); 
     4696        } 
     4697 
     4698        if (store) { 
     4699                handle_freeup (store, nread, ex); 
     4700                stop_gmsgstore (imap_folder, ctchecker, FALSE); 
     4701        } 
     4702 
     4703  return NULL; 
     4704
     4705 
     4706static char *  
     4707imap_fetch (CamelFolder *folder, const char *uid, const char *spec, gboolean *binary, CamelException *ex) 
     4708
     4709  CamelImapFolder *imap_folder = (CamelImapFolder *) folder; 
     4710  gchar *path = g_strdup_printf ("%s/%s_%s", imap_folder->cache->path, uid, spec); 
     4711  gboolean retry = TRUE; 
     4712  gint ex_id; 
     4713  gboolean err = FALSE, found = FALSE; 
     4714  gchar *err_message; 
     4715  CamelImapStore *store = NULL; 
     4716  ssize_t nread = 0; 
     4717  FILE *fil = NULL; 
     4718  gboolean ctchecker = FALSE; 
     4719 
     4720  if (binary && *binary) { 
     4721        g_free (path); 
     4722        path = g_strdup_printf ("%s/%s_%s", imap_folder->cache->path, uid, spec); 
     4723        found = g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR); 
     4724  } 
     4725 
     4726  if (!found) { 
     4727        g_free (path); 
     4728        path = g_strdup_printf ("%s/%s_%s_ENCODED", imap_folder->cache->path, uid, spec); 
     4729        found = g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR); 
     4730        if (found) { 
     4731                if (binary) 
     4732                        *binary = FALSE; 
     4733        } else if (binary && *binary) { 
     4734                g_free (path); 
     4735                path = g_strdup_printf ("%s/%s_%s", imap_folder->cache->path, uid, spec); 
     4736        } 
     4737  } 
     4738 
     4739  if (!found) 
     4740  { 
     4741        if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (folder->parent_store), ex)) { 
     4742 
     4743                camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, 
     4744                                     _("This message is not currently available")); 
     4745                g_free (path); 
     4746                path = NULL; 
     4747                found = FALSE; 
     4748 
     4749        } else { 
     4750 
     4751                char *tag, line[MAX_LINE_LEN]; 
     4752                int taglen; 
     4753                CamelStreamBuffer *server_stream; 
     4754                int fd; 
     4755 
     4756                store = create_gmsgstore (imap_folder, &ctchecker, ex); 
     4757                if (!store) 
     4758                        return NULL; 
     4759 
     4760                camel_operation_start (NULL, _("Retrieving message part")); 
     4761 
     4762                while (retry) 
     4763                { 
     4764                        retry = FALSE; 
     4765 
     4766                        fil = fopen (path, "w"); 
     4767 
     4768                        if (!fil || fd == -1) { 
     4769                                err = TRUE; 
     4770                                ex_id = CAMEL_EXCEPTION_SERVICE_UNAVAILABLE; 
     4771                                err_message = g_strdup_printf ("Can't write %s", path); 
     4772                                goto fetch_errorhandler; 
     4773                        } 
     4774 
     4775                        fd = fileno (fil); 
     4776 
     4777                        if (binary && *binary && store->capabilities & IMAP_CAPABILITY_BINARY) 
     4778                        { 
     4779                                gchar line[MAX_LINE_LEN]; 
     4780                                gboolean err = FALSE; 
     4781                                char two_bytes[2]; 
     4782                                char t_str [1024]; 
     4783                                int f = 0; 
     4784                                ssize_t hread = 1; 
     4785                                gint length=0, rec=0; 
     4786                                char *pos, *ppos; 
     4787                                gboolean unsolicited = TRUE; 
     4788 
     4789                                g_free (path); 
     4790                                path = g_strdup_printf ("%s/%s_%s", imap_folder->cache->path, uid, spec); 
     4791 
     4792                                nread = 0; 
     4793 
     4794                                /* Stops idle */ 
     4795                                camel_imap_command_start (store, folder, ex, 
     4796                                        "UID FETCH %s BINARY.PEEK[%s]", uid, spec); 
     4797 
     4798                                while (unsolicited) 
     4799                                { 
     4800                                        two_bytes [0] = ' '; 
     4801                                        f = 0; 
     4802                                        nread = 1; 
     4803 
     4804                                        /* a01 uid fetch 1 BINARY.PEEK[] 
     4805                                         * * Bla bla 
     4806                                         * * 1 FETCH (UID 1 BINARY[] {24693}\r\n 
     4807                                         * Subject: Testing.... 
     4808                                         * )\r\n 
     4809                                         * a01 OK .... \r\n */ 
     4810 
     4811                        &n