]> code.citadel.org Git - citadel.git/blob - citadel/serv_network.c
fix all the <time.h> vs. <sys/time.h> issues, hopefully
[citadel.git] / citadel / serv_network.c
1 /*
2  * $Id$ 
3  *
4  * This module will eventually replace netproc and some of its utilities.
5  * Copyright (C) 2000 by Art Cancro and others.
6  * This code is released under the terms of the GNU General Public License.
7  *
8  */
9
10 #include "sysdep.h"
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <stdio.h>
14 #include <fcntl.h>
15 #include <signal.h>
16 #include <pwd.h>
17 #include <errno.h>
18 #include <sys/types.h>
19
20 #if TIME_WITH_SYS_TIME
21 # include <sys/time.h>
22 # include <time.h>
23 #else
24 # if HAVE_SYS_TIME_H
25 #  include <sys/time.h>
26 # else
27 #  include <time.h>
28 # endif
29 #endif
30
31 #include <sys/wait.h>
32 #include <string.h>
33 #include <limits.h>
34 #include "citadel.h"
35 #include "server.h"
36 #include "sysdep_decls.h"
37 #include "citserver.h"
38 #include "support.h"
39 #include "config.h"
40 #include "dynloader.h"
41 #include "room_ops.h"
42 #include "user_ops.h"
43 #include "policy.h"
44 #include "database.h"
45 #include "msgbase.h"
46 #include "tools.h"
47 #include "internet_addressing.h"
48 #include "serv_network.h"
49
50
51 void cmd_gnet(char *argbuf) {
52         char filename[SIZ];
53         char buf[SIZ];
54         FILE *fp;
55
56         if (CtdlAccessCheck(ac_room_aide)) return;
57         assoc_file_name(filename, &CC->quickroom, "netconfigs");
58         cprintf("%d Network settings for room #%ld <%s>\n",
59                 LISTING_FOLLOWS,
60                 CC->quickroom.QRnumber, CC->quickroom.QRname);
61
62         fp = fopen(filename, "r");
63         if (fp != NULL) {
64                 while (fgets(buf, sizeof buf, fp) != NULL) {
65                         buf[strlen(buf)-1] = 0;
66                         cprintf("%s\n", buf);
67                 }
68                 fclose(fp);
69         }
70
71         cprintf("000\n");
72 }
73
74
75 void cmd_snet(char *argbuf) {
76         char tempfilename[SIZ];
77         char filename[SIZ];
78         char buf[SIZ];
79         FILE *fp;
80
81         if (CtdlAccessCheck(ac_room_aide)) return;
82         safestrncpy(tempfilename, tmpnam(NULL), sizeof tempfilename);
83         assoc_file_name(filename, &CC->quickroom, "netconfigs");
84
85         fp = fopen(tempfilename, "w");
86         if (fp == NULL) {
87                 cprintf("%d Cannot open %s: %s\n",
88                         ERROR+INTERNAL_ERROR,
89                         tempfilename,
90                         strerror(errno));
91         }
92
93         cprintf("%d %s\n", SEND_LISTING, tempfilename);
94         while (client_gets(buf), strcmp(buf, "000")) {
95                 fprintf(fp, "%s\n", buf);
96         }
97         fclose(fp);
98
99         /* Now copy the temp file to its permanent location
100          * (We use /bin/mv instead of link() because they may be on
101          * different filesystems)
102          */
103         unlink(filename);
104         snprintf(buf, sizeof buf, "/bin/mv %s %s", tempfilename, filename);
105         system(buf);
106 }
107
108
109
110 /*
111  * Spools out one message from the list.
112  */
113 void network_spool_msg(long msgnum, void *userdata) {
114         struct SpoolControl *sc;
115         struct namelist *nptr;
116         int err;
117         char *instr = NULL;
118         int instr_len = 0;
119         struct CtdlMessage *imsg;
120
121         sc = (struct SpoolControl *)userdata;
122
123         /* If no recipients, bail out now.
124          * (May need to tweak this when we add other types of targets)
125          */
126         if (sc->listrecps == NULL) return;
127         
128         /* First, copy it to the spoolout room */
129         err = CtdlSaveMsgPointerInRoom(SMTP_SPOOLOUT_ROOM, msgnum, 0);
130         if (err != 0) return;
131
132         lprintf(9, "Generating delivery instructions\n");
133         instr_len = 4096;
134         instr = mallok(instr_len);
135         sprintf(instr,
136                 "Content-type: %s\n\nmsgid|%ld\nsubmitted|%ld\n"
137                 "bounceto|postmaster@%s\n" ,
138                 SPOOLMIME, msgnum, time(NULL), config.c_fqdn );
139
140         imsg = mallok(sizeof(struct CtdlMessage));
141         memset(imsg, 0, sizeof(struct CtdlMessage));
142         imsg->cm_magic = CTDLMESSAGE_MAGIC;
143         imsg->cm_anon_type = MES_NORMAL;
144         imsg->cm_format_type = FMT_RFC822;
145         imsg->cm_fields['A'] = strdoop("Citadel");
146         imsg->cm_fields['M'] = instr;
147
148         /* Generate delivery instructions for each recipient */
149         for (nptr = sc->listrecps; nptr != NULL; nptr = nptr->next) {
150                 if (instr_len - strlen(instr) < SIZ) {
151                         instr_len = instr_len * 2;
152                         instr = reallok(instr, instr_len);
153                 }
154                 sprintf(&instr[strlen(instr)], "remote|%s|0||\n",
155                         nptr->name);
156         }
157
158         /* Save delivery instructions in spoolout room */
159         CtdlSaveMsg(imsg, "", SMTP_SPOOLOUT_ROOM, MES_LOCAL);
160         CtdlFreeMessage(imsg);
161
162         /* update lastsent */
163         sc->lastsent = msgnum;
164 }
165
166
167
168
169 /*
170  * Batch up and send all outbound traffic from the current room
171  */
172 void network_spoolout_current_room(void) {
173         char filename[SIZ];
174         char buf[SIZ];
175         char instr[SIZ];
176         FILE *fp;
177         struct SpoolControl sc;
178         /* struct namelist *digestrecps = NULL; */
179         struct namelist *nptr;
180
181         memset(&sc, 0, sizeof(struct SpoolControl));
182         assoc_file_name(filename, &CC->quickroom, "netconfigs");
183
184         fp = fopen(filename, "r");
185         if (fp == NULL) {
186                 lprintf(7, "Outbound batch processing skipped for <%s>\n",
187                         CC->quickroom.QRname);
188                 return;
189         }
190
191         lprintf(5, "Outbound batch processing started for <%s>\n",
192                 CC->quickroom.QRname);
193
194         while (fgets(buf, sizeof buf, fp) != NULL) {
195                 buf[strlen(buf)-1] = 0;
196
197                 extract(instr, buf, 0);
198                 if (!strcasecmp(instr, "lastsent")) {
199                         sc.lastsent = extract_long(buf, 1);
200                 }
201                 else if (!strcasecmp(instr, "listrecp")) {
202                         nptr = (struct namelist *)
203                                 mallok(sizeof(struct namelist));
204                         nptr->next = sc.listrecps;
205                         extract(nptr->name, buf, 1);
206                         sc.listrecps = nptr;
207                 }
208
209
210         }
211         fclose(fp);
212
213
214         /* Do something useful */
215         CtdlForEachMessage(MSGS_GT, sc.lastsent, (-63), NULL, NULL,
216                 network_spool_msg, &sc);
217
218
219         /* Now rewrite the config file */
220         fp = fopen(filename, "w");
221         if (fp == NULL) {
222                 lprintf(1, "ERROR: cannot open %s: %s\n",
223                         filename, strerror(errno));
224         }
225         else {
226                 fprintf(fp, "lastsent|%ld\n", sc.lastsent);
227
228                 /* Write out the listrecps while freeing from memory at the
229                  * same time.  Am I clever or what?  :)
230                  */
231                 while (sc.listrecps != NULL) {
232                         fprintf(fp, "listrecp|%s\n", sc.listrecps->name);
233                         nptr = sc.listrecps->next;
234                         phree(sc.listrecps);
235                         sc.listrecps = nptr;
236                 }
237
238                 fclose(fp);
239         }
240
241         lprintf(5, "Outbound batch processing finished for <%s>\n",
242                 CC->quickroom.QRname);
243 }
244
245
246
247 /* FIXME temporary server command for batch send */
248 void cmd_batc(char *argbuf) {
249         if (CtdlAccessCheck(ac_aide)) return;
250
251         network_spoolout_current_room();
252
253         cprintf("%d FIXME cmd_batc() ok\n", OK);
254 }
255
256
257
258 char *Dynamic_Module_Init(void)
259 {
260         CtdlRegisterProtoHook(cmd_gnet, "GNET", "Get network config");
261         CtdlRegisterProtoHook(cmd_snet, "SNET", "Get network config");
262
263         /* FIXME
264            temporary server command for batch send
265          */
266         CtdlRegisterProtoHook(cmd_batc, "BATC", "send out batch (temp)");
267
268         return "$Id$";
269 }