/* Mail.c */
/* Dec 1991, Justin McKinnerney <Joarm> */
#include <stdio.h>
#include <ctype.h>
#include <sys/time.h>
#include "config.h"
#include "db.h"
#include "interface.h"
#include "externs.h"
struct mail *mdb;
mdbref mdb_top;
static const char *dash_line =
"-------------------------------------------------------------------------";
void read_mail(); /* make compiler happy */
void do_mail(player, list, obj)
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(player, to, msg)
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(*(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));
}
mdbref mail_top(player)
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(player, number)
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);
}
void read_mail(player, number)
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(player, mode)
dbref player;
char 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(player, list)
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.");
}
}
void putmref(f, ref)
FILE *f;
mdbref ref;
{
fprintf(f, "%d\n", ref);
}
void putstring(f, s)
FILE *f;
char *s;
{
if(s)
fputs(s, f);
putc('\n', f);
}
mdbref getmref(f)
FILE *f;
{
static char buff[BUFFER_LEN];
fgets(buff, sizeof(buff), f);
return(atol(buff));
}
static const char *getstring(f)
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(f)
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, mdb[loop].message);
}
}
void load_mail(f)
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()
{
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");
}