5 * \defgroup PageFunc Functions which implement the chat and paging facilities.
12 * \brief display the form for paging (x-messaging) another user
14 void display_page(void)
18 strcpy(recp, bstr("recp"));
20 output_headers(1, 1, 2, 0, 0, 0);
21 wprintf("<div id=\"banner\">\n"
22 "<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#444455\"><TR><TD>"
23 "<SPAN CLASS=\"titlebar\">");
24 wprintf(_("Send instant message"));
26 "</TD></TR></TABLE>\n"
27 "</div>\n<div id=\"content\">\n"
30 wprintf("<div class=\"fix_scrollbar_bug\">"
31 "<table border=0 width=100%% bgcolor=\"#ffffff\"><tr><td>\n");
33 wprintf(_("Send an instant message to: "));
37 wprintf("<FORM METHOD=\"POST\" action=\"page_user\">\n");
39 wprintf("<TABLE border=0 width=100%%><TR><TD>\n");
41 wprintf("<INPUT TYPE=\"hidden\" NAME=\"recp\" VALUE=\"");
45 wprintf("<INPUT TYPE=\"hidden\" NAME=\"closewin\" VALUE=\"");
46 escputs(bstr("closewin"));
49 wprintf(_("Enter message text:"));
52 wprintf("<TEXTAREA NAME=\"msgtext\" wrap=soft ROWS=5 COLS=40 "
53 "WIDTH=40></TEXTAREA>\n");
55 wprintf("</TD></TR></TABLE><br />\n");
57 wprintf("<INPUT TYPE=\"submit\" NAME=\"send_button\" VALUE=\"%s\">", _("Send message"));
58 wprintf("<br /><a href=\"javascript:window.close();\"%s</A>\n", _("Cancel"));
60 wprintf("</FORM></CENTER>\n");
61 wprintf("</td></tr></table></div>\n");
66 * \brief page another user
74 output_headers(1, 1, 2, 0, 0, 0);
75 wprintf("<div id=\"banner\">\n"
76 "<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#444455\"><TR><TD>"
77 "<SPAN CLASS=\"titlebar\">");
78 wprintf(_("Add or edit an event"));
80 "</TD></TR></TABLE>\n"
81 "</div>\n<div id=\"content\">\n"
84 strcpy(recp, bstr("recp"));
85 strcpy(closewin, bstr("closewin"));
87 if (strlen(bstr("send_button")) == 0) {
89 wprintf(_("Message was not sent."));
90 wprintf("</EM><br />\n");
92 serv_printf("SEXP %s|-", recp);
93 serv_getln(buf, sizeof buf);
96 text_to_server(bstr("msgtext"));
99 wprintf(_("Message has been sent to "));
101 wprintf(".</EM><br />\n");
104 wprintf("<EM>%s</EM><br />\n", &buf[4]);
108 if (!strcasecmp(closewin, "yes")) {
109 wprintf("<CENTER><a href=\"javascript:window.close();\">");
110 wprintf(_("[ close window ]"));
111 wprintf("</A></CENTER>\n");
120 * \brief multiuser chat
126 /** First, check to make sure we're still allowed in this room. */
127 serv_printf("GOTO %s", WC->wc_roomname);
128 serv_getln(buf, sizeof buf);
130 smart_goto("_BASEROOM_");
135 * If the chat socket is still open from a previous chat,
136 * close it -- because it might be stale or in the wrong room.
138 if (WC->chat_sock < 0) {
139 close(WC->chat_sock);
140 WC->chat_sock = (-1);
144 * WebCit Chat works by having transmit, receive, and refresh
145 * frames. Load the frameset. (This isn't AJAX but the headers
146 * output by begin_ajax_response() happen to be the ones we need.)
148 begin_ajax_response();
149 do_template("chatframeset");
156 * \brief display page popup
157 * If there are instant messages waiting, and we notice that we haven't checked them in
158 * a while, it probably means that we need to open the instant messenger window.
160 void page_popup(void)
164 /** JavaScript function to alert the user that popups are probably blocked */
165 wprintf("<script type=\"text/javascript\"> "
166 "function PopUpFailed() { "
170 _("You have one or more instant messages waiting, but the Citadel Instant Messenger "
171 "window failed to open. This is probably because you have a popup blocker "
172 "installed. Please configure your popup blocker to allow popups from this site "
173 "if you wish to receive instant messages.")
176 /** First, do the check as part of our page load. */
178 serv_getln(buf, sizeof buf);
180 if ((time(NULL) - WC->last_pager_check) > 60) {
181 wprintf("<script type=\"text/javascript\">"
182 " var oWin = window.open('static/instant_messenger.html', "
183 " 'CTDL_MESSENGER', 'width=700,height=400'); "
184 " if (oWin==null || typeof(oWin)==\"undefined\") { "
192 /** Then schedule it to happen again a minute from now if the user is idle. */
193 wprintf("<script type=\"text/javascript\"> "
194 " function HandleSslp(sslg_xmlresponse) { "
195 " sslg_response = sslg_xmlresponse.responseText.substr(0, 1); "
196 " if (sslg_response == 'Y') { "
197 " var oWin = window.open('static/instant_messenger.html', 'CTDL_MESSENGER', "
198 " 'width=700,height=400'); "
199 " if (oWin==null || typeof(oWin)==\"undefined\") { "
204 " function CheckPager() { "
205 " new Ajax.Request('sslg', { method: 'get', parameters: Math.random(), "
206 " onSuccess: HandleSslp } ); "
208 " new PeriodicalExecuter(CheckPager, 30); "
216 * \brief Support function for chat
217 * make sure the chat socket is connected
220 int setup_chat_socket(void) {
223 int good_chatmode = 0;
225 if (WC->chat_sock < 0) {
227 if (!strcasecmp(ctdlhost, "uds")) {
228 /** unix domain socket */
229 sprintf(buf, "%s/citadel.socket", ctdlport);
230 WC->chat_sock = uds_connectsock(buf);
234 WC->chat_sock = tcp_connectsock(ctdlhost, ctdlport);
237 if (WC->chat_sock < 0) {
241 /** Temporarily swap the serv and chat sockets during chat talk */
243 WC->serv_sock = WC->chat_sock;
246 serv_getln(buf, sizeof buf);
248 serv_printf("USER %s", WC->wc_username);
249 serv_getln(buf, sizeof buf);
251 serv_printf("PASS %s", WC->wc_password);
252 serv_getln(buf, sizeof buf);
254 serv_printf("GOTO %s", WC->wc_roomname);
255 serv_getln(buf, sizeof buf);
258 serv_getln(buf, sizeof buf);
267 /** Unswap the sockets. */
269 WC->serv_sock = WC->chat_sock;
272 if (!good_chatmode) close(WC->serv_sock);
281 * \brief Receiving side of the chat window.
282 * This is implemented in a
283 * tiny hidden IFRAME that just does JavaScript writes to
284 * other frames whenever it refreshes and finds new data.
286 void chat_recv(void) {
290 int end_chat_now = 0;
294 char *output_data = NULL;
296 output_headers(0, 0, 0, 0, 0, 0);
298 wprintf("Content-type: text/html; charset=utf-8\n");
302 "<meta http-equiv=\"refresh\" content=\"3\" />\n"
305 "<body bgcolor=\"#FFFFFF\">\n"
308 if (setup_chat_socket() != 0) {
309 wprintf(_("An error occurred while setting up the chat socket."));
310 wprintf("</BODY></HTML>\n");
316 * See if there is any chat data waiting.
318 output_data = strdup("");
321 pf.fd = WC->chat_sock;
324 if (poll(&pf, 1, 1) > 0) if (pf.revents & POLLIN) {
327 /** Temporarily swap the serv and chat sockets during chat talk */
329 WC->serv_sock = WC->chat_sock;
332 serv_getln(buf, sizeof buf);
334 if (!strcmp(buf, "000")) {
336 strcat(buf, _("Now exiting chat mode."));
340 /** Unswap the sockets. */
342 WC->serv_sock = WC->chat_sock;
345 /** Append our output data */
346 output_data = realloc(output_data, strlen(output_data) + strlen(buf) + 4);
347 strcat(output_data, buf);
348 strcat(output_data, "\n");
351 } while ( (got_data) && (!end_chat_now) );
354 close(WC->chat_sock);
355 WC->chat_sock = (-1);
356 wprintf("<img src=\"static/blank.gif\" onLoad=\"parent.window.close();\">\n");
359 if (strlen(output_data) > 0) {
361 if (output_data[strlen(output_data)-1] == '\n') {
362 output_data[strlen(output_data)-1] = 0;
365 /** Output our fun to the other frame. */
366 wprintf("<img src=\"static/blank.gif\" WIDTH=1 HEIGHT=1\n"
370 for (i=0; i<num_tokens(output_data, '\n'); ++i) {
371 extract_token(buf, output_data, i, '\n', sizeof buf);
372 extract_token(cl_user, buf, 0, '|', sizeof cl_user);
373 extract_token(cl_text, buf, 1, '|', sizeof cl_text);
375 if (strcasecmp(cl_text, "NOOP")) {
377 wprintf("parent.chat_transcript.document.write('");
379 if (strcasecmp(cl_user, WC->last_chat_user)) {
380 wprintf("<TABLE border=0 WIDTH=100%% "
381 "CELLSPACING=1 CELLPADDING=0 "
382 "BGCOLOR="#FFFFFF">"
383 "<TR><TD></TR></TD></TABLE>"
388 wprintf("<TABLE border=0 WIDTH=100%% "
389 "CELLSPACING=0 CELLPADDING=0 "
390 "BGCOLOR="#EEEEEE">");
394 if (!strcasecmp(cl_user, ":")) {
398 if (strcasecmp(cl_user, WC->last_chat_user)) {
401 if (!strcasecmp(cl_user, WC->wc_fullname)) {
402 wprintf("<FONT COLOR="#FF0000">");
405 wprintf("<FONT COLOR="#0000FF">");
409 wprintf("</FONT>: </B>");
412 wprintf(" ");
415 if (!strcasecmp(cl_user, ":")) {
419 wprintf("</TD></TR></TABLE>");
422 strcpy(WC->last_chat_user, cl_user);
426 wprintf("parent.chat_transcript.scrollTo(999999,999999);\">\n");
431 wprintf("</BODY></HTML>\n");
437 * \brief sending side of the chat window
439 void chat_send(void) {
444 output_headers(0, 0, 0, 0, 0, 0);
445 wprintf("Content-type: text/html; charset=utf-8\n");
448 "<BODY onLoad=\"document.chatsendform.send_this.focus();\" >"
451 if (bstr("send_this") != NULL) {
452 strcpy(send_this, bstr("send_this"));
455 strcpy(send_this, "");
458 if (strlen(bstr("help_button")) > 0) {
459 strcpy(send_this, "/help");
462 if (strlen(bstr("list_button")) > 0) {
463 strcpy(send_this, "/who");
466 if (strlen(bstr("exit_button")) > 0) {
467 strcpy(send_this, "/quit");
470 if (setup_chat_socket() != 0) {
471 wprintf(_("An error occurred while setting up the chat socket."));
472 wprintf("</BODY></HTML>\n");
477 /** Temporarily swap the serv and chat sockets during chat talk */
479 WC->serv_sock = WC->chat_sock;
482 while (strlen(send_this) > 0) {
483 if (strlen(send_this) < 67) {
484 serv_puts(send_this);
485 strcpy(send_this, "");
488 for (i=55; i<67; ++i) {
489 if (send_this[i] == ' ') break;
491 strncpy(buf, send_this, i);
493 strcpy(send_this, &send_this[i]);
498 /** Unswap the sockets. */
500 WC->serv_sock = WC->chat_sock;
503 wprintf("<FORM METHOD=\"POST\" action=\"chat_send\" NAME=\"chatsendform\">\n");
504 wprintf("<INPUT TYPE=\"text\" SIZE=\"80\" MAXLENGTH=\"%d\" "
505 "NAME=\"send_this\">\n", SIZ-10);
507 wprintf("<INPUT TYPE=\"submit\" NAME=\"send_button\" VALUE=\"%s\">\n", _("Send"));
508 wprintf("<INPUT TYPE=\"submit\" NAME=\"help_button\" VALUE=\"%s\">\n", _("Help"));
509 wprintf("<INPUT TYPE=\"submit\" NAME=\"list_button\" VALUE=\"%s\">\n", _("List users"));
510 wprintf("<INPUT TYPE=\"submit\" NAME=\"exit_button\" VALUE=\"%s\">\n", _("Exit"));
511 wprintf("</FORM>\n");
513 wprintf("</BODY></HTML>\n");