3ac9339c2045d65573e411c741fe0053b6f3ea49
[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-2009 by the citadel.org team
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 3 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include "sysdep.h"
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <stdio.h>
28 #include <fcntl.h>
29 #include <signal.h>
30 #include <pwd.h>
31 #include <errno.h>
32 #include <sys/types.h>
33
34 #if TIME_WITH_SYS_TIME
35 # include <sys/time.h>
36 # include <time.h>
37 #else
38 # if HAVE_SYS_TIME_H
39 #  include <sys/time.h>
40 # else
41 #  include <time.h>
42 # endif
43 #endif
44
45 #include <sys/wait.h>
46 #include <string.h>
47 #include <limits.h>
48 #include <libcitadel.h>
49 #include "citadel.h"
50 #include "server.h"
51 #include "citserver.h"
52 #include "support.h"
53 #include "config.h"
54 #include "user_ops.h"
55 #include "database.h"
56 #include "msgbase.h"
57 #include "internet_addressing.h"
58 #include "genstamp.h"
59 #include "domain.h"
60
61
62 #include "ctdl_module.h"
63
64
65 void inetcfg_setTo(struct CtdlMessage *msg) {
66         char *conf;
67         char buf[SIZ];
68         
69         if (msg->cm_fields['M']==NULL) return;
70         conf = strdup(msg->cm_fields['M']);
71
72         if (conf != NULL) {
73                 do {
74                         extract_token(buf, conf, 0, '\n', sizeof buf);
75                         strcpy(conf, &conf[strlen(buf)+1]);
76                 } while ( (!IsEmptyStr(conf)) && (!IsEmptyStr(buf)) );
77
78                 if (inetcfg != NULL) free(inetcfg);
79                 inetcfg = conf;
80         }
81 }
82
83
84 #ifdef ___NOT_CURRENTLY_IN_USE___
85 void spamstrings_setTo(struct CtdlMessage *msg) {
86         char buf[SIZ];
87         char *conf;
88         struct spamstrings_t *sptr;
89         int i, n;
90
91         /* Clear out the existing list */
92         while (spamstrings != NULL) {
93                 sptr = spamstrings;
94                 spamstrings = spamstrings->next;
95                 free(sptr->string);
96                 free(sptr);
97         }
98
99         /* Read in the new list */
100         if (msg->cm_fields['M']==NULL) return;
101         conf = strdup(msg->cm_fields['M']);
102         if (conf == NULL) return;
103
104         n = num_tokens(conf, '\n');
105         for (i=0; i<n; ++i) {
106                 extract_token(buf, conf, i, '\n', sizeof buf);
107                 sptr = malloc(sizeof(struct spamstrings_t));
108                 sptr->string = strdup(buf);
109                 sptr->next = spamstrings;
110                 spamstrings = sptr;
111         }
112
113 }
114 #endif
115
116
117 /*
118  * This handler detects changes being made to the system's Internet
119  * configuration.
120  */
121 int inetcfg_aftersave(struct CtdlMessage *msg) {
122         char *ptr;
123         int linelen;
124
125         /* If this isn't the configuration room, or if this isn't a MIME
126          * message, don't bother.
127          */
128         if (strcasecmp(msg->cm_fields['O'], SYSCONFIGROOM)) return(0);
129         if (msg->cm_format_type != 4) return(0);
130
131         ptr = msg->cm_fields['M'];
132         while (ptr != NULL) {
133         
134                 linelen = strcspn(ptr, "\n");
135                 if (linelen == 0) return(0);    /* end of headers */    
136                 
137                 if (!strncasecmp(ptr, "Content-type: ", 14)) {
138                         if (!strncasecmp(&ptr[14], INTERNETCFG,
139                            strlen(INTERNETCFG))) {
140                                 inetcfg_setTo(msg);     /* changing configs */
141                         }
142                 }
143
144                 ptr = strchr((char *)ptr, '\n');
145                 if (ptr != NULL) ++ptr;
146         }
147
148         return(0);
149 }
150
151
152 void inetcfg_init_backend(long msgnum, void *userdata) {
153         struct CtdlMessage *msg;
154
155         msg = CtdlFetchMessage(msgnum, 1);
156         if (msg != NULL) {
157                 inetcfg_setTo(msg);
158                 CtdlFreeMessage(msg);
159         }
160 }
161
162
163 #ifdef ___NOT_CURRENTLY_IN_USE___
164 void spamstrings_init_backend(long msgnum, void *userdata) {
165         struct CtdlMessage *msg;
166
167         msg = CtdlFetchMessage(msgnum, 1);
168         if (msg != NULL) {
169                 spamstrings_setTo(msg);
170                 CtdlFreeMessage(msg);
171         }
172 }
173 #endif
174
175
176 void inetcfg_init(void) {
177         if (CtdlGetRoom(&CC->room, SYSCONFIGROOM) != 0) return;
178         CtdlForEachMessage(MSGS_LAST, 1, NULL, INTERNETCFG, NULL,
179                 inetcfg_init_backend, NULL);
180 }
181
182
183
184
185 /*****************************************************************************/
186 /*                      MODULE INITIALIZATION STUFF                          */
187 /*****************************************************************************/
188 void clenaup_inetcfg(void)
189 {
190         char *buf;
191
192         buf = inetcfg;
193         inetcfg = NULL;
194         if (buf != NULL)
195                 free(buf);
196 }
197
198 CTDL_MODULE_INIT(inetcfg)
199 {
200         if (!threading)
201         {
202                 CtdlRegisterMessageHook(inetcfg_aftersave, EVT_AFTERSAVE);
203                 inetcfg_init();
204                 CtdlRegisterCleanupHook(clenaup_inetcfg);
205         }
206         
207         /* return our Subversion id for the Log */
208         return "inetcfg";
209 }
210