You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
368 lines
9.2 KiB
C
368 lines
9.2 KiB
C
/*
|
|
* Yet another daemon library especially designed to be used
|
|
* with libsxmp based daemons.
|
|
*
|
|
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
|
|
*
|
|
* 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 <http://www.gnu.org/licenses/>.";
|
|
*
|
|
*/
|
|
|
|
#ifndef __YDAEMON_YDAEMON_H__
|
|
#define __YDAEMON_YDAEMON_H__
|
|
|
|
#include <stdint.h>
|
|
#include <time.h>
|
|
#include <sys/types.h>
|
|
#include <pthread.h>
|
|
|
|
#include <tdata/usrtc.h>
|
|
#include <tdata/idx_allocator.h>
|
|
#include <sexpr/sexp.h>
|
|
|
|
/* some syntax */
|
|
|
|
/**
|
|
* --values (variables)
|
|
*/
|
|
#define VAR_CREATE_GROUP "create-var-group"
|
|
#define VAR_SET "var-set"
|
|
/**
|
|
* --modules
|
|
* (%MODULE_ADD_SX '<name> <type>) -- add a module to the list of available modules
|
|
* (%MODULE_SET_SX '<name> (:%MODULE_PREFIX|%MODULE_PATHNAME|%MODULE_CNFPATH *<value>))
|
|
* *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__ */
|