1 /*****************************************************************************/
7 // This application and all source files used in its construction, except
8 // where noted, are licensed under the MIT License, and have been written
11 // Copyright (c) 2002 OpenBeOS Project
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 /*****************************************************************************/
33 #include "FolderWatcher.h"
38 #include <kernel/fs_attr.h>
41 #include <NodeMonitor.h>
44 // Implementation of FolderWatcher
46 FolderWatcher::FolderWatcher(BLooper
* looper
, const BDirectory
& folder
, bool watchAttrChanges
)
49 , fWatchAttrChanges(watchAttrChanges
)
51 // add this handler to the application for node monitoring
53 looper
->AddHandler(this);
57 // start attribute change watching for existing files
58 if (watchAttrChanges
) {
61 while (fFolder
.GetNextEntry(&entry
) == B_OK
&& entry
.GetNodeRef(&node
) == B_OK
) {
62 StartAttrWatching(&node
);
66 // start watching the spooler directory
68 fFolder
.GetNodeRef(&ref
);
69 watch_node(&ref
, B_WATCH_DIRECTORY
, this);
72 FolderWatcher::~FolderWatcher() {
73 // stop node watching for spooler directory
75 fFolder
.GetNodeRef(&ref
);
76 watch_node(&ref
, B_STOP_WATCHING
, this);
77 // stop sending notifications to this handler
81 BLooper
* looper
= Looper();
83 looper
->RemoveHandler(this);
88 void FolderWatcher::SetListener(FolderListener
* listener
) {
92 bool FolderWatcher::BuildEntryRef(BMessage
* msg
, const char* dirName
, entry_ref
* entry
) {
94 if (msg
->FindInt32("device", &entry
->device
) == B_OK
&&
95 msg
->FindInt64(dirName
, &entry
->directory
) == B_OK
&&
96 msg
->FindString("name", &name
) == B_OK
) {
97 entry
->set_name(name
);
103 bool FolderWatcher::BuildNodeRef(BMessage
* msg
, node_ref
* node
) {
104 return (msg
->FindInt32("device", &node
->device
) == B_OK
&&
105 msg
->FindInt64("node", &node
->node
) == B_OK
);
108 void FolderWatcher::HandleCreatedEntry(BMessage
* msg
, const char* dirName
) {
111 if (BuildEntryRef(msg
, dirName
, &entry
) &&
112 BuildNodeRef(msg
, &node
)) {
113 if (fWatchAttrChanges
) StartAttrWatching(&node
);
114 fListener
->EntryCreated(&node
, &entry
);
118 void FolderWatcher::HandleRemovedEntry(BMessage
* msg
) {
120 if (BuildNodeRef(msg
, &node
)) {
121 if (fWatchAttrChanges
) StopAttrWatching(&node
);
122 fListener
->EntryRemoved(&node
);
126 void FolderWatcher::HandleChangedAttr(BMessage
* msg
) {
128 if (BuildNodeRef(msg
, &node
)) {
129 fListener
->AttributeChanged(&node
);
133 void FolderWatcher::MessageReceived(BMessage
* msg
) {
138 if (msg
->what
== B_NODE_MONITOR
) {
139 if (fListener
== NULL
|| msg
->FindInt32("opcode", &opcode
) != B_OK
) return;
142 case B_ENTRY_CREATED
:
143 HandleCreatedEntry(msg
, "directory");
145 case B_ENTRY_REMOVED
:
146 HandleRemovedEntry(msg
);
149 fFolder
.GetNodeRef(&folder
);
150 if (msg
->FindInt64("to directory", &dir
) == B_OK
&& folder
.node
== dir
) {
151 // entry moved into this folder
152 HandleCreatedEntry(msg
, "to directory");
153 } else if (msg
->FindInt64("from directory", &dir
) == B_OK
&& folder
.node
== dir
) {
154 // entry removed from this folder
155 HandleRemovedEntry(msg
);
159 HandleChangedAttr(msg
);
161 default: // nothing to do
165 inherited::MessageReceived(msg
);
169 status_t
FolderWatcher::StartAttrWatching(node_ref
* node
) {
170 return watch_node(node
, B_WATCH_ATTR
, this);
173 status_t
FolderWatcher::StopAttrWatching(node_ref
* node
) {
174 return watch_node(node
, B_STOP_WATCHING
, this);