From: Wilfried Goesgens Date: Sun, 20 Jan 2013 16:11:22 +0000 (+0100) Subject: NETSPOOL: move spool types into their own function. X-Git-Tag: v8.20~147 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=1e991a40e1f138a787bda455b4011359f33ea9d5 NETSPOOL: move spool types into their own function. --- diff --git a/citadel/modules/network/serv_netmail.c b/citadel/modules/network/serv_netmail.c index ea324a590..b98e30bb1 100644 --- a/citadel/modules/network/serv_netmail.c +++ b/citadel/modules/network/serv_netmail.c @@ -84,7 +84,8 @@ /* * Deliver digest messages */ -void network_deliver_digest(SpoolControl *sc) { +void network_deliver_digest(SpoolControl *sc) +{ struct CitContext *CCC = CC; char buf[SIZ]; int i; @@ -125,11 +126,11 @@ void network_deliver_digest(SpoolControl *sc) { /* 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 - ); + "%s <%ld.list-id.%s>", + CC->room.QRname, + CC->room.QRnumber, + config.c_fqdn + ); /* * Go fetch the contents of the digest @@ -189,6 +190,191 @@ void network_deliver_digest(SpoolControl *sc) { } +void network_process_digest(SpoolControl *sc, struct CtdlMessage *omsg, long *delete_after_send) +{ + + struct CtdlMessage *msg = NULL; + + /* + * Process digest recipients + */ + if ((sc->RNCfg->NetConfigs[digestrecp] == NULL) || + (sc->digestfp == NULL)) + return; + + msg = CtdlDuplicateMessage(omsg); + if (msg != NULL) { + fprintf(sc->digestfp, + " -----------------------------------" + "------------------------------------" + "-------\n"); + fprintf(sc->digestfp, "From: "); + if (msg->cm_fields['A'] != NULL) { + fprintf(sc->digestfp, + "%s ", + msg->cm_fields['A']); + } + if (msg->cm_fields['F'] != NULL) { + fprintf(sc->digestfp, + "<%s> ", + msg->cm_fields['F']); + } + else if (msg->cm_fields['N'] != NULL) { + fprintf(sc->digestfp, + "@%s ", + msg->cm_fields['N']); + } + fprintf(sc->digestfp, "\n"); + if (msg->cm_fields['U'] != NULL) { + fprintf(sc->digestfp, + "Subject: %s\n", + msg->cm_fields['U']); + } + + CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); + + safestrncpy(CC->preferred_formats, + "text/plain", + sizeof CC->preferred_formats); + + CtdlOutputPreLoadedMsg(msg, + MT_CITADEL, + HEADERS_NONE, + 0, 0, 0); + + StrBufTrim(CC->redirect_buffer); + fwrite(HKEY("\n"), 1, sc->digestfp); + fwrite(SKEY(CC->redirect_buffer), 1, sc->digestfp); + fwrite(HKEY("\n"), 1, sc->digestfp); + + FreeStrBuf(&CC->redirect_buffer); + + sc->num_msgs_spooled += 1; + CtdlFreeMessage(msg); + } +} + + +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) + return; + + /* create our own copy of the message. + * We're going to need to modify it + * in order to insert the [list name] in it, etc. + */ + + 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. + */ + + /* 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 (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] = '_'; + } + } + } + + /* Handle delivery */ +// network_deliver_list(msg, sc, CC->room.QRname); + CtdlFreeMessage(msg); +} + /* * Deliver list messages to everyone on the list ... efficiently */ @@ -250,419 +436,270 @@ void network_deliver_list(struct CtdlMessage *msg, SpoolControl *sc, const char } -/* - * Spools out one message from the list. - */ -void network_spool_msg(long msgnum, - void *userdata) +void network_process_participate(SpoolControl *sc, struct CtdlMessage *omsg, long *delete_after_send) { - RoomNetCfgLine* mptr; - struct CitContext *CCC = CC; - StrBuf *Buf = NULL; - SpoolControl *sc; - int i; - char *newpath = NULL; struct CtdlMessage *msg = NULL; - RoomNetCfgLine *nptr; - struct ser_ret sermsg; - FILE *fp; - char filename[PATH_MAX]; - char buf[SIZ]; - int bang = 0; - int send = 1; - int delete_after_send = 0; /* Set to 1 to delete after spooling */ + int i; int ok_to_participate = 0; + StrBuf *Buf = NULL; + RoomNetCfgLine *nptr; struct recptypes *valid; - sc = (SpoolControl *)userdata; - /* - * Process mailing list recipients + * Process client-side list participations for this room */ - if (sc->RNCfg->NetConfigs[listrecp] != NULL) { - /* Fetch the message. We're going to need to modify it - * in order to insert the [list name] in it, etc. - */ - msg = CtdlFetchMessage(msgnum, 1); - if (msg != NULL) { - int rlen; - char *pCh; - StrBuf *Subject, *FlatSubject; - - 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. - */ + if (sc->RNCfg->NetConfigs[participate] == NULL) + return; - /* 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 (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] = '_'; - } - } - } + msg = CtdlDuplicateMessage(omsg); - /* Handle delivery */ - network_deliver_list(msg, sc, CC->room.QRname); - CtdlFreeMessage(msg); + /* Only send messages which originated on our own + * Citadel network, otherwise we'll end up sending the + * remote mailing list's messages back to it, which + * is rude... + */ + ok_to_participate = 0; + if (msg->cm_fields['N'] != NULL) { + if (!strcasecmp(msg->cm_fields['N'], + config.c_nodename)) { + ok_to_participate = 1; + } + + Buf = NewStrBufPlain(msg->cm_fields['N'], -1); + if (CtdlIsValidNode(NULL, + NULL, + Buf, + sc->working_ignetcfg, + sc->the_netmap) == 0) + { + ok_to_participate = 1; } } - - /* - * Process digest recipients - */ - if ((sc->RNCfg->NetConfigs[digestrecp] != NULL) && (sc->digestfp != NULL)) { - msg = CtdlFetchMessage(msgnum, 1); - if (msg != NULL) { - fprintf(sc->digestfp, - " -----------------------------------" - "------------------------------------" - "-------\n"); - fprintf(sc->digestfp, "From: "); - if (msg->cm_fields['A'] != NULL) { - fprintf(sc->digestfp, - "%s ", - msg->cm_fields['A']); - } - if (msg->cm_fields['F'] != NULL) { - fprintf(sc->digestfp, - "<%s> ", - msg->cm_fields['F']); - } - else if (msg->cm_fields['N'] != NULL) { - fprintf(sc->digestfp, - "@%s ", - msg->cm_fields['N']); + if (ok_to_participate) { + 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] = '_'; } - fprintf(sc->digestfp, "\n"); - if (msg->cm_fields['U'] != NULL) { - fprintf(sc->digestfp, - "Subject: %s\n", - msg->cm_fields['U']); + } + + /* + * Figure out how big a buffer we need to alloc + */ + for (nptr = sc->RNCfg->NetConfigs[participate]; + nptr != NULL; + nptr = nptr->next) + { + if (msg->cm_fields['R'] != NULL) { + free(msg->cm_fields['R']); } + msg->cm_fields['R'] = + strdup(ChrPtr(nptr->Value[0])); + + valid = validate_recipients(msg->cm_fields['R'], + NULL, 0); + + CtdlSubmitMsg(msg, valid, "", 0); + free_recipients(valid); + } + } + FreeStrBuf(&Buf); + CtdlFreeMessage(msg); +} - CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); - - safestrncpy(CC->preferred_formats, - "text/plain", - sizeof CC->preferred_formats); - - CtdlOutputPreLoadedMsg(msg, - MT_CITADEL, - HEADERS_NONE, - 0, 0, 0); - - StrBufTrim(CC->redirect_buffer); - fwrite(HKEY("\n"), 1, sc->digestfp); - fwrite(SKEY(CC->redirect_buffer), 1, sc->digestfp); - fwrite(HKEY("\n"), 1, sc->digestfp); +void network_process_ignetpush(SpoolControl *sc, struct CtdlMessage *omsg, long *delete_after_send) +{ + struct CtdlMessage *msg = NULL; + struct CitContext *CCC = CC; + struct ser_ret sermsg; + char buf[SIZ]; + char filename[PATH_MAX]; + FILE *fp; + size_t newpath_len; + char *newpath = NULL; + RoomNetCfgLine* mptr; + StrBuf *Buf = NULL; + int i; + int bang = 0; + int send = 1; - FreeStrBuf(&CC->redirect_buffer); + if (sc->RNCfg->NetConfigs[ignet_push_share] == NULL) + return; + /* + * Process IGnet push shares + */ + msg = CtdlDuplicateMessage(omsg); - sc->num_msgs_spooled += 1; - CtdlFreeMessage(msg); - } + /* 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; + /* - * Process client-side list participations for this room + * Determine if this message is set to be deleted + * after sending out on the network */ - if (sc->RNCfg->NetConfigs[participate] != NULL) { - msg = CtdlFetchMessage(msgnum, 1); - if (msg != NULL) { - - /* Only send messages which originated on our own - * Citadel network, otherwise we'll end up sending the - * remote mailing list's messages back to it, which - * is rude... - */ - ok_to_participate = 0; - if (msg->cm_fields['N'] != NULL) { - if (!strcasecmp(msg->cm_fields['N'], - config.c_nodename)) { - ok_to_participate = 1; - } + if (msg->cm_fields['S'] != NULL) { + if (!strcasecmp(msg->cm_fields['S'], "CANCEL")) { + *delete_after_send = 1; + } + } - Buf = NewStrBufPlain(msg->cm_fields['N'], -1); - if (CtdlIsValidNode(NULL, - NULL, - Buf, - sc->working_ignetcfg, - sc->the_netmap) == 0) - { - ok_to_participate = 1; + /* Now send it to every node */ + for (mptr = sc->RNCfg->NetConfigs[ignet_push_share]; + mptr != NULL; + mptr = mptr->next) + { + send = 1; + NewStrBufDupAppendFlush(&Buf, mptr->Value[0], 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(mptr->Value[0])); + + 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'], '!'); + if (bang > 1) { + for (i=0; i<(bang-1); ++i) { + extract_token(buf, + msg->cm_fields['P'], + i, '!', + sizeof buf); + + QN_syslog(LOG_DEBUG, "Compare <%s> to <%s>\n", + buf, ChrPtr(mptr->Value[0])) ; + if (!strcasecmp(buf, ChrPtr(mptr->Value[0]))) { + send = 0; + break; } } - if (ok_to_participate) { - if (msg->cm_fields['F'] != NULL) { - free(msg->cm_fields['F']); + + QN_syslog(LOG_INFO, + "%sSending to %s\n", + (send)?"":"Not ", + ChrPtr(mptr->Value[0])); + } + + /* 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 (msg->cm_fields['C'] != NULL) { + free(msg->cm_fields['C']); + } + if (StrLength(mptr->Value[0]) > 0) { + msg->cm_fields['C'] = + strdup(ChrPtr(mptr->Value[0])); + } + else { + msg->cm_fields['C'] = + strdup(CC->room.QRname); + } + + /* serialize it for transmission */ + serialize_message(&sermsg, msg); + if (sermsg.len > 0) { + + /* write it to a spool file */ + snprintf(filename, + sizeof(filename), + "%s/%s@%lx%x", + ctdl_netout_dir, + ChrPtr(mptr->Value[0]), + 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); } - 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] = '_'; - } + else { + QN_syslog(LOG_ERR, + "%s: %s\n", + filename, + strerror(errno)); } - /* - * Figure out how big a buffer we need to alloc - */ - for (nptr = sc->RNCfg->NetConfigs[participate]; - nptr != NULL; - nptr = nptr->next) - { - if (msg->cm_fields['R'] != NULL) { - free(msg->cm_fields['R']); - } - msg->cm_fields['R'] = - strdup(ChrPtr(nptr->Value[0])); - - valid = validate_recipients(msg->cm_fields['R'], - NULL, 0); - - CtdlSubmitMsg(msg, valid, "", 0); - free_recipients(valid); - } + /* free the serialized version */ + free(sermsg.ser); } - CtdlFreeMessage(msg); } } + FreeStrBuf(&Buf); + CtdlFreeMessage(msg); +} - if (sc->RNCfg->NetConfigs[ignet_push_share] != NULL) - { - /* - * Process IGnet push shares - */ - msg = CtdlFetchMessage(msgnum, 1); - if (msg != NULL) { - size_t newpath_len; - /* 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; +/* + * Spools out one message from the list. + */ +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; - /* - * 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")) { - delete_after_send = 1; - } - } + sc = (SpoolControl *)userdata; + + msg = CtdlFetchMessage(msgnum, 1); + + 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); - /* Now send it to every node */ - if (sc->RNCfg->NetConfigs[ignet_push_share] != NULL) - for (mptr = sc->RNCfg->NetConfigs[ignet_push_share]; mptr != NULL; - mptr = mptr->next) { - - send = 1; - NewStrBufDupAppendFlush(&Buf, mptr->Value[0], 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(mptr->Value[0])); - - 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'], '!'); - if (bang > 1) { - for (i=0; i<(bang-1); ++i) { - extract_token(buf, - msg->cm_fields['P'], - i, '!', - sizeof buf); - - QN_syslog(LOG_DEBUG, "Compare <%s> to <%s>\n", - buf, ChrPtr(mptr->Value[0])) ; - if (!strcasecmp(buf, ChrPtr(mptr->Value[0]))) { - send = 0; - break; - } - } - - QN_syslog(LOG_INFO, - "%sSending to %s\n", - (send)?"":"Not ", - ChrPtr(mptr->Value[0])); - } - - /* 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 (msg->cm_fields['C'] != NULL) { - free(msg->cm_fields['C']); - } - if (StrLength(mptr->Value[0]) > 0) { - msg->cm_fields['C'] = - strdup(ChrPtr(mptr->Value[0])); - } - else { - msg->cm_fields['C'] = - strdup(CC->room.QRname); - } - - /* serialize it for transmission */ - serialize_message(&sermsg, msg); - if (sermsg.len > 0) { - - /* write it to a spool file */ - snprintf(filename, - sizeof(filename), - "%s/%s@%lx%x", - ctdl_netout_dir, - ChrPtr(mptr->Value[0]), - 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); - } - - } - } - CtdlFreeMessage(msg); - } - } /* update lastsent */ - ///sc->lastsent = msgnum; ////// TODO + sc->lastsent = msgnum; /* Delete this message if delete-after-send is set */ if (delete_after_send) { CtdlDeleteMessages(CC->room.QRname, &msgnum, 1, ""); } - FreeStrBuf(&Buf); }