1 /* direvent - directory content watcher daemon 2 Copyright (C) 2012-2016 Sergey Poznyakoff 3 4 Direvent is free software; you can redistribute it and/or modify it 5 under the terms of the GNU General Public License as published by the 6 Free Software Foundation; either version 3 of the License, or (at your 7 option) any later version. 8 9 Direvent is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License along 15 with direvent. If not, see <http://www.gnu.org/licenses/>. */ 16 17 #include "config.h" 18 #include <sys/types.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <syslog.h> 22 #include <errno.h> 23 #include <string.h> 24 #include <unistd.h> 25 #include <signal.h> 26 #include <regex.h> 27 #include <grecs/list.h> 28 #include <grecs/symtab.h> 29 #include "gettext.h" 30 31 #define _(s) gettext(s) 32 #define N_(s) s 33 34 /* Generic (system-independent) event codes */ 35 #define GENEV_CREATE 0x01 36 #define GENEV_WRITE 0x02 37 #define GENEV_ATTRIB 0x04 38 #define GENEV_DELETE 0x08 39 40 /* Handler flags. */ 41 #define HF_NOWAIT 0x01 /* Don't wait for termination */ 42 #define HF_STDOUT 0x02 /* Capture stdout */ 43 #define HF_STDERR 0x04 /* Capture stderr */ 44 #define HF_SHELL 0x08 /* Call program via /bin/sh -c */ 45 46 #ifndef DEFAULT_TIMEOUT 47 # define DEFAULT_TIMEOUT 5 48 #endif 49 50 typedef struct { 51 int gen_mask; /* Generic event mask */ 52 int sys_mask; /* System event mask */ 53 } event_mask; 54 55 /* Event description */ 56 struct transtab { 57 char *name; 58 int tok; 59 }; 60 61 enum pattern_type { 62 PAT_EXACT, 63 PAT_GLOB, 64 PAT_REGEX 65 }; 66 67 struct filename_pattern { 68 enum pattern_type type; 69 int neg; 70 union { 71 regex_t re; 72 char *glob; 73 } v; 74 }; 75 76 typedef struct filpatlist *filpatlist_t; 77 78 struct watchpoint; 79 80 typedef int (*event_handler_fn) (struct watchpoint *wp, 81 event_mask *event, 82 const char *dir, 83 const char *file, 84 void *data); 85 typedef void (*handler_free_fn) (void *data); 86 87 /* Handler structure */ 88 struct handler { 89 size_t refcnt; /* Reference counter */ 90 event_mask ev_mask; /* Event mask */ 91 filpatlist_t fnames; /* File name patterns */ 92 event_handler_fn run; 93 handler_free_fn free; 94 void *data; 95 }; 96 97 typedef struct handler_list *handler_list_t; 98 typedef struct handler_iterator *handler_iterator_t; 99 100 /* Watchpoint links the directory being monitored and a list of 101 handlers for various events: */ 102 struct watchpoint { 103 size_t refcnt; 104 int wd; /* Watch descriptor */ 105 struct watchpoint *parent; /* Points to the parent watcher. 106 NULL for top-level watchers */ 107 char *dirname; /* Pathname being watched */ 108 int isdir; /* Is it directory */ 109 handler_list_t handler_list; /* List of handlers */ 110 int depth; /* Recursion depth */ 111 char *split_p; /* Points to the deleted directory 112 separator in dirname (see 113 split_pathname, 114 unsplit_pathname */ 115 #if USE_IFACE == IFACE_KQUEUE 116 mode_t file_mode; 117 time_t file_ctime; 118 #endif 119 }; 120 121 #define __cat2__(a,b) a ## b 122 #define handler_matches_event(h,m,f,n) \ 123 (((h)->ev_mask.__cat2__(m,_mask) & (f)) && \ 124 filpatlist_match((h)->fnames, n) == 0) 125 126 struct handler *handler_alloc(event_mask ev_mask); 127 void handler_free(struct handler *hp); 128 129 struct prog_handler { 130 int flags; /* Handler flags */ 131 char *command; /* Handler command (with eventual arguments) */ 132 uid_t uid; /* Run as this user (unless 0) */ 133 gid_t *gidv; /* Run with these groups' privileges */ 134 size_t gidc; /* Number of elements in gidv */ 135 unsigned timeout; /* Handler timeout */ 136 char **env; /* Environment */ 137 }; 138 139 struct handler *prog_handler_alloc(event_mask ev_mask, filpatlist_t fpat, 140 struct prog_handler *p); 141 void prog_handler_free(struct prog_handler *); 142 size_t prog_handler_envrealloc(struct prog_handler *hp, size_t count); 143 144 145 extern int foreground; 146 extern int debug_level; 147 extern int facility; 148 extern char *tag; 149 extern int syslog_include_prio; 150 extern char *pidfile; 151 extern char *user; 152 extern unsigned opt_timeout; 153 extern unsigned opt_flags; 154 extern int signo; 155 extern int stop; 156 157 extern pid_t self_test_pid; 158 extern int exit_code; 159 160 161 void *emalloc(size_t size); 162 void *ecalloc(size_t nmemb, size_t size); 163 void *erealloc(void *ptr, size_t size); 164 char *estrdup(const char *str); 165 166 char *mkfilename(const char *dir, const char *file); 167 168 void diag(int prio, const char *fmt, ...); 169 void debugprt(const char *fmt, ...); 170 171 #define debug(l, c) do { if (debug_level>=(l)) debugprt c; } while(0) 172 173 void signal_setup(void (*sf) (int)); 174 int detach(void (*)(void)); 175 176 int sysev_filemask(struct watchpoint *dp); 177 void sysev_init(void); 178 int sysev_add_watch(struct watchpoint *dwp, event_mask mask); 179 void sysev_rm_watch(struct watchpoint *dwp); 180 int sysev_select(void); 181 int sysev_name_to_code(const char *name); 182 const char *sysev_code_to_name(int code); 183 184 int defevt(const char *name, event_mask *mask, int line); 185 int getevt(const char *name, event_mask *mask); 186 int evtnullp(event_mask *mask); 187 event_mask *event_mask_init(event_mask *m, int fflags, event_mask const *); 188 void evtsetall(event_mask *m); 189 190 /* Translate generic events to system ones and vice-versa */ 191 extern event_mask genev_xlat[]; 192 /* Translate generic event codes to symbolic names and vice-versa */ 193 extern struct transtab genev_transtab[]; 194 /* Translate system event codes to symbolic names and vice-versa */ 195 extern struct transtab sysev_transtab[]; 196 197 int trans_strtotok(struct transtab *tab, const char *str, int *ret); 198 char *trans_toktostr(struct transtab *tab, int tok); 199 char *trans_tokfirst(struct transtab *tab, int tok, int *next); 200 char *trans_toknext(struct transtab *tab, int tok, int *next); 201 202 struct pathent { 203 long depth; 204 size_t len; 205 char path[1]; 206 }; 207 208 void config_help(void); 209 void config_init(void); 210 void config_parse(const char *file); 211 212 int get_facility(const char *arg); 213 int get_priority(const char *arg); 214 215 int watchpoint_init(struct watchpoint *dwp); 216 void watchpoint_ref(struct watchpoint *dw); 217 void watchpoint_unref(struct watchpoint *dw); 218 void watchpoint_gc(void); 219 220 int watchpoint_pattern_match(struct watchpoint *dwp, const char *file_name); 221 222 void watchpoint_run_handlers(struct watchpoint *wp, int evflags, 223 const char *dirname, const char *filename); 224 225 226 void setup_watchers(void); 227 void shutdown_watchers(void); 228 229 struct watchpoint *watchpoint_lookup(const char *dirname); 230 int check_new_watcher(const char *dir, const char *name); 231 struct watchpoint *watchpoint_install(const char *path, int *pnew); 232 struct watchpoint *watchpoint_install_ptr(struct watchpoint *dw); 233 void watchpoint_suspend(struct watchpoint *dwp); 234 void watchpoint_destroy(struct watchpoint *dwp); 235 int watchpoint_install_sentinel(struct watchpoint *dwp); 236 237 int watch_pathname(struct watchpoint *parent, const char *dirname, int isdir, int notify); 238 239 char *split_pathname(struct watchpoint *dp, char **dirname); 240 void unsplit_pathname(struct watchpoint *dp); 241 242 void ev_log(int flags, struct watchpoint *dp); 243 void deliver_ev_create(struct watchpoint *dp, 244 const char *dirname, const char *filename); 245 int subwatcher_create(struct watchpoint *parent, const char *dirname, 246 int notify); 247 248 struct handler *handler_itr_first(struct watchpoint *dp, 249 handler_iterator_t *itr); 250 struct handler *handler_itr_next(handler_iterator_t *itr); 251 struct handler *handler_itr_current(handler_iterator_t itr); 252 253 #define for_each_handler(d,i,h) \ 254 for (h = handler_itr_first(d, &(i)); \ 255 h; \ 256 h = handler_itr_next(&(i))) 257 258 259 handler_list_t handler_list_create(void); 260 handler_list_t handler_list_copy(handler_list_t); 261 void handler_list_unref(handler_list_t hlist); 262 void handler_list_append(handler_list_t hlist, 263 struct handler *hp); 264 size_t handler_list_remove(handler_list_t hlist, struct handler *hp); 265 size_t handler_list_size(handler_list_t hlist); 266 267 struct process *process_lookup(pid_t pid); 268 void process_cleanup(int expect_term); 269 void process_timeouts(void); 270 char **environ_setup(char **hint, char **kve); 271 272 #define NITEMS(a) ((sizeof(a)/sizeof((a)[0]))) 273 struct sigtab { 274 int signo; 275 void (*sigfun)(int); 276 }; 277 278 int sigv_set_action(int sigc, int *sigv, struct sigaction *sa); 279 int sigv_set_all(void (*handler)(int), int sigc, int *sigv, 280 struct sigaction *retsa); 281 int sigv_set_tab(int sigc, struct sigtab *sigtab, struct sigaction *retsa); 282 int sigv_set_action_tab(int sigc, struct sigtab *sigtab, struct sigaction *sa); 283 284 struct grecs_locus; 285 int filpatlist_add(filpatlist_t *fptr, char const *arg, 286 struct grecs_locus *loc); 287 void filpatlist_add_exact(filpatlist_t *fptr, char const *arg); 288 void filpatlist_destroy(filpatlist_t *fptr); 289 int filpatlist_match(filpatlist_t fp, const char *name); 290 int filpatlist_is_empty(filpatlist_t fp); 291 292