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:
Not Zed
2000-09-28 11:31:29 +00:00
committed by Michael Zucci
parent 18579aa7e0
commit e71de4c021
13 changed files with 4851 additions and 295 deletions

View File

@ -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):

View File

@ -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 \

File diff suppressed because it is too large Load Diff

257
camel/camel-charset-map.c Normal file
View 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
View 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 */

View File

@ -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));

View File

@ -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 *);

View File

@ -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++) {

View File

@ -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;

View File

@ -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 */

View File

@ -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);

View File

@ -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;
}

View File

@ -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;