wileymud-1.187b/
wileymud-1.187b/attic/
wileymud-1.187b/attic/bin/
wileymud-1.187b/attic/lib/
wileymud-1.187b/attic/lib/adm/
wileymud-1.187b/attic/lib/man/
wileymud-1.187b/attic/lib/new-wld/
wileymud-1.187b/attic/lib/new-wld/default/
wileymud-1.187b/attic/lib/old/
wileymud-1.187b/attic/lib/wld/
wileymud-1.187b/attic/public_html/
wileymud-1.187b/attic/public_html/gfx/
wileymud-1.187b/attic/src/bin/
wileymud-1.187b/attic/src/etc/
wileymud-1.187b/attic/src/libauth-4.0-p5/
wileymud-1.187b/attic/src/sedna/
wileymud-1.187b/backups/
wileymud-1.187b/bin/
wileymud-1.187b/docs/
wileymud-1.187b/etc/
wileymud-1.187b/lib/
wileymud-1.187b/lib/adm/
wileymud-1.187b/lib/boards/
wileymud-1.187b/lib/log/
wileymud-1.187b/lib/man/
wileymud-1.187b/lib/ply/
wileymud-1.187b/lib/ply/a/
wileymud-1.187b/lib/ply/b/
wileymud-1.187b/lib/ply/c/
wileymud-1.187b/lib/ply/d/
wileymud-1.187b/lib/ply/g/
wileymud-1.187b/lib/ply/k/
wileymud-1.187b/lib/ply/m/
wileymud-1.187b/lib/ply/s/
wileymud-1.187b/lib/ply/t/
wileymud-1.187b/public_html/gfx/
wileymud-1.187b/src/bin/
wileymud-1.187b/src/convert/attic/
wileymud-1.187b/src/convert/obj/
wileymud-1.187b/src/convert/perl/
wileymud-1.187b/src/convert/perl/MudConvert/
wileymud-1.187b/src/convert/perl/MudConvert/DUMP/
wileymud-1.187b/src/convert/perl/MudConvert/Report/
wileymud-1.187b/src/convert/perl/MudConvert/WileyMUD/
wileymud-1.187b/src/convert/perl/output/
wileymud-1.187b/src/convert/perl/output/DUMP/
wileymud-1.187b/src/convert/perl/output/Report/
wileymud-1.187b/src/convert/perl/output/WileyMUD/
wileymud-1.187b/src/etc/
wileymud-1.187b/src/etc/init.d/
wileymud-1.187b/src/etc/rc.d/
wileymud-1.187b/src/etc/rc.d/init.d/
wileymud-1.187b/src/lib/
wileymud-1.187b/src/lib/adm/
wileymud-1.187b/src/lib/boards/
wileymud-1.187b/src/lib/log/
wileymud-1.187b/src/lib/man/
wileymud-1.187b/src/lib/ply/
wileymud-1.187b/src/lib/ply/a/
wileymud-1.187b/src/lib/ply/b/
wileymud-1.187b/src/lib/ply/c/
wileymud-1.187b/src/lib/ply/d/
wileymud-1.187b/src/lib/ply/e/
wileymud-1.187b/src/lib/ply/f/
wileymud-1.187b/src/lib/ply/g/
wileymud-1.187b/src/lib/ply/h/
wileymud-1.187b/src/lib/ply/i/
wileymud-1.187b/src/lib/ply/j/
wileymud-1.187b/src/lib/ply/k/
wileymud-1.187b/src/lib/ply/l/
wileymud-1.187b/src/lib/ply/m/
wileymud-1.187b/src/lib/ply/n/
wileymud-1.187b/src/lib/ply/o/
wileymud-1.187b/src/lib/ply/p/
wileymud-1.187b/src/lib/ply/q/
wileymud-1.187b/src/lib/ply/r/
wileymud-1.187b/src/lib/ply/s/
wileymud-1.187b/src/lib/ply/t/
wileymud-1.187b/src/lib/ply/u/
wileymud-1.187b/src/lib/ply/v/
wileymud-1.187b/src/lib/ply/w/
wileymud-1.187b/src/lib/ply/x/
wileymud-1.187b/src/lib/ply/y/
wileymud-1.187b/src/lib/ply/z/
wileymud-1.187b/src/obj/
wileymud-1.187b/src/utils/
wileymud-1.187b/src/utils/mobmaker/
#include <stdio.h>
#include <stdlib.h>
/* #include <unistd.h> */
#include <sys/types.h>
#include <signal.h>
#include <string.h>
#include <ctype.h>
#include <sys/time.h>
#include <time.h>

#include "global.h"
#include "bug.h"
#include "utils.h"
#include "comm.h"
#include "db.h"
#include "interpreter.h"
#include "multiclass.h"
#include "modify.h"
#include "handler.h"
#include "act_info.h"
#define _BOARD_C
#include "board.h"

struct char_data                       *board_kludge_char = NULL;
struct Board                           *board_list = NULL;

void InitBoards()
{
  if (DEBUG > 2)
    log_info("called %s with no arguments", __PRETTY_FUNCTION__);

  /*
   * this is called at the very beginning, like shopkeepers 
   */
  board_list = NULL;

}

void InitABoard(struct obj_data *obj)
{
  struct Board                           *new_board = NULL;
  struct Board                           *tmp = NULL;

  if (DEBUG > 2)
    log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_ONAME(obj));

  if (board_list) {
    /*
     **  try to match a board with an existing board in the game
     */
    for (tmp = board_list; tmp; tmp = tmp->next) {
      if (tmp->Vnum == obj->item_number) {
        board_load_board(tmp);
	return;
      }
    }
  }

  CREATE(new_board, struct Board, 1);
  new_board->Vnum = obj_index[obj->item_number].virtual;
  board_load_board(new_board);

  tmp = board_list;
  new_board->next = tmp;
  board_list = new_board;
}

struct Board                           *FindBoardInRoom(int room)
{
  struct obj_data                        *o = NULL;
  struct Board                           *nb = NULL;

  if (DEBUG > 2)
    log_info("called %s with %d", __PRETTY_FUNCTION__, room);

  if (!real_roomp(room))
    return (NULL);

  for (o = real_roomp(room)->contents; o; o = o->next_content) {
    if (obj_index[o->item_number].func == (ifuncp)board) {
      for (nb = board_list; nb; nb = nb->next) {
	if (nb->Vnum == obj_index[o->item_number].virtual)
	  return (nb);
      }
      return (NULL);
    }
  }
  return (NULL);
}

/*
 * This is a special procedure, the cmd/arg arguments must be in this order!
 */
int board(struct char_data *ch, int cmd, char *arg)
{
  struct Board                           *nb = NULL;

  if (DEBUG > 2)
    log_info("called %s with %s, %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch), VNULL(arg), cmd);

  nb = FindBoardInRoom(ch->in_room);

  if (!nb)
    return (FALSE);

  if (!ch->desc)
    return (FALSE);

  switch (cmd) {
    case CMD_north:
    case CMD_east:
    case CMD_south:
    case CMD_west:
    case CMD_up:
    case CMD_down:
    case CMD_who:
    case CMD_tell:
    case CMD_exits:
    case CMD_goto:
    case CMD_pager:
    case CMD_shutdown:
      return FALSE;
      break;
    case CMD_look:					       /* look */
      if (!board_show_board(ch, arg, nb))		       /* no args, or failed */
	do_look(ch, "", 0);
      return TRUE;
      break;
    case CMD_write:					       /* write */
      board_write_msg(ch, arg, nb);
      return TRUE;
      break;
    case CMD_read:					       /* read */
      board_display_msg(ch, arg, nb);
      return TRUE;
      break;
    case CMD_remove:					       /* remove */
      board_remove_msg(ch, arg, nb);
      return TRUE;
      break;
    default:
      return TRUE;
  }
}

void board_write_msg(struct char_data *ch, char *arg, struct Board *b)
{
  char                                    new_arg[60] = "\0\0\0";
  char                                    time_str[60] = "\0\0\0";
  struct tm                              *tm_info = NULL;
  time_t                                  tc;

  if (DEBUG > 2)
    log_info("called %s with %s, %s, %08zx", __PRETTY_FUNCTION__, SAFE_NAME(ch), VNULL(arg), (size_t)b);

  if (b->msg_num > MAX_MSGS - 1) {
    cprintf(ch, "The board is full already.\r\n");
    return;
  }
  if (board_kludge_char) {
    cprintf(ch, "Sorry, but someone has stolen the pen.. wait a few minutes.\r\n");
    return;
  }

  for (; isspace(*arg); arg++);

  if (!*arg) {
    cprintf(ch, "We must have a headline!\r\n");
    return;
  }
  board_kludge_char = ch;

  tc = time(0);
  tm_info = (struct tm *)localtime(&tc);

  /*
   * +4 is for a space and '()' around the character name. 
   */
  CREATE(b->head[b->msg_num], char, 70 + strlen(GET_NAME(ch)) + 4);

  strncpy(new_arg, arg, 40);
  sprintf(time_str, "%s", asctime(tm_info));
  time_str[strlen(time_str) - 1] = '\0';
  sprintf(b->head[b->msg_num], "%s (%s) %s", new_arg, GET_NAME(ch), time_str);
  b->msgs[b->msg_num] = NULL;

  cprintf(ch, "Write your message. Terminate with an @.\r\n\r\n");
  act("$n starts to write a message.", TRUE, ch, 0, 0, TO_ROOM);

  ch->desc->str = &b->msgs[b->msg_num];
  ch->desc->max_str = MAX_MESSAGE_LENGTH;

  b->msg_num++;
}

int board_remove_msg(struct char_data *ch, char *arg, struct Board *b)
{
  int                                     ind = 0;
  int                                     msg = 0;
  char                                    msg_number[MAX_INPUT_LENGTH] = "\0\0\0";

  if (DEBUG > 2)
    log_info("called %s with %s, %s, %08zx", __PRETTY_FUNCTION__, SAFE_NAME(ch), VNULL(arg), (size_t)b);

  one_argument(arg, msg_number);

  if (!*msg_number || !isdigit(*msg_number))
    return (0);
  if (!(msg = atoi(msg_number)))
    return (0);
  if (!b->msg_num) {
    cprintf(ch, "The board is empty!\r\n");
    return (1);
  }
  if (msg < 1 || msg > b->msg_num) {
    cprintf(ch, "That message exists only in your imagination..\r\n");
    return (1);
  }
  if (GetMaxLevel(ch) < 19) {
    cprintf(ch, "Due to misuse of the REMOVE command, only 19th level\r\n");
    cprintf(ch, "and above can remove messages.\r\n");
    return 1;
  }
  ind = msg;
  ind--;
  DESTROY(b->head[ind]);
  DESTROY(b->msgs[ind]);
  for (; ind < b->msg_num - 1; ind++) {
    b->head[ind] = b->head[ind + 1];
    b->msgs[ind] = b->msgs[ind + 1];
  }
  b->msg_num--;
  board_save_board(b);
  cprintf(ch, "Message %d removed.\r\n", msg);
  return (1);
}

void board_reset_board(struct Board *b)
{
  int                                     ind = 0;

  if (DEBUG > 2)
    log_info("called %s with %08zx", __PRETTY_FUNCTION__, (size_t)b);

  for (ind = 0; ind < MAX_MSGS; ind++) {
    DESTROY(b->head[ind]);
    DESTROY(b->msgs[ind]);
    b->head[ind] = b->msgs[ind] = NULL;
  }
  b->msg_num = 0;
  return;
}

int board_display_msg(struct char_data *ch, char *arg, struct Board *b)
{
  char                                    msg_number[MAX_INPUT_LENGTH] = "\0\0\0";
  int                                     msg = 0;

  if (DEBUG > 2)
    log_info("called %s with %s, %s, %08zx", __PRETTY_FUNCTION__, SAFE_NAME(ch), VNULL(arg), (size_t)b);

  one_argument(arg, msg_number);
  if (!*msg_number || !isdigit(*msg_number))
    return (0);
  if (!(msg = atoi(msg_number)))
    return (0);
  if (!b->msg_num) {
    cprintf(ch, "The board is empty!\r\n");
    return (1);
  }
  if (msg < 1 || msg > b->msg_num) {
    cprintf(ch, "That message exists only in your imagination..\r\n");
    return (1);
  }
  page_printf(ch, "Message %d : %s\r\n\r\n%s", msg, b->head[msg - 1], b->msgs[msg - 1]);
  return (1);
}

int board_show_board(struct char_data *ch, char *arg, struct Board *b)
{
  int                                     i = 0;
  char                                    tmp[MAX_INPUT_LENGTH] = "\0\0\0";

  if (DEBUG > 2)
    log_info("called %s with %s, %s, %08zx", __PRETTY_FUNCTION__, SAFE_NAME(ch), VNULL(arg), (size_t)b);

  one_argument(arg, tmp);

  if (!*tmp || !isname(tmp, "board bulletin"))
    return (0);

  if (board_kludge_char) {
    cprintf(ch, "Sorry, but someone is writing a message\r\n");
    return (0);
  }

  page_printf(ch, "This is a bulletin board. Usage: READ/REMOVE <messg #>, WRITE <header>\r\n");
  if (!b->msg_num) {
    page_printf(ch, "The board is empty.\r\n");
  } else if (b->msg_num == 1) {
    page_printf(ch, "There is 1 message on the board.\r\n");
  } else {
    page_printf(ch, "There are %d messages on the board.\r\n", b->msg_num);
  }
  for (i = 0; i < b->msg_num; i++)
    page_printf(ch, "%-2d : %s\r\n", i + 1, b->head[i]);

  return (1);
}

void board_save_board(struct Board *bp)
{
    FILE *fp = NULL;
    int board_id = 0;
    int message_id = 0;
    char board_filename[MAX_STRING_LENGTH] = "\0\0\0\0\0\0\0";
    int i = 0;

    if (DEBUG > 2)
        log_info("called %s with %08zx", __PRETTY_FUNCTION__, (size_t)bp);

    if (!bp)
        return;

    if (!bp->msg_num) {
        log_info("No messages to save.\r\n");
        return;
    }

    board_id = bp->Vnum;
    sprintf(board_filename, "%s/%d.data", BOARD_DIR, board_id);
    if(!(fp = fopen(board_filename, "w"))) {
        log_error("Cannot open %s for writing!", board_filename);
        return;
    }

    fprintf(fp, "%d\n", bp->msg_num);
    for (i = 0; i < bp->msg_num; i++) {
        char message_date[25] = "\0\0\0\0\0\0\0";
        char message_header[MAX_STRING_LENGTH] = "\0\0\0\0\0\0\0";
        char message_sender[MAX_STRING_LENGTH] = "\0\0\0\0\0\0\0";
        char message_text[MAX_STRING_LENGTH] = "\0\0\0\0\0\0\0";
        char *mp = NULL;
        
        message_id = i;

        /* Adventurers WANTED! (Quixadhal) Sun Jul 25 00:35:39 2004 */
        strcpy(message_date, bp->head[i] + strlen(bp->head[i]) - 24);
        strcpy(message_header, bp->head[i]);
        message_header[strlen(message_header) - 26] = '\0';

        mp = strrchr(message_header, '(');
        if (mp) {
            strcpy(message_sender, mp + 1);
            *(mp - 1) = '\0';
        } else {
            *message_sender = '\0';
        }

        if (!bp->msgs[i]) {
            CREATE(bp->msgs[i], char, 50);			       /* Quixadhal: Why 50? */
            strcpy(bp->msgs[i], "Generic Message");
        }
        strcpy(message_text, bp->msgs[i]);

        fprintf(fp, "%d\n%s~\n%s~\n%s~\n%s~\n", message_id, message_date, message_sender, message_header, message_text);
    }
    fclose(fp);
}

void board_load_board(struct Board *bp)
{
    FILE *fp = NULL;
    int board_id = 0;
    int message_id = 0;
    char board_filename[MAX_STRING_LENGTH] = "\0\0\0\0\0\0\0";
    int message_count = 0;
    int i = 0;

    if (DEBUG > 2)
        log_info("called %s with %08zx", __PRETTY_FUNCTION__, (size_t)bp);

    if (!bp)
        return;

    board_id = bp->Vnum;
    sprintf(board_filename, "%s/%d.data", BOARD_DIR, board_id);
    if(!(fp = fopen(board_filename, "r"))) {
        log_error("Cannot open %s for reading!", board_filename);
        return;
    }

    message_count = fread_number(fp);
    bp->msg_num = MIN(MAX_MSGS, message_count);
    if(message_count >= MAX_MSGS)
        log_error("BOARD %d IS FULL!", board_id);

    for (i = 0; i < bp->msg_num; i++) {
        char *message_date = NULL;
        char *message_header = NULL;
        char *message_sender = NULL;
        char *message_text = NULL;
        char full_header[MAX_STRING_LENGTH] = "\0\0\0\0\0\0\0";
        
        message_id = fread_number(fp);
        message_date = strdup(new_fread_string(fp));
        message_sender = strdup(new_fread_string(fp));
        message_header = strdup(new_fread_string(fp));
        message_text = strdup(new_fread_string(fp));

        /* Adventurers WANTED! (Quixadhal) Sun Jul 25 00:35:39 2004 */
        strcpy(full_header, message_header);
        strcat(full_header, " (");
        strcat(full_header, message_sender);
        strcat(full_header, ") ");
        strcat(full_header, message_date);

        free(message_date);
        free(message_header);
        free(message_sender);
        CREATE(bp->head[message_id], char, strlen(full_header) + 1);
        strcpy(bp->head[message_id], full_header);
        bp->msgs[message_id] = message_text;
    }
    fclose(fp);
}