/*xprintf system by Darien of sandstorm*/
/*Once you have All of the bellow installed, all you have todo is go through your code
  and change the sprintf's to xprintf's.  Now, you want to avoid using xprintf on anything
  that is plainly a char *, if you wish to use xprintf on something that is a char * use xprintf_2
  on it, it defaults to MIL as the max-size, you may change that if you wish, but it suits my mud
  just fine.
  Enjoy.  This is very helpful in catching overflows.
 */


In merc.h where you have your defines such as MAX_STRING_LENGTH add this.

#define MAS	       262144 // This should be MORE then enough.


Replace your MAX_STRING_LENGTH/MAX_INPUT_LENGTH with these.
#define MAX_STRING_LENGTH	 8192
#define MAX_INPUT_LENGTH	 2048

In merc.h add this to your proto-types.
void safe_printf(const char *file, const char *function, int line,int size, char *str, char *fmt, ...);

Further down place this.  Warning this doesn't work with all compilers,
This works with GCC.

# define xprintf(var,args...)   safe_printf (__FILE__, __FUNCTION__, __LINE__, sizeof(var), (var), ##args )

/*This is for char * arguments.*/
# define xprintf_2(var,args...) safe_printf (__FILE__, __FUNCTION__, __LINE__, MIL, (var), ##args)


/*Originaly, i heard on gamedev that someone was looking for a way to stop sprintf
 *from overflowing, ofcourse, people fail to think of functions like strlcpy, which
 *is essentaily a safe sprintf, atleast as it has been described to me.  I however
 *chose to write my own system.  This allows me to capture the function, and line
 *of the overflowing string in question.  Thus allowing me to essentaily find out
 *where the mud overflows, and stop it from happening.  Great little tool.
 *All i ask is that you leave this header in place.  -- Darien of Sandstorm:Mages Sanctuary
 */
void safe_printf(const char *file, const char *function, int line,int size, char *str, char *fmt, ...)
{
  char buf [MAS];
  va_list args;
  va_start (args, fmt);
  vsprintf (buf, fmt, args);
  va_end (args);

  /*Max Alloc Size is allot!*/
  if(size > MAS)
  {
    char egbug[MSL];
    log_string(LOG_BUG, "xprintf size greater then MAS!!!!\n\r");
    log_string(LOG_BUG, "Warning: Overflow has been caught by xprintf.\n\r");
    log_string(LOG_BUG, "Memcheck: xprintf:File %s, Function %s, Line %d.\n\r",file,function,line);
    xprintf(egbug, "Memcheck: System memory corrupted by overflow through xprintf: File: %s Function: %s Line: %d",file, function,line);
    wiznet(egbug,NULL,NULL,WIZ_MEMCHECK,0,0);
    return;
  }

  if ((unsigned)size < strlen(buf)+1) 
  {
    char egbug[MSL];
    log_string(LOG_BUG, "XPRINTF error: fmt %s.\n\r",fmt);
    log_string(LOG_BUG, "Warning: Overflow has been caught by xprintf.\n\r");
    log_string(LOG_BUG, "Memcheck: xprintf: File %s, Function %s, Line %d.\n\r",file,function,line);
    /*Yes, this is a potential loop bug if infact the xprintf does collapse in on itself..*/
    xprintf(egbug, "Memcheck: System memory corrupted by overflow through xprintf: File: %s Function: %s Line: %d",file,function,line);
    wiznet(egbug,NULL,NULL,WIZ_MEMCHECK,0,0);
  }
  else
  {
	    strcpy(str,buf);
	    //Disabled for now.
	    //strlcpy(str,buf,size-2);
	    //str[size-1] = '\0';

	    /*Just double checking.*/
	   if( strlen( str ) > (unsigned)size - 1 )
	   {
		 char egbug[MSL];
	   	 log_string(LOG_BUG, "XPRINTF error: fmt %s.\n\r",fmt);
		     log_string(LOG_BUG, "Warning: Overflow has been caught by xprintf.\n\r");
		 log_string(LOG_BUG, "Memcheck: Xprintf: File %s, Function %s, Line %d.\n\r",file, function,line);

		 /*Yes, this is a potential loop bug if infact the xprintf does collapse in on itself..*/
		 xprintf(egbug, "Memcheck: System memory corrupted by overflow through xprintf: File: %s Function: %s Line: %d",file, function,line);
		 wiznet(egbug,NULL,NULL,WIZ_MEMCHECK,0,0);
	   }
  }
}