#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ac-stdint.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <errno.h>
#include <assert.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#if defined(HAVE_SYS_TIME_H)
# include <sys/time.h>
#elif defined(HAVE_SYS_TIMEB_H)
# include <sys/timeb.h>
#endif
#ifdef HAVE_SYSLOG_H
# include <syslog.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <ctype.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#include <pwd.h>
#include "subst/subst.h"
#include "util/util_compat.h"
#ifndef INCL_UTIL_H
#define INCL_UTIL_H
#ifdef __cplusplus
extern "C" {
#endif
#define HAVE_EXPAT 1
#include "sha1.h"
#include "md5.h"
#ifdef POOL_DEBUG
#define POOL_NUM 40009
#endif
struct pheap
{
void *block;
int size, used;
};
typedef void (*pool_cleaner)(void *arg);
struct pfree
{
pool_cleaner f;
void *arg;
struct pheap *heap;
struct pfree *next;
};
typedef struct pool_struct
{
int size;
struct pfree *cleanup;
struct pfree *cleanup_tail;
struct pheap *heap;
#ifdef POOL_DEBUG
char name[8], zone[32];
int lsize;
} _pool, *pool;
#define pool_new() _pool_new(ZONE)
#define pool_heap(i) _pool_new_heap(i,ZONE)
#else
} _pool, *pool;
#define pool_heap(i) _pool_new_heap(i,NULL,0)
#define pool_new() _pool_new(NULL,0)
#endif
pool _pool_new(char *zone, int line);
pool _pool_new_heap(int size, char *zone, int line);
void *pmalloc(pool p, int size);
void *pmalloc_x(pool p, int size, char c);
void *pmalloco(pool p, int size);
char *pstrdup(pool p, const char *src);
void pool_stat(int full);
char *pstrdupx(pool p, const char *src, int len);
void pool_cleanup(pool p, pool_cleaner f, void *arg);
void pool_free(pool p);
int pool_size(pool p);
char *j_strdup(const char *str);
char *j_strcat(char *dest, char *txt);
int j_strcmp(const char *a, const char *b);
int j_strcasecmp(const char *a, const char *b);
int j_strncmp(const char *a, const char *b, int i);
int j_strncasecmp(const char *a, const char *b, int i);
int j_strlen(const char *a);
int j_atoi(const char *a, int def);
char *j_attr(const char** atts, char *attr);
char *j_strnchr(const char *s, int c, int n);
void shahash_r(const char* str, char hashbuf[41]);
typedef struct xhn_struct
{
struct xhn_struct *next;
const char *key;
void *val;
} *xhn, _xhn;
typedef struct xht_struct
{
pool p;
int prime;
int dirty;
int count;
struct xhn_struct *zen;
int iter_bucket;
xhn iter_node;
} *xht, _xht;
xht xhash_new(int prime);
void xhash_put(xht h, const char *key, void *val);
void xhash_putx(xht h, const char *key, int len, void *val);
void *xhash_get(xht h, const char *key);
void *xhash_getx(xht h, const char *key, int len);
void xhash_zap(xht h, const char *key);
void xhash_zapx(xht h, const char *key, int len);
void xhash_free(xht h);
typedef void (*xhash_walker)(xht h, const char *key, void *val, void *arg);
void xhash_walk(xht h, xhash_walker w, void *arg);
int xhash_dirty(xht h);
int xhash_count(xht h);
pool xhash_pool(xht h);
int xhash_iter_first(xht h);
int xhash_iter_next(xht h);
void xhash_iter_zap(xht h);
int xhash_iter_get(xht h, const char **key, void **val);
char *strescape(pool p, char *buf, int len);
char *strunescape(pool p, char *buf);
struct spool_node
{
char *c;
struct spool_node *next;
};
typedef struct spool_struct
{
pool p;
int len;
struct spool_node *last;
struct spool_node *first;
} *spool;
spool spool_new(pool p);
void spooler(spool s, ...);
char *spool_print(spool s);
void spool_add(spool s, char *str);
void spool_escape(spool s, char *raw, int len);
char *spools(pool p, ...);
#define uri_STREAMS "http://etherx.jabber.org/streams"
#define uri_CLIENT "jabber:client"
#define uri_SERVER "jabber:server"
#define uri_DIALBACK "jabber:server:dialback"
#define uri_TLS "urn:ietf:params:xml:ns:xmpp-tls"
#define uri_SASL "urn:ietf:params:xml:ns:xmpp-sasl"
#define uri_BIND "urn:ietf:params:xml:ns:xmpp-bind"
#define uri_XSESSION "urn:ietf:params:xml:ns:xmpp-session"
#define uri_STREAM_ERR "urn:ietf:params:xml:ns:xmpp-streams"
#define uri_STANZA_ERR "urn:ietf:params:xml:ns:xmpp-stanzas"
#define uri_COMPONENT "http://jabberd.jabberstudio.org/ns/component/1.0"
#define uri_SESSION "http://jabberd.jabberstudio.org/ns/session/1.0"
#define uri_RESOLVER "http://jabberd.jabberstudio.org/ns/resolver/1.0"
#define uri_XDATA "jabber:x:data"
#define uri_XML "http://www.w3.org/XML/1998/namespace"
typedef struct prep_cache_st {
xht node;
xht domain;
xht resource;
} *prep_cache_t;
prep_cache_t prep_cache_new(void);
void prep_cache_free(prep_cache_t pc);
char *prep_cache_node_get(prep_cache_t pc, char *from);
void prep_cache_node_set(prep_cache_t pc, char *from, char *to);
char *prep_cache_domain_get(prep_cache_t pc, char *from);
void prep_cache_domain_set(prep_cache_t pc, char *from, char *to);
char *prep_cache_resource_get(prep_cache_t pc, char *from);
void prep_cache_resource_set(prep_cache_t pc, char *from, char *to);
typedef struct jid_st {
prep_cache_t pc;
unsigned char node[1024];
unsigned char domain[1024];
unsigned char resource[1024];
unsigned char *_user;
unsigned char *_full;
int dirty;
struct jid_st *next;
} *jid_t;
jid_t jid_new(prep_cache_t pc, const unsigned char *id, int len);
jid_t jid_reset(jid_t jid, const unsigned char *id, int len);
void jid_free(jid_t jid);
int jid_prep(jid_t jid);
void jid_expand(jid_t jid);
const unsigned char *jid_user(jid_t jid);
const unsigned char *jid_full(jid_t jid);
int jid_compare_user(jid_t a, jid_t b);
int jid_compare_full(jid_t a, jid_t b);
jid_t jid_dup(jid_t jid);
int jid_search(jid_t list, jid_t jid);
jid_t jid_zap(jid_t list, jid_t jid);
jid_t jid_append(jid_t list, jid_t jid);
typedef enum {
log_STDOUT,
log_SYSLOG,
log_FILE
} log_type_t;
typedef struct log_st
{
log_type_t type;
FILE *file;
} *log_t;
typedef struct log_facility_st
{
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);
typedef struct nad_st **nad_cache_t;
struct nad_elem_st
{
int parent;
int iname, lname;
int icdata, lcdata;
int itail, ltail;
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;
struct nad_elem_st *elems;
struct nad_attr_st *attrs;
struct nad_ns_st *nss;
char *cdata;
int *depths;
int elen, alen, nlen, clen, dlen;
int ecur, acur, ncur, ccur;
int scope;
struct nad_st *next;
} *nad_t;
nad_cache_t nad_cache_new(void);
void nad_cache_free(nad_cache_t cache);
nad_t nad_new(nad_cache_t cache);
nad_t nad_copy(nad_t nad);
void nad_free(nad_t nad);
int nad_find_elem(nad_t nad, int elem, int ns, const char *name, int depth);
int nad_find_attr(nad_t nad, int elem, int ns, const char *name, const char *val);
int nad_find_namespace(nad_t nad, int elem, const char *uri, const char *prefix);
int nad_find_scoped_namespace(nad_t nad, const char *uri, const char *prefix);
void nad_set_attr(nad_t nad, int elem, int ns, const char *name, const char *val, int vallen);
int nad_insert_elem(nad_t nad, int elem, int ns, const char *name, const char *cdata);
void nad_wrap_elem(nad_t nad, int elem, int ns, const char *name);
int nad_append_elem(nad_t nad, int ns, const char *name, int depth);
int nad_append_attr(nad_t nad, int ns, const char *name, const char *val);
void nad_append_cdata(nad_t nad, const char *cdata, int len, int depth);
int nad_add_namespace(nad_t nad, const char *uri, const char *prefix);
int nad_append_namespace(nad_t nad, int elem, const char *uri, const char *prefix);
void nad_print(nad_t nad, int elem, char **xml, int *len);
void nad_serialize(nad_t nad, char **buf, int *len);
nad_t nad_deserialize(nad_cache_t cache, const char *buf);
#ifdef HAVE_EXPAT
nad_t nad_parse(nad_cache_t cache, const char *buf, int len);
#endif
#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)
typedef struct config_elem_st *config_elem_t;
typedef struct config_st *config_t;
struct config_st
{
xht hash;
nad_cache_t nads;
nad_t nad;
};
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);
typedef struct access_rule_st
{
struct sockaddr_storage ip;
int mask;
} *access_rule_t;
typedef struct access_st
{
int order;
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);
typedef struct rate_st
{
int total;
int seconds;
int wait;
time_t time;
int count;
time_t bad;
} *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);
#include "inaddr.h"
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);
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);
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);
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);
extern char *b64_encode(char *buf, int len);
extern char *b64_decode(char *buf);
#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);
void hex_from_raw(char *in, int inlen, char *out);
int hex_to_raw(char *in, int inlen, char *out);
#include "xdata.h"
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
#ifdef DEBUG
#define log_debug if(get_debug_flag()) debug_log
#else
#define log_debug if(0) debug_log
#endif
typedef void jsighandler_t(int);
jsighandler_t* jabber_signal(int signo, jsighandler_t *func);
#ifdef __cplusplus
}
#endif
#endif