/* Mail.c */
/* Dec 1991, Justin McKinnerney <Joarm> */
#include "os.h"
#include "config.h"
#include "db.h"
#include "interface.h"
#include "externs.h"
struct mail *mdb;
mdbref mdb_top;
static const char *dash_line =
"-------------------------------------------------------------------------";
static void read_mail (dbref player, mdbref number);
static mdbref mail_top (dbref player);
void do_mail (dbref player, char *list, char *obj)
{
dbref to;
mdbref temp;
if (!Wizard (player) && Typeof (player) != TYPE_PLAYER) {
notify (player, "Sorry, only players can do that.");
return;
}
if (!*list) {
check_mail (player, 1);
return;
}
if (Wizard (player) && !string_compare (list, "mdb-stats")) {
notify (player, tprintf ("There are %d messages total.", mdb_top));
return;
}
if (Wizard (player) && !string_compare (list, "mdb-purge")) {
mail_init ();
fprintf (stderr, "MAIL ERASE BY: %s", db[player].name);
notify (player, "You have cleared ALL mail!");
return;
}
if (*list > '0' && *list <= '9' && (!*obj || obj == NULL)) {
read_mail (player, atol (list));
return;
}
if (!string_compare (list, "clear")) {
clear_mail (player, obj);
return;
}
if (*list > '0' && *list <= '9') {
temp = search_mail (player, atol (list));
if (temp > 0 && temp <= mdb_top)
to = mdb[temp].from;
else {
notify (player, "Invalid message number.");
return;
}
} else if ((to = lookup_player (list)) == NOTHING) {
notify (player, "No such player.");
return;
}
send_mail (player, to, obj);
}
void send_mail (dbref player, dbref to, char *msg)
{
time_t tt;
struct mail *newdb;
char *p;
char temp[BUFFER_LEN];
if (player == to) {
notify (player, "Why would you want to send mail to yourself?");
return;
}
mdb_top++;
if ((newdb =
(struct mail *) realloc (mdb, (mdb_top + 1) * sizeof (struct mail) + 1))
== NULL) {
notify (player, "Out of memory error, please notify God.");
return;
}
memcpy (newdb, mdb, (mdb_top + 1) * sizeof (struct mail) + 1);
mdb = (struct mail *) newdb;
mdb[mdb_top].number = 0;
mdb[mdb_top].number = mail_top (to) + 1;
mdb[mdb_top].message = NULL;
for (p = temp; *msg; msg++) {
if (*msg == '%' && tolower ((int)*(msg + 1) == 'r'))
msg++;
else
*p++ = *msg;
}
*p = 0;
SET (mdb[mdb_top].message, pronoun_substitute (player, temp, player));
mdb[mdb_top].from = player;
mdb[mdb_top].to = to;
mdb[mdb_top].read = 0;
tt = time ((time_t *) 0);
mdb[mdb_top].time = NULL;
strcpy (temp, ctime (&tt));
SET (mdb[mdb_top].time, temp);
mdb[mdb_top].time[strlen (mdb[mdb_top].time) - 1] = 0;
if (db[to].flags & PLAYER_CONNECT)
notify (to, tprintf ("You sense that you have new mail from %s.",
db[player].name));
notify (player, tprintf ("Your mail has been sent to %s.", db[to].name));
}
static mdbref mail_top (dbref player)
{
mdbref loop;
mdbref check = 0;
for (loop = 1; loop <= mdb_top; loop++)
if (mdb[loop].to == player && mdb[loop].number > check)
check = mdb[loop].number;
return (check);
}
mdbref search_mail (dbref player, mdbref number)
{
mdbref loop;
for (loop = 1; loop <= mdb_top; loop++)
if (mdb[loop].to == player && mdb[loop].number == number)
return (loop);
return (0);
}
static void read_mail (dbref player, mdbref number)
{
mdbref msg;
char tbuf1[BUFFER_LEN];
if ((msg = search_mail (player, number)) > 0 && msg <= mdb_top) {
sprintf (tbuf1, "From: %-16s Time: %s", db[(mdb[msg].from)].name,
mdb[msg].time);
if (mdb[msg].read)
sprintf (tbuf1 + strlen (tbuf1), " Status: Read");
else
sprintf (tbuf1 + strlen (tbuf1), " Status: Unread");
notify (player, dash_line);
notify (player, tbuf1);
notify (player, dash_line);
notify (player, mdb[msg].message);
notify (player, dash_line);
mdb[msg].read = 1;
} else
notify (player, "Invalid message number.");
}
void check_mail (dbref player, int mode)
{
mdbref loop;
mdbref num = 0;
char tbuf1[BUFFER_LEN];
switch (mode) {
case 0:
for (loop = 1; loop <= mdb_top && num != 2; loop++)
if (mdb[loop].to == player)
if (mdb[loop].read)
num = 1;
else
num = 2;
switch (num) {
case 0:
notify (player, "\n*** You have no mail ***\n");
break;
case 1:
notify (player, "\n*** You have mail ***\n");
break;
case 2:
notify (player, "\n*** You have NEW mail ***\n");
break;
}
break;
case 1:
notify (player,
"-------------------------------- MAIL -------------------------------");
for (loop = 1; num = search_mail (player, loop); loop++) {
tbuf1[0] = 0;
if (mdb[num].read)
sprintf (tbuf1, "[ ] ");
else
sprintf (tbuf1, "[*] ");
sprintf (tbuf1 + strlen (tbuf1), "%d ", loop);
sprintf (tbuf1 + strlen (tbuf1), "From: %-16s Time: %s",
db[(mdb[num].from)].name, mdb[num].time);
notify (player, tbuf1);
}
notify (player, dash_line);
break;
}
}
void clear_mail (dbref player, char *list)
{
mdbref num, loop;
int flag = 0;
struct mail *newdb;
if (!list || !*list) {
for (loop = 1; num = search_mail (player, loop); loop++) {
flag = 1;
mdb[num].to = mdb[mdb_top].to;
mdb[num].from = mdb[mdb_top].from;
mdb[num].number = mdb[mdb_top].number;
mdb[mdb_top].number = 0;
mdb[num].read = mdb[mdb_top].read;
mdb[num].message = mdb[mdb_top].message;
mdb[num].time = mdb[mdb_top].time;
--mdb_top;
}
if (flag) {
if ((newdb =
(struct mail *) realloc (mdb,
(mdb_top + 1) * sizeof (struct mail) + 1))
== NULL) {
notify (player, "ERROR: Out of memory <Please notify God>");
fprintf (stderr, "ERROR: Out of memory in clear_mail\n");
return;
}
memcpy (newdb, mdb, (mdb_top + 1) * sizeof (struct mail) + 1);
mdb = (struct mail *) newdb;
notify (player, "Mailbox cleared!");
} else
notify (player, "No mail to clear!");
} else {
if (flag = atol (list))
if (num = search_mail (player, flag)) {
mdb[num].to = mdb[mdb_top].to;
mdb[num].from = mdb[mdb_top].from;
mdb[num].number = mdb[mdb_top].number;
mdb[num].read = mdb[mdb_top].read;
mdb[num].message = mdb[mdb_top].message;
mdb[num].time = mdb[mdb_top].time;
--mdb_top;
if ((newdb =
(struct mail *) realloc (mdb,
(mdb_top + 1) * sizeof (struct mail) + 1))
== NULL) {
notify (player, "ERROR: Out of memory <please notify God>");
fprintf (stderr, "ERROR: Out of memory in clear_mail\n");
return;
}
memcpy (newdb, mdb, (mdb_top + 1) * sizeof (struct mail) + 1);
mdb = (struct mail *) newdb;
if (flag < mail_top (player))
for (loop = flag + 1; num = search_mail (player, loop); loop++)
mdb[num].number--;
notify (player, tprintf ("Message #%d cleared!", flag));
} else
notify (player, "Invalid message number.");
}
}
static void putmref (FILE *f, mdbref ref)
{
fprintf (f, "%d\n", ref);
}
static void putstring (FILE *f, char *s)
{
if (s)
fputs (s, f);
putc ('\n', f);
}
static mdbref getmref (FILE *f)
{
static char buff[BUFFER_LEN];
fgets (buff, sizeof (buff), f);
return (atol (buff));
}
static const char *getstring (FILE *f)
{
static char buff[BUFFER_LEN];
char *p;
fgets (buff, sizeof (buff), f);
for (p = buff; *p; p++)
if (*p == '\n') {
*p = '\0';
break;
}
return buff;
}
void dump_mail (FILE *f)
{
mdbref loop;
if (mdb_top <= 0)
return;
putmref (f, mdb_top);
for (loop = 1; loop <= mdb_top; loop++) {
putmref (f, mdb[loop].from);
putmref (f, mdb[loop].to);
putmref (f, mdb[loop].number);
putmref (f, mdb[loop].read);
putstring (f, mdb[loop].time);
putstring (f, (char*)mdb[loop].message);
}
}
void load_mail (FILE *f)
{
mdbref loop;
char temp[BUFFER_LEN];
struct mail *newdb;
mdb_top = 0;
mdb = (struct mail *) malloc (sizeof (struct mail) + 1);
mdb[0].message = 0;
mdb[0].time = 0;
mdb[0].to = 0;
mdb[0].from = 0;
mdb[0].read = 0;
mdb_top = getmref (f);
if ((newdb =
(struct mail *) realloc (mdb, (mdb_top + 1) * sizeof (struct mail) + 1))
== NULL) {
fprintf (stderr, "ERROR: Out of memory in load_mail\n");
return;
}
memcpy (newdb, mdb, (mdb_top + 1) * sizeof (struct mail) + 1);
mdb = (struct mail *) newdb;
for (loop = 1; loop <= mdb_top; loop++) {
mdb[loop].from = getmref (f);
mdb[loop].to = getmref (f);
mdb[loop].number = getmref (f);
mdb[loop].read = getmref (f);
strcpy (temp, getstring (f));
mdb[loop].time = NULL;
SET (mdb[loop].time, temp);
strcpy (temp, getstring (f));
mdb[loop].message = NULL;
SET (mdb[loop].message, temp);
}
}
void mail_init (void)
{
fprintf (stderr, "MAIL INIT\n");
mdb_top = 0;
mdb = (struct mail *) malloc (sizeof (struct mail) + 1);
mdb[0].message = 0;
mdb[0].time = 0;
mdb[0].number = 0;
mdb[0].to = 0;
mdb[0].from = 0;
mdb[0].read = 0;
fprintf (stderr, "INITALIZED\n");
}