citadel
About: Citadel is an advanced messaging and collaboration system for groupware and BBS applications (preferred OS: Linux).
  Fossies Dox: citadel.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

serv_extensions.c
Go to the documentation of this file.
1/*
2 * Citadel Extension Loader
3 * Originally written by Brian Costello <btx@calyx.net>
4 *
5 * Copyright (c) 1987-2021 by the citadel.org team
6 *
7 * This program is open source software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <stdlib.h>
17#include <unistd.h>
18#include <stdio.h>
19#include <sys/stat.h>
20#include <libcitadel.h>
21#include "sysdep_decls.h"
22#include "modules/crypto/serv_crypto.h" /* Needed until a universal crypto startup hook is implimented for CtdlStartTLS */
23#include "serv_extensions.h"
24#include "ctdl_module.h"
25#include "config.h"
26
27
28/*
29 * Structure defentitions for hook tables
30 */
31
35 char content_type[64];
36 void (*h_function_pointer) (char *, int);
37};
39
40
41/*
42 * SessionFunctionHook extensions are used for any type of hook for which
43 * the context in which it's being called (which is determined by the event
44 * type) will make it obvious for the hook function to know where to look for
45 * pertinent data.
46 */
51 void (*h_function_pointer) (void);
53};
55
56
57/*
58 * UserFunctionHook extensions are used for any type of hook which implements
59 * an operation on a user or username (potentially) other than the one
60 * operating the current session.
61 */
67};
69
70
71/*
72 * MessageFunctionHook extensions are used for hooks which implement handlers
73 * for various types of message operations (save, read, etc.)
74 */
78 int (*h_function_pointer) (struct CtdlMessage *msg, struct recptypes *recps);
80};
82
83
84/*
85 * DeleteFunctionHook extensions are used for hooks which get called when a
86 * message is about to be deleted.
87 */
91 void (*h_function_pointer) (char *target_room, long msgnum);
92};
94
95
96/*
97 * ExpressMessageFunctionHook extensions are used for hooks which implement
98 * the sending of an instant message through various channels. Any function
99 * registered should return the number of recipients to whom the message was
100 * successfully transmitted.
101 */
105 int (*h_function_pointer) (char *, char *, char *, char *);
106 int order;
107};
109
110
111/*
112 * RoomFunctionHook extensions are used for hooks which impliment room
113 * processing functions when new messages are added.
114 */
118 int (*fcn_ptr) (struct ctdlroom *);
119};
121
122
126 void (*fcn_ptr) (int *, long **, const char *);
127 char *name;
128};
130
132
135 void (*handler) (char *cmdbuf);
136 const char *cmd;
137 const char *desc;
138};
139
140HashList *ProtoHookList = NULL;
141
142
143#define ERR_PORT (1 << 1)
144
145
146static StrBuf *portlist = NULL;
147static StrBuf *errormessages = NULL;
148
149
151ConstStr Empty = {HKEY("")};
152char *ErrSubject = "Startup Problems";
153ConstStr ErrGeneral[] = {
154 {HKEY("Citadel had trouble on starting up. ")},
155 {HKEY(" This means, Citadel won't be the service provider for a specific service you configured it to.\n\n"
156 "If you don't want Citadel to provide these services, turn them off in WebCit via: ")},
157 {HKEY("To make both ways actualy take place restart the citserver with \"sendcommand down\"\n\n"
158 "The errors returned by the system were:\n")},
159 {HKEY("You can recheck the above if you follow this faq item:\n"
160 "http://www.citadel.org/doku.php?id=faq:mastering_your_os:net#netstat")}
161};
162
163ConstStr ErrPortShort = { HKEY("We couldn't bind all ports you configured to be provided by Citadel Server.\n")};
164ConstStr ErrPortWhere = { HKEY("\"Admin->System Preferences->Network\".\n\nThe failed ports and sockets are: ")};
165ConstStr ErrPortHint = { HKEY("If you want Citadel to provide you with that functionality, "
166 "check the output of \"netstat -lnp\" on Linux, or \"netstat -na\" on BSD"
167 " and disable the program that binds these ports.\n")};
168
169
170void LogPrintMessages(long err)
171{
172 StrBuf *Message;
173 StrBuf *List, *DetailList;
174 ConstStr *Short, *Where, *Hint;
175
176
177 Message = NewStrBufPlain(NULL, StrLength(portlist) + StrLength(errormessages));
178
180
181 switch (err)
182 {
183 case ERR_PORT:
184 Short = &ErrPortShort;
185 Where = &ErrPortWhere;
186 Hint = &ErrPortHint;
187 List = portlist;
188 DetailList = errormessages;
189 break;
190 default:
191 Short = &Empty;
192 Where = &Empty;
193 Hint = &Empty;
194 List = NULL;
195 DetailList = NULL;
196 }
197
198 StrBufAppendBufPlain(Message, CKEY(ErrGeneral[0]), 0);
199 StrBufAppendBufPlain(Message, CKEY(*Short), 0);
200 StrBufAppendBufPlain(Message, CKEY(ErrGeneral[1]), 0);
201 StrBufAppendBufPlain(Message, CKEY(*Where), 0);
202 StrBufAppendBuf(Message, List, 0);
203 StrBufAppendBufPlain(Message, HKEY("\n\n"), 0);
204 StrBufAppendBufPlain(Message, CKEY(*Hint), 0);
205 StrBufAppendBufPlain(Message, HKEY("\n\n"), 0);
206 StrBufAppendBufPlain(Message, CKEY(ErrGeneral[2]), 0);
207 StrBufAppendBuf(Message, DetailList, 0);
208 StrBufAppendBufPlain(Message, HKEY("\n\n"), 0);
209 StrBufAppendBufPlain(Message, CKEY(ErrGeneral[3]), 0);
210
211 syslog(LOG_ERR, "extensions: %s", ChrPtr(Message));
212 syslog(LOG_ERR, "extensions: %s", ErrSubject);
213 quickie_message("Citadel", NULL, NULL, AIDEROOM, ChrPtr(Message), FMT_FIXED, ErrSubject);
214
215 FreeStrBuf(&Message);
216 FreeStrBuf(&List);
217 FreeStrBuf(&DetailList);
218}
219
220
221void AddPortError(char *Port, char *ErrorMessage)
222{
223 long len;
224
226
227 len = StrLength(errormessages);
228 if (len > 0) StrBufAppendBufPlain(errormessages, HKEY("; "), 0);
229 else errormessages = NewStrBuf();
230 StrBufAppendBufPlain(errormessages, ErrorMessage, -1, 0);
231
232
233 len = StrLength(portlist);
234 if (len > 0) StrBufAppendBufPlain(portlist, HKEY(";"), 0);
235 else portlist = NewStrBuf();
236 StrBufAppendBufPlain(portlist, Port, -1, 0);
237}
238
239
240int DLoader_Exec_Cmd(char *cmdbuf)
241{
242 void *vP;
244
245 if (GetHash(ProtoHookList, cmdbuf, 4, &vP) && (vP != NULL)) {
246 p = (ProtoFunctionHook*) vP;
247 p->handler(&cmdbuf[5]);
248 return 1;
249 }
250 return 0;
251}
252
253
254void CtdlRegisterProtoHook(void (*handler) (char *), char *cmd, char *desc)
255{
257
258 if (ProtoHookList == NULL)
259 ProtoHookList = NewHash (1, FourHash);
260
261
262 p = (ProtoFunctionHook *)
263 malloc(sizeof(ProtoFunctionHook));
264
265 if (p == NULL) {
266 fprintf(stderr, "can't malloc new ProtoFunctionHook\n");
267 exit(EXIT_FAILURE);
268 }
269 p->handler = handler;
270 p->cmd = cmd;
271 p->desc = desc;
272
273 Put(ProtoHookList, cmd, 4, p, NULL);
274 syslog(LOG_DEBUG, "extensions: registered server command %s (%s)", cmd, desc);
275}
276
277
278void CtdlRegisterSessionHook(void (*fcn_ptr) (void), int EventType, int Priority)
279{
280 SessionFunctionHook *newfcn;
281
282 newfcn = (SessionFunctionHook *)
284 newfcn->Priority = Priority;
285 newfcn->h_function_pointer = fcn_ptr;
286 newfcn->eventtype = EventType;
287
288 SessionFunctionHook **pfcn;
289 pfcn = &SessionHookTable;
290 while ((*pfcn != NULL) &&
291 ((*pfcn)->Priority < newfcn->Priority) &&
292 ((*pfcn)->next != NULL))
293 pfcn = &(*pfcn)->next;
294
295 newfcn->next = *pfcn;
296 *pfcn = newfcn;
297
298 syslog(LOG_DEBUG, "extensions: registered a new session function (type %d Priority %d)", EventType, Priority);
299}
300
301
302void CtdlUnregisterSessionHook(void (*fcn_ptr) (void), int EventType)
303{
304 SessionFunctionHook *cur, *p, *last;
305 last = NULL;
306 cur = SessionHookTable;
307 while (cur != NULL) {
308 if ((fcn_ptr == cur->h_function_pointer) &&
309 (EventType == cur->eventtype))
310 {
311 syslog(LOG_DEBUG, "extensions: unregistered session function (type %d)", EventType);
312 p = cur->next;
313
314 free(cur);
315 cur = NULL;
316
317 if (last != NULL)
318 last->next = p;
319 else
321 cur = p;
322 }
323 else {
324 last = cur;
325 cur = cur->next;
326 }
327 }
328}
329
330
331void CtdlRegisterUserHook(void (*fcn_ptr) (ctdluser *), int EventType)
332{
333
334 UserFunctionHook *newfcn;
335
336 newfcn = (UserFunctionHook *)
337 malloc(sizeof(UserFunctionHook));
338 newfcn->next = UserHookTable;
339 newfcn->h_function_pointer = fcn_ptr;
340 newfcn->eventtype = EventType;
341 UserHookTable = newfcn;
342
343 syslog(LOG_DEBUG, "extensions: registered a new user function (type %d)",
344 EventType);
345}
346
347
348void CtdlUnregisterUserHook(void (*fcn_ptr) (struct ctdluser *), int EventType)
349{
350 UserFunctionHook *cur, *p, *last;
351 last = NULL;
352 cur = UserHookTable;
353 while (cur != NULL) {
354 if ((fcn_ptr == cur->h_function_pointer) &&
355 (EventType == cur->eventtype))
356 {
357 syslog(LOG_DEBUG, "extensions: unregistered user function (type %d)", EventType);
358 p = cur->next;
359
360 free(cur);
361 cur = NULL;
362
363 if (last != NULL)
364 last->next = p;
365 else
366 UserHookTable = p;
367 cur = p;
368 }
369 else {
370 last = cur;
371 cur = cur->next;
372 }
373 }
374}
375
376
377void CtdlRegisterMessageHook(int (*handler)(struct CtdlMessage *, struct recptypes *), int EventType)
378{
379
380 MessageFunctionHook *newfcn;
381
382 newfcn = (MessageFunctionHook *)
384 newfcn->next = MessageHookTable;
385 newfcn->h_function_pointer = handler;
386 newfcn->eventtype = EventType;
387 MessageHookTable = newfcn;
388
389 syslog(LOG_DEBUG, "extensions: registered a new message function (type %d)", EventType);
390}
391
392
393void CtdlUnregisterMessageHook(int (*handler)(struct CtdlMessage *, struct recptypes *), int EventType)
394{
395 MessageFunctionHook *cur, *p, *last;
396 last = NULL;
397 cur = MessageHookTable;
398 while (cur != NULL) {
399 if ((handler == cur->h_function_pointer) &&
400 (EventType == cur->eventtype))
401 {
402 syslog(LOG_DEBUG, "extensions: unregistered message function (type %d)", EventType);
403 p = cur->next;
404 free(cur);
405 cur = NULL;
406
407 if (last != NULL)
408 last->next = p;
409 else
411 cur = p;
412 }
413 else {
414 last = cur;
415 cur = cur->next;
416 }
417 }
418}
419
420
421void CtdlRegisterRoomHook(int (*fcn_ptr)(struct ctdlroom *))
422{
423 RoomFunctionHook *newfcn;
424
425 newfcn = (RoomFunctionHook *)
426 malloc(sizeof(RoomFunctionHook));
427 newfcn->next = RoomHookTable;
428 newfcn->fcn_ptr = fcn_ptr;
429 RoomHookTable = newfcn;
430
431 syslog(LOG_DEBUG, "extensions: registered a new room function");
432}
433
434
435void CtdlUnregisterRoomHook(int (*fcn_ptr)(struct ctdlroom *))
436{
437 RoomFunctionHook *cur, *p, *last;
438 last = NULL;
439 cur = RoomHookTable;
440 while (cur != NULL)
441 {
442 if (fcn_ptr == cur->fcn_ptr) {
443 syslog(LOG_DEBUG, "extensions: unregistered room function");
444 p = cur->next;
445
446 free(cur);
447 cur = NULL;
448
449 if (last != NULL)
450 last->next = p;
451 else
452 RoomHookTable = p;
453 cur = p;
454 }
455 else {
456 last = cur;
457 cur = cur->next;
458 }
459 }
460}
461
462
463void CtdlRegisterDeleteHook(void (*handler)(char *, long) )
464{
465 DeleteFunctionHook *newfcn;
466
467 newfcn = (DeleteFunctionHook *)
468 malloc(sizeof(DeleteFunctionHook));
469 newfcn->next = DeleteHookTable;
470 newfcn->h_function_pointer = handler;
471 DeleteHookTable = newfcn;
472
473 syslog(LOG_DEBUG, "extensions: registered a new delete function");
474}
475
476
477void CtdlUnregisterDeleteHook(void (*handler)(char *, long) )
478{
479 DeleteFunctionHook *cur, *p, *last;
480
481 last = NULL;
482 cur = DeleteHookTable;
483 while (cur != NULL) {
484 if (handler == cur->h_function_pointer )
485 {
486 syslog(LOG_DEBUG, "extensions: unregistered delete function");
487 p = cur->next;
488 free(cur);
489
490 if (last != NULL)
491 last->next = p;
492 else
493 DeleteHookTable = p;
494
495 cur = p;
496 }
497 else {
498 last = cur;
499 cur = cur->next;
500 }
501 }
502}
503
504
505void CtdlRegisterFixedOutputHook(char *content_type, void (*handler)(char *, int) )
506{
507 FixedOutputHook *newfcn;
508
509 newfcn = (FixedOutputHook *)
510 malloc(sizeof(FixedOutputHook));
511 newfcn->next = FixedOutputTable;
512 newfcn->h_function_pointer = handler;
513 safestrncpy(newfcn->content_type, content_type, sizeof newfcn->content_type);
514 FixedOutputTable = newfcn;
515
516 syslog(LOG_DEBUG, "extensions: registered a new fixed output function for %s", newfcn->content_type);
517}
518
519
520void CtdlUnregisterFixedOutputHook(char *content_type)
521{
522 FixedOutputHook *cur, *p, *last;
523
524 last = NULL;
525 cur = FixedOutputTable;
526 while (cur != NULL) {
527 /* This will also remove duplicates if any */
528 if (!strcasecmp(content_type, cur->content_type)) {
529 syslog(LOG_DEBUG, "extensions: unregistered fixed output function for %s", content_type);
530 p = cur->next;
531 free(cur);
532
533 if (last != NULL)
534 last->next = p;
535 else
537
538 cur = p;
539 }
540 else
541 {
542 last = cur;
543 cur = cur->next;
544 }
545 }
546}
547
548
549/* returns nonzero if we found a hook and used it */
550int PerformFixedOutputHooks(char *content_type, char *content, int content_length)
551{
552 FixedOutputHook *fcn;
553
554 for (fcn = FixedOutputTable; fcn != NULL; fcn = fcn->next) {
555 if (!strcasecmp(content_type, fcn->content_type)) {
556 (*fcn->h_function_pointer) (content, content_length);
557 return(1);
558 }
559 }
560 return(0);
561}
562
563
564void CtdlRegisterXmsgHook(int (*fcn_ptr) (char *, char *, char *, char *), int order)
565{
566
567 XmsgFunctionHook *newfcn;
568
569 newfcn = (XmsgFunctionHook *) malloc(sizeof(XmsgFunctionHook));
570 newfcn->next = XmsgHookTable;
571 newfcn->order = order;
572 newfcn->h_function_pointer = fcn_ptr;
573 XmsgHookTable = newfcn;
574 syslog(LOG_DEBUG, "extensions: registered a new x-msg function (priority %d)", order);
575}
576
577
578void CtdlUnregisterXmsgHook(int (*fcn_ptr) (char *, char *, char *, char *), int order)
579{
580 XmsgFunctionHook *cur, *p, *last;
581
582 last = NULL;
583 cur = XmsgHookTable;
584 while (cur != NULL) {
585 /* This will also remove duplicates if any */
586 if (fcn_ptr == cur->h_function_pointer &&
587 order == cur->order) {
588 syslog(LOG_DEBUG, "extensions: unregistered x-msg function (priority %d)", order);
589 p = cur->next;
590 free(cur);
591
592 if (last != NULL) {
593 last->next = p;
594 }
595 else {
596 XmsgHookTable = p;
597 }
598 cur = p;
599 }
600 else {
601 last = cur;
602 cur = cur->next;
603 }
604 }
605}
606
607
608void CtdlRegisterServiceHook(int tcp_port,
609 char *sockpath,
610 void (*h_greeting_function) (void),
611 void (*h_command_function) (void),
612 void (*h_async_function) (void),
613 const char *ServiceName)
614{
615 ServiceFunctionHook *newfcn;
616 char *message;
617
618 newfcn = (ServiceFunctionHook *) malloc(sizeof(ServiceFunctionHook));
619 message = (char*) malloc (SIZ + SIZ);
620
621 newfcn->next = ServiceHookTable;
622 newfcn->tcp_port = tcp_port;
623 newfcn->sockpath = sockpath;
624 newfcn->h_greeting_function = h_greeting_function;
625 newfcn->h_command_function = h_command_function;
626 newfcn->h_async_function = h_async_function;
627 newfcn->ServiceName = ServiceName;
628
629 if (sockpath != NULL) {
630 newfcn->msock = ctdl_uds_server(sockpath, CtdlGetConfigInt("c_maxsessions"));
631 snprintf(message, SIZ, "extensions: unix domain socket '%s': ", sockpath);
632 }
633 else if (tcp_port <= 0) { /* port -1 to disable */
634 syslog(LOG_INFO, "extensions: service %s has been manually disabled, skipping", ServiceName);
635 free (message);
636 free(newfcn);
637 return;
638 }
639 else {
640 newfcn->msock = ctdl_tcp_server(CtdlGetConfigStr("c_ip_addr"), tcp_port, CtdlGetConfigInt("c_maxsessions"));
641 snprintf(message, SIZ, "extensions: TCP port %s:%d: (%s) ",
642 CtdlGetConfigStr("c_ip_addr"), tcp_port, ServiceName);
643 }
644
645 if (newfcn->msock > 0) {
646 ServiceHookTable = newfcn;
647 strcat(message, "registered.");
648 syslog(LOG_INFO, "%s", message);
649 }
650 else {
651 AddPortError(message, "failed");
652 strcat(message, "FAILED.");
653 syslog(LOG_ERR, "%s", message);
654 free(newfcn);
655 }
656 free(message);
657}
658
659
660void CtdlUnregisterServiceHook(int tcp_port, char *sockpath,
661 void (*h_greeting_function) (void),
662 void (*h_command_function) (void),
663 void (*h_async_function) (void)
664 )
665{
666 ServiceFunctionHook *cur, *p, *last;
667
668 last = NULL;
669 cur = ServiceHookTable;
670 while (cur != NULL) {
671 /* This will also remove duplicates if any */
672 if (h_greeting_function == cur->h_greeting_function &&
673 h_command_function == cur->h_command_function &&
674 h_async_function == cur->h_async_function &&
675 tcp_port == cur->tcp_port &&
676 !(sockpath && cur->sockpath && strcmp(sockpath, cur->sockpath)) )
677 {
678 if (cur->msock > 0)
679 close(cur->msock);
680 if (sockpath) {
681 syslog(LOG_INFO, "extensions: closed UNIX domain socket %s", sockpath);
682 unlink(sockpath);
683 } else if (tcp_port) {
684 syslog(LOG_INFO, "extensions: closed TCP port %d", tcp_port);
685 } else {
686 syslog(LOG_INFO, "extensions: unregistered service \"%s\"", cur->ServiceName);
687 }
688 p = cur->next;
689 free(cur);
690 if (last != NULL)
691 last->next = p;
692 else
694 cur = p;
695 }
696 else {
697 last = cur;
698 cur = cur->next;
699 }
700 }
701}
702
703
705{
706 /* sort of a duplicate of close_masters() but called earlier */
708
709 cur = ServiceHookTable;
710 while (cur != NULL)
711 {
712 if (cur->msock != -1)
713 {
714 close(cur->msock);
715 cur->msock = -1;
716 if (cur->sockpath != NULL){
717 syslog(LOG_INFO, "extensions: [%s] Closed UNIX domain socket %s", cur->ServiceName, cur->sockpath);
718 unlink(cur->sockpath);
719 } else {
720 syslog(LOG_INFO, "extensions: [%s] closing service", cur->ServiceName);
721 }
722 }
723 cur = cur->next;
724 }
725}
726
727
728void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, const char *), char *name)
729{
730 SearchFunctionHook *newfcn;
731
732 if (!name || !fcn_ptr) {
733 return;
734 }
735
736 newfcn = (SearchFunctionHook *)
737 malloc(sizeof(SearchFunctionHook));
739 newfcn->name = name;
740 newfcn->fcn_ptr = fcn_ptr;
742
743 syslog(LOG_DEBUG, "extensions: registered a new search function (%s)", name);
744}
745
746void CtdlUnregisterSearchFuncHook(void (*fcn_ptr)(int *, long **, const char *), char *name)
747{
748 SearchFunctionHook *cur, *p, *last;
749
750 last = NULL;
752 while (cur != NULL) {
753 if (fcn_ptr &&
754 (cur->fcn_ptr == fcn_ptr) &&
755 name && !strcmp(name, cur->name))
756 {
757 syslog(LOG_DEBUG, "extensions: unregistered search function(%s)", name);
758 p = cur->next;
759 free (cur);
760 if (last != NULL)
761 last->next = p;
762 else
764 cur = p;
765 }
766 else {
767 last = cur;
768 cur = cur->next;
769 }
770 }
771}
772
773
774void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, const char *search_string, const char *func_name)
775{
776 SearchFunctionHook *fcn = NULL;
777
778 for (fcn = SearchFunctionHookTable; fcn != NULL; fcn = fcn->next) {
779 if (!func_name || !strcmp(func_name, fcn->name)) {
780 (*fcn->fcn_ptr) (num_msgs, search_msgs, search_string);
781 return;
782 }
783 }
784 *num_msgs = 0;
785}
786
787
788void PerformSessionHooks(int EventType)
789{
790 SessionFunctionHook *fcn = NULL;
791
792 for (fcn = SessionHookTable; fcn != NULL; fcn = fcn->next) {
793 if (fcn->eventtype == EventType) {
794 if (EventType == EVT_TIMER) {
795 pthread_setspecific(MyConKey, NULL); /* for every hook */
796 }
797 (*fcn->h_function_pointer) ();
798 }
799 }
800}
801
802void PerformUserHooks(ctdluser *usbuf, int EventType)
803{
804 UserFunctionHook *fcn = NULL;
805
806 for (fcn = UserHookTable; fcn != NULL; fcn = fcn->next) {
807 if (fcn->eventtype == EventType) {
808 (*fcn->h_function_pointer) (usbuf);
809 }
810 }
811}
812
813int PerformMessageHooks(struct CtdlMessage *msg, struct recptypes *recps, int EventType)
814{
815 MessageFunctionHook *fcn = NULL;
816 int total_retval = 0;
817
818 /* Other code may elect to protect this message from server-side
819 * handlers; if this is the case, don't do anything.
820 */
821 if (msg->cm_flags & CM_SKIP_HOOKS) {
822 return(0);
823 }
824
825 /* Otherwise, run all the hooks appropriate to this event type.
826 */
827 for (fcn = MessageHookTable; fcn != NULL; fcn = fcn->next) {
828 if (fcn->eventtype == EventType) {
829 total_retval = total_retval + (*fcn->h_function_pointer) (msg, recps);
830 }
831 }
832
833 /* Return the sum of the return codes from the hook functions. If
834 * this is an EVT_BEFORESAVE event, a nonzero return code will cause
835 * the save operation to abort.
836 */
837 return total_retval;
838}
839
840
841int PerformRoomHooks(struct ctdlroom *target_room)
842{
843 RoomFunctionHook *fcn;
844 int total_retval = 0;
845
846 syslog(LOG_DEBUG, "extensions: performing room hooks for <%s>", target_room->QRname);
847
848 for (fcn = RoomHookTable; fcn != NULL; fcn = fcn->next) {
849 total_retval = total_retval + (*fcn->fcn_ptr) (target_room);
850 }
851
852 /* Return the sum of the return codes from the hook functions.
853 */
854 return total_retval;
855}
856
857
858void PerformDeleteHooks(char *room, long msgnum)
859{
861
862 for (fcn = DeleteHookTable; fcn != NULL; fcn = fcn->next) {
863 (*fcn->h_function_pointer) (room, msgnum);
864 }
865}
866
867
868int PerformXmsgHooks(char *sender, char *sender_email, char *recp, char *msg)
869{
870 XmsgFunctionHook *fcn;
871 int total_sent = 0;
872 int p;
873
874 for (p=0; p<MAX_XMSG_PRI; ++p) {
875 for (fcn = XmsgHookTable; fcn != NULL; fcn = fcn->next) {
876 if (fcn->order == p) {
877 total_sent +=
878 (*fcn->h_function_pointer)
879 (sender, sender_email, recp, msg);
880 }
881 }
882 /* Break out of the loop if a higher-priority function
883 * successfully delivered the message. This prevents duplicate
884 * deliveries to local users simultaneously signed onto
885 * remote services.
886 */
887 if (total_sent) break;
888 }
889 return total_sent;
890}
891
892
893/*
894 * Dirty hack until we impliment a hook mechanism for this
895 */
896void CtdlModuleStartCryptoMsgs(char *ok_response, char *nosup_response, char *error_response)
897{
898#ifdef HAVE_OPENSSL
899 CtdlStartTLS (ok_response, nosup_response, error_response);
900#endif
901}
902
903
905{
906 if (!threading) {
907 }
908 return "modules";
909}
char * CtdlGetConfigStr(char *key)
Definition: config.c:393
int CtdlGetConfigInt(char *key)
Definition: config.c:426
pthread_key_t MyConKey
Definition: context.c:20
#define CTDL_MODULE_INIT(module_name)
Definition: ctdl_module.h:50
long quickie_message(const char *from, const char *fromaddr, const char *to, char *room, const char *text, int format_type, const char *subject)
Definition: msgbase.c:2921
void * malloc(size_t)
void free(void *)
void CtdlModuleStartCryptoMsgs(char *ok_response, char *nosup_response, char *error_response)
void AddPortError(char *Port, char *ErrorMessage)
void CtdlShutdownServiceHooks(void)
void CtdlUnregisterUserHook(void(*fcn_ptr)(struct ctdluser *), int EventType)
SessionFunctionHook * SessionHookTable
DeleteFunctionHook * DeleteHookTable
int PerformRoomHooks(struct ctdlroom *target_room)
MessageFunctionHook * MessageHookTable
char * ErrSubject
ConstStr Empty
void CtdlUnregisterDeleteHook(void(*handler)(char *, long))
void CtdlUnregisterServiceHook(int tcp_port, char *sockpath, void(*h_greeting_function)(void), void(*h_command_function)(void), void(*h_async_function)(void))
ConstStr ErrPortWhere
void PerformSessionHooks(int EventType)
void CtdlRegisterServiceHook(int tcp_port, char *sockpath, void(*h_greeting_function)(void), void(*h_command_function)(void), void(*h_async_function)(void), const char *ServiceName)
void CtdlRegisterSessionHook(void(*fcn_ptr)(void), int EventType, int Priority)
int PerformFixedOutputHooks(char *content_type, char *content, int content_length)
void CtdlRegisterRoomHook(int(*fcn_ptr)(struct ctdlroom *))
RoomFunctionHook * RoomHookTable
void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, const char *search_string, const char *func_name)
#define ERR_PORT
void CtdlRegisterUserHook(void(*fcn_ptr)(ctdluser *), int EventType)
XmsgFunctionHook * XmsgHookTable
void CtdlRegisterMessageHook(int(*handler)(struct CtdlMessage *, struct recptypes *), int EventType)
SearchFunctionHook * SearchFunctionHookTable
void LogPrintMessages(long err)
void CtdlRegisterFixedOutputHook(char *content_type, void(*handler)(char *, int))
void CtdlUnregisterFixedOutputHook(char *content_type)
static StrBuf * portlist
HashList * ProtoHookList
void CtdlUnregisterXmsgHook(int(*fcn_ptr)(char *, char *, char *, char *), int order)
long DetailErrorFlags
ConstStr ErrGeneral[]
UserFunctionHook * UserHookTable
void CtdlUnregisterSessionHook(void(*fcn_ptr)(void), int EventType)
FixedOutputHook * FixedOutputTable
ConstStr ErrPortHint
void PerformUserHooks(ctdluser *usbuf, int EventType)
ServiceFunctionHook * ServiceHookTable
int PerformXmsgHooks(char *sender, char *sender_email, char *recp, char *msg)
int DLoader_Exec_Cmd(char *cmdbuf)
void CtdlRegisterSearchFuncHook(void(*fcn_ptr)(int *, long **, const char *), char *name)
void CtdlUnregisterRoomHook(int(*fcn_ptr)(struct ctdlroom *))
static StrBuf * errormessages
ConstStr ErrPortShort
void CtdlRegisterXmsgHook(int(*fcn_ptr)(char *, char *, char *, char *), int order)
void CtdlRegisterDeleteHook(void(*handler)(char *, long))
void CtdlUnregisterSearchFuncHook(void(*fcn_ptr)(int *, long **, const char *), char *name)
int PerformMessageHooks(struct CtdlMessage *msg, struct recptypes *recps, int EventType)
void PerformDeleteHooks(char *room, long msgnum)
void CtdlUnregisterMessageHook(int(*handler)(struct CtdlMessage *, struct recptypes *), int EventType)
void CtdlRegisterProtoHook(void(*handler)(char *), char *cmd, char *desc)
struct ctdluser usbuf
Definition: serv_migrate.c:496
#define FMT_FIXED
Definition: server.h:177
#define CM_SKIP_HOOKS
Definition: server.h:43
@ MAX_XMSG_PRI
Definition: server.h:240
#define EVT_TIMER
Definition: server.h:224
int snprintf(char *buf, size_t max, const char *fmt,...)
Definition: snprintf.c:69
unsigned int cm_flags
Definition: server.h:39
void(* h_function_pointer)(char *target_room, long msgnum)
DeleteFunctionHook * next
void(* h_function_pointer)(char *, int)
FixedOutputHook * next
char content_type[64]
MessageFunctionHook * next
int(* h_function_pointer)(struct CtdlMessage *msg, struct recptypes *recps)
void(* handler)(char *cmdbuf)
int(* fcn_ptr)(struct ctdlroom *)
RoomFunctionHook * next
void(* fcn_ptr)(int *, long **, const char *)
SearchFunctionHook * next
void(* h_greeting_function)(void)
void(* h_async_function)(void)
void(* h_command_function)(void)
const char * ServiceName
ServiceFunctionHook * next
void(* h_function_pointer)(void)
SessionFunctionHook * next
void(* h_function_pointer)(struct ctdluser *usbuf)
UserFunctionHook * next
XmsgFunctionHook * next
int(* h_function_pointer)(char *, char *, char *, char *)
char QRname[128]
Definition: citadel.h:108
#define SIZ
Definition: sysconfig.h:33
#define AIDEROOM
Definition: sysconfig.h:63
int ctdl_tcp_server(char *ip_addr, int port_number, int queue_len)
Definition: sysdep.c:112
int ctdl_uds_server(char *sockpath, int queue_len)
Definition: sysdep.c:198