Commit 2a4a208a authored by Niels Möller's avatar Niels Möller

*** empty log message ***

Rev: src/sexp_commands.c:1.1
Rev: src/sexp_commands.h:1.1
Rev: src/sexp_conv:1.1
Rev: src/sexp_conv.c:1.1
parent 600f3470
[attr]binary -text -crlf -diff -ident [attr]binary -text -crlf -diff -ident
* text ident * text ident
sexp_conv binary
/* sexp_commands.c
*
* Reading and writing of s-expressions.
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1999 Balazs Scheidler, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sexp_commands.h"
#include "format.h"
#include "xalloc.h"
#include "sexp_commands.c.x"
/* (write out sexp)
*
* Returns the sexp. */
/* GABA:
(class
(name write_sexp_command)
(super command)
(vars
(format . int)
(dest object abstract_write)))
*/
static void
do_write_sexp(struct command *s,
struct lsh_object *a,
struct command_continuation *c,
struct exception_handler *e UNUSED)
{
CAST(write_sexp_command, self, s);
CAST_SUBTYPE(sexp, o, a);
A_WRITE(self->dest, sexp_format(o, self->format, 0));
if (self->format != SEXP_CANONICAL)
A_WRITE(self->dest, ssh_format("\n"));
COMMAND_RETURN(c, a);
}
struct command *
make_write_sexp_to(int format, struct abstract_write *dest)
{
NEW(write_sexp_command, self);
self->super.call = do_write_sexp;
self->format = format;
self->dest = dest;
return &self->super;
}
/* GABA:
(class
(name write_sexp_collect)
(super command_simple)
(vars
(format . int)))
*/
static struct lsh_object *
do_write_sexp_collect(struct command_simple *s,
struct lsh_object *a)
{
CAST(write_sexp_collect, self, s);
CAST_SUBTYPE(abstract_write, dest, a);
return &make_write_sexp_to(self->format, dest)->super;
}
struct command_simple *
make_write_sexp_command(int format)
{
NEW(write_sexp_collect, self);
self->super.super.call = do_call_simple_command;
self->super.call_simple = do_write_sexp_collect;
self->format = format;
return &self->super;
}
/* GABA:
(class
(name read_sexp_command)
(super command)
(vars
(format . int)
(goon . int)))
*/
#define SEXP_BUFFER_SIZE 1024
static void
do_read_sexp(struct command *s,
struct lsh_object *a,
struct command_continuation *c,
struct exception_handler *e)
{
CAST(read_sexp_command, self, s);
CAST_SUBTYPE(io_fd, fd, a);
io_read(fd,
make_buffered_read(SEXP_BUFFER_SIZE,
make_read_sexp(self->format, self->goon, c, e)),
NULL);
}
struct command *
make_read_sexp_command(int format, int goon)
{
NEW(read_sexp_command, self);
self->super.call = do_read_sexp;
self->format = format;
self->goon = goon;
return &self->super;
}
/* sexp_commands.h
*
* Reading and writing of s-expressions.
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1999 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SEXP_COMMANDS_H_INCLUDED
#define SEXP_COMMANDS_H_INCLUDED
#include "abstract_io.h"
#include "command.h"
#include "sexp.h"
struct command_simple *
make_write_sexp_command(int format);
struct command *
make_write_sexp_to(int format, struct abstract_write *dest);
struct command *
make_read_sexp_command(int format, int goon);
#endif /* SEXP_COMMANDS_H_INCLUDED */
File added
/* sexpconv.c
*
* Reads a sexp in given form from, and writes it in given form.
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1999 Balazs Scheidler, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "io.h"
#include "lsh.h"
#include "sexp_commands.h"
#include "werror.h"
#include "xalloc.h"
#include "getopt.h"
#include <string.h>
#include <unistd.h>
#include "sexp_conv.c.x"
/* Global, for simplicity */
int exit_code = EXIT_SUCCESS;
struct sexp_format
{
char *name;
int id;
};
static const struct sexp_format sexp_formats[] = {
{ "transport", SEXP_TRANSPORT },
{ "canonical", SEXP_CANONICAL },
{ "advanced", SEXP_ADVANCED },
{ "international", SEXP_INTERNATIONAL },
{ NULL, 0 }
};
static void list_formats(void)
{
int i;
werror("Available formats are:\n");
for (i = 0; sexp_formats[i].name; i++)
werror(" %z\n", sexp_formats[i].name);
}
static int lookup_sexp_format(const char *name)
{
int i;
for (i = 0; sexp_formats[i].name; i++)
{
if (strcasecmp(sexp_formats[i].name, name) == 0)
return sexp_formats[i].id;
}
return -1;
}
/* GABA:
(expr
(name make_sexp_conv)
(params
(read object command)
(write object command))
;; (dest object abstract_write))
(expr
(lambda (in)
(write (read in)))))
*/
static void
do_exc_sexp_conv_io_handler(struct exception_handler *self,
const struct exception *x)
{
if (x->type & EXC_IO)
{
CAST_SUBTYPE(io_exception, e, x);
switch(x->type)
{
case EXC_IO_EOF:
close_fd_nicely(e->fd, 0);
break;
case EXC_IO_READ:
case EXC_IO_WRITE:
if (e->fd)
close_fd(e->fd, 0);
exit_code = EXIT_FAILURE;
break;
default:
exit_code = EXIT_FAILURE;
EXCEPTION_RAISE(self->parent, x);
return;
}
werror("lsh: %z, (errno = %i)\n", x->msg, e->error);
}
else
EXCEPTION_RAISE(self->parent, x);
}
static struct exception_handler exc_io_handler
= STATIC_EXCEPTION_HANDLER(do_exc_sexp_conv_io_handler, &default_exception_handler);
/* GABA:
(class
(name exc_sexp_conv_handler)
(super exception_handler)
(vars
(in object io_fd)))
*/
static void
do_exc_sexp_conv_handler(struct exception_handler *s,
const struct exception *x)
{
CAST(exc_sexp_conv_handler, self, s);
switch (x->type)
{
case EXC_SEXP_SYNTAX:
werror("Invalid SEXP input.\n");
exit_code = EXIT_FAILURE;
break;
case EXC_SEXP_EOF:
/* Normal termination */
break;
default:
exit_code = EXIT_FAILURE;
EXCEPTION_RAISE(self->super.parent, x);
return;
}
close_fd(&self->in->super, 0);
}
static struct exception_handler *
make_exc_sexp_conv_handler(struct io_fd *in)
{
NEW(exc_sexp_conv_handler, self);
self->super.raise = do_exc_sexp_conv_handler;
self->super.parent = &default_exception_handler;
self->in = in;
return &self->super;
}
#define SEXP_BUFFER_SIZE 1024
int main(int argc, char **argv)
{
int option;
int input_format = SEXP_ADVANCED;
int output_format = SEXP_ADVANCED;
NEW(io_backend, backend);
for (;;)
{
static const struct option options[] =
{
{ "verbose", no_argument, NULL, 'v' },
{ "quiet", no_argument, NULL, 'q' },
{ "debug", no_argument, &debug_flag, 1},
{ "input", required_argument, NULL, 'i'},
{ "output", required_argument, NULL, 'o'},
{ NULL }
};
option = getopt_long(argc, argv, "qvi:o:", options, NULL);
switch(option)
{
case -1:
goto options_done;
case 'q':
quiet_flag = 1;
break;
case 'v':
verbose_flag = 1;
break;
case 'i':
/* specify input format */
input_format = lookup_sexp_format(optarg);
if (input_format < 0)
{
werror("Invalid input format.\n");
list_formats();
return EXIT_FAILURE;
}
break;
case 'o':
/* specify output format */
output_format = lookup_sexp_format(optarg);
if (output_format < 0)
{
werror("Invalid output format.\n");
list_formats();
return EXIT_FAILURE;
}
break;
}
}
options_done:
init_backend(backend);
{
CAST_SUBTYPE(command, work,
make_sexp_conv(
make_read_sexp_command(input_format, 1),
make_write_sexp_to(output_format,
&(io_write(make_io_fd(backend,
STDOUT_FILENO,
&exc_io_handler),
SEXP_BUFFER_SIZE,
NULL)
->write_buffer->super))));
struct io_fd *in = make_io_fd(backend, STDIN_FILENO, &exc_io_handler);
COMMAND_CALL(work, in,
&discard_continuation,
make_exc_sexp_conv_handler(in));
}
io_run(backend);
return exit_code;
}
Markdown is supported
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