/************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefiting. We hope that you share your changes too. What goes * * around, comes around. * *************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * *************************************************************************** * 1stMud ROM Derivative (c) 2001-2004 by Markanth * * http://www.firstmud.com/ <markanth@firstmud.com> * * By using this code you have agreed to follow the term of * * the 1stMud license in ../doc/1stMud/LICENSE * ***************************************************************************/ #include "merc.h" #include "recycle.h" void write_string(FileData * fp, const char *name, const char *str, const char *def) { if (NullStr(name)) f_printf(fp, "%s~" LF, fix_string(str)); else if (!NullStr(str) && (NullStr(def) || str_cmp(str, def))) f_printf(fp, "%s%s%s~" LF, name, format_tabs(strlen(name)), fix_string(str)); } void write_word(FileData * fp, const char *name, const char *str, const char *def) { if (NullStr(name)) f_printf(fp, "'%s'" LF, fix_string(str)); else if (!NullStr(str) && (NullStr(def) || str_cmp(str, def))) f_printf(fp, "%s%s'%s'" LF, name, format_tabs(strlen(name)), fix_string(str)); } void write_bit(FileData * fp, const char *name, flag_t bit, flag_t def) { if (NullStr(name)) f_printf(fp, "%s" LF, write_flags(bit)); else if (bit != def) f_printf(fp, "%s%s%s" LF, name, format_tabs(strlen(name)), write_flags(bit)); } void write_header(FileData * fp, const char *head) { if (!NullStr(head)) f_printf(fp, "%s%s", head, format_tabs(strlen(head))); } void f_writef(FileData * fp, const char *name, const char *format, ...) { if (!NullStr(format)) { va_list args; char buf[MPL]; va_start(args, format); vsnprintf(buf, sizeof(buf), format, args); va_end(args); if (!NullStr(name)) f_printf(fp, name); f_printf(fp, "%s%s", format_tabs(strlen(name)), buf); } else if (!NullStr(name)) { f_printf(fp, name); } } void write_time(FileData * fp, const char *name, time_t time, bool fTime) { if (!NullStr(name)) f_printf(fp, "%s%s", name, format_tabs(strlen(name))); else f_printf(fp, " "); f_printf(fp, TIME_T_FMT, time); f_printf(fp, " (%s)" LF, !fTime ? str_time(time, -1, NULL) : timestr(current_time - time, false)); } void read_time(FileData * fp, time_t * tptr) { *tptr = read_long(fp); read_to_eol(fp); } void read_dice(FileData * fp, int *dice) { int i; for (i = 0; i < DICE_MAX - 1; i++) { dice[i] = read_number(fp); read_letter(fp); } dice[i] = read_number(fp); } void write_dice(FileData * fp, int *dice) { int i; for (i = 0; i < DICE_MAX - 1; i++) { f_printf(fp, "%dd", dice[i]); } f_printf(fp, "%d", dice[i]); } bool is_space(char c) { if (isspace(c)) { switch (c) { case CUSTOMSTART: case CUSTOMEND: case MXP_BEGc: case MXP_ENDc: return false; default: return true; } } else return false; } #define MLR (MAX_STRING_LENGTH * 25) const char *read_file(FileData * fp) { char buf[MLR + 2]; char c; size_t i = 0; bool sFull = false; memset(buf, 0, sizeof(buf)); for (;;) { if (i >= MLR && !sFull) { bugf("file size exceeded %d maximum.", MLR); sFull = true; } switch (c = f_getc(fp)) { default: if (!sFull) { buf[i] = c; i++; } break; case '\n': if (!sFull) { buf[i] = '\n'; i++; buf[i] = '\r'; i++; } break; case '\r': break; case NUL: return str_dup(buf); } } } FILE *file_open(const char *file, const char *mode) { FILE *fp; if (fpReserve != NULL) { fclose(fpReserve); fpReserve = NULL; } if (!(fp = fopen(file, mode))) { fpReserve = fopen(NULL_FILE, "r"); return NULL; } return fp; } void file_close(FILE * fp) { if (fp != NULL) { fflush(fp); fclose(fp); } fp = NULL; if (fpReserve == NULL) fpReserve = fopen(NULL_FILE, "r"); } char read_letter(FileData * fp) { char c; do { c = f_getc(fp); } while (is_space(c)); return c; } int read_number(FileData * fp) { int number; bool sign; char c; do { c = f_getc(fp); } while (is_space(c)); number = 0; sign = false; if (c == '+') { c = f_getc(fp); } else if (c == '-') { sign = true; c = f_getc(fp); } if (!isdigit(c)) { bugf("bad format '%c'... %s.", c, AttemptJump ? "attempting longjmp" : "aborting"); if (AttemptJump) { longjmp(jump_env, 1); } else abort(); } while (isdigit(c)) { number = number * 10 + c - '0'; c = f_getc(fp); } if (sign) number = 0 - number; if (c == '|') number += read_number(fp); else if (c != ' ') f_ungetc(c, fp); return number; } long read_long(FileData * fp) { long number; bool sign; char c; do { c = f_getc(fp); } while (is_space(c)); number = 0; sign = false; if (c == '+') { c = f_getc(fp); } else if (c == '-') { sign = true; c = f_getc(fp); } if (!isdigit(c)) { bugf("bad format '%c'... %s.", c, AttemptJump ? "attempting longjmp" : "aborting"); if (AttemptJump) { longjmp(jump_env, 1); } else abort(); } while (isdigit(c)) { number = number * 10 + c - '0'; c = f_getc(fp); } if (sign) number = 0 - number; if (c == '|') number += read_long(fp); else if (c != ' ') f_ungetc(c, fp); return number; } flag_t read_flag(FileData * fp) { flag_t number; flag_t flag; flag_t temp = 1; char c; bool negative = false; do { c = f_getc(fp); } while (is_space(c)); if (c != '+') { if (c == '-') { negative = true; c = f_getc(fp); } number = 0; if (!isdigit(c)) { while (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) { number += flag_convert(c); c = f_getc(fp); } } while (isdigit(c)) { number = number * 10 + c - '0'; c = f_getc(fp); } if (c == '|') number += read_flag(fp); else if (c != ' ') f_ungetc(c, fp); if (negative) return -1 * number; return number; } else { number = 0; flag = 0; do { c = f_getc(fp); flag += (temp << number) * (c == 'Y'); number++; } while (c == 'Y' || c == 'n'); if (c == '\n' || c == '\r') f_ungetc(c, fp); return flag; } } void read_to_eol(FileData * fp) { char c; do { c = f_getc(fp); } while (c != '\n' && c != '\r'); do { c = f_getc(fp); } while (c == '\n' || c == '\r'); f_ungetc(c, fp); return; } char *read_word(FileData * fp) { static char word[MIL]; char *pword; char cEnd; do { if (f_eof(fp)) { bug("EOF encountered on read."); if (run_level == RUNLEVEL_BOOTING) exit(1); word[0] = NUL; return word; } cEnd = f_getc(fp); } while (is_space(cEnd)); if (cEnd == '\'' || cEnd == '"') { pword = word; } else { word[0] = cEnd; pword = word + 1; cEnd = ' '; } for (; pword < word + MIL; pword++) { *pword = f_getc(fp); if (cEnd == ' ' ? is_space(*pword) : *pword == cEnd) { if (cEnd == ' ') f_ungetc(*pword, fp); *pword = NUL; return word; } } bugf("word too long... %s.", AttemptJump ? "attempting longjmp" : "aborting"); if (AttemptJump) { longjmp(jump_env, 1); } else abort(); return NULL; } const char *read_string(FileData * fp) { static char buf[MLR + 2]; size_t i = 0; register char c; bool sFull = false; do { c = f_getc(fp); } while (is_space(c)); if (c == '~') return str_dup(""); buf[i++] = c; for (;;) { if (i >= MLR && !sFull) { bugf("String [%20.20s...] exceeded [%d] MLR", buf, MLR); sFull = true; } switch (c = f_getc(fp)) { default: if (!sFull) { buf[i++] = c; } break; case NUL: bugf("EOF reached... %s.", AttemptJump ? "attempting longjmp" : "aborting"); if (AttemptJump) { longjmp(jump_env, 1); } else abort(); break; case '\n': if (!sFull) { buf[i++] = '\n'; buf[i++] = '\r'; } break; case '\r': break; case '~': buf[i] = NUL; return str_dup(buf); break; } } } void read_strfree(FileData * fp, const char **pstr) { free_string(*pstr); *pstr = read_string(fp); } const char *read_line(FileData * fp) { static char line[MSL]; char *pline; char c; int ln; pline = line; line[0] = NUL; ln = 0; do { if (f_eof(fp)) { bug("EOF encountered on read."); strcpy(line, ""); return line; } c = f_getc(fp); } while (is_space(c)); f_ungetc(c, fp); do { if (f_eof(fp)) { bug("EOF encountered on read."); *pline = NUL; return line; } c = f_getc(fp); *pline++ = c; ln++; if (ln >= (MSL - 1)) { bug("line too long"); break; } } while (c != '\n' && c != '\r'); do { c = f_getc(fp); } while (c == '\n' || c == '\r'); f_ungetc(c, fp); *pline = NUL; return line; } #ifdef STFILEIO stFile *stopen(const char *file, const char *mode) { struct stat buf; FileData *stfp; if (NullStr(file)) return NULL; stfp = new_stfile(); if (stfp == NULL) return NULL; stfp->file = str_dup(file); stfp->mode = str_dup(mode); if (mode[0] == NUL || tolower(mode[0]) == 'r') { if (stat(file, &buf) == -1 || !S_ISREG(buf.st_mode)) { free_stfile(stfp); return NULL; } if ((stfp->stream = file_open(file, mode)) == NULL) { free_stfile(stfp); return NULL; } stfp->pos = 0; stfp->size = buf.st_size; alloc_mem(stfp->str, char, stfp->size + 1); fread(stfp->str, stfp->size + 1, 1, stfp->stream); stfp->str[stfp->size] = NUL; } else { static int count = 0; ++count, count %= 999; #if !defined WIN32 && !defined __CYGWIN__ stfp->temp = str_dupf("%s.tmp%03d", stfp->file, count); if ((stfp->stream = file_open(stfp->temp, mode)) == NULL) #else if ((stfp->stream = file_open(stfp->file, mode)) == NULL) #endif { free_stfile(stfp); return NULL; } } Link(stfp, stfile, next, prev); return stfp; } int stclose(stFile * fp) { #if !defined WIN32 && !defined __CYGWIN__ if (!NullStr(fp->temp) && rename(fp->temp, fp->file) == -1) { bugf("error renaming %s -> %s", fp->temp, fp->file); } #endif free_stfile(fp); fp = NULL; return 0; } int stflush(stFile * fp) { if (fp != NULL) { if (!NullStr(fp->mode) && fp->mode[0] != 'r') { fprintf(fp->stream, "%s\n", fp->str); } fflush(fp->stream); } else for (fp = stfile_first; fp; fp = fp->next) stflush(fp); return 0; } int steof(FileData * fp) { return (fp->pos >= fp->size) ? EOF : 0; } int stgetc(FileData * fp) { char c = fp->str[fp->pos]; if (!steof(fp)) fp->pos++; return c; } int stungetc(int c, stFile * fp) { if (fp->pos > 0) fp->pos--; return fp->str[fp->pos]; } size_t stread(void *ptr, size_t size, size_t nmemb, stFile * fp) { size_t nsize; if (!fp->str || steof(fp)) return 0; nsize = Min(fp->pos + size, fp->size); memcpy(ptr, &fp->str[fp->pos], nsize); return nsize; } int stprintf(stFile * fp, const char *fmt, ...) { va_list args; int len; if (!fp || NullStr(fmt) || NullStr(fp->mode) || tolower(fp->mode[0]) == 'r' || !fp->stream) return 0; va_start(args, fmt); len = vfprintf(fp->stream, fmt, args); va_end(args); return len; } int stseek(stFile * fp, long offset, int whence) { if (!fp) return -1; switch (whence) { case SEEK_SET: fp->pos = 0; break; default: case SEEK_CUR: break; case SEEK_END: fp->pos = fp->size; break; } if (fp->pos + offset < 0 || fp->pos + offset >= fp->size) return -1; fp->pos += offset; return 0; } #endif