/* * Yet another daemon library especially designed to be used * with libsxmp based daemons. * * (c) Alexander Vdolainen 2016 * * libsxmp is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * libsxmp 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see ."; * */ #ifndef __YDAEMON_YDAEMON_H__ #define __YDAEMON_YDAEMON_H__ #include #include #include #include #include #include #include /* some syntax */ /** * --values (variables) */ #define VAR_CREATE_GROUP "create-var-group" #define VAR_SET "var-set" /** * --modules * (%MODULE_ADD_SX ' ) -- add a module to the list of available modules * (%MODULE_SET_SX ' (:%MODULE_PREFIX|%MODULE_PATHNAME|%MODULE_CNFPATH *)) * *value might be the following: * a. in case of double or single quote - will be taken as is * b. without quotes will be interpreted as variable (must be defined before this expression) */ #define MODULE_ADD_SX "module-add" #define MODULE_SET_SX "module-set" /** { */ /* module config values for _SET_SX */ #define MODULE_PREFIX "prefix" #define MODULE_PATHNAME "pathname" #define MODULE_CNFPATH "config-path" /** } */ #define MODULE_LOAD_SX "module-load" #define MODULE_RUN_SX "module-run" /* internal functions */ #define SCMOBJECT "object" /* functions for the logs */ #define YDOPENLOGS "yd-open-logfile" /* limits */ #define MAX_SCM_FUNCTIONS 16384 #define MAX_SERVICES 8192 #define MAX_MODULES 4096 enum { SCINT = 0, SCCSTR, SCOBJECTPTR, SCUNDEFINED, }; typedef struct __scm_ret { uint8_t serr; uint8_t type; uint32_t len; union { void *ret; struct { int32_t ec; uint32_t ru32; }; }; } scret_t; #define RETURN_SRET_SERR(r, e) (r).serr = e; return r #define RETURN_SRET_IRES(r, e) (r).serr = 0; (r).type = SCINT; (r).ec = e; \ return r #define RETURN_SRET_ORES(r, e) (r).serr = 0; (r).type = SCOBJECTPTR; (r).ret = (e); \ return r struct __ydaemon_context_type; /** * @brief Type used to describe scm function * * It contains name i.e. keyword, pointer to the * function itself and optional pointer to the * implementation specific data. It packs to usrtc * search structure. */ typedef struct __scm_func { char *name; scret_t (*call)(struct __ydaemon_context_type *, sexp_t *, void *); void *priv; usrtc_node_t node; } scm_function_t; /** * @brief Type used to describe a tree of scm functions * * It contains a search structure with packed * scm_function_t set and also contain special * private pointer that might be optionally used * by implementation. */ typedef struct __scm_func_tree { usrtc_t functions; void *priv; } scm_function_tree_t; /** * @brief Values types * * Describes the type of value * @see zdc_conf_val_t */ typedef enum { STRING = 0, INT, UINT, LONG, ULONG, BLOB, SEXPR, CUSTOM, } ydc_val_type_t; /** * @brief configuration event * * Type used to describe events occured with values */ typedef enum { YC_EVENT_ADD, YC_EVENT_MODIFY, YC_EVENT_DESTROY, YC_EVENT_ATTACH, } ydc_event_t; /** * @brief Type used to fit all required parameters * * It contain mode, system settings and a lot of other * config defined parameters. */ typedef struct __ym_conf { /* parameters groups */ usrtc_t p_groups; /**< Parameters groups */ /* functions tree */ void *init_funcs; /* locking */ pthread_rwlock_t grp_lock; /**< Locking for groups */ pthread_mutex_t conf_lock; /**< Locking for state change, function ops, system io */ } ydc_conf_t; /** * @brief Type of the parameters group * * Store values. */ typedef struct __ym_pgroup { usrtc_t values; usrtc_node_t unode; char *name; pthread_rwlock_t val_lock; } ydc_pgroup_t; /** * @brief Type used to describe value * * Used to store value. */ typedef struct __ym_conf_value { usrtc_node_t unode; ydc_val_type_t type; int len; char *name; void *value; void (*on_eventv)(struct __ym_conf_value *, struct __ym_conf_value *, ydc_conf_t *, ydc_event_t); void *priv; } ydc_conf_val_t; typedef struct __ydaemon_log_type { FILE *logstream; int verbose_level; int se; } yd_log_t; typedef struct __ydaemon_context_type { usrtc_t *services; usrtc_t *modules; scm_function_tree_t *func; /** < functions for configuration and processing */ ydc_conf_t *values; /** < values stored by the groups */ yd_log_t *logcontext; int flags; pthread_rwlock_t modlock; pthread_mutex_t looplock; int daemon; } yd_context_t; #define yd_mod_ctx_wrlock(n) pthread_rwlock_wrlock(&(n)->modlock) #define yd_mod_ctx_rdlock(n) pthread_rwlock_rdlock(&(n)->modlock) #define yd_mod_ctx_unlock(n) pthread_rwlock_unlock(&(n)->modlock) typedef enum { YD_SERVICE_MUX = 0, YD_SXMP_MOD, YD_DATASTORE_MOD, YD_OTHER, } yd_mod_type_t; typedef struct __ydaemon_module { char *name; char *pathname; char *cnfname; char *prefix; void *dlhandle; void *(*getobject)(void *, const char *); int (*shutdown)(yd_context_t *); int (*preinit)(yd_context_t *); int (*init)(yd_context_t *); int (*run)(yd_context_t *); yd_mod_type_t type; int flags; usrtc_node_t node; } yd_mod_t; /* functions defines for modules */ #define def_shutdown(PREFIX) int PREFIX ## _shutdown(yd_context_t *ctx) #define def_preinit(PREFIX) int PREFIX ## _preinit(yd_context_t *ctx) #define def_init(PREFIX) int PREFIX ## _init(yd_context_t *ctx) #define def_run(PREFIX) int PREFIX ## _run(yd_context_t *ctx) #define def_getobject(PREFIX) void* PREFIX ## _getobject(void *priv, const char *oname) /* function arguments macros */ #define def_ctx ctx #define defpriv priv #define defoname oname #define yd_mod_set_prefix(n, p) (n)->prefix = (p) #define yd_mod_set_pathname(n, p) (n)->pathname = (p) #define yd_mod_set_cfgpath(n, p) (n)->cnfname = (p) #define yd_mod_preinit(n) \ { memset((n), 0, sizeof(yd_mod_t)); usrtc_node_init((n)->node, (n)); } int yd_mod_init(yd_context_t *, yd_mod_t *); int yd_mod_get(yd_context_t *, const char *, yd_mod_t **); int yd_mod_load(yd_context_t *, yd_mod_t *); int yd_mod_run(yd_context_t *, yd_mod_t *); int yd_mod_shutdown(yd_context_t *, yd_mod_t *); void *yd_mod_getobject(yd_context_t *, yd_mod_t *, void *, const char *); void *yd_mod_getsym(yd_context_t *, yd_mod_t *, const char *); typedef struct __ydaemon_service { char *name; /* name of the service */ void *ops; /* the subject to think about ... */ void *connection; /* as backends private data */ void *conf; /* special configuration */ usrtc_node_t node; } yd_service_t; #define yd_ctx_values(c) (c)->values int yd_init_ctx(yd_context_t *); int yd_eval_ctx(yd_context_t *, const char *); scret_t yd_eval_sexp(yd_context_t *, sexp_t *); int yd_mainloop(yd_context_t *); void yd_mainloop_exit(yd_context_t *); int yd_set_daemonize(yd_context_t *, int); /* modules related functions */ int yd_mod_add(yd_context_t *, const char *, yd_mod_type_t); /* internal functions API */ void scm_func_tree_free(scm_function_tree_t *pt); int scm_func_tree_init(scm_function_tree_t **pt, void *priv); int scm_func_tree_insert(yd_context_t *zdx, const char *name, scret_t (*call)(yd_context_t *, sexp_t *, void *), void *priv); int scm_func_tree_insert_t(yd_context_t *zdx, scm_function_t *f); scret_t scm_func_tree_call(yd_context_t *zdx, void *cnf, sexp_t *sx, char *name); int scm_func_tree_delete(yd_context_t *zdx, char *name); /* variables related functions */ int ydc_conf_init(ydc_conf_t *); int ydc_conf_create_pgroup(ydc_conf_t *, char *); int ydc_conf_get_val(ydc_conf_t *, const char *, ydc_conf_val_t **); int ydc_conf_add_val_p(ydc_conf_t *, const char *, int); /* some internal stuff */ #define UNIT_TESTS 1 #ifdef UNIT_TESTS #define blub printf("%d at %s\n", __LINE__, __FUNCTION__) #endif /* logging */ enum { YL_DEBUG = 0, YL_INFO, YL_WARN, YL_ERROR, }; void ydlog(yd_context_t *ctx, int olvl, const char *fmt, ...); void yddaemon(yd_context_t *ctx); /* object storage */ #define MAX_OBJECTS 65535 typedef struct __ostore_type { usrtc_t objects; pthread_rwlock_t rwlock; } obj_store_t; typedef struct __ostore_node_type { char *name; void *objdata; usrtc_node_t node; } obj_store_node_t; int obj_store_init(obj_store_t *); int obj_store_set(obj_store_t *, const char *, void *); int obj_store_get(obj_store_t *, const char *, void **); int obj_store_remove(obj_store_t *, const char *); #endif /* __YDAEMON_YDAEMON_H__ */