Index: tracker-inotify.c =================================================================== RCS file: /cvs/gnome/tracker/src/trackerd/tracker-inotify.c,v retrieving revision 1.14 diff -u -r1.14 tracker-inotify.c --- tracker-inotify.c 11 Sep 2006 13:14:57 -0000 1.14 +++ tracker-inotify.c 20 Sep 2006 16:58:08 -0000 @@ -33,42 +33,42 @@ /* list to temporarily store moved_from events so they can be matched against moved_to events */ static GSList *move_list; static GQueue *inotify_queue; -static int inotify_monitor_fd = -1; -static int inotify_count = 0; +static int inotify_monitor_fd = -1; +static int inotify_count = 0; static GIOChannel *gio; +static gboolean process_moved_events (); + + gboolean tracker_is_directory_watched (const char * dir, DBConnection *db_con) { char ***res; + char **row; - if (!tracker->is_running) { - return FALSE; - } + g_return_val_if_fail (dir != NULL && dir[0] == G_DIR_SEPARATOR, FALSE); - if (!dir || strlen (dir) == 0 || dir[0] != G_DIR_SEPARATOR) { + if (!tracker->is_running) { return FALSE; } res = tracker_exec_proc (db_con, "GetWatchID", 1, dir); - if (res) { - char **row; - - row = tracker_db_get_row (res, 0); + if (!res) { + return FALSE; + } - if (row && row[0]) { - if (atoi (row[0]) > -1) { - return TRUE; - } - } + row = tracker_db_get_row (res, 0); + if (!row || !row[0] || atoi (row[0]) < 0) { tracker_db_free_result (res); + return FALSE; } - return FALSE; + tracker_db_free_result (res); + return TRUE; } @@ -88,9 +88,7 @@ { char *prefix_start, *str; - if (source == NULL) { - return NULL; - } + g_return_val_if_fail (source != NULL, NULL); if (delimiter == NULL) { return g_strdup (source); @@ -116,202 +114,214 @@ info = tracker_create_file_info (uri, action, 1, WATCH_OTHER); - if (tracker_file_info_is_valid (info)) { - info->is_directory = is_dir; + if (!tracker_file_info_is_valid (info)) { + return; + } - if (is_delete_event (action)) { - char *parent; + info->is_directory = is_dir; - parent = g_path_get_dirname (info->uri); + if (is_delete_event (action)) { + char *parent; - if (tracker_file_is_valid (parent)) { - g_async_queue_push (tracker->file_process_queue, info); + parent = g_path_get_dirname (info->uri); - tracker_notify_file_data_available (); - } else { - info = tracker_free_file_info (info); - } + if (tracker_file_is_valid (parent)) { + g_async_queue_push (tracker->file_process_queue, info); + tracker_notify_file_data_available (); + } else { + info = tracker_free_file_info (info); + } - if (parent) { - g_free (parent); - } + g_free (parent); + return; + } - return; - } + /* we are not interested in create events for non-folders (we use writable file closed instead) */ + if (action == TRACKER_ACTION_DIRECTORY_CREATED) { - /* we are not interested in create events for non-folders (we use writable file closed instead) */ - if (action == TRACKER_ACTION_DIRECTORY_CREATED) { - info->action = TRACKER_ACTION_DIRECTORY_CREATED; - info->is_directory = TRUE; - tracker_db_insert_pending_file (main_thread_db_con, info->file_id, info->uri, info->mime, 0, info->action, info->is_directory); - info = tracker_free_file_info (info); - return; + info->action = TRACKER_ACTION_DIRECTORY_CREATED; + info->is_directory = TRUE; + tracker_db_insert_pending_file (main_thread_db_con, info->file_id, info->uri, info->mime, 0, info->action, info->is_directory); + info = tracker_free_file_info (info); + return; - } else if (action == TRACKER_ACTION_FILE_CREATED) { - info = tracker_free_file_info (info); - return; + } else if (action == TRACKER_ACTION_FILE_CREATED) { - } else if (action == TRACKER_ACTION_DIRECTORY_MOVED_FROM || action == TRACKER_ACTION_FILE_MOVED_FROM) { - info->cookie = cookie; - info->counter = 1; - move_list = g_slist_prepend (move_list, info); - return; + info = tracker_free_file_info (info); + return; + + } else if (action == TRACKER_ACTION_DIRECTORY_MOVED_FROM || action == TRACKER_ACTION_FILE_MOVED_FROM) { - } else if (action == TRACKER_ACTION_FILE_MOVED_TO || action == TRACKER_ACTION_DIRECTORY_MOVED_TO) { - FileInfo *moved_to_info; - GSList *tmp; + info->cookie = cookie; + info->counter = 1; + move_list = g_slist_prepend (move_list, info); + g_timeout_add_full (G_PRIORITY_LOW, + 350, + (GSourceFunc) process_moved_events, + NULL, NULL + ); + return; - moved_to_info = info; + } else if (action == TRACKER_ACTION_FILE_MOVED_TO || action == TRACKER_ACTION_DIRECTORY_MOVED_TO) { + FileInfo *moved_to_info; + GSList *tmp; - for (tmp = move_list; tmp; tmp = tmp->next) { - FileInfo *moved_from_info; + moved_to_info = info; - moved_from_info = (FileInfo *) tmp->data; + for (tmp = move_list; tmp; tmp = tmp->next) { + FileInfo *moved_from_info; - if (!moved_from_info) { - tracker_log ("bad FileInfo struct found in move list. Skipping..."); - continue; - } + moved_from_info = (FileInfo *) tmp->data; + + if (!moved_from_info) { + tracker_log ("bad FileInfo struct found in move list. Skipping..."); + continue; + } + + if ((cookie > 0) && (moved_from_info->cookie == cookie)) { + char *str_file_id, *name, *path; - if ((cookie > 0) && (moved_from_info->cookie == cookie)) { - char *str_file_id, *name, *path; + tracker_log ("found matching inotify pair for from %s to %s", moved_from_info->uri, moved_to_info->uri); + move_list = g_slist_remove (move_list, tmp->data); - tracker_log ("found matching inotify pair for from %s to %s", moved_from_info->uri, moved_to_info->uri); - move_list = g_slist_remove (move_list, tmp->data); + moved_from_info = tracker_db_get_file_info (main_thread_db_con, moved_from_info); - moved_from_info = tracker_db_get_file_info (main_thread_db_con, moved_from_info); + /* if orig file not in DB, treat it as a create action */ + if (moved_from_info->file_id == -1) { + tracker_log ("warning original file %s not found in DB", moved_from_info->uri); + break; + } - /* if orig file not in DB, treat it as a create action */ - if (moved_from_info->file_id == -1) { - tracker_log ("warning original file %s not found in DB", moved_from_info->uri); - break; + str_file_id = g_strdup_printf ("%ld", moved_from_info->file_id); + name = g_path_get_basename (moved_to_info->uri); + path = g_path_get_dirname (moved_to_info->uri); + + /* update db so that fileID reflects new uri */ + tracker_db_update_file_move (main_thread_db_con, moved_from_info->file_id, path, name, moved_from_info->indextime); + + /* update File.Path and File.Filename metadata */ + tracker_db_set_metadata (main_thread_db_con, "Files", str_file_id, "File.Path", path, TRUE); + tracker_db_set_metadata (main_thread_db_con, "Files", str_file_id, "File.Name", name, TRUE); + + g_free (str_file_id); + g_free (name); + g_free (path); + + if (tracker_is_directory (moved_to_info->uri)) { + char *modified_path, *old_path, *match_path; + char ***res; + + /* update all childs of the moved directory */ + modified_path = g_strconcat (moved_to_info->uri, G_DIR_SEPARATOR_S, NULL); + old_path = g_strconcat (moved_from_info->uri, G_DIR_SEPARATOR_S, NULL); + match_path = g_strconcat (old_path, "%", NULL); + + tracker_log ("moved file is a dir"); + + /* stop watching old dir, start watching new dir */ + tracker_remove_watch_dir (moved_from_info->uri, TRUE, main_thread_db_con); + tracker_remove_poll_dir (moved_from_info->uri); + + if (tracker_count_watch_dirs () < MAX_FILE_WATCHES) { + tracker_add_watch_dir (moved_to_info->uri, main_thread_db_con); + } else { + tracker_add_poll_dir (moved_to_info->uri); } - str_file_id = g_strdup_printf ("%ld", moved_from_info->file_id); - name = g_path_get_basename (moved_to_info->uri); - path = g_path_get_dirname (moved_to_info->uri); - - /* update db so that fileID reflects new uri */ - tracker_db_update_file_move (main_thread_db_con, moved_from_info->file_id, path, name, moved_from_info->indextime); - - /* update File.Path and File.Filename metadata */ - tracker_db_set_metadata (main_thread_db_con, "Files", str_file_id, "File.Path", path, TRUE); - tracker_db_set_metadata (main_thread_db_con, "Files", str_file_id, "File.Name", name, TRUE); - - g_free (str_file_id); - g_free (name); - g_free (path); - - if (tracker_is_directory (moved_to_info->uri)) { - char *modified_path, *old_path, *match_path; - char ***res; - - /* update all childs of the moved directory */ - modified_path = g_strconcat (moved_to_info->uri, G_DIR_SEPARATOR_S, NULL); - old_path = g_strconcat (moved_from_info->uri, G_DIR_SEPARATOR_S, NULL); - match_path = g_strconcat (old_path, "%", NULL); - - tracker_log ("moved file is a dir"); - - /* stop watching old dir, start watching new dir */ - tracker_remove_watch_dir (moved_from_info->uri, TRUE, main_thread_db_con); - tracker_remove_poll_dir (moved_from_info->uri); - - if (tracker_count_watch_dirs () < MAX_FILE_WATCHES) { - tracker_add_watch_dir (moved_to_info->uri, main_thread_db_con); - } else { - tracker_add_poll_dir (moved_to_info->uri); - } + /* update all changed File.Path metadata */ + tracker_exec_proc (main_thread_db_con, "UpdateFileMovePath", 2, moved_to_info->uri, moved_from_info->uri); - /* update all changed File.Path metadata */ - tracker_exec_proc (main_thread_db_con, "UpdateFileMovePath", 2, moved_to_info->uri, moved_from_info->uri); + /* for each subfolder, we must do the same as above */ - /* for each subfolder, we must do the same as above */ + /* get all sub folders that were moved and add watches */ + res = tracker_db_get_file_subfolders (main_thread_db_con, moved_from_info->uri); - /* get all sub folders that were moved and add watches */ - res = tracker_db_get_file_subfolders (main_thread_db_con, moved_from_info->uri); + if (res) { + char **row; + int k; - if (res) { - char **row; - int k; + k = 0; - k = 0; + while ((row = tracker_db_get_row (res, k))) { - while ((row = tracker_db_get_row (res, k))) { + char *dir_name, *sep, *new_path; + k++; - k++; - if (row && row[0] && row[1] && row[2]) { - char *dir_name, *sep; + if (!row || !row[0] || !row[1] || !row[2]) { + continue; + } - dir_name = g_build_filename (row[1], row[2], NULL); + dir_name = g_build_filename (row[1], row[2], NULL); - sep = str_get_after_prefix (dir_name, old_path); + sep = str_get_after_prefix (dir_name, old_path); - if (sep) { - char *new_path; + if (!sep) { + g_free (dir_name); + continue; + } - new_path = g_build_filename (moved_to_info->uri, sep, NULL); - g_free (sep); + new_path = g_build_filename (moved_to_info->uri, sep, NULL); + g_free (sep); - tracker_log ("moving subfolder %s to %s", dir_name, new_path); + tracker_log ("moving subfolder %s to %s", dir_name, new_path); - /* update all changed File.Path metadata for all files in this subfolder*/ - tracker_exec_proc (main_thread_db_con, "UpdateFileMovePath", 2, new_path, dir_name); + /* update all changed File.Path metadata for all files in this subfolder*/ + tracker_exec_proc (main_thread_db_con, "UpdateFileMovePath", 2, new_path, dir_name); - /* update all subfolders and contained files to new path */ - tracker_exec_proc (main_thread_db_con, "UpdateFileMoveChild", 2, new_path, dir_name); + /* update all subfolders and contained files to new path */ + tracker_exec_proc (main_thread_db_con, "UpdateFileMoveChild", 2, new_path, dir_name); - if (tracker_count_watch_dirs () < MAX_FILE_WATCHES) { - tracker_add_watch_dir (new_path, main_thread_db_con); - } else { - tracker_add_poll_dir (new_path); - } - g_free (new_path); - g_free (dir_name); - } - } + if (tracker_count_watch_dirs () < MAX_FILE_WATCHES) { + tracker_add_watch_dir (new_path, main_thread_db_con); + } else { + tracker_add_poll_dir (new_path); } + g_free (new_path); + g_free (dir_name); - tracker_db_free_result (res); } - /* update uri path of all files in moved folder */ - tracker_exec_proc (main_thread_db_con, "UpdateFileMoveChild", 2, moved_to_info->uri, moved_from_info->uri); - - g_free (modified_path); - g_free (old_path); - g_free (match_path); + tracker_db_free_result (res); } - moved_from_info = tracker_free_file_info (moved_from_info); - moved_to_info = tracker_free_file_info (moved_to_info); - info = NULL; - return; + /* update uri path of all files in moved folder */ + tracker_exec_proc (main_thread_db_con, "UpdateFileMoveChild", 2, moved_to_info->uri, moved_from_info->uri); + + g_free (modified_path); + g_free (old_path); + g_free (match_path); } - } - /* matching pair not found so treat as a create action */ - tracker_log ("no matching pair found for inotify move event"); - if (tracker_is_directory (info->uri)) { - info->action = TRACKER_ACTION_DIRECTORY_CREATED; - } else { - info->action = TRACKER_ACTION_FILE_CREATED; + moved_from_info = tracker_free_file_info (moved_from_info); + moved_to_info = tracker_free_file_info (moved_to_info); + info = NULL; + return; } - tracker_db_insert_pending_file (main_thread_db_con, info->file_id, info->uri, info->mime, 0, info->action, info->is_directory); - info = tracker_free_file_info (info); - return; + } - } else if (action == TRACKER_ACTION_WRITABLE_FILE_CLOSED) { - //tracker_log ("File %s has finished changing", info->uri); - tracker_db_insert_pending_file (main_thread_db_con, info->file_id, info->uri, info->mime, 0, info->action, info->is_directory); - info = tracker_free_file_info (info); - return; + /* matching pair not found so treat as a create action */ + tracker_log ("no matching pair found for inotify move event"); + if (tracker_is_directory (info->uri)) { + info->action = TRACKER_ACTION_DIRECTORY_CREATED; + } else { + info->action = TRACKER_ACTION_FILE_CREATED; } + tracker_db_insert_pending_file (main_thread_db_con, info->file_id, info->uri, info->mime, 0, info->action, info->is_directory); + info = tracker_free_file_info (info); + return; + + } else if (action == TRACKER_ACTION_WRITABLE_FILE_CLOSED) { + + //tracker_log ("File %s has finished changing", info->uri); + tracker_db_insert_pending_file (main_thread_db_con, info->file_id, info->uri, info->mime, 0, info->action, info->is_directory); + info = tracker_free_file_info (info); + return; - tracker_log ("not processing event %s for uri %s", tracker_actions[info->action], info->uri); - tracker_free_file_info (info); } + + tracker_log ("not processing event %s for uri %s", tracker_actions[info->action], info->uri); + tracker_free_file_info (info); } @@ -339,7 +349,6 @@ /* make sure file no longer exists before issuing a "delete" */ if (!tracker_file_is_valid (info->uri)) { - if (info->action == TRACKER_ACTION_DIRECTORY_MOVED_FROM) { process_event (info->uri, TRUE, TRACKER_ACTION_DIRECTORY_DELETED, 0); } else { @@ -356,6 +365,9 @@ } } + if (!move_list) + return FALSE; + return TRUE; } @@ -413,16 +425,6 @@ return TRACKER_ACTION_IGNORE; } - -static void -free_inotify_event (struct inotify_event *event) -{ - g_return_if_fail (event); - - g_free (event); -} - - static gboolean process_inotify_events (void) { @@ -472,7 +474,7 @@ monitor_name = g_strdup (row[0]); } else { monitor_name = NULL; - free_inotify_event (event); + g_free (event); continue; } @@ -480,14 +482,14 @@ } if (action_type == TRACKER_ACTION_IGNORE) { - free_inotify_event (event); + g_free (event); //tracker_log ("inotify event has no action"); continue; } if ( !filename || strlen(filename) == 0) { //tracker_log ("inotify event has no filename"); - free_inotify_event (event); + g_free (event); continue; } @@ -495,7 +497,7 @@ if (!file_utf8_uri || strlen(file_utf8_uri) == 0) { tracker_log ("******ERROR**** file uri could not be converted to utf8 format"); - free_inotify_event (event); + g_free (event); continue; } @@ -508,7 +510,7 @@ if (!dir_utf8_uri) { tracker_log ("******ERROR**** file uri could not be converted to utf8 format"); g_free (file_utf8_uri); - free_inotify_event (event); + g_free (event); continue; } @@ -521,23 +523,11 @@ } - if (monitor_name) { - g_free (monitor_name); - } - - if (str) { - g_free (str); - } - - if (file_utf8_uri) { - g_free (file_utf8_uri); - } - - if (dir_utf8_uri) { - g_free (dir_utf8_uri); - } - - free_inotify_event (event); + g_free (monitor_name); + g_free (str); + g_free (file_utf8_uri); + g_free (dir_utf8_uri); + g_free (event); } return FALSE; @@ -575,8 +565,7 @@ pevent = (struct inotify_event *) &buffer[buffer_i]; event_size = sizeof (struct inotify_event) + pevent->len; - event = g_malloc (event_size); - memmove (event, pevent, event_size); + event = g_memdup (pevent, event_size); g_queue_push_tail (inotify_queue, event); buffer_i += event_size; } @@ -590,15 +579,11 @@ gboolean tracker_start_watching (void) { - if (inotify_monitor_fd != -1) { - return FALSE; - } + g_return_val_if_fail (inotify_monitor_fd == -1, FALSE); inotify_monitor_fd = inotify_init (); - if (inotify_monitor_fd < 0) { - return FALSE; - } + g_return_val_if_fail (inotify_monitor_fd >= 0, FALSE); inotify_queue = g_queue_new (); @@ -607,11 +592,6 @@ g_io_channel_set_flags (gio, G_IO_FLAG_NONBLOCK, NULL); /* periodically process unmatched moved_from events */ - g_timeout_add_full (G_PRIORITY_LOW, - 350, - (GSourceFunc) process_moved_events, - NULL, NULL - ); return TRUE; } @@ -629,11 +609,9 @@ { char *dir_in_locale; - if (!tracker->is_running) { - return FALSE; - } + g_return_val_if_fail (dir != NULL && dir[0] == G_DIR_SEPARATOR, FALSE); - if (!dir || strlen (dir) == 0 || dir[0] != G_DIR_SEPARATOR) { + if (!tracker->is_running) { return FALSE; } @@ -648,6 +626,7 @@ if (g_access (dir_in_locale, F_OK) == 0 && g_access (dir_in_locale, R_OK) == 0) { const guint32 mask = (IN_CLOSE_WRITE | IN_MOVE | IN_CREATE | IN_DELETE| IN_DELETE_SELF | IN_MOVE_SELF); int wd; + char *str_wd; wd = inotify_add_watch (inotify_monitor_fd, dir_in_locale, mask); @@ -656,16 +635,14 @@ if (wd < 0) { tracker_log ("Inotify watch on %s has failed", dir); return FALSE; - } else { - char *str_wd; - - str_wd = g_strdup_printf ("%d", wd); - tracker_exec_proc (db_con, "InsertWatch", 2, dir, str_wd); - g_free (str_wd); - inotify_count++; - tracker_log ("Watching directory %s (total watches = %d)", dir, inotify_count); - return TRUE; } + + str_wd = g_strdup_printf ("%d", wd); + tracker_exec_proc (db_con, "InsertWatch", 2, dir, str_wd); + g_free (str_wd); + inotify_count++; + tracker_log ("Watching directory %s (total watches = %d)", dir, inotify_count); + return TRUE; } g_free (dir_in_locale); @@ -677,41 +654,30 @@ static gboolean delete_watch (const char *dir, DBConnection *db_con) { - char ***res; - int wd; - gboolean found; + char ***res; + int wd; + char **row; - if (!dir || strlen (dir) == 0 || dir[0] != G_DIR_SEPARATOR) { - return FALSE; - } + g_return_val_if_fail (dir != NULL && dir[0] == G_DIR_SEPARATOR, FALSE); res = tracker_exec_proc (db_con, "GetWatchID", 1, dir); wd = -1; - if (res) { - char **row; - - row = tracker_db_get_row (res, 0); - - if (row && row[0]) { - wd = atoi (row[0]); - found = TRUE; - } else { - found = FALSE; - } - - tracker_db_free_result (res); - - } else { - found = FALSE; + if (!res) { + tracker_log ("WARNING : watch id not found for uri %s", dir); + return FALSE; } - if (!found) { + row = tracker_db_get_row (res, 0); + + if (!row || !row[0]) { tracker_log ("WARNING : watch id not found for uri %s", dir); return FALSE; } + wd = atoi (row[0]); + tracker_exec_proc (db_con, "DeleteWatch", 1, dir); if (wd > -1) { @@ -726,44 +692,42 @@ void tracker_remove_watch_dir (const char *dir, gboolean delete_subdirs, DBConnection *db_con) { - if (!dir || strlen (dir) == 0 || dir[0] != G_DIR_SEPARATOR) { - return; - } + char ***res; + char **row; + int k; + int wd; + + g_return_if_fail (dir != NULL && dir[0] == G_DIR_SEPARATOR); delete_watch (dir, db_con); - if (delete_subdirs) { - char ***res; - int wd; + if (!delete_subdirs) { + return; + } - res = tracker_db_get_sub_watches (db_con, dir); + res = tracker_db_get_sub_watches (db_con, dir); - wd = -1; + wd = -1; - if (res) { - char **row; - int k; + if (!res) { + return; + } - k = 0; + for (k = 0; (row = tracker_db_get_row (res, k)) && row[0]; k++) { - while ((row = tracker_db_get_row (res, k))) { - k++; + wd = atoi (row[0]); - if (row && row[0]) { - wd = atoi (row[0]); - if (wd > -1) { - inotify_rm_watch (inotify_monitor_fd, wd); - inotify_count--; - } - } - } + if (wd < 0) { + continue; + } - tracker_db_free_result (res); + inotify_rm_watch (inotify_monitor_fd, wd); + inotify_count--; + } - tracker_db_delete_sub_watches (db_con, dir); + tracker_db_free_result (res); - } - } + tracker_db_delete_sub_watches (db_con, dir); }