/* dircond - directory content watcher daemon Copyright (C) 2012, 2013 Sergey Poznyakoff Dircond is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Dircond is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with dircond. If not, see . */ #include #include #include #include #include #include "dircond.h" /* Event codes */ struct event { int evcode; char *evname; }; struct event events[] = { { IN_ACCESS, "access" }, { IN_ATTRIB, "attrib" }, { IN_CLOSE_WRITE, "close_write" }, { IN_CLOSE_NOWRITE, "close_nowrite" }, { IN_CREATE, "create" }, { IN_DELETE, "delete" }, { IN_MODIFY, "modify" }, { IN_MOVED_FROM, "moved_from" }, { IN_MOVED_TO, "moved_to" }, { IN_OPEN, "open" }, { 0 } }; void ev_log(struct inotify_event *ep, struct dirwatcher *dp) { int i; if (debug_level > 0) { for (i = 0; events[i].evname; i++) { if (events[i].evcode & ep->mask) debug(1, ("%s/%s: %s", dp->dirname, ep->name, events[i].evname)); } } } /* Convert event name to event code */ int ev_name_to_code(const char *name) { int i; for (i = 0; events[i].evname; i++) { if (strcmp(events[i].evname, name) == 0) return events[i].evcode; } return 0; } const char * ev_code_to_name(int code) { int i; for (i = 0; events[i].evname; i++) { if (events[i].evcode & code) return events[i].evname; } return NULL; } struct symevt { int used; char *name; int mask; int line; }; struct hashtab *evtab; static unsigned symevt_hash(void *data, unsigned long hashsize) { struct symevt *sym = data; return hash_string(sym->name, hashsize); } static int symevt_cmp(const void *a, const void *b) { struct symevt const *syma = a; struct symevt const *symb = b; return strcmp(syma->name, symb->name); } static int symevt_copy(void *a, void *b) { struct symevt *syma = a; struct symevt *symb = b; syma->used = 1; syma->name = estrdup(symb->name); return 0; } static void symevt_free(void *p) { struct symevt *sym = p; free(sym->name); free(sym); } int defevt(const char *name, int mask, int line) { struct symevt key, *evp; int install = 1; if (!evtab) { evtab = hashtab_create(sizeof(struct symevt), symevt_hash, symevt_cmp, symevt_copy, NULL, symevt_free); if (!evtab) { diag(LOG_CRIT, "not enough memory"); exit(1); } } key.name = (char *) name; evp = hashtab_lookup_or_install(evtab, &key, &install); if (!install) return evp->line; evp->mask = mask; evp->line = line; return 0; } int getevt(const char *name) { if (evtab) { struct symevt key, *evp; key.name = (char *) name; evp = hashtab_lookup_or_install(evtab, &key, NULL); if (evp) return evp->mask; } return ev_name_to_code(name); }