Back to index

citadel  8.12
Defines | Functions | Variables
rooms.c File Reference
#include "sysdep.h"
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdarg.h>
#include <libcitadel.h>
#include "citadel.h"
#include "citadel_ipc.h"
#include "citadel_decls.h"
#include "rooms.h"
#include "commands.h"
#include "messages.h"
#include "tuiconfig.h"
#include "snprintf.h"
#include "screen.h"
#include "citadel_dirs.h"

Go to the source code of this file.

Defines

#define IFNEXPERT   if ((userflags&US_EXPERT)==0)

Functions

void stty_ctdl (int cmd)
void dotgoto (CtdlIPC *ipc, char *towhere, int display_name, int fromungoto)
void progress (CtdlIPC *ipc, unsigned long curr, unsigned long cmax)
int pattern (char *search, char *patn)
int file_checksum (char *filename)
int nukedir (char *dirname)
void load_floorlist (CtdlIPC *ipc)
void room_tree_list (struct ctdlroomlisting *rp)
int rordercmp (struct ctdlroomlisting *r1, struct ctdlroomlisting *r2)
static void listrms (struct march *listing, int new_only, int floor_only, unsigned int flags, char *match)
void list_other_floors (void)
void knrooms (CtdlIPC *ipc, int kn_floor_mode)
void listzrooms (CtdlIPC *ipc)
void dotknown (CtdlIPC *ipc, int what, char *match)
int set_room_attr (CtdlIPC *ipc, unsigned int ibuf, char *prompt, unsigned int sbit)
int select_floor (CtdlIPC *ipc, int rfloor)
void editthisroom (CtdlIPC *ipc)
void dotungoto (CtdlIPC *ipc, char *towhere)
void ungoto (CtdlIPC *ipc)
int save_buffer (void *file, size_t filelen, const char *pathname)
void destination_directory (char *dest, const char *supplied_filename)
void download (CtdlIPC *ipc, int proto)
void roomdir (CtdlIPC *ipc)
void invite (CtdlIPC *ipc)
void kickout (CtdlIPC *ipc)
void killroom (CtdlIPC *ipc)
void forget (CtdlIPC *ipc)
void entroom (CtdlIPC *ipc)
void readinfo (CtdlIPC *ipc)
void whoknows (CtdlIPC *ipc)
void do_edit (CtdlIPC *ipc, char *desc, char *read_cmd, char *check_cmd, char *write_cmd)
void enterinfo (CtdlIPC *ipc)
void enter_bio (CtdlIPC *ipc)
void create_floor (CtdlIPC *ipc)
void edit_floor (CtdlIPC *ipc)
void kill_floor (CtdlIPC *ipc)

Variables

unsigned room_flags
char room_name []
char temp []
char tempdir []
int editor_pid
int screenwidth
int screenheight
char fullname []
char sigcaught
char floor_mode
char curr_floor
int ugnum
long uglsn
char * uglist []
long uglistlsn []
int uglistsize
char floorlist [128][SIZ]

Define Documentation

#define IFNEXPERT   if ((userflags&US_EXPERT)==0)

Definition at line 42 of file rooms.c.


Function Documentation

void create_floor ( CtdlIPC ipc)

Definition at line 1289 of file rooms.c.

{
       char buf[SIZ];
       char newfloorname[SIZ];
       int r;               /* IPC response code */

       load_floorlist(ipc);

       r = CtdlIPCCreateFloor(ipc, 0, "", buf);
       if ( (r / 100 != 2) && (r != ERROR + ILLEGAL_VALUE) ) {
              scr_printf("%s\n", buf);
              return;
       }

       newprompt("Name for new floor: ", newfloorname, 255);
       if (!*newfloorname) return;
       r = CtdlIPCCreateFloor(ipc, 1, newfloorname, buf);
       if (r / 100 == 2) {
              scr_printf("Floor has been created.\n");
       } else {
              scr_printf("%s\n", buf);
       }

       load_floorlist(ipc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void destination_directory ( char *  dest,
const char *  supplied_filename 
)

Definition at line 805 of file rooms.c.

{
       static char save_dir[SIZ] = { 0 };

       if (IsEmptyStr(save_dir)) {
              if (getenv("HOME") == NULL) {
                     strcpy(save_dir, ".");
              }
              else {
                     sprintf(save_dir, "%s/Desktop", getenv("HOME"));
                     if (access(save_dir, W_OK) != 0) {
                            sprintf(save_dir, "%s", getenv("HOME"));
                            if (access(save_dir, W_OK) != 0) {
                                   sprintf(save_dir, ".");
                            }
                     }
              }
       }

       sprintf(dest, "%s/%s", save_dir, supplied_filename);
       strprompt("Save as", dest, PATH_MAX);

       /* Remember the directory for next time */
       strcpy(save_dir, dest);
       if (strrchr(save_dir, '/') != NULL) {
              strcpy(strrchr(save_dir, '/'), "");
       }
       else {
              strcpy(save_dir, ".");
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void do_edit ( CtdlIPC ipc,
char *  desc,
char *  read_cmd,
char *  check_cmd,
char *  write_cmd 
)

Definition at line 1185 of file rooms.c.

{
       FILE *fp;
       char cmd[SIZ];
       int b, cksum, editor_exit;

       if (IsEmptyStr(editor_path)) {
              scr_printf("Do you wish to re-enter %s? ", desc);
              if (yesno() == 0)
                     return;
       }

       fp = fopen(temp, "w");
       fclose(fp);

       CtdlIPC_chat_send(ipc, check_cmd);
       CtdlIPC_chat_recv(ipc, cmd);
       if (cmd[0] != '2') {
              scr_printf("%s\n", &cmd[4]);
              return;
       }

       if (!IsEmptyStr(editor_path)) {
              CtdlIPC_chat_send(ipc, read_cmd);
              CtdlIPC_chat_recv(ipc, cmd);
              if (cmd[0] == '1') {
                     fp = fopen(temp, "w");
                     while (CtdlIPC_chat_recv(ipc, cmd), strcmp(cmd, "000")) {
                            fprintf(fp, "%s\n", cmd);
                     }
                     fclose(fp);
              }
       }

       cksum = file_checksum(temp);

       if (!IsEmptyStr(editor_path)) {
              char tmp[SIZ];

              snprintf(tmp, sizeof tmp, "WINDOW_TITLE=%s", desc);
              putenv(tmp);
              stty_ctdl(SB_RESTORE);
              editor_pid = fork();
              if (editor_pid == 0) {
                     chmod(temp, 0600);
                     execlp(editor_path, editor_path, temp, NULL);
                     exit(1);
              }
              if (editor_pid > 0)
                     do {
                            editor_exit = 0;
                            b = ka_wait(&editor_exit);
                     } while ((b != editor_pid) && (b >= 0));
              editor_pid = (-1);
              scr_printf("Executed %s\n", editor_path);
              stty_ctdl(0);
       } else {
              scr_printf("Entering %s.  Press return twice when finished.\n", desc);
              fp = fopen(temp, "r+");
              citedit(fp);
              fclose(fp);
       }

       if (file_checksum(temp) == cksum) {
              scr_printf("*** Aborted.\n");
       }

       else {
              CtdlIPC_chat_send(ipc, write_cmd);
              CtdlIPC_chat_recv(ipc, cmd);
              if (cmd[0] != '4') {
                     scr_printf("%s\n", &cmd[4]);
                     return;
              }

              fp = fopen(temp, "r");
              while (fgets(cmd, SIZ - 1, fp) != NULL) {
                     cmd[strlen(cmd) - 1] = 0;
                     CtdlIPC_chat_send(ipc, cmd);
              }
              fclose(fp);
              CtdlIPC_chat_send(ipc, "000");
       }

       unlink(temp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void dotgoto ( CtdlIPC ipc,
char *  towhere,
int  display_name,
int  fromungoto 
)

Definition at line 343 of file citadel.c.

{
       char aaa[SIZ], bbb[SIZ];
       static long ls = 0L;
       int newmailcount = 0;
       int partial_match, best_match;
       char from_floor;
       int ugpos = uglistsize;
       int r;                      /* IPC result code */
       struct ctdlipcroom *room = NULL;
       int rv = 0;

       /* store ungoto information */
       if (fromungoto == 0) {
              /* sloppy slide them all down, hey it's the client, who cares. :-) */
              if (uglistsize >= (UGLISTLEN-1)) {
                     int lp;
                     free (uglist[0]);
                     for (lp = 0; lp < (UGLISTLEN-1); lp++) {
                            uglist[lp] = uglist[lp+1];
                            uglistlsn[lp] = uglistlsn[lp+1];
                     }
                     ugpos--;
              } else {
                     uglistsize++;
              }
        
              uglist[ugpos] = malloc(strlen(room_name)+1);
              strcpy(uglist[ugpos], room_name);
              uglistlsn[ugpos] = ls;
       }
      
       /* first try an exact match */
       r = CtdlIPCGotoRoom(ipc, towhere, "", &room, aaa);
       if (r / 10 == 54) {
              newprompt("Enter room password: ", bbb, 9);
              r = CtdlIPCGotoRoom(ipc, towhere, bbb, &room, aaa);
              if (r / 10 == 54) {
                     scr_printf("Wrong password.\n");
                     return;
              }
       }      

       /*
        * If a match is not found, try a partial match.
        * Partial matches anywhere in the string carry a weight of 1,
        * left-aligned matches carry a weight of 2.  Pick the room that
        * has the highest-weighted match.  Do not match on forgotten
        * rooms.
        */
       if (r / 100 != 2) {
              struct march *march = NULL;

              best_match = 0;
              strcpy(bbb, "");

              r = CtdlIPCKnownRooms(ipc, SubscribedRooms, AllFloors, &march, aaa);
              if (r / 100 == 1) {
                     /* Run the roomlist; free the data as we go */
                     struct march *mp = march;   /* Current */

                     while (mp) {
                            partial_match = 0;
                            if (pattern(mp->march_name, towhere) >= 0) {
                                   partial_match = 1;
                            }
                            if (!strncasecmp(mp->march_name, towhere, strlen(towhere))) {
                                   partial_match = 2;
                            }
                            if (partial_match > best_match) {
                                   strcpy(bbb, mp->march_name);
                                   best_match = partial_match;
                            }
                            /* Both pointers are NULL at end of list */
                            march = mp->next;
                            free(mp);
                            mp = march;
                     }
              }

              if (IsEmptyStr(bbb)) {
                     scr_printf("No room '%s'.\n", towhere);
                     return;
              }
              r = CtdlIPCGotoRoom(ipc, bbb, "", &room, aaa);
       }
       if (r / 100 != 1 && r / 100 != 2) {
              scr_printf("%s\n", aaa);
              return;
       }
       safestrncpy(room_name, room->RRname, ROOMNAMELEN);
       room_flags = room->RRflags;
       room_flags2 = room->RRflags2;
       from_floor = curr_floor;
       curr_floor = room->RRfloor;

       /* Determine, based on the room's default view, whether an <E>nter message
        * command will be valid here.
        */
       switch(room->RRdefaultview) {
              case VIEW_BBS:
              case VIEW_MAILBOX:
              case VIEW_BLOG:
                                   entmsg_ok = 1;
                                   break;
              default:
                                   entmsg_ok = 0;
                                   break;
       }

       remove_march(room_name, 0);
       if (!strcasecmp(towhere, "_BASEROOM_"))
              remove_march(towhere, 0);
       if (!room->RRunread)
              next_lazy_cmd = 5;   /* Don't read new if no new msgs */
       if ((from_floor != curr_floor) && (display_name > 0) && (floor_mode == 1)) {
              if (floorlist[(int) curr_floor][0] == 0)
                     load_floorlist(ipc);
              scr_printf("(Entering floor: %s)\n", &floorlist[(int) curr_floor][0]);
       }
       if (display_name == 1) {
              color(BRIGHT_WHITE);
              scr_printf("%s ", room_name);
              color(DIM_WHITE);
              scr_printf("- ");
       }
       if (display_name != 2) {
              color(BRIGHT_YELLOW);
              scr_printf("%d ", room->RRunread);
              color(DIM_WHITE);
              scr_printf("new of ");
              color(BRIGHT_YELLOW);
              scr_printf("%d ", room->RRtotal);
              color(DIM_WHITE);
              scr_printf("messages.\n");
       }
       highest_msg_read = room->RRlastread;
       maxmsgnum = room->RRhighest;
       is_mail = room->RRismailbox;
       is_room_aide = room->RRaide;
       ls = room->RRlastread;

       /* read info file if necessary */
       if (room->RRinfoupdated > 0)
              readinfo(ipc);

       /* check for newly arrived mail if we can */
       newmailcount = room->RRnewmail;
       if (newmailcount > 0) {
              color(BRIGHT_RED);
              if (newmailcount == 1) {
                     scr_printf("*** A new mail message has arrived.\n");
              }
              else {
                     scr_printf("*** %d new mail messages have arrived.\n",
                                   newmailcount);
              }
              color(DIM_WHITE);
              if (!IsEmptyStr(rc_gotmail_cmd)) {
                     rv = system(rc_gotmail_cmd);
                     if (rv) 
                            scr_printf("*** failed to check for mail calling %s Reason %d.\n",
                                      rc_gotmail_cmd, rv);
              }
       }
       free(room);

       if (screenwidth>5) snprintf(&status_line[1], screenwidth-1, "%s  |  %s  |  %s  |  %s  |  %d new mail  |",
              (secure ? "Encrypted" : "Unencrypted"),
              ipc->ServInfo.humannode,
              ipc->ServInfo.site_location,
              room_name,
              newmailcount
       );
}

Here is the call graph for this function:

Here is the caller graph for this function:

void dotknown ( CtdlIPC ipc,
int  what,
char *  match 
)

Definition at line 361 of file rooms.c.

{                           /* list rooms according to attribute */
       struct march *listing = NULL;
       struct march *mptr;
       int r;        /* IPC response code */
       char buf[SIZ];

       /* Ask the server for a room list */
       r = CtdlIPCKnownRooms(ipc, AllAccessibleRooms, (-1), &listing, buf);
       if (r / 100 != 1) {
              listing = NULL;
       }

       color(BRIGHT_CYAN);

       switch (what) {
    case 0:
       scr_printf("\n   Anonymous rooms:\n");
           listrms(listing, LISTRMS_ALL, -1, QR_ANONONLY|QR_ANONOPT, NULL);
       scr_printf("\n");
              break;
    case 1:
       scr_printf("\n   Directory rooms:\n");
           listrms(listing, LISTRMS_ALL, -1, QR_DIRECTORY, NULL);
       scr_printf("\n");
              break;
    case 2:
       scr_printf("\n   Matching \"%s\" rooms:\n", match);
           listrms(listing, LISTRMS_ALL, -1, 0, match);
       scr_printf("\n");
              break;
    case 3:
       scr_printf("\n   Preferred only rooms:\n");
           listrms(listing, LISTRMS_ALL, -1, QR_PREFONLY, NULL);
       scr_printf("\n");
              break;
    case 4:
       scr_printf("\n   Private rooms:\n");
           listrms(listing, LISTRMS_ALL, -1, QR_PRIVATE, NULL);
       scr_printf("\n");
              break;
    case 5:
       scr_printf("\n   Read only rooms:\n");
           listrms(listing, LISTRMS_ALL, -1, QR_READONLY, NULL);
       scr_printf("\n");
              break;
    case 6:
       scr_printf("\n   Shared rooms:\n");
           listrms(listing, LISTRMS_ALL, -1, QR_NETWORK, NULL);
       scr_printf("\n");
              break;
       }

       /* Free the room list */
       while (listing) {
              mptr = listing->next;
              free(listing);
              listing = mptr;
       };

       color(DIM_WHITE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void dotungoto ( CtdlIPC ipc,
char *  towhere 
)

Definition at line 687 of file rooms.c.

  {
    /* Find this 'towhere' room in the list ungoto from this room to
       that at the messagepointer position in that room in our ungoto list.
       I suppose I could be a real dick and just ungoto that many places
       in our list. */
    int found = -1;
    int lp;
       char buf[SIZ];
       struct ctdlipcroom *rret = NULL;   /* ignored */
       int r;

       if (uglistsize == 0)
      {
              scr_printf("No rooms to ungoto.\n");
              return;
      }
       if (towhere == NULL)
      {
              scr_printf("Must specify a room to ungoto.\n");
              return;
      }
       if (IsEmptyStr(towhere))
      {
              scr_printf("Must specify a room to ungoto.\n");
              return;
      }
    for (lp = uglistsize-1; lp >= 0; lp--)
      {
        if (strcasecmp(towhere, uglist[lp]) == 0)
          {
            found = lp;
            break;
          }
      }
    if (found == -1)
      {
              scr_printf("Room: %s not in ungoto list.\n", towhere);
       return;
      }

       r = CtdlIPCGotoRoom(ipc, uglist[found], "", &rret, buf);
       if (rret) free(rret);       /* ignored */
       if (r / 100 != 2) {
              scr_printf("%s\n", buf);
              return;
       }
       r = CtdlIPCSetLastRead(ipc, uglistlsn[found] ? uglistlsn[found] : 1, buf);
       if (r / 100 != 2) {
              scr_printf("%s\n", buf);
       }
       safestrncpy(buf, uglist[found], sizeof(buf));
    /* we queue ungoto information here, because we're not really
       ungotoing, we're really going to a random spot in some arbitrary
       room list. */
       dotgoto(ipc, buf, 0, 0);
  }

Here is the call graph for this function:

Here is the caller graph for this function:

void download ( CtdlIPC ipc,
int  proto 
)

Definition at line 843 of file rooms.c.

{
       char buf[SIZ];
       char filename[PATH_MAX];
       char tempname[PATH_MAX];
       char transmit_cmd[SIZ];
       FILE *tpipe = NULL;
/*     int broken = 0;*/
       int r;
       int rv = 0;
       void *file = NULL;   /* The downloaded file */
       size_t filelen = 0L; /* The downloaded file length */

       if ((room_flags & QR_DOWNLOAD) == 0) {
              scr_printf("*** You cannot download from this room.\n");
              return;
       }

       newprompt("Enter filename: ", filename, PATH_MAX);

       /* Save to local disk, for folks with their own copy of the client */
       if (proto == 5) {
              destination_directory(tempname, filename);
              r = CtdlIPCFileDownload(ipc, filename, &file, 0, progress, buf);
              if (r / 100 != 2) {
                     scr_printf("%s\n", buf);
                     return;
              }
              save_buffer(file, (size_t)extract_long(buf, 0), tempname);
              free(file);
              return;
       }

       r = CtdlIPCFileDownload(ipc, filename, &file, 0, progress, buf);
       if (r / 100 != 2) {
              scr_printf("%s\n", buf);
              return;
       }
       filelen = extract_unsigned_long(buf, 0);

       /* Meta-download for public clients */
       /* scr_printf("Fetching file from Citadel server...\n"); */
       mkdir(tempdir, 0700);
       snprintf(tempname, sizeof tempname, "%s/%s", tempdir, filename);
       tpipe = fopen(tempname, "wb");
       if (fwrite(file, filelen, 1, tpipe) < filelen) {
              /* FIXME: restart syscall on EINTR 
                 broken = 1;*/
       }
       fclose(tpipe);
       if (file) free(file);

       if (proto == 0) {
              /* FIXME: display internally instead */
              snprintf(transmit_cmd, sizeof transmit_cmd,
                     "SHELL=/dev/null; export SHELL; TERM=dumb; export TERM; exec more -d <%s",
                     tempname);
       }
       else if (proto == 1)
              snprintf(transmit_cmd, sizeof transmit_cmd, "exec sx %s", tempname);
       else if (proto == 3)
              snprintf(transmit_cmd, sizeof transmit_cmd, "exec sb %s", tempname);
       else if (proto == 4)
              snprintf(transmit_cmd, sizeof transmit_cmd, "exec sz %s", tempname);
       else
              /* FIXME: display internally instead */
              snprintf(transmit_cmd, sizeof transmit_cmd, "exec cat %s", tempname);

       stty_ctdl(SB_RESTORE);
       rv = system(transmit_cmd);
       if (rv != 0)
              scr_printf("failed to download '%s': %d\n", transmit_cmd, rv);
       stty_ctdl(SB_NO_INTR);

       /* clean up the temporary directory */
       nukedir(tempdir);
       ctdl_beep();  /* Beep beep! */
}

Here is the call graph for this function:

Here is the caller graph for this function:

void edit_floor ( CtdlIPC ipc)

Definition at line 1318 of file rooms.c.

{
       char buf[SIZ];
       struct ExpirePolicy *ep = NULL;

       load_floorlist(ipc);

       /* Fetch the expire policy (this will silently fail on old servers,
        * resulting in "default" policy)
        */
       CtdlIPCGetMessageExpirationPolicy(ipc, 1, &ep, buf);

       /* Interact with the user */
       scr_printf("You are editing the floor called \"%s\"\n", 
              &floorlist[(int) curr_floor][0] );
       strprompt("Floor name", &floorlist[(int) curr_floor][0], 255);

       /* Angels and demons dancing in my head... */
       do {
              snprintf(buf, sizeof buf, "%d", ep->expire_mode);
              strprompt
                  ("Floor default message expire policy (? for list)",
                   buf, 1);
              if (buf[0] == '?') {
                     scr_printf("\n"
                            "0. Use the system default\n"
                            "1. Never automatically expire messages\n"
                            "2. Expire by message count\n"
                            "3. Expire by message age\n");
              }
       } while ((buf[0] < '0') || (buf[0] > '3'));
       ep->expire_mode = buf[0] - '0';

       /* ...lunatics and monsters underneath my bed */
       if (ep->expire_mode == 2) {
              snprintf(buf, sizeof buf, "%d", ep->expire_value);
              strprompt("Keep how many messages online?", buf, 10);
              ep->expire_value = atol(buf);
       }

       if (ep->expire_mode == 3) {
              snprintf(buf, sizeof buf, "%d", ep->expire_value);
              strprompt("Keep messages for how many days?", buf, 10);
              ep->expire_value = atol(buf);
       }

       /* Save it */
       CtdlIPCSetMessageExpirationPolicy(ipc, 1, ep, buf);
       CtdlIPCEditFloor(ipc, curr_floor, &floorlist[(int)curr_floor][0], buf);
       scr_printf("%s\n", buf);
       load_floorlist(ipc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void editthisroom ( CtdlIPC ipc)

Definition at line 501 of file rooms.c.

{
       int rbump = 0;
       char raide[USERNAME_SIZE];
       char buf[SIZ];
       struct ctdlroom *attr = NULL;
       struct ExpirePolicy *eptr = NULL;
       int r;                      /* IPC response code */

       /* Fetch the existing room config */
       r = CtdlIPCGetRoomAttributes(ipc, &attr, buf);
       if (r / 100 != 2) {
              scr_printf("%s\n", buf);
              return;
       }
       eptr = &(attr->QRep);

       /* Fetch the name of the current room aide */
       r = CtdlIPCGetRoomAide(ipc, buf);
       if (r / 100 == 2) {
              safestrncpy(raide, buf, sizeof raide);
       } else {
              strcpy(raide, "");
       }
       if (IsEmptyStr(raide)) {
              strcpy(raide, "none");
       }

       /* Fetch the expire policy (this will silently fail on old servers,
        * resulting in "default" policy)
        */
       r = CtdlIPCGetMessageExpirationPolicy(ipc, 0, &eptr, buf);

       /* Now interact with the user. */

       strprompt("Room name", attr->QRname, ROOMNAMELEN-1);
       attr->QRfloor = select_floor(ipc, attr->QRfloor);
       attr->QRflags = set_room_attr(ipc, attr->QRflags, "Private room", QR_PRIVATE);
       if (attr->QRflags & QR_PRIVATE) {
              attr->QRflags = set_room_attr(ipc, attr->QRflags,
                                   "Hidden room (accessible to anyone who knows the room name)",
                                   QR_GUESSNAME);
       }

       /* if it's public, clear the privacy classes */
       if ((attr->QRflags & QR_PRIVATE) == 0) {
              if (attr->QRflags & QR_GUESSNAME) {
                     attr->QRflags = attr->QRflags - QR_GUESSNAME;
              }
              if (attr->QRflags & QR_PASSWORDED) {
                     attr->QRflags = attr->QRflags - QR_PASSWORDED;
              }
       }

       /* if it's private, choose the privacy classes */
       if ((attr->QRflags & QR_PRIVATE)
           && ((attr->QRflags & QR_GUESSNAME) == 0)) {
              attr->QRflags = set_room_attr(ipc, attr->QRflags,
                                   "Accessible by entering a password",
                                   QR_PASSWORDED);
       }
       if ((attr->QRflags & QR_PRIVATE)
           && ((attr->QRflags & QR_PASSWORDED) == QR_PASSWORDED)) {
              strprompt("Room password", attr->QRpasswd, 9);
       }

       if ((attr->QRflags & QR_PRIVATE) == QR_PRIVATE) {
              rbump = boolprompt("Cause current users to forget room", 0);
       }

       attr->QRflags = set_room_attr(ipc, attr->QRflags,
                                   "Preferred users only", QR_PREFONLY);
       attr->QRflags = set_room_attr(ipc, attr->QRflags,
                                   "Read-only room", QR_READONLY);
       attr->QRflags2 = set_room_attr(ipc, attr->QRflags2,
                            "Allow message deletion by anyone who can post",
                            QR2_COLLABDEL);
       attr->QRflags = set_room_attr(ipc, attr->QRflags,
                                   "Permanent room", QR_PERMANENT);
       attr->QRflags2 = set_room_attr(ipc, attr->QRflags2,
                                                           "Subject Required (Force "
                                                           "users to specify a message "
                                   "subject)", QR2_SUBJECTREQ);
       attr->QRflags = set_room_attr(ipc, attr->QRflags,
                                   "Directory room", QR_DIRECTORY);
       if (attr->QRflags & QR_DIRECTORY) {
              strprompt("Directory name", attr->QRdirname, 14);
              attr->QRflags =
                  set_room_attr(ipc, attr->QRflags,
                                          "Uploading allowed", QR_UPLOAD);
              attr->QRflags =
                  set_room_attr(ipc, attr->QRflags, "Downloading allowed",
                              QR_DOWNLOAD);
              attr->QRflags =
                  set_room_attr(ipc, attr->QRflags,
                                          "Visible directory", QR_VISDIR);
       }
       attr->QRflags = set_room_attr(ipc, attr->QRflags,
                                   "Network shared room", QR_NETWORK);
       attr->QRflags2 = set_room_attr(ipc, attr->QRflags2,
                            "Self-service list subscribe/unsubscribe",
                            QR2_SELFLIST);
       attr->QRflags2 = set_room_attr(ipc, attr->QRflags2,
                            "public posting to this room via room_roomname@yourcitadel.org",
                            QR2_SMTP_PUBLIC);
       attr->QRflags2 = set_room_attr(ipc, attr->QRflags2,
                            "moderated mailinglist",
                            QR2_MODERATED);
       attr->QRflags = set_room_attr(ipc, attr->QRflags,
                            "Automatically make all messages anonymous",
                            QR_ANONONLY);
       if ((attr->QRflags & QR_ANONONLY) == 0) {
              attr->QRflags = set_room_attr(ipc, attr->QRflags,
                                   "Ask users whether to make messages anonymous",
                                   QR_ANONOPT);
       }
       attr->QRorder = intprompt("Listing order", attr->QRorder, 0, 127);

       /* Ask about the room aide */
       do {
              strprompt("Room aide (or 'none')", raide, 29);
              if (!strcasecmp(raide, "none")) {
                     strcpy(raide, "");
                     break;
              } else {
                     r = CtdlIPCQueryUsername(ipc, raide, buf);
                     if (r / 100 != 2)
                            scr_printf("%s\n", buf);
              }
       } while (r / 100 != 2);

       /* Angels and demons dancing in my head... */
       do {
              snprintf(buf, sizeof buf, "%d", attr->QRep.expire_mode);
              strprompt("Message expire policy (? for list)", buf, 1);
              if (buf[0] == '?') {
                     scr_printf("\n"
                            "0. Use the default for this floor\n"
                            "1. Never automatically expire messages\n"
                            "2. Expire by message count\n"
                            "3. Expire by message age\n");
              }
       } while ((buf[0] < 48) || (buf[0] > 51));
       attr->QRep.expire_mode = buf[0] - 48;

       /* ...lunatics and monsters underneath my bed */
       if (attr->QRep.expire_mode == 2) {
              snprintf(buf, sizeof buf, "%d", attr->QRep.expire_value);
              strprompt("Keep how many messages online?", buf, 10);
              attr->QRep.expire_value = atol(buf);
       }

       if (attr->QRep.expire_mode == 3) {
              snprintf(buf, sizeof buf, "%d", attr->QRep.expire_value);
              strprompt("Keep messages for how many days?", buf, 10);
              attr->QRep.expire_value = atol(buf);
       }

       /* Give 'em a chance to change their minds */
       scr_printf("Save changes (y/n)? ");

       if (yesno() == 1) {
              r = CtdlIPCSetRoomAide(ipc, raide, buf);
              if (r / 100 != 2) {
                     scr_printf("%s\n", buf);
              }

              r = CtdlIPCSetMessageExpirationPolicy(ipc, 0, eptr, buf);
              if (r / 100 != 2) {
                     scr_printf("%s\n", buf);
              }

              r = CtdlIPCSetRoomAttributes(ipc, rbump, attr, buf);
              scr_printf("%s\n", buf);
              strncpy(buf, attr->QRname, ROOMNAMELEN);
              free(attr);
              if (r / 100 == 2)
                     dotgoto(ipc, buf, 2, 0);
       }
       else free(attr);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void enter_bio ( CtdlIPC ipc)

Definition at line 1279 of file rooms.c.

{
       char cmd[SIZ];
       snprintf(cmd, sizeof cmd, "RBIO %s", fullname);
       do_edit(ipc, "your Bio", cmd, "NOOP", "EBIO");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void enterinfo ( CtdlIPC ipc)

Definition at line 1274 of file rooms.c.

{                           /* edit info file for current room */
       do_edit(ipc, "the Info file for this room", "RINF", "EINF 0", "EINF 1");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void entroom ( CtdlIPC ipc)

Definition at line 1045 of file rooms.c.

{
       char buf[SIZ];
       char new_room_name[ROOMNAMELEN];
       int new_room_type;
       char new_room_pass[10];
       int new_room_floor;
       int a, b;
       int r;                      /* IPC response code */

       /* Check permission to create room */
       r = CtdlIPCCreateRoom(ipc, 0, "", 1, "", 0, buf);
       if (r / 100 != 2) {
              scr_printf("%s\n", buf);
              return;
       }

       newprompt("Name for new room? ", new_room_name, ROOMNAMELEN - 1);
       if (IsEmptyStr(new_room_name)) {
              return;
       }
       for (a = 0; !IsEmptyStr(&new_room_name[a]); ++a) {
              if (new_room_name[a] == '|') {
                     new_room_name[a] = '_';
              }
       }

       new_room_floor = select_floor(ipc, (int) curr_floor);

       IFNEXPERT formout(ipc, "roomaccess");
       do {
              scr_printf("<?>Help\n"
                     "<1>Public room (shown to all users by default)\n"
                     "<2>Hidden room (accessible to anyone who knows the room name)\n"
                     "<3>Passworded room (hidden, plus requires a password to enter)\n"
                     "<4>Invitation-only room (requires access to be granted by an Aide)\n"
                            "<5>Personal room (accessible to you only)\n"
                     "Enter room type: "
              );
              do {
                     b = inkey();
              } while (((b < '1') || (b > '5')) && (b != '?'));
              if (b == '?') {
                     scr_printf("?\n");
                     formout(ipc, "roomaccess");
              }
       } while ((b < '1') || (b > '5'));
       b -= '0';                   /* Portable */
       scr_printf("%d\n", b);
       new_room_type = b - 1;
       if (new_room_type == 2) {
              newprompt("Enter a room password: ", new_room_pass, 9);
              for (a = 0; !IsEmptyStr(&new_room_pass[a]); ++a)
                     if (new_room_pass[a] == '|')
                            new_room_pass[a] = '_';
       } else {
              strcpy(new_room_pass, "");
       }

       scr_printf("\042%s\042, a", new_room_name);
       if (b == 1)
              scr_printf(" public room.");
       if (b == 2)
              scr_printf(" hidden room.");
       if (b == 3)
              scr_printf(" passworded room, password: %s", new_room_pass);
       if (b == 4)
              scr_printf("n invitation-only room.");
       if (b == 5)
              scr_printf(" personal room.");
       scr_printf("\nInstall it? (y/n) : ");
       if (yesno() == 0) {
              return;
       }

       r = CtdlIPCCreateRoom(ipc, 1, new_room_name, new_room_type,
                           new_room_pass, new_room_floor, buf);
       if (r / 100 != 2) {
              scr_printf("%s\n", buf);
              return;
       }

       /* command succeeded... now GO to the new room! */
       dotgoto(ipc, new_room_name, 0, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int file_checksum ( char *  filename)

Definition at line 584 of file routines.c.

{
       int cksum = 0;
       int ch;
       FILE *fp;

       fp = fopen(filename,"r");
       if (fp == NULL) return(0);

       /* yes, this algorithm may allow cksum to overflow, but that's ok
        * as long as it overflows consistently, which it will.
        */
       while (ch=getc(fp), ch>=0) {
              cksum = (cksum + ch);
       }

       fclose(fp);
       return(cksum);
}
void forget ( CtdlIPC ipc)

Definition at line 1023 of file rooms.c.

{                           /* forget the current room */
       char buf[SIZ];

       scr_printf("Are you sure you want to forget this room? ");
       if (yesno() == 0)
              return;

       remove_march(room_name, 0);
       if (CtdlIPCForgetRoom(ipc, buf) / 100 != 2) {
              scr_printf("%s\n", buf);
              return;
       }

       /* now return to the lobby */
       dotgoto(ipc, "_BASEROOM_", 0, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void invite ( CtdlIPC ipc)

Definition at line 967 of file rooms.c.

{
       char username[USERNAME_SIZE];
       char buf[SIZ];

       newprompt("Name of user? ", username, USERNAME_SIZE);
       if (username[0] == 0)
              return;

       CtdlIPCInviteUserToRoom(ipc, username, buf);
       scr_printf("%s\n", buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void kickout ( CtdlIPC ipc)

Definition at line 984 of file rooms.c.

{
       char username[USERNAME_SIZE];
       char buf[SIZ];

       newprompt("Name of user? ", username, USERNAME_SIZE);
       if (username[0] == 0)
              return;

       CtdlIPCKickoutUserFromRoom(ipc, username, buf);
       scr_printf("%s\n", buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void kill_floor ( CtdlIPC ipc)

Definition at line 1377 of file rooms.c.

{
       int floornum_to_delete, a;
       char buf[SIZ];

       load_floorlist(ipc);
       do {
              floornum_to_delete = (-1);
              scr_printf("(Press return to abort)\n");
              newprompt("Delete which floor? ", buf, 255);
              if (IsEmptyStr(buf))
                     return;
              for (a = 0; a < 128; ++a)
                     if (!strcasecmp(&floorlist[a][0], buf))
                            floornum_to_delete = a;
              if (floornum_to_delete < 0) {
                     scr_printf("No such floor.  Select one of:\n");
                     for (a = 0; a < 128; ++a)
                            if (floorlist[a][0] != 0)
                                   scr_printf("%s\n", &floorlist[a][0]);
              }
       } while (floornum_to_delete < 0);
       CtdlIPCDeleteFloor(ipc, 1, floornum_to_delete, buf);
       scr_printf("%s\n", buf);
       load_floorlist(ipc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void killroom ( CtdlIPC ipc)

Definition at line 1001 of file rooms.c.

{
       char aaa[100];
       int r;

       r = CtdlIPCDeleteRoom(ipc, 0, aaa);
       if (r / 100 != 2) {
              scr_printf("%s\n", aaa);
              return;
       }

       scr_printf("Are you sure you want to kill this room? ");
       if (yesno() == 0)
              return;

       r = CtdlIPCDeleteRoom(ipc, 1, aaa);
       scr_printf("%s\n", aaa);
       if (r / 100 != 2)
              return;
       dotgoto(ipc, "_BASEROOM_", 0, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void knrooms ( CtdlIPC ipc,
int  kn_floor_mode 
)

Definition at line 266 of file rooms.c.

{
       int a;
       struct march *listing = NULL;
       struct march *mptr;
       int r;        /* IPC response code */
       char buf[SIZ];


       /* Ask the server for a room list */
       r = CtdlIPCKnownRooms(ipc, SubscribedRooms, (-1), &listing, buf);
       if (r / 100 != 1) {
              listing = NULL;
       }

       load_floorlist(ipc);


       if (kn_floor_mode == 0) {
              color(BRIGHT_CYAN);
              scr_printf("\n   Rooms with unread messages:\n");
              listrms(listing, LISTRMS_NEW_ONLY, -1, 0, NULL);
              color(BRIGHT_CYAN);
              scr_printf("\n\n   No unseen messages in:\n");
              listrms(listing, LISTRMS_OLD_ONLY, -1, 0, NULL);
              scr_printf("\n");
       }

       if (kn_floor_mode == 1) {
              color(BRIGHT_CYAN);
              scr_printf("\n   Rooms with unread messages on %s:\n",
                     floorlist[(int) curr_floor]);
              listrms(listing, LISTRMS_NEW_ONLY, curr_floor, 0, NULL);
              color(BRIGHT_CYAN);
              scr_printf("\n\n   Rooms with no new messages on %s:\n",
                     floorlist[(int) curr_floor]);
              listrms(listing, LISTRMS_OLD_ONLY, curr_floor, 0, NULL);
              color(BRIGHT_CYAN);
              scr_printf("\n\n   Other floors:\n");
              list_other_floors();
              scr_printf("\n");
       }

       if (kn_floor_mode == 2) {
              for (a = 0; a < 128; ++a) {
                     if (floorlist[a][0] != 0) {
                            color(BRIGHT_CYAN);
                            scr_printf("\n   Rooms on %s:\n",
                                   floorlist[a]);
                            listrms(listing, LISTRMS_ALL, a, 0, NULL);
                            scr_printf("\n");
                     }
              }
       }

       /* Free the room list */
       while (listing) {
              mptr = listing->next;
              free(listing);
              listing = mptr;
       };

       color(DIM_WHITE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void list_other_floors ( void  )

Definition at line 244 of file rooms.c.

{
       int a, c;

       c = 1;
       for (a = 0; a < 128; ++a) {
              if ((strlen(floorlist[a]) > 0) && (a != curr_floor)) {
                     if ((c + strlen(floorlist[a]) + 4) > screenwidth) {
                            scr_printf("\n");
                            c = 1;
                     }
                     scr_printf("%s:  ", floorlist[a]);
                     c = c + strlen(floorlist[a]) + 3;
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void listrms ( struct march listing,
int  new_only,
int  floor_only,
unsigned int  flags,
char *  match 
) [static]

Definition at line 175 of file rooms.c.

{
       struct march *mptr;
       struct ctdlroomlisting *rl = NULL;
       struct ctdlroomlisting *rp;
       struct ctdlroomlisting *rs;
       int list_it;

       for (mptr = listing; mptr != NULL; mptr = mptr->next) {
              list_it = 1;

              if ( (new_only == LISTRMS_NEW_ONLY)
                 && ((mptr->march_access & UA_HASNEWMSGS) == 0)) 
                     list_it = 0;

              if ( (new_only == LISTRMS_OLD_ONLY)
                 && ((mptr->march_access & UA_HASNEWMSGS) != 0)) 
                     list_it = 0;

              if ( (floor_only >= 0)
                 && (mptr->march_floor != floor_only))
                     list_it = 0;

              if (flags && (mptr->march_flags & flags) == 0)
                  list_it = 0;

           if (match && (pattern(mptr->march_name, match) == -1))
                     list_it = 0;

              if (list_it) {
                     rp = malloc(sizeof(struct ctdlroomlisting));
                     strncpy(rp->rlname, mptr->march_name, ROOMNAMELEN);
                     rp->rlflags = mptr->march_flags;
                     rp->rlfloor = mptr->march_floor;
                     rp->rlorder = mptr->march_order;
                     rp->lnext = NULL;
                     rp->rnext = NULL;
       
                     rs = rl;
                     if (rl == NULL) {
                            rl = rp;
                     } else {
                            while (rp != NULL) {
                                   if (rordercmp(rp, rs) < 0) {
                                          if (rs->lnext == NULL) {
                                                 rs->lnext = rp;
                                                 rp = NULL;
                                          } else {
                                                 rs = rs->lnext;
                                          }
                                   } else {
                                          if (rs->rnext == NULL) {
                                                 rs->rnext = rp;
                                                 rp = NULL;
                                          } else {
                                                 rs = rs->rnext;
                                          }
                                   }
                            }
                     }
              }
       }

       room_tree_list(NULL);
       room_tree_list(rl);
       color(DIM_WHITE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void listzrooms ( CtdlIPC ipc)

Definition at line 332 of file rooms.c.

{                           /* list public forgotten rooms */
       struct march *listing = NULL;
       struct march *mptr;
       int r;        /* IPC response code */
       char buf[SIZ];


       /* Ask the server for a room list */
       r = CtdlIPCKnownRooms(ipc, UnsubscribedRooms, (-1), &listing, buf);
       if (r / 100 != 1) {
              listing = NULL;
       }

       color(BRIGHT_CYAN);
       scr_printf("\n   Forgotten public rooms:\n");
       listrms(listing, LISTRMS_ALL, -1, 0, NULL);
       scr_printf("\n");

       /* Free the room list */
       while (listing) {
              mptr = listing->next;
              free(listing);
              listing = mptr;
       };

       color(DIM_WHITE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void load_floorlist ( CtdlIPC ipc)

Definition at line 74 of file rooms.c.

{
       int a;
       char buf[SIZ];
       char *listing = NULL;
       int r;               /* IPC response code */

       for (a = 0; a < 128; ++a)
              floorlist[a][0] = 0;

       r = CtdlIPCFloorListing(ipc, &listing, buf);
       if (r / 100 != 1) {
              strcpy(floorlist[0], "Main Floor");
              return;
       }
       while (*listing && !IsEmptyStr(listing)) {
              extract_token(buf, listing, 0, '\n', sizeof buf);
              remove_token(listing, 0, '\n');
              extract_token(floorlist[extract_int(buf, 0)], buf, 1, '|', SIZ);
       }
       free(listing);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int nukedir ( char *  dirname)

Definition at line 607 of file routines.c.

{
       DIR *dp;
       struct dirent *d;
       char filename[SIZ];

       dp = opendir(dirname);
       if (dp == NULL) {
              return(errno);
       }

       while (d = readdir(dp), d != NULL) {
              snprintf(filename, sizeof filename, "%s/%s",
                     dirname, d->d_name);
              unlink(filename);
       }

       closedir(dp);
       return(rmdir(dirname));
}

Here is the caller graph for this function:

int pattern ( char *  search,
char *  patn 
)

Definition at line 387 of file routines.c.

                                      {
       int a,b,len;
       
       len = strlen(patn);
       for (a=0; !IsEmptyStr(&search[a]); ++a) {
              b=strncasecmp(&search[a],patn,len);
              if (b==0) return(b);
       }
       return(-1);
}

Here is the caller graph for this function:

void progress ( CtdlIPC ipc,
unsigned long  curr,
unsigned long  cmax 
)

Definition at line 450 of file routines.c.

{
       static char dots[] =
              "**************************************************";
       char dots_printed[51];
       char fmt[42];
       unsigned long a;

       if (curr >= cmax) {
              scr_printf("\r%79s\r","");
       } else {
              /* a will be range 0-50 rather than 0-100 */
              a=(curr * 50) / cmax;
              sprintf(fmt, "[%%s%%%lds] %%3ld%%%% %%10ld/%%10ld\r", 50 - a);
              strncpy(dots_printed, dots, a);
              dots_printed[a] = 0;
              scr_printf(fmt, dots_printed, "",
                            curr * 100 / cmax, curr, cmax);
              scr_flush();
       }
}
void readinfo ( CtdlIPC ipc)

Definition at line 1133 of file rooms.c.

{                           /* read info file for current room */
       char buf[SIZ];
       char raide[64];
       int r;               /* IPC response code */
       char *text = NULL;

       /* Name of currernt room aide */
       r = CtdlIPCGetRoomAide(ipc, buf);
       if (r / 100 == 2)
              safestrncpy(raide, buf, sizeof raide);
       else
              strcpy(raide, "");

       if (!IsEmptyStr(raide))
              scr_printf("Room aide is %s.\n\n", raide);

       r = CtdlIPCRoomInfo(ipc, &text, buf);
       if (r / 100 != 1)
              return;

       if (text) {
              fmout(screenwidth, NULL, text, NULL, 1);
              free(text);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void room_tree_list ( struct ctdlroomlisting rp)

Definition at line 98 of file rooms.c.

{
       static int c = 0;
       char rmname[ROOMNAMELEN];
       int f;

       if (rp == NULL) {
              c = 1;
              return;
       }

       if (rp->lnext != NULL) {
              room_tree_list(rp->lnext);
       }

       if (sigcaught == 0) {
              strcpy(rmname, rp->rlname);
              f = rp->rlflags;
              if ((c + strlen(rmname) + 4) > screenwidth) {

                     /* line break, check the paginator */
                     scr_printf("\n");
                     c = 1;
              }
              if (f & QR_MAILBOX) {
                     color(BRIGHT_YELLOW);
              } else if (f & QR_PRIVATE) {
                     color(BRIGHT_RED);
              } else {
                     color(DIM_WHITE);
              }
              scr_printf("%s", rmname);
              if ((f & QR_DIRECTORY) && (f & QR_NETWORK))
                     scr_printf("}  ");
              else if (f & QR_DIRECTORY)
                     scr_printf("]  ");
              else if (f & QR_NETWORK)
                     scr_printf(")  ");
              else
                     scr_printf(">  ");
              c = c + strlen(rmname) + 3;
       }

       if (rp->rnext != NULL) {
              room_tree_list(rp->rnext);
       }

       free(rp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void roomdir ( CtdlIPC ipc)

Definition at line 926 of file rooms.c.

{
       char flnm[256];
       char flsz[32];
       char comment[256];
       char mimetype[256];
       char buf[256];
       char *listing = NULL;       /* Returned directory listing */
       int r;

       r = CtdlIPCReadDirectory(ipc, &listing, buf);
       if (r / 100 != 1) {
              scr_printf("%s\n", buf);
              return;
       }

       extract_token(comment, buf, 0, '|', sizeof comment);
       extract_token(flnm, buf, 1, '|', sizeof flnm);
       scr_printf("\nDirectory of %s on %s\n", flnm, comment);
       scr_printf("-----------------------\n");
       while (listing && *listing && !IsEmptyStr(listing)) {
              extract_token(buf, listing, 0, '\n', sizeof buf);
              remove_token(listing, 0, '\n');

              extract_token(flnm, buf, 0, '|', sizeof flnm);
              extract_token(flsz, buf, 1, '|', sizeof flsz);
              extract_token(mimetype, buf, 2, '|', sizeof mimetype);
              extract_token(comment, buf, 3, '|', sizeof comment);
              if (strlen(flnm) <= 14)
                     scr_printf("%-14s %8s %s [%s]\n", flnm, flsz, comment, mimetype);
              else
                     scr_printf("%s\n%14s %8s %s [%s]\n", flnm, "", flsz,
                            comment, mimetype);
       }
       if (listing) free(listing);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int rordercmp ( struct ctdlroomlisting r1,
struct ctdlroomlisting r2 
)

Definition at line 152 of file rooms.c.

{
       if ((r1 == NULL) && (r2 == NULL))
              return (0);
       if (r1 == NULL)
              return (-1);
       if (r2 == NULL)
              return (1);
       if (r1->rlfloor < r2->rlfloor)
              return (-1);
       if (r1->rlfloor > r2->rlfloor)
              return (1);
       if (r1->rlorder < r2->rlorder)
              return (-1);
       if (r1->rlorder > r2->rlorder)
              return (1);
       return (0);
}

Here is the caller graph for this function:

int save_buffer ( void *  file,
size_t  filelen,
const char *  pathname 
)

Definition at line 775 of file rooms.c.

{
       size_t block = 0;
       size_t bytes_written = 0;
       FILE *fp;

       fp = fopen(pathname, "w");
       if (!fp) {
              scr_printf("Cannot open '%s': %s\n", pathname, strerror(errno));
              return 0;
       }
       do {
              block = fwrite((char *)file + bytes_written, 1,
                            filelen - bytes_written, fp);
              bytes_written += block;
       } while (errno == EINTR && bytes_written < filelen);
       fclose(fp);

       if (bytes_written < filelen) {
              scr_printf("Trouble saving '%s': %s\n", pathname,
                            strerror(errno));
              return 0;
       }
       return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int select_floor ( CtdlIPC ipc,
int  rfloor 
)

Definition at line 444 of file rooms.c.

{
       int a, newfloor;
       char floorstr[SIZ];

       if (floor_mode == 1) {
              if (floorlist[(int) curr_floor][0] == 0) {
                     load_floorlist(ipc);
              }

              do {
                     newfloor = (-1);
                     safestrncpy(floorstr, floorlist[rfloor],
                                sizeof floorstr);
                     strprompt("Which floor", floorstr, 255);
                     for (a = 0; a < 128; ++a) {
                            if (!strcasecmp
                                (floorstr, &floorlist[a][0]))
                                   newfloor = a;
                            if ((newfloor < 0)
                                &&
                                (!strncasecmp
                                 (floorstr, &floorlist[a][0],
                                  strlen(floorstr))))
                                   newfloor = a;
                            if ((newfloor < 0)
                                && (pattern(&floorlist[a][0], floorstr)
                                   >= 0))
                                   newfloor = a;
                     }
                     if (newfloor < 0) {
                            scr_printf("\n One of:\n");
                            for (a = 0; a < 128; ++a) {
                                   if (floorlist[a][0] != 0) {
                                          scr_printf("%s\n",
                                                 &floorlist[a][0]);
                                   }
                            }
                     }
              } while (newfloor < 0);
              return (newfloor);
       }

       else {
              scr_printf("Floor selection bypassed because you have "
                     "floor mode disabled.\n");
       }

       return (rfloor);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int set_room_attr ( CtdlIPC ipc,
unsigned int  ibuf,
char *  prompt,
unsigned int  sbit 
)

Definition at line 425 of file rooms.c.

{
       int a;

       a = boolprompt(prompt, (ibuf & sbit));
       ibuf = (ibuf | sbit);
       if (!a) {
              ibuf = (ibuf ^ sbit);
       }
       return (ibuf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void stty_ctdl ( int  cmd)

Definition at line 1163 of file commands.c.

{                           /* BSD version of stty_ctdl() */
       struct sgttyb live;
       static struct sgttyb saved_settings;
       static int last_cmd = 0;

       if (cmd == SB_LAST)
              cmd = last_cmd;
       else
              last_cmd = cmd;

       if ((cmd == 0) || (cmd == 1)) {
              gtty(0, &live);
              live.sg_flags |= CBREAK;
              live.sg_flags |= CRMOD;
              live.sg_flags |= NL1;
              live.sg_flags &= ~ECHO;
              if (cmd == 1)
                     live.sg_flags |= NOFLSH;
              stty(0, &live);
       }
       if (cmd == 2) {
              gtty(0, &saved_settings);
       }
       if (cmd == 3) {
              stty(0, &saved_settings);
       }
}
void ungoto ( CtdlIPC ipc)

Definition at line 745 of file rooms.c.

{
       char buf[SIZ];
       struct ctdlipcroom *rret = NULL;   /* ignored */
       int r;

       if (uglistsize == 0)
              return;

       r = CtdlIPCGotoRoom(ipc, uglist[uglistsize-1], "", &rret, buf);
       if (rret) free(rret);       /* ignored */
       if (r / 100 != 2) {
              scr_printf("%s\n", buf);
              return;
       }
       r = CtdlIPCSetLastRead(ipc, uglistlsn[uglistsize-1] ? uglistlsn[uglistsize-1] : 1, buf);
       if (r / 100 != 2) {
              scr_printf("%s\n", buf);
       }
       safestrncpy(buf, uglist[uglistsize-1], sizeof(buf));
       uglistsize--;
       free(uglist[uglistsize]);
       /* Don't queue ungoto info or we end up in a loop */
       dotgoto(ipc, buf, 0, 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void whoknows ( CtdlIPC ipc)

Definition at line 1164 of file rooms.c.

{
       char buf[256];
       char *listing = NULL;
       int r;

       r = CtdlIPCWhoKnowsRoom(ipc, &listing, buf);
       if (r / 100 != 1) {
              scr_printf("%s\n", buf);
              return;
       }
       while (!IsEmptyStr(listing)) {
              extract_token(buf, listing, 0, '\n', sizeof buf);
              remove_token(listing, 0, '\n');
              if (sigcaught == 0)
                     scr_printf("%s\n", buf);
       }
       free(listing);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char curr_floor

Definition at line 107 of file citadel.c.

Definition at line 80 of file citadel.c.

char floor_mode

Definition at line 106 of file citadel.c.

char floorlist[128][SIZ]

Definition at line 108 of file citadel.c.

char fullname[]

Definition at line 81 of file citadel.c.

unsigned room_flags

Definition at line 82 of file citadel.c.

char room_name[]

Definition at line 85 of file citadel.c.

Definition at line 42 of file screen.c.

Definition at line 43 of file screen.c.

char sigcaught

Definition at line 100 of file citadel.c.

char temp[]

Definition at line 76 of file citadel.c.

char tempdir[]

Definition at line 78 of file citadel.c.

char* uglist[]

Definition at line 86 of file citadel.c.

long uglistlsn[]

Definition at line 87 of file citadel.c.

Definition at line 88 of file citadel.c.

long uglsn
int ugnum