/* 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
#ifndef DEFAULT_TIMEOUT
# define DEFAULT_TIMEOUT 5
#endif
/* Handler flags. */
#define HF_NOWAIT 0x01 /* Don't wait for termination */
#define HF_STDOUT 0x02 /* Capture stdout */
#define HF_STDERR 0x04 /* Capture stderr */
/* Handler structure */
struct handler {
struct handler *next;
int ev_mask; /* Event mask */
int flags; /* Handler flags */
const char *prog; /* Handler program (no arguments allowed) */
uid_t uid; /* Run as this user (unless 0) */
gid_t *gidv; /* Run with these groups' privileges */
size_t gidc; /* Number of elements in gidv */
unsigned timeout; /* Handler timeout */
};
/* A directory watcher is described by the following structure */
struct dirwatcher {
int refcnt;
int wd; /* Watch descriptor */
struct dirwatcher *parent; /* Points to the parent watcher.
NULL for top-level watchers */
char *dirname; /* Pathname being watched */
struct handler *handler_list; /* Handlers */
int depth;
};
extern int foreground;
extern int debug_level;
extern int facility;
extern char *tag;
extern char *pidfile;
extern char *user;
extern unsigned opt_timeout;
extern unsigned opt_flags;
extern int opt_facility;
extern int ifd;
void *emalloc(size_t size);
void *ecalloc(size_t nmemb, size_t size);
void *erealloc(void *ptr, size_t size);
char *estrdup(const char *str);
char *mkfilename(const char *dir, const char *file);
void diag(int prio, const char *fmt, ...);
void debugprt(const char *fmt, ...);
#define debug(l, c) do { if (debug_level>=(l)) debugprt c; } while(0)
int ev_name_to_code(const char *name);
const char *ev_code_to_name(int code);
void ev_log(struct inotify_event *ep, struct dirwatcher *dp);
int defevt(const char *name, int mask, int line);
int getevt(const char *name);
struct hashtab;
struct hashent {
int used;
};
int hashtab_replace(struct hashtab *st, void *ent, void **old_ent);
const char *hashtab_strerror(int rc);
int hashtab_remove(struct hashtab *st, void *elt);
int hashtab_get_index(unsigned *idx, struct hashtab *st, void *key,
int *install);
void *hashtab_lookup_or_install(struct hashtab *st, void *key, int *install);
void hashtab_clear(struct hashtab *st);
struct hashtab *hashtab_create(size_t elsize,
unsigned (*hash_fun)(void *, unsigned long),
int (*cmp_fun)(const void *, const void *),
int (*copy_fun)(void *, void *),
void *(*alloc_fun)(size_t),
void (*free_fun)(void *));
void hashtab_free(struct hashtab *st);
size_t hashtab_count_entries(struct hashtab *st);
typedef int (*hashtab_enumerator_t) (struct hashent *, void *);
int hashtab_foreach(struct hashtab *st, hashtab_enumerator_t fun,
void *data);
size_t hashtab_count(struct hashtab *st);
unsigned hash_string(const char *name, unsigned long hashsize);
struct pathent {
struct pathent *next;
long depth;
size_t len;
char path[1];
};
struct pathdefn {
int used;
char *name;
struct pathent *pathlist;
};
int pathdefn_add(const char *name, const char *dir, long depth);
struct pathent *pathdefn_get(const char *name);
void config_parse(const char *file);
int read_facility(const char *arg, int *pres);
void setup_watchers(void);
struct dirwatcher *dirwatcher_lookup_wd(int wd);
int check_new_watcher(const char *dir, const char *name);
struct dirwatcher *dirwatcher_install(const char *path, int *pnew);
void remove_watcher(const char *dir, const char *name);