2 * This module handles shared rooms, inter-Citadel mail, and outbound
3 * mailing list processing.
5 * Copyright (c) 2000-2012 by the citadel.org team
7 * This program is open source software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 3.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
23 # if HAVE_SYS_SYSCALL_H
24 # include <sys/syscall.h>
28 #include <libcitadel.h>
30 #include "include/ctdl_module.h"
31 HashList *CfgTypeHash = NULL;
35 void RegisterRoomCfgType(const char* Name, long len, RoomNetCfg eCfg, CfgLineParser p, int uniq, CfgLineSerializer s, CfgLineDeAllocator d)
39 pCfg = (CfgLineType*) malloc(sizeof(CfgLineType));
45 pCfg->IsSingleLine = uniq;
47 if (CfgTypeHash == NULL)
48 CfgTypeHash = NewHash(1, NULL);
49 Put(CfgTypeHash, Name, len, pCfg, NULL);
53 const CfgLineType *GetCfgTypeByStr(const char *Key, long len)
57 if (GetHash(CfgTypeHash, Key, len, &pv) && (pv != NULL))
59 return (const CfgLineType *) pv;
67 const CfgLineType *GetCfgTypeByEnum(RoomNetCfg eCfg, HashPos *It)
74 RewindHashPos(CfgTypeHash, It, 1);
75 while (GetNextHashPos(CfgTypeHash, It, &len, &Key, &pv) && (pv != NULL))
77 pCfg = (CfgLineType*) pv;
83 void ParseGeneric(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *OneRNCFG)
87 nptr = (RoomNetCfgLine *)
88 malloc(sizeof(RoomNetCfgLine));
89 nptr->next = OneRNCFG->NetConfigs[ThisOne->C];
90 nptr->Value = NewStrBufPlain(LinePos, StrLength(Line) - ( LinePos - ChrPtr(Line)) );
91 OneRNCFG->NetConfigs[ThisOne->C] = nptr;
94 void SerializeGeneric(const CfgLineType *ThisOne, StrBuf *OutputBuffer, OneRoomNetCfg *OneRNCFG, RoomNetCfgLine *data)
96 StrBufAppendBufPlain(OutputBuffer, CKEY(ThisOne->Str), 0);
97 StrBufAppendBuf(OutputBuffer, data->Value, 0);
98 StrBufAppendBufPlain(OutputBuffer, HKEY("\n"), 0);
101 void DeleteGenericCfgLine(const CfgLineType *ThisOne, RoomNetCfgLine **data)
103 FreeStrBuf(&(*data)->Value);
107 int read_spoolcontrol_file(OneRoomNetCfg **pOneRNCFG, char *filename)
110 const char *ErrStr = NULL;
112 const CfgLineType *pCfg;
115 OneRoomNetCfg *OneRNCFG;
117 fd = open(filename, O_NONBLOCK|O_RDONLY);
122 OneRNCFG = malloc(sizeof(OneRoomNetCfg));
123 memset(OneRNCFG, 0, sizeof(OneRoomNetCfg));
124 *pOneRNCFG = OneRNCFG;
126 while (StrBufTCP_read_line(Line, &fd, 0, &ErrStr) >= 0) {
127 if (StrLength(Line) == 0)
130 InStr = NewStrBufPlain(NULL, StrLength(Line));
131 StrBufExtract_NextToken(InStr, Line, &Pos, '|');
133 pCfg = GetCfgTypeByStr(SKEY(InStr));
136 pCfg->Parser(pCfg, Line, Pos, OneRNCFG);
140 if (OneRNCFG->misc == NULL)
142 OneRNCFG->misc = NewStrBufDup(Line);
146 if(StrLength(OneRNCFG->misc) > 0)
147 StrBufAppendBufPlain(OneRNCFG->misc, HKEY("\n"), 0);
148 StrBufAppendBuf(OneRNCFG->misc, Line, 0);
159 int save_spoolcontrol_file(OneRoomNetCfg *OneRNCFG, char *filename)
163 char tempfilename[PATH_MAX];
168 long reltid; /* if we don't have SYS_gettid, use "random" value */
173 len = strlen(filename);
174 memcpy(tempfilename, filename, len + 1);
176 #if defined(HAVE_SYONERNCFGALL_H) && defined (SYS_gettid)
177 reltid = syOneRNCFGall(SYS_gettid);
179 gettimeofday(&tv, NULL);
180 /* Promote to time_t; types differ on some OSes (like darwin) */
181 unixtime = tv.tv_sec;
183 sprintf(tempfilename + len, ".%ld-%ld", reltid, unixtime);
185 TmpFD = open(tempfilename, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
187 if ((TmpFD < 0) || (errno != 0)) {
188 syslog(LOG_CRIT, "ERROR: cannot open %s: %s\n",
189 filename, strerror(errno));
190 unlink(tempfilename);
194 CfgIt = GetNewHashPos(CfgTypeHash, 1);
195 fchown(TmpFD, config.c_ctdluid, 0);
196 for (eCfg = subpending; eCfg < maxRoomNetCfg; eCfg ++)
198 const CfgLineType *pCfg;
199 pCfg = GetCfgTypeByEnum(eCfg, CfgIt);
200 if (pCfg->IsSingleLine)
202 pCfg->Serializer(pCfg, OutBuffer, OneRNCFG, NULL);
206 RoomNetCfgLine *pName = OneRNCFG->NetConfigs[pCfg->C];
207 while (pName != NULL)
209 pCfg->Serializer(pCfg, OutBuffer, OneRNCFG, pName);
217 DeleteHashPos(&CfgIt);
220 if (OneRNCFG->misc != NULL) {
221 StrBufAppendBuf(OutBuffer, OneRNCFG->misc, 0);
224 rc = write(TmpFD, ChrPtr(OutBuffer), StrLength(OutBuffer));
225 if ((rc >=0 ) && (rc == StrLength(Cfg)))
228 rename(tempfilename, filename);
233 "unable to write %s; [%s]; not enough space on the disk?\n",
237 unlink(tempfilename);
240 FreeStrBuf(&OutBuffer);
248 void free_spoolcontrol_struct(OneRoomNetCfg **pOneRNCFG)
252 OneRoomNetCfg *OneRNCFG;
254 OneRNCFG = *pOneRNCFG;
255 CfgIt = GetNewHashPos(CfgTypeHash, 1);
256 for (eCfg = subpending; eCfg < maxRoomNetCfg; eCfg ++)
258 const CfgLineType *pCfg;
259 RoomNetCfgLine *pNext, *pName;
261 pCfg = GetCfgTypeByEnum(eCfg, CfgIt);
262 pName= OneRNCFG->NetConfigs[pCfg->C];
263 while (pName != NULL)
266 pCfg->DeAllocator(pCfg, &pName);
270 DeleteHashPos(&CfgIt);
272 FreeStrBuf(&OneRNCFG->Sender);
273 FreeStrBuf(&OneRNCFG->RoomInfo);
274 FreeStrBuf(&OneRNCFG->misc);