00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "modules.h"
00015 #include "language.h"
00016 #include "version.h"
00017
00018 char *mod_current_evtbuffer = NULL;
00019
00020 EvtMessageHash *EVENT[MAX_CMD_HASH];
00021 EvtHookHash *EVENTHOOKS[MAX_CMD_HASH];
00022
00023 EvtMessage *find_event(const char *name)
00024 {
00025 EvtMessage *m;
00026 m = findEventHandler(EVENT, name);
00027 return m;
00028 }
00029
00030 EvtHook *find_eventhook(const char *name)
00031 {
00032 EvtHook *m;
00033 m = findEventHook(EVENTHOOKS, name);
00034 return m;
00035 }
00036
00037 void send_event(const char *name, int argc, ...)
00038 {
00039 va_list va;
00040 char *a;
00041 int idx = 0;
00042 char **argv;
00043
00044 argv = (char **) malloc(sizeof(char *) * argc);
00045 va_start(va, argc);
00046 for (idx = 0; idx < argc; idx++) {
00047 a = va_arg(va, char *);
00048 argv[idx] = sstrdup(a);
00049 }
00050 va_end(va);
00051
00052 if (debug)
00053 alog("debug: Emitting event \"%s\" (%d args)", name, argc);
00054
00055 event_process_hook(name, argc, argv);
00056
00060 for (idx = 0; idx < argc; idx++) {
00061 free(argv[idx]);
00062 }
00063 free(argv);
00064 }
00065
00066 void eventprintf(char *fmt, ...)
00067 {
00068 va_list args;
00069 char buf[16384];
00070 char *event;
00071
00072 va_start(args, fmt);
00073 vsnprintf(buf, sizeof(buf), fmt, args);
00074 event = sstrdup(buf);
00075 event_message_process(event);
00076 va_end(args);
00077 if (event) {
00078 free(event);
00079 }
00080 return;
00081 }
00082
00083 void event_message_process(char *eventbuf)
00084 {
00085 int retVal = 0;
00086 EvtMessage *current = NULL;
00087 char source[64];
00088 char cmd[64];
00089 char buf[512];
00090 char *s;
00091 int ac;
00092 char **av;
00093 EvtMessage *evm;
00094
00095
00096 *buf = '\0';
00097 *source = '\0';
00098 *cmd = '\0';
00099
00100 strscpy(buf, eventbuf, sizeof(buf));
00101
00102 doCleanBuffer((char *) buf);
00103
00104
00105 if (*buf == ':') {
00106 s = strpbrk(buf, " ");
00107 if (!s)
00108 return;
00109 *s = 0;
00110 while (isspace(*++s));
00111 strscpy(source, buf + 1, sizeof(source));
00112 memmove(buf, s, strlen(s) + 1);
00113 } else {
00114 *source = 0;
00115 }
00116 if (!*buf)
00117 return;
00118 s = strpbrk(buf, " ");
00119 if (s) {
00120 *s = 0;
00121 while (isspace(*++s));
00122 } else
00123 s = buf + strlen(buf);
00124 strscpy(cmd, buf, sizeof(cmd));
00125 ac = split_buf(s, &av, 1);
00126
00127
00128 evm = find_event(cmd);
00129 if (evm) {
00130 char *mod_current_module_name_save = mod_current_module_name;
00131 Module *mod_current_module_save = mod_current_module;
00132 if (evm->func) {
00133 mod_current_module_name = evm->mod_name;
00134 mod_current_module = findModule(evm->mod_name);
00135 retVal = evm->func(source, ac, av);
00136 if (retVal == MOD_CONT) {
00137 current = evm->next;
00138 while (current && current->func && retVal == MOD_CONT) {
00139 mod_current_module_name = current->mod_name;
00140 mod_current_module = findModule(current->mod_name);
00141 retVal = current->func(source, ac, av);
00142 current = current->next;
00143 }
00144 }
00145 mod_current_module_name = mod_current_module_name_save;
00146 mod_current_module = mod_current_module_save;
00147 }
00148 }
00149
00150 free(av);
00151 }
00152
00153 void event_process_hook(const char *name, int argc, char **argv)
00154 {
00155 int retVal = 0;
00156 EvtHook *current = NULL;
00157 EvtHook *evh;
00158 if (mod_current_evtbuffer) {
00159 free(mod_current_evtbuffer);
00160 }
00161
00162 evh = find_eventhook(name);
00163 if (evh) {
00164 if (evh->func) {
00165 char *mod_current_module_name_save = mod_current_module_name;
00166 Module *mod_current_module_save = mod_current_module;
00167 mod_current_module = findModule(evh->mod_name);
00168 mod_current_module_name = evh->mod_name;
00169 retVal = evh->func(argc, argv);
00170 if (retVal == MOD_CONT) {
00171 current = evh->next;
00172 while (current && current->func && retVal == MOD_CONT) {
00173 mod_current_module = findModule(current->mod_name);
00174 mod_current_module_name = current->mod_name;
00175 retVal = current->func(argc, argv);
00176 current = current->next;
00177 }
00178 }
00179 mod_current_module_name = mod_current_module_name_save;
00180 mod_current_module = mod_current_module_save;
00181 }
00182 }
00183 }
00184
00191 int displayEventMessage(EvtMessage * evm)
00192 {
00193 EvtMessage *msg = NULL;
00194 int i = 0;
00195 alog("Displaying message list for %s", evm->name);
00196 for (msg = evm; msg; msg = msg->next) {
00197 alog("%d: 0x%p", ++i, (void *) msg);
00198 }
00199 alog("end");
00200 return 0;
00201 }
00202
00209 int displayEventHook(EvtHook * evh)
00210 {
00211 EvtHook *msg = NULL;
00212 int i = 0;
00213 alog("Displaying message list for %s", evh->name);
00214 for (msg = evh; msg; msg = msg->next) {
00215 alog("%d: 0x%p", ++i, (void *) msg);
00216 }
00217 alog("end");
00218 return 0;
00219 }
00220
00227 int displayHookFromHash(char *name)
00228 {
00229 EvtHookHash *current = NULL;
00230 int index = 0;
00231 index = CMD_HASH(name);
00232 if (debug > 1) {
00233 alog("debug: trying to display message %s", name);
00234 }
00235 for (current = EVENTHOOKS[index]; current; current = current->next) {
00236 if (stricmp(name, current->name) == 0) {
00237 displayEventHook(current->evh);
00238 }
00239 }
00240 if (debug > 1) {
00241 alog("debug: done displaying message %s", name);
00242 }
00243 return 0;
00244 }
00245
00252 int displayEvtMessageFromHash(char *name)
00253 {
00254 EvtMessageHash *current = NULL;
00255 int index = 0;
00256 index = CMD_HASH(name);
00257 if (debug > 1) {
00258 alog("debug: trying to display message %s", name);
00259 }
00260 for (current = EVENT[index]; current; current = current->next) {
00261 if (stricmp(name, current->name) == 0) {
00262 displayEventMessage(current->evm);
00263 }
00264 }
00265 if (debug > 1) {
00266 alog("debug: done displaying message %s", name);
00267 }
00268 return 0;
00269 }
00270
00271
00272
00273
00274
00281 EvtMessage *createEventHandler(char *name,
00282 int (*func) (char *source, int ac,
00283 char **av))
00284 {
00285 EvtMessage *evm = NULL;
00286 if (!func) {
00287 return NULL;
00288 }
00289 if ((evm = malloc(sizeof(EvtMessage))) == NULL) {
00290 fatal("Out of memory!");
00291 }
00292 evm->name = sstrdup(name);
00293 evm->func = func;
00294 evm->mod_name = NULL;
00295 evm->next = NULL;
00296 return evm;
00297 }
00298
00305 EvtHook *createEventHook(char *name, int (*func) (int argc, char **argv))
00306 {
00307 EvtHook *evh = NULL;
00308 if (!func) {
00309 return NULL;
00310 }
00311 if ((evh = malloc(sizeof(EvtHook))) == NULL) {
00312 fatal("Out of memory!");
00313 }
00314 evh->name = sstrdup(name);
00315 evh->func = func;
00316 evh->mod_name = NULL;
00317 evh->next = NULL;
00318 return evh;
00319 }
00320
00328 EvtMessage *findEventHandler(EvtMessageHash * msgEvtTable[],
00329 const char *name)
00330 {
00331 int idx;
00332 EvtMessageHash *current = NULL;
00333 if (!msgEvtTable || !name) {
00334 return NULL;
00335 }
00336 idx = CMD_HASH(name);
00337
00338 for (current = msgEvtTable[idx]; current; current = current->next) {
00339 if (stricmp(name, current->name) == 0) {
00340 return current->evm;
00341 }
00342 }
00343 return NULL;
00344 }
00345
00353 EvtHook *findEventHook(EvtHookHash * hookEvtTable[], const char *name)
00354 {
00355 int idx;
00356 EvtHookHash *current = NULL;
00357 if (!hookEvtTable || !name) {
00358 return NULL;
00359 }
00360 idx = CMD_HASH(name);
00361
00362 for (current = hookEvtTable[idx]; current; current = current->next) {
00363 if (stricmp(name, current->name) == 0) {
00364 return current->evh;
00365 }
00366 }
00367 return NULL;
00368 }
00369
00376 int addCoreEventHandler(EvtMessageHash * msgEvtTable[], EvtMessage * evm)
00377 {
00378 if (!msgEvtTable || !evm) {
00379 return MOD_ERR_PARAMS;
00380 }
00381 evm->core = 1;
00382 return addEventHandler(msgEvtTable, evm);
00383 }
00384
00391 int addEventHandler(EvtMessageHash * msgEvtTable[], EvtMessage * evm)
00392 {
00393
00394 int index = 0;
00395 EvtMessageHash *current = NULL;
00396 EvtMessageHash *newHash = NULL;
00397 EvtMessageHash *lastHash = NULL;
00398
00399 if (!msgEvtTable || !evm) {
00400 return MOD_ERR_PARAMS;
00401 }
00402
00403 index = CMD_HASH(evm->name);
00404
00405 for (current = msgEvtTable[index]; current; current = current->next) {
00406 if (stricmp(evm->name, current->name) == 0) {
00407 evm->next = current->evm;
00408 current->evm = evm;
00409 if (debug)
00410 alog("debug: existing msg: (0x%p), new msg (0x%p)",
00411 (void *) evm->next, (void *) evm);
00412 return MOD_ERR_OK;
00413 }
00414 lastHash = current;
00415 }
00416
00417 if ((newHash = malloc(sizeof(EvtMessageHash))) == NULL) {
00418 fatal("Out of memory");
00419 }
00420 newHash->next = NULL;
00421 newHash->name = sstrdup(evm->name);
00422 newHash->evm = evm;
00423
00424 if (lastHash == NULL)
00425 msgEvtTable[index] = newHash;
00426 else
00427 lastHash->next = newHash;
00428 return MOD_ERR_OK;
00429 }
00430
00437 int addEventHook(EvtHookHash * hookEvtTable[], EvtHook * evh)
00438 {
00439
00440 int index = 0;
00441 EvtHookHash *current = NULL;
00442 EvtHookHash *newHash = NULL;
00443 EvtHookHash *lastHash = NULL;
00444
00445 if (!hookEvtTable || !evh) {
00446 return MOD_ERR_PARAMS;
00447 }
00448
00449 index = CMD_HASH(evh->name);
00450
00451 for (current = hookEvtTable[index]; current; current = current->next) {
00452 if (stricmp(evh->name, current->name) == 0) {
00453 evh->next = current->evh;
00454 current->evh = evh;
00455 if (debug)
00456 alog("debug: existing msg: (0x%p), new msg (0x%p)",
00457 (void *) evh->next, (void *) evh);
00458 return MOD_ERR_OK;
00459 }
00460 lastHash = current;
00461 }
00462
00463 if ((newHash = malloc(sizeof(EvtHookHash))) == NULL) {
00464 fatal("Out of memory");
00465 }
00466 newHash->next = NULL;
00467 newHash->name = sstrdup(evh->name);
00468 newHash->evh = evh;
00469
00470 if (lastHash == NULL)
00471 hookEvtTable[index] = newHash;
00472 else
00473 lastHash->next = newHash;
00474 return MOD_ERR_OK;
00475 }
00476
00483 int addCoreEventHook(EvtHookHash * hookEvtTable[], EvtHook * evh)
00484 {
00485 if (!hookEvtTable || !evh) {
00486 return MOD_ERR_PARAMS;
00487 }
00488 evh->core = 1;
00489 return addEventHook(hookEvtTable, evh);
00490 }
00491
00498 int moduleAddEventHandler(EvtMessage * evm)
00499 {
00500 int status;
00501
00502 if (!evm) {
00503 return MOD_ERR_PARAMS;
00504 }
00505
00506 if (!mod_current_module) {
00507 return MOD_ERR_UNKNOWN;
00508 }
00509
00510 evm->core = 0;
00511 if (!evm->mod_name) {
00512 evm->mod_name = sstrdup(mod_current_module->name);
00513 }
00514
00515 status = addEventHandler(EVENT, evm);
00516 if (debug) {
00517 displayEvtMessageFromHash(evm->name);
00518 }
00519 return status;
00520 }
00521
00528 int moduleAddEventHook(EvtHook * evh)
00529 {
00530 int status;
00531
00532 if (!evh) {
00533 return MOD_ERR_PARAMS;
00534 }
00535
00536 if (!mod_current_module) {
00537 return MOD_ERR_UNKNOWN;
00538 }
00539
00540 evh->core = 0;
00541 if (!evh->mod_name) {
00542 evh->mod_name = sstrdup(mod_current_module->name);
00543 }
00544
00545 status = addEventHook(EVENTHOOKS, evh);
00546 if (debug) {
00547 displayHookFromHash(evh->name);
00548 }
00549 return status;
00550 }
00551
00557 int moduleEventDelHandler(char *name)
00558 {
00559 EvtMessage *evm;
00560 int status;
00561
00562 if (!mod_current_module) {
00563 return MOD_ERR_UNKNOWN;
00564 }
00565 evm = findEventHandler(EVENT, name);
00566 if (!evm) {
00567 return MOD_ERR_NOEXIST;
00568 }
00569
00570 status = delEventHandler(EVENT, evm, mod_current_module->name);
00571 if (debug) {
00572 displayEvtMessageFromHash(evm->name);
00573 }
00574 return status;
00575 }
00576
00582 int moduleEventDelHook(const char *name)
00583 {
00584 EvtHook *evh;
00585 int status;
00586
00587 if (!mod_current_module) {
00588 return MOD_ERR_UNKNOWN;
00589 }
00590 evh = findEventHook(EVENTHOOKS, name);
00591 if (!evh) {
00592 return MOD_ERR_NOEXIST;
00593 }
00594
00595 status = delEventHook(EVENTHOOKS, evh, mod_current_module->name);
00596 if (debug) {
00597 displayHookFromHash(evh->name);
00598 }
00599 return status;
00600 }
00601
00609 int delEventHandler(EvtMessageHash * msgEvtTable[], EvtMessage * evm,
00610 char *mod_name)
00611 {
00612 int index = 0;
00613 EvtMessageHash *current = NULL;
00614 EvtMessageHash *lastHash = NULL;
00615 EvtMessage *tail = NULL, *last = NULL;
00616
00617 if (!evm || !msgEvtTable) {
00618 return MOD_ERR_PARAMS;
00619 }
00620
00621 index = CMD_HASH(evm->name);
00622
00623 for (current = msgEvtTable[index]; current; current = current->next) {
00624 if (stricmp(evm->name, current->name) == 0) {
00625 if (!lastHash) {
00626 tail = current->evm;
00627 if (tail->next) {
00628 while (tail) {
00629 if (mod_name && tail->mod_name
00630 && (stricmp(mod_name, tail->mod_name) == 0)) {
00631 if (last) {
00632 last->next = tail->next;
00633 } else {
00634 current->evm = tail->next;
00635 }
00636 return MOD_ERR_OK;
00637 }
00638 last = tail;
00639 tail = tail->next;
00640 }
00641 } else {
00642 msgEvtTable[index] = current->next;
00643 free(current->name);
00644 return MOD_ERR_OK;
00645 }
00646 } else {
00647 tail = current->evm;
00648 if (tail->next) {
00649 while (tail) {
00650 if (mod_name && tail->mod_name
00651 && (stricmp(mod_name, tail->mod_name) == 0)) {
00652 if (last) {
00653 last->next = tail->next;
00654 } else {
00655 current->evm = tail->next;
00656 }
00657 return MOD_ERR_OK;
00658 }
00659 last = tail;
00660 tail = tail->next;
00661 }
00662 } else {
00663 lastHash->next = current->next;
00664 free(current->name);
00665 return MOD_ERR_OK;
00666 }
00667 }
00668 }
00669 lastHash = current;
00670 }
00671 return MOD_ERR_NOEXIST;
00672 }
00673
00674
00682 int delEventHook(EvtHookHash * hookEvtTable[], EvtHook * evh,
00683 char *mod_name)
00684 {
00685 int index = 0;
00686 EvtHookHash *current = NULL;
00687 EvtHookHash *lastHash = NULL;
00688 EvtHook *tail = NULL, *last = NULL;
00689
00690 if (!evh || !hookEvtTable) {
00691 return MOD_ERR_PARAMS;
00692 }
00693
00694 index = CMD_HASH(evh->name);
00695
00696 for (current = hookEvtTable[index]; current; current = current->next) {
00697 if (stricmp(evh->name, current->name) == 0) {
00698 if (!lastHash) {
00699 tail = current->evh;
00700 if (tail->next) {
00701 while (tail) {
00702 if (mod_name && tail->mod_name
00703 && (stricmp(mod_name, tail->mod_name) == 0)) {
00704 if (last) {
00705 last->next = tail->next;
00706 } else {
00707 current->evh = tail->next;
00708 }
00709 return MOD_ERR_OK;
00710 }
00711 last = tail;
00712 tail = tail->next;
00713 }
00714 } else {
00715 hookEvtTable[index] = current->next;
00716 free(current->name);
00717 return MOD_ERR_OK;
00718 }
00719 } else {
00720 tail = current->evh;
00721 if (tail->next) {
00722 while (tail) {
00723 if (mod_name && tail->mod_name
00724 && (stricmp(mod_name, tail->mod_name) == 0)) {
00725 if (last) {
00726 last->next = tail->next;
00727 } else {
00728 current->evh = tail->next;
00729 }
00730 return MOD_ERR_OK;
00731 }
00732 last = tail;
00733 tail = tail->next;
00734 }
00735 } else {
00736 lastHash->next = current->next;
00737 free(current->name);
00738 return MOD_ERR_OK;
00739 }
00740 }
00741 }
00742 lastHash = current;
00743 }
00744 return MOD_ERR_NOEXIST;
00745 }
00746
00747
00753 int destroyEventHandler(EvtMessage * evm)
00754 {
00755 if (!evm) {
00756 return MOD_ERR_PARAMS;
00757 }
00758 if (evm->name) {
00759 free(evm->name);
00760 }
00761 evm->func = NULL;
00762 if (evm->mod_name) {
00763 free(evm->mod_name);
00764 }
00765 evm->next = NULL;
00766 return MOD_ERR_OK;
00767 }
00768
00774 int destroyEventHook(EvtHook * evh)
00775 {
00776 if (!evh) {
00777 return MOD_ERR_PARAMS;
00778 }
00779 if (evh->name) {
00780 free(evh->name);
00781 }
00782 evh->func = NULL;
00783 if (evh->mod_name) {
00784 free(evh->mod_name);
00785 }
00786 evh->next = NULL;
00787 return MOD_ERR_OK;
00788 }