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