jabberd2
2.2.16
|
00001 /* 00002 * jabberd - Jabber Open Source Server 00003 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, 00004 * Ryan Eatmon, Robert Norris 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA 00019 */ 00020 00021 #include "sm.h" 00022 00023 #ifdef _WIN32 00024 # define LIBRARY_DIR "." 00025 # include <windows.h> 00026 #else 00027 # include <dlfcn.h> 00028 #endif /* _WIN32 */ 00029 00037 /* these functions implement a multiplexor to get calls to the correct module 00038 * for the given type */ 00039 00040 /* Notes on dynamic modules (cedricv@) : 00041 Modules are searched by name mod_[modulename].so or mod_[modulename].dll 00042 depending platform. 00043 You have to set <path>[full_path]</path> within <modules> in sm.xml config, 00044 else it will only search in LD_LIBRARY_PATH or c:\windows\system32 00045 */ 00046 00047 mm_t mm_new(sm_t sm) { 00048 mm_t mm; 00049 int celem, melem, attr, *nlist = NULL; 00050 char id[13], name[32], mod_fullpath[PATH_MAX], arg[1024], *modules_path; 00051 mod_chain_t chain = (mod_chain_t) NULL; 00052 mod_instance_t **list = NULL, mi; 00053 module_t mod; 00054 00055 mm = (mm_t) calloc(1, sizeof(struct mm_st)); 00056 00057 mm->sm = sm; 00058 mm->modules = xhash_new(101); 00059 00060 if((celem = nad_find_elem(sm->config->nad, 0, -1, "modules", 1)) < 0) 00061 return mm; 00062 00063 modules_path = config_get_one(sm->config, "modules.path", 0); 00064 if (modules_path != NULL) 00065 log_write(sm->log, LOG_NOTICE, "modules search path: %s", modules_path); 00066 else 00067 log_write(sm->log, LOG_NOTICE, "modules search path undefined, using deafult: "LIBRARY_DIR); 00068 00069 celem = nad_find_elem(sm->config->nad, celem, -1, "chain", 1); 00070 while(celem >= 0) { 00071 if((attr = nad_find_attr(sm->config->nad, celem, -1, "id", NULL)) < 0) { 00072 celem = nad_find_elem(sm->config->nad, celem, -1, "chain", 0); 00073 continue; 00074 } 00075 00076 snprintf(id, 13, "%.*s", NAD_AVAL_L(sm->config->nad, attr), NAD_AVAL(sm->config->nad, attr)); 00077 id[12] = '\0'; 00078 00079 log_debug(ZONE, "processing config for chain '%s'", id); 00080 00081 list = NULL; 00082 if(strcmp(id, "sess-start") == 0) { 00083 chain = chain_SESS_START; 00084 list = &mm->sess_start; 00085 nlist = &mm->nsess_start; 00086 } 00087 else if(strcmp(id, "sess-end") == 0) { 00088 chain = chain_SESS_END; 00089 list = &mm->sess_end; 00090 nlist = &mm->nsess_end; 00091 } 00092 else if(strcmp(id, "in-sess") == 0) { 00093 chain = chain_IN_SESS; 00094 list = &mm->in_sess; 00095 nlist = &mm->nin_sess; 00096 } 00097 else if(strcmp(id, "in-router") == 0) { 00098 chain = chain_IN_ROUTER; 00099 list = &mm->in_router; 00100 nlist = &mm->nin_router; 00101 } 00102 else if(strcmp(id, "out-sess") == 0) { 00103 chain = chain_OUT_SESS; 00104 list = &mm->out_sess; 00105 nlist = &mm->nout_sess; 00106 } 00107 else if(strcmp(id, "out-router") == 0) { 00108 chain = chain_OUT_ROUTER; 00109 list = &mm->out_router; 00110 nlist = &mm->nout_router; 00111 } 00112 else if(strcmp(id, "pkt-sm") == 0) { 00113 chain = chain_PKT_SM; 00114 list = &mm->pkt_sm; 00115 nlist = &mm->npkt_sm; 00116 } 00117 else if(strcmp(id, "pkt-user") == 0) { 00118 chain = chain_PKT_USER; 00119 list = &mm->pkt_user; 00120 nlist = &mm->npkt_user; 00121 } 00122 else if(strcmp(id, "pkt-router") == 0) { 00123 chain = chain_PKT_ROUTER; 00124 list = &mm->pkt_router; 00125 nlist = &mm->npkt_router; 00126 } 00127 else if(strcmp(id, "user-load") == 0) { 00128 chain = chain_USER_LOAD; 00129 list = &mm->user_load; 00130 nlist = &mm->nuser_load; 00131 } 00132 else if(strcmp(id, "user-unload") == 0) { 00133 chain = chain_USER_UNLOAD; 00134 list = &mm->user_unload; 00135 nlist = &mm->nuser_unload; 00136 } 00137 else if(strcmp(id, "user-create") == 0) { 00138 chain = chain_USER_CREATE; 00139 list = &mm->user_create; 00140 nlist = &mm->nuser_create; 00141 } 00142 else if(strcmp(id, "user-delete") == 0) { 00143 chain = chain_USER_DELETE; 00144 list = &mm->user_delete; 00145 nlist = &mm->nuser_delete; 00146 } 00147 else if(strcmp(id, "disco-extend") == 0) { 00148 chain = chain_DISCO_EXTEND; 00149 list = &mm->disco_extend; 00150 nlist = &mm->ndisco_extend; 00151 } 00152 00153 if(list == NULL) { 00154 log_write(sm->log, LOG_ERR, "unknown chain type '%s'", id); 00155 00156 celem = nad_find_elem(sm->config->nad, celem, -1, "chain", 0); 00157 continue; 00158 } 00159 00160 melem = nad_find_elem(sm->config->nad, celem, -1, "module", 1); 00161 while(melem >= 0) { 00162 if(NAD_CDATA_L(sm->config->nad, melem) <= 0) { 00163 melem = nad_find_elem(sm->config->nad, melem, -1, "module", 0); 00164 continue; 00165 } 00166 00167 arg[0] = '\0'; 00168 attr = nad_find_attr(sm->config->nad, melem, -1, "arg", NULL); 00169 if(attr >= 0) { 00170 snprintf(arg, 1024, "%.*s", NAD_AVAL_L(sm->config->nad, attr), NAD_AVAL(sm->config->nad, attr)); 00171 log_debug(ZONE, "module arg: %s", arg); 00172 } 00173 00174 snprintf(name, 32, "%.*s", NAD_CDATA_L(sm->config->nad, melem), NAD_CDATA(sm->config->nad, melem)); 00175 00176 mod = xhash_get(mm->modules, name); 00177 if(mod == NULL) { 00178 mod = (module_t) calloc(1, sizeof(struct module_st)); 00179 00180 mod->mm = mm; 00181 mod->index = mm->nindex; 00182 mod->name = strdup(name); 00183 #ifndef _WIN32 00184 if (modules_path != NULL) 00185 snprintf(mod_fullpath, PATH_MAX, "%s/mod_%s.so", modules_path, name); 00186 else 00187 snprintf(mod_fullpath, PATH_MAX, "%s/mod_%s.so", LIBRARY_DIR, name); 00188 mod->handle = dlopen(mod_fullpath, RTLD_LAZY); 00189 if (mod->handle != NULL) 00190 mod->module_init_fn = dlsym(mod->handle, "module_init"); 00191 #else 00192 if (modules_path != NULL) 00193 snprintf(mod_fullpath, PATH_MAX, "%s\\mod_%s.dll", modules_path, name); 00194 else 00195 snprintf(mod_fullpath, PATH_MAX, "mod_%s.dll", name); 00196 mod->handle = (void*) LoadLibrary(mod_fullpath); 00197 if (mod->handle != NULL) 00198 mod->module_init_fn = (int (*)(mod_instance_t))GetProcAddress((HMODULE) mod->handle, "module_init"); 00199 #endif 00200 00201 if (mod->handle != NULL && mod->module_init_fn != NULL) { 00202 log_debug(ZONE, "preloaded module '%s' to chain '%s' (not added yet)", name, id); 00203 xhash_put(mm->modules, mod->name, (void *) mod); 00204 mm->nindex++; 00205 } else { 00206 #ifndef _WIN32 00207 log_write(sm->log, LOG_ERR, "failed loading module '%s' to chain '%s' (%s)", name, id, dlerror()); 00208 if (mod->handle != NULL) 00209 dlclose(mod->handle); 00210 #else 00211 log_write(sm->log, LOG_ERR, "failed loading module '%s' to chain '%s' (errcode: %x)", name, id, GetLastError()); 00212 if (mod->handle != NULL) 00213 FreeLibrary((HMODULE) mod->handle); 00214 #endif 00215 00216 melem = nad_find_elem(sm->config->nad, melem, -1, "module", 0); 00217 continue; 00218 } 00219 } 00220 00221 mi = (mod_instance_t) calloc(1, sizeof(struct mod_instance_st)); 00222 00223 mi->sm = sm; 00224 mi->mod = mod; 00225 mi->chain = chain; 00226 mi->arg = (arg[0] == '\0') ? NULL : strdup(arg); 00227 mi->seq = mod->init; 00228 00229 if(mod->module_init_fn(mi) != 0) { 00230 log_write(sm->log, LOG_ERR, "init for module '%s' (seq %d) failed", name, mi->seq); 00231 free(mi); 00232 00233 if(mod->init == 0) { 00234 xhash_zap(mm->modules, mod->name); 00235 00236 #ifndef _WIN32 00237 if (mod->handle != NULL) 00238 dlclose(mod->handle); 00239 #else 00240 if (mod->handle != NULL) 00241 FreeLibrary((HMODULE) mod->handle); 00242 #endif 00243 00244 free(mod->name); 00245 free(mod); 00246 00247 mm->nindex--; 00248 00249 melem = nad_find_elem(sm->config->nad, melem, -1, "module", 0); 00250 continue; 00251 } 00252 } 00253 00254 mod->init++; 00255 00256 *list = (mod_instance_t *) realloc(*list, sizeof(mod_instance_t) * (*nlist + 1)); 00257 (*list)[*nlist] = mi; 00258 00259 log_write(sm->log, LOG_NOTICE, "module '%s' added to chain '%s' (order %d index %d seq %d)", mod->name, id, *nlist, mod->index, mi->seq); 00260 00261 (*nlist)++; 00262 00263 melem = nad_find_elem(sm->config->nad, melem, -1, "module", 0); 00264 } 00265 00266 celem = nad_find_elem(sm->config->nad, celem, -1, "chain", 0); 00267 } 00268 00269 return mm; 00270 } 00271 00272 static void _mm_reaper(const char *module, int modulelen, void *val, void *arg) { 00273 module_t mod = (module_t) val; 00274 00275 if(mod->free != NULL) 00276 (mod->free)(mod); 00277 00278 #ifndef _WIN32 00279 if (mod->handle != NULL) 00280 dlclose(mod->handle); 00281 #else 00282 if (mod->handle != NULL) 00283 FreeLibrary((HMODULE) mod->handle); 00284 #endif 00285 00286 free(mod->name); 00287 free(mod); 00288 } 00289 00290 void mm_free(mm_t mm) { 00291 int i, j, *nlist = NULL; 00292 mod_instance_t **list = NULL, mi; 00293 00294 /* close down modules */ 00295 xhash_walk(mm->modules, _mm_reaper, NULL); 00296 00297 /* free instances */ 00298 for(i = 0; i < 13; i++) { 00299 switch(i) { 00300 case 0: 00301 list = &mm->sess_start; 00302 nlist = &mm->nsess_start; 00303 break; 00304 case 1: 00305 list = &mm->sess_end; 00306 nlist = &mm->nsess_end; 00307 break; 00308 case 2: 00309 list = &mm->in_sess; 00310 nlist = &mm->nin_sess; 00311 break; 00312 case 3: 00313 list = &mm->in_router; 00314 nlist = &mm->nin_router; 00315 break; 00316 case 4: 00317 list = &mm->out_sess; 00318 nlist = &mm->nout_sess; 00319 break; 00320 case 5: 00321 list = &mm->out_router; 00322 nlist = &mm->nout_router; 00323 break; 00324 case 6: 00325 list = &mm->pkt_sm; 00326 nlist = &mm->npkt_sm; 00327 break; 00328 case 7: 00329 list = &mm->pkt_user; 00330 nlist = &mm->npkt_user; 00331 break; 00332 case 8: 00333 list = &mm->pkt_router; 00334 nlist = &mm->npkt_router; 00335 break; 00336 case 9: 00337 list = &mm->user_load; 00338 nlist = &mm->nuser_load; 00339 break; 00340 case 10: 00341 list = &mm->user_create; 00342 nlist = &mm->nuser_create; 00343 break; 00344 case 11: 00345 list = &mm->user_delete; 00346 nlist = &mm->nuser_delete; 00347 break; 00348 case 12: 00349 list = &mm->disco_extend; 00350 nlist = &mm->ndisco_extend; 00351 break; 00352 } 00353 00354 for(j = 0; j < *nlist; j++) { 00355 mi = (*list)[j]; 00356 if(mi->arg != NULL) 00357 free(mi->arg); 00358 free(mi); 00359 } 00360 } 00361 00362 /* free lists */ 00363 free(mm->sess_start); 00364 free(mm->sess_end); 00365 free(mm->in_sess); 00366 free(mm->in_router); 00367 free(mm->out_sess); 00368 free(mm->out_router); 00369 free(mm->pkt_sm); 00370 free(mm->pkt_user); 00371 free(mm->pkt_router); 00372 free(mm->user_load); 00373 free(mm->user_create); 00374 free(mm->user_delete); 00375 free(mm->disco_extend); 00376 00377 xhash_free(mm->modules); 00378 00379 free(mm); 00380 } 00381 00383 int mm_sess_start(mm_t mm, sess_t sess) { 00384 int n, ret = 0; 00385 mod_instance_t mi; 00386 00387 log_debug(ZONE, "dispatching sess-start chain"); 00388 00389 ret = 0; 00390 for(n = 0; n < mm->nsess_start; n++) { 00391 mi = mm->sess_start[n]; 00392 if(mi == NULL) { 00393 log_debug(ZONE, "module at index %d is not loaded yet", n); 00394 continue; 00395 } 00396 if(mi->mod->sess_start == NULL) { 00397 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00398 continue; 00399 } 00400 00401 log_debug(ZONE, "calling module %s", mi->mod->name); 00402 00403 ret = (mi->mod->sess_start)(mi, sess); 00404 if(ret != 0) 00405 break; 00406 } 00407 00408 log_debug(ZONE, "sess-start chain returning %d", ret); 00409 00410 return ret; 00411 } 00412 00414 void mm_sess_end(mm_t mm, sess_t sess) { 00415 int n; 00416 mod_instance_t mi; 00417 00418 log_debug(ZONE, "dispatching sess-end chain"); 00419 00420 for(n = 0; n < mm->nsess_end; n++) { 00421 mi = mm->sess_end[n]; 00422 if(mi == NULL) { 00423 log_debug(ZONE, "module at index %d is not loaded yet", n); 00424 continue; 00425 } 00426 if(mi->mod->sess_end == NULL) { 00427 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00428 continue; 00429 } 00430 00431 log_debug(ZONE, "calling module %s", mi->mod->name); 00432 00433 (mi->mod->sess_end)(mi, sess); 00434 } 00435 00436 log_debug(ZONE, "sess-end chain returning"); 00437 } 00438 00440 mod_ret_t mm_in_sess(mm_t mm, sess_t sess, pkt_t pkt) { 00441 int n; 00442 mod_instance_t mi; 00443 mod_ret_t ret = mod_PASS; 00444 00445 log_debug(ZONE, "dispatching in-sess chain"); 00446 00447 ret = mod_PASS; 00448 for(n = 0; n < mm->nin_sess; n++) { 00449 mi = mm->in_sess[n]; 00450 if(mi == NULL) { 00451 log_debug(ZONE, "module at index %d is not loaded yet", n); 00452 continue; 00453 } 00454 if(mi->mod->in_sess == NULL) { 00455 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00456 continue; 00457 } 00458 00459 log_debug(ZONE, "calling module %s", mi->mod->name); 00460 00461 ret = (mi->mod->in_sess)(mi, sess, pkt); 00462 if(ret != mod_PASS) 00463 break; 00464 } 00465 00466 log_debug(ZONE, "in-sess chain returning %d", ret); 00467 00468 return ret; 00469 } 00470 00472 mod_ret_t mm_in_router(mm_t mm, pkt_t pkt) { 00473 int n; 00474 mod_instance_t mi; 00475 mod_ret_t ret = mod_PASS; 00476 00477 log_debug(ZONE, "dispatching in-router chain"); 00478 00479 if (mm != NULL && pkt != NULL ) 00480 for(n = 0; n < mm->nin_router; n++) { 00481 mi = mm->in_router[n]; 00482 if(mi == NULL) { 00483 log_debug(ZONE, "module at index %d is not loaded yet", n); 00484 continue; 00485 } 00486 if(mi->mod == NULL || mi->mod->in_router == NULL) { 00487 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00488 continue; 00489 } 00490 00491 log_debug(ZONE, "calling module %s", mi->mod->name); 00492 00493 ret = (mi->mod->in_router)(mi, pkt); 00494 if(ret != mod_PASS) 00495 break; 00496 } 00497 00498 log_debug(ZONE, "in-router chain returning %d", ret); 00499 00500 return ret; 00501 } 00502 00504 mod_ret_t mm_out_sess(mm_t mm, sess_t sess, pkt_t pkt) { 00505 int n; 00506 mod_instance_t mi; 00507 mod_ret_t ret = mod_PASS; 00508 00509 log_debug(ZONE, "dispatching out-sess chain"); 00510 00511 for(n = 0; n < mm->nout_sess; n++) { 00512 mi = mm->out_sess[n]; 00513 if(mi == NULL) { 00514 log_debug(ZONE, "module at index %d is not loaded yet", n); 00515 continue; 00516 } 00517 if(mi->mod->out_sess == NULL) { 00518 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00519 continue; 00520 } 00521 00522 log_debug(ZONE, "calling module %s", mi->mod->name); 00523 00524 ret = (mi->mod->out_sess)(mi, sess, pkt); 00525 if(ret != mod_PASS) 00526 break; 00527 } 00528 00529 log_debug(ZONE, "out-sess chain returning %d", ret); 00530 00531 return ret; 00532 } 00533 00535 mod_ret_t mm_out_router(mm_t mm, pkt_t pkt) { 00536 int n; 00537 mod_instance_t mi; 00538 mod_ret_t ret = mod_PASS; 00539 00540 log_debug(ZONE, "dispatching out-router chain"); 00541 00542 for(n = 0; n < mm->nout_router; n++) { 00543 mi = mm->out_router[n]; 00544 if(mi == NULL) { 00545 log_debug(ZONE, "module at index %d is not loaded yet", n); 00546 continue; 00547 } 00548 if(mi->mod->out_router == NULL) { 00549 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00550 continue; 00551 } 00552 00553 log_debug(ZONE, "calling module %s", mi->mod->name); 00554 00555 ret = (mi->mod->out_router)(mi, pkt); 00556 if(ret != mod_PASS) 00557 break; 00558 } 00559 00560 log_debug(ZONE, "out-router chain returning %d", ret); 00561 00562 return ret; 00563 } 00564 00566 mod_ret_t mm_pkt_sm(mm_t mm, pkt_t pkt) { 00567 int n, ret = 0; 00568 mod_instance_t mi; 00569 00570 log_debug(ZONE, "dispatching pkt-sm chain"); 00571 00572 for(n = 0; n < mm->npkt_sm; n++) { 00573 mi = mm->pkt_sm[n]; 00574 if(mi == NULL) { 00575 log_debug(ZONE, "module at index %d is not loaded yet", n); 00576 continue; 00577 } 00578 if(mi->mod->pkt_sm == NULL) { 00579 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00580 continue; 00581 } 00582 00583 log_debug(ZONE, "calling module %s", mi->mod->name); 00584 00585 ret = (mi->mod->pkt_sm)(mi, pkt); 00586 if(ret != mod_PASS) 00587 break; 00588 } 00589 00590 log_debug(ZONE, "pkt-sm chain returning %d", ret); 00591 00592 return ret; 00593 } 00594 00596 mod_ret_t mm_pkt_user(mm_t mm, user_t user, pkt_t pkt) { 00597 int n; 00598 mod_instance_t mi; 00599 mod_ret_t ret = mod_PASS; 00600 00601 log_debug(ZONE, "dispatching pkt-user chain"); 00602 00603 for(n = 0; n < mm->npkt_user; n++) { 00604 mi = mm->pkt_user[n]; 00605 if(mi == NULL) { 00606 log_debug(ZONE, "module at index %d is not loaded yet", n); 00607 continue; 00608 } 00609 if(mi->mod->pkt_user == NULL) { 00610 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00611 continue; 00612 } 00613 00614 log_debug(ZONE, "calling module %s", mi->mod->name); 00615 00616 ret = (mi->mod->pkt_user)(mi, user, pkt); 00617 if(ret != mod_PASS) 00618 break; 00619 } 00620 00621 log_debug(ZONE, "pkt-user chain returning %d", ret); 00622 00623 return ret; 00624 } 00625 00627 mod_ret_t mm_pkt_router(mm_t mm, pkt_t pkt) { 00628 int n; 00629 mod_instance_t mi; 00630 mod_ret_t ret = mod_PASS; 00631 00632 log_debug(ZONE, "dispatching pkt-router chain"); 00633 00634 for(n = 0; n < mm->npkt_router; n++) { 00635 mi = mm->pkt_router[n]; 00636 if(mi == NULL) { 00637 log_debug(ZONE, "module at index %d is not loaded yet", n); 00638 continue; 00639 } 00640 if(mi->mod->pkt_router == NULL) { 00641 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00642 continue; 00643 } 00644 00645 log_debug(ZONE, "calling module %s", mi->mod->name); 00646 00647 ret = (mi->mod->pkt_router)(mi, pkt); 00648 if(ret != mod_PASS) 00649 break; 00650 } 00651 00652 log_debug(ZONE, "pkt-router chain returning %d", ret); 00653 00654 return ret; 00655 } 00656 00658 int mm_user_load(mm_t mm, user_t user) { 00659 int n; 00660 mod_instance_t mi; 00661 int ret = 0; 00662 00663 log_debug(ZONE, "dispatching user-load chain"); 00664 00665 for(n = 0; n < mm->nuser_load; n++) { 00666 mi = mm->user_load[n]; 00667 if(mi == NULL) { 00668 log_debug(ZONE, "module at index %d is not loaded yet", n); 00669 continue; 00670 } 00671 if(mi->mod->user_load == NULL) { 00672 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00673 continue; 00674 } 00675 00676 log_debug(ZONE, "calling module %s", mi->mod->name); 00677 00678 ret = (mi->mod->user_load)(mi, user); 00679 if(ret != 0) 00680 break; 00681 } 00682 00683 log_debug(ZONE, "user-load chain returning %d", ret); 00684 00685 return ret; 00686 } 00687 00689 int mm_user_unload(mm_t mm, user_t user) { 00690 int n; 00691 mod_instance_t mi; 00692 int ret = 0; 00693 00694 log_debug(ZONE, "dispatching user-unload chain"); 00695 00696 for(n = 0; n < mm->nuser_unload; n++) { 00697 mi = mm->user_unload[n]; 00698 if(mi == NULL) { 00699 log_debug(ZONE, "module at index %d is not loaded yet", n); 00700 continue; 00701 } 00702 if(mi->mod->user_unload == NULL) { 00703 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00704 continue; 00705 } 00706 00707 log_debug(ZONE, "calling module %s", mi->mod->name); 00708 00709 ret = (mi->mod->user_unload)(mi, user); 00710 if(ret != 0) 00711 break; 00712 } 00713 00714 log_debug(ZONE, "user-unload chain returning %d", ret); 00715 00716 return ret; 00717 } 00718 00720 int mm_user_create(mm_t mm, jid_t jid) { 00721 int n; 00722 mod_instance_t mi; 00723 int ret = 0; 00724 00725 log_debug(ZONE, "dispatching user-create chain"); 00726 00727 for(n = 0; n < mm->nuser_create; n++) { 00728 mi = mm->user_create[n]; 00729 if(mi == NULL) { 00730 log_debug(ZONE, "module at index %d is not loaded yet", n); 00731 continue; 00732 } 00733 if(mi->mod->user_create == NULL) { 00734 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00735 continue; 00736 } 00737 00738 log_debug(ZONE, "calling module %s", mi->mod->name); 00739 00740 ret = (mi->mod->user_create)(mi, jid); 00741 if(ret != 0) 00742 break; 00743 } 00744 00745 log_debug(ZONE, "user-create chain returning %d", ret); 00746 00747 return ret; 00748 } 00749 00751 void mm_user_delete(mm_t mm, jid_t jid) { 00752 int n; 00753 mod_instance_t mi; 00754 00755 log_debug(ZONE, "dispatching user-delete chain"); 00756 00757 for(n = 0; n < mm->nuser_delete; n++) { 00758 mi = mm->user_delete[n]; 00759 if(mi == NULL) { 00760 log_debug(ZONE, "module at index %d is not loaded yet", n); 00761 continue; 00762 } 00763 if(mi->mod->user_delete == NULL) { 00764 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00765 continue; 00766 } 00767 00768 log_debug(ZONE, "calling module %s", mi->mod->name); 00769 00770 (mi->mod->user_delete)(mi, jid); 00771 } 00772 00773 log_debug(ZONE, "user-delete chain returning"); 00774 } 00775 00777 void mm_disco_extend(mm_t mm, pkt_t pkt) { 00778 int n; 00779 mod_instance_t mi; 00780 00781 log_debug(ZONE, "dispatching disco-extend chain"); 00782 00783 for(n = 0; n < mm->ndisco_extend; n++) { 00784 mi = mm->disco_extend[n]; 00785 if(mi == NULL) { 00786 log_debug(ZONE, "module at index %d is not loaded yet", n); 00787 continue; 00788 } 00789 if(mi->mod->disco_extend == NULL) { 00790 log_debug(ZONE, "module %s has no handler for this chain", mi->mod->name); 00791 continue; 00792 } 00793 00794 log_debug(ZONE, "calling module %s", mi->mod->name); 00795 00796 (mi->mod->disco_extend)(mi, pkt); 00797 } 00798 00799 log_debug(ZONE, "disco-extend chain returning"); 00800 }