/*Copyright by Erwin Andreasen, 2000*/
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "db.h"
#include "recycle.h"
#include "unistd.h"
DECLARE_DO_FUN(do_look);
void do_copyove (CHAR_DATA *ch, char *argument)
{
send_to_char("If you want to COPYOVER, spell it out.\n\r",ch);
return;
}
void do_copyover (CHAR_DATA *ch, char * argument)
{
FILE *fp;
DESCRIPTOR_DATA *d, *d_next;
char buf [100], buf2[100],buf3[100];
fp = fopen (COPYOVER_FILE, "w");
if (!fp)
{
send_to_char ("Copyover file not writeable, aborted.\n\r",ch);
bug ("Could not write to copyover file",0);
perror ("do_copyover:fopen");
return;
}
/* Consider changing all saved areas here, if you use OLC */
do_asave (NULL, "");/* - autosave changed areas */
save_sockets();
save_ranks();
sprintf (buf, "\n\r *** COPYOVER by %s - please remain seated!\n\r", ch->name);
/* For each playing descriptor, save its state */
for (d = descriptor_list; d ; d = d_next)
{
CHAR_DATA * och = CH (d);
d_next = d->next; /* We delete from the list , so need to save this */
if (!d->character || d->connected > CON_PLAYING) /* drop those logging on */
{
write_to_descriptor (d->descriptor, "\n\rSorry, we are rebooting. Come back in a few minutes.\n\r", 0);
close_socket (d); /* throw'em out */
}
else
{
fprintf (fp, "%d %s %s\n", d->descriptor, och->name, d->host);
if (och->level == 1)
{
write_to_descriptor (d->descriptor, "Since you are level one, and level one characters do not save, you gain a free level!\n\r", 0);
advance_level (och);
och->level++; /* Advance_level doesn't do that */
}
save_char_obj (och);
write_to_descriptor (d->descriptor, buf, 0);
}
}
fprintf (fp, "-1\n");
fclose (fp);
/* Close reserve and other always-open files and release other resources */
fclose (fpReserve);
/* exec - descriptors are inherited */
sprintf (buf, "%d", port);
sprintf (buf2, "%d", control);
sprintf (buf3, "%d", wwwcontrol);
execl (EXE_FILE, "rot","copyover", buf2, buf3, (char *) NULL);
/* Failed - sucessful exec will not return */
perror ("do_copyover: execl");
send_to_char ("Copyover FAILED!\n\r",ch);
/* Here you might want to reopen fpReserve */
fpReserve = fopen(NULL_FILE,"r");
}
/* Recover from a copyover - load players */
void copyover_recover ()
{
DESCRIPTOR_DATA *d;
FILE *fp;
char name [100];
char host[MAX_STRING_LENGTH];
int desc;
bool fOld;
bug ("Copyover recovery initiated",0);
fp = fopen (COPYOVER_FILE, "r");
if (!fp) /* there are some descriptors open which will hang forever then ? */
{
perror ("copyover_recover:fopen");
bug ("Copyover file not found. Exitting.\n\r",0);
exit (1);
}
unlink (COPYOVER_FILE); /* In case something crashes - doesn't prevent reading */
for (;;)
{
fscanf (fp, "%d %s %s\n", &desc, name, host);
if (desc == -1)
break;
/* Write something, and check if it goes error-free */
if (!write_to_descriptor (desc, "\n\rRestoring from copyover...\n\r",0))
{
close (desc); /* nope */
continue;
}
d = alloc_perm (sizeof(DESCRIPTOR_DATA));
init_descriptor2 (d,desc); /* set up various stuff */
d->host = str_dup (host);
d->next = descriptor_list;
descriptor_list = d;
d->connected = /*CON_COPYOVER_RECOVER*/ -15; /* -15, so close_socket frees the char */
/* Now, find the pfile */
fOld = load_char_obj (d, name);
if (!fOld) /* Player file not found?! */
{
write_to_descriptor (desc, "\n\rSomehow, your character was lost in the copyover. Sorry.\n\r", 0);
close_socket (d);
}
else /* ok! */
{
write_to_descriptor (desc, "\n\rCopyover recovery complete.\n\r",0);
/* Just In Case */
if (!d->character->in_room)
d->character->in_room = get_room_index (ROOM_VNUM_TEMPLE);
/* Insert in the char_list */
d->character->next = char_list;
char_list = d->character;
d->character->pcdata->socket=str_dup(host);
d->ip=str_dup(host);
conn_so_far++;
char_to_room (d->character, d->character->in_room);
if(d->character->pet)
char_to_room(d->character->pet,d->character->in_room);
do_look (d->character, "");
act ("$n materializes!", d->character, NULL, NULL, TO_ROOM);
if(d->character->pet)
act("$n materializes!", d->character->pet,NULL,NULL,TO_ROOM);
d->connected = CON_PLAYING;
reset_char(d->character);
}
}
fclose (fp);
}