/* fcache.c */
#include "config.h"
/*
* This file is part of TeenyMUD II.
* Copyright(C) 1993, 1994, 1995 by Jason Downs.
* All rights reserved.
*
* TeenyMUD II is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* TeenyMUD II is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file 'COPYING'); if not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "conf.h"
#include "fcache.h"
#include "teeny.h"
#include "externs.h"
#include "hash/hash.h"
/* file cache -- cache text files in memory, allowing for line-by-line ret. */
static Hash_Table CacheTable;
static int CacheInited = 0;
static FCACHE *fcache_load _ANSI_ARGS_((char *));
static void fcache_free _ANSI_ARGS_((FCACHE *));
FCACHE *fcache_open(fname, sptr)
char *fname;
off_t *sptr;
{
FHEAD *ret;
Hash_Entry *hp;
struct stat sbuf;
int new;
if((fname == (char *)NULL) || (fname[0] == '\0')) {
*sptr = -1;
return((FCACHE *)NULL);
}
if(!CacheInited) {
Hash_InitTable(&CacheTable, 0, HASH_STRING_KEYS);
CacheInited++;
}
if(stat(fname, &sbuf) != 0) {
*sptr = -1;
return((FCACHE *)NULL);
}
hp = Hash_CreateEntry(&CacheTable, fname, &new);
if (new) {
ret = (FHEAD *)ty_malloc(sizeof(FHEAD), "fcache_open");
ret->stamp = sbuf.st_mtime;
ret->lines = fcache_load(fname);
Hash_SetValue(hp, (int *)ret);
} else {
ret = (FHEAD *)Hash_GetValue(hp);
if(sbuf.st_mtime > ret->stamp) {
fcache_free(ret->lines);
ret->lines = fcache_load(fname);
ret->stamp = sbuf.st_mtime;
Hash_SetValue(hp, (int *)ret);
}
}
*sptr = sbuf.st_size;
return(ret->lines);
}
static FCACHE *fcache_load(fname)
char *fname;
{
FILE *fp;
FCACHE *new, *ptr;
char buffer[128];
fp = fopen(fname, "r");
if(fp == (FILE *)NULL)
return((FCACHE *)NULL);
for(new = (FCACHE *)NULL, ptr = (FCACHE *)NULL;
!feof(fp) && (fgets(buffer, 128, fp) != (char *)NULL);) {
if(new == (FCACHE *)NULL) { /* first line */
new = (FCACHE *)ty_malloc(sizeof(FCACHE), "fcache_open");
new->next = (FCACHE *)NULL;
ptr = new;
} else {
ptr->next = (FCACHE *)ty_malloc(sizeof(FCACHE), "fcache_open");
ptr = ptr->next;
ptr->next = (FCACHE *)NULL;
}
remove_newline(buffer);
if(buffer[0] == '\0') {
ptr->str[0] = buffer[0];
ptr->ptr = ptr->str;
} else {
ptr->line = (char *)ty_strdup(buffer, "fcache_open");
ptr->ptr = ptr->line;
}
}
fclose(fp);
return(new);
}
static void fcache_free(ptr)
register FCACHE *ptr;
{
register FCACHE *next;
while(ptr != (FCACHE *)NULL) {
next = ptr->next;
if(ptr->ptr == ptr->line)
ty_free((VOID *)ptr->line);
ty_free((VOID *)ptr);
ptr = next;
}
}