cfc9adbae10d8f56a6fc8cc94b09dbe5654947dd
[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         int er_floor;
567         int i;
568
569         serv_puts("GETR");
570         serv_gets(buf);
571
572         if (buf[0]!='2') {
573                 display_error(&buf[4]);
574                 return;
575                 }
576
577         extract(er_name,&buf[4],0);
578         extract(er_password,&buf[4],1);
579         extract(er_dirname,&buf[4],2);
580         er_flags=extract_int(&buf[4],3);
581         er_floor=extract_int(&buf[4],4);
582
583
584         printf("HTTP/1.0 200 OK\n");
585         output_headers(1);
586
587         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=000077><TR><TD>");
588         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
589         wprintf("<B>Edit this room</B>\n");
590         wprintf("</FONT></TD></TR></TABLE>\n");
591
592         wprintf("<FORM METHOD=\"POST\" ACTION=\"/editroom\">\n");
593
594         wprintf("<UL><LI>Name of room: ");      
595         wprintf("<INPUT TYPE=\"text\" NAME=\"er_name\" VALUE=\"%s\" MAXLENGTH=\"19\">\n",er_name);
596
597         wprintf("<LI>Resides on floor: ");
598         load_floorlist();
599         wprintf("<SELECT NAME=\"er_floor\" SIZE=\"1\">\n");
600         for (i=0; i<128; ++i) if (strlen(floorlist[i])>0) {
601                 wprintf("<OPTION ");
602                 if (i == er_floor) wprintf("SELECTED ");
603                 wprintf("VALUE=\"%d\">", i);
604                 escputs(floorlist[i]);
605                 wprintf("</OPTION>\n");
606                 }
607         wprintf("</SELECT>\n");
608
609         wprintf("<LI>Type of room:<UL>\n");
610
611         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"public\" ");
612         if ((er_flags & QR_PRIVATE) == 0) wprintf("CHECKED ");
613         wprintf("> Public room\n");
614
615         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"guessname\" ");
616         if ((er_flags & QR_PRIVATE)&&
617            (er_flags & QR_GUESSNAME)) wprintf("CHECKED ");
618         wprintf("> Private - guess name\n");
619
620         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"passworded\" ");
621         if ((er_flags & QR_PRIVATE)&&
622            (er_flags & QR_PASSWORDED)) wprintf("CHECKED ");
623         wprintf("> Private - require password:\n");
624         wprintf("<INPUT TYPE=\"text\" NAME=\"er_password\" VALUE=\"%s\" MAXLENGTH=\"9\">\n",er_password);
625
626         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"invonly\" ");
627         if ( (er_flags & QR_PRIVATE)
628            && ((er_flags & QR_GUESSNAME) == 0)
629            && ((er_flags & QR_PASSWORDED) == 0) )
630                 wprintf("CHECKED ");
631         wprintf("> Private - invitation only\n");
632
633         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"bump\" VALUE=\"yes\" ");
634         wprintf("> If private, cause current users to forget room\n");
635
636         wprintf("</UL>\n");
637
638         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"prefonly\" VALUE=\"yes\" ");
639         if (er_flags & QR_PREFONLY) wprintf("CHECKED ");
640         wprintf("> Preferred users only\n");
641
642         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"readonly\" VALUE=\"yes\" ");
643         if (er_flags & QR_READONLY) wprintf("CHECKED ");
644         wprintf("> Read-only room\n");
645
646 /* directory stuff */
647         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"directory\" VALUE=\"yes\" ");
648         if (er_flags & QR_DIRECTORY) wprintf("CHECKED ");
649         wprintf("> File directory room\n");
650
651         wprintf("<UL><LI>Directory name: ");
652         wprintf("<INPUT TYPE=\"text\" NAME=\"er_dirname\" VALUE=\"%s\" MAXLENGTH=\"14\">\n",er_dirname);
653
654         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"ulallowed\" VALUE=\"yes\" ");
655         if (er_flags & QR_UPLOAD) wprintf("CHECKED ");
656         wprintf("> Uploading allowed\n");
657
658         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"dlallowed\" VALUE=\"yes\" ");
659         if (er_flags & QR_DOWNLOAD) wprintf("CHECKED ");
660         wprintf("> Downloading allowed\n");
661
662         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"visdir\" VALUE=\"yes\" ");
663         if (er_flags & QR_VISDIR) wprintf("CHECKED ");
664         wprintf("> Visible directory</UL>\n");
665
666 /* end of directory stuff */
667         
668         wprintf("<LI><INPUT TYPE=\"checkbox\" NAME=\"network\" VALUE=\"yes\" ");
669         if (er_flags & QR_NETWORK) wprintf("CHECKED ");
670         wprintf("> Network shared room\n");
671
672 /* start of anon options */
673
674         wprintf("<LI>Anonymous messages<UL>\n");
675         
676         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"anon\" VALUE=\"no\" ");
677         if ( ((er_flags & QR_ANONONLY)==0)
678            && ((er_flags & QR_ANONOPT)==0)) wprintf("CHECKED ");
679         wprintf("> No anonymous messages\n");
680
681         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"anon\" VALUE=\"anononly\" ");
682         if (er_flags & QR_ANONONLY) wprintf("CHECKED ");
683         wprintf("> All messages are anonymous\n");
684
685         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"anon\" VALUE=\"anon2\" ");
686         if (er_flags & QR_ANONOPT) wprintf("CHECKED ");
687         wprintf("> Prompt user when entering messages</UL>\n");
688
689 /* end of anon options */
690
691         wprintf("<LI>Room aide: \n");
692         serv_puts("GETA");
693         serv_gets(buf);
694         if (buf[0]!='2') {
695                 wprintf("<EM>%s</EM>\n",&buf[4]);
696                 }
697         else {
698                 extract(er_roomaide,&buf[4],0);
699                 wprintf("<INPUT TYPE=\"text\" NAME=\"er_roomaide\" VALUE=\"%s\" MAXLENGTH=\"25\">\n",er_roomaide);
700                 }
701                 
702         wprintf("</UL><CENTER>\n");
703         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">");
704         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
705         wprintf("</CENTER>\n");
706
707         wprintf("</FORM></HTML>\n");
708         wDumpContent();
709         }
710
711
712 /*
713  * save new parameters for a room
714  */
715 void editroom(void) {
716         char buf[256];
717         char er_name[20];
718         char er_password[10];
719         char er_dirname[15];
720         char er_roomaide[26];
721         int er_floor;
722         unsigned er_flags;
723         int bump;
724
725
726         if (strcmp(bstr("sc"),"OK")) {
727                 display_error("Cancelled.  Changes were not saved.");
728                 return;
729                 }
730         
731         serv_puts("GETR");
732         serv_gets(buf);
733
734         if (buf[0]!='2') {
735                 display_error(&buf[4]);
736                 return;
737                 }
738
739         extract(er_name,&buf[4],0);
740         extract(er_password,&buf[4],1);
741         extract(er_dirname,&buf[4],2);
742         er_flags=extract_int(&buf[4],3);
743
744         strcpy(er_roomaide,bstr("er_roomaide"));
745         if (strlen(er_roomaide)==0) {
746                 serv_puts("GETA");
747                 serv_gets(buf);
748                 if (buf[0]!='2') {
749                         strcpy(er_roomaide,"");
750                         }
751                 else {
752                         extract(er_roomaide,&buf[4],0);
753                         }
754                 }
755
756         strcpy(buf,bstr("er_name"));            buf[20] = 0;
757         if (strlen(buf)>0) strcpy(er_name,buf);
758
759         strcpy(buf,bstr("er_password"));        buf[10] = 0;
760         if (strlen(buf)>0) strcpy(er_password,buf);
761
762         strcpy(buf,bstr("er_dirname"));         buf[15] = 0;
763         if (strlen(buf)>0) strcpy(er_dirname,buf);
764
765         strcpy(buf,bstr("type"));
766         er_flags &= !(QR_PRIVATE|QR_PASSWORDED|QR_GUESSNAME);
767
768         if (!strcmp(buf,"invonly")) {
769                 er_flags |= (QR_PRIVATE);
770                 }
771         if (!strcmp(buf,"guessname")) {
772                 er_flags |= (QR_PRIVATE | QR_GUESSNAME);
773                 }
774         if (!strcmp(buf,"passworded")) {
775                 er_flags |= (QR_PRIVATE | QR_PASSWORDED);
776                 }
777
778         if (!strcmp(bstr("prefonly"),"yes")) {
779                 er_flags |= QR_PREFONLY;
780                 }
781         else {
782                 er_flags &= ~QR_PREFONLY;
783                 }
784
785         if (!strcmp(bstr("readonly"),"yes")) {
786                 er_flags |= QR_READONLY;
787                 }
788         else {
789                 er_flags &= ~QR_READONLY;
790                 }
791
792         if (!strcmp(bstr("network"),"yes")) {
793                 er_flags |= QR_NETWORK;
794                 }
795         else {
796                 er_flags &= ~QR_NETWORK;
797                 }
798
799         if (!strcmp(bstr("directory"),"yes")) {
800                 er_flags |= QR_DIRECTORY;
801                 }
802         else {
803                 er_flags &= ~QR_DIRECTORY;
804                 }
805
806         if (!strcmp(bstr("ulallowed"),"yes")) {
807                 er_flags |= QR_UPLOAD;
808                 }
809         else {
810                 er_flags &= ~QR_UPLOAD;
811                 }
812
813         if (!strcmp(bstr("dlallowed"),"yes")) {
814                 er_flags |= QR_DOWNLOAD;
815                 }
816         else {
817                 er_flags &= ~QR_DOWNLOAD;
818                 }
819
820         if (!strcmp(bstr("visdir"),"yes")) {
821                 er_flags |= QR_VISDIR;
822                 }
823         else {
824                 er_flags &= ~QR_VISDIR;
825                 }
826
827         strcpy(buf,bstr("anon"));
828
829         er_flags &= ~(QR_ANONONLY | QR_ANONOPT);
830         if (!strcmp(buf,"anononly")) er_flags |= QR_ANONONLY;
831         if (!strcmp(buf,"anon2")) er_flags |= QR_ANONOPT;
832
833         bump = 0;
834         if (!strcmp(bstr("bump"),"yes")) bump = 1;
835
836         er_floor = atoi(bstr("er_floor"));
837
838         sprintf(buf,"SETR %s|%s|%s|%u|%d|%d",
839                 er_name,er_password,er_dirname,er_flags,bump,er_floor);
840         serv_puts(buf);
841         serv_gets(buf);
842         if (buf[0]!='2') {
843                 display_error(&buf[4]);
844                 return;
845                 }
846         gotoroom(er_name, 0);
847
848         if (strlen(er_roomaide)>0) {
849                 sprintf(buf,"SETA %s",er_roomaide);
850                 serv_puts(buf);
851                 serv_gets(buf);
852                 if (buf[0]!='2') {
853                         display_error(&buf[4]);
854                         return;
855                         }
856                 }
857
858         gotoroom(er_name, 1);
859         }
860
861
862
863 /*
864  * display the form for entering a new room
865  */
866 void display_entroom(void) {
867         char buf[256];
868
869         serv_puts("CRE8 0");
870         serv_gets(buf);
871         
872         if (buf[0]!='2') {
873                 display_error(&buf[4]);
874                 return;
875                 }
876
877         printf("HTTP/1.0 200 OK\n");
878         output_headers(1);
879
880         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=000077><TR><TD>");
881         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
882         wprintf("<B>Enter (create) a new room</B>\n");
883         wprintf("</FONT></TD></TR></TABLE>\n");
884
885         wprintf("<FORM METHOD=\"POST\" ACTION=\"/entroom\">\n");
886
887         wprintf("<UL><LI>Name of room: ");      
888         wprintf("<INPUT TYPE=\"text\" NAME=\"er_name\" MAXLENGTH=\"19\">\n");
889
890         wprintf("<LI>Type of room:<UL>\n");
891
892         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"public\" ");
893         wprintf("CHECKED > Public room\n");
894
895         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"guessname\" ");
896         wprintf("> Private - guess name\n");
897
898         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"passworded\" ");
899         wprintf("> Private - require password:\n");
900         wprintf("<INPUT TYPE=\"text\" NAME=\"er_password\" MAXLENGTH=\"9\">\n");
901
902         wprintf("<LI><INPUT TYPE=\"radio\" NAME=\"type\" VALUE=\"invonly\" ");
903         wprintf("> Private - invitation only\n");
904
905         wprintf("<CENTER>\n");
906         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">");
907         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
908         wprintf("</CENTER>\n");
909         wprintf("</FORM></HTML>\n");
910         wDumpContent();
911         }
912
913
914
915 /*
916  * enter a new room
917  */
918 void entroom(void) {
919         char buf[256];
920         char er_name[20];
921         char er_type[20];
922         char er_password[10];
923         int er_num_type;
924
925         if (strcmp(bstr("sc"),"OK")) {
926                 display_error("Cancelled.  No new room was created.");
927                 return;
928                 }
929         
930         strcpy(er_name,bstr("er_name"));
931         strcpy(er_type,bstr("type"));
932         strcpy(er_password,bstr("er_password"));
933
934         er_num_type = 0;
935         if (!strcmp(er_type,"guessname")) er_num_type = 1;
936         if (!strcmp(er_type,"passworded")) er_num_type = 2;
937         if (!strcmp(er_type,"invonly")) er_num_type = 3;
938
939         sprintf(buf,"CRE8 1|%s|%d|%s",er_name,er_num_type,er_password);
940         serv_puts(buf);
941         serv_gets(buf);
942         if (buf[0]!='2') {
943                 display_error(&buf[4]);
944                 return;
945                 }
946         gotoroom(er_name, 1);
947         }
948
949
950 /*
951  * display the screen to enter a private room
952  */
953 void display_private(char *rname, int req_pass)
954 {
955
956         printf("HTTP/1.0 200 OK\n");
957         output_headers(1);
958
959         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
960         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
961         wprintf("<B>Goto a private room</B>\n");
962         wprintf("</FONT></TD></TR></TABLE>\n");
963
964         wprintf("<CENTER>\n");
965         wprintf("If you know the name of a hidden (guess-name) or\n");
966         wprintf("passworded room, you can enter that room by typing\n");
967         wprintf("its name below.  Once you gain access to a private\n");
968         wprintf("room, it will appear in your regular room listings\n");
969         wprintf("so you don't have to keep returning here.\n");
970         wprintf("<BR><BR>");
971         
972         wprintf("<FORM METHOD=\"POST\" ACTION=\"/goto_private\">\n");
973
974         wprintf("<TABLE border><TR><TD>");
975         wprintf("Enter room name:</TD><TD>");
976         wprintf("<INPUT TYPE=\"text\" NAME=\"gr_name\" VALUE=\"%s\" MAXLENGTH=\"19\">\n",rname);
977
978         if (req_pass) {
979                 wprintf("</TD></TR><TR><TD>");
980                 wprintf("Enter room password:</TD><TD>");
981                 wprintf("<INPUT TYPE=\"password\" NAME=\"gr_pass\" MAXLENGTH=\"9\">\n");
982                 }
983
984         wprintf("</TD></TR></TABLE>\n");
985         
986         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">");
987         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
988         wprintf("</FORM></HTML>\n");
989         wDumpContent();
990         }
991
992 /* 
993  * goto a private room
994  */
995 void goto_private(void) {
996         char hold_rm[32];
997         char buf[256];
998         
999         if (strcasecmp(bstr("sc"),"OK")) {
1000                 display_main_menu();
1001                 return;
1002                 }
1003
1004         strcpy(hold_rm,wc_roomname);
1005         strcpy(buf,"GOTO ");
1006         strcat(buf,bstr("gr_name"));
1007         strcat(buf,"|");
1008         strcat(buf,bstr("gr_pass"));
1009         serv_puts(buf);
1010         serv_gets(buf);
1011
1012         if (buf[0]=='2') {
1013                 gotoroom(bstr("gr_name"),1);
1014                 return;
1015                 }
1016
1017         if (!strncmp(buf,"540",3)) {
1018                 display_private(bstr("gr_name"),1);
1019                 return;
1020                 }
1021
1022         printf("HTTP/1.0 200 OK\n");
1023         output_headers(1);
1024         wprintf("%s\n",&buf[4]);
1025         wDumpContent();
1026         return;
1027         }
1028
1029
1030 /*
1031  * display the screen to zap a room
1032  */
1033 void display_zap(void) {
1034         printf("HTTP/1.0 200 OK\n");
1035         output_headers(1);
1036         
1037         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
1038         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
1039         wprintf("<B>Zap (forget) the current room</B>\n");
1040         wprintf("</FONT></TD></TR></TABLE>\n");
1041
1042         wprintf("If you select this option, <em>%s</em> will ", wc_roomname);
1043         wprintf("disappear from your room list.  Is this what you wish ");
1044         wprintf("to do?<BR>\n");
1045
1046         wprintf("<FORM METHOD=\"POST\" ACTION=\"/zap\">\n");
1047         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"OK\">");
1048         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
1049         wprintf("</FORM></HTML>\n");
1050         wDumpContent();
1051         }
1052
1053
1054 /* 
1055  * zap a room
1056  */
1057 void zap(void) {
1058         char buf[256];
1059
1060         if (strcmp(bstr("sc"),"OK")) {
1061                 display_main_menu();
1062                 return;
1063                 }
1064
1065         serv_printf("GOTO %s", wc_roomname);
1066         serv_gets(buf);
1067         if (buf[0] != '2') {
1068                 display_error(&buf[4]);
1069                 return;
1070                 }
1071
1072         serv_puts("FORG");
1073         serv_gets(buf);
1074         if (buf[0] != '2') {
1075                 display_error(&buf[4]);
1076                 return;
1077                 }
1078
1079         gotoroom(bstr("_BASEROOM_"),1);
1080         }
1081
1082
1083
1084
1085 /*
1086  * Confirm deletion of the current room
1087  */
1088 void confirm_delete_room(void) {
1089         char buf[256];
1090         
1091         serv_puts("KILL 0");
1092         serv_gets(buf);
1093         if (buf[0] != '2') {
1094                 display_error(&buf[4]);
1095                 return;
1096                 }
1097
1098         printf("HTTP/1.0 200 OK\n");
1099         output_headers(1);
1100         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
1101         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
1102         wprintf("<B>Confirm deletion of room</B>\n");
1103         wprintf("</FONT></TD></TR></TABLE>\n");
1104
1105         wprintf("<CENTER>");
1106         wprintf("<FORM METHOD=\"POST\" ACTION=\"/delete_room\">\n");
1107
1108         wprintf("Are you sure you want to delete <FONT SIZE=+1>");
1109         escputs(wc_roomname);
1110         wprintf("</FONT>?<BR>\n");
1111
1112         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Delete\">");
1113         wprintf("<INPUT TYPE=\"submit\" NAME=\"sc\" VALUE=\"Cancel\">");
1114
1115         wprintf("</FORM></CENTER></BODY></HTML>\n");
1116         wDumpContent();
1117         }
1118
1119
1120 /*
1121  * Delete the current room
1122  */
1123 void delete_room(void) {
1124         char buf[256];
1125         char sc[256];
1126
1127         strcpy(sc, bstr("sc"));
1128         
1129         if (strcasecmp(sc, "Delete")) {
1130                 display_error("Cancelled.  This room was not deleted.");
1131                 return;
1132                 }
1133
1134         serv_puts("KILL 1");
1135         serv_gets(buf);
1136         if (buf[0] != '2') {
1137                 display_error(&buf[4]);
1138                 }
1139         else {
1140                 gotoroom("_BASEROOM_", 1);
1141                 }
1142         }
1143
1144
1145