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 1328 : _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 0 : struct sys_notify_context *ctx; 49 0 : const char *bname; 50 0 : int i; 51 : 52 1328 : if (num_backends == 0) { 53 0 : return NULL; 54 : } 55 : 56 1328 : if (ev == NULL) { 57 0 : return NULL; 58 : } 59 : 60 1328 : ctx = talloc_zero(mem_ctx, struct sys_notify_context); 61 1328 : if (ctx == NULL) { 62 0 : return NULL; 63 : } 64 : 65 1328 : ctx->ev = ev; 66 : 67 1328 : bname = share_string_option(ctx, scfg, NOTIFY_BACKEND, NULL); 68 1328 : if (!bname) { 69 1328 : if (num_backends) { 70 1328 : bname = backends[0].name; 71 : } else { 72 0 : bname = "__unknown__"; 73 : } 74 : } 75 : 76 2656 : for (i=0;i<num_backends;i++) { 77 0 : char *enable_opt_name; 78 0 : bool enabled; 79 : 80 1328 : enable_opt_name = talloc_asprintf(mem_ctx, "notify:%s", 81 1328 : backends[i].name); 82 1328 : enabled = share_bool_option(scfg, enable_opt_name, true); 83 1328 : talloc_free(enable_opt_name); 84 : 85 1328 : if (!enabled) 86 1328 : continue; 87 : 88 0 : if (strcasecmp(backends[i].name, bname) == 0) { 89 0 : bname = backends[i].name; 90 0 : break; 91 : } 92 : } 93 : 94 1328 : ctx->name = bname; 95 1328 : ctx->notify_watch = NULL; 96 : 97 1328 : if (i < num_backends) { 98 0 : ctx->notify_watch = backends[i].notify_watch; 99 : } 100 : 101 1328 : 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 68 : _PUBLIC_ NTSTATUS sys_notify_register(TALLOC_CTX *ctx, 126 : struct sys_notify_backend *backend) 127 : { 128 3 : struct sys_notify_backend *b; 129 68 : b = talloc_realloc(ctx, backends, 130 : struct sys_notify_backend, num_backends+1); 131 68 : NT_STATUS_HAVE_NO_MEMORY(b); 132 68 : backends = b; 133 68 : backends[num_backends] = *backend; 134 68 : num_backends++; 135 68 : return NT_STATUS_OK; 136 : } 137 : 138 68 : _PUBLIC_ NTSTATUS sys_notify_init(void) 139 : { 140 3 : static bool initialized = false; 141 : #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *); 142 3 : STATIC_sys_notify_MODULES_PROTO; 143 68 : init_module_fn static_init[] = { STATIC_sys_notify_MODULES }; 144 : 145 68 : if (initialized) return NT_STATUS_OK; 146 68 : initialized = true; 147 : 148 68 : run_init_functions(NULL, static_init); 149 : 150 68 : return NT_STATUS_OK; 151 : }