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

Changed the closure mechanism. Now, the first argument to all closures

is a pointer to a pointer to itself, which may be changed. They no
longer return themselves (or a replacement).

Rev: src/abstract_io.h:1.5
Rev: src/blocking_write.c:1.3
Rev: src/blocking_write.h:1.3
Rev: src/client.c:1.5
Rev: src/client.h:1.4
Rev: src/debug.c:1.6
Rev: src/debug.h:1.5
Rev: src/encrypt.c:1.6
Rev: src/io.c:1.6
Rev: src/lshd.c:1.2
Rev: src/packet_dispatch.c:1.4
Rev: src/pad.c:1.6
Rev: src/read_line.c:1.3
Rev: src/read_line.h:1.4
Rev: src/read_packet.c:1.3
Rev: src/unpad.c:1.5
Rev: src/void.c:1.6
Rev: src/write_buffer.c:1.4
Rev: src/write_buffer.h:1.4
Rev: src/zlib.c:1.5
parent e80942e0
...@@ -8,9 +8,12 @@ ...@@ -8,9 +8,12 @@
#include "lsh_types.h" #include "lsh_types.h"
#if 0
struct abstract_read; struct abstract_read;
typedef int (*abstract_read_f)(struct abstract_read *closure, typedef int (*abstract_read_f)(struct abstract_read *r,
UINT8 *buffer, UINT32 length); UINT8 *buffer, UINT32 length);
#endif
/* A read-function returning n means: /* A read-function returning n means:
* *
* n > 0: n bytes were read successfully. * n > 0: n bytes were read successfully.
...@@ -23,34 +26,43 @@ typedef int (*abstract_read_f)(struct abstract_read *closure, ...@@ -23,34 +26,43 @@ typedef int (*abstract_read_f)(struct abstract_read *closure,
struct abstract_read struct abstract_read
{ {
abstract_read_f read; int (*read)(struct abstract_read **r,
UINT8 *buffer, UINT32 length);
}; };
#define A_READ(f, buffer, length) (f)->read((f), (buffer), (length)) #define A_READ(f, buffer, length) (f)->read(&(f), (buffer), (length))
#if 0
struct read_handler; struct read_handler;
typedef struct read_handler * (*read_handler_f)(struct read_handler *closure, typedef struct read_handler * (*read_handler_f)(struct read_handler *closure,
struct abstract_read *read); struct abstract_read *read);
#endif
/* May store a new handler into *h. */
struct read_handler struct read_handler
{ {
read_handler_f handler; int (*handler)(struct read_handler **h,
struct abstract_read *read);
}; };
#define READ_HANDLER(h, read) ((h)->handler((h), (read))) #define READ_HANDLER(h, read) ((h)->handler(&(h), (read)))
/* FIXME: What should writers return? Perhaps a new writer, /* FIXME: What should writers return? Perhaps a new writer,
* analogous to read-handlers? */ * analogous to read-handlers? */
#if 0
struct abstract_write; struct abstract_write;
typedef int (*abstract_write_f)(struct abstract_write *closure, typedef int (*abstract_write_f)(struct abstract_write *closure,
struct lsh_string *packet); struct lsh_string *packet);
#endif
/* May store a new handler into *w. */
struct abstract_write struct abstract_write
{ {
abstract_write_f write; int (*write)(struct abstract_write **w,
struct lsh_string *packet);
}; };
#define A_WRITE(f, packet) ((f)->write((f), (packet))) #define A_WRITE(f, packet) ((f)->write(&(f), (packet)))
/* A processor that passes its result on to another processor */ /* A processor that passes its result on to another processor */
struct abstract_write_pipe struct abstract_write_pipe
......
...@@ -6,9 +6,12 @@ ...@@ -6,9 +6,12 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
static int do_write(struct pad_processor *closure, static int do_write(struct abstract_write **w,
struct lsh_string *packet) struct lsh_string *packet)
{ {
struct packet_blocking_write *closure
= (struct packet_blocking_write *) *w;
UINT32 left = packet->length; UINT32 left = packet->length;
UINT8 *p = packet->data; UINT8 *p = packet->data;
...@@ -36,10 +39,10 @@ struct abstract_write *make_blocking_write_procesor(int fd) ...@@ -36,10 +39,10 @@ struct abstract_write *make_blocking_write_procesor(int fd)
struct blocking_write_processor *closure struct blocking_write_processor *closure
= xalloc(sizeof(struct blocking_write_processor_processor)); = xalloc(sizeof(struct blocking_write_processor_processor));
closure->p->f = (abstract_write_f) do_write; closure->p->f = do_write;
closure->fd = fd; closure->fd = fd;
return (struct abstract_write *) closure; return &closure->super;
} }
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
#ifndef LSH_BLOCKING_WRITE_H_INCLUDED #ifndef LSH_BLOCKING_WRITE_H_INCLUDED
#define LSH_BLOCKING_WRITE_H_INCLUDED #define LSH_BLOCKING_WRITE_H_INCLUDED
struct blocking_write_processor struct packet_blocking_write
{ {
struct abstract_write w; struct abstract_write super;
int fd; int fd;
}; };
......
...@@ -19,9 +19,12 @@ ...@@ -19,9 +19,12 @@
struct read_handler *make_client_read_line(); struct read_handler *make_client_read_line();
struct callback *make_client_close_handler(); struct callback *make_client_close_handler();
static int client_initiate(struct client_callback *closure, static int client_initiate(struct fd_callback *c,
int fd) int fd)
{ {
struct client_callback *closure
= (struct client_callback *) c;
struct ssh_connection *connection = ssh_connection_alloc(); struct ssh_connection *connection = ssh_connection_alloc();
struct abstract_write *write = struct abstract_write *write =
io_read_write(closure->backend, fd, io_read_write(closure->backend, fd,
...@@ -44,10 +47,13 @@ struct client_line_handler ...@@ -44,10 +47,13 @@ struct client_line_handler
struct ssh_connection *connection; struct ssh_connection *connection;
}; };
static struct read_handler *do_line(struct client_line_handler *closure, static struct read_handler *do_line(struct line_handler **h,
UINT32 length, UINT32 length,
UINT8 *line) UINT8 *line)
{ {
struct client_line_handler *closure
= (struct client_line_handler *) *h;
if ( (length >= 4) && !memcmp(line, "SSH-", 4)) if ( (length >= 4) && !memcmp(line, "SSH-", 4))
{ {
/* Parse and remember format string */ /* Parse and remember format string */
...@@ -55,8 +61,8 @@ static struct read_handler *do_line(struct client_line_handler *closure, ...@@ -55,8 +61,8 @@ static struct read_handler *do_line(struct client_line_handler *closure,
|| ((length >= 9) && !memcmp(line + 4, "1.99-", 5))) || ((length >= 9) && !memcmp(line + 4, "1.99-", 5)))
{ {
struct read_handler *new struct read_handler *new
= make_read_packet(make_debug_processor(make_packet_void(), = make_read_packet(make_packet_debug(make_packet_void(),
stderr), stderr),
closure->connection->max_packet); closure->connection->max_packet);
closure->connection->server_version closure->connection->server_version
...@@ -73,8 +79,10 @@ static struct read_handler *do_line(struct client_line_handler *closure, ...@@ -73,8 +79,10 @@ static struct read_handler *do_line(struct client_line_handler *closure,
werror_safe(length, line); werror_safe(length, line);
werror("\n"); werror("\n");
fatal("client.c: do_line: Unsupported version.\n"); /* FIXME: Clean up properly */
/* FIXME: What could be returned here? */ free(closure);
*h = 0;
return 0; return 0;
} }
} }
...@@ -93,10 +101,10 @@ struct read_handler *make_client_read_line(struct ssh_connection *s) ...@@ -93,10 +101,10 @@ struct read_handler *make_client_read_line(struct ssh_connection *s)
struct client_line_handler *closure struct client_line_handler *closure
= xalloc(sizeof(struct client_line_handler)); = xalloc(sizeof(struct client_line_handler));
closure->super.handler = (line_handler_f) do_line; closure->super.handler = do_line;
closure->connection = s; closure->connection = s;
return make_read_line( (struct line_handler *) closure); return make_read_line(&closure->super);
} }
struct fd_callback *make_client_callback(struct io_backend *b, struct fd_callback *make_client_callback(struct io_backend *b,
...@@ -106,12 +114,12 @@ struct fd_callback *make_client_callback(struct io_backend *b, ...@@ -106,12 +114,12 @@ struct fd_callback *make_client_callback(struct io_backend *b,
{ {
struct client_callback *connected = xalloc(sizeof(struct client_callback)); struct client_callback *connected = xalloc(sizeof(struct client_callback));
connected->c.f = (fd_callback_f) client_initiate; connected->super.f = client_initiate;
connected->backend = b; connected->backend = b;
connected->block_size = block_size; connected->block_size = block_size;
connected->id_comment = comment; connected->id_comment = comment;
return (struct fd_callback *) connected; return &connected->super;
} }
static int client_die(struct callback *closure) static int client_die(struct callback *closure)
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
struct client_callback struct client_callback
{ {
struct fd_callback c; struct fd_callback super;
struct io_backend *backend; struct io_backend *backend;
UINT32 block_size; UINT32 block_size;
char *id_comment; char *id_comment;
......
...@@ -5,9 +5,12 @@ ...@@ -5,9 +5,12 @@
#include "debug.h" #include "debug.h"
#include "xalloc.h" #include "xalloc.h"
static int do_debug(struct debug_processor *closure, static int do_debug(struct abstract_write **w,
struct lsh_string *packet) struct lsh_string *packet)
{ {
struct packet_debug *closure
= (struct packet_debug *) *w;
UINT32 i; UINT32 i;
fprintf(closure->output, "DEBUG: (packet size %d = 0x%x)\n", fprintf(closure->output, "DEBUG: (packet size %d = 0x%x)\n",
...@@ -27,15 +30,15 @@ static int do_debug(struct debug_processor *closure, ...@@ -27,15 +30,15 @@ static int do_debug(struct debug_processor *closure,
} }
struct abstract_write * struct abstract_write *
make_debug_processor(struct abstract_write *continuation, FILE *output) make_packet_debug(struct abstract_write *continuation, FILE *output)
{ {
struct debug_processor *closure = xalloc(sizeof(struct debug_processor)); struct packet_debug *closure = xalloc(sizeof(struct packet_debug));
closure->super.super.write = (abstract_write_f) do_debug; closure->super.super.write = do_debug;
closure->super.next = continuation; closure->super.next = continuation;
closure->output = output; closure->output = output;
return (struct abstract_write *) closure; return &closure->super.super;
} }
...@@ -9,14 +9,14 @@ ...@@ -9,14 +9,14 @@
#include <stdio.h> #include <stdio.h>
#include "abstract_io.h" #include "abstract_io.h"
struct debug_processor struct packet_debug
{ {
struct abstract_write_pipe super; struct abstract_write_pipe super;
FILE *output; FILE *output;
}; };
struct abstract_write * struct abstract_write *
make_debug_processor(struct abstract_write *continuation, FILE *output); make_packet_debug(struct abstract_write *continuation, FILE *output);
#endif */ LSH_DEBUG_H_INCLUDED */ #endif */ LSH_DEBUG_H_INCLUDED */
...@@ -5,9 +5,12 @@ ...@@ -5,9 +5,12 @@
#include "encrypt.h" #include "encrypt.h"
#include "xalloc.h" #include "xalloc.h"
static int do_encrypt(struct encrypt_processor *closure, static int do_encrypt(struct encrypt_processor **c,
struct simple_packet *packet) struct simple_packet *packet)
{ {
struct encrypt_processor *closure
= (struct encrypt_processor *) *c;
/* FIXME: Use ssh_format() */ /* FIXME: Use ssh_format() */
struct simple_packet *new struct simple_packet *new
= lsh_string_alloc(packet->length + closure->mac_size); = lsh_string_alloc(packet->length + closure->mac_size);
...@@ -36,7 +39,7 @@ make_packet_encrypt(struct abstract_write *continuation, ...@@ -36,7 +39,7 @@ make_packet_encrypt(struct abstract_write *continuation,
{ {
struct encrypt_processor *closure = xalloc(sizeof(struct encrypt_processor)); struct encrypt_processor *closure = xalloc(sizeof(struct encrypt_processor));
closure->c.p.f = (abstract_write_f) do_encrypt; closure->super.super.write = do_encrypt;
closure->c.next = continuation; closure->c.next = continuation;
closure->mac_size = mac_size; closure->mac_size = mac_size;
closure->mac_function = mac_function; closure->mac_function = mac_function;
...@@ -44,7 +47,7 @@ make_packet_encrypt(struct abstract_write *continuation, ...@@ -44,7 +47,7 @@ make_packet_encrypt(struct abstract_write *continuation,
closure->encrypt_function = encrypt_function; closure->encrypt_function = encrypt_function;
closure->encrypt_state = encrypt_state; closure->encrypt_state = encrypt_state;
return (struct abstract_write *) closure; return &closure->super.super;
} }
...@@ -22,12 +22,15 @@ ...@@ -22,12 +22,15 @@
struct fd_read struct fd_read
{ {
struct abstract_read a; struct abstract_read super;
int fd; int fd;
}; };
static int do_read(struct fd_read *closure, UINT8 *buffer, UINT32 length) static int do_read(struct abstract_read **r, UINT8 *buffer, UINT32 length)
{ {
struct fd_read *closure
= (struct fd_read *) *r;
while(1) while(1)
{ {
int res = read(closure->fd, buffer, length); int res = read(closure->fd, buffer, length);
...@@ -35,7 +38,7 @@ static int do_read(struct fd_read *closure, UINT8 *buffer, UINT32 length) ...@@ -35,7 +38,7 @@ static int do_read(struct fd_read *closure, UINT8 *buffer, UINT32 length)
return A_EOF; return A_EOF;
if (res > 0) if (res > 0)
return res; return res;
switch(errno) switch(errno)
{ {
case EINTR: case EINTR:
...@@ -60,7 +63,7 @@ static int do_read(struct fd_read *closure, UINT8 *buffer, UINT32 length) ...@@ -60,7 +63,7 @@ static int do_read(struct fd_read *closure, UINT8 *buffer, UINT32 length)
/* UNLINK_FD must be followed by a continue, to avoid updating _fd */ /* UNLINK_FD must be followed by a continue, to avoid updating _fd */
#define UNLINK_FD (*_fd = (*_fd)->next) #define UNLINK_FD (*_fd = (*_fd)->next)
void io_run(struct io_backend *b) void io_run(struct io_backend *b)
{ {
while(1) while(1)
...@@ -70,141 +73,140 @@ void io_run(struct io_backend *b) ...@@ -70,141 +73,140 @@ void io_run(struct io_backend *b)
nfds_t nfds; nfds_t nfds;
int timeout; int timeout;
int res; int res;
nfds = b->nio + b->nlisten + b->nconnect; nfds = b->nio + b->nlisten + b->nconnect;
if (b->callouts) if (b->callouts)
{ {
time_t now = time(NULL); time_t now = time(NULL);
if (now >= b->callouts->when) if (now >= b->callouts->when)
timeout = 0; timeout = 0;
else else
{ {
if (b->callouts->when > now + MAX_TIMEOUT) if (b->callouts->when > now + MAX_TIMEOUT)
timeout = MAX_TIMEOUT * 1000; timeout = MAX_TIMEOUT * 1000;
else else
timeout = (b->callouts->when - now) * 1000; timeout = (b->callouts->when - now) * 1000;
} }
} }
else else
{ {
if (!nfds) if (!nfds)
/* All done */ /* All done */
break; break;
timeout = -1; timeout = -1;
} }
fds = alloca(sizeof(struct pollfd) * nfds); fds = alloca(sizeof(struct pollfd) * nfds);
/* Handle fds in order: read, accept, connect, write, */ /* Handle fds in order: write, read, accept, connect. */
i = 0; i = 0;
FOR_FDS(struct io_fd, fd, b->io, i++) FOR_FDS(struct io_fd, fd, b->io, i++)
{ {
fds[i].fd = fd->on_hold ? -1 : fd->fd; fds[i].fd = fd->on_hold ? -1 : fd->fd;
fds[i].events = 0; fds[i].events = 0;
if (!fd->on_hold) if (!fd->on_hold)
fds[i].events |= POLLIN; fds[i].events |= POLLIN;
/* pre_write returns 0 if the buffer is empty */ /* pre_write returns 0 if the buffer is empty */
if (write_buffer_pre_write(fd->buffer)) if (write_buffer_pre_write(fd->buffer))
fds[i].events |= POLLOUT; fds[i].events |= POLLOUT;
} }
END_FOR_FDS; END_FOR_FDS;
FOR_FDS(struct listen_fd, fd, b->listen, i++) FOR_FDS(struct listen_fd, fd, b->listen, i++)
{ {
fds[i].fd = fd->fd; fds[i].fd = fd->fd;
fds[i].events = POLLIN; fds[i].events = POLLIN;
} }
END_FOR_FDS; END_FOR_FDS;
FOR_FDS(struct connect_fd, fd, b->connect, i++) FOR_FDS(struct connect_fd, fd, b->connect, i++)
{ {
fds[i].fd = fd->fd; fds[i].fd = fd->fd;
fds[i].events = POLLOUT; fds[i].events = POLLOUT;
} }
END_FOR_FDS; END_FOR_FDS;
res = poll(fds, nfds, timeout); res = poll(fds, nfds, timeout);
if (!res) if (!res)
{ {
/* Timeout. Run the callout */ /* Timeout. Run the callout */
struct callout *f = b->callouts; struct callout *f = b->callouts;
if (!CALLBACK(f->callout)) if (!CALLBACK(f->callout))
fatal("What now?"); fatal("What now?");
b->callouts = f->next; b->callouts = f->next;
free(f); free(f);
} }
if (res<0) if (res<0)
{ {
switch(errno) switch(errno)
{ {
case EAGAIN: case EAGAIN:
case EINTR: case EINTR:
continue; continue;
default: default:
fatal("io_run:poll failed: %s", strerror(errno)); fatal("io_run:poll failed: %s", strerror(errno));
} }
} }
else else
{ /* Process files */ { /* Process files */
i = 0; i = 0;
/* Handle writing first */ /* Handle writing first */
FOR_FDS(struct io_fd, fd, b->io, i++) FOR_FDS(struct io_fd, fd, b->io, i++)
{ {
if (fds[i].revents & POLLOUT) if (fds[i].revents & POLLOUT)
{ {
UINT32 size = MIN(fd->buffer->end - fd->buffer->start, UINT32 size = MIN(fd->buffer->end - fd->buffer->start,
fd->buffer->block_size); fd->buffer->block_size);
int res = write(fd->fd, int res = write(fd->fd,
fd->buffer->buffer + fd->buffer->start, fd->buffer->buffer + fd->buffer->start,
size); size);
if (!res) if (!res)
fatal("Closed?"); fatal("Closed?");
if (res < 0) if (res < 0)