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 if (evm->func) {
00131 mod_current_module_name = evm->mod_name;
00132 retVal = evm->func(source, ac, av);
00133 mod_current_module_name = NULL;
00134 if (retVal == MOD_CONT) {
00135 current = evm->next;
00136 while (current && current->func && retVal == MOD_CONT) {
00137 mod_current_module_name = current->mod_name;
00138 retVal = current->func(source, ac, av);
00139 mod_current_module_name = NULL;
00140 current = current->next;
00141 }
00142 }
00143 }
00144 }
00145
00146 free(av);
00147 }
00148
00149 void event_process_hook(const char *name, int argc, char **argv)
00150 {
00151 int retVal = 0;
00152 EvtHook *current = NULL;
00153 EvtHook *evh;
00154 if (mod_current_evtbuffer) {
00155 free(mod_current_evtbuffer);
00156 }
00157
00158 evh = find_eventhook(name);
00159 if (evh) {
00160 if (evh->func) {
00161 mod_current_module_name = evh->mod_name;
00162 retVal = evh->func(argc, argv);
00163 mod_current_module_name = NULL;
00164 if (retVal == MOD_CONT) {
00165 current = evh->next;
00166 while (current && current->func && retVal == MOD_CONT) {
00167 mod_current_module_name = current->mod_name;
00168 retVal = current->func(argc, argv);
00169 mod_current_module_name = NULL;
00170 current = current->next;
00171 }
00172 }
00173 }
00174 }
00175 }
00176
00183 int displayEventMessage(EvtMessage * evm)
00184 {
00185 EvtMessage *msg = NULL;
00186 int i = 0;
00187 alog("Displaying message list for %s", evm->name);
00188 for (msg = evm; msg; msg = msg->next) {
00189 alog("%d: 0x%p", ++i, (void *) msg);
00190 }
00191 alog("end");
00192 return 0;
00193 }
00194
00201 int displayEventHook(EvtHook * evh)
00202 {
00203 EvtHook *msg = NULL;
00204 int i = 0;
00205 alog("Displaying message list for %s", evh->name);
00206 for (msg = evh; msg; msg = msg->next) {
00207 alog("%d: 0x%p", ++i, (void *) msg);
00208 }
00209 alog("end");
00210 return 0;
00211 }
00212
00219 int displayHookFromHash(char *name)
00220 {
00221 EvtHookHash *current = NULL;
00222 int index = 0;
00223 index = CMD_HASH(name);
00224 if (debug > 1) {
00225 alog("debug: trying to display message %s", name);
00226 }
00227 for (current = EVENTHOOKS[index]; current; current = current->next) {
00228 if (stricmp(name, current->name) == 0) {
00229 displayEventHook(current->evh);
00230 }
00231 }
00232 if (debug > 1) {
00233 alog("debug: done displaying message %s", name);
00234 }
00235 return 0;
00236 }
00237
00244 int displayEvtMessageFromHash(char *name)
00245 {
00246 EvtMessageHash *current = NULL;
00247 int index = 0;
00248 index = CMD_HASH(name);
00249 if (debug > 1) {
00250 alog("debug: trying to display message %s", name);
00251 }
00252 for (current = EVENT[index]; current; current = current->next) {
00253 if (stricmp(name, current->name) == 0) {
00254 displayEventMessage(current->evm);
00255 }
00256 }
00257 if (debug > 1) {
00258 alog("debug: done displaying message %s", name);
00259 }
00260 return 0;
00261 }
00262
00263
00264
00265
00266
00273 EvtMessage *createEventHandler(char *name,
00274 int (*func) (char *source, int ac,
00275 char **av))
00276 {
00277 EvtMessage *evm = NULL;
00278 if (!func) {
00279 return NULL;
00280 }
00281 if ((evm = malloc(sizeof(EvtMessage))) == NULL) {
00282 fatal("Out of memory!");
00283 }
00284 evm->name = sstrdup(name);
00285 evm->func = func;
00286 evm->mod_name = NULL;
00287 evm->next = NULL;
00288 return evm;
00289 }
00290
00297 EvtHook *createEventHook(char *name, int (*func) (int argc, char **argv))
00298 {
00299 EvtHook *evh = NULL;
00300 if (!func) {
00301 return NULL;
00302 }
00303 if ((evh = malloc(sizeof(EvtHook))) == NULL) {
00304 fatal("Out of memory!");
00305 }
00306 evh->name = sstrdup(name);
00307 evh->func = func;
00308 evh->mod_name = NULL;
00309 evh->next = NULL;
00310 return evh;
00311 }
00312
00320 EvtMessage *findEventHandler(EvtMessageHash * msgEvtTable[],
00321 const char *name)
00322 {
00323 int idx;
00324 EvtMessageHash *current = NULL;
00325 if (!msgEvtTable || !name) {
00326 return NULL;
00327 }
00328 idx = CMD_HASH(name);
00329
00330 for (current = msgEvtTable[idx]; current; current = current->next) {
00331 if (stricmp(name, current->name) == 0) {
00332 return current->evm;
00333 }
00334 }
00335 return NULL;
00336 }
00337
00345 EvtHook *findEventHook(EvtHookHash * hookEvtTable[], const char *name)
00346 {
00347 int idx;
00348 EvtHookHash *current = NULL;
00349 if (!hookEvtTable || !name) {
00350 return NULL;
00351 }
00352 idx = CMD_HASH(name);
00353
00354 for (current = hookEvtTable[idx]; current; current = current->next) {
00355 if (stricmp(name, current->name) == 0) {
00356 return current->evh;
00357 }
00358 }
00359 return NULL;
00360 }
00361
00368 int addCoreEventHandler(EvtMessageHash * msgEvtTable[], EvtMessage * evm)
00369 {
00370 if (!msgEvtTable || !evm) {
00371 return MOD_ERR_PARAMS;
00372 }
00373 evm->core = 1;
00374 return addEventHandler(msgEvtTable, evm);
00375 }
00376
00383 int addEventHandler(EvtMessageHash * msgEvtTable[], EvtMessage * evm)
00384 {
00385
00386 int index = 0;
00387 EvtMessageHash *current = NULL;
00388 EvtMessageHash *newHash = NULL;
00389 EvtMessageHash *lastHash = NULL;
00390
00391 if (!msgEvtTable || !evm) {
00392 return MOD_ERR_PARAMS;
00393 }
00394
00395 index = CMD_HASH(evm->name);
00396
00397 for (current = msgEvtTable[index]; current; current = current->next) {
00398 if (stricmp(evm->name, current->name) == 0) {
00399 evm->next = current->evm;
00400 current->evm = evm;
00401 if (debug)
00402 alog("debug: existing msg: (0x%p), new msg (0x%p)",
00403 (void *) evm->next, (void *) evm);
00404 return MOD_ERR_OK;
00405 }
00406 lastHash = current;
00407 }
00408
00409 if ((newHash = malloc(sizeof(EvtMessageHash))) == NULL) {
00410 fatal("Out of memory");
00411 }
00412 newHash->next = NULL;
00413 newHash->name = sstrdup(evm->name);
00414 newHash->evm = evm;
00415
00416 if (lastHash == NULL)
00417 msgEvtTable[index] = newHash;
00418 else
00419 lastHash->next = newHash;
00420 return MOD_ERR_OK;
00421 }
00422
00429 int addEventHook(EvtHookHash * hookEvtTable[], EvtHook * evh)
00430 {
00431
00432 int index = 0;
00433 EvtHookHash *current = NULL;
00434 EvtHookHash *newHash = NULL;
00435 EvtHookHash *lastHash = NULL;
00436
00437 if (!hookEvtTable || !evh) {
00438 return MOD_ERR_PARAMS;
00439 }
00440
00441 index = CMD_HASH(evh->name);
00442
00443 for (current = hookEvtTable[index]; current; current = current->next) {
00444 if (stricmp(evh->name, current->name) == 0) {
00445 evh->next = current->evh;
00446 current->evh = evh;
00447 if (debug)
00448 alog("debug: existing msg: (0x%p), new msg (0x%p)",
00449 (void *) evh->next, (void *) evh);
00450 return MOD_ERR_OK;
00451 }
00452 lastHash = current;
00453 }
00454
00455 if ((newHash = malloc(sizeof(EvtHookHash))) == NULL) {
00456 fatal("Out of memory");
00457 }
00458 newHash->next = NULL;
00459 newHash->name = sstrdup(evh->name);
00460 newHash->evh = evh;
00461
00462 if (lastHash == NULL)
00463 hookEvtTable[index] = newHash;
00464 else
00465 lastHash->next = newHash;
00466 return MOD_ERR_OK;
00467 }
00468
00475 int addCoreEventHook(EvtHookHash * hookEvtTable[], EvtHook * evh)
00476 {
00477 if (!hookEvtTable || !evh) {
00478 return MOD_ERR_PARAMS;
00479 }
00480 evh->core = 1;
00481 return addEventHook(hookEvtTable, evh);
00482 }
00483
00490 int moduleAddEventHandler(EvtMessage * evm)
00491 {
00492 int status;
00493
00494 if (!evm) {
00495 return MOD_ERR_PARAMS;
00496 }
00497
00498
00499 if ((mod_current_module_name) && (!mod_current_module)) {
00500 mod_current_module = findModule(mod_current_module_name);
00501 }
00502
00503 if (!mod_current_module) {
00504 return MOD_ERR_UNKNOWN;
00505 }
00506 evm->core = 0;
00507 if (!evm->mod_name) {
00508 evm->mod_name = sstrdup(mod_current_module->name);
00509 }
00510
00511 status = addEventHandler(EVENT, evm);
00512 if (debug) {
00513 displayEvtMessageFromHash(evm->name);
00514 }
00515 return status;
00516 }
00517
00524 int moduleAddEventHook(EvtHook * evh)
00525 {
00526 int status;
00527
00528 if (!evh) {
00529 return MOD_ERR_PARAMS;
00530 }
00531
00532 if ((mod_current_module_name) && (!mod_current_module)) {
00533 mod_current_module = findModule(mod_current_module_name);
00534 }
00535
00536 if (!mod_current_module) {
00537 return MOD_ERR_UNKNOWN;
00538 }
00539 evh->core = 0;
00540 if (!evh->mod_name) {
00541 evh->mod_name = sstrdup(mod_current_module->name);
00542 }
00543
00544 status = addEventHook(EVENTHOOKS, evh);
00545 if (debug) {
00546 displayHookFromHash(evh->name);
00547 }
00548 return status;
00549 }
00550
00556 int moduleEventDelHandler(char *name)
00557 {
00558 EvtMessage *evm;
00559 int status;
00560
00561 if (!mod_current_module) {
00562 return MOD_ERR_UNKNOWN;
00563 }
00564 evm = findEventHandler(EVENT, name);
00565 if (!evm) {
00566 return MOD_ERR_NOEXIST;
00567 }
00568
00569 status = delEventHandler(EVENT, evm, mod_current_module->name);
00570 if (debug) {
00571 displayEvtMessageFromHash(evm->name);
00572 }
00573 return status;
00574 }
00575
00581 int moduleEventDelHook(const char *name)
00582 {
00583 EvtHook *evh;
00584 int status;
00585
00586 if (!mod_current_module) {
00587 return MOD_ERR_UNKNOWN;
00588 }
00589 evh = findEventHook(EVENTHOOKS, name);
00590 if (!evh) {
00591 return MOD_ERR_NOEXIST;
00592 }
00593
00594 status = delEventHook(EVENTHOOKS, evh, mod_current_module->name);
00595 if (debug) {
00596 displayHookFromHash(evh->name);
00597 }
00598 return status;
00599 }
00600
00608 int delEventHandler(EvtMessageHash * msgEvtTable[], EvtMessage * evm,
00609 char *mod_name)
00610 {
00611 int index = 0;
00612 EvtMessageHash *current = NULL;
00613 EvtMessageHash *lastHash = NULL;
00614 EvtMessage *tail = NULL, *last = NULL;
00615
00616 if (!evm || !msgEvtTable) {
00617 return MOD_ERR_PARAMS;
00618 }
00619
00620 index = CMD_HASH(evm->name);
00621
00622 for (current = msgEvtTable[index]; current; current = current->next) {
00623 if (stricmp(evm->name, current->name) == 0) {
00624 if (!lastHash) {
00625 tail = current->evm;
00626 if (tail->next) {
00627 while (tail) {
00628 if (mod_name && tail->mod_name
00629 && (stricmp(mod_name, tail->mod_name) == 0)) {
00630 if (last) {
00631 last->next = tail->next;
00632 } else {
00633 current->evm = tail->next;
00634 }
00635 return MOD_ERR_OK;
00636 }
00637 last = tail;
00638 tail = tail->next;
00639 }
00640 } else {
00641 msgEvtTable[index] = current->next;
00642 free(current->name);
00643 return MOD_ERR_OK;
00644 }
00645 } else {
00646 tail = current->evm;
00647 if (tail->next) {
00648 while (tail) {
00649 if (mod_name && tail->mod_name
00650 && (stricmp(mod_name, tail->mod_name) == 0)) {
00651 if (last) {
00652 last->next = tail->next;
00653 } else {
00654 current->evm = tail->next;
00655 }
00656 return MOD_ERR_OK;
00657 }
00658 last = tail;
00659 tail = tail->next;
00660 }
00661 } else {
00662 lastHash->next = current->next;
00663 free(current->name);
00664 return MOD_ERR_OK;
00665 }
00666 }
00667 }
00668 lastHash = current;
00669 }
00670 return MOD_ERR_NOEXIST;
00671 }
00672
00673
00681 int delEventHook(EvtHookHash * hookEvtTable[], EvtHook * evh,
00682 char *mod_name)
00683 {
00684 int index = 0;
00685 EvtHookHash *current = NULL;
00686 EvtHookHash *lastHash = NULL;
00687 EvtHook *tail = NULL, *last = NULL;
00688
00689 if (!evh || !hookEvtTable) {
00690 return MOD_ERR_PARAMS;
00691 }
00692
00693 index = CMD_HASH(evh->name);
00694
00695 for (current = hookEvtTable[index]; current; current = current->next) {
00696 if (stricmp(evh->name, current->name) == 0) {
00697 if (!lastHash) {
00698 tail = current->evh;
00699 if (tail->next) {
00700 while (tail) {
00701 if (mod_name && tail->mod_name
00702 && (stricmp(mod_name, tail->mod_name) == 0)) {
00703 if (last) {
00704 last->next = tail->next;
00705 } else {
00706 current->evh = tail->next;
00707 }
00708 return MOD_ERR_OK;
00709 }
00710 last = tail;
00711 tail = tail->next;
00712 }
00713 } else {
00714 hookEvtTable[index] = current->next;
00715 free(current->name);
00716 return MOD_ERR_OK;
00717 }
00718 } else {
00719 tail = current->evh;
00720 if (tail->next) {
00721 while (tail) {
00722 if (mod_name && tail->mod_name
00723 && (stricmp(mod_name, tail->mod_name) == 0)) {
00724 if (last) {
00725 last->next = tail->next;
00726 } else {
00727 current->evh = tail->next;
00728 }
00729 return MOD_ERR_OK;
00730 }
00731 last = tail;
00732 tail = tail->next;
00733 }
00734 } else {
00735 lastHash->next = current->next;
00736 free(current->name);
00737 return MOD_ERR_OK;
00738 }
00739 }
00740 }
00741 lastHash = current;
00742 }
00743 return MOD_ERR_NOEXIST;
00744 }
00745
00746
00752 int destroyEventHandler(EvtMessage * evm)
00753 {
00754 if (!evm) {
00755 return MOD_ERR_PARAMS;
00756 }
00757 if (evm->name) {
00758 free(evm->name);
00759 }
00760 evm->func = NULL;
00761 if (evm->mod_name) {
00762 free(evm->mod_name);
00763 }
00764 evm->next = NULL;
00765 return MOD_ERR_OK;
00766 }
00767
00773 int destroyEventHook(EvtHook * evh)
00774 {
00775 if (!evh) {
00776 return MOD_ERR_PARAMS;
00777 }
00778 if (evh->name) {
00779 free(evh->name);
00780 }
00781 evh->func = NULL;
00782 if (evh->mod_name) {
00783 free(evh->mod_name);
00784 }
00785 evh->next = NULL;
00786 return MOD_ERR_OK;
00787 }