void network_deliver_list(struct CtdlMessage *msg, SpoolControl *sc, const char *RoomName);
-void aggregate_recipients(StrBuf **recps, RoomNetCfg Which, OneRoomNetCfg *OneRNCfg)
+void aggregate_recipients(StrBuf **recps, RoomNetCfg Which, OneRoomNetCfg *OneRNCfg, long nSegments)
{
+ int i;
size_t recps_len = 0;
RoomNetCfgLine *nptr;
struct CitContext *CCC = CC;
/* Each recipient */
for (nptr = OneRNCfg->NetConfigs[Which]; nptr != NULL; nptr = nptr->next) {
if (nptr != OneRNCfg->NetConfigs[Which]) {
- StrBufAppendBufPlain(*recps, HKEY(","), 0);
+ for (i = 0; i < nSegments; i++)
+ StrBufAppendBufPlain(*recps, HKEY(","), i);
}
StrBufAppendBuf(*recps, nptr->Value[0], 0);
+ if (Which == ignet_push_share)
+ {
+ StrBufAppendBufPlain(*recps, HKEY(","), 0);
+ StrBufAppendBuf(*recps, nptr->Value[1], 0);
+
+ }
+ }
+}
+
+static void ListCalculateSubject(struct CtdlMessage *msg)
+{
+ struct CitContext *CCC = CC;
+ StrBuf *Subject, *FlatSubject;
+ int rlen;
+ char *pCh;
+
+ if (msg->cm_fields['U'] == NULL) {
+ Subject = NewStrBufPlain(HKEY("(no subject)"));
+ }
+ else {
+ Subject = NewStrBufPlain(
+ msg->cm_fields['U'], -1);
+ }
+ FlatSubject = NewStrBufPlain(NULL, StrLength(Subject));
+ StrBuf_RFC822_to_Utf8(FlatSubject, Subject, NULL, NULL);
+
+ rlen = strlen(CCC->room.QRname);
+ pCh = strstr(ChrPtr(FlatSubject), CCC->room.QRname);
+ if ((pCh == NULL) ||
+ (*(pCh + rlen) != ']') ||
+ (pCh == ChrPtr(FlatSubject)) ||
+ (*(pCh - 1) != '[')
+ )
+ {
+ StrBuf *tmp;
+ StrBufPlain(Subject, HKEY("["));
+ StrBufAppendBufPlain(Subject,
+ CCC->room.QRname,
+ rlen, 0);
+ StrBufAppendBufPlain(Subject, HKEY("] "), 0);
+ StrBufAppendBuf(Subject, FlatSubject, 0);
+ /* so we can free the right one swap them */
+ tmp = Subject;
+ Subject = FlatSubject;
+ FlatSubject = tmp;
+ StrBufRFC2047encode(&Subject, FlatSubject);
}
+
+ if (msg->cm_fields['U'] != NULL)
+ free (msg->cm_fields['U']);
+ msg->cm_fields['U'] = SmashStrBuf(&Subject);
+
+ FreeStrBuf(&FlatSubject);
}
/*
void network_deliver_digest(SpoolControl *sc)
{
char buf[SIZ];
- int i;
struct CtdlMessage *msg = NULL;
long msglen;
- StrBuf *recps = NULL;
- char *precps;
struct recptypes *valid;
char bounce_to[256];
+ if (sc->Users[listrecp] == NULL)
+ return;
+
if (sc->num_msgs_spooled < 1) {
fclose(sc->digestfp);
sc->digestfp = NULL;
msg->cm_fields['A'] = strdup(CC->room.QRname);
snprintf(buf, sizeof buf, "[%s]", CC->room.QRname);
msg->cm_fields['U'] = strdup(buf);
- sprintf(buf, "room_%s@%s", CC->room.QRname, config.c_fqdn);
- for (i=0; buf[i]; ++i) {
- if (isspace(buf[i])) buf[i]='_';
- buf[i] = tolower(buf[i]);
- }
- msg->cm_fields['F'] = strdup(buf);
- msg->cm_fields['R'] = strdup(buf);
+
+ CtdlMsgSetCM_Fields(msg, 'F', SKEY(sc->Users[roommailalias]));
+ CtdlMsgSetCM_Fields(msg, 'R', SKEY(sc->Users[roommailalias]));
/* Set the 'List-ID' header */
- msg->cm_fields['L'] = malloc(1024);
- snprintf(msg->cm_fields['L'], 1024,
- "%s <%ld.list-id.%s>",
- CC->room.QRname,
- CC->room.QRnumber,
- config.c_fqdn
- );
+ CtdlMsgSetCM_Fields(msg, 'L', SKEY(sc->ListID));
/*
* Go fetch the contents of the digest
sc->digestfp = NULL;
/* Now generate the delivery instructions */
- aggregate_recipients(&recps, digestrecp, sc->RNCfg);
+ if (sc->Users[listrecp] == NULL)
+ return;
/* Where do we want bounces and other noise to be heard?
*Surely not the list members! */
snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", config.c_fqdn);
/* Now submit the message */
- precps = SmashStrBuf(&recps);
- valid = validate_recipients(precps, NULL, 0);
- free(precps);
+ valid = validate_recipients(ChrPtr(sc->Users[listrecp]), NULL, 0);
if (valid != NULL) {
valid->bounce_to = strdup(bounce_to);
valid->envelope_from = strdup(bounce_to);
/*
* Process digest recipients
*/
- if ((sc->RNCfg->NetConfigs[digestrecp] == NULL) ||
+ if ((sc->Users[digestrecp] == NULL)||
(sc->digestfp == NULL))
return;
void network_process_list(SpoolControl *sc, struct CtdlMessage *omsg, long *delete_after_send)
{
- int rlen;
- char *pCh;
- StrBuf *Subject, *FlatSubject;
struct CtdlMessage *msg = NULL;
- int i;
/*
* Process mailing list recipients
*/
- if (sc->RNCfg->NetConfigs[listrecp] == NULL)
+ if (sc->Users[listrecp] == NULL)
return;
/* create our own copy of the message.
msg = CtdlDuplicateMessage(omsg);
- if (msg->cm_fields['K'] != NULL)
- free(msg->cm_fields['K']);
- if (msg->cm_fields['V'] == NULL){
- /* local message, no enVelope */
- StrBuf *Buf;
- Buf = NewStrBuf();
- StrBufAppendBufPlain(Buf,
- msg->cm_fields['O']
- , -1, 0);
- StrBufAppendBufPlain(Buf, HKEY("@"), 0);
- StrBufAppendBufPlain(Buf, config.c_fqdn, -1, 0);
-
- msg->cm_fields['K'] = SmashStrBuf(&Buf);
- }
- else {
- msg->cm_fields['K'] =
- strdup (msg->cm_fields['V']);
- }
- /* Set the 'List-ID' header */
- if (msg->cm_fields['L'] != NULL) {
- free(msg->cm_fields['L']);
- }
- msg->cm_fields['L'] = malloc(1024);
- snprintf(msg->cm_fields['L'], 1024,
- "%s <%ld.list-id.%s>",
- CC->room.QRname,
- CC->room.QRnumber,
- config.c_fqdn
- );
-
- /* Prepend "[List name]" to the subject */
- if (msg->cm_fields['U'] == NULL) {
- Subject = NewStrBufPlain(HKEY("(no subject)"));
- }
- else {
- Subject = NewStrBufPlain(
- msg->cm_fields['U'], -1);
- }
- FlatSubject = NewStrBufPlain(NULL, StrLength(Subject));
- StrBuf_RFC822_to_Utf8(FlatSubject, Subject, NULL, NULL);
-
- rlen = strlen(CC->room.QRname);
- pCh = strstr(ChrPtr(FlatSubject), CC->room.QRname);
- if ((pCh == NULL) ||
- (*(pCh + rlen) != ']') ||
- (pCh == ChrPtr(FlatSubject)) ||
- (*(pCh - 1) != '[')
- )
- {
- StrBuf *tmp;
- StrBufPlain(Subject, HKEY("["));
- StrBufAppendBufPlain(Subject,
- CC->room.QRname,
- rlen, 0);
- StrBufAppendBufPlain(Subject, HKEY("] "), 0);
- StrBufAppendBuf(Subject, FlatSubject, 0);
- /* so we can free the right one swap them */
- tmp = Subject;
- Subject = FlatSubject;
- FlatSubject = tmp;
- StrBufRFC2047encode(&Subject, FlatSubject);
- }
-
- if (msg->cm_fields['U'] != NULL)
- free (msg->cm_fields['U']);
- msg->cm_fields['U'] = SmashStrBuf(&Subject);
-
- FreeStrBuf(&FlatSubject);
- /* else we won't modify the buffer, since the
- * roomname is already here.
- */
+ CtdlMsgSetCM_Fields(msg, 'K', SKEY(sc->Users[roommailalias]));
/* if there is no other recipient, Set the recipient
* of the list message to the email address of the
if ((msg->cm_fields['R'] == NULL) ||
IsEmptyStr(msg->cm_fields['R']))
{
- if (msg->cm_fields['R'] != NULL)
- free(msg->cm_fields['R']);
-
- msg->cm_fields['R'] = malloc(256);
- snprintf(msg->cm_fields['R'], 256,
- "room_%s@%s", CC->room.QRname,
- config.c_fqdn);
- for (i=0; msg->cm_fields['R'][i]; ++i) {
- if (isspace(msg->cm_fields['R'][i])) {
- msg->cm_fields['R'][i] = '_';
- }
- }
+ CtdlMsgSetCM_Fields(msg, 'R', SKEY(sc->Users[roommailalias]));
}
+ /* Set the 'List-ID' header */
+ CtdlMsgSetCM_Fields(msg, 'L', SKEY(sc->ListID));
+
+
+ /* Prepend "[List name]" to the subject */
+ ListCalculateSubject(msg);
+
/* Handle delivery */
network_deliver_list(msg, sc, CC->room.QRname);
CtdlFreeMessage(msg);
*/
void network_deliver_list(struct CtdlMessage *msg, SpoolControl *sc, const char *RoomName)
{
- StrBuf *recps = NULL;
- char *precps = NULL;
struct recptypes *valid;
char bounce_to[256];
/* Don't do this if there were no recipients! */
- if (sc->RNCfg->NetConfigs[listrecp] == NULL) return;
+ if (sc->Users[listrecp] == NULL)
+ return;
/* Now generate the delivery instructions */
- /*
- * Figure out how big a buffer we need to allocate
- */
- aggregate_recipients(&recps, listrecp, sc->RNCfg);
-
/* Where do we want bounces and other noise to be heard?
* Surely not the list members! */
snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", config.c_fqdn);
/* Now submit the message */
- precps = SmashStrBuf(&recps);
- valid = validate_recipients(precps, NULL, 0);
- free(precps);
+ valid = validate_recipients(ChrPtr(sc->Users[listrecp]), NULL, 0);
if (valid != NULL) {
valid->bounce_to = strdup(bounce_to);
valid->envelope_from = strdup(bounce_to);
void network_process_participate(SpoolControl *sc, struct CtdlMessage *omsg, long *delete_after_send)
{
struct CtdlMessage *msg = NULL;
- int i;
int ok_to_participate = 0;
StrBuf *Buf = NULL;
struct recptypes *valid;
/*
* Process client-side list participations for this room
*/
- if (sc->RNCfg->NetConfigs[participate] == NULL)
+ if (sc->Users[participate] == NULL)
return;
msg = CtdlDuplicateMessage(omsg);
}
if (ok_to_participate)
{
- StrBuf *recps = NULL;
- char *precps;
-
- if (msg->cm_fields['F'] != NULL) {
- free(msg->cm_fields['F']);
- }
- msg->cm_fields['F'] = malloc(SIZ);
/* Replace the Internet email address of the
* actual author with the email address of the
* room itself, so the remote listserv doesn't
* reject us.
- * FIXME I want to be able to pick any address
*/
- snprintf(msg->cm_fields['F'], SIZ,
- "room_%s@%s", CC->room.QRname,
- config.c_fqdn);
- for (i=0; msg->cm_fields['F'][i]; ++i) {
- if (isspace(msg->cm_fields['F'][i])) {
- msg->cm_fields['F'][i] = '_';
- }
- }
-
- aggregate_recipients(&recps, participate, sc->RNCfg);
- precps = SmashStrBuf(&recps);
- valid = validate_recipients(precps, NULL, 0);
+ CtdlMsgSetCM_Fields(msg, 'F', SKEY(sc->Users[roommailalias]));
- if (msg->cm_fields['R'] != NULL) {
- free(msg->cm_fields['R']);
- }/* TODO: check whether 'R' is set appropriate later. */
+ valid = validate_recipients(ChrPtr(sc->Users[participate]) , NULL, 0);
+ CtdlMsgSetCM_Fields(msg, 'R', SKEY(sc->Users[roommailalias]));
CtdlSubmitMsg(msg, valid, "", 0);
free_recipients(valid);
}
void network_process_ignetpush(SpoolControl *sc, struct CtdlMessage *omsg, long *delete_after_send)
{
+ StrBuf *Recipient;
+ StrBuf *RemoteRoom;
+ const char *Pos = NULL;
struct CtdlMessage *msg = NULL;
struct CitContext *CCC = CC;
struct ser_ret sermsg;
FILE *fp;
size_t newpath_len;
char *newpath = NULL;
- RoomNetCfgLine* mptr;
StrBuf *Buf = NULL;
int i;
int bang = 0;
int send = 1;
- if (sc->RNCfg->NetConfigs[ignet_push_share] == NULL)
+ if (sc->Users[ignet_push_share] == NULL)
return;
+
/*
* Process IGnet push shares
*/
}
/* Now send it to every node */
- for (mptr = sc->RNCfg->NetConfigs[ignet_push_share];
- mptr != NULL;
- mptr = mptr->next)
+ Recipient = NewStrBufPlain(NULL, StrLength(sc->Users[ignet_push_share]));
+ RemoteRoom = NewStrBufPlain(NULL, StrLength(sc->Users[ignet_push_share]));
+ while ((Pos != StrBufNOTNULL) &&
+ StrBufExtract_NextToken(Recipient, sc->Users[ignet_push_share], &Pos, ','))
{
+ StrBufExtract_NextToken(RemoteRoom, sc->Users[ignet_push_share], &Pos, ',');
send = 1;
- NewStrBufDupAppendFlush(&Buf, mptr->Value[0], NULL, 1);
+ NewStrBufDupAppendFlush(&Buf, Recipient, NULL, 1);
/* Check for valid node name */
if (CtdlIsValidNode(NULL,
{
QN_syslog(LOG_ERR,
"Invalid node <%s>\n",
- ChrPtr(mptr->Value[0]));
+ ChrPtr(Recipient));
send = 0;
}
sizeof buf);
QN_syslog(LOG_DEBUG, "Compare <%s> to <%s>\n",
- buf, ChrPtr(mptr->Value[0])) ;
- if (!strcasecmp(buf, ChrPtr(mptr->Value[0]))) {
+ buf, ChrPtr(Recipient)) ;
+ if (!strcasecmp(buf, ChrPtr(Recipient))) {
send = 0;
break;
}
}
QN_syslog(LOG_INFO,
- "%sSending to %s\n",
+ " %sSending to %s\n",
(send)?"":"Not ",
- ChrPtr(mptr->Value[0]));
+ ChrPtr(Recipient));
}
/* Send the message */
if (msg->cm_fields['C'] != NULL) {
free(msg->cm_fields['C']);
}
- if (StrLength(mptr->Value[0]) > 0) {
+ if (StrLength(RemoteRoom) > 0) {
msg->cm_fields['C'] =
- strdup(ChrPtr(mptr->Value[0]));
+ strdup(ChrPtr(RemoteRoom));
}
else {
msg->cm_fields['C'] =
sizeof(filename),
"%s/%s@%lx%x",
ctdl_netout_dir,
- ChrPtr(mptr->Value[0]),
+ ChrPtr(Recipient),
time(NULL),
rand()
);
}
}
FreeStrBuf(&Buf);
+ FreeStrBuf(&Recipient);
+ FreeStrBuf(&RemoteRoom);
CtdlFreeMessage(msg);
}
void network_spool_msg(long msgnum,
void *userdata)
{
+ struct CitContext *CCC = CC;
struct CtdlMessage *msg = NULL;
long delete_after_send = 0; /* Set to 1 to delete after spooling */
SpoolControl *sc;
msg = CtdlFetchMessage(msgnum, 1);
+ if (msg == NULL)
+ {
+ QN_syslog(LOG_ERR,
+ "failed to load Message <%ld> from disk\n",
+ msgnum);
+ return;
+ }
network_process_list(sc, msg, &delete_after_send);
network_process_digest(sc, msg, &delete_after_send);
network_process_participate(sc, msg, &delete_after_send);