- 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
CfgLineDeAllocator DeAllocator;
ConstStr Str;
int IsSingleLine;
+ int nSegments;
};
struct RoomNetCfgLine {
RoomNetCfgLine *next;
- StrBuf *Value;
+ int nValues;
+ StrBuf **Value;
};
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);
#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)
*/
}
-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);
}
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
*/
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;
{
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);
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);
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);
CtdlRegisterEVCleanupHook(rss_cleanup);
CtdlRegisterDebugFlagHook(HKEY("rssclient"), LogDebugEnableRSSClient, &RSSClientDebugEnabled);
}
+ else
+ {
+ CtdlFillSystemContext(&rss_CC, "rssclient");
+ }
return "rssclient";
}
# 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;
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);
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;
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)
return 1;
}
-int save_spoolcontrol_file(OneRoomNetCfg *OneRNCFG, char *filename)
+int SaveRoomNetConfigFile(OneRoomNetCfg *OneRNCFG, char *filename)
{
RoomNetCfg eCfg;
StrBuf *Cfg;
}
-
-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 ++)
{
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 *
*-----------------------------------------------------------------------------*/
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;
}
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,
}
end_critical_section(S_NETCONFIGS);
found = is_recipient (RNCfg, RemoteIdentifier);
- free_spoolcontrol_struct(&RNCfg);
+ vFreeRoomNetworkStruct(&RNCfg);
if (found) {
return (0);
}
}
+
+
/*
* Module entry point
*/
{
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");
CTDL_MODULE_INIT(msgbase);
CTDL_MODULE_INIT(room_ops);
CTDL_MODULE_INIT(user_ops);
+ CTDL_MODULE_INIT(netconfig);
EOF
for i in serv_*.c
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