Commit 5dc75d82 authored by Niels Möller's avatar Niels Möller
Browse files

Panic commit before local system reinstall...

Rev: src/command.h:1.1
Rev: src/string_buffer.c:1.1
Rev: src/string_buffer.h:1.1
Rev: src/zlib.c:1.13
parent 64587f7b
/* command.h
*
* $id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Möller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef LSH_COMMAND_H_INCLUDED
#define LSH_COMMAND_H_INCLUDED
#include "lsh_object.h"
#include "command.h.x"
/* Continuation based command execution. A command can take one object
* as argument, and returns one object. */
/* CLASS
(class
(name command_continuation)
(vars
(c method int "struct lsh_object *result")))
*/
/* CLASS:
(class
(name command)
(vars
(do method int "struct command_continuation *c" "struct lsh_object *arg")))
*/
#define COMMAND_DO(f, c) ((f)->do((f), (c)))
#define COMMAND_RETURN(c, v) ((c)->c((c), (struct lsh_object *) (v)))
#endif /* LSH_COMMAND_H_INCLUDED */
/* string_buffer.c
*
* Functions for building strings whose lengths are not known from the
* start.
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Mller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "string_buffer.h"
struct string_node
{
struct string_node *next;
strict lsh_string *s;
};
void string_buffer_init(struct string_buffer *buffer,
UINT32 guess)
{
buffer->partial = lsh_string_alloc(guess);
buffer->left = guess;
buffer->current = buffer->partial->data;
buffer->list = NULL;
buffer->nlist = 0;
buffer->total = 0;
}
static void string_buffer_clear(struct string_buffer *buffer)
{
struct string_node *n;
lsh_string_free(buffer->partial);
for (n = n->tail; n; )
{
struct string_node *old = n;
n = old->next;
lsh_string_free(old->s);
lsh_space_free(old);
}
}
/* Assumes that the buffer->partial string is full */
static void string_buffer_grow(struct string_buffer *buffer, UINT32 increment)
{
NEW_SPACE(string_node, n);
buffer->total += buffer->partial->length;
n->s = current;
n->next = buffer->tail;
buffer->tail = n;
buffer->partial = lsh_string_alloc(increment);
buffer->current = buffer->partial->data;
buffer->left = increment;
}
#if 0
void string_buffer_putc(struct string_buffer *buffer, UINT8 c)
{
if (!buffer->left)
string_buffer_grow(buffer, buffer->increment);
assert(buffer->left);
*buffer->current++ = c;
buffer->left--;
}
void string_buffer_write(struct string_buffer *buffer,
UINT32 length, const UINT8 *s)
{
if (length > buffer->left)
{
memcpy(buffer->current, s, buffer->left);
s += buffer->left;
length -= buffer->left;
string_buffer_grow(MAX(length, buffer->increment));
}
assert(length <= buffer->left);
memcpy(buffer->current, s, length);
buffer->current += length;
buffer->left -= length;
}
struct lsh_string string_buffer_final_write(struct string_buffer *buffer,
UINT32 length, const UINT8 *s)
{
UINT32 final = buffer->total + length;
if ( (length < left) && !buffer->tail)
{
/* This should be the usual case. */
if (length)
memcpy(buffer->current, s, length);
buffer->partial->length = final
return buffer->partial;
}
else
{
struct lsh_string *res = lsh_string_alloc(final);
UINT8 *p = res->data + final;
struct string_node *n;
if (length)
{
p -= length;
memcpy(p, s, length);
}
length = buffer->partial->length - buffer->left;
p -= length;
memcpy(p, buffer->partial->data, length);
lsh_string_free(buffer->partial);
for (n = buffer->tail; n; )
{
struct string_node *old = n;
n = n->next;
p -= old->s->length;
memcpy(p, old->s->data, old->s->length);
lsh_string_free(old->s);
lsh_space_free(old);
}
assert(p == res->data);
return res;
}
}
#endif
struct lsh_string string_buffer_final(struct string_buffer *buffer,
UINT32 left_over)
{
UINT32 length = buffer->partial->length - left_over;
UINT32 final = buffer->total + length;
if (!tail)
{
/* This should be the usual case. */
buffer->partial->length = final;
return buffer->partial;
}
else
{
struct lsh_string *res = lsh_string_alloc(final);
UINT8 *p = res->data + final;
struct string_node *n;
p -= length;
memcpy(p, buffer->partial->data, length);
lsh_string_free(buffer->partial);
for (n = buffer->tail; n; )
{
struct string_node *old = n;
n = n->next;
p -= old->s->length;
memcpy(p, old->s->data, old->s->length);
lsh_string_free(old->s);
lsh_space_free(old);
}
assert(p == res->data);
return res;
}
}
/* string_buffer.h
*
* Functions for building strings whose lengths are not known from the
* start.
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Möller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef LSH_STRING_BUFFER_H_INCLUDED
#define LSH_STRING_BUFFER_H_INCLUDED
/* We optimize for operations where we can guess an upper limit which
* is reasonable most of the time. */
#include "lsh.h"
struct string_node;
struct string_buffer
{
#if 0
/* Fail if the buffer grows larger than this value; zero means that
* there is no limit. */
UINT32 max;
/* Amount of space to allocate at a time */
UINT32 increment;
#endif
struct lsh_string *partial; /* Partial block. */
UINT32 left;
UINT8 *current;
/* List of blocks beyond the first one */
struct string_node *tail;
#if 0
unsigned nlist; /* Number of nodes */
#endif
UINT32 total; /* Total string length, in list (i.e. not including
* partial) */
};
void string_buffer_init(struct string_buffer *buffer, UINT32 guess);
#if 0
int string_buffer_putc(struct string_buffer *buffer, UINT8 c);
int string_buffer_write(struct string_buffer *buffer,
UINT32 length, const UINT8 *s);
#endif
struct lsh_string string_buffer_final(struct string_buffer *buffer,
UINT32 left);
#endif /* LSH_STRING_BUFFER_H_INCLUDED */
......@@ -25,6 +25,7 @@
#include "compress.h"
#include "format.h"
#include "string_buffer.h"
#include "werror.h"
#include "xalloc.h"
......@@ -39,8 +40,11 @@ static void do_free_zstream(z_stream *z);
(name zlib_instance)
(super compress_instance)
(vars
(zstream special-struct z_stream
#f do_free_zstream)))
;; Fail before producing larger packets than this
(max . UINT32)
(f (pointer (function int "z_stream *" int)))
(z special-struct z_stream
#f do_free_zstream)))
*/
/* CLASS:
......@@ -62,29 +66,159 @@ static void zlib_free(void *opaque UNUSED, void *address)
lsh_space_free(address);
}
static char foo_inflate[] = "inflate";
static char foo_deflate[] = "deflate";
static void do_free_zstream(z_stream *z)
{
/* Call deflateEnd() or inflateEnd(). But which? We use the opague
* pointer, as we don't use that for anything else. */
int res;
if (z->opaque == foo_inflate)
res = inflateEnd(z);
else if (z->opaque == foo_deflate)
res = deflateEnd(z);
else
fatal("Internal error!\n");
int (*free)(struct zstream *z) = z->opaque;
int res = free(z);
if (res != Z_OK)
werror("do_free_zstream: Freeing failed: %z\n",
z->msg ? z->msg : "No error");
}
/* compress incoming data */
/* Compress incoming data */
static struct lsh_string *do_zlib_deflate(struct compress_instance *c,
struct lsh_string *packet,
int free)
{
CAST(zlib_instance, self, c);
struct string_buffer buffer;
UINT32 limit = self->max;
if (!packet->length)
{
werror("do_zlib_deflate: Compressing empty packet.\n");
return free ? packet : lsh_string_dup(packet);
}
/* FIXME: This will break if the total_* counters ever overflow. Is
* that a problem? */
float rate = (self->z->total_in
? (float) self->z->total_out / self->z->total_in + 0.1
: 1.0);
string_buffer_init(&buffer,
/* This value is somewhat arbitrary */
MIN(self->max, (UINT32) (rate * packet->length) + 100));
limit -= buffer->partial->length;
self->z->next_in = packet->data;
self->z->avail_in = packet->length;
for (;;)
{
int rc;
assert(self->z->avail_in);
self->z->next_out = buffer.current;
self->z->avail_out = buffer.left;
rc = deflate(&self->z, Z_SYNC_FLUSH);
if (rc != Z_OK)
{
werror("do_zlib_deflate: deflate() failed: %z\n",
z->msg ? z->msg : "No error(?)");
if (free)
lsh_string_free(packet);
return NULL;
}
if (!self->z->avail_in)
{ /* Compressed entire packet */
if (free)
lsh_string_free(packet);
return string_buffer_final(&buffer, buffer->left - self->z->avail_out);
}
else
{ /* All output space consumed */
assert(!self->z->avail_out);
if (!limit)
{
werror("do_zlib_deflate: Packet grew too large!\n");
if (free)
lsh_string_free(packet);
string_buffer_vlear(buffer);
return NULL;
}
string_buffer_grow(&buffer, MIN(limit, packet->length + 100));
limit -= buffer->partial->length;
}
}
}
/* Decompress incoming data */
static struct lsh_string *do_zlib_inflate(struct compress_instance *c,
struct lsh_string *packet,
int free)
{
CAST(zlib_instance, self, c);
struct string_buffer buffer;
if (!packet->length)
{
werror("do_zlib_deflate: Compressing empty packet.\n");
return free ? packet : lsh_string_dup(packet);
}
/* FIXME: This will break if the total_* counters ever overflow. Is
* that a problem? */
float rate = (self->z->total_in
? (float) self->z->total_out / self->z->total_in + 0.1
: 1.0);
string_buffer_init(&buffer,
/* This value is somewhat arbitrary */
(UINT32) (rate * packet->length) + 100);
self->z->next_in = packet->data;
self->z->avail_in = packet->length;
for (;;)
{
int rc;
assert(self->z->avail_in);
self->z->next_out = buffer.current;
self->z->avail_out = buffer.left;
rc = deflate(&self->z, Z_SYNC_FLUSH);
if (rc != Z_OK)
{
werror("do_zlib_deflate: deflate() failed: %z\n",
z->msg ? z->msg : "No error(?)");
return NULL;
}
if (!self->z->avail_in)
{ /* Compressed entire packet */
if (free)
lsh_string_free(packet);
return string_buffer_final(&buffer, buffer->left - self->z->avail_out);
}
else
{ /* All output space consumed */
assert(!self->z->avail_out);
string_buffer_grow(&buffer, packet->length + 100);
}
}
}
#if 0
static struct lsh_string *do_zlib_deflate(struct compress_instance *c,
struct lsh_string *data,
int free)
......@@ -122,6 +256,7 @@ static struct lsh_string *do_zlib_deflate(struct compress_instance *c,
return compressed;
}
#endif
/* decompress incoming data */
static struct lsh_string *do_zlib_inflate(struct compress_instance *c,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment