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