From 8ce55d0a3cc3011b8e8bb08106f6a067f68d9df9 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 19 Apr 2010 14:56:57 +0000 Subject: [PATCH] * update room chat to the new protocol. This needs a couple more tweaks but I'm checking it in to avoid conflicts with other commits --- webcit/Makefile.in | 4 +- webcit/context_loop.c | 1 - webcit/paging.c | 381 ++---------------------------- webcit/roomchat.c | 179 ++++++++++++++ webcit/static/t/chatframeset.html | 27 --- webcit/static/t/iconbar.html | 2 +- webcit/static/t/roomchat.html | 28 +++ webcit/static/wclib.js | 1 - webcit/webcit.h | 2 +- 9 files changed, 236 insertions(+), 389 deletions(-) create mode 100644 webcit/roomchat.c delete mode 100644 webcit/static/t/chatframeset.html create mode 100644 webcit/static/t/roomchat.html diff --git a/webcit/Makefile.in b/webcit/Makefile.in index eb5d5a6f3..e01549886 100644 --- a/webcit/Makefile.in +++ b/webcit/Makefile.in @@ -49,7 +49,7 @@ webcit: webserver.o context_loop.o ical_dezonify.o \ cookie_conversion.o locate_host.o floors.o summary.o \ webcit.o auth.o tcp_sockets.o mainmenu.o serv_func.o who.o marchlist.o \ roomops.o roomlist.o messages.o msg_renderers.o userlist.o paging.o sysmsgs.o \ - useredit.o vcard_edit.o preferences.o html2html.o listsub.o \ + useredit.o vcard_edit.o preferences.o html2html.o listsub.o roomchat.o \ graphics.o netconf.o siteconfig.o subst.o bbsview_renderer.o \ calendar.o calendar_tools.o calendar_view.o tasks.o event.o smtpqueue.o \ availability.o iconbar.o crypto.o inetconf.o notes.o wiki.o \ @@ -64,7 +64,7 @@ webcit: webserver.o context_loop.o ical_dezonify.o \ webserver.o context_loop.o cookie_conversion.o marchlist.o \ webcit.o auth.o tcp_sockets.o mainmenu.o serv_func.o who.o listsub.o \ roomops.o roomlist.o messages.o msg_renderers.o userlist.o paging.o sysmsgs.o \ - useredit.o locate_host.o siteconfig.o subst.o vcard_edit.o floors.o \ + useredit.o locate_host.o siteconfig.o subst.o vcard_edit.o floors.o roomchat.o \ graphics.o netconf.o preferences.o html2html.o openid.o bbsview_renderer.o \ summary.o calendar.o calendar_tools.o calendar_view.o tasks.o event.o wiki.o \ availability.o ical_dezonify.o iconbar.o crypto.o inetconf.o notes.o \ diff --git a/webcit/context_loop.c b/webcit/context_loop.c index 66261da1d..34233ef41 100644 --- a/webcit/context_loop.c +++ b/webcit/context_loop.c @@ -187,7 +187,6 @@ wcsession *CreateSession(int Lockable, int Static, wcsession **wclist, ParsedHtt TheSession->Hdr = Hdr; TheSession->SessionKey = Hdr->HR.SessionKey; TheSession->serv_sock = (-1); - TheSession->chat_sock = (-1); TheSession->is_mobile = -1; pthread_setspecific(MyConKey, (void *)TheSession); diff --git a/webcit/paging.c b/webcit/paging.c index bb6ad8e2f..2c052971a 100644 --- a/webcit/paging.c +++ b/webcit/paging.c @@ -1,5 +1,23 @@ /* * $Id$ + * + * This module handles instant message related functions. + * + * Copyright (c) 1996-2010 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 "webcit.h" @@ -55,8 +73,8 @@ void display_page(void) wDumpContent(1); } -/** - * \brief page another user +/* + * page another user */ void page_user(void) { @@ -95,47 +113,8 @@ void page_user(void) -/** - * \brief multiuser chat - */ -void do_chat(void) -{ - char buf[SIZ]; - - /** First, check to make sure we're still allowed in this room. */ - serv_printf("GOTO %s", ChrPtr(WC->CurRoom.name)); - serv_getln(buf, sizeof buf); - if (buf[0] != '2') { - StrBuf *Buf; - Buf = NewStrBufPlain(HKEY("_BASEROOM_")); - smart_goto(Buf); - FreeStrBuf(&Buf); - return; - } - - /** - * If the chat socket is still open from a previous chat, - * close it -- because it might be stale or in the wrong room. - */ - if (WC->chat_sock < 0) { - close(WC->chat_sock); - WC->chat_sock = (-1); - } - - /** - * WebCit Chat works by having transmit, receive, and refresh - * frames. Load the frameset. (This isn't AJAX but the headers - * output by begin_ajax_response() happen to be the ones we need.) - */ - begin_ajax_response(); - do_template("chatframeset", NULL); - end_ajax_response(); - return; -} - - -/** - * \brief display page popup +/* + * display page popup * If there are instant messages waiting, and we notice that we haven't checked them in * a while, it probably means that we need to open the instant messenger window. */ @@ -154,313 +133,7 @@ int Conditional_PAGE_WAITING(StrBuf *Target, WCTemplputParams *TP) } } return 0; - /** Then schedule it to happen again a minute from now if the user is idle. */ -} - - - -/** - * \brief Support function for chat - * make sure the chat socket is connected - * and in chat mode. - */ -int setup_chat_socket(void) { - char buf[SIZ]; - int i; - int good_chatmode = 0; - - if (WC->chat_sock < 0) { - - if (!strcasecmp(ctdlhost, "uds")) { - /** unix domain socket */ - sprintf(buf, "%s/citadel.socket", ctdlport); - WC->chat_sock = uds_connectsock(buf); - } - else { - /** tcp socket */ - WC->chat_sock = tcp_connectsock(ctdlhost, ctdlport); - } - - if (WC->chat_sock < 0) { - return(errno); - } - - /** Temporarily swap the serv and chat sockets during chat talk */ - i = WC->serv_sock; - WC->serv_sock = WC->chat_sock; - WC->chat_sock = i; - - serv_getln(buf, sizeof buf); - if (buf[0] == '2') { - serv_printf("USER %s", ChrPtr(WC->wc_username)); - serv_getln(buf, sizeof buf); - if (buf[0] == '3') { - serv_printf("PASS %s", ChrPtr(WC->wc_password)); - serv_getln(buf, sizeof buf); - if (buf[0] == '2') { - serv_printf("GOTO %s", ChrPtr(WC->CurRoom.name)); - serv_getln(buf, sizeof buf); - if (buf[0] == '2') { - serv_puts("CHAT"); - serv_getln(buf, sizeof buf); - if (buf[0] == '8') { - good_chatmode = 1; - } - } - } - } - } - - /** Unswap the sockets. */ - i = WC->serv_sock; - WC->serv_sock = WC->chat_sock; - WC->chat_sock = i; - - if (!good_chatmode) close(WC->serv_sock); - - } - return(0); -} - - - -/** - * \brief Receiving side of the chat window. - * This is implemented in a - * tiny hidden IFRAME that just does JavaScript writes to - * other frames whenever it refreshes and finds new data. - */ -void chat_recv(void) { - int i; - struct pollfd pf; - int got_data = 0; - int end_chat_now = 0; - char buf[SIZ]; - char cl_user[SIZ]; - char cl_text[SIZ]; - char *output_data = NULL; - - output_headers(0, 0, 0, 0, 0, 0); - - hprintf("Content-type: text/html; charset=utf-8\r\n"); - begin_burst(); - wc_printf("\n" - "\n" - "\n" - "\n" - - "\n" - ); - - if (setup_chat_socket() != 0) { - wc_printf(_("An error occurred while setting up the chat socket.")); - wc_printf("\n"); - wDumpContent(0); - return; - } - - /** - * See if there is any chat data waiting. - */ - output_data = strdup(""); - do { - got_data = 0; - pf.fd = WC->chat_sock; - pf.events = POLLIN; - pf.revents = 0; - if ((poll(&pf, 1, 1) > 0) && (pf.revents & POLLIN)) { - ++got_data; - - /** Temporarily swap the serv and chat sockets during chat talk */ - i = WC->serv_sock; - WC->serv_sock = WC->chat_sock; - WC->chat_sock = i; - - serv_getln(buf, sizeof buf); - - if (!strcmp(buf, "000")) { - strcpy(buf, ":|"); - strcat(buf, _("Now exiting chat mode.")); - end_chat_now = 1; - } - - /** Unswap the sockets. */ - i = WC->serv_sock; - WC->serv_sock = WC->chat_sock; - WC->chat_sock = i; - - /** Append our output data */ - output_data = realloc(output_data, strlen(output_data) + strlen(buf) + 4); - strcat(output_data, buf); - strcat(output_data, "\n"); - } - - } while ( (got_data) && (!end_chat_now) ); - - if (end_chat_now) { - close(WC->chat_sock); - WC->chat_sock = (-1); - wc_printf("\n"); - } - - if (!IsEmptyStr(output_data)) { - int len; - len = strlen(output_data); - if (output_data[len-1] == '\n') { - output_data[len-1] = 0; - } - - /** Output our fun to the other frame. */ - wc_printf("last_chat_user)) { - wc_printf("" - "
" - ); - - } - - wc_printf(""); - - wc_printf("
"); - - if (!strcasecmp(cl_user, ":")) { - wc_printf(""); - } - - if (strcasecmp(cl_user, WC->last_chat_user)) { - wc_printf(""); - - if (!strcasecmp(cl_user, ChrPtr(WC->wc_fullname))) { - wc_printf(""); - } - else { - wc_printf(""); - } - jsescputs(cl_user); - - wc_printf(": "); - } - else { - wc_printf("   "); - } - jsescputs(cl_text); - if (!strcasecmp(cl_user, ":")) { - wc_printf(""); - } - - wc_printf("
"); - wc_printf("'); \n"); - - strcpy(WC->last_chat_user, cl_user); - } - } - - wc_printf("parent.chat_transcript.scrollTo(999999,999999);\">\n"); - } - - free(output_data); - - wc_printf("\n"); - wDumpContent(0); -} - - -/** - * \brief sending side of the chat window - */ -void chat_send(void) { - int i; - char send_this[SIZ]; - char buf[SIZ]; - - output_headers(0, 0, 0, 0, 0, 0); - hprintf("Content-type: text/html; charset=utf-8\r\n"); - begin_burst(); - wc_printf("" - "" - ); - - if (havebstr("send_this")) { - strcpy(send_this, bstr("send_this")); - } - else { - strcpy(send_this, ""); - } - - if (havebstr("help_button")) { - strcpy(send_this, "/help"); - } - - if (havebstr("list_button")) { - strcpy(send_this, "/who"); - } - - if (havebstr("exit_button")) { - strcpy(send_this, "/quit"); - } - - if (setup_chat_socket() != 0) { - wc_printf(_("An error occurred while setting up the chat socket.")); - wc_printf("\n"); - wDumpContent(0); - return; - } - - /** Temporarily swap the serv and chat sockets during chat talk */ - i = WC->serv_sock; - WC->serv_sock = WC->chat_sock; - WC->chat_sock = i; - - while (!IsEmptyStr(send_this)) { - if (strlen(send_this) < 67) { - serv_puts(send_this); - strcpy(send_this, ""); - } - else { - for (i=55; i<67; ++i) { - if (send_this[i] == ' ') break; - } - strncpy(buf, send_this, i); - buf[i] = 0; - strcpy(send_this, &send_this[i]); - serv_puts(buf); - } - } - - /** Unswap the sockets. */ - i = WC->serv_sock; - WC->serv_sock = WC->chat_sock; - WC->chat_sock = i; - - wc_printf("
\n"); - wc_printf("\n", WC->nonce); - wc_printf("\n", SIZ-10); - wc_printf("
"); - wc_printf("\n", _("Send")); - wc_printf("\n", _("Help")); - wc_printf("\n", _("List users")); - wc_printf("\n", _("Exit")); - wc_printf("
\n"); - - wc_printf("\n"); - wDumpContent(0); + /* Then schedule it to happen again a minute from now if the user is idle. */ } @@ -488,18 +161,14 @@ InitModule_PAGING { WebcitAddUrlHandler(HKEY("display_page"), "", 0, display_page, 0); WebcitAddUrlHandler(HKEY("page_user"), "", 0, page_user, 0); - WebcitAddUrlHandler(HKEY("chat"), "", 0, do_chat, 0); - WebcitAddUrlHandler(HKEY("chat_recv"), "", 0, chat_recv, 0); - WebcitAddUrlHandler(HKEY("chat_send"), "", 0, chat_send, 0); WebcitAddUrlHandler(HKEY("ajax_send_instant_message"), "", 0, ajax_send_instant_message, AJAX); RegisterConditional(HKEY("COND:PAGE:WAITING"), 0, Conditional_PAGE_WAITING, CTX_NONE); } void -SessionDestroyModule_CHAT +SessionDestroyModule_PAGING (wcsession *sess) { - if (sess->chat_sock > 0) - close(sess->chat_sock); + /* nothing here anymore */ } diff --git a/webcit/roomchat.c b/webcit/roomchat.c new file mode 100644 index 000000000..0933fa616 --- /dev/null +++ b/webcit/roomchat.c @@ -0,0 +1,179 @@ +/* + * $Id$ + * + * This module handles multiuser chat. + * + * Copyright (c) 1996-2010 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 "webcit.h" + + +/* + * Display the screen containing multiuser chat for a room. + */ +void do_chat(void) +{ + char buf[256]; + + WC->last_chat_seq = 0; + WC->last_chat_user[0] = 0; + + output_headers(1, 1, 1, 0, 0, 0); + do_template("roomchat", NULL); + + serv_puts("RCHT enter"); + serv_getln(buf, sizeof buf); + + wDumpContent(1); +} + + +/* + * Receiving side of the chat window. + * This does JavaScript writes to + * other divs whenever it refreshes and finds new data. + */ +void chat_recv(void) { + char buf[SIZ]; + char cl_user[SIZ]; + char cl_text[SIZ]; + int cl_text_len = 0; + + begin_ajax_response(); + + serv_printf("RCHT poll|%d", WC->last_chat_seq); + serv_getln(buf, sizeof buf); + if (buf[0] == '1') { + WC->last_chat_seq = extract_int(&buf[4], 0); + extract_token(cl_user, &buf[4], 2, '|', sizeof cl_user); + cl_text[0] = 0; + cl_text_len = 0; + while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { + safestrncpy(&cl_text[cl_text_len], buf, (sizeof(cl_text) - cl_text_len)); + cl_text_len += strlen(buf); + } + + wc_printf("
", WC->last_chat_seq); + + if (strcasecmp(cl_user, WC->last_chat_user)) { + wc_printf("" + "
" + ); + + } + + wc_printf(""); + + wc_printf("
"); + + if (!strcasecmp(cl_user, ":")) { + wc_printf(""); + } + + if (strcasecmp(cl_user, WC->last_chat_user)) { + wc_printf(""); + + if (!strcasecmp(cl_user, ChrPtr(WC->wc_fullname))) { + wc_printf(""); + } + else { + wc_printf(""); + } + jsescputs(cl_user); + + wc_printf(": "); + } + else { + wc_printf("   "); + } + jsescputs(cl_text); + if (!strcasecmp(cl_user, ":")) { + wc_printf(""); + } + + wc_printf("
\n"); + wc_printf("
\n"); + + strcpy(WC->last_chat_user, cl_user); + /* FIXME make this work wc_printf("parent.chat_transcript.scrollTo(999999,999999);\">\n"); */ + } + + end_ajax_response(); + +} + + +/* + * This is the sending side of the chat window. The form is designed to transmit asynchronously. + */ +void chat_send(void) { + char send_this[SIZ]; + char buf[SIZ]; + + begin_ajax_response(); + + if (havebstr("send_this")) { + strcpy(send_this, bstr("send_this")); + } + else { + strcpy(send_this, ""); + } + + if (havebstr("help_button")) { + strcpy(send_this, "/help"); + } + + if (havebstr("list_button")) { + strcpy(send_this, "/who"); + } + + if (havebstr("exit_button")) { + strcpy(send_this, "/quit"); + } + + if (!IsEmptyStr(send_this)) { + serv_puts("RCHT send"); + serv_getln(buf, sizeof buf); + if (buf[0] == '4') { + text_to_server(send_this); + serv_puts("000"); + } + } + end_ajax_response(); +} + + +void +InitModule_ROOMCHAT +(void) +{ + WebcitAddUrlHandler(HKEY("chat"), "", 0, do_chat, 0); + WebcitAddUrlHandler(HKEY("chat_recv"), "", 0, chat_recv, 0); + WebcitAddUrlHandler(HKEY("chat_send"), "", 0, chat_send, 0); +} + + +void +SessionDestroyModule_ROOMCHAT +(wcsession *sess) +{ + /* nothing here anymore */ +} diff --git a/webcit/static/t/chatframeset.html b/webcit/static/t/chatframeset.html deleted file mode 100644 index 935d79ec0..000000000 --- a/webcit/static/t/chatframeset.html +++ /dev/null @@ -1,27 +0,0 @@ - - -Real-time chat: <?ROOMNAME> - - - - - - - - - - - - - - - - - -<div align="center"> -This function requires a browser that can support frames. -</div> - - - - diff --git a/webcit/static/t/iconbar.html b/webcit/static/t/iconbar.html index b0f4b7f24..316dd11dd 100644 --- a/webcit/static/t/iconbar.html +++ b/webcit/static/t/iconbar.html @@ -52,7 +52,7 @@
  • - + diff --git a/webcit/static/t/roomchat.html b/webcit/static/t/roomchat.html new file mode 100644 index 000000000..87eefe009 --- /dev/null +++ b/webcit/static/t/roomchat.html @@ -0,0 +1,28 @@ +
    +This is the receiving side of the chat window, fee fie foe foo +
    +
    +
    + + +
    +"> +"> +"> +"> +
    + + diff --git a/webcit/static/wclib.js b/webcit/static/wclib.js index 8fd9b16bd..6d5f22820 100644 --- a/webcit/static/wclib.js +++ b/webcit/static/wclib.js @@ -36,7 +36,6 @@ Event.observe(window, 'load', resizeViewport); Event.observe(window, 'resize', resizeViewport); //document.observe("dom:loaded", setupPrefEngine); document.observe("dom:loaded", setupIconBar); -document.observe('dom:loaded', function() { if (!!document.getElementById("ib_chat_launch")) { $('ib_chat_launch').observe('click', launchChat); } }); function CtdlRandomString() { return((Math.random()+'').substr(3)); } diff --git a/webcit/webcit.h b/webcit/webcit.h index 9fff7edea..e88d0e90d 100644 --- a/webcit/webcit.h +++ b/webcit/webcit.h @@ -474,7 +474,7 @@ struct wcsession { StrBuf *ReadBuf; /* here we keep our stuff while reading linebuffered from the server. */ StrBuf *MigrateReadLineBuf; /* here we buffer legacy server read stuff */ const char *ReadPos; /* whats our read position in ReadBuf? */ - int chat_sock; /* Client socket to Citadel server - for chat */ + int last_chat_seq; /* When in chat - last message seq# we saw */ time_t lastreq; /* Timestamp of most recent HTTP */ time_t last_pager_check; /* last time we polled for instant msgs */ ServInfo *serv_info; /* Information about the citserver we're connected to */ -- 2.30.2