#include "ctdl_module.h"
-#include "netconfig.h"
#include "netspool.h"
#include "netmail.h"
+#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
-void ParseLastSent(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *rncfg)
-{
- rncfg->lastsent = extract_long(LinePos, 0);
-}
-void ParseIgnetPushShare(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *rncfg)
+
+void ParseLastSent(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *OneRNCFG)
{
-/*
- 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
*/
HashList *working_ignetcfg,
HashList *the_netmap)
{
+ struct CitContext *CCC = CC;
char buf[SIZ];
- char filename[PATH_MAX];
- SpoolControl *sc;
+ SpoolControl sc;
int i;
+ memset(&sc, 0, sizeof(SpoolControl));
+ sc.RNCfg = room_to_spool->OneRNCfg;
+ sc.lastsent = room_to_spool->OneRNCfg->lastsent;
+ sc.working_ignetcfg = working_ignetcfg;
+ sc.the_netmap = the_netmap;
+
+ if ((sc.RNCfg->NetConfigs[listrecp] == NULL) &&
+ (sc.RNCfg->NetConfigs[digestrecp] == NULL) &&
+ (sc.RNCfg->NetConfigs[participate] == NULL) &&
+ (sc.RNCfg->NetConfigs[ignet_push_share] == NULL))
+ {
+ /* nothing to do for this room... */
+ return;
+ }
+
/*
* If the room doesn't exist, don't try to perform its networking tasks.
* Normally this should never happen, but once in a while maybe a room gets
* queued for networking and then deleted before it can happen.
*/
- if (CtdlGetRoom(&CC->room, room_to_spool->name) != 0) {
+ if (CtdlGetRoom(&CCC->room, room_to_spool->name) != 0) {
syslog(LOG_CRIT, "ERROR: cannot load <%s>\n", room_to_spool->name);
return;
}
- assoc_file_name(filename, sizeof filename, &CC->room, ctdl_netcfg_dir);
- begin_critical_section(S_NETCONFIGS);
-
- /* Only do net processing for rooms that have netconfigs */
- if (!read_spoolcontrol_file(&sc, filename))
- {
- end_critical_section(S_NETCONFIGS);
- return;
- }
- syslog(LOG_INFO, "Networking started for <%s>\n", CC->room.QRname);
-
- sc->working_ignetcfg = working_ignetcfg;
- sc->the_netmap = the_netmap;
+
+ syslog(LOG_INFO, "Networking started for <%s>\n", CCC->room.QRname);
/* If there are digest recipients, we have to build a digest */
- if (sc->RNCfg->NetConfigs[digestrecp] != NULL) {
- sc->digestfp = tmpfile();
- fprintf(sc->digestfp, "Content-type: text/plain\n\n");
+ 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->RNCfg->lastsent, NULL, NULL, NULL,
- network_spool_msg, sc);
+ CtdlForEachMessage(MSGS_GT, sc.lastsent, NULL, NULL, NULL,
+ network_spool_msg, &sc);
/* If we wrote a digest, deliver it and then close it */
- snprintf(buf, sizeof buf, "room_%s@%s",
- CC->room.QRname, config.c_fqdn);
+ if (StrLength(sc.RNCfg->Sender) > 0)
+ {
+ long len;
+ len = StrLength(sc.RNCfg->Sender);
+ if (len + 1 > sizeof(buf))
+ len = sizeof(buf) - 1;
+ memcpy(buf, ChrPtr(sc.RNCfg->Sender), len);
+ buf[len] = '\0';
+ }
+ else
+ {
+ snprintf(buf, sizeof buf, "room_%s@%s",
+ CCC->room.QRname, config.c_fqdn);
+ }
+
for (i=0; buf[i]; ++i) {
buf[i] = tolower(buf[i]);
if (isspace(buf[i])) buf[i] = '_';
}
- if (sc->digestfp != NULL) {
- fprintf(sc->digestfp, " -----------------------------------"
- "------------------------------------"
- "-------\n"
- "You are subscribed to the '%s' "
- "list.\n"
- "To post to the list: %s\n",
- CC->room.QRname, buf
+ if (sc.digestfp != NULL) {
+ fprintf(sc.digestfp,
+ " -----------------------------------"
+ "------------------------------------"
+ "-------\n"
+ "You are subscribed to the '%s' "
+ "list.\n"
+ "To post to the list: %s\n",
+ CCC->room.QRname, buf
);
- network_deliver_digest(sc); /* deliver and close */
+ network_deliver_digest(&sc); /* deliver and close */
}
/* Now rewrite the config file */
- //// todo writenfree_spoolcontrol_file(&sc, filename);
+ if (sc.lastsent != room_to_spool->OneRNCfg->lastsent)
+ {
+ room_to_spool->OneRNCfg->lastsent = sc.lastsent;
+ room_to_spool->OneRNCfg->changed = 1;
+ }
end_critical_section(S_NETCONFIGS);
}
struct CitContext *CCC = CC;
DIR *dp;
struct dirent *d;
+ struct dirent *filedir_entry;
struct stat statbuf;
char filename[PATH_MAX];
static time_t last_spoolin_mtime = 0L;
+ int d_type = 0;
+ int d_namelen;
/*
* Check the spoolin directory's modification time. If it hasn't
dp = opendir(ctdl_netin_dir);
if (dp == NULL) return;
- while (d = readdir(dp), d != NULL) {
- if ((strcmp(d->d_name, ".")) && (strcmp(d->d_name, ".."))) {
+ d = (struct dirent *)malloc(offsetof(struct dirent, d_name) + PATH_MAX + 1);
+ if (d == NULL) {
+ closedir(dp);
+ return;
+ }
+
+ while ((readdir_r(dp, 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
+ 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;
+
+ if (d_type == DT_UNKNOWN) {
+ struct stat s;
+ char path[PATH_MAX];
+
+ snprintf(path,
+ PATH_MAX,
+ "%s/%s",
+ ctdl_netin_dir,
+ filedir_entry->d_name);
+
+ 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:
snprintf(filename,
sizeof filename,
"%s/%s",
}
closedir(dp);
+ free(d);
}
/*
int i;
struct stat statbuf;
int nFailed = 0;
+ int d_type = 0;
+
/* Step 1: consolidate files in the outbound queue into one file per neighbor node */
d = (struct dirent *)malloc(offsetof(struct dirent, d_name) + PATH_MAX + 1);
while ((readdir_r(dp, d, &filedir_entry) == 0) &&
(filedir_entry != NULL))
{
-#ifdef _DIRENT_HAVE_D_NAMELEN
+#ifdef _DIRENT_HAVE_D_NAMLEN
d_namelen = filedir_entry->d_namelen;
-#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
+#else
d_namelen = strlen(filedir_entry->d_name);
#endif
+
+#ifdef _DIRENT_HAVE_D_TYPE
+ d_type = filedir_entry->d_type;
+#else
+ d_type = DT_UNKNOWN;
+#endif
+ if (d_type == DT_DIR)
+ continue;
+
if ((d_namelen > 1) && filedir_entry->d_name[d_namelen - 1] == '~')
continue; /* Ignore backup files... */
while ((readdir_r(dp, d, &filedir_entry) == 0) &&
(filedir_entry != NULL))
{
-#ifdef _DIRENT_HAVE_D_NAMELEN
+#ifdef _DIRENT_HAVE_D_NAMLEN
d_namelen = filedir_entry->d_namelen;
- 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
+#else
d_namelen = strlen(filedir_entry->d_name);
#endif
+
+#ifdef _DIRENT_HAVE_D_TYPE
+ d_type = filedir_entry->d_type;
+#else
+ d_type = DT_UNKNOWN;
+#endif
+ if (d_type == DT_DIR)
+ continue;
+
if ((d_namelen == 1) &&
(filedir_entry->d_name[0] == '.'))
continue;
{
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);