Still waiting...
[citadel.git] / citadel / server / modules / inetcfg / serv_inetcfg.c
1 // This module handles the loading/saving and maintenance of the
2 // system's Internet configuration.  It's not an optional component; I
3 // wrote it as a module merely to keep things as clean and loosely coupled
4 // as possible.
5 //
6 // Copyright (c) 1987-2024 by the citadel.org team
7 //
8 // This program is open source software.  Use, duplication, or disclosure
9 // is subject to the terms of the GNU General Public License version 3.
10
11 #include "../../sysdep.h"
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <stdio.h>
15 #include <fcntl.h>
16 #include <signal.h>
17 #include <pwd.h>
18 #include <errno.h>
19 #include <sys/types.h>
20 #include <time.h>
21 #include <sys/wait.h>
22 #include <string.h>
23 #include <limits.h>
24 #include <libcitadel.h>
25 #include "../../citadel_defs.h"
26 #include "../../server.h"
27 #include "../../citserver.h"
28 #include "../../support.h"
29 #include "../../config.h"
30 #include "../../user_ops.h"
31 #include "../../database.h"
32 #include "../../msgbase.h"
33 #include "../../internet_addressing.h"
34 #include "../../genstamp.h"
35 #include "../../domain.h"
36 #include "../../ctdl_module.h"
37
38
39 void inetcfg_setTo(struct CtdlMessage *msg) {
40         char *conf;
41         char buf[SIZ];
42         
43         if (CM_IsEmpty(msg, eMessageText)) return;
44         conf = strdup(msg->cm_fields[eMessageText]);
45
46         if (conf != NULL) {
47                 do {
48                         extract_token(buf, conf, 0, '\n', sizeof buf);
49                         strcpy(conf, &conf[strlen(buf)+1]);
50                 } while ( (!IsEmptyStr(conf)) && (!IsEmptyStr(buf)) );
51
52                 if (inetcfg != NULL) free(inetcfg);
53                 inetcfg = conf;
54         }
55 }
56
57
58 // This handler detects changes being made to the system's Internet configuration.
59 int inetcfg_aftersave(struct CtdlMessage *msg, struct recptypes *recp) {
60         char *ptr;
61         int linelen;
62
63         // If this isn't the configuration room, or if this isn't a MIME message ... don't bother.
64         if ((msg->cm_fields[eOriginalRoom]) && (strcasecmp(msg->cm_fields[eOriginalRoom], SYSCONFIGROOM))) {
65                 return(0);
66         }
67         if (msg->cm_format_type != 4) {
68                 return(0);
69         }
70
71         ptr = msg->cm_fields[eMessageText];
72         while (ptr != NULL) {
73         
74                 linelen = strcspn(ptr, "\n");
75                 if (linelen == 0) {
76                         return(0);                      // end of headers
77                 }
78                 
79                 if (!strncasecmp(ptr, "Content-type: ", 14)) {
80                         if (!strncasecmp(&ptr[14], INTERNETCFG, strlen(INTERNETCFG))) {
81                                 inetcfg_setTo(msg);     // changing configs
82                         }
83                 }
84
85                 ptr = strchr((char *)ptr, '\n');
86                 if (ptr != NULL) ++ptr;
87         }
88
89         return(0);
90 }
91
92
93 void inetcfg_init_backend(long msgnum, void *userdata) {
94         struct CtdlMessage *msg;
95
96         msg = CtdlFetchMessage(msgnum, 1);
97         syslog(LOG_DEBUG, "inetcfg: config msg %ld is %s", msgnum, msg ? "not null" : "null");
98         if (msg != NULL) {
99                 inetcfg_setTo(msg);
100                 CM_Free(msg);
101         }
102 }
103
104
105 void inetcfg_init(void) {
106         syslog(LOG_DEBUG, "inetcfg: inetcfg_init() started");
107         if (CtdlGetRoom(&CC->room, SYSCONFIGROOM) != 0) {
108                 syslog(LOG_WARNING, "inetcfg: could not find <%s>", SYSCONFIGROOM);
109                 return;
110         }
111         CtdlForEachMessage(MSGS_LAST, 1, NULL, INTERNETCFG, NULL, inetcfg_init_backend, NULL);
112         syslog(LOG_DEBUG, "inetcfg: inetcfg_init() completed");
113 }
114
115
116 // Initialization function, called from modules_init.c
117 char *ctdl_module_init_inetcfg(void) {
118         if (!threading) {
119                 CtdlRegisterMessageHook(inetcfg_aftersave, EVT_AFTERSAVE);
120                 inetcfg_init();
121         }
122         
123         // return our module name for the log
124         return "inetcfg";
125 }