void do_copyover (CHAR_DATA *ch, char * argument)
{
FILE *fp;
DESCRIPTOR_DATA *d, *d_next;
char buf [100], buf2[100];
/* patch starts here */
struct stat info;
if (!stat(EXE_FILE, &info))
{
send_to_char ("Can't copyover. Executable doesn't exist.\r\n",ch);
logf ("Could not find mud executable: %s", EXE_FILE);
return;
}
/* patch ends here */
fp = fopen (COPYOVER_FILE, "w");
..blah blah..
}
void do_copyover (CHAR_DATA *ch, char * argument)
{
FILE *fp;
DESCRIPTOR_DATA *d, *d_next;
char buf [100], buf2[100];
/* patch starts here */
struct stat info;
if (!stat(EXE_FILE, &info))
{
send_to_char ("Can't copyover. Executable doesn't exist.\r\n",ch);
logf ("Could not find mud executable: %s", EXE_FILE);
return;
}
/* patch ends here */
fp = fopen (COPYOVER_FILE, "w");
..blah blah..
}
–> Compiling file: act_wiz.c <–
act_wiz.c: In function `do_copyover':
act_wiz.c:6644: error: storage size of 'info' isn't known
act_wiz.c:6646: warning: implicit declaration of function `stat'
act_wiz.c:6649: warning: implicit declaration of function `logf'
act_wiz.c:6649: error: incompatible type for argument 1 of `logf'
act_wiz.c:6649: error: too many arguments to function `logf'
act_wiz.c:6644: warning: unused variable `info'
make: *** [obj/act_wiz.o] Error 1
act_wiz.c: In function `do_copyover':
act_wiz.c:6644: error: storage size of 'info' isn't known
act_wiz.c:6646: warning: implicit declaration of function `stat'
act_wiz.c:6649: warning: passing arg 1 of `logprintf' from incompatible pointer
type
act_wiz.c:6644: warning: unused variable `info'
make: *** [obj/act_wiz.o] Error 1
void do_copyover (CHAR_DATA *ch, char * argument)
{
FILE *fp;
DESCRIPTOR_DATA *d, *d_next;
char buf [100], buf2[100];
/*
struct stat info;
if (!stat(EXE_FILE, &info))
{
send_to_char ("Can't copyover. Executable doesn't exist.\r\n",ch);
logprintf (NULL,"Could not find mud executable: %s", EXE_FILE);
return;
}
*/
fp = fopen (COPYOVER_FILE, "w");
if (!fp)
{
send_to_char ("Copyover file not writeable, aborted.\n\r",ch);
logprintf (NULL,"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_call( ch,"all");
do_forceauto(ch,"save");
if (IS_SET(ch->in_room->room_flags, ROOM_TOTAL_DARKNESS))
{
REMOVE_BIT(ch->in_room->room_flags, ROOM_TOTAL_DARKNESS);
}
//LALA
if ( IS_SET(ch->flag2, AFF2_INARENA) || IS_SET(ch->flag2,AFF2_CHALLENGED)
|| IS_SET(ch->flag2, AFF2_CHALLENGER))
{
REMOVE_BIT(ch->flag2, AFF2_CHALLENGED);
REMOVE_BIT(ch->flag2, AFF2_CHALLENGER);
REMOVE_BIT(ch->flag2, AFF2_INARENA );
undo_arena(ch);
arena = FIGHT_CLEAR;
}
do_asave (NULL, "");
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);
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);
execl (EXE_FILE, "../src/merc.exe", 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 */
}
#define EXE_FILE "../src/merc.exe"
#define EXE_FILE "../src/merc.exe"
#define EXE_FILE "../src/merc.exe"
I hadn't thought of it the way you explained it david, I do see what you mean and will do my best to improve my old habits on here. I can't make any promises because I've been typing the same way since I was 12 years old, but I will try.
Regarding the answer about git vs tar … hehe git tar, guitar,… sorry, got diverted there… you mentioned being able to skip a change while still leaving changes that were made after that in. How does this work? While I understand the concept, I'm unable to picture the actual practice. It sounds like quite the nifty feature.
There are likely going to be follow-ups on why during the build process rm -f merc.exe or gcc -o merc.exe are failing because of access errors. Assuming at some point the OP actually sees the failure messages, whether they be suppressed or in the wrong color. Factoring in the use of Erwin's copyover code and Cygwin compounds the already lame practice of making the live executable the target or removing it prior to the build process. Now the general reason why removal of the target is bad is that the mud might crash and restart, be manually rebooted, or "copyovered/hotbooted" anytime prior to creating a working target executable. It's a problem independent of operating system and with players waiting for the game to return the situation is less than ideal. On windows, and this includes cygwin (as cygwin processes are windows processes), executables and dlls are treated as memory mapped files and are locked while the process is alive. There's a trick to get around access issues by installing a new executable by renaming the running one, before copying a new one and hotbooting the mud.
I'm going to assume that the live executable (the one the startup script and the hardcoded copyover point to) reside in the area directory, and that the build target executable resides in the src directory. They could reside elsewhere, but the point of the exercise is the build process doesn't target the live executable.
Thank you for the info Tyche I'll look into this later tonight. However if I change the name of the executable, then if somebody were to do a copyover before the new one is created wouldn't the mud crash? Granted it's not likely to happen with that split second precision but stranger things do happen.