/************************************************************************** * 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 __DESCRIPTOR_H_ #define __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; mud_info.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; mud_info.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; const char *p; if (!d) return 0; width = ScrWidth(d); p = erase_new_lines(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); } bool read_from_descriptor(Descriptor * d) { unsigned int iStart, index; static unsigned char buf[sizeof(d->inbuf)]; memset(buf, 0, sizeof(buf)); if (!NullStr(d->incomm)) return true; iStart = strlen(d->inbuf); index = 0; if (iStart >= sizeof(d->inbuf) - 10) { logf("%s input overflow!", d->host); d_write(d, NEWLINE "*** PUT A LID ON IT!!! ***" NEWLINE, 0); d->inbuf[sizeof(d->inbuf) - 10] = '\0'; return true; } for (;;) { int nRead; if (sizeof(buf) - 10 - iStart == 0) { break; } nRead = recv(d->descriptor, (char *) buf + index, sizeof(buf) - 10 - index, 0); if (nRead > 0) { index += nRead; if (buf[index - 1] == '\n' || buf[index - 1] == '\r') break; } else if (nRead == 0) { logf("EOF encountered on read."); return false; } else if (check_errno(EWOULDBLOCK)) break; else { socket_error("Read_from_descriptor"); return false; } } process_telnet(d, index, buf); if (d->connected == CON_GET_TERM && (IsSet (d->desc_flags, DESC_TELOPT_EOR | DESC_TELOPT_ECHO | DESC_TELOPT_NAWS | DESC_MXP | DESC_MSP | DESC_PUEBLO | DESC_TELOPT_TTYPE | DESC_TELOPT_BINARY | DESC_PORTAL | DESC_IMP) #ifndef DISABLE_MCCP || d->out_compress #endif )) { SetBit(d->desc_flags, DESC_COLOR); d_printlnf(d, "%s{c enabled Automatically...{x", Upper(colorize("color"))); show_greeting(d); d->connected = CON_GET_NAME; } return true; } #endif