jabberd2  2.6.1
main.c
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 #include "sm.h"
22 #include <stringprep.h>
23 
31 static sig_atomic_t sm_shutdown = 0;
32 static sig_atomic_t sm_logrotate = 0;
33 static sm_t sm = NULL;
34 static char* config_file;
35 
36 static void _sm_signal(int signum)
37 {
38  sm_shutdown = 1;
39  sm_lost_router = 0;
40 }
41 
42 static void _sm_signal_hup(int signum)
43 {
44  sm_logrotate = 1;
45 }
46 
47 static void _sm_signal_usr1(int signum)
48 {
49  set_debug_flag(0);
50 }
51 
52 static void _sm_signal_usr2(int signum)
53 {
54  set_debug_flag(1);
55 }
56 
58 static void _sm_pidfile(sm_t sm) {
59  const char *pidfile;
60  FILE *f;
61  pid_t pid;
62 
63  pidfile = config_get_one(sm->config, "pidfile", 0);
64  if(pidfile == NULL)
65  return;
66 
67  pid = getpid();
68 
69  if((f = fopen(pidfile, "w+")) == NULL) {
70  log_write(sm->log, LOG_ERR, "couldn't open %s for writing: %s", pidfile, strerror(errno));
71  return;
72  }
73 
74  if(fprintf(f, "%d", pid) < 0) {
75  log_write(sm->log, LOG_ERR, "couldn't write to %s: %s", pidfile, strerror(errno));
76  fclose(f);
77  return;
78  }
79 
80  fclose(f);
81 
82  log_write(sm->log, LOG_INFO, "process id is %d, written to %s", pid, pidfile);
83 }
84 
86 static void _sm_config_expand(sm_t sm)
87 {
88  char *str;
89  config_elem_t elem;
90 
92 
93  sm->id = config_get_one(sm->config, "id", 0);
94  if(sm->id == NULL)
95  sm->id = "sm";
96 
97  sm->router_ip = config_get_one(sm->config, "router.ip", 0);
98  if(sm->router_ip == NULL)
99  sm->router_ip = "127.0.0.1";
100 
101  sm->router_port = j_atoi(config_get_one(sm->config, "router.port", 0), 5347);
102 
103  sm->router_user = config_get_one(sm->config, "router.user", 0);
104  if(sm->router_user == NULL)
105  sm->router_user = "jabberd";
106  sm->router_pass = config_get_one(sm->config, "router.pass", 0);
107  if(sm->router_pass == NULL)
108  sm->router_pass = "secret";
109 
110  sm->router_pemfile = config_get_one(sm->config, "router.pemfile", 0);
111 
112  sm->router_private_key_password = config_get_one(sm->config, "router.private_key_password", 0);
113  sm->router_ciphers = config_get_one(sm->config, "router.ciphers", 0);
114 
115  sm->retry_init = j_atoi(config_get_one(sm->config, "router.retry.init", 0), 3);
116  sm->retry_lost = j_atoi(config_get_one(sm->config, "router.retry.lost", 0), 3);
117  if((sm->retry_sleep = j_atoi(config_get_one(sm->config, "router.retry.sleep", 0), 2)) < 1)
118  sm->retry_sleep = 1;
119 
120  sm->log_type = log_STDOUT;
121  if(config_get(sm->config, "log") != NULL) {
122  if((str = config_get_attr(sm->config, "log", 0, "type")) != NULL) {
123  if(strcmp(str, "file") == 0)
124  sm->log_type = log_FILE;
125  else if(strcmp(str, "syslog") == 0)
126  sm->log_type = log_SYSLOG;
127  }
128  }
129 
130  if(sm->log_type == log_SYSLOG) {
131  sm->log_facility = config_get_one(sm->config, "log.facility", 0);
132  sm->log_ident = config_get_one(sm->config, "log.ident", 0);
133  if(sm->log_ident == NULL)
134  sm->log_ident = "jabberd/sm";
135  } else if(sm->log_type == log_FILE)
136  sm->log_ident = config_get_one(sm->config, "log.file", 0);
137 
138  elem = config_get(sm->config, "storage.limits.queries");
139  if(elem != NULL)
140  {
141  sm->query_rate_total = j_atoi(elem->values[0], 0);
142  if(sm->query_rate_total != 0)
143  {
144  sm->query_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 5);
145  sm->query_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 60);
146  }
147  }
148 }
149 
150 static void _sm_hosts_expand(sm_t sm)
151 {
152  config_elem_t elem;
153  char id[1024];
154  int i;
155 
156  elem = config_get(sm->config, "local.id");
157  if(!elem) {
158  /* use SM id */
159  xhash_put(sm->hosts, pstrdup(xhash_pool(sm->hosts), sm->id), sm);
160  log_write(sm->log, LOG_NOTICE, "id: %s", sm->id);
161  return;
162  }
163 
164  for(i = 0; i < elem->nvalues; i++) {
165  /* stringprep ids (domain names) so that they are in canonical form */
166  strncpy(id, elem->values[i], 1024);
167  id[1023] = '\0';
168  if (stringprep_nameprep(id, 1024) != 0) {
169  log_write(sm->log, LOG_ERR, "cannot stringprep id %s, aborting", id);
170  exit(1);
171  }
172 
173  /* insert into vHosts xhash */
174  xhash_put(sm->hosts, pstrdup(xhash_pool(sm->hosts), id), sm);
175 
176  log_write(sm->log, LOG_NOTICE, "[%s] configured", id);
177  }
178 }
179 
180 static int _sm_router_connect(sm_t sm) {
181  log_write(sm->log, LOG_NOTICE, "attempting connection to router at %s, port=%d", sm->router_ip, sm->router_port);
182 
183  sm->fd = mio_connect(sm->mio, sm->router_port, sm->router_ip, NULL, sm_mio_callback, (void *) sm);
184  if(sm->fd == NULL) {
185  if(errno == ECONNREFUSED)
186  sm_lost_router = 1;
187  log_write(sm->log, LOG_NOTICE, "connection attempt to router failed: %s (%d)", MIO_STRERROR(MIO_ERROR), MIO_ERROR);
188  return 1;
189  }
190 
191  sm->router = sx_new(sm->sx_env, sm->fd->fd, sm_sx_callback, (void *) sm);
192  sx_client_init(sm->router, 0, NULL, NULL, NULL, "1.0");
193 
194  return 0;
195 }
196 
197 JABBER_MAIN("jabberd2sm", "Jabber 2 Session Manager", "Jabber Open Source Server: Session Manager", "jabberd2router\0")
198 {
199  int optchar;
200  sess_t sess;
201  char id[1024];
202 #ifdef POOL_DEBUG
203  time_t pool_time = 0;
204 #endif
205  const char *cli_id = 0;
206 
207 #ifdef HAVE_UMASK
208  umask((mode_t) 0027);
209 #endif
210 
211  srand(time(NULL));
212 
213 #ifdef HAVE_WINSOCK2_H
214 /* get winsock running */
215  {
216  WORD wVersionRequested;
217  WSADATA wsaData;
218  int err;
219 
220  wVersionRequested = MAKEWORD( 2, 2 );
221 
222  err = WSAStartup( wVersionRequested, &wsaData );
223  if ( err != 0 ) {
224  /* !!! tell user that we couldn't find a usable winsock dll */
225  return 0;
226  }
227  }
228 #endif
229 
230  jabber_signal(SIGINT, _sm_signal);
231  jabber_signal(SIGTERM, _sm_signal);
232 #ifdef SIGHUP
233  jabber_signal(SIGHUP, _sm_signal_hup);
234 #endif
235 #ifdef SIGPIPE
236  jabber_signal(SIGPIPE, SIG_IGN);
237 #endif
238  jabber_signal(SIGUSR1, _sm_signal_usr1);
239  jabber_signal(SIGUSR2, _sm_signal_usr2);
240 
241 
242  sm = (sm_t) calloc(1, sizeof(struct sm_st));
243 
244  /* load our config */
245  sm->config = config_new();
246 
247  config_file = CONFIG_DIR "/sm.xml";
248 
249  /* cmdline parsing */
250  while((optchar = getopt(argc, argv, "Dc:hi:?")) >= 0)
251  {
252  switch(optchar)
253  {
254  case 'c':
255  config_file = optarg;
256  break;
257  case 'D':
258 #ifdef DEBUG
259  set_debug_flag(1);
260 #else
261  printf("WARN: Debugging not enabled. Ignoring -D.\n");
262 #endif
263  break;
264  case 'i':
265  cli_id = optarg;
266  break;
267  case 'h': case '?': default:
268  fputs(
269  "sm - jabberd session manager (" VERSION ")\n"
270  "Usage: sm <options>\n"
271  "Options are:\n"
272  " -c <config> config file to use [default: " CONFIG_DIR "/sm.xml]\n"
273  " -i id Override <id> config element\n"
274 #ifdef DEBUG
275  " -D Show debug output\n"
276 #endif
277  ,
278  stdout);
279  config_free(sm->config);
280  free(sm);
281  return 1;
282  }
283  }
284 
285  if(config_load_with_id(sm->config, config_file, cli_id) != 0)
286  {
287  fputs("sm: couldn't load config, aborting\n", stderr);
288  config_free(sm->config);
289  free(sm);
290  return 2;
291  }
292 
293  _sm_config_expand(sm);
294 
295  sm->log = log_new(sm->log_type, sm->log_ident, sm->log_facility);
296  log_write(sm->log, LOG_NOTICE, "starting up");
297 
298  /* stringprep id (domain name) so that it's in canonical form */
299  strncpy(id, sm->id, 1024);
300  id[sizeof(id)-1] = '\0';
301  if (stringprep_nameprep(id, 1024) != 0) {
302  log_write(sm->log, LOG_ERR, "cannot stringprep id %s, aborting", sm->id);
303  exit(1);
304  }
305  sm->id = id;
306 
307  _sm_pidfile(sm);
308 
309  sm_signature(sm, PACKAGE " sm " VERSION);
310 
311  /* start storage */
312  sm->st = storage_new(sm->config, sm->log);
313  if (sm->st == NULL) {
314  log_write(sm->log, LOG_ERR, "failed to initialise one or more storage drivers, aborting");
315  exit(1);
316  }
317 
318  /* pre-index known namespaces */
319  sm->xmlns = xhash_new(101);
320  xhash_put(sm->xmlns, uri_AUTH, (void *) ns_AUTH);
321  xhash_put(sm->xmlns, uri_REGISTER, (void *) ns_REGISTER);
322  xhash_put(sm->xmlns, uri_ROSTER, (void *) ns_ROSTER);
323  xhash_put(sm->xmlns, uri_AGENTS, (void *) ns_AGENTS);
324  xhash_put(sm->xmlns, uri_DELAY, (void *) ns_DELAY);
325  xhash_put(sm->xmlns, uri_BROWSE, (void *) ns_BROWSE);
326  xhash_put(sm->xmlns, uri_EVENT, (void *) ns_EVENT);
327  xhash_put(sm->xmlns, uri_GATEWAY, (void *) ns_GATEWAY);
328  xhash_put(sm->xmlns, uri_EXPIRE, (void *) ns_EXPIRE);
329  xhash_put(sm->xmlns, uri_SEARCH, (void *) ns_SEARCH);
330  xhash_put(sm->xmlns, uri_DISCO, (void *) ns_DISCO);
333  sm->xmlns_refcount = xhash_new(101);
334 
335  /* supported features */
336  sm->features = xhash_new(101);
337 
338  /* load acls */
339  sm->acls = aci_load(sm);
340 
341  /* the core supports iq, everything else is handled by the modules */
342  feature_register(sm, "iq");
343 
344  /* startup the modules */
345  sm->mm = mm_new(sm);
346 
347  log_write(sm->log, LOG_NOTICE, "version: %s", sm->signature);
348 
349  sm->sessions = xhash_new(401);
350 
351  sm->users = xhash_new(401);
352 
353  sm->query_rates = xhash_new(101);
354 
355  sm->sx_env = sx_env_new();
356 
357 #ifdef HAVE_SSL
358  if(sm->router_pemfile != NULL) {
360  if(sm->sx_ssl == NULL) {
361  log_write(sm->log, LOG_ERR, "failed to load SSL pemfile, SSL disabled");
362  sm->router_pemfile = NULL;
363  }
364  }
365 #endif
366 
367  /* get sasl online */
368  sm->sx_sasl = sx_env_plugin(sm->sx_env, sx_sasl_init, "xmpp", NULL, NULL);
369  if(sm->sx_sasl == NULL) {
370  log_write(sm->log, LOG_ERR, "failed to initialise SASL context, aborting");
371  exit(1);
372  }
373 
374  sm->mio = mio_new(MIO_MAXFD);
375 
376  /* vHosts map */
377  sm->hosts = xhash_new(1021);
378  _sm_hosts_expand(sm);
379 
380  sm->retry_left = sm->retry_init;
381  _sm_router_connect(sm);
382 
383  while(!sm_shutdown) {
384  mio_run(sm->mio, 5);
385 
386  if(sm_logrotate) {
388 
389  log_write(sm->log, LOG_NOTICE, "reopening log ...");
390  log_free(sm->log);
391  sm->log = log_new(sm->log_type, sm->log_ident, sm->log_facility);
392  log_write(sm->log, LOG_NOTICE, "log started");
393 
394  sm_logrotate = 0;
395  }
396 
397  if(sm_lost_router) {
398  if(sm->retry_left < 0) {
399  log_write(sm->log, LOG_NOTICE, "attempting reconnect");
400  sleep(sm->retry_sleep);
401  sm_lost_router = 0;
402  if (sm->router) sx_free(sm->router);
403  _sm_router_connect(sm);
404  }
405 
406  else if(sm->retry_left == 0) {
407  sm_shutdown = 1;
408  }
409 
410  else {
411  log_write(sm->log, LOG_NOTICE, "attempting reconnect (%d left)", sm->retry_left);
412  sm->retry_left--;
413  sleep(sm->retry_sleep);
414  sm_lost_router = 0;
415  if (sm->router) sx_free(sm->router);
416  _sm_router_connect(sm);
417  }
418  }
419 
420 #ifdef POOL_DEBUG
421  if(time(NULL) > pool_time + 60) {
422  pool_stat(1);
423  pool_time = time(NULL);
424  }
425 #endif
426  }
427 
428  log_write(sm->log, LOG_NOTICE, "shutting down");
429 
430  /* shut down sessions */
431  if(xhash_iter_first(sm->sessions))
432  do {
433  xhash_iter_get(sm->sessions, NULL, NULL, (void *) &sess);
434  sm_c2s_action(sess, "ended", NULL);
435  sess_end(sess);
436  } while (xhash_iter_next(sm->sessions));
437 
438  xhash_free(sm->sessions);
439 
440  if (sm->fd) mio_close(sm->mio, sm->fd);
441  mio_free(sm->mio);
442 
443  mm_free(sm->mm);
444  storage_free(sm->st);
445 
446  aci_unload(sm->acls);
447  xhash_free(sm->acls);
448  xhash_free(sm->features);
449  xhash_free(sm->xmlns);
451  xhash_free(sm->users);
452  xhash_free(sm->hosts);
453  xhash_free(sm->query_rates);
454 
455  sx_free(sm->router);
456 
457  sx_env_free(sm->sx_env);
458 
459  log_free(sm->log);
460 
461  config_free(sm->config);
462 
463  free(sm);
464 
465 #ifdef POOL_DEBUG
466  pool_stat(1);
467 #endif
468 
469 #ifdef HAVE_WINSOCK2_H
470  WSACleanup();
471 #endif
472 
473  return 0;
474 }
const char * log_facility
syslog facility (local0 - local7)
Definition: sm.h:203
static sm_t sm
Definition: main.c:33
xht query_rates
Definition: sm.h:230
data structures and prototypes for the session manager
int retry_init
number of times to try connecting to the router at startup
Definition: sm.h:206
#define ns_DISCO_INFO
Definition: sm.h:81
#define uri_BROWSE
Definition: uri.h:70
#define ns_GATEWAY
Definition: sm.h:76
const char ** values
Definition: util.h:209
#define uri_DISCO
Definition: uri.h:79
int query_rate_seconds
Definition: sm.h:228
#define ns_EXPIRE
Definition: sm.h:77
int config_load_with_id(config_t c, const char *file, const char *id)
turn an xml file into a config hash
Definition: config.c:80
const char * id
component id
Definition: sm.h:168
#define ns_DISCO_ITEMS
Definition: sm.h:80
void xhash_free(xht h)
Definition: xhash.c:241
static sig_atomic_t sm_shutdown
Definition: main.c:31
xht aci_load(router_t r)
Definition: aci.c:31
static void _sm_signal_usr1(int signum)
Definition: main.c:47
void config_free(config_t c)
cleanup
Definition: config.c:411
#define uri_AUTH
Definition: uri.h:61
log_t log
log context
Definition: sm.h:200
mio_t mio_new(int maxfd)
create/free the mio subsytem
Definition: mio.c:38
#define mio_run(m, timeout)
give some cpu time to mio to check it&#39;s sockets, 0 is non-blocking
Definition: mio.h:164
static void _sm_signal(int signum)
Definition: main.c:36
config_t config
config context
Definition: sm.h:198
void log_write(log_t log, int level, const char *msgfmt,...)
Definition: log.c:104
mm_t mm
module subsystem
Definition: sm.h:213
xht hosts
vHosts map
Definition: sm.h:224
void sm_c2s_action(sess_t dest, const char *action, const char *target)
send a new action route
Definition: sm.c:280
sx_t sx_new(sx_env_t env, int tag, sx_callback_t cb, void *arg)
if you change these, reflect your changes in the table in error.c
Definition: sx.c:23
config_t config_new(void)
new config structure
Definition: config.c:25
#define MIO_STRERROR(e)
Definition: mio.h:170
static void _sm_hosts_expand(sm_t sm)
Definition: main.c:150
#define mio_free(m)
Definition: mio.h:137
static char * config_file
Definition: main.c:34
int j_atoi(const char *a, int def)
Definition: str.c:87
void log_free(log_t log)
Definition: log.c:174
int xhash_iter_next(xht h)
Definition: xhash.c:320
static void _sm_pidfile(sm_t sm)
store the process id
Definition: main.c:58
mm_t mm_new(sm_t sm)
allocate a module manager instance, and loads the modules
Definition: mm.c:47
xht sessions
pointers to all connected sessions (key is random sm id)
Definition: sm.h:191
sx_env_t sx_env_new(void)
Definition: env.c:23
#define mio_connect(m, port, hostip, srcip, app, arg)
for creating a new socket connected to this ip:port (returns new fd or <0, use mio_read/write first) ...
Definition: mio.h:144
sx_plugin_t sx_ssl
SX SSL plugin.
Definition: sm.h:184
xht users
pointers to currently loaded users (key is user@domain)
Definition: sm.h:189
static void _sm_signal_hup(int signum)
Definition: main.c:42
char * config_get_attr(config_t c, const char *key, int num, const char *attr)
get an attr for this value
Definition: config.c:315
Definition: log.h:42
#define MIO_ERROR
all MIO related routines should use those for error reporting
Definition: mio.h:168
static void _sm_config_expand(sm_t sm)
pull values out of the config file
Definition: main.c:86
#define ns_ROSTER
Definition: sm.h:71
int retry_left
number of tries left before failure
Definition: sm.h:209
void sess_end(sess_t sess)
Definition: sess.c:85
#define ns_REGISTER
Definition: sm.h:70
sx_plugin_t sx_env_plugin(sx_env_t env, sx_plugin_init_t init,...)
load a plugin into the environment
Definition: env.c:48
sx_t router
SX of router connection.
Definition: sm.h:186
xht xmlns_refcount
ref-counting for modules namespaces
Definition: sm.h:194
void sx_client_init(sx_t s, unsigned int flags, const char *ns, const char *to, const char *from, const char *version)
Definition: client.c:111
int sm_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg)
Definition: sm.c:241
#define uri_ROSTER
Definition: uri.h:63
void set_debug_log_from_config(config_t c)
Definition: log.c:267
storage_t st
storage subsystem
Definition: sm.h:211
session manager global context
Definition: sm.h:167
void pool_stat(int full)
Definition: pool.c:285
void xhash_put(xht h, const char *key, void *val)
Definition: xhash.c:163
const char * router_ciphers
password for private key if pemfile key is encrypted
Definition: sm.h:178
static sig_atomic_t sm_logrotate
Definition: main.c:32
int sm_sx_callback(sx_t s, sx_event_t e, void *data, void *arg)
our master callback
Definition: sm.c:33
log_type_t log_type
log type
Definition: sm.h:202
const char * router_private_key_password
Definition: sm.h:176
#define uri_AGENTS
Definition: uri.h:64
void mm_free(mm_t mm)
free a mm instance
Definition: mm.c:294
#define ns_DISCO
Definition: sm.h:79
int xhash_iter_get(xht h, const char **key, int *keylen, void **val)
Definition: xhash.c:374
#define uri_REGISTER
Definition: uri.h:62
void sm_signature(sm_t sm, const char *str)
this is gratuitous, but apache gets one, so why not?
Definition: sm.c:313
void sx_free(sx_t s)
Definition: sx.c:70
struct sm_st * sm_t
Definition: sm.h:59
JABBER_MAIN("jabberd2c2s", "Jabber 2 C2S", "Jabber Open Source Server: Client to Server", "jabberd2router\)
Definition: main.c:657
const char * log_ident
log identifier
Definition: sm.h:204
jsighandler_t * jabber_signal(int signo, jsighandler_t *func)
Definition: jsignal.c:33
const char * router_user
username to authenticate to the router as
Definition: sm.h:172
void feature_register(sm_t sm, const char *feature)
register a feature
Definition: feature.c:37
const char * router_pass
password to authenticate to the router with
Definition: sm.h:173
#define uri_SEARCH
Definition: uri.h:77
sx_env_t sx_env
SX environment.
Definition: sm.h:182
#define uri_GATEWAY
Definition: uri.h:72
int retry_lost
number of times to try reconnecting to the router if the connection drops
Definition: sm.h:207
JABBERD2_API int sx_sasl_init(sx_env_t env, sx_plugin_t p, va_list args)
init function
Definition: sasl.c:881
config_elem_t config_get(config_t c, const char *key)
get the config element for this key
Definition: config.c:272
There is one instance of this struct per user who is logged in to this c2s instance.
Definition: c2s.h:74
char signature[2048]
server signature
Definition: sm.h:217
#define uri_DELAY
Definition: uri.h:65
const char * router_ip
ip to connect to the router at
Definition: sm.h:170
#define ns_EVENT
Definition: sm.h:75
int xhash_iter_first(xht h)
iteration
Definition: xhash.c:311
mio_fd_t fd
file descriptor of router connection
Definition: sm.h:187
static void _sm_signal_usr2(int signum)
Definition: main.c:52
const char * router_pemfile
name of file containing a SSL certificate & key for channel to the router
Definition: sm.h:174
void set_debug_flag(int v)
Definition: log.c:264
mio_t mio
TLS ciphers.
Definition: sm.h:180
int sx_ssl_init(sx_env_t env, sx_plugin_t p, va_list args)
args: name, pemfile, cachain, mode
Definition: ssl.c:905
sig_atomic_t sm_lost_router
Definition: sm.c:30
int query_rate_wait
Definition: sm.h:229
const char *** attrs
Definition: util.h:211
pool_t xhash_pool(xht h)
get our pool
Definition: xhash.c:305
int retry_sleep
sleep interval between retries
Definition: sm.h:208
char * pstrdup(pool_t p, const char *src)
XXX efficient: move this to const char * and then loop throug the existing heaps to see if src is wit...
Definition: pool.c:191
Definition: log.h:43
#define MIO_MAXFD
Definition: mio.h:46
#define ns_AUTH
Definition: sm.h:69
Definition: log.h:44
#define mio_close(m, fd)
request that mio close this fd
Definition: mio.h:155
xht acls
access control lists (key is list name, value is jid_t list)
Definition: sm.h:215
char * j_attr(const char **atts, const char *attr)
Definition: str.c:95
log_t log_new(log_type_t type, const char *ident, const char *facility)
Definition: log.c:69
const char * config_get_one(config_t c, const char *key, int num)
get config value n for this key
Definition: config.c:278
xht xmlns
index of namespaces (for iq sub-namespace in pkt_t)
Definition: sm.h:193
xht xhash_new(int prime)
Definition: xhash.c:96
#define uri_DISCO_INFO
Definition: uri.h:81
int query_rate_total
Database query rate limits.
Definition: sm.h:227
#define uri_DISCO_ITEMS
Definition: uri.h:80
#define uri_EXPIRE
Definition: uri.h:73
void sx_env_free(sx_env_t env)
Definition: env.c:31
#define uri_EVENT
Definition: uri.h:71
a single element
Definition: util.h:207
#define ns_AGENTS
Definition: sm.h:72
#define ns_DELAY
Definition: sm.h:73
int router_port
port to connect to the router at
Definition: sm.h:171
#define ns_BROWSE
Definition: sm.h:74
#define ns_SEARCH
Definition: sm.h:78
int nvalues
Definition: util.h:210
sx_plugin_t sx_sasl
SX SASL plugin.
Definition: sm.h:183
static int _sm_router_connect(sm_t sm)
Definition: main.c:180
void aci_unload(xht aci)
unload aci table
Definition: aci.c:114
xht features
feature index (key is feature string
Definition: sm.h:196