ur/
ur/boards/
ur/clans/
ur/councils/
ur/homes/
ur/planets/
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include "mud.h"
#ifdef USE_IMC
	#include "imc.h"
  	#include "icec.h"
#endif

/* Globals */
int		control;
int		control2;
int		conjava;
int		conclient;


/* Externals */
char *help_fix		args( ( char *text ) );

/*
 * Copyover "do" Function		-Nopey
 * 6/11/01
 */
void do_copyover( CHAR_DATA *ch, char *argument )
{
	char arg[MAX_INPUT_LENGTH];

	argument = one_argument( argument, arg );
	
	/* if there is no arg supplied */
	if( arg[0] == '\0' )
	{
		send_to_char_color( "\n\r&YSyntax: copyover saveall\n\r", ch );
		send_to_char_color( "Syntax: copyover nosave&g\n\r", ch );
		return;
	}

	/* saves all data */
	if( !str_cmp( arg, "saveall" ) )
	{
		log_string( "Copyover: Saving Game Data..." );
		save_gamedata();
		log_string( "Copyover Save: Game Data Saved. Performing Copyover..." );
		copyover();
		return;
	}

	/* saves nothing */
	if( !str_cmp( arg, "nosave" ) )
	{
		log_string( "Copyover NoSave: Performing Copyover..." );
		copyover();
		return;
	}
}

/*
 * Actual Copyover "Beef" Function	-Nopey
 */
void copyover()
{
	FILE *fp;
	DESCRIPTOR_DATA *d = NULL;
	char buf2[100], buf3[100], buf4[100], buf5[100], buf6[100];
	int port = 5555;
	fp = fopen( COPYOVER_FILE, "w" );
	
#ifdef USE_IMC
	log_string( "Copyover: Initiating IMC2 shutdown..." );
	imc_shutdown();
	log_string( "Copyover: IMC2 Shutdown Complete." );
#endif
	for( d = first_descriptor; d; d = d->next )
	{	
		write_to_buffer( d, "Copyover: Copyover has been initiated. Hold on.\n\r", 0 );
		/* drop those logging on */
		if( !d->character || d->connected != CON_PLAYING )
        	{
			write_to_buffer( d, "Sorry the game is currently in a copyover. Please come back in a minute or so.\n\r", 0 );
			close_socket( d, FALSE );
		}
		else
		{
#ifdef I3
			I3_close_char( d );
#endif
			if( d->character->top_level == 1 )
			{
				write_to_descriptor( d->descriptor, "Since you are level one, and level ones are not saved, you gain a level!\n\r", 0 );
				fprintf( fp, "%d %d %d %d %s %s %s\n", d->descriptor, d->port, ROOM_VNUM_TEMPLE, d->idle, d->character->name, d->user, d->host );
			        advance_level(d->character, 1);
                  		d->character->top_level++;
			} else 
				fprintf( fp, "%d %d %d %d %s %s %s\n", d->descriptor, d->port, d->character->in_room->vnum, d->idle, d->character->name, d->user, d->host );
		}		
	}
	fprintf (fp, "-1\n");
	fclose( fp );

#ifdef I3
    log_string( "Initiating Intermud-3 shutdown...." );	
    I3_shutdown( 0 );
    log_string( "Intermud-3 shutdown completed." );
#endif

	log_string( "Initiating Copyover." );
	fclose( fpReserve );
	fclose( fpLOG );

	/* exec - descriptors are inherited */
        sprintf( buf2, "%d", port );
        sprintf( buf3, "%d", control );
        sprintf( buf4, "%d", control2 );
        sprintf( buf5, "%d", conclient );
        sprintf( buf6, "%d", conjava );
	
	/* execute the file */
	execl( EXE_FILE, "unknown", buf2, "copyover", buf3, buf4, buf5, buf6, (char*)NULL );
	
        /* Here you might want to reopen fpReserve */
        /* Since I'm a neophyte type guy, I'll assume
	 * this is a good idea and cut and past from main() */
        if( ( fpReserve = fopen( NULL_FILE, "r" ) ) == NULL )
        {
        	perror( NULL_FILE );
                exit( 1 );
        }
        if( ( fpLOG = fopen( NULL_FILE, "r" ) ) == NULL )
        {
                perror( NULL_FILE );
                exit( 1 );
        }
	log_string( "Copyover FAILED!" );
	perror( "Copyover: Execl" ); 
}

/*
 * Copyover Recover
 * Rewritten 6/14/01		-Nopey
 */
void copyover_recover()
{
	DESCRIPTOR_DATA *d = NULL;
	FILE *fp;
	char name [100];   
  	char host[MAX_STRING_LENGTH];
	char user[MAX_INPUT_LENGTH]; /* 6/24/01 - User fix - Nopey */
	char buf[MAX_INPUT_LENGTH];
  	int desc;
	int dport; /* 6/24/01 - Port fix - Nopey */
	int idle; /* 6/24/01 - Idle fix - Nopey */
  	bool fOld;
	int room;
	fp = fopen( COPYOVER_FILE, "r" );
	
	/* there are some descriptors open which will hang forever then ? */
	if( !fp )
        {
                  perror("Copyver: copyover_recover:fopen");
                  log_string( "Copyover File not Found. Exiting.");
                  exit( 1 ); 
        }

	log_string( "Copyover: Recovering Character Links..." );

	/* In case something crashes - doesn't prevent reading */  
	unlink( COPYOVER_FILE );
/*	unlink( MOBSAVE_FILE ); 
	unlink( OBJSAVE_FILE ); */  

	for( ; ; )
	{
		fscanf( fp, "%d %d %d %d %s %s %s\n", &desc, &dport, &room, &idle, name, user, host );
		if( desc == -1 )
       		break;

		/* Write something, and check if it goes error-free */
     		if(!write_to_descriptor(desc, "\n\rCopyover: Restoring your link.\n\r", 0))
       		       	close( desc ); /* nope */
                

		/* boot up the descriptor! */
                CREATE( d, DESCRIPTOR_DATA, 1 );
                d->next		= NULL;
                d->descriptor	= desc;
                d->connected	= CON_GET_NAME;
                d->outsize	= 2000;
                d->idle		= 0;
                d->lines	= 0;
                d->scrlen	= 24;
                d->newstate	= 0;
                d->prevcolor	= 0x07;
                CREATE( d->outbuf, char, d->outsize );
                d->user = STRALLOC( user );
                d->host = STRALLOC( host );
                d->port = dport;
                d->idle = idle;

                LINK( d, first_descriptor, last_descriptor, next, prev );
		d->connected = CON_COPYOVER_RECOVER;

		/* Now, find the pfile */
		fOld = load_char_obj( d, name, FALSE );
	
		/* No pfile? */
		if( !fOld )
		{	
			write_to_descriptor( desc, "Copyover: Somehow your Character was lost during the Copyover. Please contact an Immortal.\n\r", 0 );
			close_socket (d, FALSE);
		}
		else /* ok! */
		{
			d->character->in_room = get_room_index( room );
			if( !d->character->in_room )
				d->character->in_room = get_room_index( ROOM_VNUM_TEMPLE );
			 /* Insert in the char_list */
           		LINK( d->character, first_char, last_char, next, prev );
			num_descriptors++;
           		sysdata.maxplayers++;
			/* send to the room */
			char_to_room( d->character, d->character->in_room );
#ifdef I3
	      		I3_char_login( d->character );
#endif
			d->connected = CON_PLAYING;
			do_look( d->character, "auto noprog" );
			act( AT_YELLOW, "$n magically arrives in a puff of grey smoke.", d->character, NULL, NULL, TO_ROOM);
			sprintf( buf, "\n\rWelcome back, %s.\n\r", d->character->name );
			write_to_buffer( d, buf, 0 );
		}
	}
	log_string( "Copyover Sucessful. Resuming Play." );
	fclose( fp );
	return;
}

/*
 * Not sure if this is even used anymore... oh well
 */

/*
 * Decided to Clean the code up even more	-Nopey
 * Left here for upgrades so that the people
 * don't need to get old init_descriptor.
 * **NOTE** If your NOT upgrading, comment this out.
 */
void init_descriptor( DESCRIPTOR_DATA *d, int desc)
{
        d->next		= NULL;
        d->descriptor	= desc;
        d->connected	= CON_GET_NAME;
        d->outsize	= 2000;
        d->idle		= 0;
        d->lines	= 0;
        d->scrlen	= 24;
        d->newstate	= 0;
        d->prevcolor	= 0x07;
    CREATE( d->outbuf, char, d->outsize );
}


void save_gamedata()
{
	char filename[256];
	FILE *fpout;
	AREA_DATA *tarea;
	CHAR_DATA *victim;
	HELP_DATA *pHelp;
	
	        for( victim = first_char; victim; victim = victim->next )
        	{
			/* save character */
        		save_char_obj( victim );
        		pager_printf_color( victim, "&YYou have been manually due to a copyover.\n\r" );
        	}
	
		/* save area files */
		for( tarea = first_build; tarea; tarea = tarea->next )
		{
        		if( !IS_SET( tarea->status, AREA_LOADED ) )
        		{
        			continue;
        		}
        		sprintf( filename, "%s%s", BUILD_DIR, tarea->filename );
        		fold_area( tarea, filename, FALSE );
		}
		rename( "help.are", "help.are.bak" );
        	log_string( "Saving help.are..." );
		fclose( fpReserve );
        	if ( ( fpout = fopen( "help.are", "w" ) ) == NULL )
        	{
        	   bug( "hset save: fopen", 0 );
        	   perror( "help.are" );
        	   fpReserve = fopen( NULL_FILE, "r" );
	   	   return;
		}
		fprintf( fpout, "#HELPS\n\n" );
        	for ( pHelp = first_help; pHelp; pHelp = pHelp->next )
        	    fprintf( fpout, "%d %s~\n%s~\n\n",
        		pHelp->level, pHelp->keyword, help_fix(pHelp->text) );
        	fprintf( fpout, "0 $~\n\n\n#$\n" );
        	fclose( fpout );
        	fpReserve = fopen( NULL_FILE, "r" );
        	//save_commands();
        	save_socials();
        	save_commands();
        	save_skill_table();
        	save_herb_table();
		return;
}