#include "board.h"
mapping boards,
security,
priv,
timeouts,
archives;
int num;
#define T_MIN 0
#define T_MAX 1
#define T_TIMEOUT 2
#define DEFAULT_MIN 10
#define DEFAULT_MAX 80
#define DEFAULT_TIMEOUT 14
#define ARCHIVE_DIR "/open/boards/"
void expire_boards();
string query_archive(string board);
static int zap_message(string board, int num);
void create() {
num = 1;
boards = ([ ]);
security = ([ ]);
priv = ([ ]); /* Private boards... only lords or specified people
* can read. */
timeouts = ([ ]);
archives = ([ ]);
seteuid((string)"/secure/master"->creator_file(file_name(this_object())));
restore_object(BOARD_FILE,1);
expire_boards();
} /* create() */
string *query_boards() {
return m_indices(boards);
} /* query_boards() */
int query_lord(string str) {
return (int)"/secure/master"->query_lord(str);
} /* query_lord() */
mixed get_subjects(string name) {
string pl;
int bit;
if (file_name(previous_object())[0..10] != "/obj/misc/board"[0..10])
return ({ });
pl = (string)this_player()->query_name();
bit = priv[name] && !query_lord(pl) &&
(member_array(pl, security[name]) == -1);
if (!boards[name] || bit)
return ({ });
return boards[name];
} /* get_subjects() */
string get_message(string board, int num) {
string name;
if (file_name(previous_object())[0..10] != "/obj/misc/board"[0..10])
return 0;
name = (string)this_player()->query_name();
if (!boards[board] || (priv[board] && !query_lord(name)
&& (member_array(geteuid(previous_object()),
security[board]) == -1)))
return 0;
if (num < 0 || num >= sizeof(boards[board]))
return 0;
name = sprintf("%s%d",BOARD_DIR, boards[board][num][B_NUM]);
if (file_size(name) <= 0)
return 0;
return read_file(name);
} /* get_message() */
int save_me() {
save_object(BOARD_FILE,1);
} /* save_me() */
int add_message(string board, string name, string subject, string body) {
string fname;
int test, irp;
test = priv[board] && !query_lord(name) && (-1 == member_array(name,
security[board]));
if (!boards[board] || test)
return 0;
else
boards[board] += ({ ({ subject, name, num++, time() }) });
fname = sprintf("%s%d", BOARD_DIR, num-1);
// Fix by Aragorn
body = replace_string(body,"@@","");
write_file(fname, body);
save_me();
if (timeouts[board] && timeouts[board][T_MAX] &&
sizeof(boards[board]) > timeouts[board][T_MAX]) {
while (sizeof(boards[board]) > timeouts[board][T_MAX]) {
zap_message(board, 0);
irp++;
}
event(users(), "inform", capitalize(name)+" posts a message to "+board+
" and "+irp+" message"+(irp>1?"s":"")+
" explodes in sympathy", "message");
} else
event(users(), "inform", capitalize(name)+" posts a message to "+board,
"message");
return num-1;
} /* add_message() */
int create_board(string board, int priva) {
board = lower_case(board);
if (boards[board])
return 0;
boards[board] = ({ });
security[board] = ({ this_player()->query_name() });
if (priva)
priv[board] = priva;
save_me();
write("Created board "+board+".\n");
return 1;
} /* create_board() */
int add_allowed(string board, string name) {
string nam;
if (sscanf(file_name(previous_object()), "/obj/misc/board%s", nam) != 1)
return 0;
nam = (string)this_player()->query_name();
if (member_array(nam, security[board]) == -1 &&
!"/secure/master"->query_lord(nam))
return 0;
if (!"/secure/login"->test_user(name))
return 0;
security[board] += ({ name });
save_me();
write("Added "+name+" to the security array for "+board+".\n");
return 1;
} /* add_allowed() */
int remove_allowed(string board, string name) {
string nam;
int i;
if (sscanf(file_name(previous_object()), "/obj/misc/board%s", nam) != 1)
return 0;
nam = geteuid(previous_object());
if ((i= member_array(name, security[board])) == -1 &&
!"/secure/master"->query_lord(nam))
return 0;
security[board] = delete(security[board], i, 1);
save_me();
write("Removed "+name+" from the security array for "+board+".\n");
return 1;
} /* add_allowed() */
static int zap_message(string board, int off) {
int num;
string nam, archive;
if (off < 0 || off >= sizeof(boards[board]))
return 0; /* out of range error */
num = boards[board][off][B_NUM];
nam = sprintf("%s%d", BOARD_DIR, num);
archive = query_archive(board);
if (archive) {
mixed *stuff;
stuff = boards[board][off];
write_file(archive,
sprintf("\n----\nNote #%d by %s posted at %s\nTitle: '%s'\n\n",
off, capitalize(stuff[B_NAME]), ctime(stuff[B_TIME]),
stuff[B_SUBJECT])+
read_file(nam));
}
boards[board] = delete(boards[board],off,1);
rm(nam);
save_me();
return 1;
} /* zap_message() */
int delete_message(string board, int off) {
string nam, archive;
int num;
if (file_name(previous_object())[0..10] != "/obj/misc/board"[0..10])
return 0;
nam = geteuid(this_player());
if(!security[board]) security[board] = ({ });
if (member_array(nam, security[board]) == -1 &&
boards[board][off][B_NAME] != nam &&
!"/secure/master"->query_lord(nam))
return 0; /* not allowed to delete the notes */
return zap_message(board, off);
} /* delete_message() */
string *query_security(string board) {
string *str;
str = security[board];
if (!str) return str;
return str + ({ });
} /* query_security() */
int delete_board(string board) {
string nam;
if (!boards[board])
return 0;
nam = geteuid(previous_object());
if (member_array(nam, security[board]) == -1 &&
!"/secure/master"->query_lord(nam))
return 0; /* not allowed to delete the notes */
while (sizeof(boards[board]))
delete_message(board, 0);
boards = m_delete(boards, board);
security = m_delete(security, board);
map_delete(archives, board);
map_delete(timeouts, board);
save_me();
return 1;
} /* delete_board() */
string *list_of_boards() {
return m_indices(boards);
} /* list_of_boards() */
int set_timeout(string board, int timeout) {
string nam;
if (!boards[board]) return 0;
nam = geteuid(previous_object());
if (member_array(nam, security[board]) == -1 &&
!"/secure/master"->query_lord(nam))
return 0; /* not allowed to delete the notes */
if (!timeouts[board]) {
timeouts[board] = ({ DEFAULT_MIN, DEFAULT_MAX, timeout });
return 1;
}
timeouts[board][T_TIMEOUT] = timeout;
save_me();
write("Set the automagic timeout to "+timeout+" days for "+board+".\n");
return 1;
} /* set_timeout() */
int set_minimum(string board, int min) {
string nam;
if (!boards[board]) return 0;
nam = geteuid(previous_object());
if (member_array(nam, security[board]) == -1 &&
!"/secure/master"->query_lord(nam))
return 0; /* not allowed to delete the notes */
if (!timeouts[board]) {
timeouts[board] = ({ min, DEFAULT_MAX, DEFAULT_TIMEOUT });
return 1;
}
timeouts[board][T_MIN] = min;
save_me();
write("Set the minimum number of messages to "+min+" for "+board+".\n");
return 1;
} /* set_minimum() */
int set_maximum(string board, int max) {
string nam;
if (!boards[board]) return 0;
nam = geteuid(previous_object());
if (member_array(nam, security[board]) == -1 &&
!"/secure/master"->query_lord(nam))
return 0; /* not allowed to delete the notes */
if (!timeouts[board]) {
timeouts[board] = ({ DEFAULT_MIN, max, DEFAULT_TIMEOUT });
return 1;
}
timeouts[board][T_MAX] = max;
save_me();
write("Set the maximum number of messages to "+max+" for "+board+".\n");
return 1;
} /* set_maximum() */
int set_archive(string board, string file) {
string nam;
if (!boards[board]) return 0;
nam = geteuid(previous_object());
if (member_array(nam, security[board]) == -1 &&
!"/secure/master"->query_lord(nam))
return 0; /* not allowed to delete the notes */
archives[board] = file;
save_me();
write("Set the archive file to "+file+" for "+board+".\n");
return 1;
} /* set_archive() */
int query_timeout(string board) {
if (!timeouts[board])
return 0;
return timeouts[board][T_TIMEOUT];
} /* query_timeout() */
int query_minimum(string board) {
if (!timeouts[board])
return 0;
return timeouts[board][T_MIN];
} /* query_minimum() */
int query_maximum(string board) {
if (!timeouts[board])
return 0;
return timeouts[board][T_MAX];
} /* query_maximum() */
string query_archive(string board) {
if (!boards[board]) return 0;
if (undefinedp(archives[board]))
return ARCHIVE_DIR+board;
return archives[board];
} /* query_archive() */
void expire_boards() {
string *bo, nam;
int i, tim, num;
bo = keys(timeouts);
for (i=0;i<sizeof(bo);i++) {
nam = bo[i];
if ((tim=timeouts[nam][T_TIMEOUT]) &&
(sizeof(boards[nam]) > timeouts[nam][T_MIN]) &&
((boards[nam][0][B_TIME]+(tim*(24*60*60))) < time())) {
while (sizeof(boards[nam]) > timeouts[nam][T_MIN] &&
boards[nam][0][B_TIME]+(tim*24*60*60) < time()) {
zap_message(nam, 0);
num++;
}
event(users(), "inform", "Board handler removes "+num+" messages "+
"from "+nam, "message");
}
}
if (!find_call_out("expire_boards"))
call_out("expire_boards", 60*60);
} /* expire_boards() */
int convert_board(string board, string *subject, string *body) {
int i;
string sub, name, tim;
if (!boards[board])
create_board(board, 0);
for (i=0;i<sizeof(subject);i++) {
sscanf(subject[i], "%s (%s, %s)", sub, name, tim);
add_message(board, name, sub, body[i]);
}
return 1;
} /* convert_board() */
int query_prevent_shadow() { return 1; }
int query_num() { return num; }