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