📄 util.h
字号:
{ char *facility; int number;} log_facility_t;extern log_t log_new(log_type_t type, char *ident, char *facility);extern void log_write(log_t log, int level, const char *msgfmt, ...);extern void log_free(log_t log);/* Not A DOM *//* using nad: * * nad is very simplistic, and requires all string handling to use a length. * Apps using this must be aware of the structure and access it directly for * most information. nads can only be built by successively using the _append_ * functions correctly. After built, they can be modified using other functions, * or by direct access. To access cdata on an elem or attr, use nad->cdata + * nad->xxx[index].ixxx for the start, and .lxxx for len. * * Namespace support seems to work, but hasn't been thoroughly tested. in * particular, editing the nad after its creation might have quirks. use at * your own risk! Note that nad_add_namespace() brings a namespace into scope * for the next element added with nad_append_elem(), nad_insert_elem() or * nad_wrap_elem() (and by extension, any of its subelements). This is the same * way that Expat does things, so nad_add_namespace() can be driven from the * Expat's StartNamespaceDeclHandler. */typedef struct nad_st **nad_cache_t;struct nad_elem_st{ int parent; int iname, lname; int icdata, lcdata; /* cdata within this elem (up to first child) */ int itail, ltail; /* cdata after this elem */ int attr; int ns; int my_ns; int depth;};struct nad_attr_st{ int iname, lname; int ival, lval; int my_ns; int next;};struct nad_ns_st{ int iuri, luri; int iprefix, lprefix; int next;};typedef struct nad_st{ nad_cache_t cache; /* he who gave us life */ struct nad_elem_st *elems; struct nad_attr_st *attrs; struct nad_ns_st *nss; char *cdata; int *depths; /* for tracking the last elem at a depth */ int elen, alen, nlen, clen, dlen; int ecur, acur, ncur, ccur; int scope; /* currently scoped namespaces, get attached to the next element */ struct nad_st *next; /* for keeping a list of nads */} *nad_t;/** create a new cache for nads */nad_cache_t nad_cache_new(void);/** free the cache */void nad_cache_free(nad_cache_t cache);/** create a new nad */nad_t nad_new(nad_cache_t cache);/** copy a nad */nad_t nad_copy(nad_t nad);/** free that nad */void nad_free(nad_t nad);/** find the next element with this name/depth *//** 0 for siblings, 1 for children and so on */int nad_find_elem(nad_t nad, int elem, int ns, const char *name, int depth);/** find the first matching attribute (and optionally value) */int nad_find_attr(nad_t nad, int elem, int ns, const char *name, const char *val);/** find the first matching namespace (and optionally prefix) */int nad_find_namespace(nad_t nad, int elem, const char *uri, const char *prefix);/** find a namespace in scope (and optionally prefix) */int nad_find_scoped_namespace(nad_t nad, const char *uri, const char *prefix);/** reset or store the given attribute */void nad_set_attr(nad_t nad, int elem, int ns, const char *name, const char *val, int vallen);/** insert and return a new element as a child of this one */int nad_insert_elem(nad_t nad, int elem, int ns, const char *name, const char *cdata);/** wrap an element with another element */void nad_wrap_elem(nad_t nad, int elem, int ns, const char *name);/** append and return a new element */int nad_append_elem(nad_t nad, int ns, const char *name, int depth);/** append attribs to the last element */int nad_append_attr(nad_t nad, int ns, const char *name, const char *val);/** append more cdata to the last element */void nad_append_cdata(nad_t nad, const char *cdata, int len, int depth);/** add a namespace to the next element (ie, called when the namespace comes into scope) */int nad_add_namespace(nad_t nad, const char *uri, const char *prefix);/** declare a namespace on an already existing element */int nad_append_namespace(nad_t nad, int elem, const char *uri, const char *prefix);/** create a string representation of the given element (and children), point references to it */void nad_print(nad_t nad, int elem, char **xml, int *len);/** serialize and deserialize a nad */void nad_serialize(nad_t nad, char **buf, int *len);nad_t nad_deserialize(nad_cache_t cache, const char *buf);#ifdef HAVE_EXPAT/** create a nad from raw xml */nad_t nad_parse(nad_cache_t cache, const char *buf, int len);#endif/* these are some helpful macros */#define NAD_ENAME(N,E) (N->cdata + N->elems[E].iname)#define NAD_ENAME_L(N,E) (N->elems[E].lname)#define NAD_CDATA(N,E) (N->cdata + N->elems[E].icdata)#define NAD_CDATA_L(N,E) (N->elems[E].lcdata)#define NAD_ANAME(N,A) (N->cdata + N->attrs[A].iname)#define NAD_ANAME_L(N,A) (N->attrs[A].lname)#define NAD_AVAL(N,A) (N->cdata + N->attrs[A].ival)#define NAD_AVAL_L(N,A) (N->attrs[A].lval)#define NAD_NURI(N,NS) (N->cdata + N->nss[NS].iuri)#define NAD_NURI_L(N,NS) (N->nss[NS].luri)#define NAD_NPREFIX(N,NS) (N->cdata + N->nss[NS].iprefix)#define NAD_NPREFIX_L(N,NS) (N->nss[NS].lprefix)#define NAD_ENS(N,E) (N->elems[E].my_ns)#define NAD_ANS(N,A) (N->attrs[A].my_ns)/* config files */typedef struct config_elem_st *config_elem_t;typedef struct config_st *config_t;/** holder for the config hash and nad */struct config_st{ xht hash; nad_cache_t nads; nad_t nad;};/** a single element */struct config_elem_st{ char **values; int nvalues; char ***attrs;};extern config_t config_new(void);extern int config_load(config_t c, char *file);extern config_elem_t config_get(config_t c, char *key);extern char *config_get_one(config_t c, char *key, int num);extern int config_count(config_t c, char *key);extern char *config_get_attr(config_t c, char *key, int num, char *attr);extern void config_free(config_t);/* * IP-based access controls */typedef struct access_rule_st{ struct sockaddr_storage ip; int mask;} *access_rule_t;typedef struct access_st{ int order; /* 0 = allow,deny 1 = deny,allow */ access_rule_t allow; int nallow; access_rule_t deny; int ndeny;} *access_t;access_t access_new(int order);void access_free(access_t access);int access_allow(access_t access, char *ip, char *mask);int access_deny(access_t access, char *ip, char *mask);int access_check(access_t access, char *ip);/* * rate limiting */typedef struct rate_st{ int total; /* if we exceed this many events */ int seconds; /* in this many seconds */ int wait; /* then go bad for this many seconds */ time_t time; /* time we started counting events */ int count; /* event count */ time_t bad; /* time we went bad, or 0 if we're not */} *rate_t;rate_t rate_new(int total, int seconds, int wait);void rate_free(rate_t rt);void rate_reset(rate_t rt);void rate_add(rate_t rt, int count);int rate_left(rate_t rt);int rate_check(rate_t rt); /* 1 == good, 0 == bad *//* * helpers for ip addresses */#include "inaddr.h" /* used in mio as well *//* * serialisation helper functions */int ser_string_get(char **dest, int *source, const char *buf, int len);int ser_int_get(int *dest, int *source, const char *buf, int len);void ser_string_set(char *source, int *dest, char **buf, int *len);void ser_int_set(int source, int *dest, char **buf, int *len);/* * priority queues */typedef struct _jqueue_node_st *_jqueue_node_t;struct _jqueue_node_st { void *data; int priority; _jqueue_node_t next; _jqueue_node_t prev;};typedef struct _jqueue_st { pool p; _jqueue_node_t cache; _jqueue_node_t front; _jqueue_node_t back; int size;} *jqueue_t;jqueue_t jqueue_new(void);void jqueue_free(jqueue_t q);void jqueue_push(jqueue_t q, void *data, int pri);void *jqueue_pull(jqueue_t q);int jqueue_size(jqueue_t q);/* ISO 8601 / JEP-0082 date/time manipulation */typedef enum { dt_DATE = 1, dt_TIME = 2, dt_DATETIME = 3, dt_LEGACY = 4} datetime_t;time_t datetime_in(char *date);void datetime_out(time_t t, datetime_t type, char *date, int datelen);/* base64 functions */extern int ap_base64decode_len(const char *bufcoded, int buflen);extern int ap_base64decode(char *bufplain, const char *bufcoded, int buflen);extern int ap_base64decode_binary(unsigned char *bufplain, const char *bufcoded, int buflen);extern int ap_base64encode_len(int len);extern int ap_base64encode(char *encoded, const char *string, int len);extern int ap_base64encode_binary(char *encoded, const unsigned char *string, int len);/* convenience, result string must be free()'d by caller */extern char *b64_encode(char *buf, int len);extern char *b64_decode(char *buf);/* stanza manipulation */#define stanza_err_BAD_REQUEST (100)#define stanza_err_CONFLICT (101)#define stanza_err_FEATURE_NOT_IMPLEMENTED (102)#define stanza_err_FORBIDDEN (103)#define stanza_err_GONE (104)#define stanza_err_INTERNAL_SERVER_ERROR (105)#define stanza_err_ITEM_NOT_FOUND (106)#define stanza_err_JID_MALFORMED (107)#define stanza_err_NOT_ACCEPTABLE (108)#define stanza_err_NOT_ALLOWED (109)#define stanza_err_PAYMENT_REQUIRED (110)#define stanza_err_RECIPIENT_UNAVAILABLE (111)#define stanza_err_REDIRECT (112)#define stanza_err_REGISTRATION_REQUIRED (113)#define stanza_err_REMOTE_SERVER_NOT_FOUND (114)#define stanza_err_REMOTE_SERVER_TIMEOUT (115)#define stanza_err_RESOURCE_CONSTRAINT (116)#define stanza_err_SERVICE_UNAVAILABLE (117)#define stanza_err_SUBSCRIPTION_REQUIRED (118)#define stanza_err_UNDEFINED_CONDITION (119)#define stanza_err_UNEXPECTED_REQUEST (120)#define stanza_err_OLD_UNAUTH (121)#define stanza_err_LAST (122)extern nad_t stanza_error(nad_t nad, int elem, int err);extern nad_t stanza_tofrom(nad_t nad, int elem);/* hex conversion utils */void hex_from_raw(char *in, int inlen, char *out);int hex_to_raw(char *in, int inlen, char *out);/* xdata in a seperate file */#include "xdata.h"/* debug logging */int get_debug_flag(void);void set_debug_flag(int v);void debug_log(char *file, int line, const char *msgfmt, ...);#define ZONE __FILE__,__LINE__#define MAX_DEBUG 4096/* if no debug, basically compile it out */#ifdef DEBUG#define log_debug if(get_debug_flag()) debug_log#else#define log_debug if(0) debug_log#endif/* Portable signal function */typedef void jsighandler_t(int);jsighandler_t* jabber_signal(int signo, jsighandler_t *func);#ifdef __cplusplus}#endif#endif /* INCL_UTIL_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -