X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fchat%2Fserv_chat.c;h=d5c7be32c68e2ca9b74c073e36d3e09088a243b6;hb=8c47559cb5ae97ec0fa35660ee16fd61a9451c72;hp=5643cf849c93ea914438b96ac0fae86bf87263dc;hpb=2ce2e7704ce19788031a3063e8d27fee63c29686;p=citadel.git diff --git a/citadel/modules/chat/serv_chat.c b/citadel/modules/chat/serv_chat.c index 5643cf849..d5c7be32c 100644 --- a/citadel/modules/chat/serv_chat.c +++ b/citadel/modules/chat/serv_chat.c @@ -4,6 +4,22 @@ * This module handles all "real time" communication between users. The * modes of communication currently supported are Chat and Paging. * + * Copyright (c) 1987-2009 by the citadel.org team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * */ #include "sysdep.h" #include @@ -54,6 +70,7 @@ struct imlog { long usernums[2]; char usernames[2][128]; time_t lastmsg; + int last_serial; StrBuf *conversation; }; @@ -62,7 +79,7 @@ struct imlog *imlist = NULL; /* * This function handles the logging of instant messages to disk. */ -void log_instant_message(struct CitContext *me, struct CitContext *them, char *msgtext) +void log_instant_message(struct CitContext *me, struct CitContext *them, char *msgtext, int serial_number) { long usernums[2]; long t; @@ -111,20 +128,29 @@ void log_instant_message(struct CitContext *me, struct CitContext *them, char *m this_im->conversation = NewStrBuf(); this_im->next = imlist; imlist = this_im; - StrBufAppendBufPlain(this_im->conversation, + StrBufAppendBufPlain(this_im->conversation, HKEY( "Content-type: text/html\r\n" - "Content-transfer-encoding: 7bit\r\n\r\n" - "instant message transcript\r\n" - "\r\n", - -1, 0); - } - - this_im->lastmsg = time(NULL); /* Touch the timestamp so we know when to flush */ - StrBufAppendBufPlain(this_im->conversation, "

", -1, 0); - StrBufAppendBufPlain(this_im->conversation, me->user.fullname, -1, 0); - StrBufAppendBufPlain(this_im->conversation, ": ", -1, 0); - StrEscAppend(this_im->conversation, NULL, msgtext, 0, 0); - StrBufAppendBufPlain(this_im->conversation, "

\r\n", -1, 0); + "Content-transfer-encoding: 7bit\r\n" + "\r\n" + "\r\n" + ), 0); + } + + + /* Since it's possible for this function to get called more than once if a user is logged + * in on multiple sessions, we use the message's serial number to keep track of whether + * we've already logged it. + */ + if (this_im->last_serial != serial_number) + { + this_im->lastmsg = time(NULL); /* Touch the timestamp so we know when to flush */ + this_im->last_serial = serial_number; + StrBufAppendBufPlain(this_im->conversation, HKEY("

"), 0); + StrBufAppendBufPlain(this_im->conversation, me->user.fullname, -1, 0); + StrBufAppendBufPlain(this_im->conversation, HKEY(": "), 0); + StrEscAppend(this_im->conversation, NULL, msgtext, 0, 0); + StrBufAppendBufPlain(this_im->conversation, HKEY("

\r\n"), 0); + } end_critical_section(S_IM_LOGS); } @@ -259,13 +285,11 @@ void do_chat_listing(int allflag) } GenerateRoomDisplay(roomname, ccptr, CC); - if ((CC->user.axlevel < 6) - && (!IsEmptyStr(ccptr->fake_roomname))) { + if ((CC->user.axlevel < 6) && (!IsEmptyStr(ccptr->fake_roomname))) { strcpy(roomname, ccptr->fake_roomname); } - if ((ccptr->cs_flags & CS_CHAT) - && ((ccptr->cs_flags & CS_STEALTH) == 0)) { + if ((ccptr->cs_flags & CS_CHAT) && ((ccptr->cs_flags & CS_STEALTH) == 0)) { if ((allflag == 0) || (allflag == 1)) { cprintf(":| %-25s <%s>:\n", (ccptr->fake_username[0]) ? ccptr->fake_username : ccptr->curr_user, @@ -641,6 +665,7 @@ int send_instant_message(char *lun, char *lem, char *x_user, char *x_msg) char *un; size_t msglen = 0; int do_send = 0; /* 1 = send message; 0 = only check for valid recipient */ + static int serial_number = 0; /* this keeps messages from getting logged twice */ if (strlen(x_msg) > 0) { msglen = strlen(x_msg) + 4; @@ -649,6 +674,7 @@ int send_instant_message(char *lun, char *lem, char *x_user, char *x_msg) /* find the target user's context and append the message */ begin_critical_section(S_SESSION_TABLE); + ++serial_number; for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) { if (ccptr->fake_username[0]) { @@ -664,10 +690,8 @@ int send_instant_message(char *lun, char *lem, char *x_user, char *x_msg) && ((ccptr->disable_exp == 0) || (CC->user.axlevel >= 6)) ) { if (do_send) { - newmsg = (struct ExpressMessage *) - malloc(sizeof (struct ExpressMessage)); - memset(newmsg, 0, - sizeof (struct ExpressMessage)); + newmsg = (struct ExpressMessage *) malloc(sizeof (struct ExpressMessage)); + memset(newmsg, 0, sizeof (struct ExpressMessage)); time(&(newmsg->timestamp)); safestrncpy(newmsg->sender, lun, sizeof newmsg->sender); safestrncpy(newmsg->sender_email, lem, sizeof newmsg->sender_email); @@ -680,7 +704,7 @@ int send_instant_message(char *lun, char *lem, char *x_user, char *x_msg) /* and log it ... */ if (ccptr != CC) { - log_instant_message(CC, ccptr, newmsg->text); + log_instant_message(CC, ccptr, newmsg->text, serial_number); } } ++message_sent; @@ -846,10 +870,10 @@ void flush_individual_conversation(struct imlog *im) { long msgnum = 0; char roomname[ROOMNAMELEN]; - StrBufAppendBufPlain(im->conversation, + StrBufAppendBufPlain(im->conversation, HKEY( "\r\n" - "\r\n", - -1, 0 + "\r\n" + ), 0 ); msg = malloc(sizeof(struct CtdlMessage)); @@ -867,7 +891,7 @@ void flush_individual_conversation(struct imlog *im) { } msg->cm_fields['O'] = strdup(PAGELOGROOM); msg->cm_fields['N'] = strdup(NODENAME); - msg->cm_fields['M'] = strdup(ChrPtr(im->conversation)); + msg->cm_fields['M'] = SmashStrBuf(&im->conversation); /* we own this memory now */ /* Start with usernums[1] because it's guaranteed to be higher than usernums[0], * so if there's only one party, usernums[0] will be zero but usernums[1] won't. @@ -934,10 +958,9 @@ void flush_conversations_to_disk(time_t if_older_than) { */ while (flush_these) { - flush_individual_conversation(flush_these); + flush_individual_conversation(flush_these); /* This will free the string buffer */ imptr = flush_these; flush_these = flush_these->next; - FreeStrBuf(&imptr->conversation); free(imptr); } }