diff -x CVS -pruN tracker.orig/configure.in tracker.modif/configure.in --- tracker.orig/configure.in 2006-09-13 22:03:55.000000000 +0200 +++ tracker.modif/configure.in 2006-09-20 04:33:53.000000000 +0200 @@ -31,7 +31,10 @@ PKG_CHECK_MODULES(PANGO, [ pango >= 1.0. AC_SUBST(PANGO_CFLAGS) AC_SUBST(PANGO_LIBS) - +# Check fo GMime +PKG_CHECK_MODULES(GMIME, [ gmime-2.0 >= 2.2.3 ]) +AC_SUBST(GMIME_CFLAGS) +AC_SUBST(GMIME_LIBS) # Check for Dbus 0.50 or higher PKG_CHECK_MODULES(DBUS, [dbus-1 >= 0.50 dbus-glib-1 >= 0.50 ]) diff -x CVS -pruN tracker.orig/src/trackerd/Makefile.am tracker.modif/src/trackerd/Makefile.am --- tracker.orig/src/trackerd/Makefile.am 2006-09-13 22:03:56.000000000 +0200 +++ tracker.modif/src/trackerd/Makefile.am 2006-09-20 04:35:06.000000000 +0200 @@ -9,6 +9,7 @@ INCLUDES = \ -DDATADIR=\""$(datadir)"\" \ $(GLIB2_CFLAGS) \ $(PANGO_CFLAGS) \ + $(GMIME_CFLAGS) \ $(QDBM_CFLAGS) \ $(SQLITE3_CFLAGS) \ $(FAM_CFLAGS) \ @@ -66,6 +67,10 @@ trackerd_SOURCES = \ tracker-dbus-search.h \ tracker-dbus-search.c \ $(db_sources) \ + tracker-mbox-evolution.c \ + tracker-mbox-evolution.h \ + tracker-mbox.c \ + tracker-mbox.h \ tracker-metadata.c \ tracker-metadata.h \ tracker-rdf-query.c \ @@ -95,10 +100,11 @@ trackerd_LDADD = $(GLIB2_LIBS) \ $(FAM_LIBS) \ $(DBUS_LIBS) \ $(MYSQL_LIBS) \ - $(PANGO_LIBS) \ + $(PANGO_LIBS) \ + $(GMIME_LIBS) \ $(QDBM_LIBS) \ $(SQLITE3_LIBS) \ - -lstdc++ + -lstdc++ tracker_convert_file_SOURCES = tracker-convert-file.c tracker-parser.c tracker-stemmer.c diff -x CVS -pruN tracker.orig/src/trackerd/tracker-db.c tracker.modif/src/trackerd/tracker-db.c --- tracker.orig/src/trackerd/tracker-db.c 2006-09-16 18:54:01.000000000 +0200 +++ tracker.modif/src/trackerd/tracker-db.c 2006-09-20 04:37:05.000000000 +0200 @@ -177,10 +177,8 @@ get_meta_table_data (gpointer key, if (tracker_metadata_is_date (db_action->db_con, mtype)) { char *dvalue; - - dvalue = tracker_format_date (avalue); - + if (dvalue) { time_t time; @@ -197,7 +195,6 @@ get_meta_table_data (gpointer key, evalue = tracker_long_to_str (time); // tracker_log ("date is %s", evalue); } - } else { return; @@ -214,7 +211,6 @@ get_meta_table_data (gpointer key, } - tracker_db_set_metadata (db_action->db_con, "Files", db_action->file_id, mtype, mvalue, TRUE); if (mvalue) { @@ -223,6 +219,23 @@ get_meta_table_data (gpointer key, } +off_t +tracker_db_get_last_mbox_offset (DBConnection *db_con, const char *mbox_uri) +{ + /* FIXME */ + return 0; +} + + +void +tracker_db_update_mbox_offset (DBConnection *db_con, MailBox *mb) +{ + /* FIXME + * new offset is in mb->next_email_offset + */ +} + + void tracker_db_save_metadata (DBConnection *db_con, GHashTable *table, long file_id) { @@ -240,12 +253,26 @@ tracker_db_save_metadata (DBConnection * tracker_db_end_transaction (db_con); } - g_free (db_action.file_id); } void +tracker_db_save_email (DBConnection *db_con, MailMessage *mm) +{ + if (!mm) { + return; + } + + /* + * FIXME + */ + + tracker_log ("Saving email with mbox's uri \"%s\" and id \"%s\".", mm->mbox_uri, mm->message_id); +} + + +void tracker_db_save_thumbs (DBConnection *db_con, const char *small_thumb, const char *large_thumb, long file_id) { char *str_file_id; @@ -328,8 +355,6 @@ tracker_db_get_files_in_folder (DBConnec } - - gboolean tracker_metadata_is_date (DBConnection *db_con, const char *meta) { @@ -361,7 +386,7 @@ tracker_db_get_pending_file (DBConnectio row = tracker_db_get_row (res, 0); - if (row && row[0] && row[1] && row[2] && row[3] && row[4]) { + if (row && row[0] && row[1] && row[2] && row[3] && row[4]) { info = tracker_create_file_info (uri, atoi (row[2]), 0, 0); info->mime = g_strdup (row[3]); info->is_directory = (strcmp (row[4], "0") == 0); diff -x CVS -pruN tracker.orig/src/trackerd/tracker-db.h tracker.modif/src/trackerd/tracker-db.h --- tracker.orig/src/trackerd/tracker-db.h 2006-09-10 01:54:07.000000000 +0200 +++ tracker.modif/src/trackerd/tracker-db.h 2006-09-20 04:30:36.000000000 +0200 @@ -23,6 +23,7 @@ #include #include "tracker-utils.h" +#include "tracker-mbox.h" #include "config.h" @@ -33,23 +34,24 @@ #endif - - -FileInfo * tracker_db_get_file_info (DBConnection *db_con, FileInfo *info); -int tracker_db_get_file_id (DBConnection *db_con, const char *uri); -gboolean tracker_is_valid_service (DBConnection *db_con, const char *service); -char * tracker_db_get_id (DBConnection *db_con, const char *service, const char *uri); -void tracker_db_save_metadata (DBConnection *db_con, GHashTable *table, long file_id); +FileInfo * tracker_db_get_file_info (DBConnection *db_con, FileInfo *info); +int tracker_db_get_file_id (DBConnection *db_con, const char *uri); +gboolean tracker_is_valid_service (DBConnection *db_con, const char *service); +char * tracker_db_get_id (DBConnection *db_con, const char *service, const char *uri); +off_t tracker_db_get_last_mbox_offset (DBConnection *db_con, const char *mbox_uri); +void tracker_db_update_mbox_offset (DBConnection *db_con, MailBox *mb); +void tracker_db_save_metadata (DBConnection *db_con, GHashTable *table, long file_id); +void tracker_db_save_email (DBConnection *db_con, MailMessage *mm); void tracker_db_save_thumbs (DBConnection *db_con, const char *small_thumb, const char *large_thumb, long file_id); -char ** tracker_db_get_files_in_folder (DBConnection *db_con, const char *folder_uri); +char ** tracker_db_get_files_in_folder (DBConnection *db_con, const char *folder_uri); FieldDef * tracker_db_get_field_def (DBConnection *db_con, const char *field_name); -void tracker_db_free_field_def (FieldDef *def); +void tracker_db_free_field_def (FieldDef *def); gboolean tracker_metadata_is_date (DBConnection *db_con, const char *meta); -FileInfo * tracker_db_get_pending_file (DBConnection *db_con, const char *uri); -void tracker_db_update_pending_file (DBConnection *db_con, const char *uri, int counter, TrackerChangeAction action); -void tracker_db_insert_pending_file (DBConnection *db_con, long file_id, const char *uri, const char *mime, int counter, TrackerChangeAction action, gboolean is_directory); -gboolean tracker_db_index_id_exists (DBConnection *db_con, unsigned int id); -gboolean tracker_db_has_pending_files (DBConnection *db_con); +FileInfo * tracker_db_get_pending_file (DBConnection *db_con, const char *uri); +void tracker_db_update_pending_file (DBConnection *db_con, const char *uri, int counter, TrackerChangeAction action); +void tracker_db_insert_pending_file (DBConnection *db_con, long file_id, const char *uri, const char *mime, int counter, TrackerChangeAction action, gboolean is_directory); +gboolean tracker_db_index_id_exists (DBConnection *db_con, unsigned int id); +gboolean tracker_db_has_pending_files (DBConnection *db_con); gboolean tracker_db_has_pending_metadata (DBConnection *db_con); #endif diff -x CVS -pruN tracker.orig/src/trackerd/trackerd.c tracker.modif/src/trackerd/trackerd.c --- tracker.orig/src/trackerd/trackerd.c 2006-09-16 18:54:02.000000000 +0200 +++ tracker.modif/src/trackerd/trackerd.c 2006-09-20 04:30:36.000000000 +0200 @@ -48,6 +48,7 @@ #endif #include "tracker-db.h" +#include "tracker-mbox.h" #include "tracker-metadata.h" #include "tracker-dbus-methods.h" #include "tracker-dbus-metadata.h" @@ -154,15 +155,11 @@ has_prefix (const char *str1, const char static gboolean do_cleanup (const char *sig_msg) { - - if (tracker->log_file) { tracker_log ("Received signal '%s' so now shutting down", sig_msg); - } - - tracker_print_object_allocations (); - + tracker_print_object_allocations (); + } /* clear pending files and watch tables*/ //tracker_db_clear_temp (main_thread_db_con); @@ -178,7 +175,7 @@ do_cleanup (const char *sig_msg) while (!g_mutex_trylock (tracker->files_signal_mutex)) { g_usleep (100); } - + g_mutex_unlock (tracker->files_signal_mutex); @@ -228,6 +225,8 @@ do_cleanup (const char *sig_msg) g_mutex_unlock (tracker->files_check_mutex); g_mutex_lock (tracker->files_stopped_mutex); + tracker_end_email_watching (); + tracker_db_close (main_thread_db_con); /* This must be called after all other db functions */ @@ -622,10 +621,11 @@ static void index_file (DBConnection *db_con, FileInfo *info) { char *str_link_uri, *str_file_id; - char *str_mtime, *str_atime; char *name, *path; GHashTable *meta_table; + gboolean is_a_mbox, is_an_email_attachment; + if (!tracker->is_running) { return; } @@ -633,6 +633,20 @@ index_file (DBConnection *db_con, FileIn /* the file being indexed or info struct may have been deleted in transit so check if still valid and intact */ g_return_if_fail (tracker_file_info_is_valid (info)); + is_a_mbox = FALSE; + is_an_email_attachment = FALSE; + + if (tracker_is_in_a_application_mail_dir (info->uri)) { + if (tracker_is_a_handled_mbox_file (info->uri)) { + is_a_mbox = TRUE; + } else { + /* we get a non mbox file */ + return; + } + } else if (tracker_is_an_email_attachment (info->uri)) { + is_an_email_attachment = TRUE; + } + if (!tracker_file_is_valid (info->uri)) { tracker_log ("Warning - file %s no longer exists - abandoning index on this file", info->uri); return; @@ -643,17 +657,24 @@ index_file (DBConnection *db_con, FileIn tracker_log ("indexing file %s", info->uri); - meta_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - if (info->mime) { g_free (info->mime); } - if (!info->is_directory) { + if (is_a_mbox || is_an_email_attachment) { + if (info->is_directory) { + tracker_log ("******ERROR**** a mbox or an email attachment is detected as directory"); + return; + } + info->mime = tracker_get_mime_type (info->uri); } else { - info->mime = g_strdup ("Folder"); - info->file_size = 0; + if (!info->is_directory) { + info->mime = tracker_get_mime_type (info->uri); + } else { + info->mime = g_strdup ("Folder"); + info->file_size = 0; + } } if (info->is_link) { @@ -662,24 +683,32 @@ index_file (DBConnection *db_con, FileIn str_link_uri = g_strdup (" "); } - - str_mtime = tracker_date_to_str (info->mtime); - str_atime = tracker_date_to_str (info->atime); - name = g_path_get_basename (info->uri); path = g_path_get_dirname (info->uri); - g_hash_table_insert (meta_table, g_strdup ("File.Path"), g_strdup (path)); - g_hash_table_insert (meta_table, g_strdup ("File.Name"), g_strdup (name)); - g_hash_table_insert (meta_table, g_strdup ("File.Link"), g_strdup (str_link_uri)); - g_hash_table_insert (meta_table, g_strdup ("File.Format"), g_strdup (info->mime)); - g_hash_table_insert (meta_table, g_strdup ("File.Size"), tracker_long_to_str (info->file_size)); - g_hash_table_insert (meta_table, g_strdup ("File.Permissions"), g_strdup (info->permissions)); - g_hash_table_insert (meta_table, g_strdup ("File.Modified"), g_strdup (str_mtime)); - g_hash_table_insert (meta_table, g_strdup ("File.Accessed"), g_strdup (str_atime)); + if (!is_a_mbox) { + char *str_mtime, *str_atime; - g_free (str_mtime); - g_free (str_atime); + str_mtime = tracker_date_to_str (info->mtime); + str_atime = tracker_date_to_str (info->atime); + + meta_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + g_hash_table_insert (meta_table, g_strdup ("File.Path"), g_strdup (path)); + g_hash_table_insert (meta_table, g_strdup ("File.Name"), g_strdup (name)); + g_hash_table_insert (meta_table, g_strdup ("File.Link"), g_strdup (str_link_uri)); + g_hash_table_insert (meta_table, g_strdup ("File.Format"), g_strdup (info->mime)); + g_hash_table_insert (meta_table, g_strdup ("File.Size"), tracker_long_to_str (info->file_size)); + g_hash_table_insert (meta_table, g_strdup ("File.Permissions"), g_strdup (info->permissions)); + g_hash_table_insert (meta_table, g_strdup ("File.Modified"), g_strdup (str_mtime)); + g_hash_table_insert (meta_table, g_strdup ("File.Accessed"), g_strdup (str_atime)); + + g_free (str_mtime); + g_free (str_atime); + + } else { + meta_table = NULL; + } str_file_id = tracker_long_to_str (info->file_id); @@ -687,11 +716,18 @@ index_file (DBConnection *db_con, FileIn if (info->file_id == -1) { char *service_name; - if (info->is_directory) { - service_name = g_strdup ("Folders"); + if (is_a_mbox) { + service_name = g_strdup ("Email"); + } else if (is_an_email_attachment) { + service_name = g_strdup ("EmailAttachments"); } else { - service_name = tracker_get_service_type_for_mime (info->mime); + if (info->is_directory) { + service_name = g_strdup ("Folders"); + } else { + service_name = tracker_get_service_type_for_mime (info->mime); + } } + tracker_db_create_service (db_con, path, name, service_name, info->is_directory, info->is_link, FALSE, 0, info->mtime); //tracker_log ("processed file %s with mime %s and service %s", info->uri, info->mime, service_name); @@ -701,7 +737,6 @@ index_file (DBConnection *db_con, FileIn info->file_id = tracker_db_get_file_id (db_con, info->uri); } else { - tracker_log ("updating file %s ", info->uri); tracker_db_update_file (db_con, info->file_id, info->mtime); @@ -712,11 +747,47 @@ index_file (DBConnection *db_con, FileIn if (info->file_id != -1) { - tracker_db_save_metadata (db_con, meta_table, info->file_id); - } + if (is_a_mbox) { + off_t offset; + MailBox *mb; + MailMessage *msg; + + offset = tracker_db_get_last_mbox_offset (db_con, info->uri); + + mb = tracker_mbox_parse_from_offset (info->uri, offset); + + while ((msg = tracker_mbox_parse_next (mb))) { + + if (!tracker->is_running) { + tracker_free_mail_message (msg); + tracker_close_mbox_and_free_memory (mb); + + g_free (name); + g_free (path); + + g_free (str_file_id); + g_free (str_link_uri); + + return; + } + tracker_db_update_mbox_offset (db_con, mb); - g_hash_table_destroy (meta_table); + tracker_db_save_email (db_con, msg); + + tracker_index_each_email_attachment (db_con, msg); + + tracker_free_mail_message (msg); + } + + tracker_close_mbox_and_free_memory (mb); + + } else { + tracker_db_save_metadata (db_con, meta_table, info->file_id); + + g_hash_table_destroy (meta_table); + } + } g_free (name); g_free (path); @@ -817,6 +888,11 @@ start_watching (gpointer data) exit (1); } else { + /* start emails watching */ + if (tracker->index_emails) { + tracker_watch_emails (main_thread_db_con); + } + if (data) { char *watch_folder; int len; @@ -933,7 +1009,7 @@ extract_metadata_thread (void) g_async_queue_push (tracker->file_metadata_queue, info_tmp); } - if (tracker->is_running) { + if (tracker->is_running) { tracker_db_free_result (res); } } @@ -951,52 +1027,62 @@ extract_metadata_thread (void) if (info) { if (info->uri) { - GHashTable *meta_table; - char *file_as_text; + char *file_as_text; - tracker_log ("Extracting Metadata for file %s with mime %s", info->uri, info->mime); + if (tracker_is_a_handled_mbox_file (info->uri)) { + tracker_log ("Extracting Metadata for email from mbox %s", info->uri); - /* refresh stat data in case its changed */ - info = tracker_get_file_info (info); + /* extract body's mail content according to its type: plain text or HTML */ + /* FIXME */ - if (info->file_id == -1) { - info->file_id = (long) tracker_db_get_file_id (db_con, info->uri); - } + } else { + GHashTable *meta_table; - meta_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + tracker_log ("Extracting Metadata for file %s with mime %s", info->uri, info->mime); - tracker_metadata_get_embedded (info->uri, info->mime, meta_table); + /* refresh stat data in case its changed */ + info = tracker_get_file_info (info); - if (g_hash_table_size (meta_table) > 0) { - tracker_db_save_metadata (db_con, meta_table, info->file_id); + if (info->file_id == -1) { + info->file_id = tracker_db_get_file_id (db_con, info->uri); + } - /* to do - emit dbus signal here for EmbeddedMetadataChanged */ - } + meta_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - g_hash_table_destroy (meta_table); + tracker_metadata_get_embedded (info->uri, info->mime, meta_table); - if (tracker->do_thumbnails) { - char *small_thumb_file; + if (g_hash_table_size (meta_table) > 0) { + tracker_db_save_metadata (db_con, meta_table, info->file_id); - /* see if there is a thumbnailer script for the file's mime type */ + /* to do - emit dbus signal here for EmbeddedMetadataChanged */ + } - small_thumb_file = tracker_metadata_get_thumbnail (info->uri, info->mime, THUMB_SMALL); + g_hash_table_destroy (meta_table); - if (small_thumb_file) { - char *large_thumb_file; - large_thumb_file = tracker_metadata_get_thumbnail (info->uri, info->mime, THUMB_LARGE); + if (tracker->do_thumbnails) { + char *small_thumb_file; - if (large_thumb_file) { + /* see if there is a thumbnailer script for the file's mime type */ - tracker_db_save_thumbs (db_con, small_thumb_file, large_thumb_file, info->file_id); + small_thumb_file = tracker_metadata_get_thumbnail (info->uri, info->mime, THUMB_SMALL); - /* to do - emit dbus signal ThumbNailChanged */ + if (small_thumb_file) { + char *large_thumb_file; - g_free (large_thumb_file); - } + large_thumb_file = tracker_metadata_get_thumbnail (info->uri, info->mime, THUMB_LARGE); + + if (large_thumb_file) { + + tracker_db_save_thumbs (db_con, small_thumb_file, large_thumb_file, info->file_id); + + /* to do - emit dbus signal ThumbNailChanged */ - g_free (small_thumb_file); + g_free (large_thumb_file); + } + + g_free (small_thumb_file); + } } } @@ -1024,6 +1110,10 @@ extract_metadata_thread (void) g_free (file_as_text); } + + if (tracker_is_an_email_attachment (info->uri)) { + tracker_unlink_email_attachment (info->uri); + } } tracker_dec_info_ref (info); diff -x CVS -pruN tracker.orig/src/trackerd/tracker-mbox.c tracker.modif/src/trackerd/tracker-mbox.c --- tracker.orig/src/trackerd/tracker-mbox.c 1970-01-01 01:00:00.000000000 +0100 +++ tracker.modif/src/trackerd/tracker-mbox.c 2006-09-20 04:30:36.000000000 +0200 @@ -0,0 +1,527 @@ +/* Tracker + * mbox routines + * Copyright (C) 2005, Mr Jamie McCracken + * + * This library 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 library 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 library; if not, write to the + * free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include + +#include "tracker-mbox.h" +#include "tracker-mbox-evolution.h" + + +extern Tracker *tracker; + + +typedef struct { + char *attachment_name; + char *mime; + char *tmp_decoded_file; +} MailAttachment; + + +static char *base_path_for_attachments = NULL; +static GSList *mboxes = NULL; + + +/* must be called before any work on mbox files */ +void +tracker_watch_emails (DBConnection *db_con) +{ + if (!tracker->index_emails) { + return; + } + + if (!base_path_for_attachments) { + char *pid; + + pid = g_strdup_printf ("%d", getpid ()); + base_path_for_attachments = g_build_filename (g_get_tmp_dir (), pid, "attachment", NULL); + g_free (pid); + } + + g_mime_init (0); + + + mboxes = NULL; + + if (tracker->index_evolution_emails) { + mboxes = g_slist_concat (mboxes, watch_emails_of_evolution (db_con)); + } +} + + +void +tracker_end_email_watching (void) +{ + g_slist_foreach (mboxes, (GFunc) g_free, NULL); + g_slist_free (mboxes); + mboxes = NULL; + + if (base_path_for_attachments) { + g_free (base_path_for_attachments); + base_path_for_attachments = NULL; + } + + g_mime_shutdown (); +} + + +gboolean +tracker_is_in_a_application_mail_dir (const char *uri) +{ + return (is_in_a_evolution_mail_dir (uri)); +} + + +gboolean +tracker_is_a_handled_mbox_file (const char *uri) +{ + const GSList *tmp; + + for (tmp = mboxes; tmp; tmp = g_slist_next (tmp)) { + const char *tmp_uri; + + tmp_uri = (char *) tmp->data; + + if (strcmp (tmp_uri, uri) == 0) { + return TRUE; + } + } + + return FALSE; +} + + +MailBox * +tracker_mbox_parse_from_offset (const char *uri, off_t offset) +{ + char *uri_in_locale; + FILE *f; + GMimeStream *stream; + GMimeParser *parser; + MailBox *mb; + + if (!uri) { + return NULL; + } + + uri_in_locale = g_filename_from_utf8 (uri, -1, NULL, NULL, NULL); + + if (!uri_in_locale) { + tracker_log ("******ERROR**** uri could not be converted to locale format"); + g_free (uri_in_locale); + return NULL; + } + + f = g_fopen (uri_in_locale, "r"); + + g_free (uri_in_locale); + + if (!f) { + return NULL; + } + + stream = g_mime_stream_file_new_with_bounds (f, offset, -1); + + if (!stream) { + fclose (f); + return NULL; + } + + parser = g_mime_parser_new_with_stream (stream); + + if (!parser) { + g_object_unref (stream); + return NULL; + } + + g_mime_parser_set_scan_from (parser, TRUE); + + + mb = g_new (MailBox, 1); + + mb->mbox_uri = g_strdup (uri); + + if (is_in_a_evolution_mail_dir (uri)) { + mb->mail_app = MAIL_APP_EVOLUTION; + } else { + mb->mail_app = MAIL_APP_UNKNOWN; + } + + mb->stream = stream; + mb->parser = parser; + mb->next_email_offset = offset; + + return mb; +} + + +void +tracker_close_mbox_and_free_memory (MailBox *mb) +{ + if (mb) { + g_free (mb->mbox_uri); + g_object_unref (mb->parser); + g_object_unref (mb->stream); + } +} + + +static GSList * +add_recipients (GSList *list, GMimeMessage *message, const char *type) +{ + const InternetAddressList *addrs_list; + + for (addrs_list = g_mime_message_get_recipients (message, type); addrs_list; addrs_list = addrs_list->next) { + Person *p; + + p = g_new (Person, 1); + + p->name = g_strdup (addrs_list->address->name); + p->addr = g_strdup (addrs_list->address->value.addr); + + list = g_slist_append (list, p); + } + + return list; +} + + +static void +find_attachment (GMimeObject *obj, gpointer data) +{ + GMimePart *part; + MailMessage *mail_msg; + const char *content_disposition; + + if (!data) { + return; + } + + part = (GMimePart *) obj; + + if (!GMIME_IS_PART (part)) { + return; + } + + mail_msg = (MailMessage *) data; + + content_disposition = g_mime_part_get_content_disposition (part); + + /* test whether it is a mail attachment */ + if (content_disposition && + strcmp (content_disposition, GMIME_DISPOSITION_ATTACHMENT) == 0) { + const GMimeContentType *content_type; + MailAttachment *ma; + FILE *f; + + content_type = g_mime_part_get_content_type (part); + + if (!content_type->params) { + return; + } + + + ma = g_new (MailAttachment, 1); + + ma->attachment_name = g_strdup (g_mime_part_get_filename (part)); + ma->mime = g_strconcat (content_type->type, "/", content_type->subtype, NULL); + ma->tmp_decoded_file = g_build_filename (mail_msg->path_to_attachments, ma->attachment_name, NULL); + + f = g_fopen (ma->tmp_decoded_file, "w"); + + if (f) { + GMimeStream *stream_tmp_file; + GMimeDataWrapper *wrapper; + + stream_tmp_file = g_mime_stream_file_new (f); + wrapper = g_mime_part_get_content_object (part); + g_mime_data_wrapper_write_to_stream (wrapper, stream_tmp_file); + + mail_msg->attachments = g_slist_prepend (mail_msg->attachments, ma); + + g_object_unref (wrapper); + g_object_unref (stream_tmp_file); + } else { + g_free (ma->attachment_name); + g_free (ma->mime); + g_free (ma->tmp_decoded_file); + g_free (ma); + } + + } +} + + +MailMessage * +tracker_mbox_parse_next (MailBox *mb) +{ + MailMessage *msg; + guint64 msg_offset; + GMimeMessage *message; + const char *tmp; + time_t date; + int gmt_offset; + gboolean is_html; + + if (!mb || !mb->parser) { + return NULL; + } + + msg_offset = g_mime_parser_tell (mb->parser); + + message = g_mime_parser_construct_message (mb->parser); + + mb->next_email_offset = g_mime_parser_tell (mb->parser); + + if (!message) { + return NULL; + } + + msg = g_new (MailMessage, 1); + + msg->mbox_uri = g_strdup (mb->mbox_uri); + msg->offset = msg_offset; + msg->message_id = g_strdup (g_mime_message_get_message_id (message)); + msg->references = NULL; + + /* In-Reply-To header looks like , we want string directly */ + tmp = g_mime_message_get_header (message, "In-Reply-To"); + if (tmp) { + int len; + + len = strlen (tmp); + + if (len > 2) { + msg->reply_to_id = g_strndup (tmp + 1, len - 2); + } else { + /* two characters at least: < and >. Otherwise we don't know what we have! */ + msg->reply_to_id = NULL; + } + } else { + msg->reply_to_id = NULL; + } + + g_mime_message_get_date (message, &date, &gmt_offset); + msg->date = (long) (date + gmt_offset); + + msg->mail_from = g_strdup (g_mime_message_get_sender (message)); + + msg->mail_to = add_recipients (NULL, message, GMIME_RECIPIENT_TYPE_TO); + msg->mail_cc = add_recipients (NULL, message, GMIME_RECIPIENT_TYPE_CC); + msg->mail_bcc = add_recipients (NULL, message, GMIME_RECIPIENT_TYPE_BCC); + + msg->subject = g_strdup (g_mime_message_get_subject (message)); + + msg->body = g_mime_message_get_body (message, FALSE, &is_html); + msg->content_type = g_strdup (is_html ? "text/html" : "text/plain"); + + /* make directory to save attachment */ + msg->path_to_attachments = g_build_filename (base_path_for_attachments, msg->mbox_uri, msg->message_id, NULL); + g_mkdir_with_parents (msg->path_to_attachments, 0700); + + msg->attachments = NULL; + + /* find then save attachments in g_get_tmp_dir() and save entries in MailMessage struct */ + g_mime_message_foreach_part (message, + find_attachment, + msg); + + g_object_unref (message); + + if (!msg->attachments) { + /* no attachment found, so we remove directory immediately */ + g_rmdir (msg->path_to_attachments); + } + + return msg; +} + + +void +tracker_free_mail_message (MailMessage *msg) +{ + if (!msg) { + return; + } + + if (msg->mbox_uri) { + g_free (msg->mbox_uri); + } + + if (msg->message_id) { + g_free (msg->message_id); + } + + if (msg->references) { + g_strfreev (msg->references); + } + + if (msg->reply_to_id) { + g_free (msg->reply_to_id); + } + + if (msg->mail_from) { + g_free (msg->mail_from); + } + + if (msg->mail_to) { + g_slist_foreach (msg->mail_to, (GFunc) tracker_free_person, NULL); + g_slist_free (msg->mail_to); + } + + if (msg->mail_cc) { + g_slist_foreach (msg->mail_cc, (GFunc) tracker_free_person, NULL); + g_slist_free (msg->mail_cc); + } + + if (msg->mail_bcc) { + g_slist_foreach (msg->mail_bcc, (GFunc) tracker_free_person, NULL); + g_slist_free (msg->mail_bcc); + } + + if (msg->subject) { + g_free (msg->subject); + } + + if (msg->content_type) { + g_free (msg->content_type); + } + + if (msg->body) { + g_free (msg->body); + } + + if (msg->path_to_attachments) { + g_free (msg->path_to_attachments); + } + + if (msg->attachments) { + GSList *tmp; + + for (tmp = msg->attachments; tmp; tmp = g_slist_next (tmp)) { + MailAttachment *ma; + + ma = (MailAttachment *) tmp->data; + + if (ma->attachment_name) { + g_free (ma->attachment_name); + } + + if (ma->mime) { + g_free (ma->mime); + } + + if (ma->tmp_decoded_file) { + g_free (ma->tmp_decoded_file); + } + + g_free (ma); + } + + g_slist_free (msg->attachments); + } + + g_free (msg); +} + + +void +tracker_free_person (Person *p) +{ + if (!p) { + return; + } + + if (p->name) { + g_free (p->name); + } + + if (p->addr) { + g_free (p->addr); + } + + g_free (p); +} + + +gboolean +tracker_is_an_email_attachment (const char *uri) +{ + int len; + + if (!uri || !base_path_for_attachments) { + return FALSE; + } + + len = strlen (base_path_for_attachments); + + return (strncmp (uri, base_path_for_attachments, len) == 0); +} + + +void +tracker_index_each_email_attachment (DBConnection *db_con, const MailMessage *msg) +{ + const GSList *tmp; + + if (!msg) { + return; + } + + for (tmp = msg->attachments; tmp; tmp = g_slist_next (tmp)) { + const MailAttachment *ma; + FileInfo *info; + + ma = (MailAttachment *) tmp->data; + + info = tracker_create_file_info (ma->tmp_decoded_file, TRACKER_ACTION_CHECK, 0, WATCH_OTHER); + + info->is_directory = FALSE; + info->mime = g_strdup (ma->mime); + + g_async_queue_push (tracker->file_process_queue, info); + } +} + + +void +tracker_unlink_email_attachment (const char *uri) +{ + char *uri_in_locale; + + if (!uri || !tracker_is_an_email_attachment (uri)) { + return; + } + + uri_in_locale = g_filename_from_utf8 (uri, -1, NULL, NULL, NULL); + + if (!uri_in_locale) { + tracker_log ("******ERROR**** uri could not be converted to locale format"); + g_free (uri_in_locale); + return; + } + + g_unlink (uri_in_locale); + + g_free (uri_in_locale); +} diff -x CVS -pruN tracker.orig/src/trackerd/tracker-mbox-evolution.c tracker.modif/src/trackerd/tracker-mbox-evolution.c --- tracker.orig/src/trackerd/tracker-mbox-evolution.c 1970-01-01 01:00:00.000000000 +0100 +++ tracker.modif/src/trackerd/tracker-mbox-evolution.c 2006-09-20 04:30:36.000000000 +0200 @@ -0,0 +1,137 @@ +/* Tracker + * mbox routines + * Copyright (C) 2005, Mr Jamie McCracken + * + * This library 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 library 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 library; if not, write to the + * free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#include "tracker-mbox-evolution.h" + +#ifdef HAVE_INOTIFY +# include "tracker-inotify.h" +#else +# ifdef HAVE_FAM +# include "tracker-fam.h" +# endif +#endif + + +extern Tracker *tracker; + + +#define EVOLUTION_MAIL_DIR ".evolution/mail" + + +static GSList * +find_evolution_mboxes (const char *evolution_dir) +{ + GSList *file_list; + char *filenames[] = {"Inbox", "Sent", NULL}; + char *dir, **filename; + size_t len; + + if (!evolution_dir) { + return NULL; + } + + len = strlen (evolution_dir); + + if (len && evolution_dir[len - 1] == G_DIR_SEPARATOR) { + dir = g_strndup (evolution_dir, len - 1); + } else { + dir = g_strdup (evolution_dir); + } + + file_list = NULL; + + for (filename = filenames; *filename; filename++) { + char *file; + + file = g_build_filename (dir, "local", *filename, NULL); + + if (!g_access (file, F_OK) && !g_access (file, R_OK)) { + file_list = g_slist_prepend (file_list, file); + } + } + + g_free (dir); + + return file_list; +} + + +GSList * +watch_emails_of_evolution (DBConnection *db_con) +{ + char *evolution_dir; + GSList *list; + const GSList *tmp; + + evolution_dir = g_build_filename (g_get_home_dir (), EVOLUTION_MAIL_DIR, NULL); + + list = find_evolution_mboxes (evolution_dir); + + g_free (evolution_dir); + + for (tmp = list; tmp; tmp = g_slist_next (tmp)) { + const char *uri; + char *base_dir; + FileInfo *info; + + uri = (char *) tmp->data; + + base_dir = g_path_get_dirname (uri); + + if (!tracker_is_directory_watched (base_dir, db_con)) { + tracker_add_watch_dir (base_dir, db_con); + } + + g_free (base_dir); + + + info = tracker_create_file_info (uri, TRACKER_ACTION_CHECK, 0, WATCH_OTHER); + + info->is_directory = FALSE; + info->mime = g_strdup ("application/mbox"); + + g_async_queue_push (tracker->file_process_queue, info); + } + + return list; +} + + +gboolean +is_in_a_evolution_mail_dir (const char *uri) +{ + char *path; + int len; + gboolean ret; + + path = g_build_filename (g_get_home_dir (), EVOLUTION_MAIL_DIR, NULL); + + len = strlen (path); + + ret = (strncmp (uri, path, len) == 0); + + g_free (path); + + return ret; +} diff -x CVS -pruN tracker.orig/src/trackerd/tracker-mbox-evolution.h tracker.modif/src/trackerd/tracker-mbox-evolution.h --- tracker.orig/src/trackerd/tracker-mbox-evolution.h 1970-01-01 01:00:00.000000000 +0100 +++ tracker.modif/src/trackerd/tracker-mbox-evolution.h 2006-09-20 04:30:36.000000000 +0200 @@ -0,0 +1,43 @@ +/* Tracker + * mbox routines + * Copyright (C) 2005, Mr Jamie McCracken + * + * This library 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 library 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 library; if not, write to the + * free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _TRACKER_MBOX_EVOLUTION_H_ +#define _TRACKER_MBOX_EVOLUTION_H_ + +#include + +#include "config.h" + +#ifdef USING_SQLITE +# include "tracker-db-sqlite.h" +#else +# include "tracker-db-mysql.h" +#endif + + +/* + * These functions are supposed to be used only with tracker-mbox.c + * + */ + +GSList * watch_emails_of_evolution (DBConnection *db_con); +gboolean is_in_a_evolution_mail_dir (const char *uri); + +#endif diff -x CVS -pruN tracker.orig/src/trackerd/tracker-mbox.h tracker.modif/src/trackerd/tracker-mbox.h --- tracker.orig/src/trackerd/tracker-mbox.h 1970-01-01 01:00:00.000000000 +0100 +++ tracker.modif/src/trackerd/tracker-mbox.h 2006-09-20 04:30:36.000000000 +0200 @@ -0,0 +1,93 @@ +/* Tracker + * mbox routines + * Copyright (C) 2005, Mr Jamie McCracken + * + * This library 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 library 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 library; if not, write to the + * free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _TRACKER_MBOX_H_ +#define _TRACKER_MBOX_H_ + +#include +#include + +#include "tracker-utils.h" + +#include "config.h" + +#ifdef USING_SQLITE +# include "tracker-db-sqlite.h" +#else +# include "tracker-db-mysql.h" +#endif + + +typedef enum { + MAIL_APP_EVOLUTION, + MAIL_APP_KMAIL, + MAIL_APP_THUNDERBIRD, + MAIL_APP_UNKNOWN +} MailApplication; + + +typedef struct { + char *name; + char *addr; +} Person; + + +typedef struct { + char *mbox_uri; + MailApplication mail_app; + GMimeStream *stream; + GMimeParser *parser; + guint64 next_email_offset; +} MailBox; + + +typedef struct { + char *mbox_uri; + guint64 offset; /* start address of the email */ + char *message_id; + char **references; /* array of message_ids */ + char *reply_to_id; /* message_id of email that it replies to */ + long date; + char *mail_from; + GSList *mail_to; + GSList *mail_cc; + GSList *mail_bcc; + char *subject; + char *content_type; /* text/plain or text/html etc. */ + char *body; + char *path_to_attachments; + GSList *attachments; /* names of all attachments */ +} MailMessage; + + +void tracker_watch_emails (DBConnection *db_con); +void tracker_end_email_watching (void); +gboolean tracker_is_in_a_application_mail_dir (const char *uri); +gboolean tracker_is_a_handled_mbox_file (const char *uri); +MailBox * tracker_mbox_parse_from_offset (const char *uri, off_t offset); +void tracker_close_mbox_and_free_memory (MailBox *mb); +MailMessage * tracker_mbox_parse_next (MailBox *mb); +void tracker_free_mail_message (MailMessage *msg); +void tracker_free_person (Person *p); +gboolean tracker_is_an_email_attachment (const char *uri); +void tracker_index_each_email_attachment (DBConnection *db_con, const MailMessage *msg); +void tracker_unlink_email_attachment (const char *uri); + +#endif diff -x CVS -pruN tracker.orig/src/trackerd/tracker-utils.c tracker.modif/src/trackerd/tracker-utils.c --- tracker.orig/src/trackerd/tracker-utils.c 2006-09-16 18:54:02.000000000 +0200 +++ tracker.modif/src/trackerd/tracker-utils.c 2006-09-20 04:30:36.000000000 +0200 @@ -1460,7 +1460,7 @@ tracker_load_config_file () contents = g_strconcat ("[Watches]\n", "WatchDirectoryRoots=", g_get_home_dir (), ";\n", - "NoWatchDirectory=\n\n\n", + "NoWatchDirectory=\n\n", "[Indexes]\n" "IndexTextFiles=true\n", "IndexDocuments=true\n", @@ -1473,10 +1473,14 @@ tracker_load_config_file () "IndexEpiphanyBookmarks=true\n" "IndexEpiphanyHistory=true\n", "IndexFirefoxBookmarks=true\n", - "IndexFirefoxHistory=true\n\n", + "IndexFirefoxHistory=true\n", + "IndexEMails=true\n", + "IndexEvolutionEMails=true\n\n", "[Database]\n", "StoreTextFileContentsInDB=false\n", - "DBBufferMemoryLimit=1M\n", + "DBBufferMemoryLimit=1M\n\n", + "[eMails]\n", + "AdditionalMBoxesToIndex=;\n\n" "[Thumbnails]\n" "DoThumbnails=true\n", NULL); @@ -1562,7 +1566,25 @@ tracker_load_config_file () if (g_key_file_has_key (key_file, "Indexes", "IndexFirefoxHistory", NULL)) { index_firefox_history = g_key_file_get_boolean (key_file, "Indexes", "IndexFirefoxHistory", NULL); } +*/ + if (g_key_file_has_key (key_file, "Indexes", "IndexEMails", NULL)) { + tracker->index_emails = g_key_file_get_boolean (key_file, "Indexes", "IndexEMails", NULL); + } else { + tracker->index_emails = TRUE; + } + + if (tracker->index_emails) { + if (g_key_file_has_key (key_file, "Indexes", "IndexEvolutionEMails", NULL)) { + tracker->index_evolution_emails = g_key_file_get_boolean (key_file, "Indexes", "IndexEvolutionEMails", NULL); + } else { + tracker->index_evolution_emails = TRUE; + } + } else { + tracker->index_evolution_emails = FALSE; + } + +/* if (g_key_file_has_key (key_file, "Database", "StoreTextFileContentsInDB", NULL)) { store_text_file_contents_in_db = g_key_file_get_boolean (key_file, "Indexes", "StoreTextFileContentsInDB", NULL); } @@ -1570,6 +1592,23 @@ tracker_load_config_file () db_buffer_memory_limit = g_key_file_get_string (key_file, "Database", "DBBufferMemoryLimit", NULL); */ + /* e-mails */ + + tracker->additional_mboxes_to_index = NULL; + + if (tracker->index_emails) { + if (g_key_file_has_key (key_file, "eMails", "AdditionalMBoxesToIndex", NULL)) { + char **additional_mboxes; + + additional_mboxes = g_key_file_get_string_list (key_file, "eMails", "AdditionalMBoxesToIndex", NULL, NULL); + + tracker->additional_mboxes_to_index = array_to_list (additional_mboxes); + } + } + + + /* thumbnails */ + if (g_key_file_has_key (key_file, "Thumbnails", "DoThumbnails", NULL)) { tracker->do_thumbnails = g_key_file_get_boolean (key_file, "Thumbnails", "DoThumbnails", NULL); } else { @@ -1751,7 +1790,6 @@ tracker_notify_request_data_available (v return; } - /* if thread not in check phase then we need do nothing */ if (g_mutex_trylock (tracker->request_check_mutex)) { g_mutex_unlock (tracker->request_check_mutex); diff -x CVS -pruN tracker.orig/src/trackerd/tracker-utils.h tracker.modif/src/trackerd/tracker-utils.h --- tracker.orig/src/trackerd/tracker-utils.h 2006-09-13 19:11:54.000000000 +0200 +++ tracker.modif/src/trackerd/tracker-utils.h 2006-09-20 04:30:36.000000000 +0200 @@ -48,6 +48,9 @@ typedef struct { GSList *poll_list; gboolean use_nfs_safe_locking; + gboolean index_emails; + gboolean index_evolution_emails; + GSList *additional_mboxes_to_index; gboolean do_thumbnails; GHashTable *file_scheduler;