10 #include "mbox_folder.h"
13 #include "procheader.h"
17 static gboolean mbox_write_data(FILE * mbox_fp, FILE * new_fp,
18 gchar * new_filename, gint size);
21 /**********************************************************/
25 /**********************************************************/
28 static GSList * file_lock = NULL;
30 static gboolean mbox_file_lock_file(gchar * base)
32 gchar *lockfile, *locklink;
36 lockfile = g_strdup_printf("%s.%d", base, getpid());
37 if ((lockfp = fopen(lockfile, "w")) == NULL) {
38 FILE_OP_ERROR(lockfile, "fopen");
39 g_warning(_("can't create lock file %s\n"), lockfile);
40 g_warning(_("use 'flock' instead of 'file' if possible.\n"));
45 fprintf(lockfp, "%d\n", getpid());
48 locklink = g_strconcat(base, ".lock", NULL);
49 while (link(lockfile, locklink) < 0) {
50 FILE_OP_ERROR(lockfile, "link");
52 g_warning(_("can't create %s\n"), lockfile);
58 g_warning(_("mailbox is owned by another"
59 " process, waiting...\n"));
69 static gboolean mbox_fcntl_lockwrite_file(FILE * fp)
78 if (fcntl(fileno(fp), F_SETLK, &lck) < 0)
84 static gboolean mbox_fcntl_lockread_file(FILE * fp)
93 if (fcntl(fileno(fp), F_SETLK, &lck) < 0)
99 static gboolean mbox_fcntl_unlock_file(FILE * fp)
103 lck.l_type = F_UNLCK;
108 if (fcntl(fileno(fp), F_SETLK, &lck) < 0)
114 static gboolean mbox_file_unlock_file(gchar * base)
116 gchar *lockfile, *locklink;
120 lockfile = g_strdup_printf("%s.lock", base);
127 static gboolean mbox_lockread_file(FILE * fp, gchar * base)
131 result = mbox_fcntl_lockread_file(fp);
133 if (result = mbox_file_lock_file(base)) {
134 file_lock = g_slist_append(file_lock, g_strdup(base));
135 debug_print("lockfile lock %s.\n", base);
138 g_warning(_("could not lock read file %s\n"), base);
141 debug_print("fcntl lock %s.\n", base);
146 static gboolean mbox_lockwrite_file(FILE * fp, gchar * base)
150 result = mbox_fcntl_lockwrite_file(fp);
152 if (result = mbox_file_lock_file(base)) {
153 file_lock = g_slist_append(file_lock, g_strdup(base));
154 debug_print("lockfile lock %s.\n", base);
157 g_warning(_("could not lock write file %s\n"), base);
160 debug_print("fcntl lock %s.\n", base);
165 static gboolean mbox_unlock_file(FILE * fp, gchar * base)
169 gboolean unlocked = FALSE;
171 for(l = file_lock ; l != NULL ; l = g_slist_next(l)) {
172 gchar * data = l->data;
174 if (strcmp(data, base) == 0) {
175 file_lock = g_slist_remove(file_lock, data);
177 result = mbox_file_unlock_file(base);
184 result = mbox_fcntl_unlock_file(fp);
189 /**********************************************************/
193 /**********************************************************/
195 #define MAILFILE_ERROR_NO_ERROR 0x000
196 #define MAILFILE_ERROR_FILE_NOT_FOUND 0x001
197 #define MAILFILE_ERROR_MEMORY 0x002
198 #define MAILFILE_ERROR_MESSAGE_NOT_FOUND 0x003
200 static int mailfile_error = MAILFILE_ERROR_NO_ERROR;
202 #define STATE_BEGIN 0x000
203 #define STATE_TEXT_READ 0x001
204 #define STATE_FROM_READ 0x002
205 #define STATE_FIELD_READ 0x003
206 #define STATE_END 0x004
207 #define STATE_END_OF_FILE 0x005
208 #define STATE_MEM_ERROR 0x006
209 #define STATE_TEXT_BEGIN 0x007
211 #define STATE_MASK 0x0FF // filter state from functions
213 #define STATE_RESTORE_POS 0x100 // go back while reading
215 typedef struct _mailfile mailfile;
240 static int startFrom(char * s)
242 return (strncmp(s, "From ", 5) == 0);
245 static int startSpace(char * s)
247 return ((*s == ' ') || (*s == '\t'));
250 static int startEmpty(char * s)
255 static void free_msg_list(GList * l)
257 GList * elt = g_list_first(l);
262 elt = g_list_next(elt);
269 static mailfile * mailfile_init_from_file(FILE * f, gchar * filename)
272 GList * msg_list = NULL;
279 struct _message * data = NULL;
284 while (state != STATE_END_OF_FILE) {
285 if ((state & STATE_RESTORE_POS) == 0) {
286 former_pos = lastpos;
289 r = fgets(s, 256, f);
292 ignore_next = (s[strlen(s) - 1] != '\n');
297 switch(state & 0x0F) {
300 state = STATE_END_OF_FILE;
301 else if (startFrom(s)) {
302 state = STATE_FROM_READ;
304 data = g_new0(struct _message, 1);
306 free_msg_list(msg_list);
311 data->msgnum = msgnum;
312 data->offset = lastpos;
313 data->header = lastpos;
317 data->messageid = NULL;
318 data->fromspace = NULL;
320 data->fetched = FALSE;
321 msg_list = g_list_append(msg_list, (gpointer) data);
328 case STATE_TEXT_READ:
331 else if (startFrom(s))
332 state = STATE_END | STATE_RESTORE_POS;
334 state = STATE_TEXT_READ;
337 case STATE_TEXT_BEGIN:
340 else if (startFrom(s)) {
341 data->content = lastpos;
343 state = STATE_END | STATE_RESTORE_POS;
346 state = STATE_TEXT_READ;
349 case STATE_FROM_READ:
350 data->content = lastpos;
353 else if (startSpace(s))
354 state = STATE_FROM_READ;
355 else if (startEmpty(s))
356 state = STATE_TEXT_READ;
358 state = STATE_FIELD_READ;
361 case STATE_FIELD_READ:
362 data->content = lastpos;
365 else if (startSpace(s))
366 state = STATE_FIELD_READ;
367 else if (startEmpty(s))
368 state = STATE_TEXT_BEGIN;
370 state = STATE_FIELD_READ;
374 if ((state & STATE_MASK) == STATE_END) {
375 state = STATE_BEGIN | (state & STATE_RESTORE_POS);
376 if (state & STATE_RESTORE_POS)
377 data->end = former_pos;
384 r = fgets(s, 256, f);
385 if (r == NULL || *r == '\0')
388 while (s[strlen(s) - 1] != '\n');
392 mf = (mailfile *) g_new0(struct _mailfile, 1);
394 free_msg_list(msg_list);
395 mailfile_error = MAILFILE_ERROR_MEMORY;
399 mf->msg_list = msg_list;
401 mf->filename = g_strdup(filename);
404 mailfile_error = MAILFILE_ERROR_NO_ERROR;
409 static mailfile * mailfile_init(char * filename)
415 f = fopen(filename, "r");
418 mailfile_error = MAILFILE_ERROR_FILE_NOT_FOUND;
422 mbox_lockread_file(f, filename);
424 mf = mailfile_init_from_file(f, filename);
426 mbox_unlock_file(f, filename);
433 static void mailfile_done(mailfile * f)
435 free_msg_list(f->msg_list);
442 #define MAX_READ 4096
444 static char * readfile(char * filename, int offset, int max_offset)
453 handle = fopen(filename, "r");
455 if (handle == NULL) {
456 mailfile_error = MAILFILE_ERROR_FILE_NOT_FOUND;
460 size = max_offset - offset;
462 message = (char *) malloc(size + 1);
463 if (message == NULL) {
465 mailfile_error = MAILFILE_ERROR_MEMORY;
469 fseek(handle, offset, SEEK_SET);
473 if ((size - pos) > MAX_READ)
478 bread = fread(message + pos, 1, max, handle);
494 static char * mailfile_readmsg(mailfile f, int index)
500 struct _message * msginfo;
502 nth = g_list_nth(f->msg_list, index);
505 mailfile_error = MAILFILE_ERROR_MESSAGE_NOT_FOUND;
509 msginfo = (struct _message *)nth->data;
511 offset = msginfo->offset;
512 max_offset = msginfo->end;
513 message = readfile(f->filename, offset, max_offset);
515 mailfile_error = MAILFILE_ERROR_NO_ERROR;
520 static char * mailfile_readheader(mailfile f, int index)
526 struct _message * msginfo;
528 nth = g_list_nth(f->msg_list, index);
531 mailfile_error = MAILFILE_ERROR_MESSAGE_NOT_FOUND;
535 msginfo = (struct _message *)nth->data;
537 offset = msginfo->offset;
538 max_offset = msginfo->content;
539 message = readfile(f->filename, offset, max_offset);
541 mailfile_error = MAILFILE_ERROR_NO_ERROR;
546 static int mailfile_count(mailfile * f)
548 return g_list_length(f->msg_list);
551 static int mailfile_find_deleted(mailfile f, char * filename)
555 handle = fopen(filename, "r");
558 struct _message m = elt->data;
559 n = fread(&m.deleted, sizeof(int), 1, handle);
562 elt = g_list_next(elt);
571 /**********************************************************/
573 /* mbox cache operations */
575 /**********************************************************/
583 typedef struct _mboxcache mboxcache;
585 static GHashTable * mbox_cache_table = NULL;
586 static mboxcache * current_mbox = NULL;
588 static void mbox_cache_init()
590 mbox_cache_table = g_hash_table_new(g_str_hash, g_str_equal);
593 static void mbox_cache_done()
595 g_hash_table_destroy(mbox_cache_table);
598 static void mbox_cache_free_mbox(mboxcache * cache)
601 g_free(cache->filename);
605 static mboxcache * mbox_cache_read_mbox(gchar * filename)
611 if (stat(filename, &s) < 0)
614 mf = mailfile_init(filename);
618 cache = g_new0(mboxcache, 1);
620 cache->mtime = s.st_mtime;
622 cache->filename = g_strdup(filename);
627 static mboxcache * mbox_cache_read_mbox_from_file(FILE * fp, gchar * filename)
633 if (stat(filename, &s) < 0)
636 mf = mailfile_init_from_file(fp, filename);
640 cache = g_new0(mboxcache, 1);
642 cache->mtime = s.st_mtime;
644 cache->filename = g_strdup(filename);
649 static void mbox_cache_insert_mbox(gchar * filename, mboxcache * data)
651 if (mbox_cache_table == NULL)
654 g_hash_table_insert(mbox_cache_table, filename, data);
657 static mboxcache * mbox_cache_get_mbox(gchar * filename)
659 if (mbox_cache_table == NULL)
662 return g_hash_table_lookup(mbox_cache_table, filename);
666 static gint mbox_cache_get_count(gchar * filename)
670 cache = mbox_cache_get_mbox(filename);
673 if (cache->mf == NULL)
675 return cache->mf->count;
678 static gint mbox_cache_get_mtime(gchar * filename)
682 cache = mbox_cache_get_mbox(filename);
688 static GList * mbox_cache_get_msg_list(gchar * filename)
692 cache = mbox_cache_get_mbox(filename);
697 if (cache->mf == NULL)
700 return cache->mf->msg_list;
703 static void mbox_cache_synchronize_lists(GList * msg_new_list,
704 GList * msg_old_list)
706 struct _message * msg_new;
707 struct _message * msg_old;
711 // could be improved with a hash table
712 for(l_old = msg_old_list ; l_old != NULL ;
713 l_old = g_list_next(l_old)) {
714 msg_old = (struct _message *) l_old->data;
716 if ((msg_old->messageid == NULL) ||
717 (msg_old->fromspace == NULL))
720 for(l_new = msg_new_list ; l_new != NULL ;
721 l_new = g_list_next(l_new)) {
722 msg_new = (struct _message *) l_new->data;
724 if ((msg_new->messageid == NULL) ||
725 (msg_new->fromspace == NULL))
728 if (!strcmp(msg_new->messageid, msg_old->messageid) &&
729 !strcmp(msg_new->fromspace, msg_old->fromspace)) {
731 msg_new->deleted = msg_old->deleted;
732 msg_new->flags = msg_old->flags;
739 static void mbox_cache_synchronize(gchar * filename)
741 mboxcache * new_cache;
742 mboxcache * old_cache;
743 gboolean scan_new = TRUE;
746 old_cache = mbox_cache_get_mbox(filename);
748 if (old_cache != NULL) {
749 if (stat(filename, &s) < 0) {
750 FILE_OP_ERROR(filename, "stat");
751 } else if (old_cache->mtime == s.st_mtime) {
752 debug_print("Folder is not modified.\n");
758 new_cache = mbox_cache_read_mbox(filename);
760 if (new_cache == NULL) {
761 if (old_cache != NULL)
762 mbox_cache_free_mbox(old_cache);
766 if (old_cache != NULL) {
767 if ((old_cache->mf != NULL) &&
768 (new_cache->mf != NULL))
769 mbox_cache_synchronize_lists(new_cache->mf->msg_list, old_cache->mf->msg_list);
770 mbox_cache_free_mbox(old_cache);
773 mbox_cache_insert_mbox(filename, new_cache);
777 static void mbox_cache_synchronize_from_file(FILE * fp, gchar * filename)
779 mboxcache * new_cache;
780 mboxcache * old_cache;
781 gboolean scan_new = TRUE;
784 old_cache = mbox_cache_get_mbox(filename);
786 if (old_cache != NULL) {
787 if (stat(filename, &s) < 0) {
788 FILE_OP_ERROR(filename, "stat");
789 } else if (old_cache->mtime == s.st_mtime) {
790 debug_print("Folder is not modified.\n");
796 new_cache = mbox_cache_read_mbox_from_file(fp, filename);
798 if (new_cache == NULL) {
799 if (old_cache != NULL)
800 mbox_cache_free_mbox(old_cache);
804 if (old_cache != NULL) {
805 if ((old_cache->mf != NULL) &&
806 (new_cache->mf != NULL))
807 mbox_cache_synchronize_lists(new_cache->mf->msg_list, old_cache->mf->msg_list);
808 mbox_cache_free_mbox(old_cache);
811 mbox_cache_insert_mbox(filename, new_cache);
815 gboolean mbox_cache_msg_fetched(gchar * filename, gint num)
818 struct _message * msg;
820 msg_list = mbox_cache_get_msg_list(filename);
821 msg = (struct _message *) g_list_nth_data(msg_list, num - 1);
829 void mbox_cache_msg_set_fetched(gchar * filename, gint num)
832 struct _message * msg;
834 msg_list = mbox_cache_get_msg_list(filename);
835 if ((msg = (struct _message *) g_list_nth_data(msg_list, num - 1))
842 /**********************************************************/
844 /* mbox operations */
846 /**********************************************************/
849 static MsgInfo *mbox_parse_msg(FILE * fp, gint msgnum, FolderItem *item)
853 MsgFlags flags = MSG_NEW|MSG_UNREAD;
855 g_return_val_if_fail(item != NULL, NULL);
856 g_return_val_if_fail(fp != NULL, NULL);
858 if (item->stype == F_QUEUE) {
859 MSG_SET_FLAGS(flags, MSG_QUEUED);
860 } else if (item->stype == F_DRAFT) {
861 MSG_SET_FLAGS(flags, MSG_DRAFT);
864 msginfo = procheader_file_parse(fp, flags, FALSE);
866 if (!msginfo) return NULL;
868 msginfo->msgnum = msgnum;
869 msginfo->folder = item;
871 if (stat(item->path, &s) < 0) {
872 FILE_OP_ERROR(item->path, "stat");
876 msginfo->size = s.st_size;
877 msginfo->mtime = s.st_mtime;
883 GSList *mbox_get_msg_list(Folder *folder, FolderItem *item, gboolean use_cache)
886 GHashTable *msg_table;
887 MsgFlags flags = MSG_NEW|MSG_UNREAD;
893 struct timeval tv_before, tv_after, tv_result;
895 gettimeofday(&tv_before, NULL);
900 fp = fopen(item->path, "r");
902 mbox_lockread_file(fp, item->path);
904 mbox_cache_synchronize_from_file(fp, item->path);
906 if (mbox_cache_get_mbox(item->path) == NULL) {
907 g_warning(_("parsing of %s failed.\n"), item->path);
908 mbox_unlock_file(fp, item->path);
913 for(l = mbox_cache_get_msg_list(item->path) ; l != NULL ;
914 l = g_list_next(l)) {
915 struct _message * msg;
917 msg = (struct _message *) l->data;
920 fseek(fp, msg->header, SEEK_SET);
921 msginfo = mbox_parse_msg(fp, msg->msgnum, item);
925 g_strdup(msginfo->msgid);
926 if (msginfo->fromspace)
928 g_strdup(msginfo->fromspace);
931 if (msg->flags != -1)
932 msginfo->flags = msg->flags;
933 mlist = g_slist_append(mlist, msginfo);
937 mbox_unlock_file(fp, item->path);
942 gettimeofday(&tv_after, NULL);
944 timersub(&tv_after, &tv_before, &tv_result);
945 g_print("mbox_get_msg_list: %s: elapsed time: %ld.%06ld sec\n",
946 item->path, tv_result.tv_sec, tv_result.tv_usec);
952 static gboolean mbox_extract_msg(gchar * mbox_filename, gint msgnum,
953 gchar * dest_filename)
955 struct _message * msg;
963 gboolean already_fetched;
965 src = fopen(mbox_filename, "r");
969 mbox_lockread_file(src, mbox_filename);
971 mbox_cache_synchronize_from_file(src, mbox_filename);
973 already_fetched = mbox_cache_msg_fetched(mbox_filename, msgnum);
975 if (already_fetched) {
976 mbox_unlock_file(src, mbox_filename);
981 msg_list = mbox_cache_get_msg_list(mbox_filename);
983 msg = (struct _message *) g_list_nth_data(msg_list, msgnum - 1);
986 mbox_unlock_file(src, mbox_filename);
991 offset = msg->offset;
992 max_offset = msg->end;
994 size = max_offset - offset;
996 fseek(src, offset, SEEK_SET);
998 dest = fopen(dest_filename, "w");
1000 mbox_unlock_file(src, mbox_filename);
1005 if (change_file_mode_rw(dest, dest_filename) < 0) {
1006 FILE_OP_ERROR(dest_filename, "chmod");
1007 g_warning(_("can't change file mode\n"));
1010 if (!mbox_write_data(src, dest, dest_filename, size)) {
1011 mbox_unlock_file(src, mbox_filename);
1014 unlink(dest_filename);
1021 FILE_OP_ERROR(mbox_filename, "fread");
1025 mbox_cache_msg_set_fetched(mbox_filename, msgnum);
1027 if (fclose(dest) == -1) {
1028 FILE_OP_ERROR(dest_filename, "fclose");
1032 mbox_unlock_file(src, mbox_filename);
1034 if (fclose(src) == -1) {
1035 FILE_OP_ERROR(mbox_filename, "fclose");
1040 unlink(dest_filename);
1047 gchar *mbox_fetch_msg(Folder *folder, FolderItem *item, gint num)
1052 g_return_val_if_fail(item != NULL, NULL);
1054 g_return_val_if_fail(num > 0 && num <= item->last_num, NULL);
1057 path = folder_item_get_path(item);
1058 if (!is_dir_exist(path))
1059 make_dir_hier(path);
1061 filename = g_strconcat(path, G_DIR_SEPARATOR_S, itos(num), NULL);
1065 if (!mbox_extract_msg(item->path, num, filename)) {
1073 gint mbox_add_msg(Folder *folder, FolderItem *dest, const gchar *file,
1074 gboolean remove_source)
1083 if (dest->last_num < 0) {
1084 mbox_scan_folder(folder, dest);
1085 if (dest->last_num < 0) return -1;
1088 src_fp = fopen(file, "r");
1089 if (src_fp == NULL) {
1093 dest_fp = fopen(dest->path, "a");
1094 if (dest_fp == NULL) {
1098 old_size = ftell(dest_fp);
1100 mbox_lockwrite_file(dest_fp, dest->path);
1103 n_read = fread(buf, 1, sizeof(buf), src_fp);
1104 if (n_read < sizeof(buf) && ferror(src_fp))
1106 if (fwrite(buf, n_read, 1, dest_fp) < 1) {
1107 g_warning(_("writing to %s failed.\n"), dest->path);
1108 ftruncate(fileno(dest_fp), old_size);
1114 if (n_read < sizeof(buf))
1120 if (ferror(src_fp)) {
1121 FILE_OP_ERROR(dest->path, "fread");
1124 mbox_unlock_file(src_fp, dest->path);
1126 if (fclose(src_fp) == -1) {
1127 FILE_OP_ERROR(file, "fclose");
1131 if (fclose(dest_fp) == -1) {
1132 FILE_OP_ERROR(dest->path, "fclose");
1137 ftruncate(fileno(dest_fp), old_size);
1141 if (remove_source) {
1142 if (unlink(file) < 0)
1143 FILE_OP_ERROR(file, "unlink");
1147 return dest->last_num;
1151 gint mbox_remove_msg(Folder *folder, FolderItem *item, gint num)
1153 struct _message * msg;
1156 mbox_cache_synchronize(item->path);
1158 msg_list = mbox_cache_get_msg_list(item->path);
1160 msg = (struct _message *) g_list_nth_data(msg_list,
1165 if (!mbox_rewrite(item->path)) {
1166 printf("rewrite %s\n", item->path);
1174 gint mbox_remove_all_msg(Folder *folder, FolderItem *item)
1178 fp = fopen(item->path, "w");
1188 gint mbox_move_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
1192 mbox_cache_synchronize(item->path);
1194 size = msg->end - msg->offset;
1196 src = fopen(mbox_filename, "r");
1199 fseek(src, msg->offset, SEEK_SET);
1201 mbox_lockread_file(src, mbox_filename);
1203 dest = fopen(dest_filename, "a");
1209 if (change_file_mode_rw(dest, dest_filename) < 0) {
1210 FILE_OP_ERROR(dest_filename, "chmod");
1211 g_warning(_("can't change file mode\n"));
1214 if (!mbox_write_data(src, dest, dest_filename, size)) {
1217 unlink(dest_filename);
1225 filename = mbox_fetch_msg(folder, msginfo->folder, msginfo->msgnum);
1226 if (filename == NULL)
1229 ((struct _message *) msginfo->data)->deleted = TRUE;
1231 return mbox_add_msg(folder, dest, filename, TRUE);
1234 gint mbox_move_msgs_with_dest(Folder *folder, FolderItem *dest, GSList *msglist)
1237 gchar * path = NULL;
1239 for(l = msglist ; l != NULL ; l = g_slist_next(l)) {
1240 MsgInfo * msginfo = (MsgInfo *) l->data;
1242 if (msginfo->folder)
1243 path = msginfo->folder->path;
1245 mbox_move_msg(folder, dest, msginfo);
1251 mbox_cache_synchronize(path);
1253 mbox_cache_synchronize(dest->path);
1255 return dest->last_num;
1258 void mbox_scan_folder(Folder *folder, FolderItem *item)
1267 mbox_cache_synchronize(item->path);
1269 cached = mbox_cache_get_mbox(item->path);
1271 if (cached == NULL) {
1279 n_msg = mbox_cache_get_count(item->path);
1282 item->new = item->unread = item->total = 0;
1284 gint new, unread, total;
1286 // procmsg_get_mark_sum(".", &new, &unread, &total);
1287 if (n_msg > total) {
1288 new += n_msg - total;
1289 unread += n_msg - total;
1292 item->unread = unread;
1293 item->total = n_msg;
1296 debug_print(_("Last number in dir %s = %d\n"), item->path,
1298 item->last_num = item->total;
1301 gchar * mbox_get_virtual_path(FolderItem * item)
1306 if (item->parent == NULL) {
1310 gchar * parent_path;
1311 gchar * result_path;
1313 parent_path = mbox_get_virtual_path(item->parent);
1314 if (parent_path == NULL)
1315 result_path = g_strdup(item->name);
1317 result_path = g_strconcat(parent_path,
1320 g_free(parent_path);
1326 static gboolean mbox_write_data(FILE * mbox_fp, FILE * new_fp,
1327 gchar * new_filename, gint size)
1335 while (pos < size) {
1336 if ((size - pos) > sizeof(buf))
1341 n_read = fread(buf, 1, max, mbox_fp);
1342 if (n_read < max && ferror(mbox_fp)) {
1345 if (fwrite(buf, n_read, 1, new_fp) < 1) {
1346 g_warning(_("writing to %s failed.\n"), new_filename);
1359 static gboolean mbox_write_message(FILE * mbox_fp, FILE * new_fp,
1360 gchar * new_filename,
1361 struct _message * msg)
1367 fseek(mbox_fp, msg->header, SEEK_SET);
1368 headers = procheader_get_header_list(mbox_fp);
1369 for(cur = headers ; cur != NULL ;
1370 cur = g_slist_next(cur)) {
1371 Header * h = (Header *) cur->data;
1373 if (!procheader_headername_equal(h->name,
1375 !procheader_headername_equal(h->name,
1377 fwrite(h->name, strlen(h->name),
1379 fwrite(" ", 1, 1, new_fp);
1380 fwrite(h->body, strlen(h->body),
1382 fwrite("\r\n", 2, 1, new_fp);
1385 fwrite("\r\n", 2, 1, new_fp);
1387 size = msg->end - msg->content;
1388 fseek(mbox_fp, msg->content, SEEK_SET);
1390 return mbox_write_data(mbox_fp, new_fp, new_filename, size);
1393 void mbox_update_mark(Folder * folder, FolderItem * item)
1399 msg_list = mbox_cache_get_msg_list(item->path);
1401 for(l = msg_list ; l != NULL ; l = g_list_next(l)) {
1402 struct _message * msg = (struct _message *) l->data;
1404 if (msg->msginfo != NULL) {
1405 msg->flags = msg->msginfo->flags &
1406 MSG_PERMANENT_FLAG_MASK;
1412 void mbox_change_flags(Folder * folder, FolderItem * item, MsgInfo * info)
1414 struct _message * msg = (struct _message *) info->data;
1416 msg->flags = info->flags;
1419 gboolean mbox_rewrite(gchar * mbox)
1426 gboolean modification = FALSE;
1429 msg_list = mbox_cache_get_msg_list(mbox);
1431 for(l = msg_list ; l != NULL ; l = g_list_next(l)) {
1432 struct _message * msg = (struct _message *) l->data;
1434 printf("modification\n");
1435 modification = TRUE;
1443 mbox_fp = fopen(mbox, "r+");
1444 mbox_lockwrite_file(mbox_fp, mbox);
1446 mbox_cache_synchronize_from_file(mbox_fp, mbox);
1448 new = g_strconcat(mbox, ".new", NULL);
1449 new_fp = fopen(new, "w");
1451 mbox_lockwrite_file(new_fp, new);
1455 msg_list = mbox_cache_get_msg_list(mbox);
1456 for(l = msg_list ; l != NULL ; l = g_list_next(l)) {
1457 struct _message * msg = (struct _message *) l->data;
1459 if (!mbox_write_message(mbox_fp, new_fp, new, msg)) {
1467 g_warning(_("can't rename %s to %s\n"), new, mbox);
1468 if (rename(new_fp, mbox) == -1) {
1469 g_warning(_("can't rename %s to %s\n"), new, mbox);
1470 mbox_unlock_file(new_fp, new);
1472 mbox_unlock_file(mbox_fp, mbox);
1477 mbox_unlock_file(new_fp, new);
1481 mbox_unlock_file(mbox_fp, mbox);