Back to index

citadel  8.12
Classes | Enumerations | Functions
rooms.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  ctdlroomlisting

Enumerations

enum  { LISTRMS_NEW_ONLY, LISTRMS_OLD_ONLY, LISTRMS_ALL }

Functions

void listzrooms (CtdlIPC *ipc)
void readinfo (CtdlIPC *ipc)
void forget (CtdlIPC *ipc)
void entroom (CtdlIPC *ipc)
void killroom (CtdlIPC *ipc)
void invite (CtdlIPC *ipc)
void kickout (CtdlIPC *ipc)
void editthisroom (CtdlIPC *ipc)
void roomdir (CtdlIPC *ipc)
void download (CtdlIPC *ipc, int proto)
void ungoto (CtdlIPC *ipc)
void dotungoto (CtdlIPC *ipc, char *towhere)
void whoknows (CtdlIPC *ipc)
void enterinfo (CtdlIPC *ipc)
void knrooms (CtdlIPC *ipc, int kn_floor_mode)
void dotknown (CtdlIPC *ipc, int what, char *match)
void load_floorlist (CtdlIPC *ipc)
void create_floor (CtdlIPC *ipc)
void edit_floor (CtdlIPC *ipc)
void kill_floor (CtdlIPC *ipc)
void enter_bio (CtdlIPC *ipc)
int save_buffer (void *file, size_t filelen, const char *pathname)
void destination_directory (char *dest, const char *supplied_filename)
void do_edit (CtdlIPC *ipc, char *desc, char *read_cmd, char *check_cmd, char *write_cmd)

Class Documentation

struct ctdlroomlisting

Definition at line 45 of file rooms.h.

Collaboration diagram for ctdlroomlisting:
Class Members
struct ctdlroomlisting * lnext
unsigned rlflags
int rlfloor
char rlname
int rlorder
struct ctdlroomlisting * rnext

Enumeration Type Documentation

anonymous enum
Enumerator:
LISTRMS_NEW_ONLY 
LISTRMS_OLD_ONLY 
LISTRMS_ALL 

Definition at line 55 of file rooms.h.


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 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:

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 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:

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 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 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:

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: