entangler 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +28 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/entangler.gemspec +26 -0
- data/exe/entangler +21 -0
- data/lib/entangler/entangled_file.rb +139 -0
- data/lib/entangler/executor/base.rb +242 -0
- data/lib/entangler/executor/master.rb +45 -0
- data/lib/entangler/executor/slave.rb +17 -0
- data/lib/entangler/version.rb +3 -0
- data/lib/entangler.rb +23 -0
- data/lib/notifier/bin/darwin/notify +0 -0
- data/lib/notifier/bin/linux/notify +0 -0
- data/lib/notifier/src/darwin/BUILD +7 -0
- data/lib/notifier/src/darwin/README +12 -0
- data/lib/notifier/src/darwin/notify.c +63 -0
- data/lib/notifier/src/linux/BUILD +4 -0
- data/lib/notifier/src/linux/README +18 -0
- data/lib/notifier/src/linux/notify.c +296 -0
- data/lib/notifier/src/linux/old/BUILD +11 -0
- data/lib/notifier/src/linux/old/README +14 -0
- data/lib/notifier/src/linux/old/kernel-filesystem-monitor-daemon-cat.cpp +165 -0
- data/lib/notifier/src/linux/old/kernel-filesystem-monitor-daemon.cpp +727 -0
- data/lib/notifier/src/linux/old/kernel-filesystem-monitor-daemon.hh +212 -0
- metadata +132 -0
data/lib/entangler.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'entangler/version'
|
2
|
+
require 'entangler/entangled_file'
|
3
|
+
|
4
|
+
module Entangler
|
5
|
+
class << self
|
6
|
+
attr_accessor :executor
|
7
|
+
|
8
|
+
def run(base_dir, opts = {})
|
9
|
+
opts = {mode: 'master'}.merge(opts)
|
10
|
+
|
11
|
+
require 'entangler/executor/base'
|
12
|
+
if opts[:mode] == 'master'
|
13
|
+
require 'entangler/executor/master'
|
14
|
+
self.executor = Entangler::Executor::Master.new(base_dir, opts)
|
15
|
+
elsif opts[:mode] == 'slave'
|
16
|
+
require 'entangler/executor/slave'
|
17
|
+
self.executor = Entangler::Executor::Slave.new(base_dir, opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
self.executor.run
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1,12 @@
|
|
1
|
+
The notify utility continiously prints changes in a specified directory in the following format:
|
2
|
+
|
3
|
+
M changed/path/1
|
4
|
+
M changed/path/2
|
5
|
+
-
|
6
|
+
|
7
|
+
|
8
|
+
Where M stands for "Modifed", and "-" is the indicator of end of changeset
|
9
|
+
|
10
|
+
Utility only returns specific directories that have changed, it does not print
|
11
|
+
the files/directories that have been modified: you need to determine them
|
12
|
+
yourself
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#include <CoreServices/CoreServices.h>
|
2
|
+
#include <CoreFoundation/CoreFoundation.h>
|
3
|
+
#include <sys/stat.h>
|
4
|
+
|
5
|
+
static void printChangesFunc(ConstFSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) {
|
6
|
+
char **paths = eventPaths;
|
7
|
+
int i;
|
8
|
+
for (i = 0; i < numEvents; i++) {
|
9
|
+
printf("M %s\n", paths[i]);
|
10
|
+
}
|
11
|
+
printf("-\n");
|
12
|
+
fflush(stdout);
|
13
|
+
}
|
14
|
+
|
15
|
+
void initFSEvents(const char *path) {
|
16
|
+
|
17
|
+
/* Define variables and create a CFArray object containing
|
18
|
+
CFString objects containing paths to watch.
|
19
|
+
*/
|
20
|
+
|
21
|
+
CFStringRef mypath = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
|
22
|
+
CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL);
|
23
|
+
void *callbackInfo = NULL; // could put stream-specific data here.
|
24
|
+
FSEventStreamRef stream;
|
25
|
+
CFAbsoluteTime latency = 0.1; /* Latency in seconds */
|
26
|
+
|
27
|
+
/* Create the stream, passing in a callback */
|
28
|
+
stream = FSEventStreamCreate(NULL,
|
29
|
+
&printChangesFunc,
|
30
|
+
callbackInfo,
|
31
|
+
pathsToWatch,
|
32
|
+
kFSEventStreamEventIdSinceNow, /* Or a previous event ID */
|
33
|
+
latency,
|
34
|
+
kFSEventStreamCreateFlagNone /* Flags explained in reference */
|
35
|
+
);
|
36
|
+
|
37
|
+
CFRelease(pathsToWatch);
|
38
|
+
CFRelease(mypath);
|
39
|
+
|
40
|
+
/* Create the stream before calling this. */
|
41
|
+
FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
42
|
+
FSEventStreamStart(stream);
|
43
|
+
}
|
44
|
+
|
45
|
+
int main (int argc, const char * argv[]) {
|
46
|
+
|
47
|
+
if(argc != 2) {
|
48
|
+
printf("Usage: %s <path>\n", argv[0]);
|
49
|
+
return 1;
|
50
|
+
}
|
51
|
+
|
52
|
+
struct stat tmp;
|
53
|
+
|
54
|
+
if(stat(argv[1], &tmp) != 0) {
|
55
|
+
perror("Invalid path");
|
56
|
+
return 2;
|
57
|
+
}
|
58
|
+
|
59
|
+
initFSEvents(argv[1]);
|
60
|
+
CFRunLoopRun();
|
61
|
+
|
62
|
+
return 0;
|
63
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
The notify utility continiously prints changes in a specified directory in the following format:
|
2
|
+
|
3
|
+
M changed/path/1
|
4
|
+
M changed/path/2
|
5
|
+
-
|
6
|
+
|
7
|
+
Where M stands for "Modifed", and "-" is the indicator of end of changeset
|
8
|
+
|
9
|
+
Utility only returns specific directories that have changed, it does not print
|
10
|
+
the files/directories that have been modified: you need to determine them
|
11
|
+
yourself.
|
12
|
+
|
13
|
+
Linux-specific notes:
|
14
|
+
|
15
|
+
1. You might need to adjust '/proc/sys/fs/inotify/max_user_watches' to allow more directories to be watched
|
16
|
+
2. If you have a lot of changes you might also want to increase queue size in /proc/sys/fs/inotify/max_queued_events
|
17
|
+
3. Watched queue can overflow and notify utility can run out of watched directories.
|
18
|
+
When you get exit code 3, you need to restart the daemon and re-process all directories you are interested in.
|
@@ -0,0 +1,296 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <stdlib.h>
|
3
|
+
#include <sys/types.h>
|
4
|
+
#include <sys/stat.h>
|
5
|
+
#include <sys/inotify.h>
|
6
|
+
#include <unistd.h>
|
7
|
+
#include <dirent.h>
|
8
|
+
#include <errno.h>
|
9
|
+
#include <stdlib.h>
|
10
|
+
#include <fcntl.h>
|
11
|
+
#include <sys/ioctl.h>
|
12
|
+
|
13
|
+
/* gcc should be able to optimize strlen() for constant strings */
|
14
|
+
#define PRINT(str) write(1, str, strlen(str))
|
15
|
+
#define ERROR(str) write(2, str, strlen(str))
|
16
|
+
|
17
|
+
#define EVENT_MASK (IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MODIFY|IN_MOVE_SELF\
|
18
|
+
|IN_MOVED_FROM|IN_MOVED_TO|IN_DONT_FOLLOW|IN_ONLYDIR|IN_ATTRIB)
|
19
|
+
|
20
|
+
#ifdef DEBUG
|
21
|
+
#define DEBUG_PRINT printf
|
22
|
+
#else
|
23
|
+
#define DEBUG_PRINT(...) /* printf actually adds about 7k to binary size :) */
|
24
|
+
#endif
|
25
|
+
|
26
|
+
typedef struct {
|
27
|
+
int wd;
|
28
|
+
int parent_wd;
|
29
|
+
char *name;
|
30
|
+
} _watchstruct;
|
31
|
+
|
32
|
+
char events_buf[PATH_MAX + sizeof(struct inotify_event) + 1];
|
33
|
+
static _watchstruct *watches;
|
34
|
+
int ifd = 0, max_watches;
|
35
|
+
char *watch_dir;
|
36
|
+
|
37
|
+
/* make directory path for watch descriptor (recursively) */
|
38
|
+
static void wd_path(int wd, char *path)
|
39
|
+
{
|
40
|
+
if (wd == 0) {
|
41
|
+
strcpy(path, watch_dir);
|
42
|
+
strcat(path, "/");
|
43
|
+
return;
|
44
|
+
}
|
45
|
+
|
46
|
+
if (wd < 0 || !watches[wd].name) {
|
47
|
+
DEBUG_PRINT("Recusive %d, %x\n", wd, watches[wd].name);
|
48
|
+
ERROR("Memory corrupted: asked path of deleted event\n");
|
49
|
+
exit(1);
|
50
|
+
}
|
51
|
+
|
52
|
+
wd_path(watches[wd].parent_wd, path);
|
53
|
+
if (watches[wd].name[0] == 0) return;
|
54
|
+
|
55
|
+
strcat(path, watches[wd].name);
|
56
|
+
strcat(path, "/");
|
57
|
+
}
|
58
|
+
|
59
|
+
static int add_dir_watch(int parent_wd, char *dir, char *dir_name, int no_print)
|
60
|
+
{
|
61
|
+
int wd = inotify_add_watch(ifd, dir, EVENT_MASK);
|
62
|
+
if (wd < 0) {
|
63
|
+
ERROR("Cannot add watch to '");
|
64
|
+
ERROR(dir);
|
65
|
+
ERROR("' using inotify: ");
|
66
|
+
if (errno == ENOSPC) {
|
67
|
+
ERROR("too many watches\nYou can increase number of user watches using /proc/sys/fs/inotify/max_user_watches");
|
68
|
+
} else {
|
69
|
+
ERROR(strerror(errno));
|
70
|
+
}
|
71
|
+
ERROR("\n");
|
72
|
+
if (errno != EACCES && errno != ENOENT) exit(1);
|
73
|
+
return wd;
|
74
|
+
}
|
75
|
+
|
76
|
+
if (wd >= max_watches) {
|
77
|
+
ERROR("\nToo many events; restart required to prevent watch descriptor overflow.\n");
|
78
|
+
exit(3);
|
79
|
+
}
|
80
|
+
|
81
|
+
dir_name = strdup(dir_name);
|
82
|
+
if (!dir_name) {
|
83
|
+
ERROR("Cannot strdup(dir_name)\n");
|
84
|
+
exit(1);
|
85
|
+
}
|
86
|
+
|
87
|
+
watches[wd].wd = wd;
|
88
|
+
watches[wd].parent_wd = parent_wd;
|
89
|
+
if (watches[wd].name) free(watches[wd].name);
|
90
|
+
watches[wd].name = dir_name;
|
91
|
+
|
92
|
+
if (!no_print) {
|
93
|
+
PRINT("M ");
|
94
|
+
PRINT(dir);
|
95
|
+
PRINT("\n");
|
96
|
+
}
|
97
|
+
|
98
|
+
return wd;
|
99
|
+
}
|
100
|
+
|
101
|
+
static void add_dir(int dir_wd, char *dir, int errors_fatal, int no_print)
|
102
|
+
{
|
103
|
+
char path[PATH_MAX + 1];
|
104
|
+
DIR *dh = opendir(dir);
|
105
|
+
struct dirent *ent;
|
106
|
+
struct stat st;
|
107
|
+
int dirl = strlen(dir), n = sizeof(path) - 1 - dirl, had_errors = 0, wd;
|
108
|
+
|
109
|
+
if (dirl > sizeof(path) - 3) {
|
110
|
+
ERROR("Too long path (not watched): ");
|
111
|
+
ERROR(dir);
|
112
|
+
ERROR("\n");
|
113
|
+
|
114
|
+
if (errors_fatal) exit(1);
|
115
|
+
return;
|
116
|
+
}
|
117
|
+
|
118
|
+
if (!dh) {
|
119
|
+
ERROR("Cannot opendir(");
|
120
|
+
ERROR(dir);
|
121
|
+
ERROR("): ");
|
122
|
+
ERROR(strerror(errno));
|
123
|
+
ERROR("\n");
|
124
|
+
|
125
|
+
if (errors_fatal) exit(1);
|
126
|
+
return;
|
127
|
+
}
|
128
|
+
|
129
|
+
strcpy(path, dir);
|
130
|
+
|
131
|
+
while ((ent = readdir(dh)) != NULL) {
|
132
|
+
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..") || !strcmp(ent->d_name, ".unrealsync")) continue;
|
133
|
+
|
134
|
+
path[dirl] = '/';
|
135
|
+
path[dirl + 1] = 0;
|
136
|
+
strncat(path + dirl, ent->d_name, n);
|
137
|
+
path[sizeof(path) - 1] = 0;
|
138
|
+
if (lstat(path, &st)) {
|
139
|
+
ERROR("Cannot lstat(");
|
140
|
+
ERROR(path);
|
141
|
+
ERROR("): ");
|
142
|
+
ERROR(strerror(errno));
|
143
|
+
ERROR("\n");
|
144
|
+
had_errors = 1;
|
145
|
+
continue;
|
146
|
+
}
|
147
|
+
|
148
|
+
if (S_ISDIR(st.st_mode)) {
|
149
|
+
wd = add_dir_watch(dir_wd, path, ent->d_name, no_print);
|
150
|
+
if (wd < 0) continue;
|
151
|
+
add_dir(wd, path, errors_fatal, no_print);
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
closedir(dh);
|
156
|
+
|
157
|
+
if (errors_fatal && had_errors) exit(1);
|
158
|
+
}
|
159
|
+
|
160
|
+
void debug_print_mask(uint32_t mask)
|
161
|
+
{
|
162
|
+
if (mask & IN_DELETE_SELF) DEBUG_PRINT("IN_DELETE_SELF ");
|
163
|
+
if (mask & IN_MOVE_SELF) DEBUG_PRINT("IN_MOVE_SELF ");
|
164
|
+
if (mask & IN_MOVED_FROM) DEBUG_PRINT("IN_MOVED_FROM ");
|
165
|
+
if (mask & IN_MOVED_TO) DEBUG_PRINT("IN_MOVED_TO ");
|
166
|
+
if (mask & IN_CLOSE_WRITE) DEBUG_PRINT("IN_CLOSE_WRITE ");
|
167
|
+
if (mask & IN_MODIFY) DEBUG_PRINT("IN_MODIFY ");
|
168
|
+
if (mask & IN_IGNORED) DEBUG_PRINT("IN_IGNORED ");
|
169
|
+
if (mask & IN_ISDIR) DEBUG_PRINT("IN_ISDIR ");
|
170
|
+
if (mask & IN_Q_OVERFLOW) DEBUG_PRINT("IN_Q_OVERFLOW ");
|
171
|
+
if (mask & IN_UNMOUNT) DEBUG_PRINT("IN_UNMOUNT ");
|
172
|
+
if (mask & IN_CREATE) DEBUG_PRINT("IN_CREATE ");
|
173
|
+
}
|
174
|
+
|
175
|
+
static int do_watch(int max_watches)
|
176
|
+
{
|
177
|
+
struct inotify_event *ev = (struct inotify_event*)events_buf;
|
178
|
+
ssize_t n = 0, wd;
|
179
|
+
char path[PATH_MAX + 1];
|
180
|
+
|
181
|
+
watches = (_watchstruct*) calloc(max_watches, sizeof(_watchstruct));
|
182
|
+
if (!watches) {
|
183
|
+
ERROR("Cannot allocate memory\n");
|
184
|
+
exit(1);
|
185
|
+
}
|
186
|
+
|
187
|
+
DEBUG_PRINT("Doing initial watches setup\n");
|
188
|
+
|
189
|
+
ifd = inotify_init();
|
190
|
+
if (ifd == -1) {
|
191
|
+
perror("Cannot init inotify");
|
192
|
+
exit(1);
|
193
|
+
}
|
194
|
+
|
195
|
+
wd = add_dir_watch(0, watch_dir, "", 1);
|
196
|
+
if (wd < 0) {
|
197
|
+
ERROR("Cannot add dir watch\n");
|
198
|
+
exit(1);
|
199
|
+
}
|
200
|
+
add_dir(wd, watch_dir, 1, 1);
|
201
|
+
|
202
|
+
while ((n = read(ifd, events_buf, sizeof(events_buf))) > 0) {
|
203
|
+
ev = (struct inotify_event*)events_buf;
|
204
|
+
while (n > 0) {
|
205
|
+
if (ev->mask & IN_Q_OVERFLOW) {
|
206
|
+
ERROR("Queue overflow, restart needed\n");
|
207
|
+
exit(3);
|
208
|
+
}
|
209
|
+
|
210
|
+
if (ev->mask & IN_IGNORED) {
|
211
|
+
free(watches[ev->wd].name);
|
212
|
+
watches[ev->wd].parent_wd = -1;
|
213
|
+
watches[ev->wd].name = NULL;
|
214
|
+
goto loop_end;
|
215
|
+
}
|
216
|
+
|
217
|
+
wd_path(ev->wd, path);
|
218
|
+
PRINT("M ");
|
219
|
+
PRINT(path);
|
220
|
+
PRINT("\n");
|
221
|
+
#ifdef DEBUG
|
222
|
+
if (ev->len) {
|
223
|
+
DEBUG_PRINT(" | ");
|
224
|
+
DEBUG_PRINT("%s", ev->name);
|
225
|
+
}
|
226
|
+
DEBUG_PRINT(" | ");
|
227
|
+
debug_print_mask(ev->mask);
|
228
|
+
#endif
|
229
|
+
|
230
|
+
if ((ev->mask & IN_DELETE) || (ev->mask & IN_MOVED_FROM)) {
|
231
|
+
goto loop_end;
|
232
|
+
}
|
233
|
+
|
234
|
+
if (ev->mask & IN_ISDIR) {
|
235
|
+
if (ev->len + strlen(path) > sizeof(path) - 1) {
|
236
|
+
ERROR("Too deep directory: ");
|
237
|
+
ERROR(path);
|
238
|
+
ERROR(ev->name);
|
239
|
+
ERROR("\n");
|
240
|
+
goto loop_end;
|
241
|
+
}
|
242
|
+
strcat(path, ev->name);
|
243
|
+
wd = add_dir_watch(ev->wd, path, ev->name, 0);
|
244
|
+
if (wd < 0) goto loop_end;
|
245
|
+
add_dir(ev->wd, path, 0, 0);
|
246
|
+
}
|
247
|
+
|
248
|
+
loop_end:
|
249
|
+
n -= sizeof(struct inotify_event) + ev->len;
|
250
|
+
ev = (struct inotify_event*) ((char*)ev + sizeof(struct inotify_event) + ev->len);
|
251
|
+
}
|
252
|
+
|
253
|
+
PRINT("-\n");
|
254
|
+
}
|
255
|
+
|
256
|
+
perror("Cannot read() inotify queue");
|
257
|
+
exit(1);
|
258
|
+
}
|
259
|
+
|
260
|
+
int main(int argc, char *argv[])
|
261
|
+
{
|
262
|
+
int fd, n;
|
263
|
+
char buf[12];
|
264
|
+
|
265
|
+
if (argc != 2) {
|
266
|
+
ERROR("Usage: notify <dir>\n");
|
267
|
+
return 1;
|
268
|
+
}
|
269
|
+
|
270
|
+
fd = open("/proc/sys/fs/inotify/max_user_watches", O_RDONLY);
|
271
|
+
if (fd < 0) {
|
272
|
+
perror("Cannot open /proc/sys/fs/inotify/max_user_watches");
|
273
|
+
return 1;
|
274
|
+
}
|
275
|
+
|
276
|
+
if ( (n = read(fd, buf, sizeof(buf) - 1)) < 0) {
|
277
|
+
perror("Cannot read() /proc/sys/fs/inotify/max_user_watches");
|
278
|
+
return 1;
|
279
|
+
}
|
280
|
+
|
281
|
+
buf[n] = 0;
|
282
|
+
max_watches = atoi(buf) * 2;
|
283
|
+
if (max_watches <= 0) {
|
284
|
+
ERROR("Incorrect number of watches: ");
|
285
|
+
ERROR(buf);
|
286
|
+
ERROR("\n");
|
287
|
+
return 1;
|
288
|
+
} else {
|
289
|
+
DEBUG_PRINT("Max watches: %d\n", max_watches);
|
290
|
+
}
|
291
|
+
|
292
|
+
watch_dir = argv[1];
|
293
|
+
do_watch(max_watches);
|
294
|
+
|
295
|
+
return 0;
|
296
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
The utility has been built using the following command under Ubuntu Linux 11.10 32-bit:
|
2
|
+
|
3
|
+
g++ -static -s -I. *.cpp /usr/lib/libpopt.a -o notify
|
4
|
+
|
5
|
+
Or, to achieve the minimal size of the binary:
|
6
|
+
|
7
|
+
g++ -static -s -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -I. *.cpp /usr/lib/libpopt.a -o notify
|
8
|
+
|
9
|
+
You might need to change path to libpopt to whatever location it is on your system.
|
10
|
+
Libpopt is the only dependency aside from g++ if you want to build the utility.
|
11
|
+
It comes pre-built statically with realsync, so it will most probably just work
|
@@ -0,0 +1,14 @@
|
|
1
|
+
This is a daemon that notifies about filesystem changes in the following form:
|
2
|
+
|
3
|
+
M /path/to/changed/file
|
4
|
+
M /path/to/other/changed/file
|
5
|
+
-
|
6
|
+
|
7
|
+
The daemon is based on kfsmd-0.3.3 and tuned a little bit to be more realtime
|
8
|
+
The original kfsmd-0.3.3 could be found at http://sourceforge.net/projects/witme/files/kfsmd/
|
9
|
+
The preferred way to use this daemon is to run the following:
|
10
|
+
|
11
|
+
./notify watch /path/to/watch | uniq
|
12
|
+
|
13
|
+
You can get rid of "| uniq", but in this case you will get multiple lines per each file
|
14
|
+
for each type of event (e.g. OPEN/WRITE/CLOSE)
|
@@ -0,0 +1,165 @@
|
|
1
|
+
/******************************************************************************
|
2
|
+
*******************************************************************************
|
3
|
+
*******************************************************************************
|
4
|
+
|
5
|
+
|
6
|
+
kernel-filesystem-monitor-daemon-cat
|
7
|
+
Copyright (C) 2005 Ben Martin
|
8
|
+
|
9
|
+
This program is free software; you can redistribute it and/or modify
|
10
|
+
it under the terms of the GNU General Public License as published by
|
11
|
+
the Free Software Foundation; either version 2 of the License, or
|
12
|
+
(at your option) any later version.
|
13
|
+
|
14
|
+
This program is distributed in the hope that it will be useful,
|
15
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
GNU General Public License for more details.
|
18
|
+
|
19
|
+
You should have received a copy of the GNU General Public License
|
20
|
+
along with this program; if not, write to the Free Software
|
21
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
22
|
+
|
23
|
+
For more details see the COPYING file in the root directory of this
|
24
|
+
distribution.
|
25
|
+
|
26
|
+
$Id: kernel-filesystem-monitor-daemon-cat.cpp,v 1.3 2008/05/25 21:30:52 ben Exp $
|
27
|
+
|
28
|
+
*******************************************************************************
|
29
|
+
*******************************************************************************
|
30
|
+
******************************************************************************/
|
31
|
+
|
32
|
+
#include <iostream>
|
33
|
+
#include "kernel-filesystem-monitor-daemon.hh"
|
34
|
+
#include <stdlib.h>
|
35
|
+
|
36
|
+
using namespace std;
|
37
|
+
|
38
|
+
|
39
|
+
const char* PROGRAM_NAME = "kernel-filesystem-monitor-cat";
|
40
|
+
|
41
|
+
void usage(poptContext optCon, int exitcode, char *error, char *addl)
|
42
|
+
{
|
43
|
+
poptPrintUsage(optCon, stderr, 0);
|
44
|
+
if (error) fprintf(stderr, "%s: %s0", error, addl);
|
45
|
+
exit(exitcode);
|
46
|
+
}
|
47
|
+
|
48
|
+
/********************************************************************************/
|
49
|
+
/********************************************************************************/
|
50
|
+
/********************************************************************************/
|
51
|
+
/********************************************************************************/
|
52
|
+
/********************************************************************************/
|
53
|
+
/********************************************************************************/
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
class KernelFileSystemMonitorDaemonCat
|
58
|
+
:
|
59
|
+
public KernelFileSystemMonitorDaemon
|
60
|
+
{
|
61
|
+
protected:
|
62
|
+
|
63
|
+
virtual void handle_event( struct inotify_event *pevent, time_t tt );
|
64
|
+
virtual void Closedown();
|
65
|
+
virtual void setupWorkingDirToPersistentDirIDMapping( long wd, const string& earl );
|
66
|
+
|
67
|
+
void
|
68
|
+
event_batch_start( time_t tt )
|
69
|
+
{}
|
70
|
+
|
71
|
+
void
|
72
|
+
event_batch_end( time_t tt )
|
73
|
+
{}
|
74
|
+
|
75
|
+
|
76
|
+
public:
|
77
|
+
|
78
|
+
string homedir;
|
79
|
+
|
80
|
+
KernelFileSystemMonitorDaemonCat()
|
81
|
+
{}
|
82
|
+
};
|
83
|
+
|
84
|
+
|
85
|
+
void
|
86
|
+
KernelFileSystemMonitorDaemonCat::setupWorkingDirToPersistentDirIDMapping(
|
87
|
+
long wd, const string& earl )
|
88
|
+
{
|
89
|
+
}
|
90
|
+
|
91
|
+
void
|
92
|
+
KernelFileSystemMonitorDaemonCat::handle_event( struct inotify_event *pevent, time_t tt )
|
93
|
+
{
|
94
|
+
print_event( pevent );
|
95
|
+
fflush(stdout);
|
96
|
+
}
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
void
|
101
|
+
KernelFileSystemMonitorDaemonCat::Closedown()
|
102
|
+
{
|
103
|
+
}
|
104
|
+
|
105
|
+
int main( int argc, char** argv )
|
106
|
+
{
|
107
|
+
unsigned long RunInForground = 0;
|
108
|
+
const char* homedir_CSTR = 0;
|
109
|
+
|
110
|
+
KernelFileSystemMonitorDaemonCat* daemon
|
111
|
+
= new KernelFileSystemMonitorDaemonCat();
|
112
|
+
|
113
|
+
struct poptOption optionsTable[] =
|
114
|
+
{
|
115
|
+
{ "forground", 'F', POPT_ARG_NONE, &RunInForground, 0,
|
116
|
+
"Don't run the daemon in the background", "" },
|
117
|
+
|
118
|
+
{ "homedir", 'H', POPT_ARG_STRING, &homedir_CSTR, 0,
|
119
|
+
"Home directory for user doing the monitoring", "" },
|
120
|
+
|
121
|
+
{ 0, 0, POPT_ARG_INCLUDE_TABLE, daemon->getPopTable(), \
|
122
|
+
0, "generic kfsmd daemon options:", 0 },
|
123
|
+
|
124
|
+
{ "verbose", 'v', POPT_ARG_NONE, &Verbose, 0,
|
125
|
+
"output more info", "" },
|
126
|
+
|
127
|
+
|
128
|
+
POPT_AUTOHELP
|
129
|
+
POPT_TABLEEND
|
130
|
+
};
|
131
|
+
poptContext optCon;
|
132
|
+
|
133
|
+
optCon = poptGetContext(PROGRAM_NAME, argc, (const char**)argv, optionsTable, 0);
|
134
|
+
poptSetOtherOptionHelp(optCon, "[OPTIONS]* [IGNOREPFX URL]* [WATCH URL]+ ...");
|
135
|
+
|
136
|
+
|
137
|
+
/* Now do options processing */
|
138
|
+
char c=-1;
|
139
|
+
while ((c = poptGetNextOpt(optCon)) >= 0)
|
140
|
+
{
|
141
|
+
}
|
142
|
+
|
143
|
+
daemon->ParseWatchOptions( optCon );
|
144
|
+
daemon->setRunInForground( true );
|
145
|
+
daemon->setupSignalHandlers();
|
146
|
+
|
147
|
+
daemon->homedir = getHomeDir( homedir_CSTR );
|
148
|
+
|
149
|
+
try
|
150
|
+
{
|
151
|
+
if( Verbose )
|
152
|
+
cerr << "setting up watches" << endl;
|
153
|
+
daemon->setupWatches();
|
154
|
+
if( Verbose )
|
155
|
+
cerr << "calling run" << endl;
|
156
|
+
return daemon->run();
|
157
|
+
}
|
158
|
+
catch( exception& e )
|
159
|
+
{
|
160
|
+
cerr << "Exiting due to error reason:" << e.what() << endl;
|
161
|
+
}
|
162
|
+
|
163
|
+
return 0;
|
164
|
+
}
|
165
|
+
|