ERROR HANDLING

Consider return values from handlers. A return value has several
components:

 x Success/failure indication
 
 x Next action (continue, close immediately, flush buffers then close,
   exit...)
 
 x Process return value in case the proper action is to exit.

It should be possible to encode all this information into a simple
integer. And some actions are orthogonal. For instance, a handler may
fork, and send a few messages. Now, both the fork action and any error
codes from writing must be taken care of.

Perhaps errors when processing data on one socket should propagate to
another one?

Can one safely assume that the only error that can occur when sending
a packet (typically by A_WRITE(connection->write, packet)) is LSH_FAIL
| LSH_CLOSE?


KEYS

Code is needed to generate, store and read dss keys. Preferably in a
SPKI/s-expression form.


USERS

Functions to lookup users, their passwords and .lsh/authorized_keys.


CHARSETS

Usernames and passwords must be translated from the systems charset
(default iso-8859-1) to UTF8.


CONFIGURATION

Read configuration files. Better command line options.


ALLOCATION

Not all packet consumers free processed packets properly.

Use separate allocation function for objects that are subject to gc,
and thos (for instance, strings and atom lists) which are deallocated
explicitly). 

Implement a mark&sweep gc.

Use separate "storage-types" for lsh_string_alloc and
lssh_space_alloc.

Make lists of integers (usually atoms) its own type. Can this be done
in such a way that they can also be allocated statically? 

Have the allocator initialize all objects automatically.

Better typechecking of non-heap objects. To do this one would also
need valid isa-pointers in classes (as classes are statically
allocated). If this is done properly, the meta feature could also be
cleaned up a little.


CHANNELS

Create some generic methods for connecting a channel to one or more
files. The data shuffling and error handling should be very similar
for most channel types.

Consider which errors can occur in the channel callback functions;
they are probably somewhat different from errors in higher levels. For
instance, a writing to a file associated with a channel may fail. In
that case, the channel should be closed, but the connection should not
die. Handle the LSH_CHANNEL_FINISHED code properly.

Fix the flow control (it's broken on the recieving end).


CHANNEL CLOSE

Channels may need some live-ness status. For instance, a remote
process may close its stdout and stderr, but still keep on running. In
this case, the local process should close it's stdout and stderr, but
not close the channel until it has recieved a close message and
possibly an exit status.

The server's close message should somehow be delayed until the dead
process has been reaped. I think the Right way is for the server to
initiate CHANNEL_CLOSE when all of the following conditions are true:

 The process is dead (and its exit status has been send to the
  client).
x EOF has been detected on both stdout and stderr.
 An EOF message has been recieved from the client.

The client may want to respond to the exit-status message with an
CHANNEL_EOF message, unless it wants to talk to any forked children
that may still keep the stdin open.


USER INFO

Where should the user information (name, home directory, login shell,
etc), be stored? Is there any reasonable place but the connection
structure? Perhaps the channel_open handler for the session is a
reasonable place? Then we only have to figure out when to install that
information.


PROCESSES

Dying children must be handled. For example like this: Use a signal
handler to set a flag when a child dies. Let the backend loop (io.c)
look at this flag, wait() to get status from dying children. Use an
alist pid->callback to report childrens exit status back to the remote
end. Another issue are process groups... Are they relevant? 

Kill child processes if its channel or its connection is closed
unexpectedly. 


MISC

Try to find out why read() sometimes returns -1 and sets errno==EPIPE,
on sparc-linux, 2.0.33, redhat-5.1, glibc.

Fix shadow passwd support.

Don't use stdio for werror and similar functions. The non-blocking
stderr sometime causes the C library to lose data.
