log_string( "Booting Database" );
boot_db( fCopyOver );
log_string( "Initializing socket" );
if( !fCopyOver ) /* We have already the port if copyover'ed */
control = init_socket( port );
// control2 = init_socket( port + 1 );
sprintf( log_buf, "&wStar Wars: Galactic Insights v%s.%s is ready to rock and roll on port %d.&W", MUD_VERSION_MAJOR,
MUD_VERSION_MINOR, port );
log_string( log_buf );
if( fCopyOver )
log_string( "Initiating hotboot recovery." );
----> THIS LINE close(control);
imc_shutdown( FALSE );
I3_shutdown( 0 );
It still crashes after I added that fix, but certainly not as often.
control is assigned about 13 lines up. It's probably the listening socket for the mud, which will be checked using either select() or poll() for incoming connections.
If that socket has already been closed, and you try to close it again, the universe will be unhappy. Likewise, if you try to close it and it hasn't yet been opened, life will be bad. C is annoying that way, the paranoid among us tend to check almost everything possible before accessing a pointer.
My other problem is that hotboot is saving items inside of corpses. Someone looted a corpse, a hotboot was done, and the items appeared back inside the corpse and on the player. I added the fixes to fread_obj so that it shouldn't save corpses, but it apprently still is. Any help?
That's a classic exploit which happens when you don't have atomic code. You go to move an object from the corpse to your inventiry. The code copies the object to you, then deletes it from the corpse. If it crashes between the two operations (and the resulting hotboot code saves both inventories and reboots), you end up with two copies.
Some of your choices are:
1. Live with item duplication bugs and try to prevent things that cause crashes.
2. Reverse the order so it deletes first and then copies... that would result in item loss, rather than duplication.
3. Devise a persistant scheme for doing item transfers. If you used a database, you'd wrap both operations with a transaction, which would rollback on a crash. Not using a database, you could open a file that describes the transaction in progress so if you crash before it completes, the recovery code on the other end of the hotboot could look for such files and pick up where it left off.
That's one of the reasons I prefer to let the driver crash. If you engineer it so things bounce themselves, then you don't have as much incentive to actually FIX the bugs. If your players have been sending you email for 6 hours because their game is sitting in gdb, frozen on a seg-fault, I (at least) am more likely to sit down and fix the cause of the problem, rather than slapping a band-aid on and letting it run again.