/*~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ~ Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, ~ ~ Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. ~ ~ ~ ~ Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael ~ ~ Chastain, Michael Quan, and Mitchell Tse. ~ ~ ~ ~ Ack 2.2 improvements copyright (C) 1994 by Stephen Dooley ~ ~ ACK!MUD is modified Merc2.0/2.1/2.2 code (c)Stephen Zepp 1998 Ver: 4.3 ~ ~ ~ ~ In order to use any part of this PA Diku Mud, you must comply with ~ ~ both the original Diku license in 'license.doc' as well the Merc ~ ~ license in 'license.txt', and the Ack!Mud license in 'ack_license.txt'.~ ~ In particular, you may not remove any of these copyright notices. ~ ~ ~ ~ _______ _____ ~ ~ / __ /\ / ___ \ 222222 PA_MUD by Amnon Kruvi ~ ~ /______/ / / /___\ \ 2 PA_MUD is modified ~ ~ / _______/ / _______ \ 2 Ack!Mud, v4.3 ~ ~ /_/ /_/ \_\ 2 ~ ~ 2 ~ ~ 2222222 ~ ~ ~ ~ ~ ~ Years of work have been invested to create DIKU, Merc, Ack and PA. ~ ~ Please show your respect by following the licenses, and issuing ~ ~ credits where due. ~ ~ ~ ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-*/ void *zlib_alloc(void *opaque, unsigned int items, unsigned int size) { return calloc(items, size); } void zlib_free(void *opaque, void *address) { DISPOSE(address); } bool process_compressed(DESCRIPTOR_DATA *d) { int iStart = 0, nBlock, nWrite, len; if (!d->out_compress) return TRUE; // Try to write out some data.. len = d->out_compress->next_out - d->out_compress_buf; if (len > 0) { // we have some data to write for (iStart = 0; iStart < len; iStart += nWrite) { nBlock = UMIN (len - iStart, 4096); if ((nWrite = write(d->descriptor, d->out_compress_buf + iStart, nBlock)) < 0) { if (errno == EAGAIN || errno == ENOSR) break; return FALSE; } if (!nWrite) break; } if (iStart) { // We wrote "iStart" bytes if (iStart < len) memmove(d->out_compress_buf, d->out_compress_buf+iStart, len - iStart); d->out_compress->next_out = d->out_compress_buf + len - iStart; } } return TRUE; } char enable_compress[] = { IAC, SB, TELOPT_COMPRESS, WILL, SE, 0 }; char enable_compress2[] = { IAC, SB, TELOPT_COMPRESS2, IAC, SE, 0 }; bool compressStart(DESCRIPTOR_DATA *d, unsigned char telopt) { z_stream *s; if (d->out_compress) return TRUE; bug("Starting compression for descriptor %d", d->descriptor); CREATE(s, z_stream, 1); CREATE(d->out_compress_buf, unsigned char, COMPRESS_BUF_SIZE); s->next_in = NULL; s->avail_in = 0; s->next_out = d->out_compress_buf; s->avail_out = COMPRESS_BUF_SIZE; s->zalloc = zlib_alloc; s->zfree = zlib_free; s->opaque = NULL; if (deflateInit(s, 9) != Z_OK) { DISPOSE(d->out_compress_buf); DISPOSE(s); return FALSE; } if (telopt == TELOPT_COMPRESS) write_to_descriptor(d->descriptor, enable_compress, 0); else if (telopt == TELOPT_COMPRESS2) write_to_descriptor(d->descriptor, enable_compress2, 0); else bug("compressStart: bad TELOPT passed"); d->compressing = telopt; d->out_compress = s; return TRUE; } bool compressEnd(DESCRIPTOR_DATA *d) { unsigned char dummy[1]; if (!d->out_compress) return TRUE; bug("Stopping compression for descriptor %d", d->descriptor); d->out_compress->avail_in = 0; d->out_compress->next_in = dummy; if (deflate(d->out_compress, Z_FINISH) != Z_STREAM_END) return FALSE; if (!process_compressed(d)) /* try to send any residual data */ return FALSE; deflateEnd(d->out_compress); DISPOSE(d->out_compress_buf); DISPOSE(d->out_compress); d->compressing = 0; return TRUE; } void do_compress( CHAR_DATA *ch, char *argument ) { if (!ch->desc) { send_to_char("What descriptor?!\n", ch); return; } if (!ch->desc->out_compress) { send_to_char("Initiating compression.\n\r", ch); write_to_buffer( ch->desc, compress2_on_str, 0 ); write_to_buffer( ch->desc, compress_on_str, 0 ); } else { send_to_char("Terminating ompression.\n\r", ch); compressEnd(ch->desc); } }