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