/*
* glue.c
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <ctype.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <memory.h>
#include "config.h"
#include "player.h"
#include "fix.h"
#define ABS(x) (((x)>0)?(x):-(x))
/* extern definitions */
extern void raw_wall(char *);
extern void lower_case(char *);
extern char *sys_errlist[];
/* extern int strftime(char *,int,char *,struct tm*); */
extern void alive_connect();
extern void close_down_socket(), scan_sockets(), process_players(),
init_parser(), init_rooms(), init_plist(), init_socket(),
save_player(), sync_all(), actual_timer(), init_notes(),
sync_notes(), init_help(), do_update(), timer_function(),
fork_the_thing_and_sync_the_playerfiles(), init_sitems(),
sync_sitems();
extern int total_processing;
extern void do_backup();
void close_down();
/* interns */
char *tens_words[] = {"", "ten", "twenty", "thirty", "forty", "fifty",
"sixty", "seventy", "eighty", "ninety"};
char *units_words[] = {"none", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine"};
char *teens[] = {"ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen",
"nineteen"};
char *months[12] = {"January", "February", "March", "April", "May",
"June", "July", "August", "September", "October",
"November", "December"};
char shutdown_reason[256] = "";
extern time_t shutdown_count;
/* print up birthday */
char *birthday_string(time_t bday)
{
static char bday_string[50];
struct tm *t;
t = localtime(&bday);
if ((t->tm_mday) > 10 && (t->tm_mday) < 20)
sprintf(bday_string, "%dth of %s", t->tm_mday, months[t->tm_mon]);
else
switch ((t->tm_mday) % 10)
{
case 1:
sprintf(bday_string, "%dst of %s", t->tm_mday, months[t->tm_mon]);
break;
case 2:
sprintf(bday_string, "%dnd of %s", t->tm_mday, months[t->tm_mon]);
break;
case 3:
sprintf(bday_string, "%drd of %s", t->tm_mday, months[t->tm_mon]);
break;
default:
sprintf(bday_string, "%dth of %s", t->tm_mday, months[t->tm_mon]);
break;
}
return bday_string;
}
/* return a string of the system time */
char *sys_time()
{
time_t t;
static char time_string[25];
t = time(0);
strftime(time_string, 25, "%H:%M:%S - %m/%d/%y", localtime(&t));
return time_string;
}
/* returns converted user time */
char *convert_time(time_t t)
{
static char time_string[50];
strftime(time_string, 49, "%H:%M:%S - %a, %B %d", localtime(&t));
return time_string;
}
/* get local time for all those americans :) */
char *time_diff(int diff)
{
time_t t;
static char time_string[50];
t = time(0) + 3600 * diff;
strftime(time_string, 49, "%H:%M:%S - %a, %B %d", localtime(&t));
return time_string;
}
char *time_diff_sec(time_t last_on, int diff)
{
static char time_string[50];
time_t sec_diff;
sec_diff = (3600 * diff) + last_on;
strftime(time_string, 49, "%H.%M:%S - %a, %B %d", localtime(&sec_diff));
return time_string;
}
/* converts time into words */
char *word_time(int t)
{
static char time_string[100], *fill;
int neg=0, days, hrs, mins, secs;
if (!t)
return "no time at all - doh!";
if (t < 0) {
neg = 1;
t = 0-t;
}
days = t / 86400;
hrs = (t / 3600) % 24;
mins = (t / 60) % 60;
secs = t % 60;
fill = time_string;
if (neg) {
sprintf(fill, "negative ");
while (*fill)
fill++;
}
if (days)
{
sprintf(fill, "%d day", days);
while (*fill)
fill++;
if (days != 1)
*fill++ = 's';
if (hrs || mins || secs)
{
*fill++ = ',';
*fill++ = ' ';
}
}
if (hrs)
{
sprintf(fill, "%d hour", hrs);
while (*fill)
fill++;
if (hrs != 1)
*fill++ = 's';
if (mins && secs)
{
*fill++ = ',';
*fill++ = ' ';
}
if ((mins && !secs) || (!mins && secs))
{
strcpy(fill, " and ");
while (*fill)
fill++;
}
}
if (mins)
{
sprintf(fill, "%d min", mins);
while (*fill)
fill++;
if (mins != 1)
*fill++ = 's';
if (secs)
{
strcpy(fill, " and ");
while (*fill)
fill++;
}
}
if (secs)
{
sprintf(fill, "%d sec", secs);
while (*fill)
fill++;
if (secs != 1)
*fill++ = 's';
}
*fill++ = 0;
return time_string;
}
/* returns a number in words */
char *number2string(int n)
{
int negative=0, hundreds, tens, units;
static char words[50];
char *fill;
if (n >= 1000)
{
sprintf(words, "%d", n);
return words;
}
if (!n)
return "none";
if (n < 0) {
n = 0-n;
negative = 1;
}
hundreds = n / 100;
tens = (n / 10) % 10;
units = n % 10;
fill = words;
if (negative) {
sprintf(fill, "negative ");
while (*fill)
fill++;
}
if (hundreds)
{
sprintf(fill, "%s hundred", units_words[hundreds]);
while (*fill)
fill++;
}
if (hundreds && (units || tens))
{
strcpy(fill, " and ");
while (*fill)
fill++;
}
if (tens && tens != 1)
{
strcpy(fill, tens_words[tens]);
while (*fill)
fill++;
}
if (tens != 1 && tens && units)
*fill++ = ' ';
if (units && tens != 1)
{
strcpy(fill, units_words[units]);
while (*fill)
fill++;
}
if (tens == 1)
{
strcpy(fill, teens[(n % 100) - 10]);
while (*fill)
fill++;
}
*fill++ = 0;
return words;
}
/* point to after a string */
char *end_string(char *str)
{
str = strchr(str, 0);
str++;
return str;
}
/* get gender string function */
char *get_gender_string(player * p)
{
switch (p->gender)
{
case MALE:
return "him";
break;
case FEMALE:
return "her";
break;
case PLURAL:
return "them";
break;
case OTHER:
return "it";
break;
case VOID_GENDER:
return "it";
break;
}
return "(this is frogged)";
}
/* get gender string for possessives */
char *gstring_possessive(player * p)
{
switch (p->gender)
{
case MALE:
return "his";
break;
case FEMALE:
return "her";
break;
case PLURAL:
return "their";
break;
case OTHER:
return "its";
break;
case VOID_GENDER:
return "its";
break;
}
return "(this is frogged)";
}
/* more gender strings */
char *gstring(player * p)
{
switch (p->gender)
{
case MALE:
return "he";
break;
case FEMALE:
return "she";
break;
case PLURAL:
return "they";
break;
case OTHER:
return "it";
break;
case VOID_GENDER:
return "it";
break;
}
return "(this is frogged)";
}
char *havehas(player *p)
{
switch (p->gender)
{
case PLURAL:
return "have";
break;
default:
return "has";
break;
}
return "has";
}
char *isare(player *p)
{
switch (p->gender)
{
case PLURAL:
return "are";
break;
default:
return "is";
break;
}
return "is";
}
char *waswere(player *p)
{
switch (p->gender)
{
case PLURAL:
return "were";
break;
default:
return "was";
break;
}
return "was";
}
char *single_s(player *p)
{
/* for use when you want an s returns for a SINGULAR player */
switch (p->gender)
{
case PLURAL:
return "";
break;
default:
return "s";
break;
}
return "";
}
/* returns the 'full' name of someone, that is their pretitle and name */
char *full_name(player * p)
{
static char fname[MAX_PRETITLE + MAX_NAME];
if ((!(sys_flags & NO_PRETITLES)) && (p->residency & BASE) && p->pretitle[0])
{
sprintf(fname, "%s %s", p->pretitle, p->name);
return fname;
}
return p->name;
}
/* log errors and things to file */
void log(char *file, char *string)
{
int fd, length;
#ifdef PC
sprintf(stack, "logs\\%s.log", file);
fd = open(stack, O_CREAT | O_WRONLY);
#else
sprintf(stack, "logs/%s.log", file);
fd = open(stack, O_CREAT | O_WRONLY | O_SYNC, S_IRUSR | S_IWUSR);
#endif
length = lseek(fd, 0, SEEK_END);
if (length > MAX_LOG_SIZE)
{
close(fd);
#ifdef PC
fd = open(stack, O_CREAT | O_WRONLY | O_TRUNC);
#else
fd = open(stack, O_CREAT | O_WRONLY | O_SYNC | O_TRUNC, S_IRUSR | S_IWUSR);
#endif
}
sprintf(stack, "%s - %s\n", sys_time(), string);
if (!(sys_flags & NO_PRINT_LOG))
printf(stack);
write(fd, stack, strlen(stack));
close(fd);
}
void banlog(char *file, char *string)
{
int fd, length;
sprintf(stack, "files/%s", file);
fd = open(stack, O_CREAT | O_WRONLY | O_SYNC, S_IRUSR | S_IWUSR);
length = lseek(fd, 0, SEEK_END);
sprintf(stack, "%s\n", string);
if (!(sys_flags & NO_PRINT_LOG))
printf(stack);
write(fd, stack, strlen(stack));
close(fd);
}
/* what happens when *shriek* an error occurs */
void handle_error(char *error_msg)
{
char dump[80];
/*
* if (errno==EINTR) { log("error","EINTR trap"); log("error",error_msg);
* return; }
*/
if (sys_flags & PANIC)
{
stack = stack_start;
log("error", "Immediate PANIC shutdown.");
exit(-1);
}
sys_flags |= PANIC;
/*
* sprintf(dump,"gcore %d",getpid()); system(dump);
*/
stack = stack_start;
if ( sys_flags & UPDATE )
sys_flags &= ~NO_PRINT_LOG;
log("error", error_msg);
log("boot", "Abnormal exit from error handler");
/* dump possible useful info */
log("dump", "------------ Starting dump");
sprintf(stack_start, "Errno set to %d, %s", errno, sys_errlist[errno]);
stack = end_string(stack_start);
log("dump", stack_start);
if (current_player)
{
log("dump", current_player->name);
if (current_player->location)
{
sprintf(stack_start, "player %s.%s",
current_player->location->owner->lower_name,
current_player->location->id);
stack = end_string(stack_start);
log("dump", stack_start);
} else
log("dump", "No room of current player");
sprintf(stack_start, "flags %d sys %d tag %d cus %d mis %d res %d",
current_player->flags, current_player->system_flags,
current_player->tag_flags, current_player->custom_flags,
current_player->misc_flags, current_player->residency);
stack = end_string(stack_start);
log("dump", stack_start);
log("dump", current_player->ibuffer);
} else
log("dump", "No current player !");
if (current_room)
{
sprintf(stack_start, "current %s.%s", current_room->owner->lower_name,
current_room->id);
stack = end_string(stack_start);
log("dump", stack_start);
} else
log("dump", "No current room");
sprintf(stack_start, "global flags %d, players %d", sys_flags, current_players);
stack = end_string(stack_start);
log("dump", stack_start);
sprintf(stack_start, "action %s", action);
stack = end_string(stack_start);
log("dump", stack_start);
log("dump", "---------- End of dump info");
raw_wall("\n\n"
" -=> *WIBBLE* Something bad has happened. Trying to save files <=-\007\n\n\n");
close_down();
exit(-1);
}
/* function to convert seamlessly to caps (ish) */
char *caps(char *str)
{
static char buff[500];
strncpy(buff, str, 498);
buff[0] = toupper(buff[0]);
return buff;
}
/* load a file into memory */
file load_file_verbose(char *filename, int verbose)
{
file f;
int d;
char *oldstack;
oldstack = stack;
d = open(filename, O_RDONLY);
if (d < 0)
{
sprintf(oldstack, "Can't find file:%s", filename);
stack = end_string(oldstack);
if (verbose)
log("error", oldstack);
f.where = (char *) MALLOC(1);
*(char *) f.where = 0;
f.length = 0;
stack = oldstack;
return f;
}
f.length = lseek(d, 0, SEEK_END);
lseek(d, 0, SEEK_SET);
f.where = (char *) MALLOC(f.length + 1);
memset(f.where, 0, f.length + 1);
if (read(d, f.where, f.length) < 0)
{
sprintf(oldstack, "Error reading file:%s", filename);
stack = end_string(oldstack);
log("error", oldstack);
f.where = (char *) MALLOC(1);
*(char *) f.where = 0;
f.length = 0;
stack = oldstack;
return f;
}
close(d);
if (sys_flags & VERBOSE)
{
sprintf(oldstack, "Loaded file:%s", filename);
stack = end_string(oldstack);
log("boot", oldstack);
stack = oldstack;
}
stack = oldstack;
*(f.where + f.length) = 0;
return f;
}
file load_file(char *filename)
{
return load_file_verbose(filename, 1);
}
/* convert a string to lower case */
void lower_case(char *str)
{
while (*str)
*str++ = tolower(*str);
}
/* fns to block signals */
void sigpipe()
{
if (c_player)
{
log("sigpipe", "Closing connection due to sigpipe");
shutdown(c_player->fd, 0);
close(c_player->fd);
} else
{
log("sigpipe", "Eeek! sigpipe but no current_player");
}
#if !defined(hpux) && !defined(linux)
signal(SIGPIPE, sigpipe);
#endif /* !hpux && !linux */
return;
}
void sighup()
{
log("boot", "Terminated by hangup signal");
close_down();
exit(0);
}
void sigquit()
{
handle_error("Quit signal received.");
}
void sigill()
{
handle_error("Illegal instruction.");
}
void sigfpe()
{
handle_error("Floating Point Error.");
}
void sigbus()
{
handle_error("Bus Error.");
}
void sigsegv()
{
handle_error("Segmentation Violation.");
}
#if !defined(linux)
void sigsys()
{
handle_error("Bad system call.");
}
#endif
void sigterm()
{
handle_error("Terminate signal received.");
}
void sigxfsz()
{
handle_error("File descriptor limit exceeded.");
}
void sigusr1()
{
/* dyathink he could have made this a bit longer? */
fork_the_thing_and_sync_the_playerfiles();
#if !defined(hpux) && !defined(linux)
signal(SIGUSR1, sigusr1);
#endif /* hpux && linux*/
}
/* Get ALL the files sunc to disk for a backup */
void sigusr2()
{
backup=1;
#if !defined(hpux) && !defined(linux)
signal(SIGUSR2, sigusr2);
#endif /* hpux && linux */
}
void sigchld()
{
/*
log("error", "WIbble, server's child died");
*/
#if !defined(hpux) && !defined(linux)
signal(SIGCHLD, sigchld);
#endif /* hpux && linux */
return;
}
/* close down sequence */
void close_down()
{
player *scan, *old_current;
#ifndef PC
struct itimerval new, old;
#endif
raw_wall("\007\n\n");
command_type |= HIGHLIGHT;
if (shutdown_count == 0)
{
raw_wall(shutdown_reason);
/* don't need this to be logged twice, do we? =) */
/* log("shutdown",shutdown_reason); */
}
raw_wall("\n\n\n ---====>>>> Program shutting down NOW <<<<====---"
"\n\n\n");
command_type &= ~HIGHLIGHT;
#ifndef PC
new.it_interval.tv_sec = 0;
new.it_interval.tv_usec = 0;
new.it_value.tv_sec = 0;
new.it_value.tv_usec = new.it_interval.tv_usec;
if (setitimer(ITIMER_REAL, &new, &old) < 0)
handle_error("Can't set timer.");
if (sys_flags & VERBOSE || sys_flags & PANIC)
log("boot", "Timer Stopped");
#endif
if (sys_flags & VERBOSE || sys_flags & PANIC)
log("boot", "Saving all players.");
for (scan = flatlist_start; scan; scan = scan->flat_next)
save_player(scan);
if (sys_flags & VERBOSE || sys_flags & PANIC)
log("boot", "Syncing to disk.");
sync_all();
old_current = current_player;
current_player = 0;
sync_notes(0);
sync_sitems(0);
current_player = old_current;
if (sys_flags & PANIC)
raw_wall("\n\n ---====>>>> Files sunc (phew !) <<<<====---"
"\007\n\n\n");
for (scan = flatlist_start; scan; scan = scan->flat_next)
close(scan->fd);
close_down_socket();
#ifdef PC
chdir("src");
#endif
if (!(sys_flags & PANIC))
{
unlink("junk/PID");
log("boot", "Program exited normally.");
exit(0);
}
}
/* the boot sequence */
void boot(int port)
{
char *oldstack;
int i;
#ifndef PC
struct rlimit rlp;
struct itimerval new, old;
#endif
#if defined(hpux) | defined(linux)
struct sigaction sa;
#endif /* hpux | linux */
oldstack = stack;
log("boot", "PlayCode 96 (EW-4) now beginning boot sequence.");
up_date = time(0);
#ifndef PC
#ifndef ULTRIX
#if !defined(linux)
getrlimit(RLIMIT_NOFILE, &rlp);
rlp.rlim_cur = rlp.rlim_max;
setrlimit(RLIMIT_NOFILE, &rlp);
#endif /* LINUX */
/*
max_players = (rlp.rlim_cur) - 20;
*/
max_players = 210;
if (sys_flags & VERBOSE)
{
sprintf(oldstack, "Got %d file descriptors, Allocated %d for players",
rlp.rlim_cur, max_players);
stack = end_string(oldstack);
log("boot", oldstack);
stack = oldstack;
}
#else
max_players = ULTRIX_PLAYER_LIM;
if (sys_flags & VERBOSE)
{
sprintf(oldstack, "Set max players to %d.", max_players);
stack = end_string(oldstack);
log("boot", oldstack);
stack = oldstack;
}
#endif /* ULTRIX */
#ifndef SOLARIS
getrlimit(RLIMIT_RSS, &rlp);
rlp.rlim_cur = MAX_RES;
setrlimit(RLIMIT_RSS, &rlp);
#endif
#else
max_players = 10;
#endif
flatlist_start = 0;
for (i = 0; i < 27; i++)
hashlist[i] = 0;
stdout_player = (player *) MALLOC(sizeof(player));
memset(stdout_player, 0, sizeof(player));
srand(time(0));
init_plist();
init_parser();
init_rooms();
init_notes();
init_help();
init_sitems();
#ifndef PC
if (!(sys_flags & SHUTDOWN))
{
new.it_interval.tv_sec = 0;
new.it_interval.tv_usec = (1000000 / TIMER_CLICK);
new.it_value.tv_sec = 0;
new.it_value.tv_usec = new.it_interval.tv_usec;
#if defined(hpux) | defined(linux)
sa.sa_handler = actual_timer;
sa.sa_mask = 0;
sa.sa_flags = 0;
if ((int) sigaction(SIGALRM, &sa, 0) < 0)
#else
if ((int) signal(SIGALRM, actual_timer) < 0)
#endif /* hpux | linux */
handle_error("Can't set timer signal.");
if (setitimer(ITIMER_REAL, &new, &old) < 0)
handle_error("Can't set timer.");
if (sys_flags & VERBOSE)
log("boot", "Timer started.");
}
#if defined(hpux) | defined(linux)
sa.sa_handler = sigpipe;
sa.sa_mask = 0;
sa.sa_flags = 0;
sigaction(SIGPIPE, &sa, 0);
sa.sa_handler = sighup;
sigaction(SIGHUP, &sa,0);
sa.sa_handler = sigquit;
sigaction(SIGQUIT, &sa, 0);
sa.sa_handler = sigill;
sigaction(SIGILL, &sa, 0);
sa.sa_handler = sigfpe;
sigaction(SIGFPE, &sa, 0);
sa.sa_handler = sigbus;
sigaction(SIGBUS, &sa, 0);
sa.sa_handler = sigsegv;
sigaction(SIGSEGV, &sa, 0);
#if !defined(linux)
sa.sa_handler = sigsys;
sigaction(SIGSYS, &sa, 0);
#endif /* linux */
sa.sa_handler = sigterm;
sigaction(SIGTERM, &sa, 0);
sa.sa_handler = sigxfsz;
sigaction(SIGXFSZ, &sa, 0);
sa.sa_handler = sigusr1;
sigaction(SIGUSR1, &sa, 0);
sa.sa_handler = sigusr2;
sigaction(SIGUSR2, &sa, 0);
sa.sa_handler = sigchld;
sigaction(SIGCHLD, &sa, 0);
#else
signal(SIGPIPE, sigpipe);
signal(SIGHUP, sighup);
signal(SIGQUIT, sigquit);
signal(SIGILL, sigill);
signal(SIGFPE, sigfpe);
signal(SIGBUS, sigbus);
signal(SIGSEGV, sigsegv);
signal(SIGSYS, sigsys);
signal(SIGTERM, sigterm);
signal(SIGXFSZ, sigxfsz);
signal(SIGUSR1, sigusr1);
signal(SIGUSR2, sigusr2);
signal(SIGCHLD, sigchld);
#endif /* hpux | linux */
#endif /* PC */
if (!(sys_flags & SHUTDOWN))
{
init_socket(port);
alive_connect();
}
current_players = 0;
stack = oldstack;
}
/* Log the Process ID of this process to the file junk/PID */
void log_pid(void)
{
FILE *f;
f = fopen("junk/PID", "w");
if (!f)
{
fprintf(stderr, "Log_Pid: Couldn't open junk/PID for writing!!!\n");
exit(-1);
}
fprintf(f, "%d", getpid());
fflush(f);
fclose(f);
}
/* got to have a main to control everything */
void main(int argc, char *argv[])
{
int port = 0;
action = "boot";
/*
* if (mallopt(M_MXFAST,1024)) { perror("spoon:"); exit(0); }
*/
#ifdef MALLOC_DEBUG
malloc_debug(2);
#endif
backup=0;
stack_start = (char *) MALLOC(STACK_SIZE);
memset(stack_start, 0, STACK_SIZE);
stack = stack_start;
#ifdef TRACK
funcposition=0;
#endif
if (argc == 3)
{
if (!strcasecmp("update", argv[1]))
{
if (!strcasecmp("spods", argv[2]))
{
log("boot", "Program booted to update spodlists.");
sys_flags |= SHUTDOWN | UPDATE_SPODLIST;
} else if (!strcasecmp("url", argv[2]))
{
log("boot", "Program booted for URL update.");
sys_flags |= SHUTDOWN | UPDATE_URLS;
} else if (!strcasecmp("data", argv[2]))
{
log("boot", "Program booted for data output.");
sys_flags |= SHUTDOWN | UPDATE_INT_DATA;
} else if (!strcasecmp("rooms", argv[2]))
{
log("boot", "Program booted for file rooms update.");
sys_flags |= SHUTDOWN | UPDATEROOMS;
} else if (!strcasecmp("flags", argv[2]))
{
log("boot", "Program booted for flags update");
sys_flags |= SHUTDOWN | UPDATEFLAGS;
} else
{
log("boot", "Program booted for file players update.");
sys_flags |= SHUTDOWN | UPDATE;
}
}
}
if (argc == 2)
port = atoi(argv[1]);
if (!port)
port = DEFAULT_PORT;
if (chdir(ROOT))
{
printf("Can't change to root directory.\n");
exit(1);
}
boot(port);
#ifdef PC
accept_new_connection();
#endif
if (sys_flags & UPDATE_URLS)
do_update(3);
else if (sys_flags & UPDATE_INT_DATA)
do_update(4);
else if (sys_flags & UPDATE_SPODLIST)
do_update(2);
else if (sys_flags & UPDATE)
do_update(0);
else if (sys_flags & UPDATEFLAGS)
do_update(0);
else if (sys_flags & UPDATEROOMS)
do_update(1);
sys_flags |= NO_PRINT_LOG;
if ( !(sys_flags & UPDATE) )
{
/*
fclose(stdout);
fclose(stderr);
*/
}
/* This logs the Process ID of this version of the talker. Used by the
* crontab script to send it signals to trigger the backups
*/
log_pid();
initchannels();
while (!(sys_flags & SHUTDOWN))
{
errno = 0;
if (backup)
do_backup();
if (stack != stack_start)
{
sprintf(stack_start, "Lost stack reclaimed %d bytes\n",
(int) stack - (int) stack_start);
stack = end_string(stack_start);
log("stack", stack_start);
stack = stack_start;
}
action = "scan sockets";
scan_sockets();
action = "processing players";
process_players();
action = "";
timer_function();
sigpause(0);
do_alive_ping();
}
close_down();
}
void do_backup()
{
char fname[256];
int xtime;
backup=0;
raw_wall("\n -=*> Starting Daily Backup Protocol <*=-\n");
raw_wall(" -=*> The system will resume shortly <*=-\n\n");
raw_wall(" -=*> Validating all rooms <*=-\n");
dynamic_validate_rooms((player *)0, (char *)0);
raw_wall(" -=*> Defragmenting rooms <*=-\n");
dynamic_defrag_rooms((player *)0,(char *)0);
raw_wall(" -=*> Handling mail and news <*=-\n");
sync_notes(0);
raw_wall(" -=*> Syncing objects <*=-\n");
sync_sitems(0);
raw_wall(" -=*> Saving Residents <*=-\n");
sync_all();
strcpy(fname,ROOT);
raw_wall(" -=*> Running backup autosave script <*=-\n");
strcat(fname,"backup/daily.backup.pt.1");
system(fname);
raw_wall(" -=*> Backgrounded for compression <*=-\n");
raw_wall(" -=*> Daily Backups Complete <*=-\n\n\n");
switch(fork())
{
case 0:
xtime = time(0)%ONE_WEEK;
if (xtime >= BACKUP_TIME && xtime < (BACKUP_TIME + ONE_HOUR)) {
sprintf(fname, "%sbackup/weekly.backup", ROOT);
system(fname);
} else {
fname[strlen(fname)-1]='2';
system(fname);
}
exit(0);
default:
break;
}
}