From e24d4d39b9e026d260c7745014bafe63e19f9b0b Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Mon, 31 Dec 2012 13:20:40 +0100 Subject: [PATCH] NETCFG: move netconfig parser into its own file. --- citadel/Makefile.in | 4 +- citadel/include/ctdl_module.h | 39 ++ citadel/modules/network/netspool.h | 8 +- citadel/modules/network/serv_netconfig.c | 4 +- citadel/modules/network/serv_netmail.c | 36 +- citadel/modules/network/serv_netspool.c | 425 ++----------------- citadel/modules/network/serv_network.c | 2 +- citadel/modules/network/serv_network.h | 6 - citadel/modules/pop3client/serv_pop3client.c | 1 + citadel/modules/rssclient/serv_rssclient.c | 1 + citadel/netconfig.c | 278 ++++++++++++ 11 files changed, 379 insertions(+), 425 deletions(-) create mode 100644 citadel/netconfig.c diff --git a/citadel/Makefile.in b/citadel/Makefile.in index 553ea0435..c2ecdb7ee 100644 --- a/citadel/Makefile.in +++ b/citadel/Makefile.in @@ -83,7 +83,7 @@ SOURCES=utils/aidepost.c utils/citmail.c \ locate_host.c md5.c auth.c msgbase.c parsedate.c \ room_ops.c euidindex.c server_main.c ldap.c \ support.c sysdep.c user_ops.c journaling.c threads.c \ - context.c event_client.c + context.c event_client.c netconfig.c include Make_sources @@ -138,7 +138,7 @@ SERV_OBJS = server_main.o utillib/citadel_dirs.o event_client.o \ internet_addressing.o journaling.o \ parsedate.o genstamp.o ecrash.o threads.o context.o \ clientsocket.o modules_init.o modules_upgrade.o $(SERV_MODULES) \ - svn_revision.o ldap.o + svn_revision.o ldap.o netconfig.o citserver$(EXEEXT): $(SERV_OBJS) $(CC) $(SERV_OBJS) $(LDFLAGS) $(SERVER_LDFLAGS) $(LIBS) $(SERVER_LIBS) $(RESOLV) -o citserver$(EXEEXT) diff --git a/citadel/include/ctdl_module.h b/citadel/include/ctdl_module.h index 129269215..eddcbeffc 100644 --- a/citadel/include/ctdl_module.h +++ b/citadel/include/ctdl_module.h @@ -378,6 +378,45 @@ struct config { extern struct config config; +typedef struct CfgLineType CfgLineType; +typedef struct RoomNetCfgLine RoomNetCfgLine; +typedef struct OneRoomNetCfg OneRoomNetCfg; + +typedef void (*CfgLineParser)(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *rncfg); +typedef void (*CfgLineSerializer)(const CfgLineType *ThisOne, StrBuf *OuptputBuffer, OneRoomNetCfg *rncfg, RoomNetCfgLine *data); +typedef void (*CfgLineDeAllocator)(const CfgLineType *ThisOne, RoomNetCfgLine **data); + +struct CfgLineType { + RoomNetCfg C; + CfgLineParser Parser; + CfgLineSerializer Serializer; + CfgLineDeAllocator DeAllocator; + ConstStr Str; + int IsSingleLine; +}; + +struct RoomNetCfgLine { + RoomNetCfgLine *next; + StrBuf *Value; +}; + +struct OneRoomNetCfg { + long lastsent; + StrBuf *Sender; + StrBuf *RoomInfo; + RoomNetCfgLine *NetConfigs[maxRoomNetCfg]; + StrBuf *misc; +}; + + +#define CtdlREGISTERRoomCfgType(a, p, uniq, s, d) RegisterRoomCfgType(#a, sizeof(#a) - 1, a, p, uniq, s, d); +void RegisterRoomCfgType(const char* Name, long len, RoomNetCfg eCfg, CfgLineParser p, int uniq, CfgLineSerializer s, CfgLineDeAllocator d); +void ParseGeneric(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *sc); +void SerializeGeneric(const CfgLineType *ThisOne, StrBuf *OutputBuffer, OneRoomNetCfg *sc, RoomNetCfgLine *data); +void DeleteGenericCfgLine(const CfgLineType *ThisOne, RoomNetCfgLine **data); + + + /* * Expose API calls from user_ops.c diff --git a/citadel/modules/network/netspool.h b/citadel/modules/network/netspool.h index ae0183887..34e13acae 100644 --- a/citadel/modules/network/netspool.h +++ b/citadel/modules/network/netspool.h @@ -39,11 +39,7 @@ struct maplist { typedef struct SpoolControl SpoolControl; struct SpoolControl { - long lastsent; - StrBuf *Sender; - StrBuf *RoomInfo; - namelist *NetConfigs[maxRoomNetCfg]; - StrBuf *misc; + OneRoomNetCfg *RNCfg; FILE *digestfp; int num_msgs_spooled; @@ -60,4 +56,4 @@ void network_consolidate_spoolout(HashList *working_ignetcfg, HashList *the_netm void free_spoolcontrol_struct(SpoolControl **scc); int writenfree_spoolcontrol_file(SpoolControl **scc, char *filename); int read_spoolcontrol_file(SpoolControl **scc, char *filename); -int is_recipient(SpoolControl *sc, const char *Name); +int is_recipient(OneRoomNetCfg *RNCfg, const char *Name); diff --git a/citadel/modules/network/serv_netconfig.c b/citadel/modules/network/serv_netconfig.c index 12662f066..34ef2529b 100644 --- a/citadel/modules/network/serv_netconfig.c +++ b/citadel/modules/network/serv_netconfig.c @@ -77,8 +77,8 @@ #include "threads.h" #include "context.h" #include "netconfig.h" -#include "netspool.h" #include "ctdl_module.h" +#include "netspool.h" @@ -650,7 +650,7 @@ int netconfig_check_roomaccess( return (ERROR + NO_SUCH_USER); } end_critical_section(S_NETCONFIGS); - found = is_recipient (sc, RemoteIdentifier); + found = is_recipient (sc->RNCfg, RemoteIdentifier); free_spoolcontrol_struct(&sc); if (found) { return (0); diff --git a/citadel/modules/network/serv_netmail.c b/citadel/modules/network/serv_netmail.c index faf62a01c..2078c32cc 100644 --- a/citadel/modules/network/serv_netmail.c +++ b/citadel/modules/network/serv_netmail.c @@ -76,10 +76,10 @@ #include "citadel_dirs.h" #include "threads.h" #include "context.h" +#include "ctdl_module.h" #include "netconfig.h" #include "netspool.h" #include "netmail.h" -#include "ctdl_module.h" /* @@ -95,7 +95,7 @@ void network_deliver_digest(SpoolControl *sc) { char *precps; size_t recps_len = SIZ; struct recptypes *valid; - namelist *nptr; + RoomNetCfgLine *nptr; char bounce_to[256]; if (sc->num_msgs_spooled < 1) { @@ -151,7 +151,7 @@ void network_deliver_digest(SpoolControl *sc) { /* * Figure out how big a buffer we need to allocate */ - for (nptr = sc->NetConfigs[digestrecp]; nptr != NULL; nptr = nptr->next) { + for (nptr = sc->RNCfg->NetConfigs[digestrecp]; nptr != NULL; nptr = nptr->next) { recps_len = recps_len + StrLength(nptr->Value) + 2; } @@ -165,8 +165,8 @@ void network_deliver_digest(SpoolControl *sc) { } /* Each recipient */ - for (nptr = sc->NetConfigs[digestrecp]; nptr != NULL; nptr = nptr->next) { - if (nptr != sc->NetConfigs[digestrecp]) { + for (nptr = sc->RNCfg->NetConfigs[digestrecp]; nptr != NULL; nptr = nptr->next) { + if (nptr != sc->RNCfg->NetConfigs[digestrecp]) { StrBufAppendBufPlain(recps, HKEY(","), 0); } StrBufAppendBuf(recps, nptr->Value, 0); @@ -200,18 +200,18 @@ void network_deliver_list(struct CtdlMessage *msg, SpoolControl *sc, const char char *precps = NULL; size_t recps_len = SIZ; struct recptypes *valid; - namelist *nptr; + RoomNetCfgLine *nptr; char bounce_to[256]; /* Don't do this if there were no recipients! */ - if (sc->NetConfigs[listrecp] == NULL) return; + if (sc->RNCfg->NetConfigs[listrecp] == NULL) return; /* Now generate the delivery instructions */ /* * Figure out how big a buffer we need to allocate */ - for (nptr = sc->NetConfigs[listrecp]; nptr != NULL; nptr = nptr->next) { + for (nptr = sc->RNCfg->NetConfigs[listrecp]; nptr != NULL; nptr = nptr->next) { recps_len = recps_len + StrLength(nptr->Value) + 2; } @@ -225,8 +225,8 @@ void network_deliver_list(struct CtdlMessage *msg, SpoolControl *sc, const char } /* Each recipient */ - for (nptr = sc->NetConfigs[listrecp]; nptr != NULL; nptr = nptr->next) { - if (nptr != sc->NetConfigs[listrecp]) { + for (nptr = sc->RNCfg->NetConfigs[listrecp]; nptr != NULL; nptr = nptr->next) { + if (nptr != sc->RNCfg->NetConfigs[listrecp]) { StrBufAppendBufPlain(recps, HKEY(","), 0); } StrBufAppendBuf(recps, nptr->Value, 0); @@ -263,7 +263,7 @@ void network_spool_msg(long msgnum, int i; char *newpath = NULL; struct CtdlMessage *msg = NULL; - namelist *nptr; + RoomNetCfgLine *nptr; maplist *mptr; struct ser_ret sermsg; FILE *fp; @@ -280,7 +280,7 @@ void network_spool_msg(long msgnum, /* * Process mailing list recipients */ - if (sc->NetConfigs[listrecp] != NULL) { + if (sc->RNCfg->NetConfigs[listrecp] != NULL) { /* Fetch the message. We're going to need to modify it * in order to insert the [list name] in it, etc. */ @@ -393,7 +393,7 @@ void network_spool_msg(long msgnum, /* * Process digest recipients */ - if ((sc->NetConfigs[digestrecp] != NULL) && (sc->digestfp != NULL)) { + if ((sc->RNCfg->NetConfigs[digestrecp] != NULL) && (sc->digestfp != NULL)) { msg = CtdlFetchMessage(msgnum, 1); if (msg != NULL) { fprintf(sc->digestfp, @@ -449,7 +449,7 @@ void network_spool_msg(long msgnum, /* * Process client-side list participations for this room */ - if (sc->NetConfigs[participate] != NULL) { + if (sc->RNCfg->NetConfigs[participate] != NULL) { msg = CtdlFetchMessage(msgnum, 1); if (msg != NULL) { @@ -498,7 +498,7 @@ void network_spool_msg(long msgnum, /* * Figure out how big a buffer we need to alloc */ - for (nptr = sc->NetConfigs[participate]; + for (nptr = sc->RNCfg->NetConfigs[participate]; nptr != NULL; nptr = nptr->next) { @@ -551,8 +551,8 @@ void network_spool_msg(long msgnum, } /* Now send it to every node */ - if (sc->NetConfigs[ignet_push_share] != NULL) - for (mptr = (maplist*)sc->NetConfigs[ignet_push_share]; mptr != NULL; + if (sc->RNCfg->NetConfigs[ignet_push_share] != NULL) + for (mptr = (maplist*)sc->RNCfg->NetConfigs[ignet_push_share]; mptr != NULL; mptr = mptr->next) { send = 1; @@ -657,7 +657,7 @@ void network_spool_msg(long msgnum, } /* update lastsent */ - sc->lastsent = msgnum; + sc->RNCfg->lastsent = msgnum; /* Delete this message if delete-after-send is set */ if (delete_after_send) { diff --git a/citadel/modules/network/serv_netspool.c b/citadel/modules/network/serv_netspool.c index 185c739a4..d66161bcc 100644 --- a/citadel/modules/network/serv_netspool.c +++ b/citadel/modules/network/serv_netspool.c @@ -76,113 +76,44 @@ #include "citadel_dirs.h" #include "threads.h" #include "context.h" + +#include "ctdl_module.h" + #include "netconfig.h" #include "netspool.h" #include "netmail.h" -#include "ctdl_module.h" -HashList *CfgTypeHash = NULL; -typedef struct CfgLineType CfgLineType; -typedef void (*CfgLineParser)(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, SpoolControl *sc); -typedef void (*CfgLineSerializer)(const CfgLineType *ThisOne, StrBuf *OuptputBuffer, SpoolControl *sc, namelist *data); -typedef void (*CfgLineDeAllocator)(const CfgLineType *ThisOne, namelist **data); -struct CfgLineType { - RoomNetCfg C; - CfgLineParser Parser; - CfgLineSerializer Serializer; - CfgLineDeAllocator DeAllocator; - ConstStr Str; - int IsSingleLine; -}; -#define REGISTERRoomCfgType(a, p, uniq, s, d) RegisterRoomCfgType(#a, sizeof(#a) - 1, a, p, uniq, s, d); - -void RegisterRoomCfgType(const char* Name, long len, RoomNetCfg eCfg, CfgLineParser p, int uniq, CfgLineSerializer s, CfgLineDeAllocator d) -{ - CfgLineType *pCfg; - - pCfg = (CfgLineType*) malloc(sizeof(CfgLineType)); - pCfg->Parser = p; - pCfg->Serializer = s; - pCfg->C = eCfg; - pCfg->Str.Key = Name; - pCfg->Str.len = len; - pCfg->IsSingleLine = uniq; - - if (CfgTypeHash == NULL) - CfgTypeHash = NewHash(1, NULL); - Put(CfgTypeHash, Name, len, pCfg, NULL); -} -const CfgLineType *GetCfgTypeByStr(const char *Key, long len) -{ - void *pv; - - if (GetHash(CfgTypeHash, Key, len, &pv) && (pv != NULL)) - { - return (const CfgLineType *) pv; - } - else - { - return NULL; - } -} -const CfgLineType *GetCfgTypeByEnum(RoomNetCfg eCfg, HashPos *It) +void ParseLastSent(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *rncfg) { - const char *Key; - long len; - void *pv; - CfgLineType *pCfg; - - RewindHashPos(CfgTypeHash, It, 1); - while (GetNextHashPos(CfgTypeHash, It, &len, &Key, &pv) && (pv != NULL)) - { - pCfg = (CfgLineType*) pv; - if (pCfg->C == eCfg) - return pCfg; - } - return NULL; + rncfg->lastsent = extract_long(LinePos, 0); } -void ParseDefault(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, SpoolControl *sc) -{ - namelist *nptr; - - nptr = (namelist *) - malloc(sizeof(namelist)); - nptr->next = sc->NetConfigs[ThisOne->C]; - nptr->Value = NewStrBufPlain(LinePos, StrLength(Line) - ( LinePos - ChrPtr(Line)) ); - sc->NetConfigs[ThisOne->C] = nptr; -} - -void ParseLastSent(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, SpoolControl *sc) -{ - sc->lastsent = extract_long(LinePos, 0); -} -void ParseIgnetPushShare(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, SpoolControl *sc) +void ParseIgnetPushShare(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *rncfg) { /* extract_token(nodename, LinePos, 0, '|', sizeof nodename); extract_token(roomname, LinePos, 1, '|', sizeof roomname); mptr = (maplist *) malloc(sizeof(maplist)); - mptr->next = sc->ignet_push_shares; + mptr->next = rncfg->RNCfg->ignet_push_shares; strcpy(mptr->remote_nodename, nodename); strcpy(mptr->remote_roomname, roomname); - sc->ignet_push_shares = mptr; + rncfg->RNCfg->ignet_push_shares = mptr; */ } -void ParseRoomAlias(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, SpoolControl *sc) +void ParseRoomAlias(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *rncfg) { /* - if (sc->sender != NULL) + if (rncfg->RNCfg->sender != NULL) continue; / * just one alowed... * / extract_token(nptr->name, buf, 1, '|', sizeof nptr->name); - sc->sender = nptr; + rncfg->RNCfg->sender = nptr; */ } -void ParseSubPendingLine(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, SpoolControl *sc) +void ParseSubPendingLine(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *rncfg) { if (time(NULL) - extract_long(LinePos, 3) > EXP) { @@ -193,7 +124,7 @@ void ParseSubPendingLine(const CfgLineType *ThisOne, StrBuf *Line, const char *L } } -void ParseUnSubPendingLine(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, SpoolControl *sc) +void ParseUnSubPendingLine(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *rncfg) { ///int skipthisline = 0; if (time(NULL) - extract_long(LinePos, 2) > EXP) { @@ -202,315 +133,31 @@ void ParseUnSubPendingLine(const CfgLineType *ThisOne, StrBuf *Line, const char } -void DeleteGenericCfgLine(const CfgLineType *ThisOne, namelist **data) -{ - FreeStrBuf(&(*data)->Value); - free(*data); - *data = NULL; -} -int read_spoolcontrol_file(SpoolControl **scc, char *filename) -{ - int fd; - const char *ErrStr = NULL; - const char *Pos; - const CfgLineType *pCfg; - StrBuf *Line; - StrBuf *InStr; - SpoolControl *sc; - fd = open(filename, O_NONBLOCK|O_RDONLY); - if (fd == -1) { - *scc = NULL; - return 0; - } - sc = malloc(sizeof(SpoolControl)); - memset(sc, 0, sizeof(SpoolControl)); - *scc = sc; - - while (StrBufTCP_read_line(Line, &fd, 0, &ErrStr) >= 0) { - if (StrLength(Line) == 0) - continue; - Pos = NULL; - InStr = NewStrBufPlain(NULL, StrLength(Line)); - StrBufExtract_NextToken(InStr, Line, &Pos, '|'); - - pCfg = GetCfgTypeByStr(SKEY(InStr)); - if (pCfg != NULL) - { - pCfg->Parser(pCfg, Line, Pos, sc); - } - else - { - if (sc->misc == NULL) - { - sc->misc = NewStrBufDup(Line); - } - else - { - if(StrLength(sc->misc) > 0) - StrBufAppendBufPlain(sc->misc, HKEY("\n"), 0); - StrBufAppendBuf(sc->misc, Line, 0); - } - } - } - if (fd > 0) - close(fd); - FreeStrBuf(&InStr); - FreeStrBuf(&Line); - return 1; -} - -void SerializeLastSent(const CfgLineType *ThisOne, StrBuf *OutputBuffer, SpoolControl *sc, namelist *data) +void SerializeLastSent(const CfgLineType *ThisOne, StrBuf *OutputBuffer, OneRoomNetCfg *RNCfg, RoomNetCfgLine *data) { StrBufAppendBufPlain(OutputBuffer, CKEY(ThisOne->Str), 0); - StrBufAppendPrintf(OutputBuffer, "|%ld\n", sc->lastsent); + StrBufAppendPrintf(OutputBuffer, "|%ld\n", RNCfg->lastsent); } -void SerializeGeneric(const CfgLineType *ThisOne, StrBuf *OutputBuffer, SpoolControl *sc, namelist *data) -{ - StrBufAppendBufPlain(OutputBuffer, CKEY(ThisOne->Str), 0); - StrBufAppendBuf(OutputBuffer, data->Value, 0); - StrBufAppendBufPlain(OutputBuffer, HKEY("\n"), 0); -} -void SerializeIgnetPushShare(const CfgLineType *ThisOne, StrBuf *OutputBuffer, SpoolControl *sc, namelist *data) +void SerializeIgnetPushShare(const CfgLineType *ThisOne, StrBuf *OutputBuffer, OneRoomNetCfg *RNCfg, RoomNetCfgLine *data) { StrBufAppendBufPlain(OutputBuffer, CKEY(ThisOne->Str), 0); /* - StrBufAppendPrintf(Cfg, "ignet_push_share|%s", sc->ignet_push_shares->remote_nodename); - if (!IsEmptyStr(sc->ignet_push_shares->remote_roomname)) { - StrBufAppendPrintf(Cfg, "|%s", sc->ignet_push_shares->remote_roomname); + StrBufAppendPrintf(Cfg, "ignet_push_share|%s", RNCfg->ignet_push_shares->remote_nodename); + if (!IsEmptyStr(RNCfg->ignet_push_shares->remote_roomname)) { + StrBufAppendPrintf(Cfg, "|%s", RNCfg->ignet_push_shares->remote_roomname); } StrBufAppendPrintf(Cfg, "\n"); - mptr = sc->ignet_push_shares->next; - free(sc->ignet_push_shares); - sc->ignet_push_shares = mptr; + mptr = RNCfg->ignet_push_shares->next; + free(RNCfg->ignet_push_shares); + RNCfg->ignet_push_shares = mptr; */ StrBufAppendBuf(OutputBuffer, data->Value, 0); StrBufAppendBufPlain(OutputBuffer, HKEY("\n"), 0); } -int save_spoolcontrol_file(SpoolControl *sc, char *filename) -{ - RoomNetCfg eCfg; - StrBuf *Cfg; - char tempfilename[PATH_MAX]; - int TmpFD; - long len; - time_t unixtime; - struct timeval tv; - long reltid; /* if we don't have SYS_gettid, use "random" value */ - StrBuf *OutBuffer; - int rc; - HashPos *CfgIt; - - len = strlen(filename); - memcpy(tempfilename, filename, len + 1); - - -#if defined(HAVE_SYSCALL_H) && defined (SYS_gettid) - reltid = syscall(SYS_gettid); -#endif - gettimeofday(&tv, NULL); - /* Promote to time_t; types differ on some OSes (like darwin) */ - unixtime = tv.tv_sec; - - sprintf(tempfilename + len, ".%ld-%ld", reltid, unixtime); - errno = 0; - TmpFD = open(tempfilename, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR); - Cfg = NewStrBuf(); - if ((TmpFD < 0) || (errno != 0)) { - syslog(LOG_CRIT, "ERROR: cannot open %s: %s\n", - filename, strerror(errno)); - unlink(tempfilename); - return 0; - } - else { - CfgIt = GetNewHashPos(CfgTypeHash, 1); - fchown(TmpFD, config.c_ctdluid, 0); - for (eCfg = subpending; eCfg < maxRoomNetCfg; eCfg ++) - { - const CfgLineType *pCfg; - pCfg = GetCfgTypeByEnum(eCfg, CfgIt); - if (pCfg->IsSingleLine) - { - pCfg->Serializer(pCfg, OutBuffer, sc, NULL); - } - else - { - namelist *pName = sc->NetConfigs[pCfg->C]; - while (pName != NULL) - { - pCfg->Serializer(pCfg, OutBuffer, sc, pName); - pName = pName->next; - } - - - } - - } - DeleteHashPos(&CfgIt); - - - if (sc->misc != NULL) { - StrBufAppendBuf(OutBuffer, sc->misc, 0); - } - - rc = write(TmpFD, ChrPtr(OutBuffer), StrLength(OutBuffer)); - if ((rc >=0 ) && (rc == StrLength(Cfg))) - { - close(TmpFD); - rename(tempfilename, filename); - rc = 1; - } - else { - syslog(LOG_EMERG, - "unable to write %s; [%s]; not enough space on the disk?\n", - tempfilename, - strerror(errno)); - close(TmpFD); - unlink(tempfilename); - rc = 0; - } - FreeStrBuf(&OutBuffer); - - } - return rc; -} - - - -void free_spoolcontrol_struct(SpoolControl **scc) -{ - RoomNetCfg eCfg; - HashPos *CfgIt; - SpoolControl *sc; - - sc = *scc; - CfgIt = GetNewHashPos(CfgTypeHash, 1); - for (eCfg = subpending; eCfg < maxRoomNetCfg; eCfg ++) - { - const CfgLineType *pCfg; - namelist *pNext, *pName; - - pCfg = GetCfgTypeByEnum(eCfg, CfgIt); - pName= sc->NetConfigs[pCfg->C]; - while (pName != NULL) - { - pNext = pName->next; - pCfg->DeAllocator(pCfg, &pName); - pName = pNext; - } - } - DeleteHashPos(&CfgIt); - - FreeStrBuf(&sc->Sender); - FreeStrBuf(&sc->RoomInfo); - FreeStrBuf(&sc->misc); - free(sc); - *scc=NULL; -} - -#if 0 -int writenfree_spoolcontrol_file(SpoolControl **scc, char *filename) -{ - char tempfilename[PATH_MAX]; - int TmpFD; - SpoolControl *sc; - namelist *nptr = NULL; - maplist *mptr = NULL; - long len; - time_t unixtime; - struct timeval tv; - long reltid; /* if we don't have SYS_gettid, use "random" value */ - StrBuf *Cfg; - int rc; - - len = strlen(filename); - memcpy(tempfilename, filename, len + 1); - - -#if defined(HAVE_SYSCALL_H) && defined (SYS_gettid) - reltid = syscall(SYS_gettid); -#endif - gettimeofday(&tv, NULL); - /* Promote to time_t; types differ on some OSes (like darwin) */ - unixtime = tv.tv_sec; - - sprintf(tempfilename + len, ".%ld-%ld", reltid, unixtime); - sc = *scc; - errno = 0; - TmpFD = open(tempfilename, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR); - Cfg = NewStrBuf(); - if ((TmpFD < 0) || (errno != 0)) { - syslog(LOG_CRIT, "ERROR: cannot open %s: %s\n", - filename, strerror(errno)); - free_spoolcontrol_struct(scc); - unlink(tempfilename); - } - else { - fchown(TmpFD, config.c_ctdluid, 0); - StrBufAppendPrintf(Cfg, "lastsent|%ld\n", sc->lastsent); - - /* Write out the listrecps while freeing from memory at the - * same time. Am I clever or what? :) - */ - while (sc->listrecps != NULL) { - StrBufAppendPrintf(Cfg, "listrecp|%s\n", sc->listrecps->name); - nptr = sc->listrecps->next; - free(sc->listrecps); - sc->listrecps = nptr; - } - /* Do the same for digestrecps */ - while (sc->digestrecps != NULL) { - StrBufAppendPrintf(Cfg, "digestrecp|%s\n", sc->digestrecps->name); - nptr = sc->digestrecps->next; - free(sc->digestrecps); - sc->digestrecps = nptr; - } - /* Do the same for participates */ - while (sc->participates != NULL) { - StrBufAppendPrintf(Cfg, "participate|%s\n", sc->participates->name); - nptr = sc->participates->next; - free(sc->participates); - sc->participates = nptr; - } - while (sc->ignet_push_shares != NULL) { - StrBufAppendPrintf(Cfg, "ignet_push_share|%s", sc->ignet_push_shares->remote_nodename); - if (!IsEmptyStr(sc->ignet_push_shares->remote_roomname)) { - StrBufAppendPrintf(Cfg, "|%s", sc->ignet_push_shares->remote_roomname); - } - StrBufAppendPrintf(Cfg, "\n"); - mptr = sc->ignet_push_shares->next; - free(sc->ignet_push_shares); - sc->ignet_push_shares = mptr; - } - if (sc->misc != NULL) { - StrBufAppendBufPlain(Cfg, sc->misc, -1, 0); - } - free(sc->misc); - - rc = write(TmpFD, ChrPtr(Cfg), StrLength(Cfg)); - if ((rc >=0 ) && (rc == StrLength(Cfg))) - { - close(TmpFD); - rename(tempfilename, filename); - } - else { - syslog(LOG_EMERG, - "unable to write %s; [%s]; not enough space on the disk?\n", - tempfilename, - strerror(errno)); - close(TmpFD); - unlink(tempfilename); - } - FreeStrBuf(&Cfg); - free(sc); - *scc=NULL; - } - return 1; -} -#endif -int is_recipient(SpoolControl *sc, const char *Name) +int is_recipient(OneRoomNetCfg *RNCfg, const char *Name) { const RoomNetCfg RecipientCfgs[] = { listrecp, @@ -519,14 +166,14 @@ int is_recipient(SpoolControl *sc, const char *Name) maxRoomNetCfg }; int i; - namelist *nptr; + RoomNetCfgLine *nptr; size_t len; len = strlen(Name); i = 0; while (RecipientCfgs[i] != maxRoomNetCfg) { - nptr = sc->NetConfigs[RecipientCfgs[i]]; + nptr = RNCfg->NetConfigs[RecipientCfgs[i]]; while (nptr != NULL) { @@ -579,13 +226,13 @@ void network_spoolout_room(RoomProcList *room_to_spool, sc->the_netmap = the_netmap; /* If there are digest recipients, we have to build a digest */ - if (sc->NetConfigs[digestrecp] != NULL) { + if (sc->RNCfg->NetConfigs[digestrecp] != NULL) { sc->digestfp = tmpfile(); fprintf(sc->digestfp, "Content-type: text/plain\n\n"); } /* Do something useful */ - CtdlForEachMessage(MSGS_GT, sc->lastsent, NULL, NULL, NULL, + CtdlForEachMessage(MSGS_GT, sc->RNCfg->lastsent, NULL, NULL, NULL, network_spool_msg, sc); /* If we wrote a digest, deliver it and then close it */ @@ -1214,16 +861,14 @@ CTDL_MODULE_INIT(network_spool) { if (!threading) { -// REGISTERRoomCfgType(subpending, ParseSubPendingLine, 0, SerializeSubPendingLine, DeleteSubPendingLine); /// todo: move this to mailinglist manager -// REGISTERRoomCfgType(unsubpending, ParseUnSubPendingLine0, SerializeUnSubPendingLine, DeleteUnSubPendingLine); /// todo: move this to mailinglist manager -// REGISTERRoomCfgType(lastsent, ParseLastSent, 1, SerializeLastSent, DeleteLastSent); -/// REGISTERRoomCfgType(ignet_push_share, ParseIgnetPushShare, 0, SerializeIgnetPushShare, DeleteIgnetPushShare); // todo: move this to the ignet client - REGISTERRoomCfgType(listrecp, ParseDefault, 0, SerializeGeneric, DeleteGenericCfgLine); - REGISTERRoomCfgType(digestrecp, ParseDefault, 0, SerializeGeneric, DeleteGenericCfgLine); - REGISTERRoomCfgType(pop3client, ParseDefault, 0, SerializeGeneric, DeleteGenericCfgLine);/// todo: implement pop3 specific parser - REGISTERRoomCfgType(rssclient, ParseDefault, 0, SerializeGeneric, DeleteGenericCfgLine); /// todo: implement rss specific parser - REGISTERRoomCfgType(participate, ParseDefault, 0, SerializeGeneric, DeleteGenericCfgLine); - REGISTERRoomCfgType(roommailalias, ParseRoomAlias, 0, SerializeGeneric, DeleteGenericCfgLine); +// CtdlREGISTERRoomCfgType(subpending, ParseSubPendingLine, 0, SerializeSubPendingLine, DeleteSubPendingLine); /// todo: move this to mailinglist manager +// CtdlREGISTERRoomCfgType(unsubpending, ParseUnSubPendingLine0, SerializeUnSubPendingLine, DeleteUnSubPendingLine); /// todo: move this to mailinglist manager +// CtdlREGISTERRoomCfgType(lastsent, ParseLastSent, 1, SerializeLastSent, DeleteLastSent); +/// CtdlREGISTERRoomCfgType(ignet_push_share, ParseIgnetPushShare, 0, SerializeIgnetPushShare, DeleteIgnetPushShare); // todo: move this to the ignet client + CtdlREGISTERRoomCfgType(listrecp, ParseGeneric, 0, SerializeGeneric, DeleteGenericCfgLine); + CtdlREGISTERRoomCfgType(digestrecp, ParseGeneric, 0, SerializeGeneric, DeleteGenericCfgLine); + CtdlREGISTERRoomCfgType(participate, ParseGeneric, 0, SerializeGeneric, DeleteGenericCfgLine); + CtdlREGISTERRoomCfgType(roommailalias, ParseRoomAlias, 0, SerializeGeneric, DeleteGenericCfgLine); create_spool_dirs(); //////todo CtdlRegisterCleanupHook(destroy_network_queue_room); diff --git a/citadel/modules/network/serv_network.c b/citadel/modules/network/serv_network.c index f43a49965..094aedf73 100644 --- a/citadel/modules/network/serv_network.c +++ b/citadel/modules/network/serv_network.c @@ -76,10 +76,10 @@ #include "citadel_dirs.h" #include "threads.h" #include "context.h" +#include "ctdl_module.h" #include "netconfig.h" #include "netspool.h" #include "netmail.h" -#include "ctdl_module.h" int NetQDebugEnabled = 0; struct CitContext networker_spool_CC; diff --git a/citadel/modules/network/serv_network.h b/citadel/modules/network/serv_network.h index 486c2d9ab..1cc61f460 100644 --- a/citadel/modules/network/serv_network.h +++ b/citadel/modules/network/serv_network.h @@ -30,12 +30,6 @@ extern int NetQDebugEnabled; "CC[%d]" FORMAT, \ CCC->cs_pid) -typedef struct namelist namelist; - -struct namelist { - namelist *next; - StrBuf *Value; -}; void free_netfilter_list(void); diff --git a/citadel/modules/pop3client/serv_pop3client.c b/citadel/modules/pop3client/serv_pop3client.c index 433309f38..0672919bf 100644 --- a/citadel/modules/pop3client/serv_pop3client.c +++ b/citadel/modules/pop3client/serv_pop3client.c @@ -1263,6 +1263,7 @@ CTDL_MODULE_INIT(pop3client) if (!threading) { CtdlFillSystemContext(&pop3_client_CC, "POP3aggr"); + CtdlREGISTERRoomCfgType(pop3client, ParseGeneric, 0, SerializeGeneric, DeleteGenericCfgLine);/// todo: implement pop3 specific parser pthread_mutex_init(&POP3QueueMutex, NULL); POP3QueueRooms = NewHash(1, lFlathash); POP3FetchUrls = NewHash(1, NULL); diff --git a/citadel/modules/rssclient/serv_rssclient.c b/citadel/modules/rssclient/serv_rssclient.c index 82e206792..0c8265060 100644 --- a/citadel/modules/rssclient/serv_rssclient.c +++ b/citadel/modules/rssclient/serv_rssclient.c @@ -799,6 +799,7 @@ CTDL_MODULE_INIT(rssclient) { if (threading) { + CtdlREGISTERRoomCfgType(rssclient, ParseGeneric, 0, SerializeGeneric, DeleteGenericCfgLine); /// todo: implement rss specific parser CtdlFillSystemContext(&rss_CC, "rssclient"); pthread_mutex_init(&RSSQueueMutex, NULL); RSSQueueRooms = NewHash(1, lFlathash); diff --git a/citadel/netconfig.c b/citadel/netconfig.c new file mode 100644 index 000000000..3c20541c0 --- /dev/null +++ b/citadel/netconfig.c @@ -0,0 +1,278 @@ +/* + * This module handles shared rooms, inter-Citadel mail, and outbound + * mailing list processing. + * + * Copyright (c) 2000-2012 by the citadel.org team + * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "sysdep.h" +#include + +#ifdef HAVE_SYSCALL_H +# include +#else +# if HAVE_SYS_SYSCALL_H +# include +# endif +#endif + +#include + +#include "include/ctdl_module.h" +HashList *CfgTypeHash = NULL; + + + +void RegisterRoomCfgType(const char* Name, long len, RoomNetCfg eCfg, CfgLineParser p, int uniq, CfgLineSerializer s, CfgLineDeAllocator d) +{ + CfgLineType *pCfg; + + pCfg = (CfgLineType*) malloc(sizeof(CfgLineType)); + pCfg->Parser = p; + pCfg->Serializer = s; + pCfg->C = eCfg; + pCfg->Str.Key = Name; + pCfg->Str.len = len; + pCfg->IsSingleLine = uniq; + + if (CfgTypeHash == NULL) + CfgTypeHash = NewHash(1, NULL); + Put(CfgTypeHash, Name, len, pCfg, NULL); +} + + +const CfgLineType *GetCfgTypeByStr(const char *Key, long len) +{ + void *pv; + + if (GetHash(CfgTypeHash, Key, len, &pv) && (pv != NULL)) + { + return (const CfgLineType *) pv; + } + else + { + return NULL; + } +} + +const CfgLineType *GetCfgTypeByEnum(RoomNetCfg eCfg, HashPos *It) +{ + const char *Key; + long len; + void *pv; + CfgLineType *pCfg; + + RewindHashPos(CfgTypeHash, It, 1); + while (GetNextHashPos(CfgTypeHash, It, &len, &Key, &pv) && (pv != NULL)) + { + pCfg = (CfgLineType*) pv; + if (pCfg->C == eCfg) + return pCfg; + } + return NULL; +} +void ParseGeneric(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *OneRNCFG) +{ + RoomNetCfgLine *nptr; + + nptr = (RoomNetCfgLine *) + malloc(sizeof(RoomNetCfgLine)); + nptr->next = OneRNCFG->NetConfigs[ThisOne->C]; + nptr->Value = NewStrBufPlain(LinePos, StrLength(Line) - ( LinePos - ChrPtr(Line)) ); + OneRNCFG->NetConfigs[ThisOne->C] = nptr; +} + +void SerializeGeneric(const CfgLineType *ThisOne, StrBuf *OutputBuffer, OneRoomNetCfg *OneRNCFG, RoomNetCfgLine *data) +{ + StrBufAppendBufPlain(OutputBuffer, CKEY(ThisOne->Str), 0); + StrBufAppendBuf(OutputBuffer, data->Value, 0); + StrBufAppendBufPlain(OutputBuffer, HKEY("\n"), 0); +} + +void DeleteGenericCfgLine(const CfgLineType *ThisOne, RoomNetCfgLine **data) +{ + FreeStrBuf(&(*data)->Value); + free(*data); + *data = NULL; +} +int read_spoolcontrol_file(OneRoomNetCfg **pOneRNCFG, char *filename) +{ + int fd; + const char *ErrStr = NULL; + const char *Pos; + const CfgLineType *pCfg; + StrBuf *Line; + StrBuf *InStr; + OneRoomNetCfg *OneRNCFG; + + fd = open(filename, O_NONBLOCK|O_RDONLY); + if (fd == -1) { + *pOneRNCFG = NULL; + return 0; + } + OneRNCFG = malloc(sizeof(OneRoomNetCfg)); + memset(OneRNCFG, 0, sizeof(OneRoomNetCfg)); + *pOneRNCFG = OneRNCFG; + + while (StrBufTCP_read_line(Line, &fd, 0, &ErrStr) >= 0) { + if (StrLength(Line) == 0) + continue; + Pos = NULL; + InStr = NewStrBufPlain(NULL, StrLength(Line)); + StrBufExtract_NextToken(InStr, Line, &Pos, '|'); + + pCfg = GetCfgTypeByStr(SKEY(InStr)); + if (pCfg != NULL) + { + pCfg->Parser(pCfg, Line, Pos, OneRNCFG); + } + else + { + if (OneRNCFG->misc == NULL) + { + OneRNCFG->misc = NewStrBufDup(Line); + } + else + { + if(StrLength(OneRNCFG->misc) > 0) + StrBufAppendBufPlain(OneRNCFG->misc, HKEY("\n"), 0); + StrBufAppendBuf(OneRNCFG->misc, Line, 0); + } + } + } + if (fd > 0) + close(fd); + FreeStrBuf(&InStr); + FreeStrBuf(&Line); + return 1; +} + +int save_spoolcontrol_file(OneRoomNetCfg *OneRNCFG, char *filename) +{ + RoomNetCfg eCfg; + StrBuf *Cfg; + char tempfilename[PATH_MAX]; + int TmpFD; + long len; + time_t unixtime; + struct timeval tv; + long reltid; /* if we don't have SYS_gettid, use "random" value */ + StrBuf *OutBuffer; + int rc; + HashPos *CfgIt; + + len = strlen(filename); + memcpy(tempfilename, filename, len + 1); + +#if defined(HAVE_SYONERNCFGALL_H) && defined (SYS_gettid) + reltid = syOneRNCFGall(SYS_gettid); +#endif + gettimeofday(&tv, NULL); + /* Promote to time_t; types differ on some OSes (like darwin) */ + unixtime = tv.tv_sec; + + sprintf(tempfilename + len, ".%ld-%ld", reltid, unixtime); + errno = 0; + TmpFD = open(tempfilename, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR); + Cfg = NewStrBuf(); + if ((TmpFD < 0) || (errno != 0)) { + syslog(LOG_CRIT, "ERROR: cannot open %s: %s\n", + filename, strerror(errno)); + unlink(tempfilename); + return 0; + } + else { + CfgIt = GetNewHashPos(CfgTypeHash, 1); + fchown(TmpFD, config.c_ctdluid, 0); + for (eCfg = subpending; eCfg < maxRoomNetCfg; eCfg ++) + { + const CfgLineType *pCfg; + pCfg = GetCfgTypeByEnum(eCfg, CfgIt); + if (pCfg->IsSingleLine) + { + pCfg->Serializer(pCfg, OutBuffer, OneRNCFG, NULL); + } + else + { + RoomNetCfgLine *pName = OneRNCFG->NetConfigs[pCfg->C]; + while (pName != NULL) + { + pCfg->Serializer(pCfg, OutBuffer, OneRNCFG, pName); + pName = pName->next; + } + + + } + + } + DeleteHashPos(&CfgIt); + + + if (OneRNCFG->misc != NULL) { + StrBufAppendBuf(OutBuffer, OneRNCFG->misc, 0); + } + + rc = write(TmpFD, ChrPtr(OutBuffer), StrLength(OutBuffer)); + if ((rc >=0 ) && (rc == StrLength(Cfg))) + { + close(TmpFD); + rename(tempfilename, filename); + rc = 1; + } + else { + syslog(LOG_EMERG, + "unable to write %s; [%s]; not enough space on the disk?\n", + tempfilename, + strerror(errno)); + close(TmpFD); + unlink(tempfilename); + rc = 0; + } + FreeStrBuf(&OutBuffer); + + } + return rc; +} + + + +void free_spoolcontrol_struct(OneRoomNetCfg **pOneRNCFG) +{ + RoomNetCfg eCfg; + HashPos *CfgIt; + OneRoomNetCfg *OneRNCFG; + + OneRNCFG = *pOneRNCFG; + CfgIt = GetNewHashPos(CfgTypeHash, 1); + for (eCfg = subpending; eCfg < maxRoomNetCfg; eCfg ++) + { + const CfgLineType *pCfg; + RoomNetCfgLine *pNext, *pName; + + pCfg = GetCfgTypeByEnum(eCfg, CfgIt); + pName= OneRNCFG->NetConfigs[pCfg->C]; + while (pName != NULL) + { + pNext = pName->next; + pCfg->DeAllocator(pCfg, &pName); + pName = pNext; + } + } + DeleteHashPos(&CfgIt); + + FreeStrBuf(&OneRNCFG->Sender); + FreeStrBuf(&OneRNCFG->RoomInfo); + FreeStrBuf(&OneRNCFG->misc); + free(OneRNCFG); + *pOneRNCFG=NULL; +} + -- 2.30.2