* Formalized the 'Internet Configuration' logistics. Added new API call
[citadel.git] / citadel / serv_inetcfg.c
1 /* $Id$ 
2  *
3  * This module handles the loading/saving and maintenance of the
4  * system's Internet configuration.  It's not an optional component; I
5  * wrote it as a module merely to keep things as clean and loosely coupled
6  * as possible.
7  */
8
9 #include "sysdep.h"
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <fcntl.h>
14 #include <signal.h>
15 #include <pwd.h>
16 #include <errno.h>
17 #include <sys/types.h>
18 #include <sys/time.h>
19 #include <sys/wait.h>
20 #include <string.h>
21 #include <limits.h>
22 #include "citadel.h"
23 #include "server.h"
24 #include <time.h>
25 #include "sysdep_decls.h"
26 #include "citserver.h"
27 #include "support.h"
28 #include "config.h"
29 #include "dynloader.h"
30 #include "room_ops.h"
31 #include "user_ops.h"
32 #include "policy.h"
33 #include "database.h"
34 #include "msgbase.h"
35 #include "tools.h"
36 #include "internet_addressing.h"
37 #include "genstamp.h"
38 #include "domain.h"
39
40 void inetcfg_setTo(struct CtdlMessage *msg) {
41         char *conf;
42         char buf[256];
43
44         if (msg->cm_fields['M']==NULL) return;
45         conf = strdoop(msg->cm_fields['M']);
46
47         if (conf != NULL) {
48                 do {
49                         extract_token(buf, conf, 0, '\n');
50                         strcpy(conf, &conf[strlen(buf)+1]);
51                 } while ( (strlen(conf)>0) && (strlen(buf)>0) );
52
53                 if (inetcfg != NULL) phree(inetcfg);
54                 inetcfg = conf;
55         }
56 }
57
58
59 /*
60  * This handler detects changes being made to the system's Internet
61  * configuration.
62  */
63 int inetcfg_aftersave(struct CtdlMessage *msg) {
64         char *ptr;
65         int linelen;
66
67         /* If this isn't the configuration room, or if this isn't a MIME
68          * message, don't bother.
69          */
70         if (strcasecmp(msg->cm_fields['O'], SYSCONFIGROOM)) return(0);
71         if (msg->cm_format_type != 4) return(0);
72
73         ptr = msg->cm_fields['M'];
74         while (ptr != NULL) {
75         
76                 linelen = strcspn(ptr, "\n");
77                 if (linelen == 0) return(0);    /* end of headers */    
78                 
79                 if ( (!strncasecmp(ptr, "Content-type: ", 14))
80                    && (!strncasecmp(&ptr[14], INTERNETCFG,
81                    strlen(INTERNETCFG) )) ) {
82                         /* Bingo!  The user is changing configs.
83                          */
84                         inetcfg_setTo(msg);
85                 }
86
87                 ptr = strchr((char *)ptr, '\n');
88                 if (ptr != NULL) ++ptr;
89         }
90
91         return(0);
92 }
93
94
95 void inetcfg_init_backend(long msgnum) {
96         struct CtdlMessage *msg;
97
98         msg = CtdlFetchMessage(msgnum);
99         if (msg != NULL) {
100                 inetcfg_setTo(msg);
101                 CtdlFreeMessage(msg);
102         }
103 }
104
105
106 void inetcfg_init(void) {
107         if (getroom(&CC->quickroom, SYSCONFIGROOM) != 0) return;
108         CtdlForEachMessage(MSGS_LAST, 1, INTERNETCFG, NULL,
109                 inetcfg_init_backend);
110 }
111
112
113
114
115 /*****************************************************************************/
116 /*                      MODULE INITIALIZATION STUFF                          */
117 /*****************************************************************************/
118
119
120 char *Dynamic_Module_Init(void)
121 {
122         CtdlRegisterMessageHook(inetcfg_aftersave, EVT_AFTERSAVE);
123         inetcfg_init();
124         return "$Id$";
125 }
126