1 | /*
|
---|
2 | Unix SMB/CIFS implementation.
|
---|
3 |
|
---|
4 | Copyright (C) Andrew Tridgell 2006
|
---|
5 |
|
---|
6 | This program is free software; you can redistribute it and/or modify
|
---|
7 | it under the terms of the GNU General Public License as published by
|
---|
8 | the Free Software Foundation; either version 3 of the License, or
|
---|
9 | (at your option) any later version.
|
---|
10 |
|
---|
11 | This program is distributed in the hope that it will be useful,
|
---|
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | GNU General Public License for more details.
|
---|
15 |
|
---|
16 | You should have received a copy of the GNU General Public License
|
---|
17 | along with this program. If not, see <http://www.gnu.org/licenses/>.
|
---|
18 | */
|
---|
19 |
|
---|
20 | /*
|
---|
21 | abstract the various kernel interfaces to change notify into a
|
---|
22 | single Samba friendly interface
|
---|
23 | */
|
---|
24 |
|
---|
25 | #include "includes.h"
|
---|
26 | #include "system/filesys.h"
|
---|
27 | #include "ntvfs/sysdep/sys_notify.h"
|
---|
28 | #include <tevent.h>
|
---|
29 | #include "../lib/util/dlinklist.h"
|
---|
30 | #include "param/param.h"
|
---|
31 |
|
---|
32 | /* list of registered backends */
|
---|
33 | static struct sys_notify_backend *backends;
|
---|
34 | static uint32_t num_backends;
|
---|
35 |
|
---|
36 | #define NOTIFY_BACKEND "notify:backend"
|
---|
37 |
|
---|
38 | /*
|
---|
39 | initialise a system change notify backend
|
---|
40 | */
|
---|
41 | _PUBLIC_ struct sys_notify_context *sys_notify_context_create(struct share_config *scfg,
|
---|
42 | TALLOC_CTX *mem_ctx,
|
---|
43 | struct tevent_context *ev)
|
---|
44 | {
|
---|
45 | struct sys_notify_context *ctx;
|
---|
46 | const char *bname;
|
---|
47 | int i;
|
---|
48 |
|
---|
49 | if (num_backends == 0) {
|
---|
50 | return NULL;
|
---|
51 | }
|
---|
52 |
|
---|
53 | if (ev == NULL) {
|
---|
54 | return NULL;
|
---|
55 | }
|
---|
56 |
|
---|
57 | ctx = talloc_zero(mem_ctx, struct sys_notify_context);
|
---|
58 | if (ctx == NULL) {
|
---|
59 | return NULL;
|
---|
60 | }
|
---|
61 |
|
---|
62 | ctx->ev = ev;
|
---|
63 |
|
---|
64 | bname = share_string_option(scfg, NOTIFY_BACKEND, NULL);
|
---|
65 | if (!bname) {
|
---|
66 | if (num_backends) {
|
---|
67 | bname = backends[0].name;
|
---|
68 | } else {
|
---|
69 | bname = "__unknown__";
|
---|
70 | }
|
---|
71 | }
|
---|
72 |
|
---|
73 | for (i=0;i<num_backends;i++) {
|
---|
74 | char *enable_opt_name;
|
---|
75 | bool enabled;
|
---|
76 |
|
---|
77 | enable_opt_name = talloc_asprintf(mem_ctx, "notify:%s",
|
---|
78 | backends[i].name);
|
---|
79 | enabled = share_bool_option(scfg, enable_opt_name, true);
|
---|
80 | talloc_free(enable_opt_name);
|
---|
81 |
|
---|
82 | if (!enabled)
|
---|
83 | continue;
|
---|
84 |
|
---|
85 | if (strcasecmp(backends[i].name, bname) == 0) {
|
---|
86 | bname = backends[i].name;
|
---|
87 | break;
|
---|
88 | }
|
---|
89 | }
|
---|
90 |
|
---|
91 | ctx->name = bname;
|
---|
92 | ctx->notify_watch = NULL;
|
---|
93 |
|
---|
94 | if (i < num_backends) {
|
---|
95 | ctx->notify_watch = backends[i].notify_watch;
|
---|
96 | }
|
---|
97 |
|
---|
98 | return ctx;
|
---|
99 | }
|
---|
100 |
|
---|
101 | /*
|
---|
102 | add a watch
|
---|
103 |
|
---|
104 | note that this call must modify the e->filter and e->subdir_filter
|
---|
105 | bits to remove ones handled by this backend. Any remaining bits will
|
---|
106 | be handled by the generic notify layer
|
---|
107 | */
|
---|
108 | _PUBLIC_ NTSTATUS sys_notify_watch(struct sys_notify_context *ctx,
|
---|
109 | struct notify_entry *e,
|
---|
110 | sys_notify_callback_t callback,
|
---|
111 | void *private_data, void *handle)
|
---|
112 | {
|
---|
113 | if (!ctx->notify_watch) {
|
---|
114 | return NT_STATUS_INVALID_SYSTEM_SERVICE;
|
---|
115 | }
|
---|
116 | return ctx->notify_watch(ctx, e, callback, private_data, handle);
|
---|
117 | }
|
---|
118 |
|
---|
119 | /*
|
---|
120 | register a notify backend
|
---|
121 | */
|
---|
122 | _PUBLIC_ NTSTATUS sys_notify_register(struct sys_notify_backend *backend)
|
---|
123 | {
|
---|
124 | struct sys_notify_backend *b;
|
---|
125 | b = talloc_realloc(talloc_autofree_context(), backends,
|
---|
126 | struct sys_notify_backend, num_backends+1);
|
---|
127 | NT_STATUS_HAVE_NO_MEMORY(b);
|
---|
128 | backends = b;
|
---|
129 | backends[num_backends] = *backend;
|
---|
130 | num_backends++;
|
---|
131 | return NT_STATUS_OK;
|
---|
132 | }
|
---|
133 |
|
---|
134 | _PUBLIC_ NTSTATUS sys_notify_init(void)
|
---|
135 | {
|
---|
136 | static bool initialized = false;
|
---|
137 | #define _MODULE_PROTO(init) extern NTSTATUS init(void);
|
---|
138 | STATIC_sys_notify_MODULES_PROTO;
|
---|
139 | init_module_fn static_init[] = { STATIC_sys_notify_MODULES };
|
---|
140 |
|
---|
141 | if (initialized) return NT_STATUS_OK;
|
---|
142 | initialized = true;
|
---|
143 |
|
---|
144 | run_init_functions(static_init);
|
---|
145 |
|
---|
146 | return NT_STATUS_OK;
|
---|
147 | }
|
---|