#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"); }