/* ************************************************************************
* file: mailindex.c Part of CircleMud *
* Usage: list all pieces of mail in a player mail file *
* Written by Jeremy Elson *
* All Rights Reserved *
* Copyright (C) 1993 The Trustees of The Johns Hopkins University *
************************************************************************* */
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include "../mail.h"
#define log(x) puts(x)
/* defines for fseek */
#ifndef SEEK_SET
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#endif
char MAIL_FILE[100];
mail_index_type *mail_index = 0; /* list of recs in the mail file */
position_list_type *free_list = 0; /* list of free positions in file */
long file_end_pos = 0; /* length of file */
void push_free_list(long pos)
{
position_list_type * new_pos;
new_pos = (position_list_type * )malloc(sizeof(position_list_type));
new_pos->position = pos;
new_pos->next = free_list;
free_list = new_pos;
}
long pop_free_list(void)
{
position_list_type * old_pos;
long return_value;
if ((old_pos = free_list) != 0) {
return_value = free_list->position;
free_list = old_pos->next;
free(old_pos);
return return_value;
} else
return file_end_pos;
}
mail_index_type *find_char_in_index(char *searchee)
{
mail_index_type * temp_rec;
if (!*searchee) {
log("Mail system -- non fatal error 1");
return 0;
}
for (temp_rec = mail_index;
(temp_rec && strcmp(temp_rec->recipient, searchee));
temp_rec = temp_rec->next)
;
return temp_rec;
}
void read_from_file(void *buf, int size, long filepos)
{
FILE * mail_file;
if (!(mail_file = fopen(MAIL_FILE, "r+b"))) {
perror("read_from_file (mail.c)");
exit(1);
}
if (filepos % BLOCK_SIZE) {
log("Mail system -- fatal error #2!!!");
return;
}
fseek(mail_file, filepos, SEEK_SET);
fread(buf, size, 1, mail_file);
fclose(mail_file);
return;
}
void index_mail(char *name_to_index, long pos)
{
mail_index_type * new_index;
position_list_type * new_position;
if (!*name_to_index) {
log("Mail system -- non-fatal error 2");
return;
}
if (!(new_index = find_char_in_index(name_to_index))) {
/* name not already in index.. add it */
new_index = (mail_index_type * )malloc(sizeof(mail_index_type));
strncpy(new_index->recipient, name_to_index, NAME_SIZE);
new_index->recipient[strlen(name_to_index)] = '\0';
new_index->list_start = 0;
/* add to front of list */
new_index->next = mail_index;
mail_index = new_index;
}
/* now, add this position to front of position list */
new_position = (position_list_type * )malloc(sizeof(position_list_type));
new_position->position = pos;
new_position->next = new_index->list_start;
new_index->list_start = new_position;
}
/* SCAN_FILE */
/* scan_file is called once during boot-up. It scans through the mail file
and indexes all entries currently in the mail file. */
int scan_file(void)
{
FILE * mail_file;
header_block_type next_block;
int total_messages = 0, block_num = 0;
char buf[100];
if (!(mail_file = fopen(MAIL_FILE, "r"))) {
log("Mail file non-existant... creating new file.");
mail_file = fopen(MAIL_FILE, "w");
fclose(mail_file);
return 1;
}
while (fread(&next_block, sizeof(header_block_type), 1, mail_file)) {
if (next_block.block_type == HEADER_BLOCK) {
index_mail(next_block.to, block_num * BLOCK_SIZE);
total_messages++;
} else if (next_block.block_type == DELETED_BLOCK)
push_free_list(block_num * BLOCK_SIZE);
block_num++;
}
file_end_pos = ftell(mail_file);
sprintf(buf, " %ld bytes read.", file_end_pos);
log(buf);
if (file_end_pos % BLOCK_SIZE) {
log("Error booting mail system -- Mail file corrupt!");
log("Mail disabled!");
return 0;
}
sprintf(buf, " Mail file read -- %d messages.", total_messages);
log(buf);
return 1;
} /* end of scan_file */
int main(int argc, char *argv[])
{
char searchee[NAME_SIZE+1], *ptr;
mail_index_type * i1;
position_list_type * i2;
header_block_type header;
if (argc != 2) {
log("Usage: readmail <filename>");
exit(1);
}
strcpy(MAIL_FILE, argv[1]);
scan_file();
for (i1 = mail_index; i1; i1 = i1->next) {
printf("%s\n", i1->recipient);
for (i2 = i1->list_start; i2; i2 = i2->next) {
read_from_file(&header, BLOCK_SIZE, i2->position);
printf("\t%s\n", header.from);
}
}
exit(0);
}