#ifdef DEBUG
#define LAZY
#endif
#define ERIC_DB
#include <sys/file.h>
#include "kernel.h"
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/socket.h>
#ifdef RS6000
#include <sys/select.h>
#endif
#include <arpa/inet.h>
#include <netdb.h>
#include "config.h"
#include <stdarg.h>
#include "locations.h"
#include "stdinc.h"
#include "machines.h"
#ifdef IDENT
# include "ident.h"
#endif
#ifdef INTERMUD
#include "intermud.h"
#endif
/* Char-by-char mode fixed by ErIC */
static int xmain (int fd);
static int xmain_reboot (int fd);
static int go_background (int pid_fd);
static int check_pid (void);
static void get_options (int argc, char **argv);
static void usage (void);
static void main_loop (int m_socket);
void sysreboot(int saveLoc);
void rm_pid_file (void);
static void end_connection (void);
static void new_connection (int fd);
static void handle_packet (int fd);
static void dump_info (void);
void sig_handler (int sig);
/* Some local variables */
fd_set sockets_fds;
fd_set buffer_fds;
int mud_port = -1;
int main_socket;
int width;
#ifdef REBOOT
int old_proc_num = 0;
int port_number;
#endif
int fildes[2];
char pidFileName[256];
Boolean kill_other_mud = False;
Boolean clear_syslog_file = False;
Boolean stay_foreground = False;
Boolean sig_term_happened = False;
Boolean sig_timer_happened = False;
Boolean Debug = False;
Boolean kill_and_exit = False;
static int inp_buf_c = 0;
static struct timeval zerotime =
{0, 0};
int
main (int argc, char **argv, char **ep)
{
int fd, x;
char path[1024];
char binary[1024];
sigsetmask(0);
envp = ep;
progname = argv[0];
width = getdtablesize ();
/************/
getwd (path);
sprintf (binary, "%s/%s", path, argv[0]);
#ifdef HANDLER /* see debug.h */
install_handler (binary, (char *) 0);
#endif
/************/
if (data_dir != NULL)
chdir (data_dir); /* Do chdir if specified */
get_options (argc, argv); /* Parse command line */
printf ("\ndata_dir = \"%s\".\nmax_players = %d.\nport = %d.\n",
(data_dir == NULL ? "<null>" : data_dir), max_players, mud_port);
printf ("%s " LOG_FILE " file.\n",
clear_syslog_file ? "Clear" : "Do not clear");
#ifdef DEBUG
Debug = True;
#endif
printf ("Debugging is %s.\n", Debug ? "on" : "off");
#ifdef REBOOT
if (old_proc_num)
kill_other_mud = True;
#endif
if (kill_other_mud)
{
printf ("Kill other mud.\n");
}
else
{
printf ("Ask if other mud should be killed.\n");
}
if (data_dir != NULL)
chdir (data_dir); /* Do chdir if specified */
/* Check if PID_FILE is there...and what it contains */
fd = check_pid ();
/* We arrive here only if we are to continue and now we are alone. */
/* Also, the PID_FILE is opened */
if (kill_and_exit)
exit (0);
#ifdef REBOOT
if (!old_proc_num)
#endif
x = xmain (fd);
#ifdef REBOOT
else
x = xmain_reboot (fd);
#endif
unlink (pidFileName);
if (x < 0)
{
mudlog ("Abnormal termination of mud");
exit (1);
}
mudlog ("Normal termination of mud");
return True;
}
static void
connect_ok (char *h, int port)
{
char b[80];
sprintf (b, "Connected to port %d on %s.\n\001\n", port, h);
if (stay_foreground)
{
if (write (1, b, strlen (b) - 2) == -1)
progerror ("write(1,b,strlen(b)).1 failed");
}
else
{
if (write (fildes[1], b, strlen (b)) == -1)
progerror ("write(1,b,strlen(b)).2 failed");
while (getppid () > 1);
close (fildes[1]);
}
}
#ifdef REBOOT
static int xmain_reboot (int fd)
{
int f, nzones_to_reload;
FILE *fp;
char newname[256];
int p;
int s;
/* We arrive here only if we are to continue and now we are alone. */
/* Also, the PID_FILE is opened */
if (open_logfile(LOG_FILE,clear_syslog_file) < 0) {
close(fd);
return -1;
}
/* Open up the file that contains the information about the reboot. */
sprintf(newname,"reboot_file%d",old_proc_num);
mudlog("REBOOT: Opening file %s.",newname);
if(!(fp = fopen(newname,"r")))
{
mudlog("Error on reboot, %s does not exist.",newname);
return -1;
}
/* Now that the reboot info file is opened, read in some of
* the info, namely, how much to loop, and the main socket desc. */
fscanf(fp,"%d ",&p);
port_number = p;
fscanf(fp,"%d ",&s);
fscanf(fp,"%d ",&f);
mudlog("REBOOT: Port: %d Masterport: %d Number of Entries: %d",p,s,f);
mudlog("REBOOT: Bootstrapping again.");
if (bootstrap() < 0) { /* Initialize data structures */
mudlog("REBOOT: Bootstrap failed.");
close(fd);
return -1;
}
init_userfile();
reorg_userfile();
fscanf(fp,"%d ",&nzones_to_reload);
while (nzones_to_reload) {
char zone_name[256];
fgets(zone_name,255,fp);
zone_name[strlen(zone_name)-1] = '\0';
load_zone (zone_name, NULL, NULL, NULL, NULL, NULL, NULL);
nzones_to_reload--;
}
main_socket = s;
FD_ZERO(&sockets_fds);
FD_ZERO(&buffer_fds);
FD_SET(s,&sockets_fds);
mudlog("REBOOT: Done with bootstrap - reading player info.");
/* Now, read in reboot information from the file. */
while(f)
{
int fd;
int new_loc;
int plx;
char hostname[256], char_name[256];
char *s;
PLAYER_REC *pl;
Boolean priv = False;
Boolean ok = False;
fscanf(fp,"%d ",&fd);
fscanf(fp,"%d ",&new_loc);
fgets(hostname,255,fp);
fgets(char_name,255,fp);
hostname[strlen(hostname)-1] = '\0';
char_name[strlen(char_name)-1] = '\0';
plx = find_free_player_slot();
printf("Put %s into %d.\n",char_name,plx);
setup_globals(plx);
pl = cur_player;
FD_SET(fd,&sockets_fds);
if (OPERATOR (char_name))
ok = priv = True;
else if (privileged_user (char_name))
ok = priv = True;
cur_player->isawiz = priv;
pl->sock_buffer_p = pl->sock_buffer_end = pl->sock_buffer;
pl->fil_des = fd;
pl->stream = fdopen(fd,"w");
fprintf(pl->stream,"Puff decides to prank the players and reboots the mud!\n");
pl->isforce= False;
s = pl->hostname;
cur_player->last_command = time(0);
cur_player->last_cmd = time(0);
cur_player->tr.trace_item = -1;
cur_player->logged_on = time(0);
strcpy(s, hostname);
setpname(mynum,char_name);
getuafinfo(char_name);
if(new_loc==-1)
new_loc= (phome(mynum)<0) ? phome(mynum) :
( (randperc() > 66) ? LOC_START_TEMPLE :
( (randperc() > 33) ? LOC_START_CHURCH :
LOC_HAVEN_HAVEN ));
setpwpn(mynum, -1);
setphelping(mynum, -1);
setpfighting(mynum, -1);
setpsitting(mynum, 0);
cur_player->iamon = True;
cur_player->iamon = True;
fetchprmpt(mynum);
push_input_handler(get_command);
get_command(NULL);
if (exists (new_loc))
setploc(mynum,new_loc);
else if (exists (new_loc = find_loc_by_id(phome(mynum))))
setploc(mynum,phome(mynum));
else
setploc(mynum, randperc() > 50 ? LOC_START_TEMPLE : LOC_START_CHURCH);
fprintf(pl->stream,"The Gods emphasize to Puff that her joke was NOT funny.\n");
f--;
}
/* Main program loop */
fclose(fp);
unlink (newname);
init_calendar ();
update_calendar ();
boot_reset ();
send_msg(DEST_ALL,0,LVL_MIN,LVL_MAX,NOBODY,NOBODY,
"Puff grins sheepishly and apologizes for her behavior. Unfortunately, the game has still been reset.\n");
/* write a new pid file */
{
/* ugly programming, don't try this at home.. declare your
variables at the top! */
FILE *rbfd;
rbfd = fopen(pidFileName,"w+");
if (!rbfd) {
progerror("Cannot open new pid file.\n");
}
else {
fprintf(rbfd,"%d",getpid());
fclose(rbfd);
}
}
main_loop(s);
mudlog( "Closing listening socket");
#ifdef INTERMUD
imShutdown(0);
#endif
close(s);
return 0;
}
#endif
static int
xmain (int fd)
{
int s;
int k;
struct sockaddr_in sin;
/* We arrive here only if we are to continue and now we are alone. */
/* Also, the PID_FILE is opened */
if (open_logfile (LOG_FILE, clear_syslog_file) < 0)
{
close (fd);
return -1;
}
if (bootstrap () < 0)
{ /* Initialize data structures */
close (fd);
return -1;
}
init_userfile();
reorg_userfile();
if (mud_port == -1)
mud_port = PORT;
/* Now we go background */
if (go_background (fd) < 0)
{
return -1;
}
k = 10;
bzero (&sin, sizeof (struct sockaddr_in));
/***/
while ((s = main_socket = make_service (mud_port, my_hostname,
sizeof (my_hostname),
&my_hostent, &sin)) == -4
&& errno == EADDRINUSE && --k >= 0)
{
sleep (2);
}
if (s < 0)
{
mudlog ("Error code %d from make_service", s);
progerror ("make_service");
return -1;
}
#ifndef REBOOT
if (s > 0)
{ /* We want the main socket at fd 0 */
dup2 (s, 0);
close (s);
s = main_socket = 0;
}
#endif
connect_ok (my_hostname, mud_port);
FD_ZERO (&sockets_fds);
FD_ZERO (&buffer_fds);
FD_SET (s, &sockets_fds);
/* Main program loop */
init_calendar ();
update_calendar ();
boot_reset ();
main_loop (s);
#ifdef DYRTWHO
setup_udp();
#endif
#ifdef INTERMUD
imShutdown(0);
#endif
close (s);
return 0;
}
static int
go_background (int fd)
{
char b[80];
int tty, x, y;
char *s;
/* Go background */
signal (SIGHUP, SIG_IGN);
signal (SIGINT, SIG_IGN);
signal (SIGQUIT, SIG_IGN);
signal (SIGTSTP, SIG_DFL);
signal (SIGTTOU, SIG_DFL);
signal (SIGTTIN, SIG_DFL);
if (!stay_foreground)
{
if (pipe (fildes) < 0)
{
progerror ("go_background/pipe");
exit (1);
}
switch (pid = fork ())
{
case -1:
progerror ("fork");
close (fd);
return -1;
case 0:
break;
default:
printf ("PID = %d\n", pid);
close (fd);
close (fildes[1]);
fflush (stdout); /* Flush stdout */
while ((x = read (fildes[0], b, sizeof (b))) > 0)
{
for (s = b, y = 0; y < x && s[y] != '\001'; ++y)
{
if (s[y] != '\n')
continue;
if (*s == '\001')
break;
if (write (1, s, y + 1) == -1)
progerror ("write(1, s, y + 1) failed");
s += y + 1;
x -= y + 1;
y = -1;
}
if (*s == '\001')
break;
if (x > 0)
{
if (write (1, s, x) == -1)
progerror ("write(1, s, x) failed");
}
}
exit (0); /* Let our parent process die */
}
if (stdin)
fclose (stdin);
if (stdout)
fclose (stdout);
close (fildes[0]);
}
pid = getpid (); /* Get our process id */
sprintf (b, "%d\n", pid);
if (write (fd, b, strlen (b)) == -1)
progerror ("write(fd, b, strlen(b)) failed");
close (fd);
if (!stay_foreground)
{
if ((tty = open ("/dev/tty", O_RDWR, S_IRUSR | S_IWUSR)) >= 0)
{
if (ioctl (tty, TIOCNOTTY, 0) < 0)
{
progerror ("ioctl,TIOCNOTTY");
return -1;
}
close (tty);
#ifdef LINUX
setpgrp();
#else
setpgrp (pid, pid); /* Make our own process group */
#endif
}
else if (errno != ENXIO)
{
progerror ("open,tty");
return -1;
}
signal (SIGINT, SIG_IGN);
signal (SIGQUIT, SIG_IGN);
}
else
{
signal (SIGINT, SIG_DFL);
signal (SIGQUIT, SIG_DFL);
}
signal (SIGTERM, sig_handler);
signal (SIGTSTP, SIG_DFL);
signal (SIGCONT, SIG_DFL);
signal (SIGTTOU, SIG_DFL);
signal (SIGTTIN, SIG_DFL);
#ifndef DEBUG
# ifndef HANDLER /* these may be handled by the custom handler */
signal (SIGSEGV, sig_handler); /* Segmentation fault */
signal (SIGBUS, sig_handler); /* Bus error */
# endif
signal (SIGSYS, sig_handler); /* Bad argument to system call */
#endif
signal (SIGPIPE, SIG_IGN); /* Broken pipe */
signal (SIGHUP, SIG_IGN); /* hang up */
return 1;
}
static int
check_pid (void)
{
int fd;
int pid = -1;
int c;
FILE *f;
char b[80];
sprintf(pidFileName,"%s.%d",PID_FILE,mud_port);
if ((fd = open (pidFileName, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) < 0)
{
/* The file exist already */
if (errno == EEXIST)
{
if ((f = fopen (pidFileName, "r")) != NULL)
{
/******************8
fgets (b, sizeof b, f);
pid = atoi (b);
**********************/
if (fgets (b, sizeof b, f))
pid = atoi(b);
else
pid = 0;
if (f)
fclose (f);
}
else
{
perror ("fopen," PID_FILE);
exit (1);
}
if (pid > 0)
{
if (!kill_other_mud)
{
printf ("There is another mud running, want me to kill it? ");
while ((c = getchar ()) != 'N' && c != 'n' && c != 'Y' &&
c != 'y' && c != '\n' && c != '\r');
if (c == 'Y' || c == 'y')
kill_other_mud = True;
}
if (!kill_other_mud)
{
printf ("Ok, then I'll die.\n");
exit (0);
}
printf ("Ok, Will kill other mud (PID = %d)\n", pid);
if (kill (pid, SIGTERM) < 0)
{
if (errno != ESRCH)
{
perror ("kill");
exit (1);
}
else if (unlink (pidFileName) < 0)
{ /* PID_FILE without process */
perror ("unlink");
exit (1);
}
}
}
else
{
if (unlink (pidFileName) < 0)
{ /* PID_FILE without process */
perror ("unlink");
exit (1);
}
}
c = 6;
while (True)
{
sleep (1);
if ((fd = open (pidFileName, O_WRONLY | O_CREAT | O_EXCL,
S_IRUSR | S_IWUSR)) >= 0)
break;
if (--c < 0)
{
printf ("Timeout, kill it yourself, I give up.\n");
exit (0);
}
}
}
else
{
perror ("open");
exit (1);
}
}
return fd;
}
static void
get_options (int argc, char **argv)
{
static void usage (void);
char *s;
int x;
if (argc == 1)
{
#ifdef LAZY
stay_foreground = True;
kill_other_mud = True;
mud_port = PORT;
max_players = 40;
#else
stay_foreground = False;
clear_syslog_file = False;
kill_other_mud = False;
mud_port = PORT;
max_players = 40;
#endif
return;
}
else
{
/*
* *since we make odd defaults with no args, we have to add
* * an option to say 'use real defaults', I select option a for that.
* * mudd -a is what usually should be just 'mudd'. -Alf
*/
}
while (--argc > 0)
{
s = *++argv;
if (*s++ != '-')
{
usage ();
exit (1);
}
x = *s++;
switch (x)
{
case 'a':
break;
#ifdef REBOOT
case 'r':
if ((*s != '\0') || ((--argc > 0) && (*(s = *++argv) != '\0')))
old_proc_num = atoi(s);
break;
#endif
case 'p':
if ((*s != '\0') || ((--argc > 0) && (*(s = *++argv) != '\0')))
{
if ((mud_port = atoi (s)) < 1024 || mud_port > 65535)
{
mud_port = PORT;
}
}
break;
case 'f':
stay_foreground = True;
break;
case 'k':
kill_other_mud = True;
break;
case 'c':
clear_syslog_file = True;
break;
case 'z':
#ifdef HANDLER
remove_handler ();
#else
printf ("Handler is not compiled in, option -z not operational.\n");
exit (0);
#endif
break;
case 'x':
kill_other_mud = True;
kill_and_exit = True;
break;
case 'i':
dump_info ();
exit (0);
break;
case 'n':
if ((*s != '\0') || ((--argc > 0) && (*(s = *++argv) != '\0')))
{
if ((max_players = atoi (s)) < 1 || max_players > 1000)
{
max_players = 40;
}
}
break;
case 'd':
if ((*s != '\0') || ((--argc > 0) && (*(s = *++argv) != '\0')))
{
data_dir = s;
}
break;
default:
usage ();
exit (1);
}
}
if (argc > 0)
{
usage ();
exit (1);
}
}
static void
usage (void)
{
fprintf (stderr, "Usage: %s [-p port] [-d dir] [-k] [-c] [-f] [-n count] [-x]\
\n\
Where:\n\
\tp port port to attach to.\n\
\td directory data directory.\n\
\tk kill other mud.\n\
\tc clear log file.\n\
\tn count maximum users.\n\
\tf stay in foregreound.\n\
\ti some interesting information.\n\
\tx just kill the running mud, don't run.\n\
", progname);
exit (1);
}
static void
main_loop (int m_socket)
{
static void new_connection (int fd);
int w = width;
int v;
int fd;
int plx = 0;
struct timeval *tv;
fd_set r_fds, e_fds;
/* reset(); */
cur_player = NULL;
quit_list = -1;
signal (SIGALRM, sig_handler);
for(v=0;v<32;v++) signal(v,sig_handler);
signal(SIGCHLD, SIG_DFL);
signal(SIGTRAP, SIG_DFL);
signal(SIGTERM, sig_handler);
signal(SIGTSTP, SIG_DFL);
signal(SIGCONT, SIG_DFL);
signal(SIGTTOU, SIG_DFL);
signal(SIGTTIN, SIG_DFL);
signal(SIGSEGV, sig_handler); /* Segmentation fault */
signal(SIGPIPE, SIG_IGN); /* Broken pipe */
set_timer ();
#ifdef INTERMUD
mudlog("INTERMUD: Attempting to connect to %s:%d",raddr,rport);
if((imfd = __iConn(raddr,rport)) < 0 ) {
mudlog("INTERMUD: Error connecting to %s:%d",raddr,rport);
}
else FD_SET(imfd,&sockets_fds);
#endif
while (!sig_term_happened)
{
switch (v = setjmp (to_main_loop))
{
case JMP_QUITTING:
bflush ();
end_connection ();
setup_globals (-1);
++fd;
break;
}
if (sig_timer_happened)
{
sig_timer_happened = False;
signal (SIGALRM, sig_handler);
setup_globals (-1); /* bflush() and disable mynum */
set_timer ();
on_timer ();
}
else
{
r_fds = e_fds = sockets_fds;
if (inp_buf_c > 0)
tv = &zerotime;
else
tv = NULL;
if ((v = select (w, &r_fds, NULL, &e_fds, tv)) < 0)
{
if (errno == EINTR)
continue;
progerror ("select");
exit (1);
}
fd = 0;
while (fd < width)
{
if (FD_ISSET (fd, &e_fds))
{
#ifdef INTERMUD
if( fd == imfd )
{
mudlog( "INTERMUD: Exception. Shutting down connection." );
FD_CLR( fd, &sockets_fds );
close( fd );
imfd = -1;
}
#endif
--v;
}
if (FD_ISSET (fd, &r_fds) || FD_ISSET (fd, &buffer_fds))
{
--v;
if (fd == m_socket)
{
new_connection (fd);
#ifdef INTERMUD
} else if (fd ==imfd) {
imPacket(fd);
#endif
}
else
{
handle_packet (fd);
}
bflush ();
}
while (quit_list >= 0)
end_connection ();
++fd;
}
}
}
mudlog ("SIGNAL: SIGTERM Handled");
for (plx = 0; plx < max_players; plx++)
{
if (!EMPTY (pname (plx)))
{
setup_globals (plx);
crapup ("\tSomething very unpleasant seems to have happened...",
CRAP_UNALIAS | CRAP_SAVE | CRAP_RETURN);
}
}
rm_pid_file ();
}
void
rm_pid_file (void)
{
if (unlink (pidFileName) < 0)
{
progerror ("rm_pid_file");
}
}
static void
end_connection (void)
{
INP_HANDLER *i, *j;
int fd;
int me = real_mynum;
int x;
if ((x = quit_list) < 0)
return;
if (x == real_mynum)
me = -1;
setup_globals (x);
quit_list = cur_player->quit_next;
cur_player->quit_next = -2;
fd = cur_player->fil_des;
bflush ();
i = cur_player->inp_handler;
while (i != NULL)
{
j = i;
i = i->next;
free ((char *) j);
}
cur_player->inp_handler = NULL;
if (FD_ISSET (fd, &buffer_fds))
inp_buf_c--;
FD_CLR (fd, &sockets_fds);
FD_CLR (fd, &buffer_fds);
close (fd);
if (cur_player->stream)
fclose (cur_player->stream);
cur_player->stream = NULL;
cur_player->inp_buffer_p = cur_player->inp_buffer_end = cur_player->inp_buffer;
cur_player->sock_buffer_p = cur_player->sock_buffer_end = cur_player->sock_buffer;
setup_globals (me);
}
static void
new_connection (int m_socket)
{
PLAYER_REC *pl;
FILE *f;
struct hostent *h;
int plx;
int fd;
int sin_len;
Boolean host_banned = False, host_b2 = False;
struct sockaddr_in sin;
char *host, *s;
char hostnum[MAXHOSTNAMELEN + 20];
char full_hostname[MAXHOSTNAMELEN + 20];
bzero ((char *) &sin, sizeof (struct sockaddr_in));
sin_len = sizeof (struct sockaddr_in);
if ((fd = accept (m_socket, (struct sockaddr *)&sin, &sin_len)) < 0)
{
progerror ("accept");
}
else if ((f = fdopen (fd, "w")) == NULL)
{
progerror ("fdopen");
exit (1);
}
else
{
#ifdef BROKEN_GCC
strncpy (hostnum,inet_ntoa (&sin.sin_addr), MAXHOSTNAMELEN);
#else
strncpy (hostnum, inet_ntoa (sin.sin_addr), MAXHOSTNAMELEN);
#endif
host_b2 = is_host_banned (hostnum);
host = hostnum;
if ((h = gethostbyaddr ((char *) &sin.sin_addr, sizeof (sin.sin_addr),
AF_INET)) == NULL)
{
mudlog ("gethostbyaddr: Couldn't find hostentry for %s", hostnum);
}
else
{
host_banned = is_host_banned (h->h_name);
host = h->h_name;
}
#ifdef IDENT
ident_username = (char *)GetIdent(h,m_socket,fd);
if (ident_username) {
sprintf(full_hostname,"%s@%s",ident_username,host);
}
else
#endif
strcpy(full_hostname,host);
if ((plx = find_free_player_slot ()) < 0)
{
fprintf (f, "\nSorry, this mud is full. Please come back later.\n");
if (f)
fflush (f);
if (f)
fclose (f);
return;
}
setup_globals (plx);
pl = cur_player;
pl->sock_buffer_p = pl->sock_buffer_end = pl->sock_buffer;
pl->sin_len = sin_len;
pl->sin = sin;
pl->fil_des = fd;
pl->stream = f;
pl->isforce = False;
s = pl->hostname;
if (host_banned || host_b2)
*s++ = '*';
#ifdef IDENT
strncpy(s,full_hostname,MAXHOSTNAMELEN);
#else
strncpy (s, host,MAXHOSTNAMELEN);
#endif
/* Include this socket as a socket to listen to */
FD_SET (fd, &sockets_fds);
new_player ();
}
}
void
handle_packet (int fd)
{
int plx = find_pl_index (fd);
register int x, y, g;
char *b, *c, *k;
char *p;
/*
extern char *sys_errlist[];
*/
setup_globals (plx);
g = 0;
if (cur_player->inp_buffer_p >= cur_player->inp_buffer_end)
{
if ((x = read (fd, cur_player->inp_buffer, MAX_COM_LEN - 5)) < 0)
{
if (errno == ECONNRESET || /* Connection reset by peer */
errno == EHOSTUNREACH || /* No route to host */
errno == ETIMEDOUT || /* Connection timed out */
errno == ENETUNREACH || /* Network is unreachable */
errno == ENETRESET || /* Net dropped connection on reset */
errno == ENETDOWN)
{ /* Network is down */
mudlog ("Connection failure: %s [%s]", sys_errlist[errno], pname (mynum));
crapup (NULL, CRAP_SAVE | CRAP_UNALIAS | CRAP_RETURN);
send_msg (DEST_ALL, MODE_QUIET | MODE_COLOR, max (pvis (mynum), LVL_APPREN),
LVL_MAX, mynum, NOBODY,
"[%s (%s) Link error: %s]\n", pname (mynum), cur_player->hostname, sys_errlist[errno]);
errno = 0;
longjmp (to_main_loop, JMP_QUITTING);
return;
}
/*
mudlog ("error when reading data from %s\n", pname (mynum));
*/
progerror (pname (mynum));
return;
}
if (x == 0)
{
crapup (NULL, CRAP_SAVE | CRAP_UNALIAS | CRAP_RETURN);
errno = 0;
quit_player ();
return;
}
if (*(cur_player->inp_buffer) == '\377')
{
return;
}
inp_buf_c++;
/*
* for (t = 0; t != MAX_COM_LEN; t++)
* if (cur_player->inp_buffer[t] == '%')
* cur_player->inp_buffer[t] = '&';
*/
FD_SET (fd, &buffer_fds);
b = cur_player->inp_buffer_p = (char *) cur_player->inp_buffer;
cur_player->inp_buffer_end = b + x;
}
else
{
b = cur_player->inp_buffer_p;
x = cur_player->inp_buffer_end - b;
}
c = cur_player->sock_buffer_p;
for (y = 0;
(b != 0) &&
(y < x) &&
(c < (cur_player->sock_buffer + MAX_COM_LEN - 6)) &&
b[y] != '\n' &&
b[y] != '\r';
++y)
{
if ((b[y] == '\010') || (b[y] == '\177'))
{
if (c > cur_player->sock_buffer)
c--;
}
else
*c++ = b[y];
}
cur_player->sock_buffer_p = c;
if (((y < x) && (c < (cur_player->sock_buffer + MAX_COM_LEN - 6))) && b != 0)
{
while (++y < x && (b[y] == '\n' || b[y] == '\r'));
*c = 0;
k = c;
c = cur_player->sock_buffer;
for (p = c; *p != '\0'; p++)
{
if (iscntrl (*p))
*p = ' ';
}
if (cur_player->snooped > 0)
{
*k++ = '\n';
*k-- = 0;
print_buf (c, True);
*k = 0;
}
g = 1;
}
cur_player->sock_buffer_p = c;
cur_player->inp_buffer_p = b + y;
if (y >= x)
{
FD_CLR (fd, &buffer_fds);
--inp_buf_c;
}
if (g)
{
cur_player->inp_handler->inp_handler (c);
cur_player->sock_buffer_p = cur_player->sock_buffer;
};
}
void
sig_handler (int sig)
{
switch (sig)
{
case SIGTERM:
mudlog ("SIGNAL: SIGTERM");
sig_term_happened = True;
return;
case SIGALRM:
sig_timer_happened = True;
return;
case SIGSEGV:
mudlog ("SIGNAL: SIGSEGV[%d]", sig);
break;
case SIGBUS:
mudlog ("SIGNAL: SIGBUS[%d]", sig);
break;
default:
mudlog ("SIGNAL: %d", sig);
break;
}
send_msg(DEST_ALL,0,LVL_MIN,LVL_MAX,NOBODY,NOBODY,
"Puff giggles and dances around, ecstatic about her evil plan.\n");
#ifdef INTERMUD
imShutdown(1);
#endif
if(fork()==0)
sysreboot(False);
kill(getpid(),SIGTRAP);
}
void dump_info (void)
{
time_t x;
Boolean handler;
#ifdef HANDLER
handler = True;
#else
handler = False;
#endif
x = time (0);
printf ("Current time %s", ctime (&x));
printf ("Version: %s (%s)\n", VERSION,MBANNER);
printf ("Crash handler: %sabled\n", handler ? "en" : "dis");
return;
}
#ifdef REBOOT
void rebootcom(void)
{
if (plev(mynum) < LVL_DEMI) {
bprintf ("You want me to do what?\n");
return;
}
broad ("Puff grins from ear to ear.\n");
#ifdef INTERMUD
imShutdown(1);
#endif
sysreboot(True);
}
void delaycom()
{
if (plev(mynum) < LVL_DEMI) {
bprintf("You can't do that now.\n");
} else {
if (the_world->w_delayed == 0)
the_world->w_delayed = 1;
else
the_world->w_delayed = 0;
send_msg (DEST_ALL, MODE_QUIET, LVL_DEMI, LVL_MAX, NOBODY, NOBODY,
"[&+bDelayed Reboot now &+r%s]\n", the_world->w_delayed ? "Enabled" :
"Disabled" );
mudlog("&+bDelayed Reboot: &+r%s&+b by &+Y%s", the_world->w_delayed ?
"ENABLED" : "DISABLED", pname(mynum));
}
}
void sysreboot(int saveLoc)
{
int in_bin, loop, nplayers, nzones_to_reload;
char filename[256];
char portinfo[256];
FILE *fp;
int port = port_number;
FILE *lock;
lock = fopen(".lock", "r");
if (lock != NULL)
{
broad("&+rREBOOT CANCELLED: COMPILE IN PROGRESS\n");
return;
}
sprintf(portinfo,"-p%d",port_number);
if (access ("../bin/aberd", F_OK) != -1)
in_bin = 1;
else if (access ("../src/aberd", F_OK) != -1)
in_bin = 0;
else {
bprintf ("Sorry, couldn't find aberd in ../bin/ or ../src/\n");
return;
}
signal (SIGALRM, SIG_IGN);
sprintf (filename, "reboot_file%d", getpid ());
fp = fopen (filename, "w");
fprintf (fp, "%d ", port);
fprintf (fp, "%d ", main_socket);
for (loop=0, nplayers=0; loop<max_players; loop++)
if (players[loop].iamon)
nplayers++;
fprintf (fp, "%d ", nplayers);
for (loop=num_const_zon, nzones_to_reload=0; loop<numzon; loop++)
if (!ztemporary(loop))
nzones_to_reload++;
fprintf (fp, "%d ", nzones_to_reload);
for (loop=num_const_zon; loop<numzon; loop++)
if (!ztemporary(loop))
fprintf (fp, "%s\n", zname(loop));
for (loop=0; loop<max_players; loop++) {
if (players[loop].iamon) {
setup_globals (loop);
saveme ();
fprintf (fp, "%d ", cur_player->fil_des);
fprintf (fp, "%d ", (saveLoc)?ploc(mynum):-1);
fprintf (fp, "%s\n", cur_player->hostname);
fprintf (fp, "%s\n", pname(mynum));
}
}
close_userfile();
fclose (fp);
sprintf (filename, "%d", getpid ());
mudlog ("REBOOT--------------------------------------%s", filename);
unlink (pidFileName);
if (in_bin)
execl ("../bin/aberd", "../bin/aberd", "-r", filename, portinfo, NULL);
else
execl ("../src/aberd", "../src/aberd", "-r", filename, portinfo, NULL);
}
#endif