/
vortex/area/
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdarg.h> 
#include "merc.h"
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>

#define MSL MAX_STRING_LENGTH
#define MIL MAX_INPUT_LENGTH
void logf(char * fmt, ...);

void logf (char * fmt, ...)
{
	char buf[2*MSL];
	va_list args;
	va_start (args, fmt);
	vsprintf (buf, fmt, args);
	va_end (args);
	
	log_string (buf);
}


#define CH(descriptor)  ((descriptor)->original ? \
(descriptor)->original : (descriptor)->character)

extern int port,control; /* db.c */

void do_copyover (CHAR_DATA *ch, char * argument)
{
	FILE *fp;
	DESCRIPTOR_DATA *d, *d_next;
	char buf [100], buf2[100];
	
	fp = fopen (COPYOVER_FILE, "w");
	
	if (!fp)
	{
		send_to_char ("Copyover file not writeable, aborted.\n\r",ch);
		logf ("Could not write to copyover file: %s", COPYOVER_FILE);
		perror ("do_copyover:fopen");
		return;
	}
	
	/* Consider changing all saved areas here, if you use OLC */
	
	/* do_asave (NULL, ""); - autosave changed areas */
	
	if( IS_SET(ch->act,PLR_WIZINVIS) || IS_SET(ch->act,PLR_INCOG) )
	 sprintf(buf,"\n\r *** COPYOVER by an Immortal - please remain seated!\n\r");
	else	
	 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 < 2)
			{
			 write_to_descriptor (d->descriptor, "Since you are a newbie, and have not saved, you have been advanced!\n\r", 0);
			 och->level = 2;
			 och->trust = 2;
			 och->mkill += 5;
			}
			stop_fighting(och,TRUE);
			och->challenged = NULL;
			och->challenger = NULL;
			if( IS_SET(och->newbits, HAS_HADES) )
				REMOVE_BIT(och->newbits, HAS_HADES);
			if( IS_SET(och->act,PLR_CHALLENGER) )
        			REMOVE_BIT(och->act,PLR_CHALLENGER);
			if( IS_SET(och->act,PLR_CHALLENGED) )
        			REMOVE_BIT(och->act,PLR_CHALLENGED);
        		arena = FIGHT_OPEN;
                        if( in_arena(och) )
                        {
                         char_from_room(och);
                         char_to_room(och,get_room_index(3001));
                        }
			do_stand(och,"");
			do_call(och,"all");
			save_char_obj (och);
			write_to_descriptor (d->descriptor, buf, 0);
		}
	}
	fprintf (fp, "-1\n");
        log_string("Closing file.");
	fclose (fp);
	
	/* Close reserve and other always-open files and release other resources */
	log_string("Closing reserve stream.");
	fclose (fpReserve);
	
	/* exec - descriptors are inherited */
	log_string("Attempting new execution.");
	sprintf (buf, "%d", port);
	sprintf (buf2, "%d", control);
	execl (EXE_FILE, "Vortex", buf, "copyover", buf2, (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[MSL];
	int desc;
	bool fOld;
	
	logf ("Copyover recovery initiated");
	
	fp = fopen (COPYOVER_FILE, "r");
	
	if (!fp) /* there are some descriptors open which will hang forever then ? */
	{
		perror ("copyover_recover:fopen");
		logf ("Copyover file not found. Exitting.\n\r");
		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_descriptor (d,desc); /* set up various stuff */
		
		d->host = str_dup (host);
		d->next = descriptor_list;
		descriptor_list = d;
		d->connected = CON_COPYOVER_RECOVER; /* -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;

			char_to_room (d->character, d->character->in_room);
			do_look (d->character, "");
			act ("$n materializes!", d->character, NULL, NULL, TO_ROOM);
			d->connected = CON_PLAYING;
		}
		
	}
	
	fclose (fp);
	update_players_logged();
}

void auto_copyover()
{
        FILE *fp;
	FILE *last;
        DESCRIPTOR_DATA *d, *d_next;
        char buf [100], buf2[100];

        fp = fopen (COPYOVER_FILE, "w");

        if (!fp)
        {
                logf("Could not write to copyover file: %s", COPYOVER_FILE);
                perror ("do_copyover:fopen");
                return;
        }
       fclose(fpReserve);
       if((last = fopen(LAST_COMMAND,"a")) == NULL)
         bug("Error in do_auto_save opening last_command.txt",0);

       fprintf(last,"Last Command: %s\n",
            last_command);

       fclose( last );
       fpReserve = fopen( NULL_FILE, "r" );
	sprintf(buf,"Last command was %s",last_command);
	log_string(buf);
        /* Consider changing all saved areas here, if you use OLC */

        /* do_asave (NULL, ""); - autosave changed areas */

         sprintf(buf,"\n\r *** CRASH DETECTED :: Attempting copyover...\n\r");

        /* 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 < 2)
                        {
                         write_to_descriptor (d->descriptor, "Since you are a newbie, and have not saved, you have been advanced!\n",0);
                         och->level = 2;
                         och->trust = 2;
                         och->mkill += 5;
                        }
                        stop_fighting(och,TRUE);
                        och->challenged = NULL;
                        och->challenger = NULL;
                        if( IS_SET(och->newbits, HAS_HADES) )
                                REMOVE_BIT(och->newbits, HAS_HADES);
                        if( IS_SET(och->act,PLR_CHALLENGER) )
                                REMOVE_BIT(och->act,PLR_CHALLENGER);
                        if( IS_SET(och->act,PLR_CHALLENGED) )
                                REMOVE_BIT(och->act,PLR_CHALLENGED);
                        arena = FIGHT_OPEN;
			if( in_arena(och) )
			{
			 char_from_room(och);
			 char_to_room(och,get_room_index(3001));
			}
                        do_stand(och,"");
                        do_call(och,"all");
                        save_char_obj (och);
                       write_to_descriptor (d->descriptor, buf, 0);
                }
        }
        fprintf (fp, "-1\n");
        log_string("Closing file.");
        fclose (fp);
                        
        /* Close reserve and other always-open files and release other resources */
        log_string("Closing reserve stream.");
        fclose (fpReserve);
                        
        /* exec - descriptors are inherited */
        log_string("Attempting new execution.");
        sprintf (buf, "%d", port);
        sprintf (buf2, "%d", control);  
        execl (EXE_FILE, "Vortex", buf, "copyover", buf2, (char *) NULL);
                         
        /* Failed - sucessful exec will not return */
                        
        perror ("do_copyover: execl");
        logf("Copyover FAILED!\n\r");
                        
        /* Here you might want to reopen fpReserve */
        fpReserve = fopen(NULL_FILE, "r");
}