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

Work-in-progress checking. Exceptions half way done.

Rev: src/abstract_io.h:1.25
Rev: src/channel.c:1.48
Rev: src/channel_commands.c:1.10
Rev: src/channel_commands.h:1.11
Rev: src/client.c:1.68
Rev: src/client.h:1.24
Rev: src/client_userauth.c:1.17
Rev: src/combinators.c:1.6
Rev: src/command.c:1.23
Rev: src/command.h:1.31
Rev: src/connection_commands.c:1.7
Rev: src/io.c:1.64
Rev: src/io.h:1.37
Rev: src/io_commands.c:1.15
Rev: src/lsh.c:1.64
Rev: src/lshd.c:1.58
Rev: src/read_data.c:1.19
Rev: src/read_line.c:1.25
Rev: src/read_packet.c:1.37
Rev: src/server.c:1.56
Rev: src/server_session.c:1.11
Rev: src/server_userauth.c:1.12
Rev: src/tcpforward.c:1.25
Rev: src/tcpforward_commands.c:1.8
parent 51e59eb0
......@@ -26,7 +26,7 @@
#ifndef LSH_ABSTRACT_IO_H_INCLUDED
#define LSH_ABSTRACT_IO_H_INCLUDED
#include "lsh.h"
#include "exception.h"
#define GABA_DECLARE
#include "abstract_io.h.x"
......@@ -61,19 +61,32 @@
(class
(name read_handler)
(vars
(handler indirect-method int "struct abstract_read *read")))
(handler indirect-method void "struct abstract_read *read")))
;; "struct exception_handler *io")))
*/
#define READ_HANDLER(h, read) ((h)->handler(&(h), (read)))
#if 0
/* Return values */
/* Everything's fine */
#define READ_OK 0
/* Can't process any more data right now; please hold */
#define READ_HOLD 1
/* Close nicely, after fluching the write buffer */
#define READ_CLOSE 2
/* Close immediately */
#define READ_DIE 3
#endif
/* GABA:
(class
(name abstract_write)
(vars
(write method int "struct lsh_string *packet")))
(write method void "struct lsh_string *packet" "struct exception_handler *e")))
*/
#define A_WRITE(f, packet) ((f)->write((f), (packet)))
#define A_WRITE(f, packet, e) ((f)->write((f), (packet), (e)))
/* A handler that passes packets on to another handler */
/* GABA:
......
......@@ -469,12 +469,15 @@ static int do_global_request_success(struct packet_handler *s UNUSED,
return LSH_OK | LSH_GOON;
}
{
CAST_SUBTYPE(command_continuation, c,
CAST_SUBTYPE(command_context, ctx,
object_queue_remove_head(&connection->channels->pending_global_requests));
return COMMAND_RETURN(c, connection);
return COMMAND_RETURN(ctx->c, connection);
}
}
struct exception global_request_exception =
STATIC_EXCEPTION(EXC_GLOBAL_REQUEST, "Global request failed");
static int do_global_request_failure(struct packet_handler *s UNUSED,
struct ssh_connection *connection,
struct lsh_string *packet)
......@@ -490,13 +493,13 @@ static int do_global_request_failure(struct packet_handler *s UNUSED,
return LSH_OK | LSH_GOON;
}
{
CAST_SUBTYPE(command_continuation, c,
CAST_SUBTYPE(command_context, ctx,
object_queue_remove_head(&connection->channels->pending_global_requests));
return COMMAND_RETURN(c, NULL);
return EXCEPTION_RAISE(ctx->e, &global_request_exception);
}
}
/* FIXME: Split into a continuation and an exception handler */
/* Callback given to the CHANNEL_OPEN method */
static int do_channel_open_response(struct channel_open_callback *c,
struct ssh_channel *channel,
......@@ -517,6 +520,8 @@ static int do_channel_open_response(struct channel_open_callback *c,
return LSH_FAIL | LSH_DIE;
}
/* FIXME: It would be better to allocate or at least reservea channel number earlier,
* so that we can't fail at this point */
if ( (local_channel_number
= register_channel(closure->super.connection->channels,
channel)) < 0)
......@@ -992,7 +997,8 @@ static int do_channel_close(struct packet_handler *closure UNUSED,
channel->flags |= CHANNEL_RECEIVED_CLOSE;
if (! (channel->flags & (CHANNEL_RECEIVED_EOF | CHANNEL_SENT_EOF)))
if (! (channel->flags & (CHANNEL_RECEIVED_EOF | CHANNEL_SENT_EOF
| CHANNEL_SENT_CLOSE)))
{
werror("Unexpected channel CLOSE.\n");
}
......@@ -1137,16 +1143,19 @@ static int do_channel_success(struct packet_handler *closure UNUSED,
return LSH_OK | LSH_GOON;
}
{
CAST_SUBTYPE(command_continuation, c,
CAST_SUBTYPE(command_context, ctx,
object_queue_remove_head(&channel->pending_requests));
return channel_process_status(connection->channels, channel_number,
COMMAND_RETURN(c, channel));
COMMAND_RETURN(ctx->c, channel));
}
}
lsh_string_free(packet);
return LSH_FAIL | LSH_DIE;
}
static struct exception channel_request_exception =
STATIC_EXCEPTION(EXC_CHANNEL_REQUEST, "Channel request failed");
static int do_channel_failure(struct packet_handler *closure UNUSED,
struct ssh_connection *connection,
struct lsh_string *packet)
......@@ -1172,11 +1181,11 @@ static int do_channel_failure(struct packet_handler *closure UNUSED,
return LSH_OK | LSH_GOON;
}
{
CAST_SUBTYPE(command_continuation, c,
CAST_SUBTYPE(command_context, ctx,
object_queue_remove_head(&channel->pending_requests));
return channel_process_status(connection->channels, channel_number,
COMMAND_RETURN(c, NULL));
EXCEPTION_RAISE(ctx->e, &channel_request_exception));
}
}
lsh_string_free(packet);
......@@ -1185,7 +1194,8 @@ static int do_channel_failure(struct packet_handler *closure UNUSED,
static int do_connection_service(struct command *s UNUSED,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e UNUSED)
{
CAST(ssh_connection, connection, x);
......@@ -1261,13 +1271,7 @@ static int do_connection_service(struct command *s UNUSED,
global_failure->handler = do_global_request_failure;
connection->dispatch[SSH_MSG_REQUEST_FAILURE] = global_failure;
return
#if 0
self->hook
? COMMAND_CALL(hook, connection, c)
:
#endif
COMMAND_RETURN(c, connection);
return COMMAND_RETURN(c, connection);
}
#if 0
......
......@@ -37,7 +37,8 @@
int do_channel_open_command(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e)
{
CAST_SUBTYPE(channel_open_command, self, s);
CAST(ssh_connection, connection, x);
......@@ -48,7 +49,7 @@ int do_channel_open_command(struct command *s,
{
/* Probably, we have run out of channel numbers. */
werror("do_channel_open_command: NEW_CHANNEL failed\n");
return COMMAND_RETURN(c, NULL);
return EXCEPTION_RAISE(e, &dummy_exception);
}
channel->open_continuation = c;
......@@ -58,7 +59,8 @@ int do_channel_open_command(struct command *s,
int do_channel_request_command(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e)
{
CAST_SUBTYPE(channel_request_command, self, s);
CAST_SUBTYPE(ssh_channel, channel, x);
......@@ -67,14 +69,16 @@ int do_channel_request_command(struct command *s,
= FORMAT_CHANNEL_REQUEST(self, channel, &c);
if (c)
object_queue_add_tail(&channel->pending_requests, &c->super);
object_queue_add_tail(&channel->pending_requests,
&make_command_context(c, e)->super);
return A_WRITE(channel->write, request);
}
int do_channel_global_command(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e)
{
CAST_SUBTYPE(global_request_command, self, s);
CAST_SUBTYPE(ssh_connection, connection, x);
......@@ -83,7 +87,8 @@ int do_channel_global_command(struct command *s,
= FORMAT_GLOBAL_REQUEST(self, connection, &c);
if (c)
object_queue_add_tail(&connection->channels->pending_global_requests, &c->super);
object_queue_add_tail(&connection->channels->pending_global_requests,
&make_command_context(c, e)->super);
return A_WRITE(connection->write, request);
}
......@@ -145,7 +150,8 @@ do_install_channel_open_handler(struct collect_info_2 *info,
static int
do_install_fix_global_request_handler(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e UNUSED)
{
CAST(install_global_request_handler, self, s);
CAST(ssh_connection, connection, x);
......@@ -187,7 +193,8 @@ make_install_fix_global_request_handler(UINT32 name,
static int
do_install_fix_channel_open_handler(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e UNUSED)
{
CAST(install_channel_open_handler, self, s);
CAST(ssh_connection, connection, x);
......
......@@ -51,7 +51,8 @@
int do_channel_open_command(struct command *s,
struct lsh_object *x,
struct command_continuation *c);
struct command_continuation *c,
struct exception_handler *e);
/* Takes a channel as argument, and returns the same channel or NULL. */
/* GABA:
......@@ -72,7 +73,8 @@ int do_channel_open_command(struct command *s,
int do_channel_request_command(struct command *s,
struct lsh_object *x,
struct command_continuation *c);
struct command_continuation *c,
struct exception_handler *e);
/* GABA:
(class
......@@ -89,7 +91,8 @@ int do_channel_request_command(struct command *s,
int do_channel_global_command(struct command *s,
struct lsh_object *x,
struct command_continuation *c);
struct command_continuation *c,
struct exception_handler *e);
struct command *
make_install_global_request_handler(UINT32 name,
......
......@@ -61,7 +61,9 @@
(super packet_handler)
(vars
(service simple int)
(c object command_continuation)))
(c object command_continuation)
;; Do we really need the exception handler here?
(e object exception_handler)))
*/
static int do_accept_service(struct packet_handler *c,
......@@ -89,19 +91,22 @@ static int do_accept_service(struct packet_handler *c,
}
lsh_string_free(packet);
return LSH_FAIL | LSH_DIE;
return EXCEPTION_RAISE(closure->e,
make_protocol_exception("Invalid SSH_MSG_SERVICE_ACCEPT message"));
}
struct packet_handler *
make_accept_service_handler(int service,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e)
{
NEW(accept_service_handler, closure);
closure->super.handler = do_accept_service;
closure->service = service;
closure->c = c;
closure->e = e;
return &closure->super;
}
......@@ -116,13 +121,14 @@ make_accept_service_handler(int service,
static int do_request_service(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e)
{
CAST(request_service, self, s);
CAST(ssh_connection, connection, x);
connection->dispatch[SSH_MSG_SERVICE_ACCEPT]
= make_accept_service_handler(self->service, c);
= make_accept_service_handler(self->service, c, e);
return A_WRITE(connection->write,
format_service_request(self->service));
......@@ -345,15 +351,19 @@ static int do_send(struct ssh_channel *c)
/* We have a remote shell */
static int do_client_io(struct command *s UNUSED,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e UNUSED)
{
assert(x);
#if 0
if (!x)
{
werror("do_client_io: Starting shell failed.\n");
return LSH_CHANNEL_CLOSE | LSH_FAIL;
}
else
#endif
{
CAST(client_session, session, x);
struct ssh_channel *channel = &session->super;
......
......@@ -45,7 +45,8 @@ struct close_callback *make_client_close_handler(void);
struct packet_handler *
make_accept_service_handler(int service,
struct command_continuation *c);
struct command_continuation *c,
struct exception_handler *e);
struct command *make_request_service(int service);
......
......@@ -265,7 +265,8 @@ static struct packet_handler *make_banner_handler(void)
static int do_client_userauth(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e UNUSED)
{
CAST(client_userauth, self, s);
CAST(ssh_connection, connection, x);
......@@ -277,6 +278,7 @@ static int do_client_userauth(struct command *s,
connection->dispatch[SSH_MSG_USERAUTH_BANNER]
= make_banner_handler();
/* Pass e on? */
return send_passwd(self, connection);
}
......
......@@ -109,18 +109,22 @@ static int do_command_S_continuation(struct command_continuation *c,
{
CAST(command_S_continuation, self, c);
CAST_SUBTYPE(command, op, value);
return COMMAND_CALL(self->g, self->x, make_apply(op, self->super.up));
return COMMAND_CALL(self->g, self->x,
make_apply(op, self->super.up, self->super.e),
self->super.e);
}
static struct command_continuation *
make_command_S_continuation(struct command *g,
struct lsh_object *x,
struct command_continuation *up)
struct command_continuation *up,
struct exception_handler *e)
{
NEW(command_S_continuation, c);
c->g = g;
c->x = x;
c->super.up = up;
c->super.e = e;
c->super.super.c = do_command_S_continuation;
return &c->super.super;
......@@ -128,12 +132,14 @@ make_command_S_continuation(struct command *g,
static int do_command_S_2(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e)
{
CAST(command_S_2, self, s);
return COMMAND_CALL(self->f, x,
make_command_S_continuation(self->g, x, c));
make_command_S_continuation(self->g, x, c, e),
e);
}
static struct lsh_object *
......@@ -192,13 +198,16 @@ STATIC_COLLECT_1(&collect_info_S_2);
static int do_command_Sp_3(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e)
{
CAST(command_Sp_3, self, s);
return COMMAND_CALL(self->f, x,
make_apply(self->c,
make_command_S_continuation(self->g,
x, c)));
x, c, e),
e),
e);
}
static struct lsh_object *
......@@ -264,10 +273,12 @@ STATIC_COLLECT_1(&collect_info_Sp_2);
static int do_command_B_2(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e)
{
CAST(command_B_2, self, s);
return COMMAND_CALL(self->g, x, make_apply(self->f, c));
return COMMAND_CALL(self->g, x,
make_apply(self->f, c, e), e);
}
static struct lsh_object *
......@@ -325,18 +336,20 @@ STATIC_COLLECT_1(&collect_info_B_2);
*/
static int do_command_Bp_3(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct lsh_object *x,
struct command_continuation *c,
struct exception_handler *e)
{
CAST(command_Bp_3, self, s);
return COMMAND_CALL(self->g, x,
make_apply(self->f,
make_apply(self->c, c)));
make_apply(self->c, c, e), e),
e);
}
static struct lsh_object *
do_simple_command_Bp_3(struct command_simple *s,
struct lsh_object *x)
struct lsh_object *x)
{
CAST(command_Bp_3, self, s);
CAST_SUBTYPE(command_simple, cs, self->c);
......@@ -408,16 +421,19 @@ static int do_command_C_continuation(struct command_continuation *c,
{
CAST(command_C_continuation, self, c);
CAST_SUBTYPE(command, op, value);
return COMMAND_CALL(op, self->y, self->super.up);
return COMMAND_CALL(op, self->y, self->super.up, self->super.e);
}
static struct command_continuation *
make_command_C_continuation(struct lsh_object *y,
struct command_continuation *up)
struct command_continuation *up,
struct exception_handler *e)
{
NEW(command_C_continuation, c);
c->y = y;
c->super.up = up;
c->super.e = e;
c->super.super.c = do_command_C_continuation;
return &c->super.super;
......@@ -425,12 +441,14 @@ make_command_C_continuation(struct lsh_object *y,
static int do_command_C_2(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e)
{
CAST(command_C_2, self, s);
return COMMAND_CALL(self->f, x,
make_command_C_continuation(self->y, c));
make_command_C_continuation(self->y, c, e),
e);
}
static struct lsh_object *do_simple_command_C_2(struct command_simple *s,
......@@ -485,14 +503,16 @@ STATIC_COLLECT_1(&collect_info_C_2);
*/
static int do_command_Cp_3(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct lsh_object *x,
struct command_continuation *c,
struct exception_handler *e)
{
CAST(command_Cp_3, self, s);
return COMMAND_CALL(self->f, x,
make_apply(self->c,
make_command_C_continuation(self->y, c)));
make_command_C_continuation(self->y, c, e), e),
e);
}
static struct lsh_object *
......
......@@ -36,8 +36,9 @@
#include "command.c.x"
int do_discard_continuation(struct command_continuation *ignored UNUSED,
struct lsh_object *x UNUSED)
static int
do_discard_continuation(struct command_continuation *ignored UNUSED,
struct lsh_object *x UNUSED)
{
return LSH_OK | LSH_GOON;
}
......@@ -45,7 +46,17 @@ int do_discard_continuation(struct command_continuation *ignored UNUSED,
struct command_continuation discard_continuation =
{ STATIC_HEADER, do_discard_continuation};
struct command_context *
make_command_context(struct command_continuation *c,
struct exception_handler *e)
{
NEW(command_context, self);
self->c = c;
self->e = e;
return self;
}
/* GABA:
(class
(name command_apply)
......@@ -58,16 +69,19 @@ static int do_command_apply(struct command_continuation *s,
struct lsh_object *value)
{
CAST(command_apply, self, s);
return COMMAND_CALL(self->f, value, self->super.up);
return COMMAND_CALL(self->f, value,
self->super.up, self->super.e);
}
struct command_continuation *
make_apply(struct command *f, struct command_continuation *c)
make_apply(struct command *f,
struct command_continuation *c, struct exception_handler *e)
{
NEW(command_apply, res);
res->f = f;
res->super.up = c;
res->super.e = e;
res->super.super.c = do_command_apply;
return &res->super.super;
......@@ -82,7 +96,8 @@ struct lsh_object *gaba_apply(struct lsh_object *f,
int do_call_simple_command(struct command *s,
struct lsh_object *arg,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e UNUSED)
{
CAST_SUBTYPE(command_simple, self, s);
return COMMAND_RETURN(c, COMMAND_SIMPLE(self, arg));
......@@ -93,7 +108,8 @@ int do_call_simple_command(struct command *s,
static int
do_command_unimplemented(struct command *s UNUSED,
struct lsh_object *o UNUSED,
struct command_continuation *c UNUSED)
struct command_continuation *c UNUSED,
struct exception_handler *e UNUSED)
{ fatal("command.c: Unimplemented command.\n"); }
static struct lsh_object *
......@@ -120,12 +136,13 @@ struct command_simple command_unimplemented =
static int do_trace_command(struct command *s,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e)
{
CAST(trace_command, self, s);
trace("Entering %z\n", self->name);
return COMMAND_CALL(self->real, x, c);
return COMMAND_CALL(self->real, x, c, e);
}
struct command *make_trace(const char *name, struct command *real)
......@@ -144,7 +161,8 @@ struct lsh_object *collect_trace(const char *name, struct lsh_object *c)
return &make_trace(name, real)->super;
}
#if 0
/* This command should be obsoleted by the exception mechanism */
/* Fail if NULL. This commands returns its argument unchanged. Unless
* it is NULL, in which case it doesn't return at all, but instead
* returns an LSH_FAIL status to the mainloop. */
......@@ -152,14 +170,15 @@ struct lsh_object *collect_trace(const char *name, struct lsh_object *c)
static int
do_command_die_on_null(struct command *s UNUSED,
struct lsh_object *x,
struct command_continuation *c)
struct command_continuation *c,
struct exception_handler *e)
{
return x ? COMMAND_RETURN(c, x) : LSH_FAIL | LSH_DIE;
}
struct command command_die_on_null =
{ STATIC_HEADER, do_command_die_on_null};
#endif
/* Collecting arguments */
struct lsh_object *
......@@ -281,7 +300,8 @@ make_collect_state_3(struct collect_info_3 *info,
static int do_parallell_progn(struct command *s,
struct lsh_object *x,