]> code.citadel.org Git - citadel.git/blob - webcit/roomops.c
974559fafd17e339c3e7d7c1ab65d2fb3a3be0e6
[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("\">");
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, "bottom");
241
242         wprintf("<TABLE width=100% border><TR><TH>Floor</TH>");
243         wprintf("<TH>Rooms with new messages</TH>");
244         wprintf("<TH>Rooms with no new messages</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>");
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("</TD>");
264
265                         /* Rooms with new messages column */
266                         wprintf("<TD>");
267                         sprintf(buf, "LKRN %d", a);
268                         listrms(buf);
269                         wprintf("</TD><TD>\n");
270
271                         /* Rooms with old messages column */
272                         sprintf(buf, "LKRO %d", a);
273                         listrms(buf);
274                         wprintf("</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, "bottom");
288         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
289         wprintf("<FONT 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  * generic routine to take the session to a new room
319  *
320  * display_name values:  0 = goto only
321  *                       1 = goto and display
322  *                       2 = display only
323  */
324 void gotoroom(char *gname, int display_name)
325 {
326         char buf[256];
327         static long ls = (-1L);
328
329
330         if (display_name) {
331                 printf("HTTP/1.0 200 OK\n");
332                 output_headers(0, "top");
333                 wprintf("<HTML><HEAD></HEAD>\n<BODY ");
334
335                 /* automatically fire up a read-new-msgs in the bottom frame */
336                 if (!noframes)
337                         wprintf("onload=parent.frames.bottom.location=\"/readnew\" ");
338
339                 wprintf("BACKGROUND=\"/image&name=background\" TEXT=\"#000000\" LINK=\"#004400\">\n");
340         }
341         if (display_name != 2) {
342                 /* store ungoto information */
343                 strcpy(ugname, wc_roomname);
344                 uglsn = ls;
345         }
346         /* move to the new room */
347         serv_printf("GOTO %s", gname);
348         serv_gets(buf);
349         if (buf[0] != '2') {
350                 serv_puts("GOTO _BASEROOM_");
351                 serv_gets(buf);
352         }
353         if (buf[0] != '2') {
354                 if (display_name) {
355                         wprintf("<EM>%s</EM><BR>\n", &buf[4]);
356                         wDumpContent(1);
357                 }
358                 return;
359         }
360         extract(wc_roomname, &buf[4], 0);
361         room_flags = extract_int(&buf[4], 4);
362         /* highest_msg_read = extract_int(&buf[4],6);
363            maxmsgnum = extract_int(&buf[4],5);
364            is_mail = (char) extract_int(&buf[4],7); */
365         ls = extract_long(&buf[4], 6);
366
367         if (is_aide)
368                 is_room_aide = is_aide;
369         else
370                 is_room_aide = (char) extract_int(&buf[4], 8);
371
372         remove_march(wc_roomname);
373         if (!strcasecmp(gname, "_BASEROOM_"))
374                 remove_march(gname);
375
376         /* Display the room banner */
377         if (display_name) {
378                 wprintf("<CENTER><TABLE border=0><TR>");
379
380                 if ((strlen(ugname) > 0) && (strcasecmp(ugname, wc_roomname))) {
381                         wprintf("<TD VALIGN=TOP><A HREF=\"/ungoto\">");
382                         wprintf("<IMG SRC=\"/static/back.gif\" BORDER=0></A></TD>");
383                 }
384                 wprintf("<TD VALIGN=TOP><FONT FACE=\"Arial,Helvetica,sans-serif\"><H1>%s</H1>", wc_roomname);
385                 wprintf("%d new of %d messages</FONT></TD>\n",
386                         extract_int(&buf[4], 1),
387                         extract_int(&buf[4], 2));
388
389                 /* Display room graphic.  The server doesn't actually
390                  * need the room name, but we supply it in order to
391                  * keep the browser from using a cached graphic from 
392                  * another room.
393                  */
394                 serv_puts("OIMG _roompic_");
395                 serv_gets(buf);
396                 if (buf[0] == '2') {
397                         wprintf("<TD><FONT FACE=\"Arial,Helvetica,sans-serif\">");
398                         wprintf("<IMG SRC=\"/image&name=_roompic_&room=");
399                         escputs(wc_roomname);
400                         wprintf("\"></FONT></TD>");
401                         serv_puts("CLOS");
402                         serv_gets(buf);
403                 }
404                 wprintf("<TD VALIGN=TOP><FONT FACE=\"Arial,Helvetica,sans-serif\">");
405                 readinfo(0);
406                 wprintf("</FONT></TD>");
407
408                 wprintf("<TD VALIGN=TOP><A HREF=\"/gotonext\">");
409                 wprintf("<IMG SRC=\"/static/forward.gif\" border=0></A></TD>");
410                 wprintf("</TR></TABLE></CENTER>\n");
411
412                 wDumpContent(1);
413         }
414         strcpy(wc_roomname, wc_roomname);
415 }
416
417
418 /*
419  * Locate the room on the march list which we most want to go to.  Each room
420  * is measured given a "weight" of preference based on various factors.
421  */
422 char *pop_march(int desired_floor)
423 {
424         static char TheRoom[64];
425         int TheFloor = 0;
426         int TheOrder = 32767;
427         int TheWeight = 0;
428         int weight;
429         struct march *mptr = NULL;
430
431         strcpy(TheRoom, "_BASEROOM_");
432         if (march == NULL)
433                 return (TheRoom);
434
435         for (mptr = march; mptr != NULL; mptr = mptr->next) {
436                 weight = 0;
437                 if ((strcasecmp(mptr->march_name, "_BASEROOM_")))
438                         weight = weight + 10000;
439                 if (mptr->march_floor == desired_floor)
440                         weight = weight + 5000;
441
442                 weight = weight + ((128 - (mptr->march_floor)) * 128);
443                 weight = weight + (128 - (mptr->march_order));
444
445                 if (weight > TheWeight) {
446                         TheWeight = weight;
447                         strcpy(TheRoom, mptr->march_name);
448                         TheFloor = mptr->march_floor;
449                         TheOrder = mptr->march_order;
450                 }
451         }
452         return (TheRoom);
453 }
454
455
456
457 /* Goto next room having unread messages.
458  * We want to skip over rooms that the user has already been to, and take the
459  * user back to the lobby when done.  The room we end up in is placed in
460  * newroom - which is set to 0 (the lobby) initially.
461  * We start the search in the current room rather than the beginning to prevent
462  * two or more concurrent users from dragging each other back to the same room.
463  */
464 void gotonext(void)
465 {
466         char buf[256];
467         struct march *mptr, *mptr2;
468         char next_room[32];
469
470         /* First check to see if the march-mode list is already allocated.
471          * If it is, pop the first room off the list and go there.
472          */
473
474         if (march == NULL) {
475                 serv_puts("LKRN");
476                 serv_gets(buf);
477                 if (buf[0] == '1')
478                         while (serv_gets(buf), strcmp(buf, "000")) {
479                                 mptr = (struct march *) malloc(sizeof(struct march));
480                                 mptr->next = NULL;
481                                 extract(mptr->march_name, buf, 0);
482                                 mptr->march_floor = extract_int(buf, 2);
483                                 mptr->march_order = extract_int(buf, 3);
484                                 if (march == NULL) {
485                                         march = mptr;
486                                 } else {
487                                         mptr2 = march;
488                                         while (mptr2->next != NULL)
489                                                 mptr2 = mptr2->next;
490                                         mptr2->next = mptr;
491                                 }
492                         }
493 /* add _BASEROOM_ to the end of the march list, so the user will end up
494  * in the system base room (usually the Lobby>) at the end of the loop
495  */
496                 mptr = (struct march *) malloc(sizeof(struct march));
497                 mptr->next = NULL;
498                 strcpy(mptr->march_name, "_BASEROOM_");
499                 if (march == NULL) {
500                         march = mptr;
501                 } else {
502                         mptr2 = march;
503                         while (mptr2->next != NULL)
504                                 mptr2 = mptr2->next;
505                         mptr2->next = mptr;
506                 }
507 /*
508  * ...and remove the room we're currently in, so a <G>oto doesn't make us
509  * walk around in circles
510  */
511                 remove_march(wc_roomname);
512         }
513         if (march != NULL) {
514                 strcpy(next_room, pop_march(-1));
515         } else {
516                 strcpy(next_room, "_BASEROOM_");
517         }
518         gotoroom(next_room, 1);
519 }
520
521
522
523 /*
524  * mark all messages in current room as having been read
525  */
526 void slrp_highest(void)
527 {
528         char buf[256];
529
530         /* set pointer */
531         serv_puts("SLRP HIGHEST");
532         serv_gets(buf);
533         if (buf[0] != '2') {
534                 wprintf("<EM>%s</EM><BR>\n", &buf[4]);
535                 return;
536         }
537 }
538
539
540 /*
541  * un-goto the previous room
542  */
543 void ungoto(void)
544 {
545         char buf[256];
546
547         if (!strcmp(ugname, "")) {
548                 gotoroom(wc_roomname, 1);
549                 return;
550         }
551         serv_printf("GOTO %s", ugname);
552         serv_gets(buf);
553         if (buf[0] != '2') {
554                 gotoroom(wc_roomname, 1);
555                 return;
556         }
557         if (uglsn >= 0L) {
558                 serv_printf("SLRP %ld", uglsn);
559                 serv_gets(buf);
560         }
561         strcpy(buf, ugname);
562         strcpy(ugname, "");
563         gotoroom(buf, 1);
564 }
565
566 /*
567  * display the form for editing a room
568  */
569 void display_editroom(void)
570 {
571         char buf[256];
572         char er_name[20];
573         char er_password[10];
574         char er_dirname[15];
575         char er_roomaide[26];
576         unsigned er_flags;
577         int er_floor;
578         int i;
579
580         serv_puts("GETR");
581         serv_gets(buf);
582
583         if (buf[0] != '2') {
584                 display_error(&buf[4]);
585                 return;
586         }
587         extract(er_name, &buf[4], 0);
588         extract(er_password, &buf[4], 1);
589         extract(er_dirname, &buf[4], 2);
590         er_flags = extract_int(&buf[4], 3);
591         er_floor = extract_int(&buf[4], 4);
592
593
594         printf("HTTP/1.0 200 OK\n");
595         output_headers(1, "bottom");
596
597         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=000077><TR><TD>");
598         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
599         wprintf("<B>Edit this room</B>\n");
600         wprintf("</FONT></TD></TR></TABLE>\n");
601
602         wprintf("<FORM METHOD=\"POST\" ACTION=\"/editroom\">\n");
603
604         wprintf("<UL><LI>Name of room: ");
605         wprintf("<INPUT TYPE=\"text\" NAME=\"er_name\" VALUE=\"%s\" MAXLENGTH=\"19\">\n", er_name);
606
607         wprintf("<LI>Resides on floor: ");
608         load_floorlist();
609         wprintf("<SELECT NAME=\"er_floor\" SIZE=\"1\">\n");
610         for (i = 0; i < 128; ++i)
611                 if (strlen(floorlist[i]) > 0) {
612                         wprintf("<OPTION ");
613                         if (i == er_floor)
614                                 wprintf("SELECTED ");
615                         wprintf("VALUE=\"%d\">", i);
616                         escputs(floorlist[i]);
617                         wprintf("</OPTION>\n");
618                 }
619         wprintf("</SELECT>\n");
620
621         wprintf("<LI>Type of room:<UL>\n");
622
623         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"public\" ");
624         if ((er_flags & QR_PRIVATE) == 0)
625                 wprintf("CHECKED ");
626         wprintf("> Public room\n");
627
628         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"guessname\" ");
629         if ((er_flags & QR_PRIVATE) &&
630             (er_flags & QR_GUESSNAME))
631                 wprintf("CHECKED ");
632         wprintf("> Private - guess name\n");
633
634         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"passworded\" ");
635         if ((er_flags & QR_PRIVATE) &&
636             (er_flags & QR_PASSWORDED))
637                 wprintf("CHECKED ");
638         wprintf("> Private - require password:\n");
639         wprintf("<INPUT TYPE=\"text\" NAME=\"er_password\" VALUE=\"%s\" MAXLENGTH=\"9\">\n", er_password);
640
641         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"invonly\" ");
642         if ((er_flags & QR_PRIVATE)
643             && ((er_flags & QR_GUESSNAME) == 0)
644             && ((er_flags & QR_PASSWORDED) == 0))
645                 wprintf("CHECKED ");
646         wprintf("> Private - invitation only\n");
647
648         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"bump\" VALUE=\"yes\" ");
649         wprintf("> If private, cause current users to forget room\n");
650
651         wprintf("</UL>\n");
652
653         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"prefonly\" VALUE=\"yes\" ");
654         if (er_flags & QR_PREFONLY)
655                 wprintf("CHECKED ");
656         wprintf("> Preferred users only\n");
657
658         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"readonly\" VALUE=\"yes\" ");
659         if (er_flags & QR_READONLY)
660                 wprintf("CHECKED ");
661         wprintf("> Read-only room\n");
662
663 /* directory stuff */
664         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"directory\" VALUE=\"yes\" ");
665         if (er_flags & QR_DIRECTORY)
666                 wprintf("CHECKED ");
667         wprintf("> File directory room\n");
668
669         wprintf("<UL><LI>Directory name: ");
670         wprintf("<INPUT TYPE=\"text\" NAME=\"er_dirname\" VALUE=\"%s\" MAXLENGTH=\"14\">\n", er_dirname);
671
672         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"ulallowed\" VALUE=\"yes\" ");
673         if (er_flags & QR_UPLOAD)
674                 wprintf("CHECKED ");
675         wprintf("> Uploading allowed\n");
676
677         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"dlallowed\" VALUE=\"yes\" ");
678         if (er_flags & QR_DOWNLOAD)
679                 wprintf("CHECKED ");
680         wprintf("> Downloading allowed\n");
681
682         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"visdir\" VALUE=\"yes\" ");
683         if (er_flags & QR_VISDIR)
684                 wprintf("CHECKED ");
685         wprintf("> Visible directory</UL>\n");
686
687 /* end of directory stuff */
688
689         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"network\" VALUE=\"yes\" ");
690         if (er_flags & QR_NETWORK)
691                 wprintf("CHECKED ");
692         wprintf("> Network shared room\n");
693
694 /* start of anon options */
695
696         wprintf("<LI>Anonymous messages<UL>\n");
697
698         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"anon\" VALUE=\"no\" ");
699         if (((er_flags & QR_ANONONLY) == 0)
700             && ((er_flags & QR_ANONOPT) == 0))
701                 wprintf("CHECKED ");
702         wprintf("> No anonymous messages\n");
703
704         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"anon\" VALUE=\"anononly\" ");
705         if (er_flags & QR_ANONONLY)
706                 wprintf("CHECKED ");
707         wprintf("> All messages are anonymous\n");
708
709         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"anon\" VALUE=\"anon2\" ");
710         if (er_flags & QR_ANONOPT)
711                 wprintf("CHECKED ");
712         wprintf("> Prompt user when entering messages</UL>\n");
713
714 /* end of anon options */
715
716         wprintf("<LI>Room aide: \n");
717         serv_puts("GETA");
718         serv_gets(buf);
719         if (buf[0] != '2') {
720                 wprintf("<EM>%s</EM>\n", &buf[4]);
721         } else {
722                 extract(er_roomaide, &buf[4], 0);
723                 wprintf("<INPUT TYPE=\"text\" NAME=\"er_roomaide\" VALUE=\"%s\" MAXLENGTH=\"25\">\n", er_roomaide);
724         }
725
726         wprintf("</UL><CENTER>\n");
727         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">");
728         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
729         wprintf("</CENTER>\n");
730
731         wDumpContent(1);
732 }
733
734
735 /*
736  * save new parameters for a room
737  */
738 void editroom(void)
739 {
740         char buf[256];
741         char er_name[20];
742         char er_password[10];
743         char er_dirname[15];
744         char er_roomaide[26];
745         int er_floor;
746         unsigned er_flags;
747         int bump;
748
749
750         if (strcmp(bstr("sc"), "OK")) {
751                 display_error("Cancelled.  Changes were not saved.");
752                 return;
753         }
754         serv_puts("GETR");
755         serv_gets(buf);
756
757         if (buf[0] != '2') {
758                 display_error(&buf[4]);
759                 return;
760         }
761         extract(er_name, &buf[4], 0);
762         extract(er_password, &buf[4], 1);
763         extract(er_dirname, &buf[4], 2);
764         er_flags = extract_int(&buf[4], 3);
765
766         strcpy(er_roomaide, bstr("er_roomaide"));
767         if (strlen(er_roomaide) == 0) {
768                 serv_puts("GETA");
769                 serv_gets(buf);
770                 if (buf[0] != '2') {
771                         strcpy(er_roomaide, "");
772                 } else {
773                         extract(er_roomaide, &buf[4], 0);
774                 }
775         }
776         strcpy(buf, bstr("er_name"));
777         buf[20] = 0;
778         if (strlen(buf) > 0)
779                 strcpy(er_name, buf);
780
781         strcpy(buf, bstr("er_password"));
782         buf[10] = 0;
783         if (strlen(buf) > 0)
784                 strcpy(er_password, buf);
785
786         strcpy(buf, bstr("er_dirname"));
787         buf[15] = 0;
788         if (strlen(buf) > 0)
789                 strcpy(er_dirname, buf);
790
791         strcpy(buf, bstr("type"));
792         er_flags &= !(QR_PRIVATE | QR_PASSWORDED | QR_GUESSNAME);
793
794         if (!strcmp(buf, "invonly")) {
795                 er_flags |= (QR_PRIVATE);
796         }
797         if (!strcmp(buf, "guessname")) {
798                 er_flags |= (QR_PRIVATE | QR_GUESSNAME);
799         }
800         if (!strcmp(buf, "passworded")) {
801                 er_flags |= (QR_PRIVATE | QR_PASSWORDED);
802         }
803         if (!strcmp(bstr("prefonly"), "yes")) {
804                 er_flags |= QR_PREFONLY;
805         } else {
806                 er_flags &= ~QR_PREFONLY;
807         }
808
809         if (!strcmp(bstr("readonly"), "yes")) {
810                 er_flags |= QR_READONLY;
811         } else {
812                 er_flags &= ~QR_READONLY;
813         }
814
815         if (!strcmp(bstr("network"), "yes")) {
816                 er_flags |= QR_NETWORK;
817         } else {
818                 er_flags &= ~QR_NETWORK;
819         }
820
821         if (!strcmp(bstr("directory"), "yes")) {
822                 er_flags |= QR_DIRECTORY;
823         } else {
824                 er_flags &= ~QR_DIRECTORY;
825         }
826
827         if (!strcmp(bstr("ulallowed"), "yes")) {
828                 er_flags |= QR_UPLOAD;
829         } else {
830                 er_flags &= ~QR_UPLOAD;
831         }
832
833         if (!strcmp(bstr("dlallowed"), "yes")) {
834                 er_flags |= QR_DOWNLOAD;
835         } else {
836                 er_flags &= ~QR_DOWNLOAD;
837         }
838
839         if (!strcmp(bstr("visdir"), "yes")) {
840                 er_flags |= QR_VISDIR;
841         } else {
842                 er_flags &= ~QR_VISDIR;
843         }
844
845         strcpy(buf, bstr("anon"));
846
847         er_flags &= ~(QR_ANONONLY | QR_ANONOPT);
848         if (!strcmp(buf, "anononly"))
849                 er_flags |= QR_ANONONLY;
850         if (!strcmp(buf, "anon2"))
851                 er_flags |= QR_ANONOPT;
852
853         bump = 0;
854         if (!strcmp(bstr("bump"), "yes"))
855                 bump = 1;
856
857         er_floor = atoi(bstr("er_floor"));
858
859         sprintf(buf, "SETR %s|%s|%s|%u|%d|%d",
860              er_name, er_password, er_dirname, er_flags, bump, er_floor);
861         serv_puts(buf);
862         serv_gets(buf);
863         if (buf[0] != '2') {
864                 display_error(&buf[4]);
865                 return;
866         }
867         gotoroom(er_name, 0);
868
869         if (strlen(er_roomaide) > 0) {
870                 sprintf(buf, "SETA %s", er_roomaide);
871                 serv_puts(buf);
872                 serv_gets(buf);
873                 if (buf[0] != '2') {
874                         display_error(&buf[4]);
875                         return;
876                 }
877         }
878         gotoroom(er_name, 1);
879 }
880
881
882
883 /*
884  * display the form for entering a new room
885  */
886 void display_entroom(void)
887 {
888         char buf[256];
889
890         serv_puts("CRE8 0");
891         serv_gets(buf);
892
893         if (buf[0] != '2') {
894                 display_error(&buf[4]);
895                 return;
896         }
897         printf("HTTP/1.0 200 OK\n");
898         output_headers(1, "bottom");
899
900         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=000077><TR><TD>");
901         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
902         wprintf("<B>Enter (create) a new room</B>\n");
903         wprintf("</FONT></TD></TR></TABLE>\n");
904
905         wprintf("<FORM METHOD=\"POST\" ACTION=\"/entroom\">\n");
906
907         wprintf("<UL><LI>Name of room: ");
908         wprintf("<INPUT TYPE=\"text\" NAME=\"er_name\" MAXLENGTH=\"19\">\n");
909
910         wprintf("<LI>Type of room:<UL>\n");
911
912         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"public\" ");
913         wprintf("CHECKED > Public room\n");
914
915         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"guessname\" ");
916         wprintf("> Private - guess name\n");
917
918         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"passworded\" ");
919         wprintf("> Private - require password:\n");
920         wprintf("<INPUT TYPE=\"text\" NAME=\"er_password\" MAXLENGTH=\"9\">\n");
921
922         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"invonly\" ");
923         wprintf("> Private - invitation only\n");
924
925         wprintf("<CENTER>\n");
926         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">");
927         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
928         wprintf("</CENTER>\n");
929         wprintf("</FORM>\n");
930         wDumpContent(1);
931 }
932
933
934
935 /*
936  * enter a new room
937  */
938 void entroom(void)
939 {
940         char buf[256];
941         char er_name[20];
942         char er_type[20];
943         char er_password[10];
944         int er_num_type;
945
946         if (strcmp(bstr("sc"), "OK")) {
947                 display_error("Cancelled.  No new room was created.");
948                 return;
949         }
950         strcpy(er_name, bstr("er_name"));
951         strcpy(er_type, bstr("type"));
952         strcpy(er_password, bstr("er_password"));
953
954         er_num_type = 0;
955         if (!strcmp(er_type, "guessname"))
956                 er_num_type = 1;
957         if (!strcmp(er_type, "passworded"))
958                 er_num_type = 2;
959         if (!strcmp(er_type, "invonly"))
960                 er_num_type = 3;
961
962         sprintf(buf, "CRE8 1|%s|%d|%s", er_name, er_num_type, er_password);
963         serv_puts(buf);
964         serv_gets(buf);
965         if (buf[0] != '2') {
966                 display_error(&buf[4]);
967                 return;
968         }
969         gotoroom(er_name, 1);
970 }
971
972
973 /*
974  * display the screen to enter a private room
975  */
976 void display_private(char *rname, int req_pass)
977 {
978
979         printf("HTTP/1.0 200 OK\n");
980         output_headers(1, "bottom");
981
982         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
983         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
984         wprintf("<B>Goto a private room</B>\n");
985         wprintf("</FONT></TD></TR></TABLE>\n");
986
987         wprintf("<CENTER>\n");
988         wprintf("If you know the name of a hidden (guess-name) or\n");
989         wprintf("passworded room, you can enter that room by typing\n");
990         wprintf("its name below.  Once you gain access to a private\n");
991         wprintf("room, it will appear in your regular room listings\n");
992         wprintf("so you don't have to keep returning here.\n");
993         wprintf("<BR><BR>");
994
995         wprintf("<FORM METHOD=\"POST\" ACTION=\"/goto_private\">\n");
996
997         wprintf("<TABLE border><TR><TD>");
998         wprintf("Enter room name:</TD><TD>");
999         wprintf("<INPUT TYPE=\"text\" NAME=\"gr_name\" VALUE=\"%s\" MAXLENGTH=\"19\">\n", rname);
1000
1001         if (req_pass) {
1002                 wprintf("</TD></TR><TR><TD>");
1003                 wprintf("Enter room password:</TD><TD>");
1004                 wprintf("<INPUT TYPE=\"password\" NAME=\"gr_pass\" MAXLENGTH=\"9\">\n");
1005         }
1006         wprintf("</TD></TR></TABLE>\n");
1007
1008         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">");
1009         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
1010         wprintf("</FORM>\n");
1011         wDumpContent(1);
1012 }
1013
1014 /* 
1015  * goto a private room
1016  */
1017 void goto_private(void)
1018 {
1019         char hold_rm[32];
1020         char buf[256];
1021
1022         if (strcasecmp(bstr("sc"), "OK")) {
1023                 display_main_menu();
1024                 return;
1025         }
1026         strcpy(hold_rm, wc_roomname);
1027         strcpy(buf, "GOTO ");
1028         strcat(buf, bstr("gr_name"));
1029         strcat(buf, "|");
1030         strcat(buf, bstr("gr_pass"));
1031         serv_puts(buf);
1032         serv_gets(buf);
1033
1034         if (buf[0] == '2') {
1035                 gotoroom(bstr("gr_name"), 1);
1036                 return;
1037         }
1038         if (!strncmp(buf, "540", 3)) {
1039                 display_private(bstr("gr_name"), 1);
1040                 return;
1041         }
1042         printf("HTTP/1.0 200 OK\n");
1043         output_headers(1, "bottom");
1044         wprintf("%s\n", &buf[4]);
1045         wDumpContent(1);
1046         return;
1047 }
1048
1049
1050 /*
1051  * display the screen to zap a room
1052  */
1053 void display_zap(void)
1054 {
1055         printf("HTTP/1.0 200 OK\n");
1056         output_headers(1, "bottom");
1057
1058         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
1059         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
1060         wprintf("<B>Zap (forget) the current room</B>\n");
1061         wprintf("</FONT></TD></TR></TABLE>\n");
1062
1063         wprintf("If you select this option, <em>%s</em> will ", wc_roomname);
1064         wprintf("disappear from your room list.  Is this what you wish ");
1065         wprintf("to do?<BR>\n");
1066
1067         wprintf("<FORM METHOD=\"POST\" ACTION=\"/zap\">\n");
1068         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">");
1069         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
1070         wprintf("</FORM>\n");
1071         wDumpContent(1);
1072 }
1073
1074
1075 /* 
1076  * zap a room
1077  */
1078 void zap(void)
1079 {
1080         char buf[256];
1081
1082         if (strcmp(bstr("sc"), "OK")) {
1083                 display_main_menu();
1084                 return;
1085         }
1086         serv_printf("GOTO %s", wc_roomname);
1087         serv_gets(buf);
1088         if (buf[0] != '2') {
1089                 display_error(&buf[4]);
1090                 return;
1091         }
1092         serv_puts("FORG");
1093         serv_gets(buf);
1094         if (buf[0] != '2') {
1095                 display_error(&buf[4]);
1096                 return;
1097         }
1098         gotoroom(bstr("_BASEROOM_"), 1);
1099 }
1100
1101
1102
1103
1104 /*
1105  * Confirm deletion of the current room
1106  */
1107 void confirm_delete_room(void)
1108 {
1109         char buf[256];
1110
1111         serv_puts("KILL 0");
1112         serv_gets(buf);
1113         if (buf[0] != '2') {
1114                 display_error(&buf[4]);
1115                 return;
1116         }
1117         printf("HTTP/1.0 200 OK\n");
1118         output_headers(1, "bottom");
1119         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
1120         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
1121         wprintf("<B>Confirm deletion of room</B>\n");
1122         wprintf("</FONT></TD></TR></TABLE>\n");
1123
1124         wprintf("<CENTER>");
1125         wprintf("<FORM METHOD=\"POST\" ACTION=\"/delete_room\">\n");
1126
1127         wprintf("Are you sure you want to delete <FONT SIZE=+1>");
1128         escputs(wc_roomname);
1129         wprintf("</FONT>?<BR>\n");
1130
1131         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Delete\">");
1132         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
1133
1134         wprintf("</FORM></CENTER>\n");
1135         wDumpContent(1);
1136 }
1137
1138
1139 /*
1140  * Delete the current room
1141  */
1142 void delete_room(void)
1143 {
1144         char buf[256];
1145         char sc[256];
1146
1147         strcpy(sc, bstr("sc"));
1148
1149         if (strcasecmp(sc, "Delete")) {
1150                 display_error("Cancelled.  This room was not deleted.");
1151                 return;
1152         }
1153         serv_puts("KILL 1");
1154         serv_gets(buf);
1155         if (buf[0] != '2') {
1156                 display_error(&buf[4]);
1157         } else {
1158                 gotoroom("_BASEROOM_", 1);
1159         }
1160 }