5 * Client-side functions which perform room operations
17 #include <sys/types.h>
23 #include "citadel_ipc.h"
33 #define IFNEXPERT if ((userflags&US_EXPERT)==0)
36 void sttybbs(int cmd);
37 void hit_any_key(void);
39 void strprompt(char *prompt, char *str, int len);
40 void newprompt(char *prompt, char *str, int len);
41 void dotgoto(char *towhere, int display_name, int fromungoto);
42 void serv_read(char *buf, int bytes);
43 void formout(char *name);
45 void progress(long int curr, long int cmax);
46 int pattern(char *search, char *patn);
47 int file_checksum(char *filename);
48 int nukedir(char *dirname);
50 extern unsigned room_flags;
51 extern char room_name[];
53 extern char tempdir[];
54 extern int editor_pid;
55 extern char editor_path[];
56 extern int screenwidth;
57 extern int screenheight;
58 extern char fullname[];
60 extern char sigcaught;
61 extern char floor_mode;
62 extern char curr_floor;
67 extern char *uglist[];
68 extern long uglistlsn[];
69 extern int uglistsize;
71 extern char floorlist[128][SIZ];
74 void load_floorlist(void)
79 for (a = 0; a < 128; ++a)
85 strcpy(floorlist[0], "Main Floor");
88 while (serv_gets(buf), strcmp(buf, "000")) {
89 extract(floorlist[extract_int(buf, 0)], buf, 1);
94 void room_tree_list(struct roomlisting *rp)
97 char rmname[ROOMNAMELEN];
105 if (rp->lnext != NULL) {
106 room_tree_list(rp->lnext);
109 if (sigcaught == 0) {
110 strcpy(rmname, rp->rlname);
112 if ((c + strlen(rmname) + 4) > screenwidth) {
114 /* line break, check the paginator */
118 if (f & QR_MAILBOX) {
119 color(BRIGHT_YELLOW);
120 } else if (f & QR_PRIVATE) {
125 pprintf("%s", rmname);
126 if ((f & QR_DIRECTORY) && (f & QR_NETWORK))
128 else if (f & QR_DIRECTORY)
130 else if (f & QR_NETWORK)
134 c = c + strlen(rmname) + 3;
137 if (rp->rnext != NULL) {
138 room_tree_list(rp->rnext);
146 * Room ordering stuff (compare first by floor, then by order)
148 int rordercmp(struct roomlisting *r1, struct roomlisting *r2)
150 if ((r1 == NULL) && (r2 == NULL))
156 if (r1->rlfloor < r2->rlfloor)
158 if (r1->rlfloor > r2->rlfloor)
160 if (r1->rlorder < r2->rlorder)
162 if (r1->rlorder > r2->rlorder)
169 * Common code for all room listings
171 void listrms(char *variety)
175 struct roomlisting *rl = NULL;
176 struct roomlisting *rp;
177 struct roomlisting *rs;
180 /* Ask the server for a room list */
186 while (serv_gets(buf), strcmp(buf, "000")) {
187 rp = malloc(sizeof(struct roomlisting));
188 extract(rp->rlname, buf, 0);
189 rp->rlflags = extract_int(buf, 1);
190 rp->rlfloor = extract_int(buf, 2);
191 rp->rlorder = extract_int(buf, 3);
200 if (rordercmp(rp, rs) < 0) {
201 if (rs->lnext == NULL) {
208 if (rs->rnext == NULL) {
219 room_tree_list(NULL);
225 void list_other_floors(void)
230 for (a = 0; a < 128; ++a) {
231 if ((strlen(floorlist[a]) > 0) && (a != curr_floor)) {
232 if ((c + strlen(floorlist[a]) + 4) > screenwidth) {
236 pprintf("%s: ", floorlist[a]);
237 c = c + strlen(floorlist[a]) + 3;
244 * List known rooms. kn_floor_mode should be set to 0 for a 'flat' listing,
245 * 1 to list rooms on the current floor, or 1 to list rooms on all floors.
247 void knrooms(int kn_floor_mode)
254 if (kn_floor_mode == 0) {
256 pprintf("\n Rooms with unread messages:\n");
259 pprintf("\n\n No unseen messages in:\n");
264 if (kn_floor_mode == 1) {
266 pprintf("\n Rooms with unread messages on %s:\n",
267 floorlist[(int) curr_floor]);
268 snprintf(buf, sizeof buf, "LKRN %d", curr_floor);
271 pprintf("\n\n Rooms with no new messages on %s:\n",
272 floorlist[(int) curr_floor]);
273 snprintf(buf, sizeof buf, "LKRO %d", curr_floor);
276 pprintf("\n\n Other floors:\n");
281 if (kn_floor_mode == 2) {
282 for (a = 0; a < 128; ++a) {
283 if (floorlist[a][0] != 0) {
285 pprintf("\n Rooms on %s:\n",
287 snprintf(buf, sizeof buf, "LKRA %d", a);
295 IFNEXPERT hit_any_key();
299 void listzrooms(void)
300 { /* list public forgotten rooms */
302 pprintf("\n Forgotten public rooms:\n");
306 IFNEXPERT hit_any_key();
310 int set_room_attr(int ibuf, char *prompt, unsigned int sbit)
314 a = boolprompt(prompt, (ibuf & sbit));
315 ibuf = (ibuf | sbit);
317 ibuf = (ibuf ^ sbit);
325 * Select a floor (used in several commands)
326 * The supplied argument is the 'default' floor number.
327 * This function returns the selected floor number.
329 int select_floor(int rfloor)
334 if (floor_mode == 1) {
335 if (floorlist[(int) curr_floor][0] == 0) {
341 safestrncpy(floorstr, floorlist[rfloor],
343 strprompt("Which floor", floorstr, SIZ);
344 for (a = 0; a < 128; ++a) {
346 (floorstr, &floorlist[a][0]))
351 (floorstr, &floorlist[a][0],
355 && (pattern(&floorlist[a][0], floorstr)
360 scr_printf("\n One of:\n");
361 for (a = 0; a < 128; ++a) {
362 if (floorlist[a][0] != 0) {
368 } while (newfloor < 0);
378 * .<A>ide <E>dit room
380 void editthisroom(void)
382 char rname[ROOMNAMELEN];
392 int expire_value = 0;
394 /* Fetch the existing room config */
398 scr_printf("%s\n", &buf[4]);
402 extract(rname, &buf[4], 0);
403 extract(rpass, &buf[4], 1);
404 extract(rdir, &buf[4], 2);
405 rflags = extract_int(&buf[4], 3);
406 rfloor = extract_int(&buf[4], 4);
407 rorder = extract_int(&buf[4], 5);
410 /* Fetch the name of the current room aide */
414 safestrncpy(raide, &buf[4], sizeof raide);
419 if (strlen(raide) == 0) {
420 strcpy(raide, "none");
423 /* Fetch the expire policy (this will silently fail on old servers,
424 * resulting in "default" policy)
426 serv_puts("GPEX room");
429 expire_mode = extract_int(&buf[4], 0);
430 expire_value = extract_int(&buf[4], 1);
433 /* Now interact with the user. */
434 strprompt("Room name", rname, ROOMNAMELEN - 1);
436 rfloor = select_floor(rfloor);
437 rflags = set_room_attr(rflags, "Private room", QR_PRIVATE);
438 if (rflags & QR_PRIVATE) {
439 rflags = set_room_attr(rflags,
440 "Accessible by guessing room name",
444 /* if it's public, clear the privacy classes */
445 if ((rflags & QR_PRIVATE) == 0) {
446 if (rflags & QR_GUESSNAME) {
447 rflags = rflags - QR_GUESSNAME;
449 if (rflags & QR_PASSWORDED) {
450 rflags = rflags - QR_PASSWORDED;
454 /* if it's private, choose the privacy classes */
455 if ((rflags & QR_PRIVATE)
456 && ((rflags & QR_GUESSNAME) == 0)) {
457 rflags = set_room_attr(rflags,
458 "Accessible by entering a password",
461 if ((rflags & QR_PRIVATE)
462 && ((rflags & QR_PASSWORDED) == QR_PASSWORDED)) {
463 strprompt("Room password", rpass, 9);
466 if ((rflags & QR_PRIVATE) == QR_PRIVATE) {
468 boolprompt("Cause current users to forget room", 0);
472 set_room_attr(rflags, "Preferred users only", QR_PREFONLY);
473 rflags = set_room_attr(rflags, "Read-only room", QR_READONLY);
474 rflags = set_room_attr(rflags, "Directory room", QR_DIRECTORY);
475 rflags = set_room_attr(rflags, "Permanent room", QR_PERMANENT);
476 if (rflags & QR_DIRECTORY) {
477 strprompt("Directory name", rdir, 14);
479 set_room_attr(rflags, "Uploading allowed", QR_UPLOAD);
481 set_room_attr(rflags, "Downloading allowed",
484 set_room_attr(rflags, "Visible directory", QR_VISDIR);
486 rflags = set_room_attr(rflags, "Network shared room", QR_NETWORK);
487 rflags = set_room_attr(rflags,
488 "Automatically make all messages anonymous",
490 if ((rflags & QR_ANONONLY) == 0) {
491 rflags = set_room_attr(rflags,
492 "Ask users whether to make messages anonymous",
495 rorder = intprompt("Listing order", rorder, 1, 127);
497 /* Ask about the room aide */
499 strprompt("Room aide (or 'none')", raide, 29);
500 if (!strcasecmp(raide, "none")) {
504 snprintf(buf, sizeof buf, "QUSR %s", raide);
508 scr_printf("%s\n", &buf[4]);
510 } while (buf[0] != '2');
512 if (!strcasecmp(raide, "none")) {
517 /* Angels and demons dancing in my head... */
519 snprintf(buf, sizeof buf, "%d", expire_mode);
520 strprompt("Message expire policy (? for list)", buf, 1);
523 "0. Use the default for this floor\n"
524 "1. Never automatically expire messages\n"
525 "2. Expire by message count\n"
526 "3. Expire by message age\n");
528 } while ((buf[0] < 48) || (buf[0] > 51));
529 expire_mode = buf[0] - 48;
531 /* ...lunatics and monsters underneath my bed */
532 if (expire_mode == 2) {
533 snprintf(buf, sizeof buf, "%d", expire_value);
534 strprompt("Keep how many messages online?", buf, 10);
535 expire_value = atol(buf);
538 if (expire_mode == 3) {
539 snprintf(buf, sizeof buf, "%d", expire_value);
540 strprompt("Keep messages for how many days?", buf, 10);
541 expire_value = atol(buf);
544 /* Give 'em a chance to change their minds */
545 scr_printf("Save changes (y/n)? ");
548 snprintf(buf, sizeof buf, "SETA %s", raide);
552 scr_printf("%s\n", &buf[4]);
555 snprintf(buf, sizeof buf, "SPEX room|%d|%d",
556 expire_mode, expire_value);
560 snprintf(buf, sizeof buf, "SETR %s|%s|%s|%d|%d|%d|%d",
561 rname, rpass, rdir, rflags, rbump, rfloor,
565 scr_printf("%s\n", &buf[4]);
567 dotgoto(rname, 2, 0);
573 * un-goto the previous room
580 snprintf(buf, sizeof buf, "GOTO %s", uglist[uglistsize-1]);
584 scr_printf("%s\n", &buf[4]);
587 snprintf(buf, sizeof buf, "SLRP %ld", uglistlsn[uglistsize-1]);
591 scr_printf("%s\n", &buf[4]);
593 safestrncpy (buf, uglist[uglistsize-1], sizeof(buf));
595 free(uglist[uglistsize]);
596 dotgoto(buf, 0, 1); /* Don't queue ungoto info or we end up in a loop */
600 /* Here's the code for simply transferring the file to the client,
601 * for folks who have their own clientware. It's a lot simpler than
602 * the [XYZ]modem code below...
603 * (This function assumes that a download file is already open on the server)
605 void download_to_local_disk(char *supplied_filename, long total_bytes)
609 long transmitted_bytes = 0L;
616 strcpy(filename, supplied_filename);
617 if (strlen(filename) == 0) {
618 newprompt("Filename: ", filename, 250);
621 scr_printf("Enter the name of the directory to save '%s'\n"
622 "to, or press return for the current directory.\n", filename);
623 newprompt("Directory: ", dbuf, sizeof dbuf);
624 if (strlen(dbuf) == 0)
627 strcat(dbuf, filename);
629 savefp = fopen(dbuf, "w");
630 if (savefp == NULL) {
631 scr_printf("Cannot open '%s': %s\n", dbuf, strerror(errno));
632 /* close the download file at the server */
636 scr_printf("%s\n", &buf[4]);
640 progress(0, total_bytes);
641 while ((transmitted_bytes < total_bytes) && (broken == 0)) {
642 bb = total_bytes - transmitted_bytes;
643 aa = ((bb < 4096) ? bb : 4096);
644 snprintf(buf, sizeof buf, "READ %ld|%ld", transmitted_bytes, aa);
648 scr_printf("%s\n", &buf[4]);
651 packet = extract_int(&buf[4], 0);
652 serv_read(dbuf, packet);
653 if (fwrite(dbuf, packet, 1, savefp) < 1)
655 transmitted_bytes = transmitted_bytes + (long) packet;
656 progress(transmitted_bytes, total_bytes);
659 /* close the download file at the server */
663 scr_printf("%s\n", &buf[4]);
670 * download() - download a file or files. The argument passed to this
671 * function determines which protocol to use.
672 * proto - 0 = paginate, 1 = xmodem, 2 = raw, 3 = ymodem, 4 = zmodem, 5 = save
674 void download(int proto)
679 char transmit_cmd[SIZ];
680 long total_bytes = 0L;
682 long transmitted_bytes = 0L;
688 if ((room_flags & QR_DOWNLOAD) == 0) {
689 scr_printf("*** You cannot download from this room.\n");
693 newprompt("Enter filename: ", filename, 255);
695 snprintf(buf, sizeof buf, "OPEN %s", filename);
699 scr_printf("%s\n", &buf[4]);
702 total_bytes = extract_long(&buf[4], 0);
704 /* Save to local disk, for folks with their own copy of the client */
706 download_to_local_disk(filename, total_bytes);
710 /* Meta-download for public clients */
711 scr_printf("Fetching file from Citadel server...\n");
712 mkdir(tempdir, 0700);
713 snprintf(tempname, sizeof tempname, "%s/%s", tempdir, filename);
714 tpipe = fopen(tempname, "wb");
715 while ((transmitted_bytes < total_bytes) && (broken == 0)) {
716 progress(transmitted_bytes, total_bytes);
717 bb = total_bytes - transmitted_bytes;
718 aa = ((bb < 4096) ? bb : 4096);
719 snprintf(buf, sizeof buf, "READ %ld|%ld", transmitted_bytes, aa);
723 scr_printf("%s\n", &buf[4]);
725 packet = extract_int(&buf[4], 0);
726 serv_read(dbuf, packet);
727 if (fwrite(dbuf, packet, 1, tpipe) < 1) {
730 transmitted_bytes = transmitted_bytes + (long) packet;
733 progress(transmitted_bytes, total_bytes);
735 /* close the download file at the server */
739 scr_printf("%s\n", &buf[4]);
743 snprintf(transmit_cmd, sizeof transmit_cmd,
744 "SHELL=/dev/null; export SHELL; TERM=dumb; export TERM; exec more -d <%s",
748 snprintf(transmit_cmd, sizeof transmit_cmd, "exec sx %s", tempname);
750 snprintf(transmit_cmd, sizeof transmit_cmd, "exec sb %s", tempname);
752 snprintf(transmit_cmd, sizeof transmit_cmd, "exec sz %s", tempname);
754 snprintf(transmit_cmd, sizeof transmit_cmd, "exec cat %s", tempname);
758 system(transmit_cmd);
762 /* clean up the temporary directory */
769 * read directory of this room
781 pprintf("%s\n", &buf[4]);
785 extract(comment, &buf[4], 0);
786 extract(flnm, &buf[4], 1);
787 pprintf("\nDirectory of %s on %s\n", flnm, comment);
788 pprintf("-----------------------\n");
789 while (serv_gets(buf), strcmp(buf, "000")) {
790 extract(flnm, buf, 0);
791 extract(flsz, buf, 1);
792 extract(comment, buf, 2);
793 if (strlen(flnm) <= 14)
794 pprintf("%-14s %8s %s\n", flnm, flsz, comment);
796 pprintf("%s\n%14s %8s %s\n", flnm, "", flsz,
803 * add a user to a private room
807 char aaa[31], bbb[SIZ];
809 /* Because kicking people out of public rooms now sets a LOCKOUT
810 * flag, we need to be able to invite people into public rooms
811 * in order to let them back in again.
816 * if ((room_flags & QR_PRIVATE)==0) {
817 * scr_printf("This is not a private room.\n");
822 newprompt("Name of user? ", aaa, 30);
826 snprintf(bbb, sizeof bbb, "INVT %s", aaa);
829 scr_printf("%s\n", &bbb[4]);
834 * kick a user out of a room
838 char username[31], cmd[SIZ];
840 newprompt("Name of user? ", username, 30);
841 if (strlen(username) == 0) {
845 snprintf(cmd, sizeof cmd, "KICK %s", username);
848 scr_printf("%s\n", &cmd[4]);
853 * aide command: kill the current room
862 scr_printf("%s\n", &aaa[4]);
866 scr_printf("Are you sure you want to kill this room? ");
872 scr_printf("%s\n", &aaa[4]);
875 dotgoto("_BASEROOM_", 0, 0);
879 { /* forget the current room */
882 scr_printf("Are you sure you want to forget this room? ");
889 scr_printf("%s\n", &cmd[4]);
893 /* now return to the lobby */
894 dotgoto("_BASEROOM_", 0, 0);
904 char new_room_name[ROOMNAMELEN];
906 char new_room_pass[10];
914 scr_printf("%s\n", &cmd[4]);
918 newprompt("Name for new room? ", new_room_name, ROOMNAMELEN - 1);
919 if (strlen(new_room_name) == 0) {
922 for (a = 0; a < strlen(new_room_name); ++a) {
923 if (new_room_name[a] == '|') {
924 new_room_name[a] = '_';
928 new_room_floor = select_floor((int) curr_floor);
930 IFNEXPERT formout("roomaccess");
932 scr_printf("<?>Help\n<1>Public room\n<2>Guess-name room\n"
933 "<3>Passworded room\n<4>Invitation-only room\n"
935 "Enter room type: ");
938 } while (((b < '1') || (b > '5')) && (b != '?'));
941 formout("roomaccess");
943 } while ((b < '1') || (b > '5'));
945 scr_printf("%d\n", b);
946 new_room_type = b - 1;
947 if (new_room_type == 2) {
948 newprompt("Enter a room password: ", new_room_pass, 9);
949 for (a = 0; a < strlen(new_room_pass); ++a)
950 if (new_room_pass[a] == '|')
951 new_room_pass[a] = '_';
953 strcpy(new_room_pass, "");
956 scr_printf("\042%s\042, a", new_room_name);
958 scr_printf(" public room.");
960 scr_printf(" guess-name room.");
962 scr_printf(" passworded room, password: %s", new_room_pass);
964 scr_printf("n invitation-only room.");
966 scr_printf(" personal room.");
967 scr_printf("\nInstall it? (y/n) : ");
972 snprintf(cmd, sizeof cmd, "CRE8 1|%s|%d|%s|%d", new_room_name,
973 new_room_type, new_room_pass, new_room_floor);
977 scr_printf("%s\n", &cmd[4]);
981 /* command succeeded... now GO to the new room! */
982 dotgoto(new_room_name, 0, 0);
988 { /* read info file for current room */
991 int r; /* IPC response code */
994 /* Name of currernt room aide */
995 r = CtdlIPCGetRoomAide(buf);
997 safestrncpy(raide, buf, sizeof raide);
1001 if (strlen(raide) > 0)
1002 scr_printf("Room aide is %s.\n\n", raide);
1004 r = CtdlIPCRoomInfo(&text, buf);
1009 fmout(screenwidth, NULL, text, NULL,
1010 ((userflags & US_PAGINATOR) ? 1 : 0), screenheight,
1011 (*raide) ? 2 : 0, 1);
1018 * <W>ho knows room...
1025 if (buf[0] != '1') {
1026 pprintf("%s\n", &buf[4]);
1029 while (serv_gets(buf), strncmp(buf, "000", 3)) {
1031 pprintf("%s\n", buf);
1036 void do_edit(char *desc, char *read_cmd, char *check_cmd, char *write_cmd)
1040 int b, cksum, editor_exit;
1043 if (strlen(editor_path) == 0) {
1044 scr_printf("Do you wish to re-enter %s? ", desc);
1049 fp = fopen(temp, "w");
1052 serv_puts(check_cmd);
1054 if (cmd[0] != '2') {
1055 scr_printf("%s\n", &cmd[4]);
1059 if (strlen(editor_path) > 0) {
1060 serv_puts(read_cmd);
1062 if (cmd[0] == '1') {
1063 fp = fopen(temp, "w");
1064 while (serv_gets(cmd), strcmp(cmd, "000")) {
1065 fprintf(fp, "%s\n", cmd);
1071 cksum = file_checksum(temp);
1073 if (strlen(editor_path) > 0) {
1076 snprintf(tmp, sizeof tmp, "WINDOW_TITLE=%s", desc);
1078 editor_pid = fork();
1079 if (editor_pid == 0) {
1082 sttybbs(SB_RESTORE);
1083 execlp(editor_path, editor_path, temp, NULL);
1089 b = wait(&editor_exit);
1090 } while ((b != editor_pid) && (b >= 0));
1092 scr_printf("Executed %s\n", editor_path);
1096 scr_printf("Entering %s. "
1097 "Press return twice when finished.\n", desc);
1098 fp = fopen(temp, "r+");
1103 if (file_checksum(temp) == cksum) {
1104 scr_printf("*** Aborted.\n");
1108 serv_puts(write_cmd);
1110 if (cmd[0] != '4') {
1111 scr_printf("%s\n", &cmd[4]);
1115 fp = fopen(temp, "r");
1116 while (fgets(cmd, SIZ - 1, fp) != NULL) {
1117 cmd[strlen(cmd) - 1] = 0;
1128 void enterinfo(void)
1129 { /* edit info file for current room */
1130 do_edit("the Info file for this room", "RINF", "EINF 0", "EINF 1");
1133 void enter_bio(void)
1136 snprintf(cmd, sizeof cmd, "RBIO %s", fullname);
1137 do_edit("your Bio", cmd, "NOOP", "EBIO");
1141 * create a new floor
1143 void create_floor(void)
1146 char newfloorname[SIZ];
1150 serv_puts("CFLR xx|0");
1152 if (buf[0] != '2') {
1153 scr_printf("%s\n", &buf[4]);
1157 newprompt("Name for new floor: ", newfloorname, 255);
1158 snprintf(buf, sizeof buf, "CFLR %s|1", newfloorname);
1161 if (buf[0] == '2') {
1162 scr_printf("Floor has been created.\n");
1164 scr_printf("%s\n", &buf[4]);
1171 * edit the current floor
1173 void edit_floor(void)
1176 int expire_mode = 0;
1177 int expire_value = 0;
1181 /* Fetch the expire policy (this will silently fail on old servers,
1182 * resulting in "default" policy)
1184 serv_puts("GPEX floor");
1186 if (buf[0] == '2') {
1187 expire_mode = extract_int(&buf[4], 0);
1188 expire_value = extract_int(&buf[4], 1);
1191 /* Interact with the user */
1192 strprompt("Floor name", &floorlist[(int) curr_floor][0], 255);
1194 /* Angels and demons dancing in my head... */
1196 snprintf(buf, sizeof buf, "%d", expire_mode);
1198 ("Floor default essage expire policy (? for list)",
1200 if (buf[0] == '?') {
1202 "0. Use the system default\n"
1203 "1. Never automatically expire messages\n"
1204 "2. Expire by message count\n"
1205 "3. Expire by message age\n");
1207 } while ((buf[0] < 48) || (buf[0] > 51));
1208 expire_mode = buf[0] - 48;
1210 /* ...lunatics and monsters underneath my bed */
1211 if (expire_mode == 2) {
1212 snprintf(buf, sizeof buf, "%d", expire_value);
1213 strprompt("Keep how many messages online?", buf, 10);
1214 expire_value = atol(buf);
1217 if (expire_mode == 3) {
1218 snprintf(buf, sizeof buf, "%d", expire_value);
1219 strprompt("Keep messages for how many days?", buf, 10);
1220 expire_value = atol(buf);
1224 snprintf(buf, sizeof buf, "SPEX floor|%d|%d",
1225 expire_mode, expire_value);
1229 snprintf(buf, sizeof buf, "EFLR %d|%s", curr_floor,
1230 &floorlist[(int) curr_floor][0]);
1233 scr_printf("%s\n", &buf[4]);
1241 * kill the current floor
1243 void kill_floor(void)
1245 int floornum_to_delete, a;
1250 floornum_to_delete = (-1);
1251 scr_printf("(Press return to abort)\n");
1252 newprompt("Delete which floor? ", buf, 255);
1253 if (strlen(buf) == 0)
1255 for (a = 0; a < 128; ++a)
1256 if (!strcasecmp(&floorlist[a][0], buf))
1257 floornum_to_delete = a;
1258 if (floornum_to_delete < 0) {
1259 scr_printf("No such floor. Select one of:\n");
1260 for (a = 0; a < 128; ++a)
1261 if (floorlist[a][0] != 0)
1262 scr_printf("%s\n", &floorlist[a][0]);
1264 } while (floornum_to_delete < 0);
1265 snprintf(buf, sizeof buf, "KFLR %d|1", floornum_to_delete);
1268 scr_printf("%s\n", &buf[4]);