* 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 <stdlib.h>
long usernums[2];
char usernames[2][128];
time_t lastmsg;
+ int last_serial;
StrBuf *conversation;
};
/*
* 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;
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"
- "<html><head><title>instant message transcript</title></head>\r\n"
- "<body>\r\n",
- -1, 0);
- }
-
- this_im->lastmsg = time(NULL); /* Touch the timestamp so we know when to flush */
- StrBufAppendBufPlain(this_im->conversation, "<p><b>", -1, 0);
- StrBufAppendBufPlain(this_im->conversation, me->user.fullname, -1, 0);
- StrBufAppendBufPlain(this_im->conversation, ":</b> ", -1, 0);
- StrEscAppend(this_im->conversation, NULL, msgtext, 0, 0);
- StrBufAppendBufPlain(this_im->conversation, "</p>\r\n", -1, 0);
+ "Content-transfer-encoding: 7bit\r\n"
+ "\r\n"
+ "<html><body>\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("<p><b>"), 0);
+ StrBufAppendBufPlain(this_im->conversation, me->user.fullname, -1, 0);
+ StrBufAppendBufPlain(this_im->conversation, HKEY(":</b> "), 0);
+ StrEscAppend(this_im->conversation, NULL, msgtext, 0, 0);
+ StrBufAppendBufPlain(this_im->conversation, HKEY("</p>\r\n"), 0);
+ }
end_critical_section(S_IM_LOGS);
}
}
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,
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;
/* 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]) {
&& ((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);
/* and log it ... */
if (ccptr != CC) {
- log_instant_message(CC, ccptr, newmsg->text);
+ log_instant_message(CC, ccptr, newmsg->text, serial_number);
}
}
++message_sent;
long msgnum = 0;
char roomname[ROOMNAMELEN];
- StrBufAppendBufPlain(im->conversation,
+ StrBufAppendBufPlain(im->conversation, HKEY(
"</body>\r\n"
- "</html>\r\n",
- -1, 0
+ "</html>\r\n"
+ ), 0
);
msg = malloc(sizeof(struct CtdlMessage));
}
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.
*/
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);
}
}