]> code.citadel.org Git - citadel.git/blob - webcit/messages.c
* Started moving all of the global variables into a struct, to facilitate
[citadel.git] / webcit / messages.c
1 #include <stdlib.h>
2 #include <unistd.h>
3 #include <stdio.h>
4 #include <ctype.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <time.h>
8 #include "webcit.h"
9 #include "child.h"
10
11 char reply_to[512];
12 long msgarr[1024];
13
14 /*
15  * Look for URL's embedded in a buffer and make them linkable.  We use a
16  * target window in order to keep the BBS session in its own window.
17  */
18 void url(buf)
19 char buf[];
20 {
21
22         int pos;
23         int start, end;
24         char ench;
25         char urlbuf[256];
26         char outbuf[1024];
27
28         start = (-1);
29         end = strlen(buf);
30         ench = 0;
31
32         for (pos = 0; pos < strlen(buf); ++pos) {
33                 if (!strncasecmp(&buf[pos], "http://", 7))
34                         start = pos;
35                 if (!strncasecmp(&buf[pos], "ftp://", 6))
36                         start = pos;
37         }
38
39         if (start < 0)
40                 return;
41
42         if ((start > 0) && (buf[start - 1] == '<'))
43                 ench = '>';
44         if ((start > 0) && (buf[start - 1] == '['))
45                 ench = ']';
46         if ((start > 0) && (buf[start - 1] == '('))
47                 ench = ')';
48         if ((start > 0) && (buf[start - 1] == '{'))
49                 ench = '}';
50
51         for (pos = strlen(buf); pos > start; --pos) {
52                 if ((buf[pos] == ' ') || (buf[pos] == ench))
53                         end = pos;
54         }
55
56         strncpy(urlbuf, &buf[start], end - start);
57         urlbuf[end - start] = 0;
58
59
60         strncpy(outbuf, buf, start);
61         sprintf(&outbuf[start], "%cA HREF=%c%s%c TARGET=%c%s%c%c%s%c/A%c",
62                 LB, QU, urlbuf, QU, QU, TARGET, QU, RB, urlbuf, LB, RB);
63         strcat(outbuf, &buf[end]);
64         if ( strlen(outbuf) < 250 )
65                 strcpy(buf, outbuf);
66 }
67
68
69 void read_message(msgnum, oper)
70 long msgnum;
71 char *oper;
72 {
73         char buf[256];
74         char m_subject[256];
75         char from[256];
76         long now;
77         struct tm *tm;
78         int format_type = 0;
79         int nhdr = 0;
80         int bq = 0;
81
82         sprintf(buf, "MSG0 %ld", msgnum);
83         serv_puts(buf);
84         serv_gets(buf);
85         if (buf[0] != '1') {
86                 wprintf("<STRONG>ERROR:</STRONG> %s<BR>\n", &buf[4]);
87                 return;
88         }
89         wprintf("<TABLE WIDTH=100% BORDER=0 CELLSPACING=0 CELLPADDING=0 BGCOLOR=000077><TR><TD>\n");
90         wprintf("<FONT FACE=\"Arial,Helvetica,sans-serif\" SIZE=+1 COLOR=\"FFFF00\"> ");
91         strcpy(m_subject, "");
92
93         strcpy(reply_to, "nobody...xxxxx");
94         while (serv_gets(buf), strncasecmp(buf, "text", 4)) {
95                 if (!strncasecmp(buf, "nhdr=yes", 8))
96                         nhdr = 1;
97                 if (nhdr == 1)
98                         buf[0] = '_';
99                 if (!strncasecmp(buf, "type=", 5))
100                         format_type = atoi(&buf[5]);
101                 if (!strncasecmp(buf, "from=", 5)) {
102                         wprintf("from %s ", &buf[5]);
103                         strcpy(from, &buf[5]);
104                 }
105                 if (!strncasecmp(buf, "path=", 5))
106                         strcpy(reply_to, &buf[5]);
107                 if (!strncasecmp(buf, "subj=", 5))
108                         strcpy(m_subject, &buf[5]);
109                 if ((!strncasecmp(buf, "hnod=", 5))
110                     && (strcasecmp(&buf[5], serv_info.serv_humannode)))
111                         wprintf("(%s) ", &buf[5]);
112                 if ((!strncasecmp(buf, "room=", 5))
113                     && (strcasecmp(&buf[5], WC->wc_roomname)))
114                         wprintf("in %s> ", &buf[5]);
115
116                 if (!strncasecmp(buf, "node=", 5)) {
117                         if ((WC->room_flags & QR_NETWORK)
118                         || ((strcasecmp(&buf[5], serv_info.serv_nodename)
119                         && (strcasecmp(&buf[5], serv_info.serv_fqdn))))) {
120                                 wprintf("@%s ", &buf[5]);
121                         }
122                         if ((!strcasecmp(&buf[5], serv_info.serv_nodename))
123                         || (!strcasecmp(&buf[5], serv_info.serv_fqdn))) {
124                                 strcpy(reply_to, from);
125                         } else if (haschar(&buf[5], '.') == 0) {
126                                 sprintf(reply_to, "%s @ %s", from, &buf[5]);
127                         }
128                 }
129                 if (!strncasecmp(buf, "rcpt=", 5))
130                         wprintf("to %s ", &buf[5]);
131                 if (!strncasecmp(buf, "time=", 5)) {
132                         now = atol(&buf[5]);
133                         tm = (struct tm *) localtime(&now);
134                         strcpy(buf, (char *) asctime(tm));
135                         buf[strlen(buf) - 1] = 0;
136                         strcpy(&buf[16], &buf[19]);
137                         wprintf("%s ", &buf[4]);
138                 }
139         }
140
141         if (nhdr == 1)
142                 wprintf("****");
143         wprintf("</FONT></TD>");
144
145         if (WC->is_room_aide) {
146                 wprintf("<TD ALIGN=RIGHT NOWRAP><FONT FACE=\"Arial,Helvetica,sans-serif\" COLOR=\"FFFF00\"><B>");
147
148                 wprintf("<A HREF=\"/confirm_move_msg");
149                 wprintf("&msgid=%ld", msgnum);
150                 wprintf("\">Move</A>");
151
152                 wprintf("&nbsp;&nbsp;");
153
154                 wprintf("<A HREF=\"/confirm_delete_msg");
155                 wprintf("&msgid=%ld", msgnum);
156                 wprintf("\">Del</A>");
157
158                 wprintf("</B></FONT></TD>");
159         }
160         wprintf("</TR></TABLE>\n");
161
162         if (strlen(m_subject) > 0) {
163                 wprintf("Subject: %s<BR>\n", m_subject);
164         }
165         if (format_type == 0) {
166                 fmout(NULL);
167         } else {
168                 while (serv_gets(buf), strcmp(buf, "000")) {
169                         while ((strlen(buf) > 0) && (isspace(buf[strlen(buf) - 1])))
170                                 buf[strlen(buf) - 1] = 0;
171                         if ((bq == 0) &&
172                             ((!strncmp(buf, ">", 1)) || (!strncmp(buf, " >", 2)) || (!strncmp(buf, " :-)", 4)))) {
173                                 wprintf("<FONT FACE=\"Arial,Helvetica,sans-serif\" COLOR=\"000044\"><I>");
174                                 bq = 1;
175                         } else if ((bq == 1) &&
176                                    (strncmp(buf, ">", 1)) && (strncmp(buf, " >", 2)) && (strncmp(buf, " :-)", 4))) {
177                                 wprintf("</FONT></I>");
178                                 bq = 0;
179                         }
180                         wprintf("<TT>");
181                         url(buf);
182                         escputs(buf);
183                         wprintf("</TT><BR>\n");
184                 }
185         }
186         wprintf("</I><BR>");
187 }
188
189
190
191 /* 
192  * load message pointers from the server
193  */
194 int load_msg_ptrs(servcmd)
195 char *servcmd;
196 {
197         char buf[256];
198         int nummsgs;
199
200         nummsgs = 0;
201         serv_puts(servcmd);
202         serv_gets(buf);
203         if (buf[0] != '1') {
204                 wprintf("<EM>%s</EM><BR>\n", &buf[4]);
205                 return (nummsgs);
206         }
207         while (serv_gets(buf), strcmp(buf, "000")) {
208                 msgarr[nummsgs] = atol(buf);
209                 ++nummsgs;
210         }
211         return (nummsgs);
212 }
213
214
215 /*
216  * command loop for reading messages
217  */
218 void readloop(char *oper)
219 {
220         char cmd[256];
221         int a;
222         int nummsgs;
223
224         printf("HTTP/1.0 200 OK\n");
225         output_headers(1);
226
227         wprintf("<FONT FACE=\"Arial,Helvetica,sans-serif\"><CENTER><B>%s - ", WC->wc_roomname);
228         if (!strcmp(oper, "readnew")) {
229                 strcpy(cmd, "MSGS NEW");
230                 wprintf("new messages");
231         } else if (!strcmp(oper, "readold")) {
232                 strcpy(cmd, "MSGS OLD");
233                 wprintf("old messages");
234         } else {
235                 strcpy(cmd, "MSGS ALL");
236                 wprintf("all messages");
237         }
238         wprintf("</B></CENTER><BR>\n");
239
240         nummsgs = load_msg_ptrs(cmd);
241         if (nummsgs == 0) {
242                 if (!strcmp(oper, "readnew")) {
243                         wprintf("<EM>No new messages in this room.</EM>\n");
244                 } else if (!strcmp(oper, "readold")) {
245                         wprintf("<EM>No old messages in this room.</EM>\n");
246                 } else {
247                         wprintf("<EM>This room is empty.</EM>\n");
248                 }
249                 goto DONE;
250         }
251         for (a = 0; a < nummsgs; ++a) {
252                 read_message(msgarr[a], oper);
253         }
254
255       DONE:wDumpContent(1);
256 }
257
258
259
260
261 /*
262  * Post message (or don't post message)
263  *
264  * Note regarding the "dont_post" variable:
265  * A random value (actually, it's just a timestamp) is inserted as a hidden
266  * field called "postseq" when the display_enter page is generated.  This
267  * value is checked when posting, using the static variable dont_post.  If a
268  * user attempts to post twice using the same dont_post value, the message is
269  * discarded.  This prevents the accidental double-saving of the same message
270  * if the user happens to click the browser "back" button.
271  */
272 void post_message(void)
273 {
274         char buf[256];
275         static long dont_post = (-1L);
276
277         printf("HTTP/1.0 200 OK\n");
278         output_headers(1);
279
280         wprintf("<FONT FACE=\"Arial,Helvetica,sans-serif\">");
281         strcpy(buf, bstr("sc"));
282         if (strcasecmp(buf, "Save message")) {
283                 wprintf("Cancelled.  Message was not posted.<BR>\n");
284         } else if (atol(bstr("postseq")) == dont_post) {
285                 wprintf("Automatically cancelled because you have already "
286                         "saved this message.<BR>\n");
287         } else {
288                 sprintf(buf, "ENT0 1|%s|0|0", bstr("recp"));
289                 serv_puts(buf);
290                 serv_gets(buf);
291                 if (buf[0] == '4') {
292                         text_to_server(bstr("msgtext"));
293                         serv_puts("000");
294                         wprintf("Message has been posted.<BR>\n");
295                         dont_post = atol(bstr("postseq"));
296                 } else {
297                         wprintf("<EM>%s</EM><BR>\n", &buf[4]);
298                 }
299         }
300
301         wDumpContent(1);
302 }
303
304
305
306
307
308
309
310
311 /*
312  * prompt for a recipient (to be called from display_enter() only)
313  */
314 void prompt_for_recipient()
315 {
316
317         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=007700><TR><TD>");
318         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
319         wprintf("<B>Send private e-mail</B>\n");
320         wprintf("</FONT></TD></TR></TABLE>\n");
321
322         wprintf("<CENTER>");
323         wprintf("<FORM METHOD=\"POST\" ACTION=\"/display_enter\">\n");
324         wprintf("Enter recipient: ");
325         wprintf("<INPUT TYPE=\"text\" NAME=\"recp\" MAXLENGTH=\"64\"><BR>\n");
326         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Enter message\">");
327         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
328         wprintf("</FORM></CENTER>\n");
329 }
330
331
332
333 /*
334  * display the message entry screen
335  */
336 void display_enter(void)
337 {
338         char buf[256];
339         long now;
340         struct tm *tm;
341
342         printf("HTTP/1.0 200 OK\n");
343         output_headers(1);
344
345         wprintf("<FACE=\"Arial,Helvetica,sans-serif\">");
346
347         sprintf(buf, "ENT0 0|%s|0|0", bstr("recp"));
348         serv_puts(buf);
349         serv_gets(buf);
350
351         if (!strncmp(buf, "570", 3)) {
352                 if (strlen(bstr("recp")) > 0) {
353                         wprintf("<EM>%s</EM><BR>\n", &buf[4]);
354                 }
355                 prompt_for_recipient();
356                 goto DONE;
357         }
358         if (buf[0] != '2') {
359                 wprintf("<EM>%s</EM><BR>\n", &buf[4]);
360                 goto DONE;
361         }
362         wprintf("<CENTER>Enter message below.  Messages are formatted to\n");
363         wprintf("the <EM>reader's</EM> screen width.  To defeat the\n");
364         wprintf("formatting, indent a line at least one space.  \n");
365         wprintf("<BR>");
366
367         now = time(NULL);
368         tm = (struct tm *) localtime(&now);
369         strcpy(buf, (char *) asctime(tm));
370         buf[strlen(buf) - 1] = 0;
371         strcpy(&buf[16], &buf[19]);
372         wprintf("</CENTER><FONT COLOR=\"440000\"><B> %s ", &buf[4]);
373         wprintf("from %s ", WC->wc_username);
374         if (strlen(bstr("recp")) > 0)
375                 wprintf("to %s ", bstr("recp"));
376         wprintf("in %s&gt; ", WC->wc_roomname);
377         wprintf("</B></FONT><BR><CENTER>\n");
378
379         wprintf("<FORM METHOD=\"POST\" ACTION=\"/post\">\n");
380         wprintf("<INPUT TYPE=\"hidden\" NAME=\"recp\" VALUE=\"%s\">\n",
381                 bstr("recp"));
382         wprintf("<INPUT TYPE=\"hidden\" NAME=\"postseq\" VALUE=\"%ld\">\n",
383                 now);
384         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Save message\">"
385                 "<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\"><BR>\n");
386
387         wprintf("<TEXTAREA NAME=\"msgtext\" wrap=soft ROWS=30 COLS=80 "
388                 "WIDTH=80></TEXTAREA><P>\n");
389
390         wprintf("</FORM></CENTER>\n");
391 DONE:   wDumpContent(1);
392         wprintf("</FONT>");
393 }
394
395
396
397
398
399
400
401
402 /*
403  * Confirm deletion of a message
404  */
405 void confirm_delete_msg(void)
406 {
407         long msgid;
408
409         msgid = atol(bstr("msgid"));
410
411         printf("HTTP/1.0 200 OK\n");
412         output_headers(1);
413
414         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
415         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
416         wprintf("<B>Confirm deletion of message</B>\n");
417         wprintf("</FONT></TD></TR></TABLE>\n");
418
419         wprintf("<CENTER>");
420
421         wprintf("Are you sure you want to delete this message? <BR>\n");
422
423         wprintf("<FORM METHOD=\"POST\" ACTION=\"/delete_msg\">\n");
424         wprintf("<INPUT TYPE=\"hidden\" NAME=\"msgid\" VALUE=\"%s\">\n",
425                 bstr("msgid"));
426         wprintf("<INPUT TYPE=\"submit\" NAME=\"yesno\" VALUE=\"Yes\">");
427         wprintf("<INPUT TYPE=\"submit\" NAME=\"yesno\" VALUE=\"No\">");
428         wprintf("</FORM></CENTER>\n");
429
430         wprintf("</CENTER>\n");
431         wDumpContent(1);
432 }
433
434
435
436 void delete_msg(void)
437 {
438         long msgid;
439         char buf[256];
440
441         msgid = atol(bstr("msgid"));
442
443         printf("HTTP/1.0 200 OK\n");
444         output_headers(1);
445
446         if (!strcasecmp(bstr("yesno"), "Yes")) {
447                 sprintf(buf, "DELE %ld", msgid);
448                 serv_puts(buf);
449                 serv_gets(buf);
450                 wprintf("<EM>%s</EM><BR>\n", &buf[4]);
451         } else {
452                 wprintf("<EM>Message not deleted.</EM><BR>\n");
453         }
454
455         wDumpContent(1);
456 }
457
458
459
460
461 /*
462  * Confirm move of a message
463  */
464 void confirm_move_msg(void)
465 {
466         long msgid;
467         char buf[256];
468         char targ[256];
469
470         msgid = atol(bstr("msgid"));
471
472         printf("HTTP/1.0 200 OK\n");
473         output_headers(1);
474
475         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
476         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
477         wprintf("<B>Confirm move of message</B>\n");
478         wprintf("</FONT></TD></TR></TABLE>\n");
479
480         wprintf("<CENTER>");
481
482         wprintf("Please select the room to which you would like this message moved:<BR>\n");
483
484         wprintf("<FORM METHOD=\"POST\" ACTION=\"/move_msg\">\n");
485         wprintf("<INPUT TYPE=\"hidden\" NAME=\"msgid\" VALUE=\"%s\">\n",
486                 bstr("msgid"));
487
488
489         wprintf("<SELECT NAME=\"target_room\" SIZE=5>\n");
490         serv_puts("LKRA");
491         serv_gets(buf);
492         if (buf[0] == '1') {
493                 while (serv_gets(buf), strcmp(buf, "000")) {
494                         extract(targ, buf, 0);
495                         wprintf("<OPTION>");
496                         escputs(targ);
497                         wprintf("\n");
498                 }
499         }
500         wprintf("</SELECT>\n");
501         wprintf("<BR>\n");
502
503         wprintf("<INPUT TYPE=\"submit\" NAME=\"yesno\" VALUE=\"Move\">");
504         wprintf("<INPUT TYPE=\"submit\" NAME=\"yesno\" VALUE=\"Cancel\">");
505         wprintf("</FORM></CENTER>\n");
506
507         wprintf("</CENTER>\n");
508         wDumpContent(1);
509 }
510
511
512
513 void move_msg(void)
514 {
515         long msgid;
516         char buf[256];
517
518         msgid = atol(bstr("msgid"));
519
520         printf("HTTP/1.0 200 OK\n");
521         output_headers(1);
522
523         if (!strcasecmp(bstr("yesno"), "Move")) {
524                 sprintf(buf, "MOVE %ld|%s", msgid, bstr("target_room"));
525                 serv_puts(buf);
526                 serv_gets(buf);
527                 wprintf("<EM>%s</EM><BR>\n", &buf[4]);
528         } else {
529                 wprintf("<EM>Message not deleted.</EM><BR>\n");
530         }
531
532         wDumpContent(1);
533 }