1stMud/CVS/
1stMud/area/CVS/
1stMud/backup/CVS/
1stMud/bin/
1stMud/bin/CVS/
1stMud/bin/extras/
1stMud/bin/extras/CVS/
1stMud/data/CVS/
1stMud/data/i3/CVS/
1stMud/doc/1stMud/
1stMud/doc/1stMud/CVS/
1stMud/doc/CVS/
1stMud/doc/Diku/
1stMud/doc/Diku/CVS/
1stMud/doc/MPDocs/CVS/
1stMud/doc/Merc/CVS/
1stMud/doc/Rom/
1stMud/doc/Rom/CVS/
1stMud/log/CVS/
1stMud/notes/
1stMud/notes/CVS/
1stMud/player/CVS/
1stMud/player/backup/CVS/
1stMud/player/deleted/CVS/
1stMud/src/CVS/
1stMud/src/config/CVS/
1stMud/src/h/CVS/
1stMud/src/o/CVS/
1stMud/win/CVS/
/**************************************************************************
*  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
*  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
*                                                                         *
*  Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael         *
*  Chastain, Michael Quan, and Mitchell Tse.                              *
*                                                                         *
*  In order to use any part of this Merc Diku Mud, you must comply with   *
*  both the original Diku license in 'license.doc' as well the Merc       *
*  license in 'license.txt'.  In particular, you may not remove either of *
*  these copyright notices.                                               *
*                                                                         *
*  Much time and thought has gone into this software and you are          *
*  benefiting.  We hope that you share your changes too.  What goes       *
*  around, comes around.                                                  *
***************************************************************************
*       ROM 2.4 is copyright 1993-1998 Russ Taylor                        *
*       ROM has been brought to you by the ROM consortium                 *
*           Russ Taylor (rtaylor@hypercube.org)                           *
*           Gabrielle Taylor (gtaylor@hypercube.org)                      *
*           Brian Moore (zump@rom.org)                                    *
*       By using this code, you have agreed to follow the terms of the    *
*       ROM license, in the file Rom24/doc/rom.license                    *
***************************************************************************
*          1stMud ROM Derivative (c) 2001-2004 by Markanth                *
*            http://www.firstmud.com/  <markanth@firstmud.com>            *
*         By using this code you have agreed to follow the term of        *
*             the 1stMud license in ../doc/1stMud/LICENSE                 *
***************************************************************************/

#ifndef __COMM_DESCRIPTOR_H_
#define __COMM_DESCRIPTOR_H_  1


int
d_print (Descriptor * d, const char *txt)
{
  int length;

  if (!d || NullStr (txt))
    return 0;

  length = strlen (txt);


  if (d->outtop == 0)
    {
      if (!d->fcommand)
	{
	  d->outbuf[d->outtop++] = '\n';
	  d->outbuf[d->outtop++] = '\r';
	}
      if (d->fPrompt)
	{
	  d->outbuf[d->outtop++] = '\n';
	  d->outbuf[d->outtop++] = '\r';
	  d->fPrompt = false;
	}
    }


  while (d->outtop + length >= d->outsize)
    {
      char *tmpbuf;

      if (d->outsize >= 32000)
	{
	  bug ("Buffer overflow. Closing.");
	  close_socket (d);
	  return -1;
	}
      d->outsize *= 2;
      alloc_mem (tmpbuf, char, d->outsize);
      strncpy (tmpbuf, d->outbuf, d->outtop);
      free_mem (d->outbuf);
      d->outbuf = tmpbuf;
    }


  strncpy (d->outbuf + d->outtop, txt, length);
  d->outtop += length;
  return length;
}

int
d_println (Descriptor * d, const char *txt)
{
  if (!d)
    return 0;

  return (d_print (d, txt) + d_print (d, NEWLINE));
}

int
d_printf (Descriptor * d, const char *txt, ...)
{
  va_list args;
  char buf[MPL];

  if (!d || NullStr (txt))
    return 0;

  va_start (args, txt);
  vsnprintf (buf, sizeof (buf), txt, args);
  va_end (args);

  return d_print (d, buf);
}

int
d_printlnf (Descriptor * d, const char *txt, ...)
{
  char buf[MPL];

  if (!d)
    return 0;

  buf[0] = NUL;
  if (!NullStr (txt))
    {
      va_list args;

      va_start (args, txt);
      vsnprintf (buf, sizeof (buf), txt, args);
      va_end (args);
    }
  return d_println (d, buf);
}

int
write_to_socket (SOCKET desc, const char *txt, int length)
{
  int iStart, nWrite = 0, nBlock;

  if (length <= 0)
    {
      length = strlen (txt);
    }

  for (iStart = 0; iStart < length; iStart += nWrite)
    {
      nBlock = Min (length - iStart, 4096);
      nWrite = send (desc, txt + iStart, nBlock, 0);
      if (nWrite < 0)
	{
#ifdef WIN32
	  if (WSAGetLastError () == WSAEWOULDBLOCK)
	    break;
#else
#ifndef EAGAIN
#define    	EAGAIN    	11
#endif
#ifndef ENOSR
#define    	ENOSR    	63
#endif

	  if (errno == EAGAIN || errno == ENOSR)
	    break;
#endif

	  socket_error ("write_to_socket()");
	  return -1;
	}
    }
  return iStart + Min (0, nWrite);
}


int
d_write (Descriptor * d, const char *txt, int length)
{
  if (!d)
    return 0;

  if (length <= 0)
    length = strlen (txt);

  d->bytes_normal += length;
#ifndef DISABLE_MCCP

  if (d->out_compress)
    {
      z_stream *s = d->out_compress;
      int bad_write_loop = 0, totalwritten = 0, written = 0, len;

      s->next_in = (unsigned char *) txt;
      s->avail_in = length;
      while (s->avail_in && bad_write_loop < 5)
	{
	  s->avail_out =
	    COMPRESS_BUF_SIZE - (s->next_out - d->out_compress_buf);

	  if (s->avail_out)
	    {
	      if (deflate (s, Z_SYNC_FLUSH) != Z_OK)
		{
		  logf ("d_write() - compression error.");
		  return -1;
		}
	    }

	  len = d->out_compress->next_out - d->out_compress_buf;
	  written =
	    write_to_socket (d->descriptor,
			     (char *) d->out_compress_buf, len);
	  if (written > 0)
	    {
	      d->bytes_compressed += written;
	      if (written < len)
		{
		  memmove (d->out_compress_buf,
			   d->out_compress_buf + written, len - written);
		}
	      d->out_compress->next_out = d->out_compress_buf + len - written;
	      totalwritten += written;
	    }
	  else
	    {
	      bad_write_loop++;
	    }
	}
      if (bad_write_loop == 5)
	{


	  if (totalwritten)
	    {

	      return totalwritten;
	    }
	  return -1;
	}

      return length;
    }
  else
#endif

    return write_to_socket (d->descriptor, txt, length);
}



#ifdef __cplusplus

int
Descriptor::wrap (const char *buf)
{
  Descriptor *d = this;
#else
int
dwrap (Descriptor * d, const char *buf)
{
#endif
  static char out[MSL * 5];
  int width;
  int pos;
  char *p;

  if (!d)
    return 0;

  width = ScrWidth (d);

  p = reformat_desc ((char *) buf);
  pos = 0;

  out[0] = NUL;

  do
    {
      pos = get_line_len (p, width);
      if (pos > 0)
	{
	  strncat (out, p, pos);
	  p += pos;
	  strcat (out, NEWLINE);
	}
      else
	{
	  strcat (out, p);
	  break;
	}
    }
  while (true);

  return d_print (d, out);
}

int
dwrapln (Descriptor * d, const char *buf)
{
  if (!d)
    return 0;

  return (dwrap (d, buf) + d_print (d, NEWLINE));
}

int
dwrapf (Descriptor * d, const char *buf, ...)
{
  va_list args;
  char format[MPL];

  if (!d || NullStr (buf))
    return 0;

  va_start (args, buf);
  vsnprintf (format, sizeof (format), buf, args);
  va_end (args);

  return dwrap (d, format);
}

int
dwraplnf (Descriptor * d, const char *buf, ...)
{
  char format[MPL];

  if (!d)
    return 0;

  format[0] = NUL;
  if (!NullStr (buf))
    {
      va_list args;

      va_start (args, buf);
      vsnprintf (format, sizeof (format), buf, args);
      va_end (args);
    }
  return d_println (d, format);
}
#endif