X-Git-Url: https://code.citadel.org/?p=citadel.git;a=blobdiff_plain;f=citadel%2Fmodules%2Fnetwork%2Fserv_netmail.c;h=b4c5f713b8f9f6da65d7694b247e27b37564fa29;hp=2782fbf8f23bf60a4b8a08fe98534b5fe362cac7;hb=5ac2920028e92a453c686c799327d7a66b3e7b49;hpb=2975015a8e6b00893a0ba003f3b086132fb858c8 diff --git a/citadel/modules/network/serv_netmail.c b/citadel/modules/network/serv_netmail.c index 2782fbf8f..b4c5f713b 100644 --- a/citadel/modules/network/serv_netmail.c +++ b/citadel/modules/network/serv_netmail.c @@ -1,16 +1,15 @@ /* - * This module handles shared rooms, inter-Citadel mail, and outbound - * mailing list processing. + * This module handles network mail and mailing list processing. * - * Copyright (c) 2000-2012 by the citadel.org team + * Copyright (c) 2000-2020 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 3. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * * ** NOTE ** A word on the S_NETCONFIGS semaphore: * This is a fairly high-level type of critical section. It ensures that no @@ -86,7 +85,6 @@ void aggregate_recipients(StrBuf **recps, RoomNetCfg Which, OneRoomNetCfg *OneRN int i; size_t recps_len = 0; RoomNetCfgLine *nptr; - struct CitContext *CCC = CC; *recps = NULL; /* @@ -103,9 +101,7 @@ void aggregate_recipients(StrBuf **recps, RoomNetCfg Which, OneRoomNetCfg *OneRN *recps = NewStrBufPlain(NULL, recps_len); if (*recps == NULL) { - QN_syslog(LOG_EMERG, - "Cannot allocate %ld bytes for recps...\n", - (long)recps_len); + syslog(LOG_ERR, "netmail: cannot allocate %ld bytes for recps", (long)recps_len); abort(); } @@ -185,12 +181,6 @@ void network_deliver_digest(SpoolControl *sc) if (sc->Users[digestrecp] == NULL) return; - if (sc->num_msgs_spooled < 1) { - fclose(sc->digestfp); - sc->digestfp = NULL; - return; - } - msg = malloc(sizeof(struct CtdlMessage)); memset(msg, 0, sizeof(struct CtdlMessage)); msg->cm_magic = CTDLMESSAGE_MAGIC; @@ -221,12 +211,10 @@ void network_deliver_digest(SpoolControl *sc) CM_SetAsField(msg, eMesageText, &pbuf, msglen); /* Now generate the delivery instructions */ - if (sc->Users[digestrecp] == 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); + * Surely not the list members! */ + snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", CtdlGetConfigStr("c_fqdn")); /* Now submit the message */ valid = validate_recipients(ChrPtr(sc->Users[digestrecp]), NULL, 0); @@ -245,15 +233,27 @@ void network_process_digest(SpoolControl *sc, struct CtdlMessage *omsg, long *de struct CtdlMessage *msg = NULL; - /* - * Process digest recipients - */ - if ((sc->Users[digestrecp] == NULL)|| - (sc->digestfp == NULL)) + if (sc->Users[digestrecp] == NULL) return; + /* If there are digest recipients, we have to build a digest */ + if (sc->digestfp == NULL) { + + sc->digestfp = create_digest_file(&sc->room, 1); + + if (sc->digestfp == NULL) + return; + + sc->haveDigest = ftell(sc->digestfp) > 0; + if (!sc->haveDigest) { + fprintf(sc->digestfp, "Content-type: text/plain\n\n"); + } + sc->haveDigest = 1; + } + msg = CM_Duplicate(omsg); if (msg != NULL) { + sc->haveDigest = 1; fprintf(sc->digestfp, " -----------------------------------" "------------------------------------" @@ -269,11 +269,6 @@ void network_process_digest(SpoolControl *sc, struct CtdlMessage *omsg, long *de "<%s> ", msg->cm_fields[erFc822Addr]); } - else if (!CM_IsEmpty(msg, eNodeName)) { - fprintf(sc->digestfp, - "@%s ", - msg->cm_fields[eNodeName]); - } fprintf(sc->digestfp, "\n"); if (!CM_IsEmpty(msg, eMsgSubject)) { fprintf(sc->digestfp, @@ -362,7 +357,7 @@ void network_deliver_list(struct CtdlMessage *msg, SpoolControl *sc, const char /* 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); + snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", CtdlGetConfigStr("c_fqdn")); /* Now submit the message */ valid = validate_recipients(ChrPtr(sc->Users[listrecp]), NULL, 0); @@ -381,7 +376,6 @@ void network_process_participate(SpoolControl *sc, struct CtdlMessage *omsg, lon { struct CtdlMessage *msg = NULL; int ok_to_participate = 0; - StrBuf *Buf = NULL; recptypes *valid; /* @@ -398,22 +392,11 @@ void network_process_participate(SpoolControl *sc, struct CtdlMessage *omsg, lon * is rude... */ ok_to_participate = 0; - if (!CM_IsEmpty(msg, eNodeName)) { - if (!strcasecmp(msg->cm_fields[eNodeName], - config.c_nodename)) { - ok_to_participate = 1; - } - - Buf = NewStrBufPlain(CM_KEY(msg, eNodeName)); - if (CtdlIsValidNode(NULL, - NULL, - Buf, - sc->working_ignetcfg, - sc->the_netmap) == 0) - { - ok_to_participate = 1; - } - } + + // FIXME -- After we removed CitaNet/IGnet support , we now need a new heuristic to determine + // whether a message originated locally. This means the "participate" mode no longer works. + // We'll definitely need to refactor this when we do other federated stuff later. + if (ok_to_participate) { /* Replace the Internet email address of the @@ -429,151 +412,6 @@ void network_process_participate(SpoolControl *sc, struct CtdlMessage *omsg, lon CtdlSubmitMsg(msg, valid, "", 0); free_recipients(valid); } - FreeStrBuf(&Buf); - CM_Free(msg); -} - -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; - char buf[SIZ]; - char filename[PATH_MAX]; - FILE *fp; - StrBuf *Buf = NULL; - int i; - int bang = 0; - int send = 1; - - if (sc->Users[ignet_push_share] == NULL) - return; - - /* - * Process IGnet push shares - */ - msg = CM_Duplicate(omsg); - - /* Prepend our node name to the Path field whenever - * sending a message to another IGnet node - */ - Netmap_AddMe(msg, HKEY("username")); - - /* - * Determine if this message is set to be deleted - * after sending out on the network - */ - if (!CM_IsEmpty(msg, eSpecialField)) { - if (!strcasecmp(msg->cm_fields[eSpecialField], "CANCEL")) { - *delete_after_send = 1; - } - } - - /* Now send it to every node */ - 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, Recipient, NULL, 1); - - /* Check for valid node name */ - if (CtdlIsValidNode(NULL, - NULL, - Buf, - sc->working_ignetcfg, - sc->the_netmap) != 0) - { - QN_syslog(LOG_ERR, - "Invalid node <%s>\n", - ChrPtr(Recipient)); - - send = 0; - } - - /* Check for split horizon */ - QN_syslog(LOG_DEBUG, "Path is %s\n", msg->cm_fields[eMessagePath]); - bang = num_tokens(msg->cm_fields[eMessagePath], '!'); - if (bang > 1) { - for (i=0; i<(bang-1); ++i) { - extract_token(buf, - msg->cm_fields[eMessagePath], - i, '!', - sizeof buf); - - QN_syslog(LOG_DEBUG, "Compare <%s> to <%s>\n", - buf, ChrPtr(Recipient)) ; - if (!strcasecmp(buf, ChrPtr(Recipient))) { - send = 0; - break; - } - } - - QN_syslog(LOG_INFO, - " %sSending to %s\n", - (send)?"":"Not ", - ChrPtr(Recipient)); - } - - /* Send the message */ - if (send == 1) - { - /* - * Force the message to appear in the correct - * room on the far end by setting the C field - * correctly - */ - if (StrLength(RemoteRoom) > 0) { - CM_SetField(msg, eRemoteRoom, SKEY(RemoteRoom)); - } - else { - CM_SetField(msg, eRemoteRoom, CCC->room.QRname, strlen(CCC->room.QRname)); - } - - /* serialize it for transmission */ - CtdlSerializeMessage(&sermsg, msg); - if (sermsg.len > 0) { - - /* write it to a spool file */ - snprintf(filename, - sizeof(filename), - "%s/%s@%lx%x", - ctdl_netout_dir, - ChrPtr(Recipient), - time(NULL), - rand() - ); - - QN_syslog(LOG_DEBUG, - "Appending to %s\n", - filename); - - fp = fopen(filename, "ab"); - if (fp != NULL) { - fwrite(sermsg.ser, - sermsg.len, 1, fp); - fclose(fp); - } - else { - QN_syslog(LOG_ERR, - "%s: %s\n", - filename, - strerror(errno)); - } - - /* free the serialized version */ - free(sermsg.ser); - } - } - } - FreeStrBuf(&Buf); - FreeStrBuf(&Recipient); - FreeStrBuf(&RemoteRoom); CM_Free(msg); } @@ -581,29 +419,23 @@ void network_process_ignetpush(SpoolControl *sc, struct CtdlMessage *omsg, long /* * Spools out one message from the list. */ -void network_spool_msg(long msgnum, - void *userdata) +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; sc = (SpoolControl *)userdata; - - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { - QN_syslog(LOG_ERR, - "failed to load Message <%ld> from disk\n", - msgnum); + syslog(LOG_ERR, "netmail: failed to load Message <%ld> from disk", 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); - network_process_ignetpush(sc, msg, &delete_after_send); CM_Free(msg);