MUD Shell
---------

Written by Fusion for MUD++ msmith@falcon.mercer.edu
Ported to EmberMUD 0.9.47 by zak@embermud.org.
EmberMUD can be found at www.embermud.org and http://sourceforge.net/projects/embermud/
Ported to Smaug by Samson of Alsherok.

Prerequisite Requirements
-------------------------

Only one - but it's a BIG one: That you ***NOT*** be using the other
shell code I'm distributing. The 2 versions will conflict with each
other and cause you unpredictable results at best, and at worst....
well..... yeah. Just don't do it.

Also might only work on *nix machines. YMMV.

Terms of Use
------------

You may use this snippet provided the following conditions are met:

1. Any included comment headers in the code are left intact. You may
   add your own, but do not take mine out.

2. This snippet may not be posted for redistribution on any site
without obtaining prior written consent from the Alsherok team.

If you can't agree to these terms, don't use this code, and don't expect
me to help if something breaks while installing it. Harsh? Hardly. I'm
tired of people who come crawling to whine and complain when they haven't
bothered to comply with the terms first.

NOTE: Special condition for this code: Support of any kind will not be given
due to the extremely sensitive nature of what this does. If you can't fix it
on your own, don't ask me for help. This is being done to limit my liability
in the event it is somehow then used to damage your mud. You can thank our
litigious society for that. Besides, suing me won't help. I'm broke.

What this code does
-------------------

This code enables you to open an interactive shell session with the account
the mud is hosted with. I really shouldn't need to go into the security
nightmare this could potentially create, so if you can't trust your staff,
I'd suggest not using this code. This goes way beyond just passing system
commands. It will behave more or less like you're really in the shell, except
you won't be able to open editor sessions such as pico with it.

Known issues:

1. On muds with the MCCP client compression protocol installed, immortals
who log on with that ability enabled and have access to the shell command
will be presented with a screenful of garbage if using a client that supports
MCCP. To correct this temporarily, I've added 2 lines in both shell routines
to turn off the user's MCCP. It will generally need to be restarted manually.

Installation Instructions
-------------------------

1. Add the mudshell.c file to your src directory.

2. In the Makefile, locate:

#Uncomment the line below if you are getting undefined crypt errors
NEED_CRYPT = -lcrypt

Add this below it:

#Mud Shell support. Comment out to disable this feature.
MUDSHELL = 1

Below:

H_FILES = mud.h color.h bet.h

Add the following:

ifdef MUDSHELL
   C_FILES := mudshell.c $(C_FILES)
   C_FLAGS := $(C_FLAGS) -DMUDSHELL
endif

3. In comm.c, locate the global variables section.

Add this to the list:

#ifdef MUDSHELL
   bool reap_shells = FALSE;
   extern CHAR_DATA *first_shell_ch;
   extern CHAR_DATA *last_shell_ch;
#endif

Locate function accept_new, and ABOVE that, add:

#ifdef MUDSHELL
bool can_read_descriptor( int fd )
{
   struct timeval tzero;
   fd_set R_SET;

   tzero.tv_sec = 0;
   tzero.tv_usec = 0;
   FD_ZERO( &R_SET );
   FD_SET( fd, &R_SET );
   while( select( fd + 1, &R_SET, 0, 0, &tzero ) < 0 )
   {
      if( errno == EINTR )
         continue;
      return FALSE;
   }
   return ( bool )FD_ISSET( fd, &R_SET );
}
#endif

In function aaccept_new, locate:

	if ( select( maxdesc+1, &in_set, &out_set, &exc_set, &null_time ) < 0 )
	{
	    perror( "accept_new: select: poll" );
	    exit( 1 );
	}

Below that, add:

#ifdef MUDSHELL
   /* Guess this is as good a place as any for shell reaping? */
   if( reap_shells )
   {
      CHAR_DATA *ch;
      /* No one in the shell list?  Then don't reap shells anymore! */
      if( !first_shell_ch )
         reap_shells = FALSE;
      else
      {
         /* Check the "in" pipe for each character in the list.
          * If any of them are readable, put them back into the game. */
         for( ch = first_shell_ch; ch; ch = ch->next_in_shell )
         {
            if( can_read_descriptor( ch->fdpair[0] ) )
            {
               close( ch->fdpair[0] );
               UNLINK( ch, first_shell_ch, last_shell_ch, next_in_shell, prev_in_shell );
               LINK( ch, first_char, last_char, next, prev );
               send_to_char( "MUD I/O resumed.\r\n", ch );
               ch->desc->connected = CON_PLAYING;
               continue;
            }
         }
      }
   }
#endif

Locate function game_loop, and ABOVE that, add:

#ifdef MUDSHELL
void sigchld_handler( int sig )
{
   pid_t child_pid;
   int status;

   if( ( child_pid = wait( &status ) ) < 0 )
      return;

   reap_shells = TRUE;
   return;
}
#endif

In function game_loop, locate:

#ifndef WIN32
    signal( SIGPIPE, SIG_IGN );
    signal( SIGALRM, caught_alarm );
#endif

Below that, add:

#ifdef MUDSHELL
   signal( SIGCHLD, sigchld_handler );
#endif

4. In mud.h, locate the list containing CON_PLAYING.

Add CON_MUDSHELL to the end of that list.

Then locate the char_data struct, and add the following to the end:

#ifdef MUDSHELL
   CHAR_DATA *next_in_shell;
   CHAR_DATA *prev_in_shell;
   int fdpair[2];
#endif

5. Make clean, recompile.

6. After rebooting, create a command to call do_mudshell and be absolutely sure
   about what level you make it available to.

This code has been installed and tested on Smaug 1.6 FUSS, which is a bugfixed
and cleaned up version of the base Smaug 1.4a code. The Smaug FUSS Project is
maintained on servers which run the Redhat and Fedora family of Linux. Limited
testing has also been done on the Cygwin package under WindowsXP SP1 and SP2.
Users of BSD, MSVC, MSVC++, or Macintosh platforms are on their own as The
Smaug FUSS Project does not have access to these development environments for testing.
The Smaug FUSS Project can be found at: http://www.smaugfuss.org

No guarantees are made that this code will be compatible with your codebase and any
modifications you may have made to it. No warranty of any kind is expressed or implied
by the use of this code, and we are not responsible for any damages which may result
from the application of this snippet to your codebase.

Adventure beckons in the lands of mystique....
Samson, Implementor of Alsherok
http://www.alsherok.net
telnet://alsherok.net:5500

IMC2 contact: Samson@Alsherok