]> code.citadel.org Git - citadel.git/blob - webcit/roomops.c
1ea8b5e833dcc45f2293cabacfbfbf874445ee24
[citadel.git] / webcit / roomops.c
1 /* $Id$ */
2
3 #include <stdlib.h>
4 #include <string.h>
5 #ifdef HAVE_UNISTD_H
6 #include <unistd.h>
7 #endif
8 #include <stdio.h>
9 #include <signal.h>
10 #include <sys/types.h>
11 #include "webcit.h"
12 #include "child.h"
13
14 /*
15  * This struct holds a list of rooms for <G>oto operations.
16  */
17 struct march {
18         struct march *next;
19         char march_name[32];
20         int march_floor;
21         int march_order;
22 };
23
24 /* 
25  * This struct holds a list of rooms for client display.
26  * (oooh, a tree!)
27  */
28 struct roomlisting {
29         struct roomlisting *lnext;
30         struct roomlisting *rnext;
31         char rlname[64];
32         unsigned rlflags;
33         int rlfloor;
34         int rlorder;
35 };
36
37
38 char floorlist[128][256];
39 char ugname[128];
40 long uglsn = (-1L);
41 unsigned room_flags;
42 int is_aide = 0;
43 int is_room_aide = 0;
44
45 struct march *march = NULL;
46
47 /*
48  * load the list of floors
49  */
50 void load_floorlist(void)
51 {
52         int a;
53         char buf[256];
54
55         for (a = 0; a < 128; ++a)
56                 floorlist[a][0] = 0;
57
58         serv_puts("LFLR");
59         serv_gets(buf);
60         if (buf[0] != '1') {
61                 strcpy(floorlist[0], "Main Floor");
62                 return;
63         }
64         while (serv_gets(buf), strcmp(buf, "000")) {
65                 extract(floorlist[extract_int(buf, 0)], buf, 1);
66         }
67 }
68
69
70 /*
71  * remove a room from the march list
72  */
73 void remove_march(char *aaa)
74 {
75         struct march *mptr, *mptr2;
76
77         if (march == NULL)
78                 return;
79
80         if (!strcasecmp(march->march_name, aaa)) {
81                 mptr = march->next;
82                 free(march);
83                 march = mptr;
84                 return;
85         }
86         mptr2 = march;
87         for (mptr = march; mptr != NULL; mptr = mptr->next) {
88                 if (!strcasecmp(mptr->march_name, aaa)) {
89                         mptr2->next = mptr->next;
90                         free(mptr);
91                         mptr = mptr2;
92                 } else {
93                         mptr2 = mptr;
94                 }
95         }
96 }
97
98
99
100
101
102 void room_tree_list(struct roomlisting *rp)
103 {
104         char rmname[64];
105         int f;
106
107         if (rp == NULL)
108                 return;
109
110         if (rp->lnext != NULL) {
111                 room_tree_list(rp->lnext);
112         }
113         strcpy(rmname, rp->rlname);
114         f = rp->rlflags;
115
116         wprintf("<A HREF=\"/dotgoto&room=");
117         urlescputs(rmname);
118         wprintf("\" TARGET=\"top\">");
119         escputs1(rmname, 1);
120         if ((f & QR_DIRECTORY) && (f & QR_NETWORK))
121                 wprintf("}");
122         else if (f & QR_DIRECTORY)
123                 wprintf("]");
124         else if (f & QR_NETWORK)
125                 wprintf(")");
126         else
127                 wprintf("&gt;");
128         wprintf("</A><TT> </TT>\n");
129
130         if (rp->rnext != NULL) {
131                 room_tree_list(rp->rnext);
132         }
133         free(rp);
134 }
135
136
137 /* 
138  * Room ordering stuff (compare first by floor, then by order)
139  */
140 int rordercmp(struct roomlisting *r1, struct roomlisting *r2)
141 {
142         if ((r1 == NULL) && (r2 == NULL))
143                 return (0);
144         if (r1 == NULL)
145                 return (-1);
146         if (r2 == NULL)
147                 return (1);
148         if (r1->rlfloor < r2->rlfloor)
149                 return (-1);
150         if (r1->rlfloor > r2->rlfloor)
151                 return (1);
152         if (r1->rlorder < r2->rlorder)
153                 return (-1);
154         if (r1->rlorder > r2->rlorder)
155                 return (1);
156         return (0);
157 }
158
159
160 /*
161  * Common code for all room listings
162  */
163 void listrms(char *variety)
164 {
165         char buf[256];
166         int num_rooms = 0;
167
168         struct roomlisting *rl = NULL;
169         struct roomlisting *rp;
170         struct roomlisting *rs;
171
172
173         /* Ask the server for a room list */
174         serv_puts(variety);
175         serv_gets(buf);
176         if (buf[0] != '1') {
177                 wprintf("&nbsp;");
178                 return;
179         }
180         while (serv_gets(buf), strcmp(buf, "000")) {
181                 ++num_rooms;
182                 rp = malloc(sizeof(struct roomlisting));
183                 extract(rp->rlname, buf, 0);
184                 rp->rlflags = extract_int(buf, 1);
185                 rp->rlfloor = extract_int(buf, 2);
186                 rp->rlorder = extract_int(buf, 3);
187                 rp->lnext = NULL;
188                 rp->rnext = NULL;
189
190                 rs = rl;
191                 if (rl == NULL) {
192                         rl = rp;
193                 } else
194                         while (rp != NULL) {
195                                 if (rordercmp(rp, rs) < 0) {
196                                         if (rs->lnext == NULL) {
197                                                 rs->lnext = rp;
198                                                 rp = NULL;
199                                         } else {
200                                                 rs = rs->lnext;
201                                         }
202                                 } else {
203                                         if (rs->rnext == NULL) {
204                                                 rs->rnext = rp;
205                                                 rp = NULL;
206                                         } else {
207                                                 rs = rs->rnext;
208                                         }
209                                 }
210                         }
211         }
212
213         room_tree_list(rl);
214
215         /* If no rooms were listed, print an nbsp to make the cell
216          * borders show up anyway.
217          */
218         if (num_rooms == 0) wprintf("&nbsp;");
219 }
220
221
222
223
224
225
226
227
228
229 /*
230  * list all rooms by floor
231  */
232 void list_all_rooms_by_floor(void)
233 {
234         int a;
235         char buf[256];
236
237         load_floorlist();
238
239         printf("HTTP/1.0 200 OK\n");
240         output_headers(1);
241
242         wprintf("<TABLE width=100% border><TR><TH>Floor</TH>");
243         wprintf("<TH><FONT FACE=\"Arial,Helvetica,sans-serif\">Rooms with new messages</FONT></TH>");
244         wprintf("<TH><FONT FACE=\"Arial,Helvetica,sans-serif\">Rooms with no new messages</FONT></TH></TR>\n");
245
246         for (a = 0; a < 128; ++a)
247                 if (floorlist[a][0] != 0) {
248
249                         /* Floor name column */
250                         wprintf("<TR><TD><FONT FACE=\"Arial,Helvetica,sans-serif\">");
251
252                         serv_printf("OIMG _floorpic_|%d", a);
253                         serv_gets(buf);
254                         if (buf[0] == '2') {
255                                 serv_puts("CLOS");
256                                 serv_gets(buf);
257                                 wprintf("<IMG SRC=\"/image&name=_floorpic_&parm=%d\" ALT=\"%s\">",
258                                         a, &floorlist[a][0]);
259                         } else {
260                                 escputs(&floorlist[a][0]);
261                         }
262
263                         wprintf("</FONT></TD>");
264
265                         /* Rooms with new messages column */
266                         wprintf("<TD><FONT FACE=\"Arial,Helvetica,sans-serif\">");
267                         sprintf(buf, "LKRN %d", a);
268                         listrms(buf);
269                         wprintf("</FONT></TD>\n<TD><FONT FACE=\"Arial,Helvetica,sans-serif\">");
270
271                         /* Rooms with old messages column */
272                         sprintf(buf, "LKRO %d", a);
273                         listrms(buf);
274                         wprintf("</FONT></TD></TR>\n");
275                 }
276         wprintf("</TABLE>\n");
277         wDumpContent(1);
278 }
279
280
281 /*
282  * list all forgotten rooms
283  */
284 void zapped_list(void)
285 {
286         printf("HTTP/1.0 200 OK\n");
287         output_headers(1);
288         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
289         wprintf("<FONT FACE=\"Arial,Helvetica,sans-serif\" SIZE=+1 COLOR=\"FFFFFF\"");
290         wprintf("<B>Zapped (forgotten) rooms</B>\n");
291         wprintf("</FONT></TD></TR></TABLE><BR>\n");
292         listrms("LZRM -1");
293         wprintf("<BR><BR>\n");
294         wprintf("Click on any room to un-zap it and goto that room.\n");
295         wDumpContent(1);
296 }
297
298
299 /*
300  * read this room's info file (set v to 1 for verbose mode)
301  */
302 void readinfo(int v)
303 {
304         char buf[256];
305
306         serv_puts("RINF");
307         serv_gets(buf);
308         if (buf[0] == '1')
309                 fmout(NULL);
310         else {
311                 if (v == 1)
312                         wprintf("<EM>%s</EM><BR>\n", &buf[4]);
313         }
314 }
315
316
317
318 void embed_room_banner(char *got) {
319         char buf[256];
320         char fakegot[256];
321
322         if (got == NULL) {
323                 serv_printf("GOTO %s", wc_roomname);
324                 serv_gets(fakegot);
325                 got = fakegot;
326         }
327
328         wprintf("<CENTER><TABLE border=0><TR>");
329
330         if ((strlen(ugname) > 0) && (strcasecmp(ugname, wc_roomname))) {
331                 wprintf("<TD VALIGN=TOP><A HREF=\"/ungoto\">");
332                 wprintf("<IMG SRC=\"/static/back.gif\" BORDER=0></A></TD>");
333         }
334         wprintf("<TD VALIGN=TOP><FONT FACE=\"Arial,Helvetica,sans-serif\"><FONT SIZE=+2>%s</FONT><BR>", wc_roomname);
335         wprintf("%d new of %d messages</FONT></TD>\n",
336                 extract_int(&got[4], 1),
337                 extract_int(&got[4], 2));
338
339         /* Display room graphic.  The server doesn't actually
340          * need the room name, but we supply it in order to
341          * keep the browser from using a cached graphic from 
342          * another room.
343          */
344         serv_puts("OIMG _roompic_");
345         serv_gets(buf);
346         if (buf[0] == '2') {
347                 wprintf("<TD><FONT FACE=\"Arial,Helvetica,sans-serif\">");
348                 wprintf("<IMG SRC=\"/image&name=_roompic_&room=");
349                 escputs(wc_roomname);
350                 wprintf("\"></FONT></TD>");
351                 serv_puts("CLOS");
352                 serv_gets(buf);
353         }
354         wprintf("<TD VALIGN=TOP><FONT FACE=\"Arial,Helvetica,sans-serif\">");
355         readinfo(0);
356         wprintf("</FONT></TD>");
357
358         wprintf("<TD VALIGN=TOP><A HREF=\"/gotonext\">");
359         wprintf("<IMG SRC=\"/static/forward.gif\" border=0></A></TD>");
360         wprintf("</TR></TABLE></CENTER>\n");
361 }
362
363
364
365
366
367 /*
368  * generic routine to take the session to a new room
369  *
370  * display_name values:  0 = goto only
371  *                       1 = goto and display
372  *                       2 = display only
373  */
374 void gotoroom(char *gname, int display_name)
375 {
376         char buf[256];
377         static long ls = (-1L);
378
379
380         if (display_name) {
381                 printf("HTTP/1.0 200 OK\n");
382                 printf("Pragma: no-cache\n");
383                 printf("Cache-Control: no-store\n");
384                 output_headers(0);
385
386                 wprintf("<HTML><HEAD></HEAD>\n<BODY ");
387
388                 /* automatically fire up a read-new-msgs in the bottom frame */
389                 if (!noframes)
390                         wprintf("onload=parent.frames.bottom.location=\"/readnew\" ");
391
392                 wprintf("BACKGROUND=\"/image&name=background\" TEXT=\"#000000\" LINK=\"#004400\">\n");
393         }
394         if (display_name != 2) {
395                 /* store ungoto information */
396                 strcpy(ugname, wc_roomname);
397                 uglsn = ls;
398         }
399         /* move to the new room */
400         serv_printf("GOTO %s", gname);
401         serv_gets(buf);
402         if (buf[0] != '2') {
403                 serv_puts("GOTO _BASEROOM_");
404                 serv_gets(buf);
405         }
406         if (buf[0] != '2') {
407                 if (display_name) {
408                         wprintf("<EM>%s</EM><BR>\n", &buf[4]);
409                         wDumpContent(1);
410                 }
411                 return;
412         }
413         extract(wc_roomname, &buf[4], 0);
414         room_flags = extract_int(&buf[4], 4);
415         /* highest_msg_read = extract_int(&buf[4],6);
416            maxmsgnum = extract_int(&buf[4],5);
417            is_mail = (char) extract_int(&buf[4],7); */
418         ls = extract_long(&buf[4], 6);
419
420         if (is_aide)
421                 is_room_aide = is_aide;
422         else
423                 is_room_aide = (char) extract_int(&buf[4], 8);
424
425         remove_march(wc_roomname);
426         if (!strcasecmp(gname, "_BASEROOM_"))
427                 remove_march(gname);
428
429         /* Display the room banner */
430         if (display_name) {
431                 embed_room_banner(buf);
432                 wDumpContent(1);
433         }
434         strcpy(wc_roomname, wc_roomname);
435 }
436
437
438 /*
439  * Locate the room on the march list which we most want to go to.  Each room
440  * is measured given a "weight" of preference based on various factors.
441  */
442 char *pop_march(int desired_floor)
443 {
444         static char TheRoom[64];
445         int TheFloor = 0;
446         int TheOrder = 32767;
447         int TheWeight = 0;
448         int weight;
449         struct march *mptr = NULL;
450
451         strcpy(TheRoom, "_BASEROOM_");
452         if (march == NULL)
453                 return (TheRoom);
454
455         for (mptr = march; mptr != NULL; mptr = mptr->next) {
456                 weight = 0;
457                 if ((strcasecmp(mptr->march_name, "_BASEROOM_")))
458                         weight = weight + 10000;
459                 if (mptr->march_floor == desired_floor)
460                         weight = weight + 5000;
461
462                 weight = weight + ((128 - (mptr->march_floor)) * 128);
463                 weight = weight + (128 - (mptr->march_order));
464
465                 if (weight > TheWeight) {
466                         TheWeight = weight;
467                         strcpy(TheRoom, mptr->march_name);
468                         TheFloor = mptr->march_floor;
469                         TheOrder = mptr->march_order;
470                 }
471         }
472         return (TheRoom);
473 }
474
475
476
477 /* Goto next room having unread messages.
478  * We want to skip over rooms that the user has already been to, and take the
479  * user back to the lobby when done.  The room we end up in is placed in
480  * newroom - which is set to 0 (the lobby) initially.
481  * We start the search in the current room rather than the beginning to prevent
482  * two or more concurrent users from dragging each other back to the same room.
483  */
484 void gotonext(void)
485 {
486         char buf[256];
487         struct march *mptr, *mptr2;
488         char next_room[32];
489
490         /* First check to see if the march-mode list is already allocated.
491          * If it is, pop the first room off the list and go there.
492          */
493
494         if (march == NULL) {
495                 serv_puts("LKRN");
496                 serv_gets(buf);
497                 if (buf[0] == '1')
498                         while (serv_gets(buf), strcmp(buf, "000")) {
499                                 mptr = (struct march *) malloc(sizeof(struct march));
500                                 mptr->next = NULL;
501                                 extract(mptr->march_name, buf, 0);
502                                 mptr->march_floor = extract_int(buf, 2);
503                                 mptr->march_order = extract_int(buf, 3);
504                                 if (march == NULL) {
505                                         march = mptr;
506                                 } else {
507                                         mptr2 = march;
508                                         while (mptr2->next != NULL)
509                                                 mptr2 = mptr2->next;
510                                         mptr2->next = mptr;
511                                 }
512                         }
513 /* add _BASEROOM_ to the end of the march list, so the user will end up
514  * in the system base room (usually the Lobby>) at the end of the loop
515  */
516                 mptr = (struct march *) malloc(sizeof(struct march));
517                 mptr->next = NULL;
518                 strcpy(mptr->march_name, "_BASEROOM_");
519                 if (march == NULL) {
520                         march = mptr;
521                 } else {
522                         mptr2 = march;
523                         while (mptr2->next != NULL)
524                                 mptr2 = mptr2->next;
525                         mptr2->next = mptr;
526                 }
527 /*
528  * ...and remove the room we're currently in, so a <G>oto doesn't make us
529  * walk around in circles
530  */
531                 remove_march(wc_roomname);
532         }
533         if (march != NULL) {
534                 strcpy(next_room, pop_march(-1));
535         } else {
536                 strcpy(next_room, "_BASEROOM_");
537         }
538
539         /* In noframes mode, we goto the room silently, then do a
540          * read-new-messages which causes the banner to show up anyway.
541          */
542         if (noframes) {
543                 gotoroom(next_room, 0);
544                 readloop("readnew");
545         } else {
546         /* In frames mode, we let gotoroom() bring up the banner, which then
547          * uses JavaScript to bring up the new-messages display in the
548          * bottom frame.
549          */
550                 gotoroom(next_room, 1);
551         }
552 }
553
554
555
556 /*
557  * mark all messages in current room as having been read
558  */
559 void slrp_highest(void)
560 {
561         char buf[256];
562
563         /* set pointer */
564         serv_puts("SLRP HIGHEST");
565         serv_gets(buf);
566         if (buf[0] != '2') {
567                 wprintf("<EM>%s</EM><BR>\n", &buf[4]);
568                 return;
569         }
570 }
571
572
573 /*
574  * un-goto the previous room
575  */
576 void ungoto(void)
577 {
578         char buf[256];
579
580         if (!strcmp(ugname, "")) {
581                 gotoroom(wc_roomname, 1);
582                 return;
583         }
584         serv_printf("GOTO %s", ugname);
585         serv_gets(buf);
586         if (buf[0] != '2') {
587                 gotoroom(wc_roomname, 1);
588                 return;
589         }
590         if (uglsn >= 0L) {
591                 serv_printf("SLRP %ld", uglsn);
592                 serv_gets(buf);
593         }
594         strcpy(buf, ugname);
595         strcpy(ugname, "");
596         gotoroom(buf, 1);
597 }
598
599 /*
600  * display the form for editing a room
601  */
602 void display_editroom(void)
603 {
604         char buf[256];
605         char er_name[20];
606         char er_password[10];
607         char er_dirname[15];
608         char er_roomaide[26];
609         unsigned er_flags;
610         int er_floor;
611         int i;
612
613         serv_puts("GETR");
614         serv_gets(buf);
615
616         if (buf[0] != '2') {
617                 display_error(&buf[4]);
618                 return;
619         }
620         extract(er_name, &buf[4], 0);
621         extract(er_password, &buf[4], 1);
622         extract(er_dirname, &buf[4], 2);
623         er_flags = extract_int(&buf[4], 3);
624         er_floor = extract_int(&buf[4], 4);
625
626
627         printf("HTTP/1.0 200 OK\n");
628         output_headers(1);
629
630         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=000077><TR><TD>");
631         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
632         wprintf("<B>Edit this room</B>\n");
633         wprintf("</FONT></TD></TR></TABLE>\n");
634
635         wprintf("<FORM METHOD=\"POST\" ACTION=\"/editroom\">\n");
636
637         wprintf("<UL><LI>Name of room: ");
638         wprintf("<INPUT TYPE=\"text\" NAME=\"er_name\" VALUE=\"%s\" MAXLENGTH=\"19\">\n", er_name);
639
640         wprintf("<LI>Resides on floor: ");
641         load_floorlist();
642         wprintf("<SELECT NAME=\"er_floor\" SIZE=\"1\">\n");
643         for (i = 0; i < 128; ++i)
644                 if (strlen(floorlist[i]) > 0) {
645                         wprintf("<OPTION ");
646                         if (i == er_floor)
647                                 wprintf("SELECTED ");
648                         wprintf("VALUE=\"%d\">", i);
649                         escputs(floorlist[i]);
650                         wprintf("</OPTION>\n");
651                 }
652         wprintf("</SELECT>\n");
653
654         wprintf("<LI>Type of room:<UL>\n");
655
656         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"public\" ");
657         if ((er_flags & QR_PRIVATE) == 0)
658                 wprintf("CHECKED ");
659         wprintf("> Public room\n");
660
661         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"guessname\" ");
662         if ((er_flags & QR_PRIVATE) &&
663             (er_flags & QR_GUESSNAME))
664                 wprintf("CHECKED ");
665         wprintf("> Private - guess name\n");
666
667         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"passworded\" ");
668         if ((er_flags & QR_PRIVATE) &&
669             (er_flags & QR_PASSWORDED))
670                 wprintf("CHECKED ");
671         wprintf("> Private - require password:\n");
672         wprintf("<INPUT TYPE=\"text\" NAME=\"er_password\" VALUE=\"%s\" MAXLENGTH=\"9\">\n", er_password);
673
674         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"invonly\" ");
675         if ((er_flags & QR_PRIVATE)
676             && ((er_flags & QR_GUESSNAME) == 0)
677             && ((er_flags & QR_PASSWORDED) == 0))
678                 wprintf("CHECKED ");
679         wprintf("> Private - invitation only\n");
680
681         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"bump\" VALUE=\"yes\" ");
682         wprintf("> If private, cause current users to forget room\n");
683
684         wprintf("</UL>\n");
685
686         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"prefonly\" VALUE=\"yes\" ");
687         if (er_flags & QR_PREFONLY)
688                 wprintf("CHECKED ");
689         wprintf("> Preferred users only\n");
690
691         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"readonly\" VALUE=\"yes\" ");
692         if (er_flags & QR_READONLY)
693                 wprintf("CHECKED ");
694         wprintf("> Read-only room\n");
695
696 /* directory stuff */
697         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"directory\" VALUE=\"yes\" ");
698         if (er_flags & QR_DIRECTORY)
699                 wprintf("CHECKED ");
700         wprintf("> File directory room\n");
701
702         wprintf("<UL><LI>Directory name: ");
703         wprintf("<INPUT TYPE=\"text\" NAME=\"er_dirname\" VALUE=\"%s\" MAXLENGTH=\"14\">\n", er_dirname);
704
705         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"ulallowed\" VALUE=\"yes\" ");
706         if (er_flags & QR_UPLOAD)
707                 wprintf("CHECKED ");
708         wprintf("> Uploading allowed\n");
709
710         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"dlallowed\" VALUE=\"yes\" ");
711         if (er_flags & QR_DOWNLOAD)
712                 wprintf("CHECKED ");
713         wprintf("> Downloading allowed\n");
714
715         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"visdir\" VALUE=\"yes\" ");
716         if (er_flags & QR_VISDIR)
717                 wprintf("CHECKED ");
718         wprintf("> Visible directory</UL>\n");
719
720 /* end of directory stuff */
721
722         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"network\" VALUE=\"yes\" ");
723         if (er_flags & QR_NETWORK)
724                 wprintf("CHECKED ");
725         wprintf("> Network shared room\n");
726
727 /* start of anon options */
728
729         wprintf("<LI>Anonymous messages<UL>\n");
730
731         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"anon\" VALUE=\"no\" ");
732         if (((er_flags & QR_ANONONLY) == 0)
733             && ((er_flags & QR_ANONOPT) == 0))
734                 wprintf("CHECKED ");
735         wprintf("> No anonymous messages\n");
736
737         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"anon\" VALUE=\"anononly\" ");
738         if (er_flags & QR_ANONONLY)
739                 wprintf("CHECKED ");
740         wprintf("> All messages are anonymous\n");
741
742         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"anon\" VALUE=\"anon2\" ");
743         if (er_flags & QR_ANONOPT)
744                 wprintf("CHECKED ");
745         wprintf("> Prompt user when entering messages</UL>\n");
746
747 /* end of anon options */
748
749         wprintf("<LI>Room aide: \n");
750         serv_puts("GETA");
751         serv_gets(buf);
752         if (buf[0] != '2') {
753                 wprintf("<EM>%s</EM>\n", &buf[4]);
754         } else {
755                 extract(er_roomaide, &buf[4], 0);
756                 wprintf("<INPUT TYPE=\"text\" NAME=\"er_roomaide\" VALUE=\"%s\" MAXLENGTH=\"25\">\n", er_roomaide);
757         }
758
759         wprintf("</UL><CENTER>\n");
760         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">");
761         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
762         wprintf("</CENTER>\n");
763
764         wDumpContent(1);
765 }
766
767
768 /*
769  * save new parameters for a room
770  */
771 void editroom(void)
772 {
773         char buf[256];
774         char er_name[20];
775         char er_password[10];
776         char er_dirname[15];
777         char er_roomaide[26];
778         int er_floor;
779         unsigned er_flags;
780         int bump;
781
782
783         if (strcmp(bstr("sc"), "OK")) {
784                 display_error("Cancelled.  Changes were not saved.");
785                 return;
786         }
787         serv_puts("GETR");
788         serv_gets(buf);
789
790         if (buf[0] != '2') {
791                 display_error(&buf[4]);
792                 return;
793         }
794         extract(er_name, &buf[4], 0);
795         extract(er_password, &buf[4], 1);
796         extract(er_dirname, &buf[4], 2);
797         er_flags = extract_int(&buf[4], 3);
798
799         strcpy(er_roomaide, bstr("er_roomaide"));
800         if (strlen(er_roomaide) == 0) {
801                 serv_puts("GETA");
802                 serv_gets(buf);
803                 if (buf[0] != '2') {
804                         strcpy(er_roomaide, "");
805                 } else {
806                         extract(er_roomaide, &buf[4], 0);
807                 }
808         }
809         strcpy(buf, bstr("er_name"));
810         buf[20] = 0;
811         if (strlen(buf) > 0)
812                 strcpy(er_name, buf);
813
814         strcpy(buf, bstr("er_password"));
815         buf[10] = 0;
816         if (strlen(buf) > 0)
817                 strcpy(er_password, buf);
818
819         strcpy(buf, bstr("er_dirname"));
820         buf[15] = 0;
821         if (strlen(buf) > 0)
822                 strcpy(er_dirname, buf);
823
824         strcpy(buf, bstr("type"));
825         er_flags &= !(QR_PRIVATE | QR_PASSWORDED | QR_GUESSNAME);
826
827         if (!strcmp(buf, "invonly")) {
828                 er_flags |= (QR_PRIVATE);
829         }
830         if (!strcmp(buf, "guessname")) {
831                 er_flags |= (QR_PRIVATE | QR_GUESSNAME);
832         }
833         if (!strcmp(buf, "passworded")) {
834                 er_flags |= (QR_PRIVATE | QR_PASSWORDED);
835         }
836         if (!strcmp(bstr("prefonly"), "yes")) {
837                 er_flags |= QR_PREFONLY;
838         } else {
839                 er_flags &= ~QR_PREFONLY;
840         }
841
842         if (!strcmp(bstr("readonly"), "yes")) {
843                 er_flags |= QR_READONLY;
844         } else {
845                 er_flags &= ~QR_READONLY;
846         }
847
848         if (!strcmp(bstr("network"), "yes")) {
849                 er_flags |= QR_NETWORK;
850         } else {
851                 er_flags &= ~QR_NETWORK;
852         }
853
854         if (!strcmp(bstr("directory"), "yes")) {
855                 er_flags |= QR_DIRECTORY;
856         } else {
857                 er_flags &= ~QR_DIRECTORY;
858         }
859
860         if (!strcmp(bstr("ulallowed"), "yes")) {
861                 er_flags |= QR_UPLOAD;
862         } else {
863                 er_flags &= ~QR_UPLOAD;
864         }
865
866         if (!strcmp(bstr("dlallowed"), "yes")) {
867                 er_flags |= QR_DOWNLOAD;
868         } else {
869                 er_flags &= ~QR_DOWNLOAD;
870         }
871
872         if (!strcmp(bstr("visdir"), "yes")) {
873                 er_flags |= QR_VISDIR;
874         } else {
875                 er_flags &= ~QR_VISDIR;
876         }
877
878         strcpy(buf, bstr("anon"));
879
880         er_flags &= ~(QR_ANONONLY | QR_ANONOPT);
881         if (!strcmp(buf, "anononly"))
882                 er_flags |= QR_ANONONLY;
883         if (!strcmp(buf, "anon2"))
884                 er_flags |= QR_ANONOPT;
885
886         bump = 0;
887         if (!strcmp(bstr("bump"), "yes"))
888                 bump = 1;
889
890         er_floor = atoi(bstr("er_floor"));
891
892         sprintf(buf, "SETR %s|%s|%s|%u|%d|%d",
893              er_name, er_password, er_dirname, er_flags, bump, er_floor);
894         serv_puts(buf);
895         serv_gets(buf);
896         if (buf[0] != '2') {
897                 display_error(&buf[4]);
898                 return;
899         }
900         gotoroom(er_name, 0);
901
902         if (strlen(er_roomaide) > 0) {
903                 sprintf(buf, "SETA %s", er_roomaide);
904                 serv_puts(buf);
905                 serv_gets(buf);
906                 if (buf[0] != '2') {
907                         display_error(&buf[4]);
908                         return;
909                 }
910         }
911         gotoroom(er_name, 1);
912 }
913
914
915
916 /*
917  * display the form for entering a new room
918  */
919 void display_entroom(void)
920 {
921         char buf[256];
922
923         serv_puts("CRE8 0");
924         serv_gets(buf);
925
926         if (buf[0] != '2') {
927                 display_error(&buf[4]);
928                 return;
929         }
930         printf("HTTP/1.0 200 OK\n");
931         output_headers(1);
932
933         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=000077><TR><TD>");
934         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
935         wprintf("<B>Enter (create) a new room</B>\n");
936         wprintf("</FONT></TD></TR></TABLE>\n");
937
938         wprintf("<FORM METHOD=\"POST\" ACTION=\"/entroom\">\n");
939
940         wprintf("<UL><LI>Name of room: ");
941         wprintf("<INPUT TYPE=\"text\" NAME=\"er_name\" MAXLENGTH=\"19\">\n");
942
943         wprintf("<LI>Type of room:<UL>\n");
944
945         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"public\" ");
946         wprintf("CHECKED > Public room\n");
947
948         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"guessname\" ");
949         wprintf("> Private - guess name\n");
950
951         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"passworded\" ");
952         wprintf("> Private - require password:\n");
953         wprintf("<INPUT TYPE=\"text\" NAME=\"er_password\" MAXLENGTH=\"9\">\n");
954
955         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"invonly\" ");
956         wprintf("> Private - invitation only\n");
957
958         wprintf("<CENTER>\n");
959         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">");
960         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
961         wprintf("</CENTER>\n");
962         wprintf("</FORM>\n");
963         wDumpContent(1);
964 }
965
966
967
968 /*
969  * enter a new room
970  */
971 void entroom(void)
972 {
973         char buf[256];
974         char er_name[20];
975         char er_type[20];
976         char er_password[10];
977         int er_num_type;
978
979         if (strcmp(bstr("sc"), "OK")) {
980                 display_error("Cancelled.  No new room was created.");
981                 return;
982         }
983         strcpy(er_name, bstr("er_name"));
984         strcpy(er_type, bstr("type"));
985         strcpy(er_password, bstr("er_password"));
986
987         er_num_type = 0;
988         if (!strcmp(er_type, "guessname"))
989                 er_num_type = 1;
990         if (!strcmp(er_type, "passworded"))
991                 er_num_type = 2;
992         if (!strcmp(er_type, "invonly"))
993                 er_num_type = 3;
994
995         sprintf(buf, "CRE8 1|%s|%d|%s", er_name, er_num_type, er_password);
996         serv_puts(buf);
997         serv_gets(buf);
998         if (buf[0] != '2') {
999                 display_error(&buf[4]);
1000                 return;
1001         }
1002         gotoroom(er_name, 1);
1003 }
1004
1005
1006 /*
1007  * display the screen to enter a private room
1008  */
1009 void display_private(char *rname, int req_pass)
1010 {
1011
1012         printf("HTTP/1.0 200 OK\n");
1013         output_headers(1);
1014
1015         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
1016         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
1017         wprintf("<B>Goto a private room</B>\n");
1018         wprintf("</FONT></TD></TR></TABLE>\n");
1019
1020         wprintf("<CENTER>\n");
1021         wprintf("If you know the name of a hidden (guess-name) or\n");
1022         wprintf("passworded room, you can enter that room by typing\n");
1023         wprintf("its name below.  Once you gain access to a private\n");
1024         wprintf("room, it will appear in your regular room listings\n");
1025         wprintf("so you don't have to keep returning here.\n");
1026         wprintf("<BR><BR>");
1027
1028         wprintf("<FORM METHOD=\"POST\" ACTION=\"/goto_private\">\n");
1029
1030         wprintf("<TABLE border><TR><TD>");
1031         wprintf("Enter room name:</TD><TD>");
1032         wprintf("<INPUT TYPE=\"text\" NAME=\"gr_name\" VALUE=\"%s\" MAXLENGTH=\"19\">\n", rname);
1033
1034         if (req_pass) {
1035                 wprintf("</TD></TR><TR><TD>");
1036                 wprintf("Enter room password:</TD><TD>");
1037                 wprintf("<INPUT TYPE=\"password\" NAME=\"gr_pass\" MAXLENGTH=\"9\">\n");
1038         }
1039         wprintf("</TD></TR></TABLE>\n");
1040
1041         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">");
1042         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
1043         wprintf("</FORM>\n");
1044         wDumpContent(1);
1045 }
1046
1047 /* 
1048  * goto a private room
1049  */
1050 void goto_private(void)
1051 {
1052         char hold_rm[32];
1053         char buf[256];
1054
1055         if (strcasecmp(bstr("sc"), "OK")) {
1056                 display_main_menu();
1057                 return;
1058         }
1059         strcpy(hold_rm, wc_roomname);
1060         strcpy(buf, "GOTO ");
1061         strcat(buf, bstr("gr_name"));
1062         strcat(buf, "|");
1063         strcat(buf, bstr("gr_pass"));
1064         serv_puts(buf);
1065         serv_gets(buf);
1066
1067         if (buf[0] == '2') {
1068                 gotoroom(bstr("gr_name"), 1);
1069                 return;
1070         }
1071         if (!strncmp(buf, "540", 3)) {
1072                 display_private(bstr("gr_name"), 1);
1073                 return;
1074         }
1075         printf("HTTP/1.0 200 OK\n");
1076         output_headers(1);
1077         wprintf("%s\n", &buf[4]);
1078         wDumpContent(1);
1079         return;
1080 }
1081
1082
1083 /*
1084  * display the screen to zap a room
1085  */
1086 void display_zap(void)
1087 {
1088         printf("HTTP/1.0 200 OK\n");
1089         output_headers(1);
1090
1091         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
1092         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
1093         wprintf("<B>Zap (forget) the current room</B>\n");
1094         wprintf("</FONT></TD></TR></TABLE>\n");
1095
1096         wprintf("If you select this option, <em>%s</em> will ", wc_roomname);
1097         wprintf("disappear from your room list.  Is this what you wish ");
1098         wprintf("to do?<BR>\n");
1099
1100         wprintf("<FORM METHOD=\"POST\" ACTION=\"/zap\">\n");
1101         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">");
1102         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
1103         wprintf("</FORM>\n");
1104         wDumpContent(1);
1105 }
1106
1107
1108 /* 
1109  * zap a room
1110  */
1111 void zap(void)
1112 {
1113         char buf[256];
1114
1115         if (strcmp(bstr("sc"), "OK")) {
1116                 display_main_menu();
1117                 return;
1118         }
1119         serv_printf("GOTO %s", wc_roomname);
1120         serv_gets(buf);
1121         if (buf[0] != '2') {
1122                 display_error(&buf[4]);
1123                 return;
1124         }
1125         serv_puts("FORG");
1126         serv_gets(buf);
1127         if (buf[0] != '2') {
1128                 display_error(&buf[4]);
1129                 return;
1130         }
1131         gotoroom(bstr("_BASEROOM_"), 1);
1132 }
1133
1134
1135
1136
1137 /*
1138  * Confirm deletion of the current room
1139  */
1140 void confirm_delete_room(void)
1141 {
1142         char buf[256];
1143
1144         serv_puts("KILL 0");
1145         serv_gets(buf);
1146         if (buf[0] != '2') {
1147                 display_error(&buf[4]);
1148                 return;
1149         }
1150         printf("HTTP/1.0 200 OK\n");
1151         output_headers(1);
1152         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
1153         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
1154         wprintf("<B>Confirm deletion of room</B>\n");
1155         wprintf("</FONT></TD></TR></TABLE>\n");
1156
1157         wprintf("<CENTER>");
1158         wprintf("<FORM METHOD=\"POST\" ACTION=\"/delete_room\">\n");
1159
1160         wprintf("Are you sure you want to delete <FONT SIZE=+1>");
1161         escputs(wc_roomname);
1162         wprintf("</FONT>?<BR>\n");
1163
1164         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Delete\">");
1165         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
1166
1167         wprintf("</FORM></CENTER>\n");
1168         wDumpContent(1);
1169 }
1170
1171
1172 /*
1173  * Delete the current room
1174  */
1175 void delete_room(void)
1176 {
1177         char buf[256];
1178         char sc[256];
1179
1180         strcpy(sc, bstr("sc"));
1181
1182         if (strcasecmp(sc, "Delete")) {
1183                 display_error("Cancelled.  This room was not deleted.");
1184                 return;
1185         }
1186         serv_puts("KILL 1");
1187         serv_gets(buf);
1188         if (buf[0] != '2') {
1189                 display_error(&buf[4]);
1190         } else {
1191                 gotoroom("_BASEROOM_", 1);
1192         }
1193 }