* Replaced the Java chat with a new system based on IFRAME's and JavaScript
[citadel.git] / webcit / paging.c
1 /* $Id$ */
2
3 #include <ctype.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <stdio.h>
7 #include <fcntl.h>
8 #include <signal.h>
9 #include <sys/types.h>
10 #include <sys/wait.h>
11 #include <sys/socket.h>
12 #include <sys/poll.h>
13 #include <sys/time.h>
14 #include <limits.h>
15 #include <netinet/in.h>
16 #include <netdb.h>
17 #include <string.h>
18 #include <pwd.h>
19 #include <errno.h>
20 #include <stdarg.h>
21 #include <pthread.h>
22 #include <signal.h>
23 #include "webcit.h"
24
25
26 /*
27  * display the form for paging (x-messaging) another user
28  */
29 void display_page(void)
30 {
31         char recp[SIZ];
32
33         strcpy(recp, bstr("recp"));
34
35         output_headers(3);
36
37         svprintf("BOXTITLE", WCS_STRING, "Page: %s", recp);
38         do_template("beginbox");
39
40         wprintf("<FORM METHOD=\"POST\" ACTION=\"/page_user\">\n");
41
42         wprintf("<TABLE border=0 width=100%%><TR><TD>\n");
43
44         wprintf("<INPUT TYPE=\"hidden\" NAME=\"recp\" VALUE=\"");
45         escputs(recp);
46         wprintf("\">\n");
47
48         wprintf("<INPUT TYPE=\"hidden\" NAME=\"closewin\" VALUE=\"");
49         escputs(bstr("closewin"));
50         wprintf("\">\n");
51
52         wprintf("Enter message text:<BR>");
53
54         wprintf("<TEXTAREA NAME=\"msgtext\" wrap=soft ROWS=5 COLS=40 "
55                 "WIDTH=40></TEXTAREA>\n");
56
57         wprintf("</TD></TR></TABLE><BR>\n");
58
59         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Send message\">");
60         wprintf("<BR><A HREF=\"javascript:window.close();\"Cancel</A>\n");
61
62         wprintf("</FORM></CENTER>\n");
63         do_template("endbox");
64         wDumpContent(1);
65 }
66
67 /*
68  * page another user
69  */
70 void page_user(void)
71 {
72         char recp[SIZ];
73         char sc[SIZ];
74         char buf[SIZ];
75         char closewin[SIZ];
76
77         output_headers(3);
78
79         strcpy(recp, bstr("recp"));
80         strcpy(sc, bstr("sc"));
81         strcpy(closewin, bstr("closewin"));
82
83         if (strcmp(sc, "Send message")) {
84                 wprintf("<EM>Message was not sent.</EM><BR>\n");
85         } else {
86                 serv_printf("SEXP %s|-", recp);
87                 serv_gets(buf);
88
89                 if (buf[0] == '4') {
90                         text_to_server(bstr("msgtext"), 0);
91                         serv_puts("000");
92                         wprintf("<EM>Message has been sent to ");
93                         escputs(recp);
94                         wprintf(".</EM><BR>\n");
95                 }
96                 else {
97                         wprintf("<EM>%s</EM><BR>\n", &buf[4]);
98                 }
99         }
100         
101         if (!strcasecmp(closewin, "yes")) {
102                 wprintf("<CENTER><A HREF=\"javascript:window.close();\">"
103                         "[ close window ]</A></CENTER>\n");
104         }
105
106         wDumpContent(1);
107 }
108
109
110
111 /*
112  * multiuser chat
113  */
114 void do_chat(void)
115 {
116
117         output_headers(1);
118
119         wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#000077\"><TR><TD>"
120                 "<SPAN CLASS=\"titlebar\">Real-time chat</SPAN>\n"
121                 "</TD></TR></TABLE>\n"
122                 "<IFRAME WIDTH=100%% HEIGHT=200 SRC=\"/chat_recv\" "
123                 "NAME=\"chat_recv\">\n"
124                 "<!-- Alternate content for non-supporting browsers -->\n"
125                 "If you are seeing this message, your browser does not contain\n"
126                 "the IFRAME support required for the chat window.  Please upgrade\n"
127                 "to a supported browser, such as\n"
128                 "<A HREF=\"http://www.mozilla.org\">Mozilla</A>.\n"
129                 "</IFRAME>\n"
130                 "<HR width=100%%>\n"
131                 "<IFRAME WIDTH=100%% HEIGHT=50 SRC=\"/chat_send\" "
132                 "NAME=\"chat_send\">\n"
133                 "</IFRAME>\n"
134         );
135         wDumpContent(1);
136 }
137
138
139 /*
140  *
141  */
142 void page_popup(void)
143 {
144         char buf[SIZ];
145         char pagefrom[SIZ];
146
147         /* suppress express message check, do headers but no frames */
148         output_headers(0x08 | 0x03);
149
150         while (serv_puts("GEXP"), serv_gets(buf), buf[0]=='1') {
151
152                 extract(pagefrom, &buf[4], 3);
153
154                 wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#007700\"><TR><TD>");
155                 wprintf("<SPAN CLASS=\"titlebar\">Instant message from ");
156                 escputs(pagefrom);
157                 wprintf("</SPAN></TD></TR></TABLE>\n");
158                 
159                 fmout(NULL, "LEFT");
160         }
161
162         wprintf("<CENTER>");
163         wprintf("<A HREF=\"/display_page&closewin=yes&recp=");
164         urlescputs(pagefrom);
165         wprintf("\">[ reply ]</A>&nbsp;&nbsp;&nbsp;\n");
166
167         wprintf("<A HREF=\"javascript:window.close();\">"
168                 "[ close window ]</A></B>\n"
169                 "</CENTER>");
170
171         wDumpContent(1);
172         WC->HaveExpressMessages = 0;
173 }
174
175
176
177 /*
178  * Support function for chat -- make sure the chat socket is connected
179  * and in chat mode.
180  */
181 int setup_chat_socket(void) {
182         char buf[SIZ];
183         int i;
184         int good_chatmode = 0;
185
186         if (WC->chat_sock < 0) {
187
188                 for (i=0; i<CHATLINES; ++i) {
189                         strcpy(WC->chatlines[i], "");
190                 }
191
192                 if (!strcasecmp(ctdlhost, "uds")) {
193                         /* unix domain socket */
194                         sprintf(buf, "%s/citadel.socket", ctdlport);
195                         WC->chat_sock = uds_connectsock(buf);
196                 }
197                 else {
198                         /* tcp socket */
199                         WC->chat_sock = tcp_connectsock(ctdlhost, ctdlport);
200                 }
201
202                 if (WC->chat_sock < 0) {
203                         return(errno);
204                 }
205
206                 /* Temporarily swap the serv and chat sockets during chat talk */
207                 i = WC->serv_sock;
208                 WC->serv_sock = WC->chat_sock;
209                 WC->chat_sock = i;
210
211                 serv_gets(buf);
212                 if (buf[0] == '2') {
213                         serv_printf("USER %s", WC->wc_username);
214                         serv_gets(buf);
215                         if (buf[0] == '3') {
216                                 serv_printf("PASS %s", WC->wc_password);
217                                 serv_gets(buf);
218                                 if (buf[0] == '2') {
219                                         serv_printf("GOTO %s", WC->wc_roomname);
220                                         serv_gets(buf);
221                                         if (buf[0] == '2') {
222                                                 serv_puts("CHAT");
223                                                 serv_gets(buf);
224                                                 if (buf[0] == '8') {
225                                                         good_chatmode = 1;
226                                                 }
227                                         }
228                                 }
229                         }
230                 }
231
232                 /* Unswap the sockets. */
233                 i = WC->serv_sock;
234                 WC->serv_sock = WC->chat_sock;
235                 WC->chat_sock = i;
236
237                 if (!good_chatmode) close(WC->serv_sock);
238
239         }
240         return(0);
241 }
242
243
244
245 /*
246  * receiving side of the chat window
247  */
248 void chat_recv(void) {
249         int i;
250         char name[SIZ];
251         char text[SIZ];
252         struct pollfd pf;
253         int got_data = 0;
254         int end_chat_now = 0;
255
256         output_headers(0);
257
258         wprintf("Content-type: text/html\n");
259         wprintf("\n");
260         wprintf("<HTML>\n"
261                 "<HEAD>\n"
262                 "<META HTTP-EQUIV=\"refresh\" CONTENT=\"3\">\n"
263                 "</HEAD>\n"
264                 "<BODY>"
265         );
266
267         if (setup_chat_socket() != 0) {
268                 wprintf("Error setting up chat socket</BODY></HTML>\n");
269                 wDumpContent(0);
270                 return;
271         }
272
273         /*
274          * See if there is any chat data waiting.
275          */
276         do {
277                 got_data = 0;
278                 pf.fd = WC->chat_sock;
279                 pf.events = POLLIN;
280                 pf.revents = 0;
281                 if (poll(&pf, 1, 1) > 0) if (pf.revents & POLLIN) {
282                         ++got_data;
283
284                         for (i=0; i<CHATLINES-1; ++i) {
285                                 strcpy(WC->chatlines[i], WC->chatlines[i+1]);
286                         }
287         
288                         /* Temporarily swap the serv and chat sockets during chat talk */
289                         i = WC->serv_sock;
290                         WC->serv_sock = WC->chat_sock;
291                         WC->chat_sock = i;
292         
293                         serv_gets(WC->chatlines[CHATLINES-1]);
294                         if (!strcmp(WC->chatlines[CHATLINES-1], "000")) {
295                                 end_chat_now = 1;
296                                 strcpy(WC->chatlines[CHATLINES-1], ":|exiting chat mode");
297                         }
298                         
299                         /* Unswap the sockets. */
300                         i = WC->serv_sock;
301                         WC->serv_sock = WC->chat_sock;
302                         WC->chat_sock = i;
303                 }
304         } while ( (got_data) && (!end_chat_now) );
305
306         /*
307          * Display appropriately.
308          */
309         for (i=0; i<CHATLINES; ++i) {
310                 if (strlen(WC->chatlines[i]) > 0) {
311                         extract(name, WC->chatlines[i], 0);
312                         extract(text, WC->chatlines[i], 1);
313                         if (!strcasecmp(name, WC->wc_username)) {
314                                 wprintf("<FONT COLOR=\"#00FF00\">");
315                         }
316                         else if (!strcmp(name, ":")) {
317                                 wprintf("<FONT COLOR=\"#FF0000\">");
318                         }
319                         else {
320                                 wprintf("<FONT COLOR=\"#0000FF\">");
321                         }
322                         escputs(name);
323                         wprintf(": </FONT>");
324                         escputs(text);
325                         wprintf("<BR>\n");
326                 }
327         }
328
329         if (end_chat_now) {
330                 close(WC->chat_sock);
331                 WC->chat_sock = (-1);
332                 wprintf("<IMG SRC=\"/static/blank.gif\" onLoad=\"top.location.replace('/do_welcome');\">\n");
333         }
334
335         wprintf("</BODY></HTML>\n");
336         wDumpContent(0);
337 }
338
339
340 /*
341  * sending side of the chat window
342  */
343 void chat_send(void) {
344         int i;
345         char send_this[SIZ];
346
347         output_headers(0);
348         wprintf("Content-type: text/html\n");
349         wprintf("\n");
350         wprintf("<HTML>"
351                 "<BODY onLoad=\"document.chatsendform.send_this.focus();\" >"
352         );
353
354         if (bstr("send_this") != NULL) {
355                 strcpy(send_this, bstr("send_this"));
356         }
357         else {
358                 strcpy(send_this, "");
359         }
360
361         if (bstr("sendbutton") != NULL) {
362
363                 if (!strcasecmp(bstr("sendbutton"), "Exit")) {
364                         strcpy(send_this, "/quit");
365                 }
366
367                 if (setup_chat_socket() != 0) {
368                         wprintf("Error setting up chat socket</BODY></HTML>\n");
369                         wDumpContent(0);
370                         return;
371                 }
372
373                 /* Temporarily swap the serv and chat sockets during chat talk */
374                 i = WC->serv_sock;
375                 WC->serv_sock = WC->chat_sock;
376                 WC->chat_sock = i;
377
378                 serv_puts(send_this);
379
380                 /* Unswap the sockets. */
381                 i = WC->serv_sock;
382                 WC->serv_sock = WC->chat_sock;
383                 WC->chat_sock = i;
384
385         }
386
387         wprintf("Send: ");
388         wprintf("<FORM METHOD=\"POST\" ACTION=\"/chat_send\" NAME=\"chatsendform\">\n");
389         wprintf("<INPUT TYPE=\"text\" SIZE=\"80\" MAXLENGTH=\"80\" NAME=\"send_this\">\n");
390         wprintf("<INPUT TYPE=\"submit\" NAME=\"sendbutton\" VALUE=\"Send\">\n");
391         wprintf("<INPUT TYPE=\"submit\" NAME=\"sendbutton\" VALUE=\"Exit\">\n");
392         wprintf("</FORM>\n");
393
394         wprintf("</BODY></HTML>\n");
395         wDumpContent(0);
396 }
397
398