private void OnInotify (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem == null) return; // Unsubscribe to directories that have been removed if ((type & Inotify.EventType.Delete) != 0 && (type & Inotify.EventType.IsDirectory) != 0) watch.Unsubscribe (); lock (queue.SyncRoot) { bool found = false; for (int i = 0; i < queue.Count; i++) { Event ev = (Event) queue.Dequeue (); if (ev.Path == path && ev.Subitem == subitem && ev.Srcpath == srcpath) { found = true; ev.Type = (ev.Type | type); queue.Enqueue (ev); break; } queue.Enqueue (ev); } if (!found) { queue.Enqueue (new Event (watch, path, subitem, srcpath, type, -1, Thunderbird.GetFileSize (Path.Combine (path, subitem)))); } } }
public void Unsubscribe() { if (!this.is_subscribed) { return; } Inotify.Unsubscribe(watchinfo, this); this.is_subscribed = false; }
public Event (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type, long old_size, long current_size) { this.Watch = watch; this.Path = path; this.Subitem = subitem; this.Srcpath = srcpath; this.Type = type; this.OldFileSize = old_size; this.CurrentFileSize = current_size; }
///////////////////////////////////////////////////////////////////////////////// #if INOTIFY_TEST private static void Main(string [] args) { Queue to_watch = new Queue(); bool recursive = false; foreach (string arg in args) { if (arg == "-r" || arg == "--recursive") { recursive = true; } else { // Our hashes work without a trailing path delimiter string path = arg.TrimEnd('/'); to_watch.Enqueue(path); } } while (to_watch.Count > 0) { string path = (string)to_watch.Dequeue(); Console.WriteLine("Watching {0}", path); Inotify.Subscribe(path, null, Inotify.EventType.All); if (recursive) { foreach (string subdir in DirectoryWalker.GetDirectories(path)) { to_watch.Enqueue(subdir); } } } Inotify.Start(); Inotify.Verbose = true; while (Inotify.Enabled && Inotify.WatchCount > 0) { Thread.Sleep(1000); } if (Inotify.WatchCount == 0) { Console.WriteLine("Nothing being watched."); } // Kill the event-reading thread so that we exit Inotify.Stop(); }
private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem == "") return; string full_path = Path.Combine (path, subitem); if ((type & Inotify.EventType.Create) != 0 && (type & Inotify.EventType.IsDirectory) != 0) { Watch (full_path); return; } if ((type & Inotify.EventType.Delete) != 0 && (type & Inotify.EventType.IsDirectory) != 0) { watch.Unsubscribe (); return; } if ((type & Inotify.EventType.MovedTo) != 0) { if (subitem == "summary") { // IMAP summary if (SummaryAddedEvent != null && File.Exists (full_path)) { Logger.Log.Info ("Reindexing updated IMAP summary: {0}", full_path); SummaryAddedEvent (new FileInfo (full_path), true); } } else if (Path.GetExtension (full_path) == ".ev-summary") { // mbox summary string mbox_file = Path.ChangeExtension (full_path, null); if (MboxAddedEvent != null && File.Exists (mbox_file)) { Logger.Log.Info ("Reindexing updated mbox: {0}", mbox_file); MboxAddedEvent (new FileInfo (mbox_file), true); } } } }
private void OnInotifyEvent ( Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { // Stop watching if we are deleted. We should unsubscribe to the Inotify watcher // here to, but that gives an exception. Why? if ((type & Inotify.EventType.DeleteSelf) != 0) { CancelIndexable (); return; } // We need to have a filename if (subitem == null) return; // If the running indexable generator has more items, we don't have to care here. // Otherwise launch a new indexable generator. if (indexable_generator != null && !indexable_generator.Done) return; LaunchIndexable (); }
public void Watch (string path, Inotify.EventType type) { Inotify.Subscribe (path, OnInotify, type); }
private void OnInotify (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType event_type) { if ((event_type & Inotify.EventType.MovedTo) != 0 && subitem == "dcache4.url") { IndexDirectory (path); return; } }
private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { bool is_directory; is_directory = (type & Inotify.EventType.IsDirectory) != 0; queryable.ReportEventInDirectory (path); // The case of matched move events if ((type & Inotify.EventType.MovedTo) != 0 && srcpath != null) { queryable.HandleMoveEvent (Path.GetDirectoryName (srcpath), Path.GetFileName (srcpath), path, subitem, is_directory); return; } // Then this must be an unmatched moveto // An unmatched MovedTo is like a create if ((type & Inotify.EventType.MovedTo) != 0) { // Synthesize the appropriate Create event. Note that we could check for the // IsDirectory event here, but this also shrinks the race window. if (is_directory) type |= Inotify.EventType.Create; else type |= Inotify.EventType.CloseWrite; Logger.Log.Debug ("Synthesizing event on unpaired MoveTo", type); } // An unmatched MovedFrom is like a delete if ((type & Inotify.EventType.MovedFrom) != 0) { type |= Inotify.EventType.Delete; Logger.Log.Debug ("Synthesizing event on unpaired MoveFrom", type); } if ((type & Inotify.EventType.Delete) != 0) { queryable.HandleRemoveEvent (path, subitem, is_directory); return; } if ((type & Inotify.EventType.Create) != 0) { if (is_directory) queryable.HandleAddEvent (path, subitem, is_directory); return; } if ((type & Inotify.EventType.CloseWrite) != 0) { queryable.HandleAddEvent (path, subitem, is_directory); return; } if ((type & Inotify.EventType.Attrib) != 0) { queryable.HandleAttribEvent (path, subitem, is_directory); return; } if ((type & Inotify.EventType.QueueOverflow) != 0) { Logger.Log.Warn ("Inotify queue overflowed: file system is in an unknown state"); queryable.HandleOverflowEvent (); return; } }
///////////////////////////////////////////////// // Modified/Created event using Inotify private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem == "") return; // Watch konq_cache_dir for new directory creation // Watch its subdirectories for new file creation // If any file in created in konq_cache_dir, ignore it // Its a Konq error otherwise if ((type & Inotify.EventType.IsDirectory) == 0) IndexSingleFile (Path.Combine (path, subitem)); else if ((type & Inotify.EventType.IsDirectory) != 0) Inotify.Subscribe (konq_cache_dir, OnInotifyEvent, Inotify.EventType.CloseWrite); }
///////////////////////////////////////////// private void OnInotifyEvent (int wd, string path, string subitem, string srcpath, Inotify.EventType type) { if (wd != monodoc_wd) return; if (subitem == "") return; if (Path.GetExtension (subitem) != ".zip") return; string full_path = Path.Combine (path, subitem); switch (type) { case Inotify.EventType.CloseWrite: case Inotify.EventType.CreateFile: IndexArchive (new FileInfo (full_path), Scheduler.Priority.Delayed); break; } }
///////////////////////////////////////////////// // Modified/Created event using Inotify private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem == "" || !subitem.EndsWith (".xml")) return; if ((type & Inotify.EventType.CloseWrite) != 0) IndexSingleFeed (Path.Combine (path, subitem), false); else if ((type & Inotify.EventType.Delete) != 0) RemoveFeedFile (Path.Combine (path, subitem)); }
private void OnInotify (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { long offset = 0; path = Path.Combine (path, subitem); if (ThisScheduler.ContainsByTag (path)) { Log.Debug ("Not adding task for already running task: {0}", path); return; } lock (initial_log_files) { if (initial_log_files.Contains (path)) { Log.Debug ("{0} is already scheduled for initial indexing", path); return; } } if (session_offset_table.ContainsKey (path)) offset = session_offset_table [path]; SessionIndexableGenerator generator = new SessionIndexableGenerator (this, path, offset); Scheduler.Task task = NewAddTask (generator); task.Tag = path; task.Source = this; ThisScheduler.Add (task); }
///////////////////////////////////////////////// // Modified/Created event using Inotify private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { // someone reported that backup files with abcd~ // were being generated if (subitem == "" || subitem.EndsWith ("~")) return; if ((type & Inotify.EventType.CloseWrite) != 0) IndexSingleFeed (Path.Combine (path, subitem)); else if ((type & Inotify.EventType.Delete) != 0) Removefeed_file (Path.Combine (path, subitem)); }
private void OnInotifyNewConversation (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem.Length == 0 || (type & Inotify.EventType.IsDirectory) != 0) return; if (FileIsInteresting (subitem)) IndexLog (Path.Combine (path, subitem), Scheduler.Priority.Immediate); }
private void OnInotifyNewRemote (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem.Length == 0 || (type & Inotify.EventType.IsDirectory) == 0) return; CrawlRemoteDirectory (Path.Combine (path, subitem), true); }
private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem == null) return; string full_path = Path.Combine (path, subitem); // If prefs.js is deleted... then we have nothing at all to index if (((type & Inotify.EventType.MovedTo) != 0 && srcpath == Path.Combine (path, "prefs.js")) || ((type & Inotify.EventType.Delete) != 0 && subitem == "prefs.js")) { foreach (TB.Account account in account_list) RemoveAccount (account); return; } // Update in case an account was removed or added // Thunderbird saves prefs.js with a different name and then replacing the old one // by "moving" it over the existing prefs.js. That's why MoveTo is used as inotfy type. if ((((type & Inotify.EventType.Modify) != 0 || (type & Inotify.EventType.MovedTo) != 0 || (type & Inotify.EventType.Create) != 0) && subitem == "prefs.js")) { UpdateAccounts (path); return; } // In case the address book file have been moved or deleted, we have to stop indexing it if (((type & Inotify.EventType.MovedTo) != 0 && srcpath == Path.Combine (path, "abook.mab")) || ((type & Inotify.EventType.Delete) != 0 && subitem == "abook.mab")) { TB.Account account = GetParentAccount (full_path); if (account != null) RemoveAccount (account); return; } // In case of a newly created addressbook, the current address book is modified or an old // address book is moved to where the address book can be found: either start indexing // or restart an already indexing IndeaxbleGenerator. if ((((type & Inotify.EventType.Modify) != 0 || (type & Inotify.EventType.MovedTo) != 0 || (type & Inotify.EventType.Create) != 0) && subitem == "abook.mab")) { TB.Account account = GetParentAccount (full_path); if (account == null && File.Exists (full_path)) { UpdateAccounts (path); return; } else if (account == null) return; // Tell any running indexable about this or start a new one if (queryable.ThisScheduler.ContainsByTag (full_path)) OnNotification (new NotificationEventArgs (NotificationType.RestartIndexing, account)); else IndexFile (full_path); return; } // Re-index files when needed if ((type & Inotify.EventType.Modify) != 0) { TB.Account account = GetParentAccount (full_path); if (account == null || !Thunderbird.IsMorkFile (path, subitem)) return; // In case we have a running IndexableGenerator, tell it that we have a file that needs to // be re-indexed. if (queryable.ThisScheduler.ContainsByTag (full_path)) OnNotification (new NotificationEventArgs (NotificationType.RestartIndexing, account)); else IndexFile (full_path); return; } // Index newly created directories if ((type & Inotify.EventType.Create) != 0 && (type & Inotify.EventType.IsDirectory) != 0) { if (GetParentAccount (full_path) != null && Inotify.Enabled) Inotify.Subscribe (full_path, OnInotifyEvent, Inotify.EventType.All); return; } }
///////////////////////////////////////////////// // Modified event using Inotify private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem != blam_file.Name) return; Index (); }
///////////////////////////////////////////////// // Modified/Created/Deleted event using Inotify private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem == "") return; if (Path.GetExtension (subitem) != ".note") return; if ((type & Inotify.EventType.MovedTo) != 0) { IndexNote (new FileInfo (Path.Combine (path, subitem)), Scheduler.Priority.Immediate); } if ((type & Inotify.EventType.MovedFrom) != 0 || ((type & Inotify.EventType.Delete) != 0 && (type & Inotify.EventType.IsDirectory) == 0)) RemoveNote (subitem); }
private void OnInotifyEvent ( Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { // Stop watching if we were deleted if ((type & Inotify.EventType.DeleteSelf) != 0) { watch.Unsubscribe (); return; } // We want a directory if ((type & Inotify.EventType.IsDirectory) == 0) return; // We are only watching one directory, so we only have to check for ToIndex // as subitem if (subitem != "ToIndex") return; // We only have to watch for creation of the ToIndex directory here, so that // the indexing process can be started. The Indexer will automatically clean // up if the ToIndex diretory is deleted (we still display a status message // here though) if ((type & Inotify.EventType.Create) != 0) ExceptionHandlingThread.Start (new ThreadStart (StartWorker)); else if ((type & Inotify.EventType.Delete) != 0) Logger.Log.Debug ("Stopping the Thunderbird indexing process; ToIndex disappeared"); }
private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem == "") return; string fullPath = Path.Combine (path, subitem); if ((type & Inotify.EventType.Create) != 0 && (type & Inotify.EventType.IsDirectory) != 0) { CrawlLaunchers (fullPath); return; } if ((type & Inotify.EventType.Modify) != 0) { IndexLauncher (new FileInfo (fullPath), Scheduler.Priority.Immediate); return; } }
private static void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem == "" || watching_for_updates == false) return; Reload (); }
/** * inotify callback */ private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem == "") return; string fullPath = Path.Combine (path, subitem); // we need to watch for all kinds of events - this is tricky // Case: new file is created // - if it is one of the folder_directories, index it // - if is in one of the mail_directories, index it if it is an mbox file if ((type & Inotify.EventType.Create) != 0 && (type & Inotify.EventType.IsDirectory) == 0) { if (IsMailDir (path)) { Indexable indexable = MaildirMessageToIndexable (fullPath, false); AddIndexableTask (indexable, fullPath); } else { // add mbox file to mbox_files string mbox = GetMboxFile (path, subitem); if (mbox != null) { mbox_files.Add (mbox); IndexMbox (mbox, true); } } return; } // Case: file is deleted // - if it is a mail file, we might like it to be deleted if ((type & Inotify.EventType.MovedFrom) != 0 || ((type & Inotify.EventType.Delete) != 0 && (type & Inotify.EventType.IsDirectory) == 0)) { if (IsMailDir (path)) RemoveMail (fullPath); else if (mbox_files.Contains (fullPath)) { RemoveMbox (fullPath); mbox_files.Remove (fullPath); } return; } // Case: file is moved // - files are moved from tmp/new to cur // - need to delete from the source if ((type & Inotify.EventType.MovedTo) != 0 && (type & Inotify.EventType.IsDirectory) == 0) { if (IsMailDir (path)) { Indexable indexable = MaildirMessageToIndexable (fullPath, false); AddIndexableTask (indexable, fullPath); } if (IsMailDir (srcpath)) RemoveMail (srcpath); if (mbox_files.Contains (fullPath)) { // check if this because of compaction, in which case need to delete previous mbox if (srcpath != null && srcpath.EndsWith ("." + subitem + ".compacted")) RemoveMbox (fullPath); // FIXME need to ensure IndexMbox is scheduled *after* RemoveMbox finishes // RemoveMbox creates a job with immediate priority while // IndexMbox creates a job with the default priority of a generator // Is there a better way to ensure the order ? IndexMbox (fullPath, true); } return; } // Case: file is modified i.e. there was no create event but closewrite event // - possibly some mbox was changed // FIXME kmail doesnt physically delete the deleted mails from mbox files unless compacted // - which means one has to read the .index files to find deleted messages... // - need to find the format of the .index/.index.ids etc files and parse them if ((type & Inotify.EventType.Modify) != 0 && (type & Inotify.EventType.IsDirectory) == 0) { if (mbox_files.Contains (fullPath)) IndexMbox (fullPath, false); return; } // Case: a directory is created: // well watch it anyway but also make sure its a maildir directory // if it a maildir directory, then add it to maildir_dirs if ((type & Inotify.EventType.Create) != 0 && (type & Inotify.EventType.IsDirectory) != 0) { if (!IgnoreFolder (fullPath)) { Watch (fullPath); UpdateDirectories(fullPath); } return; } // Case: if a directory is deleted: // remove watch if ((type & Inotify.EventType.Delete) != 0 && (type & Inotify.EventType.IsDirectory) != 0) { watch.Unsubscribe (); mail_directories.Remove (fullPath); folder_directories.Remove (fullPath); return; } // Case: directory is moved // FIXME: implement renaming of mail folders }
///////////////////////////////////////////////// // Modified event using Inotify private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (Path.Combine (path, subitem) != knotes_file) return; Index (); }
///////////////////////////////////////////////// private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem == "") return; if (Path.GetExtension (subitem) != ".xml") return; // We're only handling MovedTo events here. string file = Path.Combine (path, subitem); DateTime last_checked = DateTime.MinValue; FileAttributes attr; attr = FileAttributesStore.Read (file); if (attr != null) last_checked = attr.LastWriteTime; foreach (NautilusTools.NautilusMetadata nm in NautilusTools.GetMetadata (file, last_checked)) { Indexable indexable = GetIndexable (nm); Scheduler.Task task; task = this.target_queryable.NewAddTask (indexable); task.Priority = Scheduler.Priority.Immediate; ThisScheduler.Add (task); } }
private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem, string srcpath, Inotify.EventType type) { if (subitem == "") return; if (subitem[0] == '.') { string data_file = Path.Combine (path, subitem.Substring (1)); lock (pending_files) { if (File.Exists (data_file) && ! pending_files.Contains (data_file)) { pending_files.Add (data_file); IndexFile (new FileInfo (data_file)); } } } else { string meta_file = Path.Combine (path, "." + subitem); string data_file = Path.Combine (path, subitem); lock (pending_files) { if (File.Exists (meta_file) && ! pending_files.Contains (data_file)) { pending_files.Add (data_file); IndexFile (new FileInfo (data_file)); } } } }