Line data Source code
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 : #include "lib/util/samba_modules.h"
32 :
33 : #undef strcasecmp
34 :
35 : /* list of registered backends */
36 : static struct sys_notify_backend *backends;
37 : static uint32_t num_backends;
38 :
39 : #define NOTIFY_BACKEND "notify:backend"
40 :
41 : /*
42 : initialise a system change notify backend
43 : */
44 1321 : _PUBLIC_ struct sys_notify_context *sys_notify_context_create(struct share_config *scfg,
45 : TALLOC_CTX *mem_ctx,
46 : struct tevent_context *ev)
47 : {
48 : struct sys_notify_context *ctx;
49 : const char *bname;
50 : int i;
51 :
52 1321 : if (num_backends == 0) {
53 0 : return NULL;
54 : }
55 :
56 1321 : if (ev == NULL) {
57 0 : return NULL;
58 : }
59 :
60 1321 : ctx = talloc_zero(mem_ctx, struct sys_notify_context);
61 1321 : if (ctx == NULL) {
62 0 : return NULL;
63 : }
64 :
65 1321 : ctx->ev = ev;
66 :
67 1321 : bname = share_string_option(ctx, scfg, NOTIFY_BACKEND, NULL);
68 1321 : if (!bname) {
69 1321 : if (num_backends) {
70 1321 : bname = backends[0].name;
71 : } else {
72 0 : bname = "__unknown__";
73 : }
74 : }
75 :
76 2642 : for (i=0;i<num_backends;i++) {
77 : char *enable_opt_name;
78 : bool enabled;
79 :
80 1321 : enable_opt_name = talloc_asprintf(mem_ctx, "notify:%s",
81 1321 : backends[i].name);
82 1321 : enabled = share_bool_option(scfg, enable_opt_name, true);
83 1321 : talloc_free(enable_opt_name);
84 :
85 1321 : if (!enabled)
86 1321 : continue;
87 :
88 0 : if (strcasecmp(backends[i].name, bname) == 0) {
89 0 : bname = backends[i].name;
90 0 : break;
91 : }
92 : }
93 :
94 1321 : ctx->name = bname;
95 1321 : ctx->notify_watch = NULL;
96 :
97 1321 : if (i < num_backends) {
98 0 : ctx->notify_watch = backends[i].notify_watch;
99 : }
100 :
101 1321 : return ctx;
102 : }
103 :
104 : /*
105 : add a watch
106 :
107 : note that this call must modify the e->filter and e->subdir_filter
108 : bits to remove ones handled by this backend. Any remaining bits will
109 : be handled by the generic notify layer
110 : */
111 513 : _PUBLIC_ NTSTATUS sys_notify_watch(struct sys_notify_context *ctx,
112 : struct notify_entry *e,
113 : sys_notify_callback_t callback,
114 : void *private_data, void *handle)
115 : {
116 513 : if (!ctx->notify_watch) {
117 513 : return NT_STATUS_INVALID_SYSTEM_SERVICE;
118 : }
119 0 : return ctx->notify_watch(ctx, e, callback, private_data, handle);
120 : }
121 :
122 : /*
123 : register a notify backend
124 : */
125 55 : _PUBLIC_ NTSTATUS sys_notify_register(TALLOC_CTX *ctx,
126 : struct sys_notify_backend *backend)
127 : {
128 : struct sys_notify_backend *b;
129 55 : b = talloc_realloc(ctx, backends,
130 : struct sys_notify_backend, num_backends+1);
131 55 : NT_STATUS_HAVE_NO_MEMORY(b);
132 55 : backends = b;
133 55 : backends[num_backends] = *backend;
134 55 : num_backends++;
135 55 : return NT_STATUS_OK;
136 : }
137 :
138 55 : _PUBLIC_ NTSTATUS sys_notify_init(void)
139 : {
140 : static bool initialized = false;
141 : #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
142 : STATIC_sys_notify_MODULES_PROTO;
143 55 : init_module_fn static_init[] = { STATIC_sys_notify_MODULES };
144 :
145 55 : if (initialized) return NT_STATUS_OK;
146 55 : initialized = true;
147 :
148 55 : run_init_functions(NULL, static_init);
149 :
150 55 : return NT_STATUS_OK;
151 : }
|