NETCFG: make basic parsing
authorWilfried Goesgens <dothebart@citadel.org>
Wed, 9 Jan 2013 22:08:09 +0000 (23:08 +0100)
committerWilfried Goesgens <dothebart@citadel.org>
Wed, 9 Jan 2013 22:08:09 +0000 (23:08 +0100)
  - add hook to module init; make shure its run last, so everyone registered his config parsers
  - make rss hooks at the right time
  - implement generic parser that works for most of the configs by simply splitting the lines

citadel/include/ctdl_module.h
citadel/modules/network/serv_netspool.c
citadel/modules/pop3client/serv_pop3client.c
citadel/modules/rssclient/serv_rssclient.c
citadel/netconfig.c
citadel/scripts/mk_module_init.sh

index 7dad38745dd8c472f82c9658775a8b2b466db805..25a00fa70d250eaef5e6cad520ebcf4e0144493c 100644 (file)
@@ -393,11 +393,13 @@ struct CfgLineType {
        CfgLineDeAllocator DeAllocator;
        ConstStr Str;
        int IsSingleLine;
+       int nSegments;
 };
 
 struct RoomNetCfgLine {
        RoomNetCfgLine *next;
-       StrBuf *Value;
+       int nValues;
+       StrBuf **Value;
 };
 
 struct OneRoomNetCfg {
@@ -409,8 +411,8 @@ struct OneRoomNetCfg {
 };
 
 
-#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);
+#define CtdlREGISTERRoomCfgType(a, p, uniq, nSegs, s, d) RegisterRoomCfgType(#a, sizeof(#a) - 1, a, p, uniq, nSegs, s, d);
+void RegisterRoomCfgType(const char* Name, long len, RoomNetCfg eCfg, CfgLineParser p, int uniq, int nSegments, 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);
index 1da98f8071412c5570a0aded7cf13fcdf0124168..f2ad74ddea09db266443c65b5e4f9fa93baca280 100644 (file)
 #endif
 
 
-void ParseLastSent(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *rncfg)
+void ParseLastSent(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *OneRNCFG)
 {
-       rncfg->lastsent = extract_long(LinePos, 0);
-}
-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 = rncfg->RNCfg->ignet_push_shares;
-       strcpy(mptr->remote_nodename, nodename);
-       strcpy(mptr->remote_roomname, roomname);
-       rncfg->RNCfg->ignet_push_shares = mptr;
-*/
+       RoomNetCfgLine *nptr;
+       nptr = (RoomNetCfgLine *)
+               malloc(sizeof(RoomNetCfgLine));
+       
+       OneRNCFG->lastsent = extract_long(LinePos, 0);
+       OneRNCFG->NetConfigs[ThisOne->C] = nptr;
 }
 
 void ParseRoomAlias(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *rncfg)
@@ -121,24 +114,19 @@ void ParseRoomAlias(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePo
 */
 }
 
-void ParseSubPendingLine(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *rncfg)
+void ParseSubPendingLine(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *OneRNCFG)
 {
+       if (time(NULL) - extract_long(LinePos, 3) > EXP) 
+               return; /* expired subscription... */
 
-       if (time(NULL) - extract_long(LinePos, 3) > EXP) {
-               //      skipthisline = 1;
-       }
-       else
-       {
-       }
-
+       ParseGeneric(ThisOne, Line, LinePos, OneRNCFG);
 }
-void ParseUnSubPendingLine(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *rncfg)
+void ParseUnSubPendingLine(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *OneRNCFG)
 {
-       ///int skipthisline = 0;
-       if (time(NULL) - extract_long(LinePos, 2) > EXP) {
-               //      skipthisline = 1;
-       }
+       if (time(NULL) - extract_long(LinePos, 2) > EXP)
+               return; /* expired subscription... */
 
+       ParseGeneric(ThisOne, Line, LinePos, OneRNCFG);
 }
 
 
@@ -148,24 +136,15 @@ void SerializeLastSent(const CfgLineType *ThisOne, StrBuf *OutputBuffer, OneRoom
        StrBufAppendPrintf(OutputBuffer, "|%ld\n", RNCfg->lastsent);
 }
 
-void SerializeIgnetPushShare(const CfgLineType *ThisOne, StrBuf *OutputBuffer, OneRoomNetCfg *RNCfg, RoomNetCfgLine *data)
+void DeleteLastSent(const CfgLineType *ThisOne, RoomNetCfgLine **data)
 {
-       StrBufAppendBufPlain(OutputBuffer, CKEY(ThisOne->Str), 0);
-/*
-                       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 = 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);
+       free(*data);
+       *data = NULL;
 }
 
 
+
+
 /*
  * Batch up and send all outbound traffic from the current room
  */
@@ -192,7 +171,7 @@ void network_spoolout_room(RoomProcList *room_to_spool,
        begin_critical_section(S_NETCONFIGS);
 
        /* Only do net processing for rooms that have netconfigs */
-       if (!read_spoolcontrol_file(&sc, filename))
+       if (!ReadRoomNetConfigFile(&sc, filename))
        {
                end_critical_section(S_NETCONFIGS);
                return;
@@ -895,14 +874,14 @@ CTDL_MODULE_INIT(network_spool)
 {
        if (!threading)
        {
-//             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);
+               CtdlREGISTERRoomCfgType(subpending,       ParseSubPendingLine,   0, 5, SerializeGeneric,  DeleteGenericCfgLine); /// todo: move this to mailinglist manager
+               CtdlREGISTERRoomCfgType(unsubpending,     ParseUnSubPendingLine, 0, 4, SerializeGeneric,  DeleteGenericCfgLine); /// todo: move this to mailinglist manager
+               CtdlREGISTERRoomCfgType(lastsent,         ParseLastSent,         1, 1, SerializeLastSent, DeleteLastSent);
+               CtdlREGISTERRoomCfgType(ignet_push_share, ParseGeneric,          0, 2, SerializeGeneric,  DeleteGenericCfgLine); // [remotenode|remoteroomname (optional)]// todo: move this to the ignet client
+               CtdlREGISTERRoomCfgType(listrecp,         ParseGeneric,          0, 1, SerializeGeneric,  DeleteGenericCfgLine);
+               CtdlREGISTERRoomCfgType(digestrecp,       ParseGeneric,          0, 1, SerializeGeneric,  DeleteGenericCfgLine);
+               CtdlREGISTERRoomCfgType(participate,      ParseGeneric,          0, 1, SerializeGeneric,  DeleteGenericCfgLine);
+               CtdlREGISTERRoomCfgType(roommailalias,    ParseRoomAlias,        0, 1, SerializeGeneric,  DeleteGenericCfgLine);
 
                create_spool_dirs();
 //////todo             CtdlRegisterCleanupHook(destroy_network_queue_room);
index 0672919bf9c6b0ccfa51babe9bc1f10060a754ad..63451ed0583340ac2c1cc76139e9f1eacc5085f7 100644 (file)
@@ -1263,7 +1263,7 @@ CTDL_MODULE_INIT(pop3client)
        if (!threading)
        {
                CtdlFillSystemContext(&pop3_client_CC, "POP3aggr");
-               CtdlREGISTERRoomCfgType(pop3client, ParseGeneric, 0, SerializeGeneric, DeleteGenericCfgLine);/// todo: implement pop3 specific parser
+               CtdlREGISTERRoomCfgType(pop3client, ParseGeneric, 0, 3, SerializeGeneric, DeleteGenericCfgLine);
                pthread_mutex_init(&POP3QueueMutex, NULL);
                POP3QueueRooms = NewHash(1, lFlathash);
                POP3FetchUrls = NewHash(1, NULL);
index 0c826506029aa01cc02f491d4c212ea4e5f85275..29c3efea235e6ce95480198b6037cf20c68ed7cc 100644 (file)
@@ -797,10 +797,9 @@ void LogDebugEnableRSSClient(const int n)
 
 CTDL_MODULE_INIT(rssclient)
 {
-       if (threading)
+       if (!threading)
        {
-               CtdlREGISTERRoomCfgType(rssclient, ParseGeneric, 0, SerializeGeneric, DeleteGenericCfgLine); /// todo: implement rss specific parser
-               CtdlFillSystemContext(&rss_CC, "rssclient");
+               CtdlREGISTERRoomCfgType(rssclient, ParseGeneric, 0, 1, SerializeGeneric, DeleteGenericCfgLine); /// todo: implement rss specific parser
                pthread_mutex_init(&RSSQueueMutex, NULL);
                RSSQueueRooms = NewHash(1, lFlathash);
                RSSFetchUrls = NewHash(1, NULL);
@@ -809,5 +808,9 @@ CTDL_MODULE_INIT(rssclient)
                CtdlRegisterEVCleanupHook(rss_cleanup);
                CtdlRegisterDebugFlagHook(HKEY("rssclient"), LogDebugEnableRSSClient, &RSSClientDebugEnabled);
        }
+       else
+       {
+               CtdlFillSystemContext(&rss_CC, "rssclient");
+       }
        return "rssclient";
 }
index 6137bd3d48d99202e0d3ca0f779ea2f80d7e21e3..984f97a2865e68aebe74f64df5b8e4e04d1eb03a 100644 (file)
 #  include <sys/syscall.h>
 # endif
 #endif
+#include <dirent.h>
 
 #include <libcitadel.h>
 
 #include "include/ctdl_module.h"
 HashList *CfgTypeHash = NULL;
-
+HashList *RoomConfigs = NULL;
 /*-----------------------------------------------------------------------------*
  *                       Per room network configs                              *
  *-----------------------------------------------------------------------------*/
-void RegisterRoomCfgType(const char* Name, long len, RoomNetCfg eCfg, CfgLineParser p, int uniq, CfgLineSerializer s, CfgLineDeAllocator d)
+void RegisterRoomCfgType(const char* Name, long len, RoomNetCfg eCfg, CfgLineParser p, int uniq,  int nSegments, CfgLineSerializer s, CfgLineDeAllocator d)
 {
        CfgLineType *pCfg;
 
@@ -44,7 +45,7 @@ void RegisterRoomCfgType(const char* Name, long len, RoomNetCfg eCfg, CfgLinePar
        pCfg->Str.Key = Name;
        pCfg->Str.len = len;
        pCfg->IsSingleLine = uniq;
-
+       pCfg->nSegments = nSegments;
        if (CfgTypeHash == NULL)
                CfgTypeHash = NewHash(1, NULL);
        Put(CfgTypeHash, Name, len, pCfg, NULL);
@@ -84,28 +85,53 @@ const CfgLineType *GetCfgTypeByEnum(RoomNetCfg eCfg, HashPos *It)
 void ParseGeneric(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *OneRNCFG)
 {
        RoomNetCfgLine *nptr;
+       int i;
 
        nptr = (RoomNetCfgLine *)
                malloc(sizeof(RoomNetCfgLine));
        nptr->next = OneRNCFG->NetConfigs[ThisOne->C];
-       nptr->Value = NewStrBufPlain(LinePos, StrLength(Line) - ( LinePos - ChrPtr(Line)) );
+       nptr->Value = malloc(sizeof(StrBuf*) * ThisOne->nSegments);
+       memset(nptr->Value, 0, sizeof(StrBuf*) * ThisOne->nSegments);
+       if (ThisOne->nSegments == 1)
+       {
+               nptr->Value[0] = NewStrBufPlain(LinePos, StrLength(Line) - ( LinePos - ChrPtr(Line)) );
+       }
+       else for (i = 0; i < ThisOne->nSegments; i++)
+       {
+               nptr->Value[i] = NewStrBufPlain(NULL, StrLength(Line) - ( LinePos - ChrPtr(Line)) );
+               StrBufExtract_NextToken(nptr->Value[i], Line, &LinePos, '|');
+       }
+
        OneRNCFG->NetConfigs[ThisOne->C] = nptr;
 }
 
 void SerializeGeneric(const CfgLineType *ThisOne, StrBuf *OutputBuffer, OneRoomNetCfg *OneRNCFG, RoomNetCfgLine *data)
 {
+       int i;
+
        StrBufAppendBufPlain(OutputBuffer, CKEY(ThisOne->Str), 0);
-       StrBufAppendBuf(OutputBuffer, data->Value, 0);
+       for (i = 0; i < ThisOne->nSegments; i++)
+       {
+               StrBufAppendBuf(OutputBuffer, data->Value[i], 0);
+               if (i + 1 < ThisOne->nSegments)
+                       StrBufAppendBufPlain(OutputBuffer, HKEY("|"), 0);
+       }
        StrBufAppendBufPlain(OutputBuffer, HKEY("\n"), 0);
 }
 
 void DeleteGenericCfgLine(const CfgLineType *ThisOne, RoomNetCfgLine **data)
 {
-       FreeStrBuf(&(*data)->Value);
+       int i;
+
+       for (i = 0; i < ThisOne->nSegments; i++)
+       {
+               FreeStrBuf(&(*data)->Value[i]);
+       }
+       free ((*data)->Value);
        free(*data);
        *data = NULL;
 }
-int read_spoolcontrol_file(OneRoomNetCfg **pOneRNCFG, char *filename)
+int ReadRoomNetConfigFile(OneRoomNetCfg **pOneRNCFG, char *filename)
 {
        int fd;
        const char *ErrStr = NULL;
@@ -123,6 +149,7 @@ int read_spoolcontrol_file(OneRoomNetCfg **pOneRNCFG, char *filename)
        OneRNCFG = malloc(sizeof(OneRoomNetCfg));
        memset(OneRNCFG, 0, sizeof(OneRoomNetCfg));
        *pOneRNCFG = OneRNCFG;
+       Line = NewStrBuf();
 
        while (StrBufTCP_read_line(Line, &fd, 0, &ErrStr) >= 0) {
                if (StrLength(Line) == 0)
@@ -157,7 +184,7 @@ int read_spoolcontrol_file(OneRoomNetCfg **pOneRNCFG, char *filename)
        return 1;
 }
 
-int save_spoolcontrol_file(OneRoomNetCfg *OneRNCFG, char *filename)
+int SaveRoomNetConfigFile(OneRoomNetCfg *OneRNCFG, char *filename)
 {
        RoomNetCfg eCfg;
        StrBuf *Cfg;
@@ -245,14 +272,13 @@ int save_spoolcontrol_file(OneRoomNetCfg *OneRNCFG, char *filename)
 }
 
 
-
-void free_spoolcontrol_struct(OneRoomNetCfg **pOneRNCFG)
+void vFreeRoomNetworkStruct(void *vOneRoomNetCfg)
 {
        RoomNetCfg eCfg;
        HashPos *CfgIt;
        OneRoomNetCfg *OneRNCFG;
 
-       OneRNCFG = *pOneRNCFG;
+       OneRNCFG = (OneRoomNetCfg*)vOneRoomNetCfg;
        CfgIt = GetNewHashPos(CfgTypeHash, 1);
        for (eCfg = subpending; eCfg < maxRoomNetCfg; eCfg ++)
        {
@@ -274,10 +300,123 @@ void free_spoolcontrol_struct(OneRoomNetCfg **pOneRNCFG)
        FreeStrBuf(&OneRNCFG->RoomInfo);
        FreeStrBuf(&OneRNCFG->misc);
        free(OneRNCFG);
+}
+void FreeRoomNetworkStruct(OneRoomNetCfg **pOneRNCFG)
+{
+       vFreeRoomNetworkStruct(*pOneRNCFG);
        *pOneRNCFG=NULL;
 }
 
 
+void LoadAllNetConfigs(void)
+{
+       DIR *filedir = NULL;
+       struct dirent *d;
+       struct dirent *filedir_entry;
+       int d_type = 0;
+        int d_namelen;
+       long RoomNumber;
+       OneRoomNetCfg *OneRNCFG;
+       int IsNumOnly;
+       const char *pch;
+       char path[PATH_MAX];
+
+       RoomConfigs = NewHash(1, NULL);
+       filedir = opendir (ctdl_netcfg_dir);
+       if (filedir == NULL) {
+               return ; /// todo: panic!
+       }
+
+       d = (struct dirent *)malloc(offsetof(struct dirent, d_name) + PATH_MAX + 1);
+       if (d == NULL) {
+               closedir(filedir);
+               return ;
+       }
+
+       while ((readdir_r(filedir, d, &filedir_entry) == 0) &&
+              (filedir_entry != NULL))
+       {
+#ifdef _DIRENT_HAVE_D_NAMLEN
+               d_namelen = filedir_entry->d_namelen;
+#else
+               d_namelen = strlen(filedir_entry->d_name);
+#endif
+
+#ifdef _DIRENT_HAVE_D_TYPE
+               d_type = filedir_entry->d_type;
+#else
+
+#ifndef DT_UNKNOWN
+#define DT_UNKNOWN     0
+#define DT_DIR         4
+#define DT_REG         8
+#define DT_LNK         10
+
+#define IFTODT(mode)   (((mode) & 0170000) >> 12)
+#define DTTOIF(dirtype)        ((dirtype) << 12)
+#endif
+               d_type = DT_UNKNOWN;
+#endif
+               if ((d_namelen > 1) && filedir_entry->d_name[d_namelen - 1] == '~')
+                       continue; /* Ignore backup files... */
+
+               if ((d_namelen == 1) && 
+                   (filedir_entry->d_name[0] == '.'))
+                       continue;
+
+               if ((d_namelen == 2) && 
+                   (filedir_entry->d_name[0] == '.') &&
+                   (filedir_entry->d_name[1] == '.'))
+                       continue;
+
+               snprintf(path, PATH_MAX, "%s/%s", 
+                        ctdl_netcfg_dir, filedir_entry->d_name);
+
+               if (d_type == DT_UNKNOWN) {
+                       struct stat s;
+                       if (lstat(path, &s) == 0) {
+                               d_type = IFTODT(s.st_mode);
+                       }
+               }
+
+               switch (d_type)
+               {
+               case DT_DIR:
+                       break;
+               case DT_LNK: /* TODO: check whether its a file or a directory */
+               case DT_REG:
+                       IsNumOnly = 1;
+                       pch = filedir_entry->d_name;
+                       while (*pch != '\0')
+                       {
+                               if (!isdigit(*pch))
+                               {
+                                       IsNumOnly = 0;
+                               }
+                               pch ++;
+                       }
+                       if (IsNumOnly)
+                       {
+                               RoomNumber = atol(filedir_entry->d_name);
+                               ReadRoomNetConfigFile(&OneRNCFG, path);
+
+                               if (OneRNCFG != NULL)
+                                       Put(RoomConfigs, LKEY(RoomNumber), OneRNCFG, vFreeRoomNetworkStruct);
+                                   
+                               /* syslog(9, "[%s | %s]\n", ChrPtr(OneWebName), ChrPtr(FileName)); */
+                       }
+                       break;
+               default:
+                       break;
+               }
+
+
+       }
+       free(d);
+       closedir(filedir);
+}
+
+
 /*-----------------------------------------------------------------------------*
  *              Per room network configs : exchange with client                *
  *-----------------------------------------------------------------------------*/
@@ -574,8 +713,8 @@ int is_recipient(OneRoomNetCfg *RNCfg, const char *Name)
                
                while (nptr != NULL)
                {
-                       if ((StrLength(nptr->Value) == len) && 
-                           (!strcmp(Name, ChrPtr(nptr->Value))))
+                       if ((StrLength(nptr->Value[0]) == len) && 
+                           (!strcmp(Name, ChrPtr(nptr->Value[0]))))
                        {
                                return 1;
                        }
@@ -604,7 +743,7 @@ int CtdlNetconfigCheckRoomaccess(
 
        assoc_file_name(filename, sizeof filename, &CC->room, ctdl_netcfg_dir);
        begin_critical_section(S_NETCONFIGS);
-       if (!read_spoolcontrol_file(&RNCfg, filename))
+       if (!ReadRoomNetConfigFile(&RNCfg, filename))
        {
                end_critical_section(S_NETCONFIGS);
                snprintf(errmsgbuf, n,
@@ -613,7 +752,7 @@ int CtdlNetconfigCheckRoomaccess(
        }
        end_critical_section(S_NETCONFIGS);
        found = is_recipient (RNCfg, RemoteIdentifier);
-       free_spoolcontrol_struct(&RNCfg);
+       vFreeRoomNetworkStruct(&RNCfg);
        if (found) {
                return (0);
        }
@@ -906,6 +1045,8 @@ int CtdlIsValidNode(const StrBuf **nexthop,
 }
 
 
+
+
 /*
  * Module entry point
  */
@@ -913,7 +1054,7 @@ CTDL_MODULE_INIT(netconfig)
 {
        if (!threading)
        {
-
+               LoadAllNetConfigs ();
                CtdlRegisterProtoHook(cmd_gnet, "GNET", "Get network config");
                CtdlRegisterProtoHook(cmd_snet, "SNET", "Set network config");
                CtdlRegisterProtoHook(cmd_netp, "NETP", "Identify as network poller");
index 7939cd7faa92cd306b63eba6867e48eaefe95707..bbf19b783819daeb10807659c2b6babc1806ce1b 100755 (executable)
@@ -171,6 +171,7 @@ void upgrade_modules(void);
        CTDL_MODULE_INIT(msgbase);
        CTDL_MODULE_INIT(room_ops);
        CTDL_MODULE_INIT(user_ops);
+       CTDL_MODULE_INIT(netconfig);
 EOF
 
 for i in serv_*.c
@@ -318,6 +319,11 @@ fi
 
 cd $CUR_DIR
 
+# this one has to be called last, else it will not find all hooks registered.
+cat <<EOF >> $C_FILE
+        pMod = CTDL_INIT_CALL(netconfig);
+        MOD_syslog(LOG_DEBUG, "Loaded module: %s\n", pMod);
+EOF
 /usr/bin/printf "\n\n" >> $C_FILE
 /usr/bin/printf "\tfor (filter = 1; filter != 0; filter = filter << 1)\n" >> $C_FILE
 /usr/bin/printf "\t\tif ((filter & DetailErrorFlags) != 0)\n" >> $C_FILE