#include "internet_addressing.h"
#include "serv_network.h"
#include "clientsocket.h"
-#include "file_ops.h"
#include "citadel_dirs.h"
#include "threads.h"
#include "context.h"
return interested;
}
+void Netmap_AddMe(struct CtdlMessage *msg, const char *defl, long defllen)
+{
+ long node_len;
+ char buf[SIZ];
+ /* prepend our node to the path */
+ if (CM_IsEmpty(msg, eMessagePath)) {
+ CM_SetField(msg, eMessagePath, defl, defllen);
+ }
+ node_len = configlen.c_nodename;
+ if (node_len >= SIZ)
+ node_len = SIZ - 1;
+ memcpy(buf, config.c_nodename, node_len);
+ buf[node_len] = '!';
+ buf[node_len + 1] = '\0';
+ CM_PrependToField(msg, eMessagePath, buf, node_len + 1);
+}
void InspectQueuedRoom(SpoolControl **pSC,
RoomProcList *room_to_spool,
return;
}
+ begin_critical_section(S_NETCONFIGS);
if (sc->RNCfg == NULL)
sc->RNCfg = CtdlGetNetCfgForRoom(sc->room.QRnumber);
if (!HaveSpoolConfig(sc->RNCfg))
{
+ end_critical_section(S_NETCONFIGS);
free(sc);
/* nothing to do for this room... */
return;
if (StrLength(sc->RNCfg->Sender) > 0)
sc->Users[roommailalias] = NewStrBufDup(sc->RNCfg->Sender);
+ end_critical_section(S_NETCONFIGS);
sc->next = *pSC;
*pSC = sc;
FreeStrBuf(&RoomName);
}
+static time_t last_digest_delivery = 0;
/*
* Batch up and send all outbound traffic from the current room
/* If there are digest recipients, we have to build a digest */
if (sc->Users[digestrecp] != NULL) {
- sc->digestfp = tmpfile();
- fprintf(sc->digestfp, "Content-type: text/plain\n\n");
+
+ sc->digestfp = create_digest_file(&sc->room);
+ sc->haveDigest = ftell(sc->digestfp) > 0;
+ if (!sc->haveDigest) {
+ fprintf(sc->digestfp, "Content-type: text/plain\n\n");
+ }
}
CalcListID(sc);
/* remember where we started... */
lastsent = sc->lastsent;
- /* Do something useful */
+ /* Fetch the messages we ought to send & prepare them. */
CtdlForEachMessage(MSGS_GT, sc->lastsent, NULL, NULL, NULL,
network_spool_msg, sc);
- /* If we wrote a digest, deliver it and then close it */
if (StrLength(sc->Users[roommailalias]) > 0)
{
long len;
buf[i] = tolower(buf[i]);
if (isspace(buf[i])) buf[i] = '_';
}
+
+
+ /* If we wrote a digest, deliver it and then close it */
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 */
+ time_t now = time(NULL);
+ time_t secs_today = now % (24 * 60 * 60);
+ long delta = 0;
+
+ if (last_digest_delivery != 0) {
+ delta = now - last_digest_delivery;
+ delta = (24 * 60 * 60) - delta;
+ }
+
+ if (sc->haveDigest &&
+ (secs_today < 300) &&
+ (delta < 300) )
+ {
+ last_digest_delivery = now;
+ 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 */
+ }
+ fclose(sc->digestfp);
+ sc->digestfp = NULL;
+ remove_digest_file(&sc->room);
}
/* Now rewrite the config file */
if (sc->lastsent != lastsent)
{
+ begin_critical_section(S_NETCONFIGS);
sc->RNCfg = CtdlGetNetCfgForRoom(sc->room.QRnumber);
sc->RNCfg->lastsent = sc->lastsent;
sc->RNCfg->changed = 1;
+ end_critical_section(S_NETCONFIGS);
}
- end_critical_section(S_NETCONFIGS);
}
/*
struct CtdlMessage *msg = NULL;
long pos;
int field;
- struct recptypes *recp = NULL;
+ recptypes *recp = NULL;
char target_room[ROOMNAMELEN];
struct ser_ret sermsg;
- char *oldpath = NULL;
char filename[PATH_MAX];
FILE *fp;
const StrBuf *nexthop = NULL;
for (pos = 3; pos < size; ++pos) {
field = buffer[pos];
len = strlen(buffer + pos + 1);
- msg->cm_fields[field] = malloc(len + 1);
- memcpy (msg->cm_fields[field], buffer+ pos + 1, len + 1);
+ CM_SetField(msg, field, buffer + pos + 1, len);
pos = pos + len + 1;
}
/* Check for message routing */
- if (msg->cm_fields[eDestination] != NULL) {
+ if (!CM_IsEmpty(msg, eDestination)) {
if (strcasecmp(msg->cm_fields[eDestination], config.c_nodename)) {
/* route the message */
- Buf = NewStrBufPlain(msg->cm_fields[eDestination], -1);
+ Buf = NewStrBufPlain(CM_KEY(msg,eDestination));
if (CtdlIsValidNode(&nexthop,
NULL,
Buf,
working_ignetcfg,
the_netmap) == 0)
{
- /* prepend our node to the path */
- if (msg->cm_fields[eMessagePath] != NULL) {
- oldpath = msg->cm_fields[eMessagePath];
- msg->cm_fields[eMessagePath] = NULL;
- }
- else {
- oldpath = strdup("unknown_user");
- }
- size = strlen(oldpath) + SIZ;
- msg->cm_fields[eMessagePath] = malloc(size);
- snprintf(msg->cm_fields[eMessagePath], size, "%s!%s",
- config.c_nodename, oldpath);
- free(oldpath);
+ Netmap_AddMe(msg, HKEY("unknown_user"));
/* serialize the message */
- serialize_message(&sermsg, msg);
+ CtdlSerializeMessage(&sermsg, msg);
/* now send it */
if (StrLength(nexthop) == 0) {
QN_syslog(LOG_ERR, "%s: %s\n", filename, strerror(errno));
}
free(sermsg.ser);
- CtdlFreeMessage(msg);
+ CM_Free(msg);
FreeStrBuf(&Buf);
return;
}
* connected that it's inevitable.)
*/
if (network_usetable(msg) != 0) {
- CtdlFreeMessage(msg);
+ CM_Free(msg);
return;
}
/* Learn network topology from the path */
- if ((msg->cm_fields[eNodeName] != NULL) && (msg->cm_fields[eMessagePath] != NULL)) {
+ if (!CM_IsEmpty(msg, eNodeName) && !CM_IsEmpty(msg, eMessagePath)) {
NetworkLearnTopology(msg->cm_fields[eNodeName],
msg->cm_fields[eMessagePath],
the_netmap,
/* Is the sending node giving us a very persuasive suggestion about
* which room this message should be saved in? If so, go with that.
*/
- if (msg->cm_fields[eRemoteRoom] != NULL) {
+ if (!CM_IsEmpty(msg, eRemoteRoom)) {
safestrncpy(target_room, msg->cm_fields[eRemoteRoom], sizeof target_room);
}
/* Otherwise, does it have a recipient? If so, validate it... */
- else if (msg->cm_fields[eRecipient] != NULL) {
+ else if (!CM_IsEmpty(msg, eRecipient)) {
recp = validate_recipients(msg->cm_fields[eRecipient], NULL, 0);
if (recp != NULL) if (recp->num_error != 0) {
network_bounce(msg,
/* Our last shot at finding a home for this message is to see if
* it has the eOriginalRoom (O) field (Originating room) set.
*/
- else if (msg->cm_fields[eOriginalRoom] != NULL) {
+ else if (!CM_IsEmpty(msg, eOriginalRoom)) {
safestrncpy(target_room, msg->cm_fields[eOriginalRoom], sizeof target_room);
}
/* Strip out fields that are only relevant during transit */
- if (msg->cm_fields[eDestination] != NULL) {
- free(msg->cm_fields[eDestination]);
- msg->cm_fields[eDestination] = NULL;
- }
- if (msg->cm_fields[eRemoteRoom] != NULL) {
- free(msg->cm_fields[eRemoteRoom]);
- msg->cm_fields[eRemoteRoom] = NULL;
- }
+ CM_FlushField(msg, eDestination);
+ CM_FlushField(msg, eRemoteRoom);
/* save the message into a room */
if (PerformNetprocHooks(msg, target_room) == 0) {
msg->cm_flags = CM_SKIP_HOOKS;
CtdlSubmitMsg(msg, recp, target_room, 0);
}
- CtdlFreeMessage(msg);
+ CM_Free(msg);
free_recipients(recp);
}
long msgend = (-1L);
long msgcur = 0L;
int ch;
-
+ int nMessages = 0;
fp = fopen(filename, "rb");
if (fp == NULL) {
}
++msgcur;
+ nMessages ++;
}
msgend = msgcur - 1;
working_ignetcfg,
the_netmap,
netmap_changed);
+ nMessages ++;
}
+ if (nMessages > 0)
+ QN_syslog(LOG_INFO,
+ "network: processed %d messages in %s\n",
+ nMessages,
+ filename);
+
fclose(fp);
unlink(filename);
}
(filedir_entry != NULL))
{
#ifdef _DIRENT_HAVE_D_NAMLEN
- d_namelen = filedir_entry->d_namelen;
+ d_namelen = filedir_entry->d_namlen;
#else
d_namelen = strlen(filedir_entry->d_name);
(filedir_entry != NULL))
{
#ifdef _DIRENT_HAVE_D_NAMLEN
- d_namelen = filedir_entry->d_namelen;
+ d_namelen = filedir_entry->d_namlen;
#else
d_namelen = strlen(filedir_entry->d_name);
(filedir_entry != NULL))
{
#ifdef _DIRENT_HAVE_D_NAMLEN
- d_namelen = filedir_entry->d_namelen;
+ d_namelen = filedir_entry->d_namlen;
#else
d_namelen = strlen(filedir_entry->d_name);