/*
* This file handles input/output to files (including log)
*/
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include <stdlib.h>
/* include main header file */
#include "mud.h"
extern FILE *stderr;
time_t current_time;
/*
* Nifty little extendable logfunction,
* if it wasn't for Erwins social editor,
* I would never have known about the
* va_ functions.
*/
void log_string(const char *txt, ...)
{
FILE *fp;
char logfile[MAX_BUFFER];
char buf[MAX_BUFFER];
char *strtime = get_time();
va_list args;
va_start(args, txt);
vsprintf(buf, txt, args);
va_end(args);
/* point to the correct logfile */
sprintf(logfile, "../log/%6.6s.log", strtime);
/* try to open logfile */
if ((fp = fopen(logfile, "a")) == NULL)
{
communicate(NULL, "log: cannot open logfile", COMM_LOG);
return;
}
fprintf(fp, "%s: %s\n", strtime, buf);
fclose(fp);
communicate(NULL, buf, COMM_LOG);
}
/*
* Nifty little extendable bugfunction,
* if it wasn't for Erwins social editor,
* I would never have known about the
* va_ functions.
*/
void bug(const char *txt, ...)
{
FILE *fp;
char buf[MAX_BUFFER];
va_list args;
char *strtime = get_time();
va_start(args, txt);
vsprintf(buf, txt, args);
va_end(args);
/* try to open logfile */
if ((fp = fopen("../log/bugs.txt", "a")) == NULL)
{
communicate(NULL, "bug: cannot open bugfile", COMM_LOG);
return;
}
fprintf(fp, "%s: %s\n", strtime, buf);
fclose(fp);
communicate(NULL, buf, COMM_LOG);
}
/*
* This function will return the time of
* the last modification made to helpfile.
*/
time_t last_modified(char *helpfile)
{
char fHelp[256];
struct stat sBuf;
time_t mTime = 0;
sprintf(fHelp, "../help/%s", helpfile);
if (stat(fHelp, &sBuf) >= 0)
mTime = sBuf.st_mtime;
return mTime;
}
char *read_help_entry(const char *helpfile)
{
FILE *fp;
static char entry[MAX_HELP_ENTRY];
char fHelp[256];
int c, ptr = 0;
/* location of the help file */
sprintf(fHelp, "../help/%s", helpfile);
/* if there is no help file, return NULL */
if ((fp = fopen(fHelp, "r")) == NULL)
return NULL;
/* just to have something to work with */
c = getc(fp);
/* read the file in the buffer */
while (c != EOF)
{
if (c == '\n')
entry[ptr++] = '\r';
entry[ptr] = c;
if (++ptr > MAX_BUFFER - 2)
{
bug("Read_help_entry: String to long.");
abort();
}
c = getc(fp);
}
entry[ptr] = '\0';
fclose(fp);
/* return a pointer to the static buffer */
return entry;
}
/*
* Reads one line from a file, and returns a
* pointer to a _static array_ holding the line.
*/
char *fread_line(FILE *fp)
{
static char line[MAX_BUFFER];
int c, entry = 0;
/* read one line from the file */
c = getc(fp);
while (c != EOF && c != '\n')
{
line[entry] = c;
if (++entry > MAX_BUFFER - 1)
{
bug("Fread_line: Line to long.");
abort();
}
c = getc(fp);
}
line[entry] = '\0';
/* did we actually read anything ? */
if (entry == 0) return NULL;
/* return a pointer to the static buffer */
return line;
}
/*
* Reads one number from a file, returning
* the value as an integer, a leading '-' will
* be intepreted as a negative value, and this
* is the only non-digit that the function
* will not choke and die upon reading.
*/
int fread_number(FILE *fp)
{
int c, number = 0;
bool negative = FALSE;
/* initial read */
c = getc(fp);
/* speed through leading spaces */
while (c != EOF && (c == ' ' || c == '\n'))
c = getc(fp);
/* so what did we get ? */
if (c == EOF)
{
bug("Fread_number: EOF encountered.");
abort();
}
else if (c == '-')
negative = TRUE;
else if (!isdigit(c))
{
bug("Fread_number: Not a number.");
abort();
}
else
number = c - '0';
/* keep counting up */
while (isdigit(c = getc(fp)))
number = number * 10 + c - '0';
/* push back the non-digit */
ungetc(c, fp);
/* we have a number */
return (negative ? (0 - number) : number);
}
/*
* Reads one full block of text, which ends with a
* '~' (tilde). The result will be copied into an
* allocated buffer and a pointer to that buffer
* will be returned. Remember to free the memory when
* you are done using it.
*/
char *fread_string(FILE *fp)
{
char buf[4 * MAX_BUFFER];
int c, count = 0;
/* initial read */
c = getc(fp);
/* speed through leading spaces */
while (c != EOF && (c == ' ' || c == '\n'))
c = getc(fp);
/* better not have reached the end of the file */
if (c == EOF)
{
bug("Fread_string: EOF encountered.");
abort();
}
/* and keep reading */
while (c != EOF && c != '~')
{
if (c == '\n')
{
buf[count++] = '\r';
buf[count] = '\n';
}
else if (c == '\r')
{
c = getc(fp);
continue;
}
else buf[count] = c;
if (++count > (4 * MAX_BUFFER - 2))
{
bug("Fread_string: String to long.");
abort();
}
c = getc(fp);
}
buf[count] = '\0';
if (c == EOF)
bug("Fread_string: Non-fatal error, encountered EOF instead of ~.");
return strdup(buf);
}
/*
* Reads one single word, ending with the first
* encountered space ' '. Any leading spaces will
* be ignored, and the result will be copied into
* a static buffer, and a pointer to that buffer
* will be returned.
*/
char *fread_word(FILE *fp)
{
static char buf[MAX_BUFFER];
int c, count = 0;
/* initial read */
c = getc(fp);
/* speed through leading spaces and linebreaks */
while (c != EOF && (c == ' ' || c == '\n'))
c = getc(fp);
/* better not have reached the end of the file */
if (c == EOF)
{
bug("Fread_word: EOF encountered.");
abort();
}
/* and keep reading */
while (c != EOF && c != ' ' && c != '\n')
{
buf[count] = c;
if (++count > MAX_BUFFER - 1)
{
bug("Fread_word: Word to long.");
abort();
}
c = getc(fp);
}
buf[count] = '\0';
/* push back the last read if it was EOF */
if (c == EOF) ungetc(c, fp);
return buf;
}