X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fnetwork%2Fserv_netmail.c;h=941a2590e26fdef302c19f9354feeb91636c80d4;hb=dc56ca4c678006a3930caa42688b2f02a9535270;hp=a04bcfb12719aed29726c6a83410af3724d4c2b6;hpb=a5e759daa03e43dfdd940e96c13cded7ba8de39c;p=citadel.git diff --git a/citadel/modules/network/serv_netmail.c b/citadel/modules/network/serv_netmail.c index a04bcfb12..941a2590e 100644 --- a/citadel/modules/network/serv_netmail.c +++ b/citadel/modules/network/serv_netmail.c @@ -2,15 +2,15 @@ * This module handles shared rooms, inter-Citadel mail, and outbound * mailing list processing. * - * Copyright (c) 2000-2012 by the citadel.org team + * Copyright (c) 2000-2016 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 @@ -72,7 +72,6 @@ #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" @@ -87,7 +86,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; /* @@ -104,9 +102,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(); } @@ -117,6 +113,12 @@ void aggregate_recipients(StrBuf **recps, RoomNetCfg Which, OneRoomNetCfg *OneRN 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); + + } } } @@ -127,12 +129,11 @@ static void ListCalculateSubject(struct CtdlMessage *msg) int rlen; char *pCh; - if (msg->cm_fields['U'] == NULL) { + if (CM_IsEmpty(msg, eMsgSubject)) { Subject = NewStrBufPlain(HKEY("(no subject)")); } else { - Subject = NewStrBufPlain( - msg->cm_fields['U'], -1); + Subject = NewStrBufPlain(CM_KEY(msg, eMsgSubject)); } FlatSubject = NewStrBufPlain(NULL, StrLength(Subject)); StrBuf_RFC822_to_Utf8(FlatSubject, Subject, NULL, NULL); @@ -159,9 +160,7 @@ static void ListCalculateSubject(struct CtdlMessage *msg) StrBufRFC2047encode(&Subject, FlatSubject); } - if (msg->cm_fields['U'] != NULL) - free (msg->cm_fields['U']); - msg->cm_fields['U'] = SmashStrBuf(&Subject); + CM_SetAsFieldSB(msg, eMsgSubject, &Subject); FreeStrBuf(&FlatSubject); } @@ -171,20 +170,17 @@ static void ListCalculateSubject(struct CtdlMessage *msg) */ void network_deliver_digest(SpoolControl *sc) { + struct CitContext *CCC = CC; + long len; char buf[SIZ]; + char *pbuf; struct CtdlMessage *msg = NULL; long msglen; - struct recptypes *valid; + recptypes *valid; char bounce_to[256]; - if (sc->Users[listrecp] == NULL) - return; - - if (sc->num_msgs_spooled < 1) { - fclose(sc->digestfp); - sc->digestfp = NULL; + if (sc->Users[digestrecp] == NULL) return; - } msg = malloc(sizeof(struct CtdlMessage)); memset(msg, 0, sizeof(struct CtdlMessage)); @@ -192,17 +188,16 @@ void network_deliver_digest(SpoolControl *sc) msg->cm_format_type = FMT_RFC822; msg->cm_anon_type = MES_NORMAL; - sprintf(buf, "%ld", time(NULL)); - msg->cm_fields['T'] = strdup(buf); - msg->cm_fields['A'] = strdup(CC->room.QRname); - snprintf(buf, sizeof buf, "[%s]", CC->room.QRname); - msg->cm_fields['U'] = strdup(buf); + CM_SetFieldLONG(msg, eTimestamp, time(NULL)); + CM_SetField(msg, eAuthor, CCC->room.QRname, strlen(CCC->room.QRname)); + len = snprintf(buf, sizeof buf, "[%s]", CCC->room.QRname); + CM_SetField(msg, eMsgSubject, buf, len); - CtdlMsgSetCM_Fields(msg, 'F', SKEY(sc->Users[roommailalias])); - CtdlMsgSetCM_Fields(msg, 'R', SKEY(sc->Users[roommailalias])); + CM_SetField(msg, erFc822Addr, SKEY(sc->Users[roommailalias])); + CM_SetField(msg, eRecipient, SKEY(sc->Users[roommailalias])); /* Set the 'List-ID' header */ - CtdlMsgSetCM_Fields(msg, 'L', SKEY(sc->ListID)); + CM_SetField(msg, eListID, SKEY(sc->ListID)); /* * Go fetch the contents of the digest @@ -210,30 +205,26 @@ void network_deliver_digest(SpoolControl *sc) fseek(sc->digestfp, 0L, SEEK_END); msglen = ftell(sc->digestfp); - msg->cm_fields['M'] = malloc(msglen + 1); + pbuf = malloc(msglen + 1); fseek(sc->digestfp, 0L, SEEK_SET); - fread(msg->cm_fields['M'], (size_t)msglen, 1, sc->digestfp); - msg->cm_fields['M'][msglen] = '\0'; - - fclose(sc->digestfp); - sc->digestfp = NULL; + fread(pbuf, (size_t)msglen, 1, sc->digestfp); + pbuf[msglen] = '\0'; + CM_SetAsField(msg, eMesageText, &pbuf, msglen); /* Now generate the delivery instructions */ - 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); + * 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[listrecp]), NULL, 0); + valid = validate_recipients(ChrPtr(sc->Users[digestrecp]), NULL, 0); if (valid != NULL) { valid->bounce_to = strdup(bounce_to); valid->envelope_from = strdup(bounce_to); CtdlSubmitMsg(msg, valid, NULL, 0); } - CtdlFreeMessage(msg); + CM_Free(msg); free_recipients(valid); } @@ -243,40 +234,52 @@ 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; - msg = CtdlDuplicateMessage(omsg); + /* 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, " -----------------------------------" "------------------------------------" "-------\n"); fprintf(sc->digestfp, "From: "); - if (msg->cm_fields['A'] != NULL) { + if (!CM_IsEmpty(msg, eAuthor)) { fprintf(sc->digestfp, "%s ", - msg->cm_fields['A']); + msg->cm_fields[eAuthor]); } - if (msg->cm_fields['F'] != NULL) { + if (!CM_IsEmpty(msg, erFc822Addr)) { fprintf(sc->digestfp, "<%s> ", - msg->cm_fields['F']); + msg->cm_fields[erFc822Addr]); } - else if (msg->cm_fields['N'] != NULL) { + else if (!CM_IsEmpty(msg, eNodeName)) { fprintf(sc->digestfp, "@%s ", - msg->cm_fields['N']); + msg->cm_fields[eNodeName]); } fprintf(sc->digestfp, "\n"); - if (msg->cm_fields['U'] != NULL) { + if (!CM_IsEmpty(msg, eMsgSubject)) { fprintf(sc->digestfp, "Subject: %s\n", - msg->cm_fields['U']); + msg->cm_fields[eMsgSubject]); } CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); @@ -298,7 +301,7 @@ void network_process_digest(SpoolControl *sc, struct CtdlMessage *omsg, long *de FreeStrBuf(&CC->redirect_buffer); sc->num_msgs_spooled += 1; - CtdlFreeMessage(msg); + CM_Free(msg); } } @@ -318,23 +321,22 @@ void network_process_list(SpoolControl *sc, struct CtdlMessage *omsg, long *dele * in order to insert the [list name] in it, etc. */ - msg = CtdlDuplicateMessage(omsg); + msg = CM_Duplicate(omsg); - CtdlMsgSetCM_Fields(msg, 'K', SKEY(sc->Users[roommailalias])); + CM_SetField(msg, eReplyTo, SKEY(sc->Users[roommailalias])); /* if there is no other recipient, Set the recipient * of the list message to the email address of the * room itself. */ - if ((msg->cm_fields['R'] == NULL) || - IsEmptyStr(msg->cm_fields['R'])) + if (CM_IsEmpty(msg, eRecipient)) { - CtdlMsgSetCM_Fields(msg, 'R', SKEY(sc->Users[roommailalias])); + CM_SetField(msg, eRecipient, SKEY(sc->Users[roommailalias])); } /* Set the 'List-ID' header */ - CtdlMsgSetCM_Fields(msg, 'L', SKEY(sc->ListID)); + CM_SetField(msg, eListID, SKEY(sc->ListID)); /* Prepend "[List name]" to the subject */ @@ -342,7 +344,7 @@ void network_process_list(SpoolControl *sc, struct CtdlMessage *omsg, long *dele /* Handle delivery */ network_deliver_list(msg, sc, CC->room.QRname); - CtdlFreeMessage(msg); + CM_Free(msg); } /* @@ -350,7 +352,7 @@ void network_process_list(SpoolControl *sc, struct CtdlMessage *omsg, long *dele */ void network_deliver_list(struct CtdlMessage *msg, SpoolControl *sc, const char *RoomName) { - struct recptypes *valid; + recptypes *valid; char bounce_to[256]; /* Don't do this if there were no recipients! */ @@ -361,7 +363,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); @@ -372,7 +374,7 @@ void network_deliver_list(struct CtdlMessage *msg, SpoolControl *sc, const char CtdlSubmitMsg(msg, valid, NULL, 0); free_recipients(valid); } - /* Do not call CtdlFreeMessage(msg) here; the caller will free it. */ + /* Do not call CM_Free(msg) here; the caller will free it. */ } @@ -381,7 +383,7 @@ void network_process_participate(SpoolControl *sc, struct CtdlMessage *omsg, lon struct CtdlMessage *msg = NULL; int ok_to_participate = 0; StrBuf *Buf = NULL; - struct recptypes *valid; + recptypes *valid; /* * Process client-side list participations for this room @@ -389,7 +391,7 @@ void network_process_participate(SpoolControl *sc, struct CtdlMessage *omsg, lon if (sc->Users[participate] == NULL) return; - msg = CtdlDuplicateMessage(omsg); + msg = CM_Duplicate(omsg); /* Only send messages which originated on our own * Citadel network, otherwise we'll end up sending the @@ -397,13 +399,13 @@ void network_process_participate(SpoolControl *sc, struct CtdlMessage *omsg, lon * is rude... */ ok_to_participate = 0; - if (msg->cm_fields['N'] != NULL) { - if (!strcasecmp(msg->cm_fields['N'], - config.c_nodename)) { + if (!CM_IsEmpty(msg, eNodeName)) { + if (!strcasecmp(msg->cm_fields[eNodeName], CtdlGetConfigStr("c_nodename"))) + { ok_to_participate = 1; } - Buf = NewStrBufPlain(msg->cm_fields['N'], -1); + Buf = NewStrBufPlain(CM_KEY(msg, eNodeName)); if (CtdlIsValidNode(NULL, NULL, Buf, @@ -420,16 +422,16 @@ void network_process_participate(SpoolControl *sc, struct CtdlMessage *omsg, lon * room itself, so the remote listserv doesn't * reject us. */ - CtdlMsgSetCM_Fields(msg, 'F', SKEY(sc->Users[roommailalias])); + CM_SetField(msg, erFc822Addr, SKEY(sc->Users[roommailalias])); valid = validate_recipients(ChrPtr(sc->Users[participate]) , NULL, 0); - CtdlMsgSetCM_Fields(msg, 'R', SKEY(sc->Users[roommailalias])); + CM_SetField(msg, eRecipient, SKEY(sc->Users[roommailalias])); CtdlSubmitMsg(msg, valid, "", 0); free_recipients(valid); } FreeStrBuf(&Buf); - CtdlFreeMessage(msg); + CM_Free(msg); } void network_process_ignetpush(SpoolControl *sc, struct CtdlMessage *omsg, long *delete_after_send) @@ -443,8 +445,6 @@ void network_process_ignetpush(SpoolControl *sc, struct CtdlMessage *omsg, long char buf[SIZ]; char filename[PATH_MAX]; FILE *fp; - size_t newpath_len; - char *newpath = NULL; StrBuf *Buf = NULL; int i; int bang = 0; @@ -456,29 +456,19 @@ void network_process_ignetpush(SpoolControl *sc, struct CtdlMessage *omsg, long /* * Process IGnet push shares */ - msg = CtdlDuplicateMessage(omsg); + msg = CM_Duplicate(omsg); /* Prepend our node name to the Path field whenever * sending a message to another IGnet node */ - if (msg->cm_fields['P'] == NULL) - { - msg->cm_fields['P'] = strdup("username"); - } - newpath_len = strlen(msg->cm_fields['P']) + - strlen(config.c_nodename) + 2; - newpath = malloc(newpath_len); - snprintf(newpath, newpath_len, "%s!%s", - config.c_nodename, msg->cm_fields['P']); - free(msg->cm_fields['P']); - msg->cm_fields['P'] = newpath; - + Netmap_AddMe(msg, HKEY("username")); + /* * Determine if this message is set to be deleted * after sending out on the network */ - if (msg->cm_fields['S'] != NULL) { - if (!strcasecmp(msg->cm_fields['S'], "CANCEL")) { + if (!CM_IsEmpty(msg, eSpecialField)) { + if (!strcasecmp(msg->cm_fields[eSpecialField], "CANCEL")) { *delete_after_send = 1; } } @@ -500,35 +490,28 @@ void network_process_ignetpush(SpoolControl *sc, struct CtdlMessage *omsg, long sc->working_ignetcfg, sc->the_netmap) != 0) { - QN_syslog(LOG_ERR, - "Invalid node <%s>\n", - ChrPtr(Recipient)); - + syslog(LOG_ERR, "netmail: invalid node <%s>", ChrPtr(Recipient)); send = 0; } /* Check for split horizon */ - QN_syslog(LOG_DEBUG, "Path is %s\n", msg->cm_fields['P']); - bang = num_tokens(msg->cm_fields['P'], '!'); + syslog(LOG_DEBUG, "netmail: path is %s", 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['P'], + msg->cm_fields[eMessagePath], i, '!', sizeof buf); - QN_syslog(LOG_DEBUG, "Compare <%s> to <%s>\n", - buf, ChrPtr(Recipient)) ; + syslog(LOG_DEBUG, "netmail: compare <%s> to <%s>", buf, ChrPtr(Recipient)) ; if (!strcasecmp(buf, ChrPtr(Recipient))) { send = 0; break; } } - QN_syslog(LOG_INFO, - "%sSending to %s\n", - (send)?"":"Not ", - ChrPtr(Recipient)); + syslog(LOG_INFO, "netmail: %ssending to %s", (send)?"":"not ", ChrPtr(Recipient)); } /* Send the message */ @@ -539,47 +522,36 @@ void network_process_ignetpush(SpoolControl *sc, struct CtdlMessage *omsg, long * room on the far end by setting the C field * correctly */ - if (msg->cm_fields['C'] != NULL) { - free(msg->cm_fields['C']); - } if (StrLength(RemoteRoom) > 0) { - msg->cm_fields['C'] = - strdup(ChrPtr(RemoteRoom)); + CM_SetField(msg, eRemoteRoom, SKEY(RemoteRoom)); } else { - msg->cm_fields['C'] = - strdup(CC->room.QRname); + CM_SetField(msg, eRemoteRoom, CCC->room.QRname, strlen(CCC->room.QRname)); } /* serialize it for transmission */ - serialize_message(&sermsg, msg); + 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() - ); + sizeof(filename), + "%s/%s@%lx%x-mail", + ctdl_netout_dir, + ChrPtr(Recipient), + time(NULL), + rand() + ); - QN_syslog(LOG_DEBUG, - "Appending to %s\n", - filename); + syslog(LOG_DEBUG, "netmail: appending to %s", filename); fp = fopen(filename, "ab"); if (fp != NULL) { - fwrite(sermsg.ser, - sermsg.len, 1, fp); + fwrite(sermsg.ser, sermsg.len, 1, fp); fclose(fp); } else { - QN_syslog(LOG_ERR, - "%s: %s\n", - filename, - strerror(errno)); + syslog(LOG_ERR, "%s: %s\n", filename, strerror(errno)); } /* free the serialized version */ @@ -590,30 +562,33 @@ void network_process_ignetpush(SpoolControl *sc, struct CtdlMessage *omsg, long FreeStrBuf(&Buf); FreeStrBuf(&Recipient); FreeStrBuf(&RemoteRoom); - CtdlFreeMessage(msg); + CM_Free(msg); } /* * Spools out one message from the list. */ -void network_spool_msg(long msgnum, - void *userdata) +void network_spool_msg(long msgnum, void *userdata) { 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, 1); - msg = CtdlFetchMessage(msgnum, 1); - + if (msg == NULL) + { + 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); - CtdlFreeMessage(msg); + CM_Free(msg); /* update lastsent */ sc->lastsent = msgnum;