X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fserv_extensions.c;h=1934e0de008fe53a29b4410ce3774cae3a8404bc;hb=11219dbc3e638e7ee47feffbbb7d63588d7dd77f;hp=3ff6d2c282222e6010e75cf4f01c81f666ac8a6d;hpb=0570c7fd15495912f7ae76a56665bb95827f9470;p=citadel.git diff --git a/citadel/serv_extensions.c b/citadel/serv_extensions.c index 3ff6d2c28..1934e0de0 100644 --- a/citadel/serv_extensions.c +++ b/citadel/serv_extensions.c @@ -28,7 +28,6 @@ #include "snprintf.h" #endif -struct LogFunctionHook *LogHookTable = NULL; struct CleanupFunctionHook *CleanupHookTable = NULL; struct SessionFunctionHook *SessionHookTable = NULL; struct UserFunctionHook *UserHookTable = NULL; @@ -37,6 +36,7 @@ struct MessageFunctionHook *MessageHookTable = NULL; struct NetprocFunctionHook *NetprocHookTable = NULL; struct DeleteFunctionHook *DeleteHookTable = NULL; struct ServiceFunctionHook *ServiceHookTable = NULL; +struct FixedOutputHook *FixedOutputTable = NULL; struct ProtoFunctionHook { void (*handler) (char *cmdbuf); @@ -45,12 +45,115 @@ struct ProtoFunctionHook { struct ProtoFunctionHook *next; } *ProtoHookList = NULL; + +#define ERR_PORT (1 << 1) + + +static char *portlist = NULL; +static size_t nSizPort = 0; + +static char *errormessages = NULL; +static size_t nSizErrmsg = 0; + + +static long DetailErrorFlags; + + +char *ErrSubject = "Startup Problems"; +char *ErrGeneral = "Citadel had trouble on starting up. %s This means, citadel won't be the service provider for a specific service you configured it to.\n\n" +"If you don't want citadel to provide these services, turn them off in WebCit via %s%s\n\n%s\n\n" +"To make both ways actualy take place restart the citserver with \"sendcommand down\"\n\n" +"The errors returned by the system were:\n%s\n"; + + +char *ErrPortShort = "We couldn't bind all ports you configured to be provided by citadel server."; +char *ErrPortWhere = "Admin->System Preferences->Network.\n\nThe failed ports and sockets are: "; +char *ErrPortHint = "If you want citadel to provide you with that functionality, " +"check the output of \"netstat -lnp\" on linux Servers or \"netstat -na\" on *BSD" +" and stop the programm, that binds these ports. You should eventually remove " +" their initscripts in /etc/init.d so that you won't get this trouble once more.\n"; + + +void LogPrintMessages(long err) +{ + char *List, *DetailList, *Short, *Where, *Hint, *Message; + int n = nSizPort + nSizErrmsg + 5; + + Message = (char*) malloc(n * SIZ); + + switch (err) + { + case ERR_PORT: + Short = ErrPortShort; + Where = ErrPortWhere; + Hint = ErrPortHint; + List = portlist; + DetailList = errormessages; + break; + default: + Short = ""; + Where = ""; + Hint = ""; + List = ""; + DetailList = ""; + } + + + snprintf(Message, n * SIZ, ErrGeneral, Short, Where, List, Hint, DetailList); + + quickie_message("Citadel", NULL, NULL, AIDEROOM, Message, FMT_FIXED, ErrSubject); + free(Message); +} + + + +void AppendString(char **target, char *append, size_t *len, size_t rate) +{ + size_t oLen = 0; + long AddLen; + long RelPtr = 0; + + AddLen = strlen(append); + + if (*len == 0) + { + *len = rate; + + *target = (char*)malloc (*len * SIZ); + } + else + { + oLen = strlen(*target); + RelPtr = strlen(*target); + if (oLen + AddLen + 2 > *len * SIZ) + { + char *Buff = *target; + size_t NewSiz = *len + 10; + *target = malloc (NewSiz * SIZ); + memcpy (*target, Buff, NewSiz * SIZ); + *len = NewSiz; + } + } + memcpy (*target + oLen, append, AddLen); + (*target)[AddLen + 1] = '\n'; + (*target)[AddLen + 2] = '\0'; +} + +void AddPortError(char *Port, char *ErrorMessage) +{ + DetailErrorFlags |= ERR_PORT; + + AppendString(&errormessages, ErrorMessage, &nSizErrmsg, 10); + AppendString(&portlist, Port, &nSizPort, 2); +} + + void CtdlRegisterProtoHook(void (*handler) (char *), char *cmd, char *desc) { struct ProtoFunctionHook *p; p = (struct ProtoFunctionHook *) - mallok(sizeof(struct ProtoFunctionHook)); + malloc(sizeof(struct ProtoFunctionHook)); if (p == NULL) { fprintf(stderr, "can't malloc new ProtoFunctionHook\n"); @@ -61,7 +164,7 @@ void CtdlRegisterProtoHook(void (*handler) (char *), char *cmd, char *desc) p->desc = desc; p->next = ProtoHookList; ProtoHookList = p; - lprintf(5, "Registered server command %s (%s)\n", cmd, desc); + lprintf(CTDL_INFO, "Registered server command %s (%s)\n", cmd, desc); } @@ -74,13 +177,13 @@ void CtdlUnregisterProtoHook(void (*handler) (char *), char *cmd) while (cur != NULL && handler == cur->handler && !strcmp(cmd, cur->cmd)) { - lprintf(5, "Unregistered server command %s (%s)\n", + lprintf(CTDL_INFO, "Unregistered server command %s (%s)\n", cmd, cur->desc); p = cur->next; if (cur == ProtoHookList) { ProtoHookList = p; } - phree(cur); + free(cur); cur = p; } } @@ -102,80 +205,55 @@ int DLoader_Exec_Cmd(char *cmdbuf) void initialize_server_extensions(void) { - serv_bio_init(); - serv_calendar_init(); - serv_ldap_init(); - serv_chat_init(); - serv_expire_init(); - serv_imap_init(); - serv_inetcfg_init(); - serv_listsub_init(); - serv_mrtg_init(); - serv_netfilter_init(); - serv_network_init(); - serv_newuser_init(); - serv_pas2_init(); - serv_pop3_init(); - serv_rwho_init(); - serv_smtp_init(); - serv_spam_init(); - /* serv_test_init(); */ - serv_upgrade_init(); - serv_vandelay_init(); - serv_vcard_init(); + long filter; + + lprintf(CTDL_INFO, "%s\n", serv_bio_init()); + lprintf(CTDL_INFO, "%s\n", serv_calendar_init()); + lprintf(CTDL_INFO, "%s\n", serv_notes_init()); + lprintf(CTDL_INFO, "%s\n", serv_ldap_init()); + lprintf(CTDL_INFO, "%s\n", serv_chat_init()); + lprintf(CTDL_INFO, "%s\n", serv_expire_init()); + lprintf(CTDL_INFO, "%s\n", serv_imap_init()); + lprintf(CTDL_INFO, "%s\n", serv_upgrade_init()); + lprintf(CTDL_INFO, "%s\n", serv_inetcfg_init()); + lprintf(CTDL_INFO, "%s\n", serv_listsub_init()); + lprintf(CTDL_INFO, "%s\n", serv_mrtg_init()); + lprintf(CTDL_INFO, "%s\n", serv_netfilter_init()); + lprintf(CTDL_INFO, "%s\n", serv_network_init()); + lprintf(CTDL_INFO, "%s\n", serv_newuser_init()); + lprintf(CTDL_INFO, "%s\n", serv_pas2_init()); + lprintf(CTDL_INFO, "%s\n", serv_smtp_init()); + lprintf(CTDL_INFO, "%s\n", serv_pop3_init()); + lprintf(CTDL_INFO, "%s\n", serv_rwho_init()); + lprintf(CTDL_INFO, "%s\n", serv_spam_init()); + /* lprintf(CTDL_INFO, "%s\n", serv_test_init()); */ + lprintf(CTDL_INFO, "%s\n", serv_vandelay_init()); + lprintf(CTDL_INFO, "%s\n", serv_vcard_init()); + lprintf(CTDL_INFO, "%s\n", serv_fulltext_init()); + lprintf(CTDL_INFO, "%s\n", serv_autocompletion_init()); + lprintf(CTDL_INFO, "%s\n", serv_postfix_tcpdict()); + lprintf(CTDL_INFO, "%s\n", serv_sieve_init()); + lprintf(CTDL_INFO, "%s\n", serv_managesieve_init()); + + for (filter = 1; filter != 0; filter = filter << 1) + if ((filter & DetailErrorFlags) != 0) + LogPrintMessages(filter); } -void CtdlRegisterLogHook(void (*fcn_ptr) (char *), int loglevel) -{ - - struct LogFunctionHook *newfcn; - - newfcn = (struct LogFunctionHook *) - mallok(sizeof(struct LogFunctionHook)); - newfcn->next = LogHookTable; - newfcn->h_function_pointer = fcn_ptr; - newfcn->loglevel = loglevel; - LogHookTable = newfcn; - - lprintf(5, "Registered a new logging function\n"); -} - - -void CtdlUnregisterLogHook(void (*fcn_ptr) (char *), int loglevel) -{ - struct LogFunctionHook *cur, *p; - - for (cur = LogHookTable; cur != NULL; cur = cur->next) { - /* This will also remove duplicates if any */ - while (cur != NULL && - fcn_ptr == cur->h_function_pointer && - loglevel == cur->loglevel) { - lprintf(5, "Unregistered logging function\n"); - p = cur->next; - if (cur == LogHookTable) { - LogHookTable = p; - } - phree(cur); - cur = p; - } - } -} - - void CtdlRegisterCleanupHook(void (*fcn_ptr) (void)) { struct CleanupFunctionHook *newfcn; newfcn = (struct CleanupFunctionHook *) - mallok(sizeof(struct CleanupFunctionHook)); + malloc(sizeof(struct CleanupFunctionHook)); newfcn->next = CleanupHookTable; newfcn->h_function_pointer = fcn_ptr; CleanupHookTable = newfcn; - lprintf(5, "Registered a new cleanup function\n"); + lprintf(CTDL_INFO, "Registered a new cleanup function\n"); } @@ -187,12 +265,12 @@ void CtdlUnregisterCleanupHook(void (*fcn_ptr) (void)) /* This will also remove duplicates if any */ while (cur != NULL && fcn_ptr == cur->h_function_pointer) { - lprintf(5, "Unregistered cleanup function\n"); + lprintf(CTDL_INFO, "Unregistered cleanup function\n"); p = cur->next; if (cur == CleanupHookTable) { CleanupHookTable = p; } - phree(cur); + free(cur); cur = p; } } @@ -205,13 +283,13 @@ void CtdlRegisterSessionHook(void (*fcn_ptr) (void), int EventType) struct SessionFunctionHook *newfcn; newfcn = (struct SessionFunctionHook *) - mallok(sizeof(struct SessionFunctionHook)); + malloc(sizeof(struct SessionFunctionHook)); newfcn->next = SessionHookTable; newfcn->h_function_pointer = fcn_ptr; newfcn->eventtype = EventType; SessionHookTable = newfcn; - lprintf(5, "Registered a new session function (type %d)\n", + lprintf(CTDL_INFO, "Registered a new session function (type %d)\n", EventType); } @@ -225,37 +303,37 @@ void CtdlUnregisterSessionHook(void (*fcn_ptr) (void), int EventType) while (cur != NULL && fcn_ptr == cur->h_function_pointer && EventType == cur->eventtype) { - lprintf(5, "Unregistered session function (type %d)\n", + lprintf(CTDL_INFO, "Unregistered session function (type %d)\n", EventType); p = cur->next; if (cur == SessionHookTable) { SessionHookTable = p; } - phree(cur); + free(cur); cur = p; } } } -void CtdlRegisterUserHook(void (*fcn_ptr) (char *, long), int EventType) +void CtdlRegisterUserHook(void (*fcn_ptr) (struct ctdluser *), int EventType) { struct UserFunctionHook *newfcn; newfcn = (struct UserFunctionHook *) - mallok(sizeof(struct UserFunctionHook)); + malloc(sizeof(struct UserFunctionHook)); newfcn->next = UserHookTable; newfcn->h_function_pointer = fcn_ptr; newfcn->eventtype = EventType; UserHookTable = newfcn; - lprintf(5, "Registered a new user function (type %d)\n", + lprintf(CTDL_INFO, "Registered a new user function (type %d)\n", EventType); } -void CtdlUnregisterUserHook(void (*fcn_ptr) (char *, long), int EventType) +void CtdlUnregisterUserHook(void (*fcn_ptr) (struct ctdluser *), int EventType) { struct UserFunctionHook *cur, *p; @@ -264,13 +342,13 @@ void CtdlUnregisterUserHook(void (*fcn_ptr) (char *, long), int EventType) while (cur != NULL && fcn_ptr == cur->h_function_pointer && EventType == cur->eventtype) { - lprintf(5, "Unregistered user function (type %d)\n", + lprintf(CTDL_INFO, "Unregistered user function (type %d)\n", EventType); p = cur->next; if (cur == UserHookTable) { UserHookTable = p; } - phree(cur); + free(cur); cur = p; } } @@ -284,13 +362,13 @@ void CtdlRegisterMessageHook(int (*handler)(struct CtdlMessage *), struct MessageFunctionHook *newfcn; newfcn = (struct MessageFunctionHook *) - mallok(sizeof(struct MessageFunctionHook)); + malloc(sizeof(struct MessageFunctionHook)); newfcn->next = MessageHookTable; newfcn->h_function_pointer = handler; newfcn->eventtype = EventType; MessageHookTable = newfcn; - lprintf(5, "Registered a new message function (type %d)\n", + lprintf(CTDL_INFO, "Registered a new message function (type %d)\n", EventType); } @@ -305,13 +383,13 @@ void CtdlUnregisterMessageHook(int (*handler)(struct CtdlMessage *), while (cur != NULL && handler == cur->h_function_pointer && EventType == cur->eventtype) { - lprintf(5, "Unregistered message function (type %d)\n", + lprintf(CTDL_INFO, "Unregistered message function (type %d)\n", EventType); p = cur->next; if (cur == MessageHookTable) { MessageHookTable = p; } - phree(cur); + free(cur); cur = p; } } @@ -323,12 +401,12 @@ void CtdlRegisterNetprocHook(int (*handler)(struct CtdlMessage *, char *) ) struct NetprocFunctionHook *newfcn; newfcn = (struct NetprocFunctionHook *) - mallok(sizeof(struct NetprocFunctionHook)); + malloc(sizeof(struct NetprocFunctionHook)); newfcn->next = NetprocHookTable; newfcn->h_function_pointer = handler; NetprocHookTable = newfcn; - lprintf(5, "Registered a new netproc function\n"); + lprintf(CTDL_INFO, "Registered a new netproc function\n"); } @@ -340,12 +418,12 @@ void CtdlUnregisterNetprocHook(int (*handler)(struct CtdlMessage *, char *) ) /* This will also remove duplicates if any */ while (cur != NULL && handler == cur->h_function_pointer ) { - lprintf(5, "Unregistered netproc function\n"); + lprintf(CTDL_INFO, "Unregistered netproc function\n"); p = cur->next; if (cur == NetprocHookTable) { NetprocHookTable = p; } - phree(cur); + free(cur); cur = p; } } @@ -357,12 +435,12 @@ void CtdlRegisterDeleteHook(void (*handler)(char *, long) ) struct DeleteFunctionHook *newfcn; newfcn = (struct DeleteFunctionHook *) - mallok(sizeof(struct DeleteFunctionHook)); + malloc(sizeof(struct DeleteFunctionHook)); newfcn->next = DeleteHookTable; newfcn->h_function_pointer = handler; DeleteHookTable = newfcn; - lprintf(5, "Registered a new netproc function\n"); + lprintf(CTDL_INFO, "Registered a new netproc function\n"); } @@ -374,17 +452,70 @@ void CtdlUnregisterDeleteHook(void (*handler)(char *, long) ) /* This will also remove duplicates if any */ while (cur != NULL && handler == cur->h_function_pointer ) { - lprintf(5, "Unregistered netproc function\n"); + lprintf(CTDL_INFO, "Unregistered netproc function\n"); p = cur->next; if (cur == DeleteHookTable) { DeleteHookTable = p; } - phree(cur); + free(cur); + cur = p; + } + } +} + + + + +void CtdlRegisterFixedOutputHook(char *content_type, void (*handler)(char *, int) ) +{ + struct FixedOutputHook *newfcn; + + newfcn = (struct FixedOutputHook *) + malloc(sizeof(struct FixedOutputHook)); + newfcn->next = FixedOutputTable; + newfcn->h_function_pointer = handler; + safestrncpy(newfcn->content_type, content_type, sizeof newfcn->content_type); + FixedOutputTable = newfcn; + + lprintf(CTDL_INFO, "Registered a new fixed output function for %s\n", newfcn->content_type); +} + + +void CtdlUnregisterFixedOutputHook(char *content_type) +{ + struct FixedOutputHook *cur, *p; + + for (cur = FixedOutputTable; cur != NULL; cur = cur->next) { + /* This will also remove duplicates if any */ + while (cur != NULL && (!strcasecmp(content_type, cur->content_type))) { + lprintf(CTDL_INFO, "Unregistered fixed output function for %s\n", content_type); + p = cur->next; + if (cur == FixedOutputTable) { + FixedOutputTable = p; + } + free(cur); cur = p; } } } +/* returns nonzero if we found a hook and used it */ +int PerformFixedOutputHooks(char *content_type, char *content, int content_length) +{ + struct FixedOutputHook *fcn; + + for (fcn = FixedOutputTable; fcn != NULL; fcn = fcn->next) { + if (!strcasecmp(content_type, fcn->content_type)) { + (*fcn->h_function_pointer) (content, content_length); + return(1); + } + } + return(0); +} + + + + void CtdlRegisterXmsgHook(int (*fcn_ptr) (char *, char *, char *), int order) { @@ -392,12 +523,12 @@ void CtdlRegisterXmsgHook(int (*fcn_ptr) (char *, char *, char *), int order) struct XmsgFunctionHook *newfcn; newfcn = (struct XmsgFunctionHook *) - mallok(sizeof(struct XmsgFunctionHook)); + malloc(sizeof(struct XmsgFunctionHook)); newfcn->next = XmsgHookTable; newfcn->order = order; newfcn->h_function_pointer = fcn_ptr; XmsgHookTable = newfcn; - lprintf(5, "Registered a new x-msg function (priority %d)\n", order); + lprintf(CTDL_INFO, "Registered a new x-msg function (priority %d)\n", order); } @@ -410,13 +541,13 @@ void CtdlUnregisterXmsgHook(int (*fcn_ptr) (char *, char *, char *), int order) while (cur != NULL && fcn_ptr == cur->h_function_pointer && order == cur->order) { - lprintf(5, "Unregistered x-msg function " + lprintf(CTDL_INFO, "Unregistered x-msg function " "(priority %d)\n", order); p = cur->next; if (cur == XmsgHookTable) { XmsgHookTable = p; } - phree(cur); + free(cur); cur = p; } } @@ -426,49 +557,63 @@ void CtdlUnregisterXmsgHook(int (*fcn_ptr) (char *, char *, char *), int order) void CtdlRegisterServiceHook(int tcp_port, char *sockpath, void (*h_greeting_function) (void), - void (*h_command_function) (void) ) + void (*h_command_function) (void), + void (*h_async_function) (void) + ) { struct ServiceFunctionHook *newfcn; - char message[SIZ]; + char *message; + char *error; newfcn = (struct ServiceFunctionHook *) - mallok(sizeof(struct ServiceFunctionHook)); + malloc(sizeof(struct ServiceFunctionHook)); + message = (char*) malloc (SIZ); + newfcn->next = ServiceHookTable; newfcn->tcp_port = tcp_port; newfcn->sockpath = sockpath; newfcn->h_greeting_function = h_greeting_function; newfcn->h_command_function = h_command_function; + newfcn->h_async_function = h_async_function; if (sockpath != NULL) { - newfcn->msock = ig_uds_server(sockpath, config.c_maxsessions); - snprintf(message, sizeof message, "Unix domain socket '%s': ", sockpath); + newfcn->msock = ig_uds_server(sockpath, config.c_maxsessions, &error); + snprintf(message, SIZ, "Unix domain socket '%s': ", sockpath); } else if (tcp_port <= 0) { /* port -1 to disable */ - lprintf(7, "Service has been manually disabled, skipping\n"); - phree(newfcn); + lprintf(CTDL_INFO, "Service has been manually disabled, skipping\n"); + free(newfcn); return; } else { - newfcn->msock = ig_tcp_server(tcp_port, config.c_maxsessions); - snprintf(message, sizeof message, "TCP port %d: ", tcp_port); + newfcn->msock = ig_tcp_server(config.c_ip_addr, + tcp_port, + config.c_maxsessions, + &error); + snprintf(message, SIZ, "TCP port %d: ", tcp_port); } if (newfcn->msock > 0) { ServiceHookTable = newfcn; strcat(message, "registered."); - lprintf(5, "%s\n", message); + lprintf(CTDL_INFO, "%s\n", message); } else { + AddPortError(message, error); strcat(message, "FAILED."); - lprintf(2, "%s\n", message); - phree(newfcn); + lprintf(CTDL_CRIT, "%s\n", message); + free(error); + free(newfcn); } + free(message); } void CtdlUnregisterServiceHook(int tcp_port, char *sockpath, void (*h_greeting_function) (void), - void (*h_command_function) (void) ) + void (*h_command_function) (void), + void (*h_async_function) (void) + ) { struct ServiceFunctionHook *cur, *p; @@ -479,21 +624,22 @@ void CtdlUnregisterServiceHook(int tcp_port, char *sockpath, strcmp(sockpath, cur->sockpath)) && h_greeting_function == cur->h_greeting_function && h_command_function == cur->h_command_function && + h_async_function == cur->h_async_function && tcp_port == cur->tcp_port) { close(cur->msock); if (sockpath) { - lprintf(5, "Closed UNIX domain socket %s\n", + lprintf(CTDL_INFO, "Closed UNIX domain socket %s\n", sockpath); } else if (tcp_port) { - lprintf(5, "Closed TCP port %d\n", tcp_port); + lprintf(CTDL_INFO, "Closed TCP port %d\n", tcp_port); } else { - lprintf(5, "Unregistered unknown service\n"); + lprintf(CTDL_INFO, "Unregistered unknown service\n"); } p = cur->next; if (cur == ServiceHookTable) { ServiceHookTable = p; } - phree(cur); + free(cur); cur = p; } } @@ -511,24 +657,13 @@ void PerformSessionHooks(int EventType) } } -void PerformLogHooks(int loglevel, char *logmsg) -{ - struct LogFunctionHook *fcn; - - for (fcn = LogHookTable; fcn != NULL; fcn = fcn->next) { - if (fcn->loglevel >= loglevel) { - (*fcn->h_function_pointer) (logmsg); - } - } -} - -void PerformUserHooks(char *username, long usernum, int EventType) +void PerformUserHooks(struct ctdluser *usbuf, int EventType) { struct UserFunctionHook *fcn; for (fcn = UserHookTable; fcn != NULL; fcn = fcn->next) { if (fcn->eventtype == EventType) { - (*fcn->h_function_pointer) (username, usernum); + (*fcn->h_function_pointer) (usbuf); } } } @@ -540,11 +675,11 @@ int PerformMessageHooks(struct CtdlMessage *msg, int EventType) /* Other code may elect to protect this message from server-side * handlers; if this is the case, don't do anything. - lprintf(9, "** Event type is %d, flags are %d\n", + lprintf(CTDL_DEBUG, "** Event type is %d, flags are %d\n", EventType, msg->cm_flags); */ if (msg->cm_flags & CM_SKIP_HOOKS) { - lprintf(9, "Skipping hooks\n"); + lprintf(CTDL_DEBUG, "Skipping hooks\n"); return(0); } @@ -594,6 +729,8 @@ void PerformDeleteHooks(char *room, long msgnum) + + int PerformXmsgHooks(char *sender, char *recp, char *msg) { struct XmsgFunctionHook *fcn;