X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fpaging.c;h=1ee2782b712aec5671ae8ce1911d9d5c31e4e2c5;hb=8e165dd308679f195af8614d62dbdb4e43238495;hp=9cdb897ebe304761f675185881ea5c70674e56bb;hpb=1f6be0ca77d1e30294dc3add26d1a24adeb1788e;p=citadel.git diff --git a/webcit/paging.c b/webcit/paging.c index 9cdb897eb..1ee2782b7 100644 --- a/webcit/paging.c +++ b/webcit/paging.c @@ -1,26 +1,8 @@ -/* $Id$ */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "webcit.h" +/* + * $Id$ + */ +#include "webcit.h" /* * display the form for paging (x-messaging) another user @@ -31,152 +13,493 @@ void display_page(void) strcpy(recp, bstr("recp")); - output_headers(3); + output_headers(1, 1, 2, 0, 0, 0); + wc_printf("
\n"); + wc_printf("

"); + wc_printf(_("Send instant message")); + wc_printf("

"); + wc_printf("
\n"); - wprintf("
"); - wprintf("Page another user\n"); - wprintf("
\n"); + wc_printf("
\n"); - wprintf("
This will send a page (instant message) " - "to %s.\n", recp); + wc_printf("
" + "
\n"); - wprintf("
\n"); + wc_printf(_("Send an instant message to: ")); + escputs(recp); + wc_printf("
\n"); + wc_printf("\n"); + wc_printf("\n", WC->nonce); + wc_printf("\n"); - wprintf("
\n"); + wc_printf("
\n"); - wprintf("\n"); - - wprintf("\n"); + wc_printf("\">\n"); - wprintf("Enter message text:
"); + wc_printf(_("Enter message text:")); + wc_printf("
"); - wprintf("\n"); - wprintf("

\n"); + wc_printf("

\n"); - wprintf(""); - wprintf("
\n"); + wc_printf("", _("Send message")); + wc_printf("
\n", _("Cancel")); - wprintf("\n"); + wc_printf("\n"); + wc_printf("
\n"); wDumpContent(1); } -/* - * page another user +/** + * \brief page another user */ void page_user(void) { - char recp[SIZ]; - char sc[SIZ]; - char buf[SIZ]; - char closewin[SIZ]; + char recp[256]; + char buf[256]; - output_headers(1); - - strcpy(recp, bstr("recp")); - strcpy(sc, bstr("sc")); - strcpy(closewin, bstr("closewin")); + safestrncpy(recp, bstr("recp"), sizeof recp); - if (strcmp(sc, "Send message")) { - wprintf("Message was not sent.
\n"); + if (!havebstr("send_button")) { + safestrncpy(WC->ImportantMessage, + _("Message was not sent."), + sizeof WC->ImportantMessage + ); } else { serv_printf("SEXP %s|-", recp); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[0] == '4') { text_to_server(bstr("msgtext")); serv_puts("000"); - wprintf("Message has been sent to "); - escputs(recp); - wprintf(".
\n"); + stresc(buf, 256, recp, 0, 0); + snprintf(WC->ImportantMessage, + sizeof WC->ImportantMessage, + "%s%s.", + _("Message has been sent to "), + buf + ); } else { - wprintf("%s
\n", &buf[4]); + safestrncpy(WC->ImportantMessage, &buf[4], sizeof WC->ImportantMessage); } } - - if (!strcasecmp(closewin, "yes")) { - wprintf("
" - "[ close window ]
\n"); - } - wDumpContent(1); + url_do_template(); } -/* - * multiuser chat +/** + * \brief multiuser chat */ void do_chat(void) { + char buf[SIZ]; - output_headers(1); - - wprintf("
"); - wprintf("Real-time chat\n"); - wprintf("
\n"); - - wprintf("A chat window should be appearing on your screen "); - wprintf("momentarily. When you're "); - wprintf("done, type /quit to exit. You can also "); - wprintf("type /help for more commands.\n"); - - wprintf("\n"); - wprintf("\n", WC->wc_username); - wprintf("\n", WC->wc_password); - wprintf("\n", WC->wc_roomname); - wprintf("

Oops!

Looks like your browser doesn't support Java, "); - wprintf("so you won't be able to access Chat. Sorry.\n"); - wprintf("
\n"); - wDumpContent(1); + /** First, check to make sure we're still allowed in this room. */ + serv_printf("GOTO %s", ChrPtr(WC->wc_roomname)); + 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 + * 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. */ -void page_popup(void) +int Conditional_PAGE_WAITING(StrBuf *Target, WCTemplputParams *TP) { + int len; + char buf[SIZ]; + + /** JavaScript function to alert the user that popups are probably blocked */ + /** First, do the check as part of our page load. */ + serv_puts("NOOP"); + len = serv_getln(buf, sizeof buf); + if ((len >= 3) && (buf[3] == '*')) { + if ((time(NULL) - WC->last_pager_check) > 60) { + return 1; + } + } + 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]; - char pagefrom[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); + } - /* suppress express message check, do headers but no fake frames */ - output_headers(0x08 | 0x03); + if (WC->chat_sock < 0) { + return(errno); + } - while (serv_puts("GEXP"), serv_gets(buf), buf[0]=='1') { + /** 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->wc_roomname)); + serv_getln(buf, sizeof buf); + if (buf[0] == '2') { + serv_puts("CHAT"); + serv_getln(buf, sizeof buf); + if (buf[0] == '8') { + good_chatmode = 1; + } + } + } + } + } - extract(pagefrom, &buf[4], 3); + /** Unswap the sockets. */ + i = WC->serv_sock; + WC->serv_sock = WC->chat_sock; + WC->chat_sock = i; + + if (!good_chatmode) close(WC->serv_sock); - wprintf("
"); - wprintf("Express message from "); - escputs(pagefrom); - wprintf("
\n"); - - fmout(NULL); } + return(0); +} - wprintf("
"); - wprintf("[ reply ]   \n"); - wprintf("" - "[ close window ]\n" - "
"); - wDumpContent(1); - WC->HaveExpressMessages = 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); +} + + +void ajax_send_instant_message(void) { + char recp[256]; + char buf[256]; + + safestrncpy(recp, bstr("recp"), sizeof recp); + + serv_printf("SEXP %s|-", recp); + serv_getln(buf, sizeof buf); + + if (buf[0] == '4') { + text_to_server(bstr("msg")); + serv_puts("000"); + } + + escputs(buf); /* doesn't really matter what we return - the client ignores it */ +} + + +void +InitModule_PAGING +(void) +{ + 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 +(wcsession *sess) +{ + if (sess->chat_sock > 0) + close(sess->chat_sock); +}