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