text client <.A>ide <S>ysconfig <I>nternet , when encountering a "directory" domain...
[citadel.git] / citadel / modules / inetcfg / serv_inetcfg.c
1 /*
2  * This module handles the loading/saving and maintenance of the
3  * system's Internet configuration.  It's not an optional component; I
4  * wrote it as a module merely to keep things as clean and loosely coupled
5  * as possible.
6  *
7  * Copyright (c) 1987-2017 by the citadel.org team
8  *
9  * This program is open source software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 3.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17
18 #include "sysdep.h"
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <stdio.h>
22 #include <fcntl.h>
23 #include <signal.h>
24 #include <pwd.h>
25 #include <errno.h>
26 #include <sys/types.h>
27
28 #if TIME_WITH_SYS_TIME
29 # include <sys/time.h>
30 # include <time.h>
31 #else
32 # if HAVE_SYS_TIME_H
33 #  include <sys/time.h>
34 # else
35 #  include <time.h>
36 # endif
37 #endif
38
39 #include <sys/wait.h>
40 #include <string.h>
41 #include <limits.h>
42 #include <libcitadel.h>
43 #include "citadel.h"
44 #include "server.h"
45 #include "citserver.h"
46 #include "support.h"
47 #include "config.h"
48 #include "user_ops.h"
49 #include "database.h"
50 #include "msgbase.h"
51 #include "internet_addressing.h"
52 #include "genstamp.h"
53 #include "domain.h"
54 #include "ctdl_module.h"
55
56
57 void inetcfg_setTo(struct CtdlMessage *msg) {
58         char *conf;
59         char buf[SIZ];
60         
61         if (CM_IsEmpty(msg, eMesageText)) return;
62         conf = strdup(msg->cm_fields[eMesageText]);
63
64         if (conf != NULL) {
65                 do {
66                         extract_token(buf, conf, 0, '\n', sizeof buf);
67                         strcpy(conf, &conf[strlen(buf)+1]);
68                 } while ( (!IsEmptyStr(conf)) && (!IsEmptyStr(buf)) );
69
70                 if (inetcfg != NULL) free(inetcfg);
71                 inetcfg = conf;
72         }
73 }
74
75
76 /*
77  * This handler detects changes being made to the system's Internet
78  * configuration.
79  */
80 int inetcfg_aftersave(struct CtdlMessage *msg, recptypes *recp) {
81         char *ptr;
82         int linelen;
83
84         /* If this isn't the configuration room, or if this isn't a MIME
85          * message, don't bother.
86          */
87         if ((msg->cm_fields[eOriginalRoom]) && (strcasecmp(msg->cm_fields[eOriginalRoom], SYSCONFIGROOM))) {
88                 return(0);
89         }
90         if (msg->cm_format_type != 4) {
91                 return(0);
92         }
93
94         ptr = msg->cm_fields[eMesageText];
95         while (ptr != NULL) {
96         
97                 linelen = strcspn(ptr, "\n");
98                 if (linelen == 0) {
99                         return(0);      /* end of headers */    
100                 }
101                 
102                 if (!strncasecmp(ptr, "Content-type: ", 14)) {
103                         if (!strncasecmp(&ptr[14], INTERNETCFG, strlen(INTERNETCFG))) {
104                                 inetcfg_setTo(msg);     /* changing configs */
105                         }
106                 }
107
108                 ptr = strchr((char *)ptr, '\n');
109                 if (ptr != NULL) ++ptr;
110         }
111
112         return(0);
113 }
114
115
116 void inetcfg_init_backend(long msgnum, void *userdata) {
117         struct CtdlMessage *msg;
118
119         msg = CtdlFetchMessage(msgnum, 1, 1);
120         if (msg != NULL) {
121                 inetcfg_setTo(msg);
122                 CM_Free(msg);
123         }
124 }
125
126
127 void inetcfg_init(void) {
128         if (CtdlGetRoom(&CC->room, SYSCONFIGROOM) != 0) {
129                 return;
130         }
131         CtdlForEachMessage(MSGS_LAST, 1, NULL, INTERNETCFG, NULL, inetcfg_init_backend, NULL);
132 }
133
134
135 /*****************************************************************************/
136 /*                      MODULE INITIALIZATION STUFF                          */
137 /*****************************************************************************/
138 void cleanup_inetcfg(void)
139 {
140         char *buf;
141         buf = inetcfg;
142         inetcfg = NULL;
143         if (buf != NULL) {
144                 free(buf);
145         }
146 }
147
148
149 CTDL_MODULE_INIT(inetcfg)
150 {
151         if (!threading)
152         {
153                 CtdlRegisterMessageHook(inetcfg_aftersave, EVT_AFTERSAVE);
154                 inetcfg_init();
155                 CtdlRegisterCleanupHook(cleanup_inetcfg);
156         }
157         
158         /* return our module name for the log */
159         return "inetcfg";
160 }