/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * * Copyright (C) 1999 Bertrand Guiheneuf . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include #include "mh-uid.h" #include "camel-log.h" #include "camel-stream.h" #include "camel-stream-fs.h" #include "camel-stream-buffered-fs.h" #include "gmime-utils.h" #include "md5-utils.h" #include "mh-utils.h" #include #include #include #include #include #include #include #include void mh_uid_get_for_file (gchar *filename, guchar uid[16]) { CamelStream *message_stream; GArray *header_array; Rfc822Header *cur_header; int i; MD5Context ctx; message_stream = camel_stream_buffered_fs_new_with_name (filename, CAMEL_STREAM_BUFFERED_FS_READ); header_array = get_header_array_from_stream (message_stream); gtk_object_unref (GTK_OBJECT (message_stream)); md5_init (&ctx); for (i=0; ilen; i++) { cur_header = (Rfc822Header *)header_array->data + i; if (!g_strcasecmp (cur_header->name, "subject")) { md5_update (&ctx, cur_header->value, strlen (cur_header->value)); } else if (!g_strcasecmp (cur_header->name, "sender")) { md5_update (&ctx, cur_header->value, strlen (cur_header->value)); } else if (!g_strcasecmp (cur_header->name, "date")) { md5_update (&ctx, cur_header->value, strlen (cur_header->value)); } g_free (cur_header->name); g_free (cur_header->value); } g_array_free (header_array, TRUE); md5_final (uid, &ctx); } void mh_save_uid_list (CamelMhFolder *mh_folder) { GArray *uid_array; MhUidCouple *first_uid_couple; gchar *directory_path = mh_folder->directory_path; gchar *uidfile_path; int fd; int i; uidfile_path = g_strdup_printf ("%s/%s", directory_path, ".camel-uid-list"); CAMEL_LOG_FULL_DEBUG ("In the process of writing %s\n", uidfile_path); fd = open (uidfile_path, O_WRONLY | O_CREAT ); if (!fd) { CAMEL_LOG_FULL_DEBUG ("could not open file %s for writing. Exiting.\n", uidfile_path); g_free (uidfile_path); return; } g_free (uidfile_path); uid_array = mh_folder->uid_array; first_uid_couple = (MhUidCouple *)uid_array->data; /* write the number of uid contained in the file */ write (fd, &(uid_array->len), sizeof (guint)); CAMEL_LOG_FULL_DEBUG ("%d entrie present in the list\n", uid_array->len); /* now write the array of uid self */ write (fd, first_uid_couple, sizeof (MhUidCouple) * uid_array->len); close (fd); } gint mh_load_uid_list (CamelMhFolder *mh_folder) { GArray *new_uid_array; MhUidCouple *first_uid_couple; gchar *directory_path = mh_folder->directory_path; gchar *uidfile_path; int fd; guint uid_nb; struct stat stat_buf; gint stat_error = 0; uidfile_path = g_strdup_printf ("%s/%s", directory_path, ".camel-uid-list"); /* tests if file exists */ stat_error = stat (uidfile_path, &stat_buf); if (!((stat_error != -1) && S_ISREG (stat_buf.st_mode))) { CAMEL_LOG_FULL_DEBUG ("CamelMhFolder::load_uid_list " "file %s does not exist. Exiting.\n", uidfile_path); g_free (uidfile_path); return -1; } fd = open (uidfile_path, O_RDONLY); g_free (uidfile_path); if (!fd) return -1; if (mh_folder->uid_array) g_array_free (mh_folder->uid_array, FALSE); /* read the number of uids in the file */ read (fd, &uid_nb, sizeof (guint)); CAMEL_LOG_FULL_DEBUG ("reading %d uid_entries\n", uid_nb); new_uid_array = g_array_new (FALSE, FALSE, sizeof (MhUidCouple)); new_uid_array = g_array_set_size (new_uid_array, uid_nb); first_uid_couple = (MhUidCouple *)new_uid_array->data; read (fd, first_uid_couple, sizeof (MhUidCouple) * uid_nb); mh_folder->uid_array = new_uid_array; return 1; } gint mh_generate_uid_list (CamelMhFolder *mh_folder) { GArray *new_uid_array; const gchar *directory_path; struct dirent *dir_entry; DIR *dir_handle; gchar *msg_path; guint msg_count; MhUidCouple *uid_couple; guint file_number; g_assert (mh_folder); CAMEL_LOG_FULL_DEBUG ("in the process of creating uid list \n"); directory_path = mh_folder->directory_path; if (!directory_path) { CAMEL_LOG_FULL_DEBUG ("folder has no directory path. Exiting\n"); return -1; } msg_count = camel_folder_get_message_count (CAMEL_FOLDER (mh_folder), NULL); if (!msg_count) { CAMEL_LOG_FULL_DEBUG ("no message in %s. Exiting\n", directory_path); return -1; } new_uid_array = g_array_new (FALSE, FALSE, sizeof (MhUidCouple)); new_uid_array = g_array_set_size (new_uid_array, msg_count); uid_couple = (MhUidCouple *)new_uid_array->data; dir_handle = opendir (directory_path); /* read first entry in the directory */ dir_entry = readdir (dir_handle); while (dir_entry != NULL) { /* tests if the entry correspond to a message file */ if (mh_is_a_message_file (dir_entry->d_name, directory_path)) { /* get the uid for this message */ msg_path = g_strdup_printf ("%s/%s", directory_path, dir_entry->d_name); mh_uid_get_for_file (msg_path, uid_couple->uid); g_free (msg_path); /* convert filename into file number */ uid_couple->file_number = atoi (dir_entry->d_name); uid_couple++; } /* read next entry */ dir_entry = readdir (dir_handle); } closedir (dir_handle); mh_folder->uid_array = new_uid_array; }