New function to fold headers.
2000-09-28 Not Zed <NotZed@HelixCode.com> * camel-mime-utils.c (header_fold): New function to fold headers. 2000-09-27 Not Zed <NotZed@HelixCode.com> * camel-mime-parser.c (folder_scan_header): If we had an empty header, then it must be end of the headers too. (folder_scan_init): No we dont need to init the outbuf with a nul terminator. * camel-folder-summary.c (camel_folder_summary_set_uid): New function to reset the uid to a higher value. * providers/mbox/camel-mbox-summary.c (camel_mbox_summary_sync): "something failed (yo!)" what sort of crap is this? Fixed all the indenting again, what wanker keeps running stuff through indent? (message_info_new): Check the uid we loaded off the disk, if it existed already, assign a new one. If it didn't then make sure the nextuid is higher. * camel-charset-map.c: New file, used to build a large unicode decoding mapping table, and use it to determine what is the lowest charset a given word can be encoded with. Uses tables from libunicode's source. * camel-internet-address.c (internet_encode): Use header_phrase_encode to properly encode the fullname, as required. refixed indenting. Who keeps doing that? (camel_internet_address_find_address): Changed fatal return/warnings into assertions. * camel-mime-utils.c (header_raw_append_parse): Check : explicitly (removed from is_fieldname() macro). (camel_mime_special_table): Changed to short, so we can represent more bit types. (quoted_encode): Take a mask of the safe chars for this encoding. (header_address_decode): Removed a #warning that makes no sense anymore. (header_decode_date): Fixed the 'broken date' parser code, if it ever decoded it it just threw away the result. (header_encode_string): Use better charset matching for encoding strings as well. 2000-08-31 Not Zed <NotZed@HelixCode.com> * providers/mh/camel-mh-summary.c (camel_mh_summary_sync): Save the index if we do a sync. (camel_mh_summary_check): Save the index here too. Probably. svn path=/trunk/; revision=5615
This commit is contained in:
@ -1,3 +1,53 @@
|
||||
2000-09-28 Not Zed <NotZed@HelixCode.com>
|
||||
|
||||
* camel-mime-utils.c (header_fold): New function to fold headers.
|
||||
|
||||
2000-09-27 Not Zed <NotZed@HelixCode.com>
|
||||
|
||||
* camel-mime-parser.c (folder_scan_header): If we had an empty
|
||||
header, then it must be end of the headers too.
|
||||
(folder_scan_init): No we dont need to init the outbuf with a nul
|
||||
terminator.
|
||||
|
||||
* camel-folder-summary.c (camel_folder_summary_set_uid): New
|
||||
function to reset the uid to a higher value.
|
||||
|
||||
* providers/mbox/camel-mbox-summary.c (camel_mbox_summary_sync):
|
||||
"something failed (yo!)" what sort of crap is this? Fixed all the
|
||||
indenting again, what wanker keeps running stuff through indent?
|
||||
(message_info_new): Check the uid we loaded off the disk, if it
|
||||
existed already, assign a new one. If it didn't then make sure
|
||||
the nextuid is higher.
|
||||
|
||||
* camel-charset-map.c: New file, used to build a large unicode
|
||||
decoding mapping table, and use it to determine what is the
|
||||
lowest charset a given word can be encoded with. Uses tables from
|
||||
libunicode's source.
|
||||
|
||||
* camel-internet-address.c (internet_encode): Use
|
||||
header_phrase_encode to properly encode the fullname, as required.
|
||||
refixed indenting. Who keeps doing that?
|
||||
(camel_internet_address_find_address): Changed fatal return/warnings
|
||||
into assertions.
|
||||
|
||||
* camel-mime-utils.c (header_raw_append_parse): Check : explicitly
|
||||
(removed from is_fieldname() macro).
|
||||
(camel_mime_special_table): Changed to short, so we can represent
|
||||
more bit types.
|
||||
(quoted_encode): Take a mask of the safe chars for this encoding.
|
||||
(header_address_decode): Removed a #warning that makes no sense
|
||||
anymore.
|
||||
(header_decode_date): Fixed the 'broken date' parser code, if it
|
||||
ever decoded it it just threw away the result.
|
||||
(header_encode_string): Use better charset matching for encoding
|
||||
strings as well.
|
||||
|
||||
2000-08-31 Not Zed <NotZed@HelixCode.com>
|
||||
|
||||
* providers/mh/camel-mh-summary.c (camel_mh_summary_sync): Save
|
||||
the index if we do a sync.
|
||||
(camel_mh_summary_check): Save the index here too. Probably.
|
||||
|
||||
2000-09-27 Dan Winship <danw@helixcode.com>
|
||||
|
||||
* providers/imap/camel-imap-store.c (camel_imap_command_extended):
|
||||
|
||||
@ -55,6 +55,7 @@ libcamel_la_SOURCES = \
|
||||
camel-transport.c \
|
||||
camel-uid-cache.c \
|
||||
camel-url.c \
|
||||
camel-charset-map.c \
|
||||
camel.c \
|
||||
gmime-content-field.c \
|
||||
gstring-util.c \
|
||||
|
||||
3880
camel/camel-charset-map-private.h
Normal file
3880
camel/camel-charset-map-private.h
Normal file
File diff suppressed because it is too large
Load Diff
257
camel/camel-charset-map.c
Normal file
257
camel/camel-charset-map.c
Normal file
@ -0,0 +1,257 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
if you want to build the charset map, add the root directory of
|
||||
libunicode to the include path and define BUILD_MAP,
|
||||
then run it as
|
||||
./a.out > camel-charset-map-private.h
|
||||
|
||||
The tables genereated work like this:
|
||||
|
||||
An indirect array for each page of unicode character
|
||||
Each array element has an indirect pointer to one of the bytes of
|
||||
the generated bitmask.
|
||||
*/
|
||||
|
||||
#ifdef BUILD_MAP
|
||||
#include "iso/iso8859-2.h"
|
||||
#include "iso/iso8859-3.h"
|
||||
#include "iso/iso8859-4.h"
|
||||
#include "iso/iso8859-5.h"
|
||||
#include "iso/iso8859-6.h"
|
||||
#include "iso/iso8859-7.h"
|
||||
#include "iso/iso8859-8.h"
|
||||
#include "iso/iso8859-9.h"
|
||||
#include "iso/iso8859-10.h"
|
||||
#include "iso/iso8859-14.h"
|
||||
#include "iso/iso8859-15.h"
|
||||
#include "iso/koi8-r.h"
|
||||
#include "iso/koi8-u.h"
|
||||
#include "msft/cp932.h"
|
||||
#include "jis/shiftjis.h"
|
||||
|
||||
static struct {
|
||||
unsigned short *table;
|
||||
char *name;
|
||||
int type; /* type of table */
|
||||
unsigned int bit; /* assigned bit */
|
||||
} tables[] = {
|
||||
{ iso8859_2_table, "iso-8859-2", 0, 0} ,
|
||||
{ iso8859_3_table, "iso-8859-3", 0, 0} ,
|
||||
{ iso8859_4_table, "iso-8859-4", 0, 0},
|
||||
{ iso8859_5_table, "iso-8859-5", 0, 0},
|
||||
/* apparently -6 has special digits? */
|
||||
{ iso8859_6_table, "iso-8859-6", 0, 0},
|
||||
{ iso8859_7_table, "iso-8859-7", 0, 0},
|
||||
{ iso8859_8_table, "iso-8859-8", 0, 0},
|
||||
{ iso8859_9_table, "iso-8859-9", 0, 0},
|
||||
{ iso8859_10_table, "iso-8859-10", 0, 0},
|
||||
{ iso8859_14_table, "iso-8859-14", 0, 0},
|
||||
{ iso8859_15_table, "iso-8859-15", 0, 0},
|
||||
{ koi8_r_table, "koi8-r", 0, 0},
|
||||
{ koi8_u_table, "koi8-u", 0, 0},
|
||||
{ cp932_table, "CP932", 1, 0},
|
||||
{ sjis_table, "Shift-JIS", 1, 0},
|
||||
{ 0, 0}
|
||||
};
|
||||
|
||||
unsigned int encoding_map[256 * 256];
|
||||
|
||||
static void
|
||||
add_bigmap(unsigned short **table, int bit)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i=0;i<256;i++) {
|
||||
unsigned short *tab = table[i];
|
||||
if (tab) {
|
||||
for (j=0;j<256;j++) {
|
||||
if (tab[j])
|
||||
encoding_map[tab[j]] |= bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
int i, j;
|
||||
unsigned short *tab;
|
||||
int max, min;
|
||||
int bit = 0x01;
|
||||
int k;
|
||||
int bytes;
|
||||
|
||||
#if 0
|
||||
/* iso-latin-1 (not needed-detected in code) */
|
||||
for (i=0;i<256;i++) {
|
||||
encoding_map[i] |= bit;
|
||||
}
|
||||
bit <<= 1;
|
||||
#endif
|
||||
|
||||
/* dont count the terminator */
|
||||
bytes = ((sizeof(tables)/sizeof(tables[0]))+7-1)/8;
|
||||
|
||||
/* the other latin charsets */
|
||||
for (j=0;tables[j].table;j++) {
|
||||
switch (tables[j].type) {
|
||||
case 0: /* table from 128-256 */
|
||||
tab = tables[j].table;
|
||||
for (i=0;i<128;i++) {
|
||||
/* 0-127 is the common */
|
||||
encoding_map[i] |= bit;
|
||||
encoding_map[tab[i]] |= bit;
|
||||
}
|
||||
break;
|
||||
case 1: /* sparse table */
|
||||
add_bigmap(tables[j].table, bit);
|
||||
break;
|
||||
}
|
||||
tables[j].bit = bit;
|
||||
bit <<= 1;
|
||||
}
|
||||
|
||||
printf("/* This file is automatically generated: DO NOT EDIT */\n\n");
|
||||
|
||||
for (i=0;i<256;i++) {
|
||||
/* first, do we need this block? */
|
||||
for (k=0;k<bytes;k++) {
|
||||
for (j=0;j<256;j++) {
|
||||
if ((encoding_map[i*256 + j] & (0xff << (k*8))) != 0)
|
||||
break;
|
||||
}
|
||||
if (j < 256) {
|
||||
/* yes, dump it */
|
||||
printf("static unsigned char m%02x%x[256] = {\n\t", i, k);
|
||||
for (j=0;j<256;j++) {
|
||||
printf("0x%02x, ", (encoding_map[i*256+j] >> (k*8)) & 0xff );
|
||||
if (((j+1)&7) == 0 && j<255)
|
||||
printf("\n\t");
|
||||
}
|
||||
printf("\n};\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("struct {\n");
|
||||
for (k=0;k<bytes;k++) {
|
||||
printf("\tunsigned char *bits%d;\n", k);
|
||||
}
|
||||
printf("} camel_charmap[256] = {\n\t");
|
||||
for (i=0;i<256;i++) {
|
||||
/* first, do we need this block? */
|
||||
printf("{ ");
|
||||
for (k=0;k<bytes;k++) {
|
||||
for (j=0;j<256;j++) {
|
||||
if ((encoding_map[i*256 + j] & (0xff << (k*8))) != 0)
|
||||
break;
|
||||
}
|
||||
if (j < 256) {
|
||||
printf("m%02x%x, ", i, k);
|
||||
} else {
|
||||
printf("0, ");
|
||||
}
|
||||
}
|
||||
printf("}, ");
|
||||
if (((i+1)&7) == 0 && i<255)
|
||||
printf("\n\t");
|
||||
}
|
||||
printf("\n};\n\n");
|
||||
|
||||
printf("struct {\n\tconst char *name;\n\tunsigned int bit;\n} camel_charinfo[] = {\n");
|
||||
for (j=0;tables[j].table;j++) {
|
||||
printf("\t{ \"%s\", 0x%04x },\n", tables[j].name, tables[j].bit);
|
||||
}
|
||||
printf("};\n\n");
|
||||
|
||||
printf("#define charset_mask(x) \\\n");
|
||||
for (k=0;k<bytes;k++) {
|
||||
if (k!=0)
|
||||
printf("\t| ");
|
||||
else
|
||||
printf("\t");
|
||||
printf("(camel_charmap[(x)>>8].bits%d?camel_charmap[(x)>>8].bits%d[(x)&0xff]<<%d:0)", k, k, k*8);
|
||||
if (k<bytes-1)
|
||||
printf("\t\\\n");
|
||||
}
|
||||
printf("\n\n");
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "camel-charset-map.h"
|
||||
#include "camel-charset-map-private.h"
|
||||
#include <unicode.h>
|
||||
#include <glib.h>
|
||||
|
||||
unsigned int
|
||||
camel_charset_mask(unsigned int c)
|
||||
{
|
||||
if (c>0xffff)
|
||||
return 0;
|
||||
|
||||
return charset_mask(c);
|
||||
}
|
||||
|
||||
/* gets the best charset from the mask of chars in it */
|
||||
const char *
|
||||
camel_charset_best_mask(unsigned int mask)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<sizeof(camel_charinfo)/sizeof(camel_charinfo[0]);i++) {
|
||||
if (camel_charinfo[i].bit & mask)
|
||||
return camel_charinfo[i].name;
|
||||
}
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
/* finds the minimum charset for this string NULL means US-ASCII */
|
||||
const char *
|
||||
camel_charset_best(const char *in, int len)
|
||||
{
|
||||
int i;
|
||||
unsigned int mask = ~0;
|
||||
int level = 0;
|
||||
const char *inptr = in, *inend = in+len;
|
||||
|
||||
/* check what charset a given string will fit in */
|
||||
while (inptr < inend) {
|
||||
unicode_char_t c;
|
||||
const char *newinptr;
|
||||
newinptr = unicode_get_utf8(inptr, &c);
|
||||
if (newinptr == NULL) {
|
||||
inptr++;
|
||||
continue;
|
||||
}
|
||||
inptr = newinptr;
|
||||
if (c<=0xffff) {
|
||||
mask |= camel_charset_mask(c);
|
||||
|
||||
if (c>=128 && c<256)
|
||||
level = MAX(level, 1);
|
||||
else if (c>=256)
|
||||
level = MAX(level, 2);
|
||||
} else {
|
||||
mask = 0;
|
||||
level = MAX(level, 2);
|
||||
}
|
||||
}
|
||||
|
||||
switch(level) {
|
||||
case 0:
|
||||
return NULL;
|
||||
case 1:
|
||||
return "ISO-8859-1";
|
||||
case 2:
|
||||
return camel_charset_best_mask(mask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* !BUILD_MAP */
|
||||
|
||||
28
camel/camel-charset-map.h
Normal file
28
camel/camel-charset-map.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2000 Helix Code Inc.
|
||||
*
|
||||
* Authors: Michael Zucchi <notzed@helixcode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef _CAMEL_CHARSET_MAP_H
|
||||
#define _CAMEL_CHARSET_MAP_H
|
||||
|
||||
unsigned int camel_charset_mask(unsigned int c);
|
||||
const char *camel_charset_best(const char *in, int len);
|
||||
const char *camel_charset_best_mask(unsigned int mask);
|
||||
|
||||
#endif /* ! _CAMEL_CHARSET_MAP_H */
|
||||
@ -251,10 +251,15 @@ guint32 camel_folder_summary_next_uid(CamelFolderSummary *s)
|
||||
return uid;
|
||||
}
|
||||
|
||||
char *
|
||||
camel_folder_summary_next_uid_string (CamelFolderSummary *s)
|
||||
void camel_folder_summary_set_uid(CamelFolderSummary *s, guint32 uid)
|
||||
{
|
||||
return g_strdup_printf ("%u", camel_folder_summary_next_uid (s));
|
||||
s->nextuid = MAX(s->nextuid, uid);
|
||||
}
|
||||
|
||||
char *
|
||||
camel_folder_summary_next_uid_string(CamelFolderSummary *s)
|
||||
{
|
||||
return g_strdup_printf("%u", camel_folder_summary_next_uid(s));
|
||||
}
|
||||
|
||||
/* loads the content descriptions, recursively */
|
||||
@ -388,7 +393,7 @@ void camel_folder_summary_add(CamelFolderSummary *s, CamelMessageInfo *info)
|
||||
return;
|
||||
retry:
|
||||
if (info->uid == NULL) {
|
||||
info->uid = camel_folder_summary_next_uid_string (s);
|
||||
info->uid = camel_folder_summary_next_uid_string(s);
|
||||
}
|
||||
if (g_hash_table_lookup(s->messages_uid, info->uid)) {
|
||||
g_warning("Trying to insert message with clashing uid (%s). new uid re-assigned", info->uid);
|
||||
@ -1206,7 +1211,7 @@ summary_build_content_info(CamelFolderSummary *s, CamelMimeParser *mp)
|
||||
if (p->index && header_content_type_is(ct, "text", "*")) {
|
||||
char *encoding;
|
||||
const char *charset;
|
||||
|
||||
|
||||
d(printf("generating index:\n"));
|
||||
|
||||
encoding = header_content_encoding_decode(camel_mime_parser_header(mp, "content-transfer-encoding", NULL));
|
||||
|
||||
@ -167,6 +167,7 @@ void camel_folder_summary_set_build_content(CamelFolderSummary *, gboolean state
|
||||
|
||||
guint32 camel_folder_summary_next_uid (CamelFolderSummary *s);
|
||||
char *camel_folder_summary_next_uid_string (CamelFolderSummary *s);
|
||||
void camel_folder_summary_set_uid (CamelFolderSummary *s, guint32 uid);
|
||||
|
||||
/* load/save the summary in its entirety */
|
||||
int camel_folder_summary_load(CamelFolderSummary *);
|
||||
|
||||
@ -36,11 +36,11 @@ struct _address {
|
||||
};
|
||||
|
||||
static void
|
||||
camel_internet_address_class_init (CamelInternetAddressClass *klass)
|
||||
camel_internet_address_class_init(CamelInternetAddressClass *klass)
|
||||
{
|
||||
CamelAddressClass *address = (CamelAddressClass *) klass;
|
||||
|
||||
camel_internet_address_parent = CAMEL_ADDRESS_CLASS (camel_type_get_global_classfuncs (camel_address_get_type ()));
|
||||
camel_internet_address_parent = CAMEL_ADDRESS_CLASS(camel_type_get_global_classfuncs(camel_address_get_type()));
|
||||
|
||||
address->decode = internet_decode;
|
||||
address->encode = internet_encode;
|
||||
@ -48,23 +48,23 @@ camel_internet_address_class_init (CamelInternetAddressClass *klass)
|
||||
}
|
||||
|
||||
static void
|
||||
camel_internet_address_init (CamelInternetAddress *obj)
|
||||
camel_internet_address_init(CamelInternetAddress *obj)
|
||||
{
|
||||
}
|
||||
|
||||
CamelType
|
||||
camel_internet_address_get_type (void)
|
||||
camel_internet_address_get_type(void)
|
||||
{
|
||||
static CamelType type = CAMEL_INVALID_TYPE;
|
||||
|
||||
if (type == CAMEL_INVALID_TYPE) {
|
||||
type = camel_type_register (camel_address_get_type (), "CamelInternetAddress",
|
||||
sizeof (CamelInternetAddress),
|
||||
sizeof (CamelInternetAddressClass),
|
||||
(CamelObjectClassInitFunc) camel_internet_address_class_init,
|
||||
NULL,
|
||||
(CamelObjectInitFunc) camel_internet_address_init,
|
||||
NULL);
|
||||
type = camel_type_register(camel_address_get_type(), "CamelInternetAddress",
|
||||
sizeof (CamelInternetAddress),
|
||||
sizeof (CamelInternetAddressClass),
|
||||
(CamelObjectClassInitFunc) camel_internet_address_class_init,
|
||||
NULL,
|
||||
(CamelObjectInitFunc) camel_internet_address_init,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return type;
|
||||
@ -76,24 +76,24 @@ internet_decode (CamelAddress *a, const char *raw)
|
||||
struct _header_address *ha, *n;
|
||||
|
||||
/* Should probably use its own decoder or something */
|
||||
ha = header_address_decode (raw);
|
||||
ha = header_address_decode(raw);
|
||||
if (ha) {
|
||||
n = ha;
|
||||
while (n) {
|
||||
if (n->type == HEADER_ADDRESS_NAME) {
|
||||
camel_internet_address_add ((CamelInternetAddress *)a, n->name, n->v.addr);
|
||||
camel_internet_address_add((CamelInternetAddress *)a, n->name, n->v.addr);
|
||||
} else if (n->type == HEADER_ADDRESS_GROUP) {
|
||||
struct _header_address *g = n->v.members;
|
||||
while (g) {
|
||||
if (g->type == HEADER_ADDRESS_NAME)
|
||||
camel_internet_address_add ((CamelInternetAddress *)a, g->name, g->v.addr);
|
||||
camel_internet_address_add((CamelInternetAddress *)a, g->name, g->v.addr);
|
||||
/* otherwise, its an error, infact */
|
||||
g = g->next;
|
||||
}
|
||||
}
|
||||
n = n->next;
|
||||
}
|
||||
header_address_list_clear (&ha);
|
||||
header_address_list_clear(&ha);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -109,27 +109,27 @@ internet_encode (CamelAddress *a)
|
||||
if (a->addresses->len == 0)
|
||||
return NULL;
|
||||
|
||||
out = g_string_new ("");
|
||||
out = g_string_new("");
|
||||
|
||||
for (i = 0;i < a->addresses->len; i++) {
|
||||
struct _address *addr = g_ptr_array_index (a->addresses, i);
|
||||
char *name = header_encode_string (addr->name);
|
||||
struct _address *addr = g_ptr_array_index(a->addresses, i);
|
||||
char *name = header_encode_phrase(addr->name);
|
||||
|
||||
if (i != 0)
|
||||
g_string_append (out, ", ");
|
||||
g_string_append(out, ", ");
|
||||
|
||||
if (name) {
|
||||
if (*name)
|
||||
g_string_sprintfa (out, "\"%s\" <%s>", name, addr->address);
|
||||
else if (addr->address)
|
||||
g_string_sprintfa (out, "%s", addr->address);
|
||||
g_free (name);
|
||||
if (*name) {
|
||||
g_string_sprintfa(out, "%s <%s>", name, addr->address);
|
||||
} else if (addr->address)
|
||||
g_string_sprintfa(out, "%s", addr->address);
|
||||
g_free(name);
|
||||
} else
|
||||
g_string_sprintfa (out, "%s", addr->address);
|
||||
g_string_sprintfa(out, "%s", addr->address);
|
||||
}
|
||||
|
||||
ret = out->str;
|
||||
g_string_free (out, FALSE);
|
||||
g_string_free(out, FALSE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -142,11 +142,11 @@ internet_remove (CamelAddress *a, int index)
|
||||
if (index < 0 || index >= a->addresses->len)
|
||||
return;
|
||||
|
||||
addr = g_ptr_array_index (a->addresses, index);
|
||||
g_free (addr->name);
|
||||
g_free (addr->address);
|
||||
g_free (addr);
|
||||
g_ptr_array_remove_index (a->addresses, index);
|
||||
addr = g_ptr_array_index(a->addresses, index);
|
||||
g_free(addr->name);
|
||||
g_free(addr->address);
|
||||
g_free(addr);
|
||||
g_ptr_array_remove_index(a->addresses, index);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -159,7 +159,7 @@ internet_remove (CamelAddress *a, int index)
|
||||
CamelInternetAddress *
|
||||
camel_internet_address_new (void)
|
||||
{
|
||||
CamelInternetAddress *new = CAMEL_INTERNET_ADDRESS (camel_object_new (camel_internet_address_get_type ()));
|
||||
CamelInternetAddress *new = CAMEL_INTERNET_ADDRESS(camel_object_new(camel_internet_address_get_type()));
|
||||
return new;
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ camel_internet_address_add (CamelInternetAddress *a, const char *name, const cha
|
||||
struct _address *new;
|
||||
int index;
|
||||
|
||||
g_return_val_if_fail(IS_CAMEL_INTERNET_ADDRESS(a), -1);
|
||||
g_assert(IS_CAMEL_INTERNET_ADDRESS(a));
|
||||
|
||||
new = g_malloc(sizeof(*new));
|
||||
new->name = g_strdup(name);
|
||||
@ -206,7 +206,7 @@ camel_internet_address_get (const CamelInternetAddress *a, int index, const char
|
||||
{
|
||||
struct _address *addr;
|
||||
|
||||
g_return_val_if_fail(IS_CAMEL_INTERNET_ADDRESS(a), -1);
|
||||
g_assert(IS_CAMEL_INTERNET_ADDRESS(a));
|
||||
g_return_val_if_fail(index >= 0, -1);
|
||||
|
||||
if (index >= ((CamelAddress *)a)->addresses->len)
|
||||
@ -237,7 +237,7 @@ camel_internet_address_find_name(CamelInternetAddress *a, const char *name, cons
|
||||
struct _address *addr;
|
||||
int i, len;
|
||||
|
||||
g_return_val_if_fail(IS_CAMEL_INTERNET_ADDRESS(a), -1);
|
||||
g_assert(IS_CAMEL_INTERNET_ADDRESS(a));
|
||||
|
||||
len = ((CamelAddress *)a)->addresses->len;
|
||||
for (i=0;i<len;i++) {
|
||||
@ -267,7 +267,7 @@ camel_internet_address_find_address(CamelInternetAddress *a, const char *address
|
||||
struct _address *addr;
|
||||
int i, len;
|
||||
|
||||
g_return_val_if_fail(IS_CAMEL_INTERNET_ADDRESS(a), -1);
|
||||
g_assert(IS_CAMEL_INTERNET_ADDRESS(a));
|
||||
|
||||
len = ((CamelAddress *)a)->addresses->len;
|
||||
for (i=0;i<len;i++) {
|
||||
|
||||
@ -42,10 +42,10 @@
|
||||
#include "camel-stream.h"
|
||||
#include "camel-seekable-stream.h"
|
||||
|
||||
#define r(x)
|
||||
#define h(x)
|
||||
#define c(x)
|
||||
#define d(x)
|
||||
#define r(x)
|
||||
#define h(x)
|
||||
#define c(x)
|
||||
#define d(x)
|
||||
|
||||
/*#define PURIFY*/
|
||||
|
||||
@ -282,7 +282,6 @@ static void header_append_mempool(struct _header_scan_state *s, struct _header_s
|
||||
static void camel_mime_parser_class_init (CamelMimeParserClass *klass);
|
||||
static void camel_mime_parser_init (CamelMimeParser *obj);
|
||||
|
||||
#if d(!)0
|
||||
static char *states[] = {
|
||||
"HSCAN_INITIAL",
|
||||
"HSCAN_FROM", /* got 'From' line */
|
||||
@ -301,8 +300,6 @@ static char *states[] = {
|
||||
"HSCAN_MULTIPART_END",
|
||||
"HSCAN_MESSAGE_END",
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static CamelObjectClass *camel_mime_parser_parent;
|
||||
|
||||
@ -986,8 +983,6 @@ header_append_mempool(struct _header_scan_state *s, struct _header_scan_stack *h
|
||||
struct _header_raw *l, *n;
|
||||
char *content;
|
||||
|
||||
d(printf("Header: %s: %s\n", name, value));
|
||||
|
||||
content = strchr(header, ':');
|
||||
if (content) {
|
||||
register int len;
|
||||
@ -1125,14 +1120,21 @@ retry:
|
||||
s->midline = FALSE;
|
||||
}
|
||||
|
||||
h(printf("midline = %s\n", s->midline?"TRUE":"FALSE"));
|
||||
h(printf("outbuf[0] = %02x '%c' oubuf[1] = %02x '%c'\n",
|
||||
s->outbuf[0], isprint(s->outbuf[0])?s->outbuf[0]:'.',
|
||||
s->outbuf[1], isprint(s->outbuf[1])?s->outbuf[1]:'.'));
|
||||
h(printf("inptr[0] = %02x '%c' inptr[1] = %02x '%c'\n",
|
||||
inptr[0], isprint(inptr[0])?inptr[0]:'.',
|
||||
inptr[1], isprint(inptr[1])?inptr[1]:'.'));
|
||||
|
||||
if (!s->midline
|
||||
&& !(inptr[0] == ' ' || inptr[0] == '\t')) {
|
||||
if (s->outbuf[0] == '\n'
|
||||
h(printf("ok, checking\n"));
|
||||
if (s->outbuf == s->outptr
|
||||
|| s->outbuf[0] == '\n'
|
||||
|| (s->outbuf[0] == '\r' && s->outbuf[1]=='\n')) {
|
||||
h(printf("header done?\n"));
|
||||
goto header_done;
|
||||
}
|
||||
|
||||
@ -1141,7 +1143,7 @@ retry:
|
||||
s->outptr--;
|
||||
s->outptr[0] = 0;
|
||||
|
||||
d(printf("header %.10s at %d\n", s->outbuf, s->header_start));
|
||||
d(printf("header '%.10s' at %d\n", s->outbuf, s->header_start));
|
||||
|
||||
header_raw_append_parse(&h->headers, s->outbuf, s->header_start);
|
||||
|
||||
@ -1218,7 +1220,7 @@ folder_scan_content(struct _header_scan_state *s, int *lastone, char **data, int
|
||||
struct _header_scan_stack *part, *overpart = s->parts;
|
||||
int already_packed = FALSE;
|
||||
|
||||
/*printf("scanning content\n");*/
|
||||
c(printf("scanning content\n"));
|
||||
|
||||
/* FIXME: this info should be cached ? */
|
||||
part = s->parts;
|
||||
@ -1368,7 +1370,6 @@ folder_scan_init(void)
|
||||
s->stream = NULL;
|
||||
|
||||
s->outbuf = g_malloc(1024);
|
||||
s->outbuf[0] = '\0';
|
||||
s->outptr = s->outbuf;
|
||||
s->outend = s->outbuf+1024;
|
||||
|
||||
@ -1719,7 +1720,8 @@ int main(int argc, char **argv)
|
||||
perror("Cannot open mailbox");
|
||||
exit(1);
|
||||
}
|
||||
s = folder_scan_init(fd);
|
||||
s = folder_scan_init();
|
||||
folder_scan_init_with_fd(s, fd);
|
||||
s->scan_from = FALSE;
|
||||
#if 0
|
||||
h = g_malloc0(sizeof(*h));
|
||||
@ -1734,7 +1736,9 @@ int main(int argc, char **argv)
|
||||
if (s->parts->content_type
|
||||
&& (charset = header_content_type_param(s->parts->content_type, "charset"))) {
|
||||
if (strcasecmp(charset, "us-ascii")) {
|
||||
#if 0
|
||||
folder_push_filter_charset(s, "UTF-8", charset);
|
||||
#endif
|
||||
} else {
|
||||
charset = NULL;
|
||||
}
|
||||
@ -1742,39 +1746,55 @@ int main(int argc, char **argv)
|
||||
charset = NULL;
|
||||
}
|
||||
|
||||
encoding = header_raw_find(&s->parts->headers, "Content-transfer-encoding");
|
||||
encoding = header_raw_find(&s->parts->headers, "Content-transfer-encoding", 0);
|
||||
printf("encoding = '%s'\n", encoding);
|
||||
if (encoding && !strncasecmp(encoding, " base64", 7)) {
|
||||
printf("adding base64 filter\n");
|
||||
attachname = g_strdup_printf("attach.%d.%d", i, attach++);
|
||||
#if 0
|
||||
folder_push_filter_save(s, attachname);
|
||||
#endif
|
||||
g_free(attachname);
|
||||
#if 0
|
||||
folder_push_filter_mime(s, 0);
|
||||
#endif
|
||||
}
|
||||
if (encoding && !strncasecmp(encoding, " quoted-printable", 17)) {
|
||||
printf("adding quoted-printable filter\n");
|
||||
attachname = g_strdup_printf("attach.%d.%d", i, attach++);
|
||||
#if 0
|
||||
folder_push_filter_save(s, attachname);
|
||||
#endif
|
||||
g_free(attachname);
|
||||
#if 0
|
||||
folder_push_filter_mime(s, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
case HSCAN_BODY:
|
||||
printf("got body %d '%.*s'\n", len, len, data);
|
||||
break;
|
||||
case HSCAN_BODY_END:
|
||||
printf("end body %d '%.*s'\n", len, len, data);
|
||||
if (encoding && !strncasecmp(encoding, " base64", 7)) {
|
||||
printf("removing filters\n");
|
||||
#if 0
|
||||
folder_filter_pull(s);
|
||||
folder_filter_pull(s);
|
||||
#endif
|
||||
}
|
||||
if (encoding && !strncasecmp(encoding, " quoted-printable", 17)) {
|
||||
printf("removing filters\n");
|
||||
#if 0
|
||||
folder_filter_pull(s);
|
||||
folder_filter_pull(s);
|
||||
#endif
|
||||
}
|
||||
if (charset) {
|
||||
#if 0
|
||||
folder_filter_pull(s);
|
||||
#endif
|
||||
charset = NULL;
|
||||
}
|
||||
encoding = NULL;
|
||||
|
||||
@ -38,8 +38,11 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "camel-mime-utils.h"
|
||||
#include "camel-charset-map.h"
|
||||
|
||||
#ifndef CLEAN_DATE
|
||||
#include "broken-date-parser.h"
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
int strdup_count = 0;
|
||||
@ -67,15 +70,15 @@ static unsigned char tohex[16] = {
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
||||
};
|
||||
|
||||
static unsigned char camel_mime_special_table[256] = {
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5,167, 7, 5, 5, 39, 5, 5,
|
||||
static unsigned short camel_mime_special_table[256] = {
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5,231, 7, 5, 5, 39, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
178,128,140,128,128,128,128,128,140,140,128,128,140,128,136,132,
|
||||
128,128,128,128,128,128,128,128,128,128,204,140,140, 4,140,132,
|
||||
140,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
|
||||
128,128,128,128,128,128,128,128,128,128,128,172,172,172,128,128,
|
||||
128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
|
||||
128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 5,
|
||||
50,192, 76,192,192,192,192,192, 76, 76,192,192, 76,192, 72, 68,
|
||||
192,192,192,192,192,192,192,192,192,192, 76, 76, 76, 4, 76, 68,
|
||||
76,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
|
||||
192,192,192,192,192,192,192,192,192,192,192,108,236,108,192,192,
|
||||
192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
|
||||
192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, 5,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
@ -109,7 +112,7 @@ static unsigned char camel_mime_base64_rank[256] = {
|
||||
if any of these change, then the tables above should be regenerated
|
||||
by compiling this with -DBUILD_TABLE, and running.
|
||||
|
||||
gcc -o buildtable `glib-config --cflags --libs` -DBUILD_TABLE camel-mime-utils.c
|
||||
gcc -DCLEAN_DATE -o buildtable -I.. `glib-config --cflags --libs` -lunicode -DBUILD_TABLE camel-mime-utils.c
|
||||
./buildtable
|
||||
|
||||
*/
|
||||
@ -120,8 +123,9 @@ enum {
|
||||
IS_SPECIAL = 1<<3,
|
||||
IS_SPACE = 1<<4,
|
||||
IS_DSPECIAL = 1<<5,
|
||||
IS_COLON = 1<<6, /* rather wasteful of space ... */
|
||||
IS_QPSAFE = 1<<7
|
||||
IS_QPSAFE = 1<<6,
|
||||
IS_ESAFE = 1<<7, /* encoded word safe */
|
||||
IS_PSAFE = 1<<8, /* encoded word in phrase safe */
|
||||
};
|
||||
|
||||
#define is_ctrl(x) ((camel_mime_special_table[(unsigned char)(x)] & IS_CTRL) != 0)
|
||||
@ -131,8 +135,10 @@ enum {
|
||||
#define is_ttoken(x) ((camel_mime_special_table[(unsigned char)(x)] & (IS_TSPECIAL|IS_LWSP|IS_CTRL)) == 0)
|
||||
#define is_atom(x) ((camel_mime_special_table[(unsigned char)(x)] & (IS_SPECIAL|IS_SPACE|IS_CTRL)) == 0)
|
||||
#define is_dtext(x) ((camel_mime_special_table[(unsigned char)(x)] & IS_DSPECIAL) == 0)
|
||||
#define is_fieldname(x) ((camel_mime_special_table[(unsigned char)(x)] & (IS_CTRL|IS_SPACE|IS_COLON)) == 0)
|
||||
#define is_fieldname(x) ((camel_mime_special_table[(unsigned char)(x)] & (IS_CTRL|IS_SPACE)) == 0)
|
||||
#define is_qpsafe(x) ((camel_mime_special_table[(unsigned char)(x)] & IS_QPSAFE) != 0)
|
||||
#define is_especial(x) ((camel_mime_special_table[(unsigned char)(x)] & IS_ESPECIAL) != 0)
|
||||
#define is_psafe(x) ((camel_mime_special_table[(unsigned char)(x)] & IS_PSAFE) != 0)
|
||||
|
||||
/* only needs to be run to rebuild the tables above */
|
||||
#ifdef BUILD_TABLE
|
||||
@ -142,12 +148,24 @@ enum {
|
||||
#define CHARS_SPECIAL "()<>@,;:\\\".[]"
|
||||
#define CHARS_CSPECIAL "()\\\r" /* not in comments */
|
||||
#define CHARS_DSPECIAL "[]\\\r \t" /* not in domains */
|
||||
#define CHARS_ESPECIAL "()<>@,;:\"/[]?.=" /* encoded word specials */
|
||||
#define CHARS_PSPECIAL "!*+-/=_" /* encoded word specials */
|
||||
|
||||
static void
|
||||
header_init_bits(unsigned char bit, unsigned char bitcopy, int remove, unsigned char *vals, int len)
|
||||
header_remove_bits(unsigned short bit, unsigned char *vals)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;vals[i];i++)
|
||||
camel_mime_special_table[vals[i]] &= ~ bit;
|
||||
}
|
||||
|
||||
static void
|
||||
header_init_bits(unsigned short bit, unsigned short bitcopy, int remove, unsigned char *vals)
|
||||
{
|
||||
int i;
|
||||
int len = strlen(vals);
|
||||
|
||||
if (!remove) {
|
||||
for (i=0;i<len;i++) {
|
||||
camel_mime_special_table[vals[i]] |= bit;
|
||||
@ -178,16 +196,23 @@ header_decode_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<256;i++) camel_mime_special_table[i] = 0;
|
||||
for (i=0;i<32;i++) camel_mime_special_table[i] |= IS_CTRL;
|
||||
for (i=0;i<256;i++) {
|
||||
camel_mime_special_table[i] = 0;
|
||||
if (i<32)
|
||||
camel_mime_special_table[i] |= IS_CTRL;
|
||||
if ((i>=33 && i<=60) || (i>=62 && i<=126) || i==32 || i==9)
|
||||
camel_mime_special_table[i] |= IS_QPSAFE|IS_ESAFE;
|
||||
if ((i>='0' && i<='9') || (i>='a' && i<='z') || (i>='A' && i<= 'Z'))
|
||||
camel_mime_special_table[i] |= IS_PSAFE;
|
||||
}
|
||||
camel_mime_special_table[127] = IS_CTRL;
|
||||
camel_mime_special_table[' '] = IS_SPACE;
|
||||
camel_mime_special_table[':'] = IS_COLON;
|
||||
header_init_bits(IS_LWSP, 0, 0, CHARS_LWSP, sizeof(CHARS_LWSP)-1);
|
||||
header_init_bits(IS_TSPECIAL, IS_CTRL, 0, CHARS_TSPECIAL, sizeof(CHARS_TSPECIAL)-1);
|
||||
header_init_bits(IS_SPECIAL, 0, 0, CHARS_SPECIAL, sizeof(CHARS_SPECIAL)-1);
|
||||
header_init_bits(IS_DSPECIAL, 0, FALSE, CHARS_DSPECIAL, sizeof(CHARS_DSPECIAL)-1);
|
||||
for (i=0;i<256;i++) if ((i>=33 && i<=60) || (i>=62 && i<=126) || i==32 || i==9) camel_mime_special_table[i] |= IS_QPSAFE;
|
||||
header_init_bits(IS_LWSP, 0, 0, CHARS_LWSP);
|
||||
header_init_bits(IS_TSPECIAL, IS_CTRL, 0, CHARS_TSPECIAL);
|
||||
header_init_bits(IS_SPECIAL, 0, 0, CHARS_SPECIAL);
|
||||
header_init_bits(IS_DSPECIAL, 0, FALSE, CHARS_DSPECIAL);
|
||||
header_remove_bits(IS_ESAFE, CHARS_ESPECIAL);
|
||||
header_init_bits(IS_PSAFE, 0, 0, CHARS_PSPECIAL);
|
||||
}
|
||||
|
||||
void
|
||||
@ -210,7 +235,7 @@ int main(int argc, char **argv)
|
||||
header_decode_init();
|
||||
base64_init();
|
||||
|
||||
printf("static unsigned char camel_mime_special_table[256] = {\n\t");
|
||||
printf("static unsigned short camel_mime_special_table[256] = {\n\t");
|
||||
for (i=0;i<256;i++) {
|
||||
printf("%3d,", camel_mime_special_table[i]);
|
||||
if ((i&15) == 15) {
|
||||
@ -757,8 +782,10 @@ quoted_decode(const unsigned char *in, int len, unsigned char *out)
|
||||
}
|
||||
|
||||
/* rfc2047 version of quoted-printable */
|
||||
/* safemask is the mask to apply to the camel_mime_special_table to determine what
|
||||
characters can safely be included without encoding */
|
||||
static int
|
||||
quoted_encode(const unsigned char *in, int len, unsigned char *out)
|
||||
quoted_encode(const unsigned char *in, int len, unsigned char *out, unsigned short safemask)
|
||||
{
|
||||
register const unsigned char *inptr, *inend;
|
||||
unsigned char *outptr;
|
||||
@ -769,7 +796,8 @@ quoted_encode(const unsigned char *in, int len, unsigned char *out)
|
||||
outptr = out;
|
||||
while (inptr<inend) {
|
||||
c = *inptr++;
|
||||
if (is_qpsafe(c) && !(c=='_' || c=='?')) {
|
||||
/*if (is_qpsafe(c) && !(c=='_' || c=='?')) {*/
|
||||
if (camel_mime_special_table[c] & safemask) {
|
||||
if (c==' ')
|
||||
c='_';
|
||||
*outptr++=c;
|
||||
@ -983,8 +1011,8 @@ static char *encoding_map[] = {
|
||||
};
|
||||
|
||||
/* FIXME: needs a way to cache iconv opens for different charsets? */
|
||||
static
|
||||
char *rfc2047_encode_word(const char *in, int len, char *type)
|
||||
static void
|
||||
rfc2047_encode_word(GString *outstring, const char *in, int len, char *type, unsigned short safemask)
|
||||
{
|
||||
unicode_iconv_t ic;
|
||||
char *buffer, *out, *ascii;
|
||||
@ -1017,11 +1045,11 @@ char *rfc2047_encode_word(const char *in, int len, char *type)
|
||||
out = ascii;
|
||||
/* should determine which encoding is smaller, and use that? */
|
||||
out += sprintf(out, "=?%s?Q?", type);
|
||||
out += quoted_encode(buffer, enclen, out);
|
||||
out += quoted_encode(buffer, enclen, out, safemask);
|
||||
sprintf(out, "?=");
|
||||
|
||||
d(printf("converted = %s\n", ascii));
|
||||
return g_strdup(ascii);
|
||||
g_string_append(outstring, ascii);
|
||||
}
|
||||
|
||||
|
||||
@ -1065,13 +1093,18 @@ header_encode_string(const unsigned char *in)
|
||||
}
|
||||
inptr = newinptr;
|
||||
if (unicode_isspace(c)) {
|
||||
if (encoding == 0) {
|
||||
switch (encoding) {
|
||||
case 0:
|
||||
out = g_string_append_len(out, start, inptr-start);
|
||||
} else {
|
||||
char *text = rfc2047_encode_word(start, inptr-start-1, encoding_map[encoding]);
|
||||
out = g_string_append(out, text);
|
||||
break;
|
||||
case 1:
|
||||
rfc2047_encode_word(out, start, inptr-start-1, "ISO-8859-1", IS_ESAFE);
|
||||
break;
|
||||
case 2:
|
||||
rfc2047_encode_word(out, start, inptr-start-1,
|
||||
camel_charset_best(start, inptr-start-1), IS_ESAFE);
|
||||
out = g_string_append_c(out, c);
|
||||
g_free(text);
|
||||
break;
|
||||
}
|
||||
start = inptr;
|
||||
encoding = 0;
|
||||
@ -1082,12 +1115,17 @@ header_encode_string(const unsigned char *in)
|
||||
}
|
||||
}
|
||||
if (inptr-start) {
|
||||
if (encoding == 0) {
|
||||
switch (encoding) {
|
||||
case 0:
|
||||
out = g_string_append_len(out, start, inptr-start);
|
||||
} else {
|
||||
char *text = rfc2047_encode_word(start, inptr-start, encoding_map[encoding]);
|
||||
out = g_string_append(out, text);
|
||||
g_free(text);
|
||||
break;
|
||||
case 1:
|
||||
rfc2047_encode_word(out, start, inptr-start-1, "ISO-8859-1", IS_ESAFE);
|
||||
break;
|
||||
case 2:
|
||||
rfc2047_encode_word(out, start, inptr-start-1,
|
||||
camel_charset_best(start, inptr-start-1), IS_ESAFE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
outstr = out->str;
|
||||
@ -1095,6 +1133,178 @@ header_encode_string(const unsigned char *in)
|
||||
return outstr;
|
||||
}
|
||||
|
||||
/* apply quoted-string rules to a string */
|
||||
static void
|
||||
quote_word(GString *out, gboolean do_quotes, const char *start, int len)
|
||||
{
|
||||
int i, c;
|
||||
|
||||
/* TODO: What about folding on long lines? */
|
||||
if (do_quotes)
|
||||
g_string_append_c(out, '"');
|
||||
for (i=0;i<len;i++) {
|
||||
c = *start++;
|
||||
if (c == '\"' || c=='\\' || c=='\r')
|
||||
g_string_append_c(out, '\\');
|
||||
g_string_append_c(out, c);
|
||||
}
|
||||
if (do_quotes)
|
||||
g_string_append_c(out, '"');
|
||||
}
|
||||
|
||||
/* incrementing possibility for the word type */
|
||||
enum _phrase_word_t {
|
||||
WORD_ATOM,
|
||||
WORD_QSTRING,
|
||||
WORD_2047
|
||||
};
|
||||
|
||||
struct _phrase_word {
|
||||
const unsigned char *start, *end;
|
||||
enum _phrase_word_t type;
|
||||
int encoding;
|
||||
};
|
||||
|
||||
/* split the input into words
|
||||
with info about each word
|
||||
merge common word types
|
||||
clean up
|
||||
*/
|
||||
/* encodes a phrase sequence (different quoting/encoding rules to strings) */
|
||||
char *
|
||||
header_encode_phrase(const unsigned char *in)
|
||||
{
|
||||
GString *out;
|
||||
const unsigned char *inptr = in, *start, *last;
|
||||
int encoding;
|
||||
char *outstr;
|
||||
struct _phrase_word *word, *next;
|
||||
enum _phrase_word_t type;
|
||||
GList *words = NULL, *wordl, *nextl;
|
||||
int count;
|
||||
|
||||
if (in == NULL)
|
||||
return NULL;
|
||||
|
||||
out = g_string_new("");
|
||||
|
||||
/* break the input into words */
|
||||
type = WORD_ATOM;
|
||||
count = 0;
|
||||
last = inptr;
|
||||
start = inptr;
|
||||
encoding = 0;
|
||||
while (inptr && *inptr) {
|
||||
unicode_char_t c;
|
||||
const char *newinptr;
|
||||
newinptr = unicode_get_utf8(inptr, &c);
|
||||
if (newinptr == NULL) {
|
||||
w(g_warning("Invalid UTF-8 sequence encountered (pos %d, char '%c'): %s", (inptr-in), inptr[0], in));
|
||||
inptr++;
|
||||
continue;
|
||||
}
|
||||
inptr = newinptr;
|
||||
/* save this word out, multiple whitespace is not explicitly counted (?) */
|
||||
if (unicode_isspace(c)) {
|
||||
if (count > 0) {
|
||||
word = g_malloc0(sizeof(*word));
|
||||
word->start = start;
|
||||
word->end = last;
|
||||
word->type = type;
|
||||
word->encoding = encoding;
|
||||
words = g_list_append(words, word);
|
||||
count = 0;
|
||||
}
|
||||
start = inptr;
|
||||
type = WORD_ATOM;
|
||||
encoding = 0;
|
||||
} else {
|
||||
count++;
|
||||
if (c<128) {
|
||||
if (!is_atom(c))
|
||||
type = MAX(type, WORD_QSTRING);
|
||||
} else if (c>127 && c < 256) {
|
||||
type = WORD_2047;
|
||||
encoding = MAX(encoding, 1);
|
||||
} else if (c >=256) {
|
||||
type = WORD_2047;
|
||||
encoding = MAX(encoding, 2);
|
||||
}
|
||||
}
|
||||
last = inptr;
|
||||
}
|
||||
if (count > 0) {
|
||||
word = g_malloc0(sizeof(*word));
|
||||
word->start = start;
|
||||
word->end = last;
|
||||
word->type = type;
|
||||
word->encoding = encoding;
|
||||
words = g_list_append(words, word);
|
||||
}
|
||||
|
||||
/* now scan the list, checking for words of similar types that can be merged */
|
||||
wordl = words;
|
||||
while (wordl) {
|
||||
word = wordl->data;
|
||||
/* leave atoms as atoms (unless they're surrounded by quoted words??) */
|
||||
if (word->type != WORD_ATOM) {
|
||||
nextl = g_list_next(wordl);
|
||||
while (nextl) {
|
||||
next = nextl->data;
|
||||
/* merge nodes of the same (or lower?) type*/
|
||||
if (word->type == next->type || (next->type < word->type && word->type < WORD_2047) ) {
|
||||
word->end = next->end;
|
||||
words = g_list_remove_link(words, nextl);
|
||||
g_free(next);
|
||||
nextl = g_list_next(wordl);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
wordl = g_list_next(wordl);
|
||||
}
|
||||
|
||||
/* output words now with spaces between them */
|
||||
wordl = words;
|
||||
while (wordl) {
|
||||
word = wordl->data;
|
||||
switch (word->type) {
|
||||
case WORD_ATOM:
|
||||
out = g_string_append_len(out, word->start, word->end-word->start);
|
||||
break;
|
||||
case WORD_QSTRING:
|
||||
quote_word(out, TRUE, word->start, word->end-word->start);
|
||||
break;
|
||||
case WORD_2047:
|
||||
if (word->encoding == 1)
|
||||
rfc2047_encode_word(out, word->start, word->end-word->start, "ISO-8859-1", IS_PSAFE);
|
||||
else
|
||||
rfc2047_encode_word(out, word->start, word->end-word->start,
|
||||
camel_charset_best(word->start, word->end-word->start), IS_PSAFE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* copy across the right number of spaces between words */
|
||||
nextl = g_list_next(wordl);
|
||||
if (nextl) {
|
||||
int i;
|
||||
next = nextl->data;
|
||||
for (i=next->start-word->end;i>0;i--)
|
||||
out = g_string_append_c(out, ' ');
|
||||
}
|
||||
|
||||
g_free(word);
|
||||
wordl = g_list_next(wordl);
|
||||
}
|
||||
/* and we no longer need the list */
|
||||
g_list_free(words);
|
||||
|
||||
outstr = out->str;
|
||||
g_string_free(out, FALSE);
|
||||
return outstr;
|
||||
}
|
||||
|
||||
|
||||
/* these are all internal parser functions */
|
||||
|
||||
@ -1826,10 +2036,6 @@ header_address_decode(const char *in)
|
||||
|
||||
d(printf("decoding To: '%s'\n", in));
|
||||
|
||||
#ifndef NO_WARNINGS
|
||||
#warning header_to_decode needs to return some structure
|
||||
#endif
|
||||
|
||||
if (in == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -2165,19 +2371,19 @@ header_decode_date(const char *in, int *saveoffset)
|
||||
if (*inptr == ',') {
|
||||
inptr++;
|
||||
} else {
|
||||
gchar *newdate;
|
||||
|
||||
#ifndef CLEAN_DATE
|
||||
char *newdate;
|
||||
|
||||
w(g_warning("day not followed by ',' its probably a broken mail client, so we'll ignore its date entirely"));
|
||||
printf ("Giving it one last chance...\n");
|
||||
newdate = parse_broken_date (in);
|
||||
if (newdate) {
|
||||
printf ("Got: %s\n", newdate);
|
||||
if (saveoffset)
|
||||
*saveoffset = 0;
|
||||
t = header_decode_date (newdate, NULL);
|
||||
t = header_decode_date (newdate, saveoffset);
|
||||
g_free (newdate);
|
||||
return t;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (saveoffset)
|
||||
*saveoffset = 0;
|
||||
return 0;
|
||||
@ -2300,7 +2506,7 @@ header_raw_append_parse(struct _header_raw **list, const char *header, int offse
|
||||
char *name;
|
||||
|
||||
in = header;
|
||||
while (is_fieldname(*in))
|
||||
while (is_fieldname(*in) || *in==':')
|
||||
in++;
|
||||
fieldlen = in-header;
|
||||
while (is_lwsp(*in))
|
||||
@ -2629,11 +2835,68 @@ header_address_list_format(struct _header_address *a)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* simple header folding */
|
||||
/* note: assumes the input has not already been folded */
|
||||
char *
|
||||
header_fold(const char *in)
|
||||
{
|
||||
int len, outlen, i;
|
||||
const char *inptr = in, *space;
|
||||
GString *out;
|
||||
char *ret;
|
||||
|
||||
len = strlen(in);
|
||||
if (len <= CAMEL_FOLD_SIZE)
|
||||
return g_strdup(in);
|
||||
|
||||
out = g_string_new("");
|
||||
outlen = 0;
|
||||
while (*inptr) {
|
||||
space = strchr(inptr, ' ');
|
||||
if (space) {
|
||||
len = space-inptr+1;
|
||||
} else {
|
||||
len = strlen(inptr);
|
||||
}
|
||||
if (outlen + len > CAMEL_FOLD_SIZE) {
|
||||
g_string_append(out, "\n\t");
|
||||
outlen = 1;
|
||||
/* check for very long words, just cut them up */
|
||||
while (outlen+len > CAMEL_FOLD_SIZE) {
|
||||
for (i=0;i<CAMEL_FOLD_SIZE-outlen;i++)
|
||||
g_string_append_c(out, inptr[i]);
|
||||
inptr += CAMEL_FOLD_SIZE-outlen;
|
||||
len -= CAMEL_FOLD_SIZE-outlen;
|
||||
g_string_append(out, "\n\t");
|
||||
outlen = 1;
|
||||
}
|
||||
}
|
||||
outlen += len;
|
||||
for (i=0;i<len;i++) {
|
||||
g_string_append_c(out, inptr[i]);
|
||||
}
|
||||
inptr += len;
|
||||
}
|
||||
ret = out->str;
|
||||
g_string_free(out, FALSE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef BUILD_TABLE
|
||||
|
||||
/* for debugging tests */
|
||||
/* should also have some regression tests somewhere */
|
||||
|
||||
void test_phrase(const char *in)
|
||||
{
|
||||
printf("'%s' -> '%s'\n", in, header_encode_phrase(in));
|
||||
}
|
||||
|
||||
void test_fold(const char *in)
|
||||
{
|
||||
printf("'%s'\n ->\n '%s'\n", in, header_fold(in));
|
||||
}
|
||||
|
||||
void run_test(void)
|
||||
{
|
||||
char *to = "gnome hacker dudes: license-discuss@opensource.org,
|
||||
@ -2644,21 +2907,49 @@ void run_test(void)
|
||||
zucchi@zedzone.mmc.com.au, \"Foo bar\" <zed@zedzone>,
|
||||
<frob@frobzone>";
|
||||
|
||||
#if 0
|
||||
header_to_decode(to);
|
||||
|
||||
header_mime_decode("1.0");
|
||||
header_mime_decode("1.3 (produced by metasend V1.0)");
|
||||
header_mime_decode("(produced by metasend V1.0) 5.2");
|
||||
header_mime_decode("7(produced by metasend 1.0) . (produced by helix/send/1.0) 9 . 5");
|
||||
header_mime_decode("3.");
|
||||
header_mime_decode(".");
|
||||
header_mime_decode(".5");
|
||||
header_mime_decode("c.d");
|
||||
header_mime_decode("");
|
||||
header_mime_decode("1.0", 0, 0);
|
||||
header_mime_decode("1.3 (produced by metasend V1.0)", 0, 0);
|
||||
header_mime_decode("(produced by metasend V1.0) 5.2", 0, 0);
|
||||
header_mime_decode("7(produced by metasend 1.0) . (produced by helix/send/1.0) 9 . 5", 0, 0);
|
||||
header_mime_decode("3.", 0, 0);
|
||||
header_mime_decode(".", 0, 0);
|
||||
header_mime_decode(".5", 0, 0);
|
||||
header_mime_decode("c.d", 0, 0);
|
||||
header_mime_decode("", 0, 0);
|
||||
|
||||
header_msgid_decode(" <\"L3x2i1.0.Nm5.Xd-Wu\"@lists.redhat.com>");
|
||||
header_msgid_decode("<200001180446.PAA02065@beaker.htb.com.au>");
|
||||
#endif
|
||||
|
||||
test_fold("Header: This is a long header that should be folded properly at the right place, or so i hope. I should probably set the fold value to something lower for testing");
|
||||
test_fold("Header: nowletstryfoldingsomethingthatistoolongtofold,iwonderwhatitshoulddointsteadtofoldit?hmm,iguessicanjusttruncateitatsomepointortrytorefoldthepreviousstuff(yuck)tofit");
|
||||
test_phrase("Michael Zucchi (NotZed)");
|
||||
test_phrase("Zucchi, ( \\ NotZed \\ ) Michael");
|
||||
{
|
||||
int ic;
|
||||
char *outbuf, *inbuf, buffer[256];
|
||||
int inlen, outlen;
|
||||
|
||||
outlen = 256;
|
||||
inbuf = "Dra<EFBFBD>en Ka<4B>ar";
|
||||
inlen = strlen(inbuf);
|
||||
outbuf = buffer;
|
||||
ic = unicode_iconv_open("UTF-8", "ISO-8859-1");
|
||||
unicode_iconv(ic, &inbuf, &inlen, &outbuf, &outlen);
|
||||
test_phrase(buffer);
|
||||
|
||||
outlen = 256;
|
||||
inbuf = "Tomasz K<>oczko";
|
||||
inlen = strlen(inbuf);
|
||||
outbuf = buffer;
|
||||
ic = unicode_iconv_open("UTF-8", "ISO-8859-2");
|
||||
unicode_iconv(ic, &inbuf, &inlen, &outbuf, &outlen);
|
||||
test_phrase(buffer);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BUILD_TABLE */
|
||||
|
||||
@ -25,6 +25,9 @@
|
||||
#include <glib.h>
|
||||
#include <time.h>
|
||||
|
||||
/* maximum size of a line from header_fold() */
|
||||
#define CAMEL_FOLD_SIZE (72)
|
||||
|
||||
/* a list of references for this message */
|
||||
struct _header_references {
|
||||
struct _header_references *next;
|
||||
@ -131,6 +134,9 @@ void header_raw_replace(struct _header_raw **list, const char *name, const char
|
||||
void header_raw_remove(struct _header_raw **list, const char *name);
|
||||
void header_raw_clear(struct _header_raw **list);
|
||||
|
||||
/* fold a header */
|
||||
char *header_fold(const char *in);
|
||||
|
||||
/* decode a header which is a simple token */
|
||||
char *header_token_decode(const char *in);
|
||||
|
||||
@ -138,6 +144,9 @@ char *header_token_decode(const char *in);
|
||||
char *header_decode_string(const char *in);
|
||||
char *header_encode_string(const unsigned char *in);
|
||||
|
||||
/* encode a phrase, like the real name of an address */
|
||||
char *header_encode_phrase(const unsigned char *in);
|
||||
|
||||
/* decode an email date field into a GMT time, + optional offset */
|
||||
time_t header_decode_date(const char *in, int *saveoffset);
|
||||
char *header_format_date(time_t time, int offset);
|
||||
|
||||
@ -56,29 +56,29 @@ static void camel_mbox_summary_finalise (CamelObject *obj);
|
||||
static CamelFolderSummaryClass *camel_mbox_summary_parent;
|
||||
|
||||
CamelType
|
||||
camel_mbox_summary_get_type (void)
|
||||
camel_mbox_summary_get_type(void)
|
||||
{
|
||||
static CamelType type = CAMEL_INVALID_TYPE;
|
||||
|
||||
if (type == CAMEL_INVALID_TYPE) {
|
||||
type = camel_type_register (camel_folder_summary_get_type (), "CamelMboxSummary",
|
||||
sizeof (CamelMboxSummary),
|
||||
sizeof (CamelMboxSummaryClass),
|
||||
(CamelObjectClassInitFunc) camel_mbox_summary_class_init,
|
||||
NULL,
|
||||
(CamelObjectInitFunc) camel_mbox_summary_init,
|
||||
(CamelObjectFinalizeFunc) camel_mbox_summary_finalise);
|
||||
type = camel_type_register(camel_folder_summary_get_type(), "CamelMboxSummary",
|
||||
sizeof (CamelMboxSummary),
|
||||
sizeof (CamelMboxSummaryClass),
|
||||
(CamelObjectClassInitFunc) camel_mbox_summary_class_init,
|
||||
NULL,
|
||||
(CamelObjectInitFunc) camel_mbox_summary_init,
|
||||
(CamelObjectFinalizeFunc) camel_mbox_summary_finalise);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
camel_mbox_summary_class_init (CamelMboxSummaryClass *klass)
|
||||
camel_mbox_summary_class_init(CamelMboxSummaryClass *klass)
|
||||
{
|
||||
CamelFolderSummaryClass *sklass = (CamelFolderSummaryClass *) klass;
|
||||
|
||||
camel_mbox_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_type_get_global_classfuncs (camel_folder_summary_get_type ()));
|
||||
camel_mbox_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_type_get_global_classfuncs(camel_folder_summary_get_type()));
|
||||
|
||||
sklass->summary_header_load = summary_header_load;
|
||||
sklass->summary_header_save = summary_header_save;
|
||||
@ -91,7 +91,7 @@ camel_mbox_summary_class_init (CamelMboxSummaryClass *klass)
|
||||
}
|
||||
|
||||
static void
|
||||
camel_mbox_summary_init (CamelMboxSummary *obj)
|
||||
camel_mbox_summary_init(CamelMboxSummary *obj)
|
||||
{
|
||||
struct _CamelMboxSummaryPrivate *p;
|
||||
struct _CamelFolderSummary *s = (CamelFolderSummary *)obj;
|
||||
@ -107,11 +107,11 @@ camel_mbox_summary_init (CamelMboxSummary *obj)
|
||||
}
|
||||
|
||||
static void
|
||||
camel_mbox_summary_finalise (CamelObject *obj)
|
||||
camel_mbox_summary_finalise(CamelObject *obj)
|
||||
{
|
||||
CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY (obj);
|
||||
CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY(obj);
|
||||
|
||||
g_free (mbs->folder_path);
|
||||
g_free(mbs->folder_path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,85 +122,92 @@ camel_mbox_summary_finalise (CamelObject *obj)
|
||||
* Return value: A new CamelMboxSummary widget.
|
||||
**/
|
||||
CamelMboxSummary *
|
||||
camel_mbox_summary_new (const char *filename, const char *mbox_name, ibex *index)
|
||||
camel_mbox_summary_new(const char *filename, const char *mbox_name, ibex *index)
|
||||
{
|
||||
CamelMboxSummary *new = CAMEL_MBOX_SUMMARY (camel_object_new (camel_mbox_summary_get_type ()));
|
||||
CamelMboxSummary *new = CAMEL_MBOX_SUMMARY(camel_object_new(camel_mbox_summary_get_type()));
|
||||
|
||||
if (new) {
|
||||
/* ?? */
|
||||
camel_folder_summary_set_build_content (CAMEL_FOLDER_SUMMARY (new), TRUE);
|
||||
camel_folder_summary_set_filename (CAMEL_FOLDER_SUMMARY (new), filename);
|
||||
new->folder_path = g_strdup (mbox_name);
|
||||
camel_folder_summary_set_build_content(CAMEL_FOLDER_SUMMARY(new), TRUE);
|
||||
camel_folder_summary_set_filename(CAMEL_FOLDER_SUMMARY(new), filename);
|
||||
new->folder_path = g_strdup(mbox_name);
|
||||
new->index = index;
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
static int
|
||||
summary_header_load (CamelFolderSummary *s, FILE *in)
|
||||
summary_header_load(CamelFolderSummary *s, FILE *in)
|
||||
{
|
||||
CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY (s);
|
||||
CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY(s);
|
||||
|
||||
if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->summary_header_load (s, in) == -1)
|
||||
if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->summary_header_load(s, in) == -1)
|
||||
return -1;
|
||||
|
||||
return camel_folder_summary_decode_uint32 (in, &mbs->folder_size);
|
||||
return camel_folder_summary_decode_uint32(in, &mbs->folder_size);
|
||||
}
|
||||
|
||||
static int
|
||||
summary_header_save (CamelFolderSummary *s, FILE *out)
|
||||
summary_header_save(CamelFolderSummary *s, FILE *out)
|
||||
{
|
||||
CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY (s);
|
||||
CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY(s);
|
||||
|
||||
if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->summary_header_save (s, out) == -1)
|
||||
if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->summary_header_save(s, out) == -1)
|
||||
return -1;
|
||||
|
||||
return camel_folder_summary_encode_uint32 (out, mbs->folder_size);
|
||||
return camel_folder_summary_encode_uint32(out, mbs->folder_size);
|
||||
}
|
||||
|
||||
static int
|
||||
header_evolution_decode (const char *in, guint32 *uid, guint32 *flags)
|
||||
header_evolution_decode(const char *in, guint32 *uid, guint32 *flags)
|
||||
{
|
||||
char *header;
|
||||
|
||||
if (in && (header = header_token_decode(in))) {
|
||||
if (strlen (header) == strlen ("00000000-0000")
|
||||
&& sscanf (header, "%08x-%04x", uid, flags) == 2) {
|
||||
g_free (header);
|
||||
g_free(header);
|
||||
return *uid;
|
||||
}
|
||||
g_free (header);
|
||||
g_free(header);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char *
|
||||
header_evolution_encode (guint32 uid, guint32 flags)
|
||||
header_evolution_encode(guint32 uid, guint32 flags)
|
||||
{
|
||||
return g_strdup_printf ("%08x-%04x", uid, flags & 0xffff);
|
||||
return g_strdup_printf("%08x-%04x", uid, flags & 0xffff);
|
||||
}
|
||||
|
||||
static CamelMessageInfo *
|
||||
message_info_new (CamelFolderSummary *s, struct _header_raw *h)
|
||||
message_info_new(CamelFolderSummary *s, struct _header_raw *h)
|
||||
{
|
||||
CamelMessageInfo *mi;
|
||||
|
||||
mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new (s, h);
|
||||
mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new(s, h);
|
||||
if (mi) {
|
||||
const char *xev;
|
||||
guint32 uid, flags;
|
||||
CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi;
|
||||
|
||||
xev = header_raw_find (&h, "X-Evolution", NULL);
|
||||
xev = header_raw_find(&h, "X-Evolution", NULL);
|
||||
if (xev && header_evolution_decode(xev, &uid, &flags) != -1) {
|
||||
g_free (mi->uid);
|
||||
mi->uid = g_strdup_printf ("%u", uid);
|
||||
g_free(mi->uid);
|
||||
mi->uid = g_strdup_printf("%u", uid);
|
||||
if (camel_folder_summary_uid(s, mi->uid)) {
|
||||
g_free(mi->uid);
|
||||
mi->uid = camel_folder_summary_next_uid_string(s);
|
||||
} else {
|
||||
/* so we dont get clashes later on */
|
||||
camel_folder_summary_set_uid(s, uid+1);
|
||||
}
|
||||
mi->flags = flags;
|
||||
} else {
|
||||
/* to indicate it has no xev header? */
|
||||
mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV;
|
||||
mi->uid = g_strdup_printf ("%u", camel_folder_summary_next_uid (s));
|
||||
mi->uid = g_strdup_printf("%u", camel_folder_summary_next_uid(s));
|
||||
}
|
||||
mbi->frompos = -1;
|
||||
}
|
||||
@ -209,25 +216,25 @@ message_info_new (CamelFolderSummary *s, struct _header_raw *h)
|
||||
}
|
||||
|
||||
static CamelMessageInfo *
|
||||
message_info_new_from_parser (CamelFolderSummary *s, CamelMimeParser *mp)
|
||||
message_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp)
|
||||
{
|
||||
CamelMessageInfo *mi;
|
||||
CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY (s);
|
||||
CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY(s);
|
||||
|
||||
mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new_from_parser (s, mp);
|
||||
mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new_from_parser(s, mp);
|
||||
if (mi) {
|
||||
CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi;
|
||||
|
||||
mbi->frompos = camel_mime_parser_tell_start_from (mp);
|
||||
mbi->frompos = camel_mime_parser_tell_start_from(mp);
|
||||
|
||||
/* do we want to index this message as we add it, as well? */
|
||||
if (mbs->index_force
|
||||
|| (mi->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0
|
||||
|| !ibex_contains_name(mbs->index, mi->uid)) {
|
||||
|
||||
camel_folder_summary_set_index (s, mbs->index);
|
||||
camel_folder_summary_set_index(s, mbs->index);
|
||||
} else {
|
||||
camel_folder_summary_set_index (s, NULL);
|
||||
camel_folder_summary_set_index(s, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,18 +242,18 @@ message_info_new_from_parser (CamelFolderSummary *s, CamelMimeParser *mp)
|
||||
}
|
||||
|
||||
static CamelMessageInfo *
|
||||
message_info_load (CamelFolderSummary *s, FILE *in)
|
||||
message_info_load(CamelFolderSummary *s, FILE *in)
|
||||
{
|
||||
CamelMessageInfo *mi;
|
||||
|
||||
io (printf ("loading mbox message info\n"));
|
||||
io(printf("loading mbox message info\n"));
|
||||
|
||||
mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_load (s, in);
|
||||
mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_load(s, in);
|
||||
if (mi) {
|
||||
guint32 position;
|
||||
CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi;
|
||||
|
||||
camel_folder_summary_decode_uint32 (in, &position);
|
||||
camel_folder_summary_decode_uint32(in, &position);
|
||||
mbi->frompos = position;
|
||||
}
|
||||
|
||||
@ -254,74 +261,74 @@ message_info_load (CamelFolderSummary *s, FILE *in)
|
||||
}
|
||||
|
||||
static int
|
||||
message_info_save (CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi)
|
||||
message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi)
|
||||
{
|
||||
CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi;
|
||||
|
||||
io (printf ("saving mbox message info\n"));
|
||||
io(printf("saving mbox message info\n"));
|
||||
|
||||
((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_save (s, out, mi);
|
||||
((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_save(s, out, mi);
|
||||
|
||||
return camel_folder_summary_encode_uint32 (out, mbi->frompos);
|
||||
return camel_folder_summary_encode_uint32(out, mbi->frompos);
|
||||
}
|
||||
|
||||
static int
|
||||
summary_rebuild (CamelMboxSummary *mbs, off_t offset)
|
||||
summary_rebuild(CamelMboxSummary *mbs, off_t offset)
|
||||
{
|
||||
CamelFolderSummary *s = CAMEL_FOLDER_SUMMARY (mbs);
|
||||
CamelFolderSummary *s = CAMEL_FOLDER_SUMMARY(mbs);
|
||||
CamelMimeParser *mp;
|
||||
int fd;
|
||||
int ok = 0;
|
||||
|
||||
fd = open (mbs->folder_path, O_RDONLY);
|
||||
fd = open(mbs->folder_path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
printf ("%s failed to open: %s", mbs->folder_path, strerror (errno));
|
||||
printf("%s failed to open: %s", mbs->folder_path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
mp = camel_mime_parser_new ();
|
||||
camel_mime_parser_init_with_fd (mp, fd);
|
||||
camel_mime_parser_scan_from (mp, TRUE);
|
||||
camel_mime_parser_seek (mp, offset, SEEK_SET);
|
||||
mp = camel_mime_parser_new();
|
||||
camel_mime_parser_init_with_fd(mp, fd);
|
||||
camel_mime_parser_scan_from(mp, TRUE);
|
||||
camel_mime_parser_seek(mp, offset, SEEK_SET);
|
||||
|
||||
if (offset > 0) {
|
||||
if (camel_mime_parser_step (mp, NULL, NULL) == HSCAN_FROM) {
|
||||
if (camel_mime_parser_tell_start_from (mp) != offset) {
|
||||
if (camel_mime_parser_step(mp, NULL, NULL) == HSCAN_FROM) {
|
||||
if (camel_mime_parser_tell_start_from(mp) != offset) {
|
||||
g_warning ("The next message didn't start where I expected\nbuilding summary from start");
|
||||
camel_mime_parser_drop_step (mp);
|
||||
camel_mime_parser_drop_step(mp);
|
||||
offset = 0;
|
||||
camel_mime_parser_seek (mp, offset, SEEK_SET);
|
||||
camel_folder_summary_clear (CAMEL_FOLDER_SUMMARY (mbs));
|
||||
camel_mime_parser_seek(mp, offset, SEEK_SET);
|
||||
camel_folder_summary_clear(CAMEL_FOLDER_SUMMARY(mbs));
|
||||
} else {
|
||||
camel_mime_parser_unstep (mp);
|
||||
camel_mime_parser_unstep(mp);
|
||||
}
|
||||
} else {
|
||||
camel_object_unref (CAMEL_OBJECT (mp));
|
||||
camel_object_unref(CAMEL_OBJECT(mp));
|
||||
/* end of file - no content? */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
while (camel_mime_parser_step (mp, NULL, NULL) == HSCAN_FROM) {
|
||||
while (camel_mime_parser_step(mp, NULL, NULL) == HSCAN_FROM) {
|
||||
CamelMessageInfo *info;
|
||||
|
||||
info = camel_folder_summary_add_from_parser (CAMEL_FOLDER_SUMMARY (mbs), mp);
|
||||
info = camel_folder_summary_add_from_parser(CAMEL_FOLDER_SUMMARY(mbs), mp);
|
||||
if (info == NULL) {
|
||||
printf ("Could not build info from file?\n");
|
||||
ok = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
g_assert (camel_mime_parser_step (mp, NULL, NULL) == HSCAN_FROM_END);
|
||||
g_assert(camel_mime_parser_step(mp, NULL, NULL) == HSCAN_FROM_END);
|
||||
}
|
||||
|
||||
camel_object_unref (CAMEL_OBJECT (mp));
|
||||
camel_object_unref(CAMEL_OBJECT (mp));
|
||||
|
||||
/* update the file size/mtime in the summary */
|
||||
if (ok != -1) {
|
||||
struct stat st;
|
||||
|
||||
if (stat (mbs->folder_path, &st) == 0) {
|
||||
if (stat(mbs->folder_path, &st) == 0) {
|
||||
mbs->folder_size = st.st_size;
|
||||
s->time = st.st_mtime;
|
||||
}
|
||||
@ -615,16 +622,16 @@ camel_mbox_summary_sync(CamelMboxSummary *mbs, gboolean expunge, CamelException
|
||||
/* make sure we're in sync */
|
||||
count = camel_folder_summary_count (s);
|
||||
if (count > 0) {
|
||||
CamelMessageInfo *mi = camel_folder_summary_index (s, count - 1);
|
||||
camel_mbox_summary_update (mbs, mi->content->endpos);
|
||||
CamelMessageInfo *mi = camel_folder_summary_index(s, count - 1);
|
||||
camel_mbox_summary_update(mbs, mi->content->endpos);
|
||||
} else {
|
||||
camel_mbox_summary_update (mbs, 0);
|
||||
camel_mbox_summary_update(mbs, 0);
|
||||
}
|
||||
|
||||
/* check if we have any work to do */
|
||||
d(printf ("Performing sync, %d messages in inbox\n", count));
|
||||
d(printf("Performing sync, %d messages in inbox\n", count));
|
||||
for (i = 0; quick && i < count; i++) {
|
||||
info = (CamelMboxMessageInfo *)camel_folder_summary_index (s, i);
|
||||
info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
|
||||
if ((expunge && (info->info.flags & CAMEL_MESSAGE_DELETED)) ||
|
||||
(info->info.flags & CAMEL_MESSAGE_FOLDER_NOXEV))
|
||||
quick = FALSE;
|
||||
@ -632,37 +639,36 @@ camel_mbox_summary_sync(CamelMboxSummary *mbs, gboolean expunge, CamelException
|
||||
work |= (info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0;
|
||||
}
|
||||
|
||||
d(printf ("Options: %s %s %s\n", expunge ? "expunge" : "", quick ? "quick" : "", work ? "Work" : ""));
|
||||
d(printf("Options: %s %s %s\n", expunge ? "expunge" : "", quick ? "quick" : "", work ? "Work" : ""));
|
||||
|
||||
if (quick && !work)
|
||||
return 0;
|
||||
|
||||
fd = open (mbs->folder_path, O_RDWR);
|
||||
fd = open(mbs->folder_path, O_RDWR);
|
||||
if (fd == -1) {
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not open summary %s", mbs->folder_path);
|
||||
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not open summary %s", mbs->folder_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mp = camel_mime_parser_new ();
|
||||
camel_mime_parser_scan_from (mp, TRUE);
|
||||
camel_mime_parser_init_with_fd (mp, fd);
|
||||
mp = camel_mime_parser_new();
|
||||
camel_mime_parser_scan_from(mp, TRUE);
|
||||
camel_mime_parser_init_with_fd(mp, fd);
|
||||
|
||||
if (!quick) {
|
||||
tmpname = alloca (strlen (mbs->folder_path) + 5);
|
||||
sprintf (tmpname, "%s.tmp", mbs->folder_path);
|
||||
d(printf ("Writing tmp file to %s\n", tmpname));
|
||||
tmpname = alloca(strlen (mbs->folder_path) + 5);
|
||||
sprintf(tmpname, "%s.tmp", mbs->folder_path);
|
||||
d(printf("Writing tmp file to %s\n", tmpname));
|
||||
retry_out:
|
||||
fdout = open (tmpname, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
fdout = open(tmpname, O_WRONLY|O_CREAT|O_EXCL, 0600);
|
||||
if (fdout == -1) {
|
||||
if (errno == EEXIST)
|
||||
if (unlink(tmpname) != -1)
|
||||
goto retry_out;
|
||||
|
||||
tmpname = NULL;
|
||||
g_warning ("Something failed (yo!)");
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Cannot open temporary mailbox: %s", strerror (errno));
|
||||
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Cannot open temporary mailbox: %s", strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@ -676,191 +682,189 @@ camel_mbox_summary_sync(CamelMboxSummary *mbs, gboolean expunge, CamelException
|
||||
|
||||
info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i);
|
||||
|
||||
g_assert (info);
|
||||
g_assert(info);
|
||||
|
||||
d(printf ("Looking at message %s\n", info->info.uid));
|
||||
d(printf("Looking at message %s\n", info->info.uid));
|
||||
|
||||
if (expunge && info->info.flags & CAMEL_MESSAGE_DELETED) {
|
||||
d(printf ("Deleting %s\n", info->info.uid));
|
||||
d(printf("Deleting %s\n", info->info.uid));
|
||||
|
||||
g_assert (!quick);
|
||||
g_assert(!quick);
|
||||
offset -= (info->info.content->endpos - info->frompos);
|
||||
if (mbs->index)
|
||||
ibex_unindex (mbs->index, info->info.uid);
|
||||
camel_folder_summary_remove (s, (CamelMessageInfo *)info);
|
||||
ibex_unindex(mbs->index, info->info.uid);
|
||||
camel_folder_summary_remove(s, (CamelMessageInfo *)info);
|
||||
count--;
|
||||
i--;
|
||||
info = NULL;
|
||||
} else if (info->info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED)) {
|
||||
int xevok = FALSE;
|
||||
|
||||
d(printf ("Updating header for %s flags = %08x\n", info->info.uid, info->info.flags));
|
||||
d(printf("Updating header for %s flags = %08x\n", info->info.uid, info->info.flags));
|
||||
|
||||
/* find the next message, header parts */
|
||||
camel_mime_parser_seek (mp, info->frompos, SEEK_SET);
|
||||
if (camel_mime_parser_step (mp, &buffer, &len) != HSCAN_FROM) {
|
||||
g_warning ("camel_mime_parser_step failed (1)");
|
||||
camel_mime_parser_seek(mp, info->frompos, SEEK_SET);
|
||||
if (camel_mime_parser_step(mp, &buffer, &len) != HSCAN_FROM) {
|
||||
g_warning("camel_mime_parser_step failed (1)");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (camel_mime_parser_tell_start_from (mp) != info->frompos) {
|
||||
g_warning ("Summary/mbox mismatch, aborting sync");
|
||||
g_warning("Summary/mbox mismatch, aborting sync");
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Summary mismatch, aborting sync");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (camel_mime_parser_step (mp, &buffer, &len) == HSCAN_FROM_END) {
|
||||
g_warning ("camel_mime_parser_step failed (2)");
|
||||
g_warning("camel_mime_parser_step failed (2)");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Check if the X-Evolution header is valid. */
|
||||
|
||||
xev = camel_mime_parser_header (mp, "X-Evolution", &xevoffset);
|
||||
xev = camel_mime_parser_header(mp, "X-Evolution", &xevoffset);
|
||||
if (xev && header_evolution_decode (xev, &uid, &flags) != -1)
|
||||
xevok = TRUE;
|
||||
|
||||
xevnew = header_evolution_encode (strtoul (info->info.uid, NULL, 10), info->info.flags & 0xffff);
|
||||
xevnew = header_evolution_encode(strtoul (info->info.uid, NULL, 10), info->info.flags & 0xffff);
|
||||
if (quick) {
|
||||
if (!xevok) {
|
||||
g_warning ("The summary told me I had an X-Evolution header, but i dont!");
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Summary mismatch, X-Evolution header missing");
|
||||
g_warning("The summary told me I had an X-Evolution header, but i dont!");
|
||||
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Summary mismatch, X-Evolution header missing");
|
||||
goto error;
|
||||
}
|
||||
buffer = g_strdup_printf ("X-Evolution: %s", xevnew);
|
||||
lastpos = lseek (fd, 0, SEEK_CUR);
|
||||
lseek (fd, xevoffset, SEEK_SET);
|
||||
buffer = g_strdup_printf("X-Evolution: %s", xevnew);
|
||||
lastpos = lseek(fd, 0, SEEK_CUR);
|
||||
lseek(fd, xevoffset, SEEK_SET);
|
||||
do {
|
||||
len = write (fd, buffer, strlen (buffer));
|
||||
len = write(fd, buffer, strlen (buffer));
|
||||
} while (len == -1 && errno == EINTR);
|
||||
lseek (fd, lastpos, SEEK_SET);
|
||||
g_free (buffer);
|
||||
lseek(fd, lastpos, SEEK_SET);
|
||||
g_free(buffer);
|
||||
if (len == -1) {
|
||||
g_warning ("Yahoo! len == -1");
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
frompos = lseek (fdout, 0, SEEK_CUR);
|
||||
fromline = camel_mbox_summary_build_from (camel_mime_parser_headers_raw (mp));
|
||||
write (fdout, fromline, strlen(fromline));
|
||||
g_free (fromline);
|
||||
if (header_write (fdout, camel_mime_parser_headers_raw (mp), xevnew) == -1) {
|
||||
d(printf ("Error writing to tmp mailbox\n"));
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Error writing to temp mailbox: %s",
|
||||
strerror (errno));
|
||||
frompos = lseek(fdout, 0, SEEK_CUR);
|
||||
fromline = camel_mbox_summary_build_from(camel_mime_parser_headers_raw (mp));
|
||||
write(fdout, fromline, strlen(fromline));
|
||||
g_free(fromline);
|
||||
if (header_write(fdout, camel_mime_parser_headers_raw(mp), xevnew) == -1) {
|
||||
d(printf("Error writing to tmp mailbox\n"));
|
||||
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Error writing to temp mailbox: %s",
|
||||
strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
bodypos = lseek (fdout, 0, SEEK_CUR);
|
||||
d(printf ("pos = %d, endpos = %d, bodypos = %d\n",
|
||||
(int) info->info.content->pos,
|
||||
(int) info->info.content->endpos,
|
||||
(int) info->info.content->bodypos));
|
||||
if (copy_block (fd, fdout, info->info.content->bodypos,
|
||||
info->info.content->endpos - info->info.content->bodypos) == -1) {
|
||||
g_warning ("Cannot copy data to output fd");
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Cannot copy data to output fd: %s",
|
||||
strerror (errno));
|
||||
bodypos = lseek(fdout, 0, SEEK_CUR);
|
||||
d(printf("pos = %d, endpos = %d, bodypos = %d\n",
|
||||
(int) info->info.content->pos,
|
||||
(int) info->info.content->endpos,
|
||||
(int) info->info.content->bodypos));
|
||||
if (copy_block(fd, fdout, info->info.content->bodypos,
|
||||
info->info.content->endpos - info->info.content->bodypos) == -1) {
|
||||
g_warning("Cannot copy data to output fd");
|
||||
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Cannot copy data to output fd: %s",
|
||||
strerror (errno));
|
||||
goto error;
|
||||
}
|
||||
info->frompos = frompos;
|
||||
offset = bodypos - info->info.content->bodypos;
|
||||
}
|
||||
info->info.flags &= 0xffff;
|
||||
g_free (xevnew);
|
||||
g_free(xevnew);
|
||||
xevnew = NULL;
|
||||
camel_mime_parser_drop_step (mp);
|
||||
camel_mime_parser_drop_step (mp);
|
||||
camel_mime_parser_drop_step(mp);
|
||||
camel_mime_parser_drop_step(mp);
|
||||
} else {
|
||||
if (!quick) {
|
||||
if (copy_block (fd, fdout, info->frompos,
|
||||
info->info.content->endpos - info->frompos) == -1) {
|
||||
g_warning ("Cannot copy data to output fd");
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Cannot copy data to output fd: %s",
|
||||
strerror (errno));
|
||||
if (copy_block(fd, fdout, info->frompos,
|
||||
info->info.content->endpos - info->frompos) == -1) {
|
||||
g_warning("Cannot copy data to output fd");
|
||||
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Cannot copy data to output fd: %s",
|
||||
strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
/* update from pos here? */
|
||||
info->frompos += offset;
|
||||
} else {
|
||||
d(printf ("Nothing to do for this message\n"));
|
||||
d(printf("Nothing to do for this message\n"));
|
||||
}
|
||||
}
|
||||
if (!quick && info != NULL && offset != 0) {
|
||||
d(printf ("offsetting content: %d\n", (int) offset));
|
||||
camel_folder_summary_offset_content (info->info.content, offset);
|
||||
d(printf ("pos = %d, endpos = %d, bodypos = %d\n",
|
||||
(int) info->info.content->pos,
|
||||
(int) info->info.content->endpos,
|
||||
(int) info->info.content->bodypos));
|
||||
d(printf("offsetting content: %d\n", (int)offset));
|
||||
camel_folder_summary_offset_content(info->info.content, offset);
|
||||
d(printf("pos = %d, endpos = %d, bodypos = %d\n",
|
||||
(int) info->info.content->pos,
|
||||
(int) info->info.content->endpos,
|
||||
(int) info->info.content->bodypos));
|
||||
}
|
||||
}
|
||||
|
||||
d(printf ("Closing folders\n"));
|
||||
d(printf("Closing folders\n"));
|
||||
|
||||
if (close (fd) == -1) {
|
||||
g_warning ("Cannot close source folder: %s", strerror (errno));
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not close source folder %s: %s",
|
||||
mbs->folder_path, strerror (errno));
|
||||
if (close(fd) == -1) {
|
||||
g_warning("Cannot close source folder: %s", strerror(errno));
|
||||
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not close source folder %s: %s",
|
||||
mbs->folder_path, strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!quick) {
|
||||
if (close (fdout) == -1) {
|
||||
g_warning ("Cannot close tmp folder: %s", strerror (errno));
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not close temp folder: %s",
|
||||
strerror (errno));
|
||||
if (close(fdout) == -1) {
|
||||
g_warning("Cannot close tmp folder: %s", strerror(errno));
|
||||
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not close temp folder: %s",
|
||||
strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (rename (tmpname, mbs->folder_path) == -1) {
|
||||
g_warning ("Cannot rename folder: %s", strerror (errno));
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not rename folder: %s",
|
||||
strerror (errno));
|
||||
if (rename(tmpname, mbs->folder_path) == -1) {
|
||||
g_warning("Cannot rename folder: %s", strerror(errno));
|
||||
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Could not rename folder: %s",
|
||||
strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
tmpname = NULL;
|
||||
|
||||
if (mbs->index)
|
||||
ibex_save (mbs->index);
|
||||
ibex_save(mbs->index);
|
||||
}
|
||||
|
||||
if (stat (mbs->folder_path, &st) == -1) {
|
||||
g_warning ("Hmm... stat(mbs->folder_path, &st) == -1");
|
||||
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Unknown error: %s",
|
||||
strerror (errno));
|
||||
if (stat(mbs->folder_path, &st) == -1) {
|
||||
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
|
||||
"Unknown error: %s",
|
||||
strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
|
||||
camel_folder_summary_touch (s);
|
||||
camel_folder_summary_touch(s);
|
||||
s->time = st.st_mtime;
|
||||
mbs->folder_size = st.st_size;
|
||||
camel_folder_summary_save (s);
|
||||
camel_folder_summary_save(s);
|
||||
|
||||
camel_object_unref (CAMEL_OBJECT (mp));
|
||||
camel_object_unref(CAMEL_OBJECT(mp));
|
||||
|
||||
return 0;
|
||||
error:
|
||||
if (fd != -1)
|
||||
close (fd);
|
||||
close(fd);
|
||||
|
||||
if (fdout != -1)
|
||||
close (fdout);
|
||||
close(fdout);
|
||||
|
||||
g_free (xevnew);
|
||||
g_free(xevnew);
|
||||
|
||||
if (tmpname)
|
||||
unlink (tmpname);
|
||||
unlink(tmpname);
|
||||
if (mp)
|
||||
camel_object_unref (CAMEL_OBJECT (mp));
|
||||
camel_object_unref(CAMEL_OBJECT(mp));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -235,6 +235,13 @@ int camel_mh_summary_check(CamelMhSummary * mhs, int forceindex)
|
||||
g_hash_table_foreach(left, (GHFunc)remove_summary, mhs);
|
||||
g_hash_table_destroy(left);
|
||||
|
||||
/* force a save of the index, just to make sure */
|
||||
/* note this could be expensive so possibly shouldn't be here
|
||||
as such */
|
||||
if (mhs->index) {
|
||||
ibex_save(mhs->index);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -248,6 +255,9 @@ int camel_mh_summary_sync(CamelMhSummary * mhs, int expunge, CamelException *ex
|
||||
|
||||
printf("summary_sync(expunge=%s)\n", expunge?"true":"false");
|
||||
|
||||
if (mhs->index) {
|
||||
ibex_save(mhs->index);
|
||||
}
|
||||
if (!expunge)
|
||||
return 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user