diff --git a/src/libraries/libclient/async.c b/src/libraries/libclient/async.c
new file mode 100644
index 0000000000000000000000000000000000000000..b6973a33d790bf6e3b8e33f4202eb158875b544e
--- /dev/null
+++ b/src/libraries/libclient/async.c
@@ -0,0 +1,524 @@
+/*
+ * $Id: async.c,v 1.1 1993/10/06 12:09:28 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+ * async.c -- Receive asynchronous messages and call a handler.
+ *
+ * Written by Per Cederqvist 1990-07-24
+ */
+
+static char *rcsid = "$Id: async.c,v 1.1 1993/10/06 12:09:28 linus Exp $";
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+/* #include <sys/time.h> is included from kom-types.h */
+#include <sys/types.h>
+#if defined(__svr4__) && defined(__sparc__)
+/* Solaris */
+#include <stropts.h>
+#include <sys/conf.h>
+#define POLLINGREAD	I_NREAD
+#else
+#define POLLINGREAD	FIONREAD
+#endif
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <kom-types.h>
+#include <kom-errno.h>
+#include <services.h>
+
+#include "async.h"
+#include "client-malloc.h"
+#include "parse.h"
+#include "client.h"
+#include "services.h"
+
+/*
+ * The handlers.
+ */
+static void (*new_text_handler)(Text_no    text_no, 
+				Text_stat  text_s) = NULL;
+static void (*i_am_on_handler)(Who_info info) = NULL;
+static void (*i_am_off_handler)(Pers_no pers_no) = NULL;
+static void (*new_name_handler)(Conf_no  conf_no,
+				String   old_name,
+				String   new_name) = NULL;
+static void (*directed_message_handler)(Conf_no	to,
+					Conf_no from,
+					String message) = NULL;
+static void (*saving_handler)(void) = NULL;
+
+/* Forward declarators for this file. */
+    
+static Success skip_one_token(FILE *fp);
+
+/*
+ * Functions that skip tokens. A token is:
+ *	a number,
+ *	a string or
+ *	an array
+ *
+ * An array is
+ *	the character '*' or
+ *	the character '{' followed by any number of tokens followed by '}'
+ */
+
+/*
+ * skip_array is used when the first '{' of an array has been detected.
+ * It skips all tokens to the closing '}'.
+ */
+static Success
+skip_array(FILE *fp)
+{
+    int c;
+
+    while ( skipwhite(fp), (c=getc(fp)) != '}' )
+    {
+	ungetc(c, fp);
+	if ( skip_one_token(fp) != OK )
+	    return FAILURE;
+    }
+    return OK;
+}
+
+
+/*
+ * Skips the next token. Returns FAILURE if it isn't a token.
+ */
+static Success
+skip_one_token(FILE *fp)
+{
+    int c;
+    u_long strlen;
+
+    skipwhite(fp);
+    
+    switch(c=getc(fp))
+    {
+    case '{':
+	if ( skip_array(fp) != OK )
+	    return FAILURE;
+	    
+	break;
+
+    case '*':
+	break;
+
+    default:
+	if ( !isdigit(c) )
+	{
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+
+	ungetc(c, fp);
+	strlen = parse_long(fp);
+
+	if ( (c = getc(fp)) == 'H' )
+	{
+	    /* It was a string. Read it. */
+	    while ( strlen-- > 0 )
+		getc(fp);
+	}
+	else
+	{
+	    /* It was a number. Ignore it. */
+	    if ( ! isspace(c) )
+	    {
+		kom_errno = KOM_SERVER_IS_CRAZY;
+		return FAILURE;
+	    }
+	}	    
+    }
+    return OK;
+}
+
+
+
+/*
+ * Skip no_of_tokens token.
+ */
+static Success			/* FIXME+++ - should this be exported? */
+skip_token(FILE *fp,
+	   int   no_of_tokens)
+{
+    while ( no_of_tokens-- > 0 )
+    {
+	if ( skip_one_token(fp) != OK )
+	    return FAILURE;
+    }
+
+    return OK;
+}
+
+
+
+/*
+ * Functions which gather the arguments for a handler and
+ * calls that handler.
+ *
+ * A handler is always responsible for free:ing everything
+ * which is given to it as a pointer. If no handler is registered
+ * these functions of course free everything they have malloced.
+ */
+static Success
+call_new_text(FILE *fp)
+{
+    Text_no   text_no;
+    Text_stat text = EMPTY_TEXT_STAT;
+
+    text_no = parse_long(fp);
+    if ( parse_text_stat(fp, &text) != OK )
+	return FAILURE;
+
+    if ( new_text_handler == NULL )
+    {
+	if ( text.misc_items != NULL )
+	    isc_free(text.misc_items);
+    }
+    else
+	new_text_handler(text_no, text);
+
+    return OK;
+}
+
+
+static Success
+call_i_am_on(FILE *fp)
+{
+    Who_info info = EMPTY_WHO_INFO;
+
+    if ( parse_who_info(fp, &info) != OK )
+	return FAILURE;
+
+    if ( i_am_on_handler == NULL )
+    {
+	s_clear (&info.what_am_i_doing);
+	s_clear (&info.username);
+    }
+    else
+	i_am_on_handler(info);
+
+    return OK;    
+}
+
+static Success
+call_i_am_off(FILE *fp)
+{
+    Pers_no pers_no;
+
+    pers_no = parse_long(fp);
+
+    if ( i_am_off_handler != NULL )
+	i_am_off_handler(pers_no);
+
+    return OK;
+}
+
+static Success
+call_new_name(FILE *fp)
+{
+    Conf_no  conf_no;
+    String   old_name = EMPTY_STRING;
+    String   new_name = EMPTY_STRING;
+
+    conf_no = parse_long(fp);
+    
+    if ( parse_string(fp, &old_name) != OK
+	|| parse_string(fp, &new_name) != OK )
+    {
+	return FAILURE;
+    }
+
+    if ( new_name_handler == NULL )
+    {
+	s_clear (&old_name);
+	s_clear (&new_name);
+    }
+    else
+	new_name_handler(conf_no, old_name, new_name);
+
+    return OK;
+}
+
+
+static Success
+call_directed_message(FILE *fp)
+{
+    Conf_no  to, from;
+    String   message = EMPTY_STRING;
+
+    to = parse_long(fp);
+    from = parse_long(fp);
+
+    if ( parse_string(fp, &message) != OK )
+    {
+	return FAILURE;
+    }
+
+    if ( directed_message_handler == NULL )
+    {
+	s_clear (&message);
+    }
+    else
+        directed_message_handler(to, from, message);
+
+    return OK;
+}
+
+/*
+ * Call function telling that the server is syncing.
+ */
+static Success
+call_saving(FILE *fp)
+{
+    if (saving_handler == NULL)
+    {
+	/* Do nothing */
+    }
+    else
+    {
+	saving_handler();
+    }
+
+    return OK;
+}
+
+/*
+ * Parse an asynchronous message and call the appropriate function.
+ */
+Success
+async(FILE *fp)
+{
+    int tokens_to_skip;
+    Async fnc;
+
+    tokens_to_skip = parse_long(fp);
+    fnc = parse_long(fp);
+
+    switch(fnc)
+    {
+    case ay_new_text:
+	return call_new_text(fp);
+
+    case ay_i_am_on:
+	return call_i_am_on(fp);
+
+    case ay_i_am_off:
+	return call_i_am_off(fp);
+
+    case ay_new_name:
+	return call_new_name(fp);
+
+    case ay_directed_message:
+	return call_directed_message(fp);
+
+    case ay_saving:
+	return call_saving(fp);
+
+    default:
+	/*
+	 * Messages that are not implemented. Since the server
+	 * tells how long the message is it is possible to skip it.
+	 */
+	return skip_token(fp, tokens_to_skip);
+    }
+}
+
+
+/*
+ * Use the following functions to say that you want to catch a
+ * certain type of message. The default action is to ignore all
+ * messages.
+ */
+void
+register_new_text(void (*async_new_text)(Text_no    text_no, 
+					 Text_stat  text_s))
+{
+    new_text_handler = async_new_text;
+}
+
+void
+register_i_am_on(void (*async_i_am_on)(Who_info info))
+{
+    i_am_on_handler = async_i_am_on;
+}
+
+
+void
+register_i_am_off (void (*async_i_am_off)(Pers_no pers_no))
+{
+    i_am_off_handler = async_i_am_off;
+}
+
+
+void
+register_new_name(void (*async_new_name)(Conf_no  conf_no,
+					 String   old_name,
+					 String   new_name))
+{
+    new_name_handler = async_new_name;
+}
+
+
+void
+register_directed_message(void (*async_message)(Conf_no	to,
+						Conf_no	from,
+						String		message))
+{
+    directed_message_handler = async_message;
+}
+
+
+void
+register_saving(void (*saving_fun)(void))
+{
+    saving_handler = saving_fun;
+}
+
+
+static enum { poll_err, poll_got_msg, poll_no_msg }
+poll_server(void)
+{
+    int c;
+    long nread;
+    
+    while ( 1 )
+    {    
+	if ( ioctl(kom_server->fd, POLLINGREAD, (caddr_t) &nread) != 0)
+	{
+	    kom_errno = KOM_NO_CONNECT;
+	    return poll_err;
+	}
+
+	if ( nread == 0 )
+	    return poll_no_msg;
+
+	if ( (c=getc(kom_server->in)) == ':' )
+	    return (async(kom_server->in) == OK) ? poll_got_msg : poll_err;
+
+	if ( !isspace(c) )
+	{
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return poll_err;
+	}
+    }
+}
+
+	
+/*
+ *  Wait for asynchronous message from client, or input on any of
+ *  the file-descriptors in opt_set. Returns FAILURE if nothing
+ *  happened in msec milliseconds or an error occurs. (kom_errno ==
+ *  KOM_NO_ERR if the return was due to a timeout). Returns OK if
+ *  there was an asynchronous message or input on any of the fd's in
+ *  opt_set.
+ *
+ *  Set opt_set to NULL if you don't want to wait on any other input
+ *  than a message.
+ *
+ *  To wait for a message or input on stdin the following code can be used:
+ *
+ *  fd_set read_set;
+ *
+ *  FD_ZERO(&read_set);
+ *  FD_SET(fileno(stdin), &read_set);
+ *  if ( kom_wait(read_set, 1000) == OK )
+ *  {
+ *	if ( FD_ISSET(fileno(stdio), &read_set) )
+ *	    handle_stdin_input();
+ *	else
+ *	    handle_asynchronous_message();
+ *  }
+ *  else
+ *	time_out();
+ *
+ *  (The handler is called from kom_wait and not handle_asynchronous_message,
+ *   but there might be more to do afterwards since a handler cannot call
+ *   functions that communicate with the server.)
+ */
+extern  Success
+kom_wait (fd_set *opt_set,
+	  int     msec)
+{
+    struct timeval wait;
+    fd_set read_set;
+    int    nfds;
+    
+    kom_errno = KOM_NO_ERROR;
+    
+    switch(poll_server())
+    {
+    case poll_err:
+	FD_ZERO(opt_set);
+	return FAILURE;
+
+    case poll_got_msg:
+	FD_ZERO(opt_set);
+	return OK;
+
+    case poll_no_msg:
+	break;
+    }	
+
+    /* No waiting message, so wait a while or two. */
+    
+    /* Setup timeout structure */
+    wait.tv_sec  = msec / 1000;
+    wait.tv_usec = (msec % 1000) * 1000;
+
+    /* Setup file descriptor set */
+    if ( opt_set == NULL )
+    {
+	FD_ZERO(&read_set);
+	opt_set = &read_set;
+    }
+    FD_SET(kom_server->fd, opt_set);
+
+  
+    nfds = select(FD_SETSIZE,
+		  opt_set,
+		  (fd_set *) NULL,
+		  (fd_set *) NULL,
+		  &wait);
+
+    if ( nfds < 0 )
+    {
+	kom_errno = KOM_NO_CONNECT;
+	return FAILURE;
+    }
+
+    if ( FD_ISSET(kom_server->fd, opt_set) 
+	&& poll_server() == poll_err )
+    {
+	return FAILURE;
+    }
+
+    return nfds == 0 ? FAILURE : OK;
+}
+
diff --git a/src/libraries/libclient/async.h b/src/libraries/libclient/async.h
new file mode 100644
index 0000000000000000000000000000000000000000..519476347f391cd52a61109853698fb958cb99fc
--- /dev/null
+++ b/src/libraries/libclient/async.h
@@ -0,0 +1,57 @@
+/*
+ * $Id: async.h,v 1.1 1993/10/06 12:09:36 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+ * $Id: async.h,v 1.1 1993/10/06 12:09:36 linus Exp $
+ *
+ * This file contains the parts of the async protocol that are common
+ * to the server and the client.
+ */
+
+
+/*
+ * What does this packet contain? (See doc/com-spec)
+ */
+typedef enum {
+	ay_new_text = 0,
+	ay_i_am_off = 1,
+	ay_i_am_on_obsolete = 2, /* Sends a Who_info_old. */
+	ay_conf_deleted = 3,
+	ay_conf_created = 4,
+	ay_new_name = 5,
+	ay_i_am_on = 6,		/* Sends a Who_info. */
+	ay_saving = 7,
+	ay_forced_leave_conf = 8,
+	ay_login = 9,
+	/* ay_broadcast_message = 10, */
+	ay_crowded = 11,
+	ay_directed_message = 12,
+	ay_logout = 13
+} Async;
+
+/*
+ * Parse an asynchronous message and call the appropriate function.
+ */
+extern Success
+async(FILE *fp);
diff --git a/src/libraries/libclient/client-malloc.h b/src/libraries/libclient/client-malloc.h
new file mode 100644
index 0000000000000000000000000000000000000000..bbba9be93d975131ca8cdda40bc454ca0b9d6a69
--- /dev/null
+++ b/src/libraries/libclient/client-malloc.h
@@ -0,0 +1,28 @@
+/*
+ * $Id: client-malloc.h,v 1.1 1993/10/06 12:09:44 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/* $Id: client-malloc.h,v 1.1 1993/10/06 12:09:44 linus Exp $ */
+extern malloc_function	isc_malloc;
+extern realloc_function	isc_realloc;
+extern free_function	isc_free;	
diff --git a/src/libraries/libclient/client.c b/src/libraries/libclient/client.c
new file mode 100644
index 0000000000000000000000000000000000000000..5aaf4b74882c7fdc859b9f01741149f889c08dcc
--- /dev/null
+++ b/src/libraries/libclient/client.c
@@ -0,0 +1,203 @@
+/*
+ * $Id: client.c,v 1.1 1993/10/06 12:09:51 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+** client.c                        definitions of ISC client support routines
+**
+** history:
+**    900509 pen       initial coding
+**    930829 linus     changed name.
+*/
+
+static char *rcsid = "$Id: client.c,v 1.1 1993/10/06 12:09:51 linus Exp $";
+
+#include <stdio.h>
+/* #include <sys/time.h> is included from kom-types.h */
+#include <sys/types.h>  
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <unistd.h>
+
+#include <kom-types.h>
+
+#include "client-malloc.h"
+#include "client.h"
+
+/*
+ * Open a connection to a server. host == NULL means this machine.
+ */
+ISC *
+isc_connect(const char *host,
+	    int port)
+{
+    ISC *isc_si;
+    char buf[100];
+#ifdef HAVE_STRUCT_LINGER
+    struct linger  lingonsylt;
+#endif
+    int intbuf;
+    struct sockaddr_in server;
+    struct hostent *hp;
+
+
+
+    /* Allocate storage for the ISC structure */
+    isc_si = (ISC *) isc_malloc(sizeof(ISC));
+
+
+    /* Local connection? */
+    if (host == NULL)
+    {
+	gethostname(buf, sizeof(buf));
+	host = buf;
+    }
+
+    if ((hp = gethostbyname(host)) != NULL)
+    {
+	memset((char *) &server, 0, sizeof(server));
+#ifdef NETDB_DIFF
+	memcpy((char *) &server.sin_addr, hp->h_addr_list, hp->h_length);
+#else
+	memcpy((char *) &server.sin_addr, hp->h_addr, hp->h_length);
+#endif
+	server.sin_family = hp->h_addrtype;
+    }
+    else
+    {
+	perror("gethostbyname failed:");
+	server.sin_family = AF_INET;
+	server.sin_addr.s_addr = inet_addr(host);
+	if (server.sin_addr.s_addr == -1)
+	    return NULL;
+    }
+
+    server.sin_port = (int) htons(port);
+    if ((isc_si->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+	return NULL;
+
+#ifdef HAVE_STRUCT_LINGER
+    lingonsylt.l_onoff = 0;
+    lingonsylt.l_linger = 0;
+    if (setsockopt(isc_si->fd, SOL_SOCKET, SO_LINGER,
+		   (char *)&lingonsylt, sizeof(lingonsylt)) < 0)
+    {
+	perror("Can't turn off linger");
+    }
+#endif
+
+    intbuf = 0;
+    if (setsockopt(isc_si->fd, SOL_SOCKET, SO_REUSEADDR, 
+		   (char *)&intbuf, sizeof(intbuf)) < 0)
+    {
+	perror("Can't turn of reuse of local addr");
+    }
+
+    intbuf = 1;
+    if (setsockopt(isc_si->fd, SOL_SOCKET, SO_KEEPALIVE,       
+		   (char *)&intbuf, sizeof(intbuf)) < 0)
+    {
+	perror("Can't turn on KEEPALIVE");
+    }
+
+    if (connect(isc_si->fd, (struct sockaddr *)&server, sizeof(server)) < 0
+	|| (isc_si->in = fdopen(isc_si->fd, "r" )) == NULL 
+	|| (isc_si->out = fdopen(isc_si->fd, "w")) == NULL )
+    {
+	close(isc_si->fd);
+	return NULL;
+    }
+    setbuf(isc_si->in, NULL);
+    setbuf(isc_si->out, NULL);
+    
+    return isc_si;
+}
+
+
+/*
+ * Shut down the connection
+ */
+Success
+isc_disconnect(ISC *isc_si)
+{
+    fclose(isc_si->in);		/* *** check retval */
+    fclose(isc_si->out);	/* *** check retval */
+    isc_free(isc_si);
+    return OK;
+}
+
+
+
+/*
+ * Wait for a message from the server. I opt_readset != NULL also wait for
+ * messages on those fds.
+ *
+ * Return value:
+ *	< 0	error
+ *	> 0	there is a message from the server (and maybe also
+ *		in opt_readset)
+ *	= 0	there is a message in the opt_readset.
+ */
+int
+isc_wait(ISC *isc_si,
+	 int timeout,
+	 fd_set *opt_readset)
+{
+    fd_set read_set;
+    struct timeval wait;
+    int nfds;
+
+
+    /* Setup timeout structure */
+    wait.tv_sec  = timeout / 1000;
+    wait.tv_usec = (timeout * 1000) % 1000000;
+
+    /* Setup file descriptor set */
+    if ( opt_readset == NULL )
+    {
+	FD_ZERO(&read_set);
+	opt_readset = &read_set;
+    }
+    FD_SET(isc_si->fd, opt_readset);
+
+  
+    nfds = select(FD_SETSIZE,
+		  opt_readset,
+		  (fd_set *) NULL,
+		  (fd_set *) NULL,
+		  &wait);
+
+
+    return (nfds < 0 ? nfds : FD_ISSET(isc_si->fd, opt_readset));
+}
+ 
+    
diff --git a/src/libraries/libclient/client.h b/src/libraries/libclient/client.h
new file mode 100644
index 0000000000000000000000000000000000000000..1bd311200cb28ac8388ca26f12767b9b0604b3a5
--- /dev/null
+++ b/src/libraries/libclient/client.h
@@ -0,0 +1,82 @@
+/*
+ * $Id: client.h,v 1.1 1993/10/06 12:09:57 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+ * $Id: client.h,v 1.1 1993/10/06 12:09:57 linus Exp $
+ *
+** isc/client.h                     structures and defines used in a ISC client
+**
+** history:
+**   900509 pen       initial coding
+*/
+
+#ifndef _CLIENT_H_INCLUDED__
+#define _CLIENT_H_INCLUDED__
+
+typedef struct
+{
+  int fd;               /* Server TCP/IP file descriptor. */
+  FILE *in;		/* FILE * for things from the server */
+  FILE *out;		/* FILE * for things to the server */
+} ISC;
+
+
+#define KS kom_server		/* I know I'm lazy :-) /ceder */
+extern ISC *kom_server;		/* The server that is used. */
+
+
+/*
+ * Open a connection to a server. host == NULL means this machine.
+ */
+extern ISC *
+isc_connect(const char *host,
+	    int port);
+
+
+
+/*
+ * Shut down the connection
+ */
+extern Success
+isc_disconnect(ISC *isc_si);
+
+
+
+/*
+ * Wait for a message from the server. I opt_readset != NULL also wait for
+ * messages on those fds.
+ *
+ * Return value:
+ *	< 0	error
+ *	> 0	there is a message from the server (and maybe also
+ *		in opt_readset)
+ *	= 0	there is a message in the opt_readset.
+ */
+extern int
+isc_wait(ISC *isc_si,
+	 int timeout,
+	 fd_set *opt_readset);
+ 
+    
+#endif
diff --git a/src/libraries/libclient/input.c b/src/libraries/libclient/input.c
new file mode 100644
index 0000000000000000000000000000000000000000..5b7d161a8fe53761880851bfe604d007c23029ce
--- /dev/null
+++ b/src/libraries/libclient/input.c
@@ -0,0 +1,283 @@
+/*
+ * $Id: input.c,v 1.1 1993/10/06 12:10:02 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+ *  services.c  --  All the services the LysKOM server makes available
+ *		    for clients.
+ *
+ *  Created by ceder 1990-07-17
+ */
+
+static char *rcsid = "$Id: input.c,v 1.1 1993/10/06 12:10:02 linus Exp $";
+
+#include <kom-types.h>
+#include <config.h>
+#include <services.h>
+#include <kom-errno.h>
+#include "parse.h"
+#include "client.h"
+#include "async.h"
+#include "input.h"
+
+
+extern Success
+input_header(void)
+{
+    int c;
+    
+    skipwhite(KS->in);
+
+    while ( (c=getc(KS->in)) == ':' )
+    {
+	if ( async(KS->in) != OK )
+	    return FAILURE;
+	
+	skipwhite(KS->in);
+    }
+    
+    switch(c)
+    {
+    case '=':
+	(void)parse_long(KS->in);	/* Don't care abot ref_no */
+	kom_errno = KOM_NO_ERROR;
+	return OK;
+    case '%':
+	if ( (c=getc(KS->in)) == '%' )
+	{
+	    /* The server is sending '%% LysKOM protocol error.' */
+	    /* BUG: Since the line is not discarded it is harder
+	     *      than it ought to be to recover from this error. */
+	    kom_errno = KOM_CLIENT_IS_CRAZY;
+	    return FAILURE;
+	}
+	ungetc(c, KS->in);
+	(void)parse_long(KS->in);
+	kom_errno = parse_long(KS->in);
+	err_stat = parse_long(KS->in);
+	return FAILURE;
+	
+    default:
+	kom_errno = KOM_SERVER_IS_CRAZY;
+	return FAILURE;
+    }
+}
+
+	
+
+extern  Pers_no
+input_create_person (const String  name,
+		     const String  passwd )
+{
+    if ( input_header() != OK )
+	return 0;
+
+    return parse_long(KS->in);
+}
+
+
+extern  Success
+input_get_person_stat (Person        * result )
+{
+    if ( input_header() != OK )
+	return FAILURE;
+
+    return parse_person(KS->in, result);
+}
+
+extern  Success
+input_get_created_texts(Text_list   * result)
+{
+    if ( input_header() != OK )
+	return FAILURE;
+
+    return parse_text_list(KS->in, result);
+}
+
+
+extern  Success
+input_get_membership(Membership_list  * memberships)
+{
+    if ( input_header() != OK )
+	return FAILURE;
+
+    return parse_membership_list(KS->in, memberships);
+}
+
+
+extern  Success
+input_query_read_texts ( Membership * result   )
+{
+    if ( input_header() != OK )
+	return FAILURE;
+
+    return parse_membership(KS->in, result );
+}
+
+
+extern  Conf_no
+input_create_conf (const String  name,
+		   Conf_type	   type )
+{
+    if ( input_header() != OK )
+	return 0;
+
+    return parse_long(KS->in);
+}
+
+
+
+
+extern  Success
+input_lookup_name (Conf_list     *result)
+{
+    if ( input_header() != OK )
+	return FAILURE;
+
+    return parse_conf_list(KS->in, result );
+}
+
+
+
+extern  Success
+input_get_conf_stat (Conference     * result )
+{
+    if ( input_header() != OK )
+	return FAILURE;
+
+    return parse_conference(KS->in, result );
+}
+
+extern  Success
+input_get_members (Member_list	* members)
+{
+    if ( input_header() != OK )
+	return FAILURE;
+
+    return parse_member_list(KS->in, members);
+}
+
+
+extern  Success
+input_get_marks (Mark_list *result )
+{
+    if ( input_header() != OK )
+	return FAILURE;
+
+    return parse_mark_list(KS->in, result);
+}
+
+
+
+extern  Success
+input_get_text (String  *result)
+{
+    if ( input_header() != OK )
+	return FAILURE;
+    
+    return parse_string(KS->in, result);
+}
+
+
+
+extern  Success
+input_get_text_stat (Text_stat *result)
+{
+    if ( input_header() != OK )
+	return FAILURE;
+
+    return parse_text_stat(KS->in, result);
+}
+
+
+
+extern  Text_no
+input_create_text (void)
+{
+    if ( input_header() != OK )
+	return 0;
+
+    return parse_long(KS->in);
+}
+
+
+extern  Text_no
+input_create_anonymous_text (void)
+{
+    if ( input_header() != OK )
+	return 0;
+
+    return parse_long(KS->in);
+}
+
+extern  Success
+input_get_map (Text_list  * result)
+{
+    if ( input_header() != OK )
+	return FAILURE;
+
+    return parse_text_list(KS->in, result);
+}
+
+
+
+extern  Success
+input_get_time ( struct tm *time )
+{
+    if ( input_header() != OK || parse_time(KS->in, time) != OK )
+	return FAILURE;
+
+    return OK;
+}
+
+
+extern  Success
+input_who_is_on (Who_info_list *result)
+{
+    if ( input_header() != OK )
+	return FAILURE;
+
+    return parse_who_info_list(KS->in, result);
+}
+
+
+extern  Success
+input_get_info (Info *result )
+{
+    if ( input_header() != OK )
+	return FAILURE;
+
+    return parse_info(KS->in, result);
+}
+
+
+extern  Success
+input_get_unread_confs (Conf_no_list *result )
+{
+    if ( input_header() != OK )
+	return FAILURE;
+
+    return parse_conf_no_list (KS->in, result);
+}
+
+
diff --git a/src/libraries/libclient/input.h b/src/libraries/libclient/input.h
new file mode 100644
index 0000000000000000000000000000000000000000..c0bc3a15709496397c608c3443a2fe7778506067
--- /dev/null
+++ b/src/libraries/libclient/input.h
@@ -0,0 +1,104 @@
+/*
+ * $Id: input.h,v 1.1 1993/10/06 12:10:08 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+ * $Id: input.h,v 1.1 1993/10/06 12:10:08 linus Exp $
+ *
+ *  Created by ceder 1990-07-18
+ */
+
+
+extern Success
+input_header(void);
+	
+
+extern  Pers_no
+input_create_person (const String  name,
+		     const String  passwd );
+
+extern  Success
+input_get_person_stat (Person	     * result );
+
+extern  Success
+input_get_created_texts(Text_list   * result);
+
+extern  Success
+input_get_membership(Membership_list  * memberships);
+
+extern  Success
+input_query_read_texts ( Membership * result   );
+
+extern  Conf_no
+input_create_conf (const String  name,
+		   Conf_type	   type );
+
+
+
+extern  Success
+input_lookup_name (Conf_list     *result);
+
+
+extern  Success
+input_get_conf_stat (Conference    * result );
+
+
+extern  Success
+input_get_members (Member_list	* members);
+
+
+extern  Success
+input_get_marks (Mark_list *result );
+
+
+extern  Success
+input_get_text (String  *result);
+
+
+extern  Success
+input_get_text_stat (Text_stat *result);
+
+
+extern  Text_no
+input_create_text (void);
+
+extern  Text_no
+input_create_anonymous_text (void);
+
+
+extern  Success
+input_get_map (Text_list  * result);
+
+
+extern  Success
+input_get_time ( struct tm  * clock );
+
+
+extern  Success
+input_who_is_on (Who_info_list  * result);
+
+extern  Success
+input_get_unread_confs (Conf_no_list *result );
+
+extern  Success
+input_get_info (Info *result );
diff --git a/src/libraries/libclient/kom-types.c b/src/libraries/libclient/kom-types.c
new file mode 100644
index 0000000000000000000000000000000000000000..f8629954df2a2dbf76fb43ab1be179b376a1ec2a
--- /dev/null
+++ b/src/libraries/libclient/kom-types.c
@@ -0,0 +1,88 @@
+/*
+ * $Id: kom-types.c,v 1.1 1993/10/06 12:10:16 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+ *  kom-types.c
+ *		Definition of constants and other thing that
+ *		can't or shouldn't be defined in header files.
+ *
+ *
+ *  Copyright (C) 1990  Lysator Computer Club
+ *			Linkoping University,  Sweden
+ *
+ *  Everyone is granted permission to copy, modify and redistribute
+ *  this code, provided the people they give it to can.
+ *
+ *
+ *  Author:	Thomas Bellman
+ *		Lysator Computer Club
+ *		Linkoping University
+ *		Sweden
+ *
+ *  email:	bellman@Lysator.LiU.SE
+ */
+
+static char *rcsid = "$Id: kom-types.c,v 1.1 1993/10/06 12:10:16 linus Exp $";
+
+#include <stdio.h>
+#include <kom-types.h>
+#include <config.h>
+
+#define	EXPORT
+
+
+EXPORT const Conf_list		EMPTY_CONF_LIST	= EMPTY_CONF_LIST_i;
+
+EXPORT  const Pers_list		EMPTY_PERS_LIST = EMPTY_PERS_LIST_i;
+
+EXPORT  const Mark_list		EMPTY_MARK_LIST = EMPTY_MARK_LIST_i;
+
+EXPORT  const Conf_no_list	EMPTY_CONF_NO_LIST = EMPTY_CONF_NO_LIST_i;
+
+EXPORT  const Conf_type		NULL_CONF_TYPE	= NULL_CONF_TYPE_i;
+
+EXPORT  const Membership	EMPTY_MEMBERSHIP = EMPTY_MEMBERSHIP_i;
+
+EXPORT  const Membership_list	EMPTY_MEMBERSHIP_LIST = EMPTY_MEMBERSHIP_LIST_i;
+
+EXPORT  const Text_list		EMPTY_TEXT_LIST =  EMPTY_TEXT_LIST_i;
+
+EXPORT  const Member_list	EMPTY_MEMBER_LIST = EMPTY_MEMBER_LIST_i;
+
+EXPORT  const Who_info		EMPTY_WHO_INFO = EMPTY_WHO_INFO_i;
+
+EXPORT  const Who_info_ident	EMPTY_WHO_INFO_IDENT = EMPTY_WHO_INFO_IDENT_i;
+
+EXPORT  const Who_info_list 	EMPTY_WHO_INFO_LIST = EMPTY_WHO_INFO_LIST_i;
+
+EXPORT  const Priv_bits		DEFAULT_PRIV_BITS = DEFAULT_PRIV_BITS_i;
+
+EXPORT const Personal_flags DEFAULT_PERSONAL_FLAGS = DEFAULT_PERSONAL_FLAGS_i;
+
+
+EXPORT const Person EMPTY_PERSON = EMPTY_PERSON_i;
+
+EXPORT const Conference EMPTY_CONFERENCE = EMPTY_CONFERENCE_i;
+
+EXPORT const Text_stat EMPTY_TEXT_STAT = EMPTY_TEXT_STAT_i;
diff --git a/src/libraries/libclient/output.c b/src/libraries/libclient/output.c
new file mode 100644
index 0000000000000000000000000000000000000000..ce8530a007467fd9458618c4b3af7f4ec9ccf8d2
--- /dev/null
+++ b/src/libraries/libclient/output.c
@@ -0,0 +1,675 @@
+/*
+ * $Id: output.c,v 1.1 1993/10/06 12:10:23 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+ *  output.c  --  initiate call to client.
+ *
+ *  Created by ceder 1990-07-17
+ */
+
+static char *rcsid = "$Id: output.c,v 1.1 1993/10/06 12:10:23 linus Exp $";
+
+#include <stdio.h>
+
+#include <kom-types.h>
+#include <config.h>
+#include <services.h>
+
+#include "client.h"
+#include "output.h"
+#include "services.h"
+#include <com.h>
+
+#include "send.h"
+
+static void
+output_packet_header(Call_header fnc)
+{
+    fprintf(KS->out, "0 %lu", (u_long)fnc);
+}
+
+
+extern  void
+output_login_old (Pers_no	person,
+		  const String	passwd)
+{
+    output_packet_header(call_fnc_login_old);
+    fprintf(KS->out, " %lu", (u_long)person);
+    output_string(KS->out, passwd);
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+extern  void
+output_login (Pers_no		person,
+	      const String	passwd,
+	      Bool		visible)
+{
+    output_packet_header(call_fnc_login);
+    fprintf(KS->out, " %lu", (u_long)person);
+    output_string(KS->out, passwd);
+    fprintf(KS->out, " %lu", (u_long)visible);
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_logout (void)	/* can never fail */
+{
+    output_packet_header(call_fnc_logout);
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_pepsi (Conf_no	conference )
+{
+    output_packet_header(call_fnc_pepsi);
+    fprintf(KS->out, " %lu\n", (u_long)conference);
+    fflush(KS->out);
+}
+
+
+
+
+extern  void
+output_change_name (Conf_no       conf_no,
+		    const String  new_name)
+{
+    output_packet_header(call_fnc_change_name);
+    fprintf(KS->out, " %lu", (u_long)conf_no);
+    output_string(KS->out, new_name );
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_change_what_i_am_doing (const String  what_am_i_doing )
+{
+    output_packet_header(call_fnc_change_what_i_am_doing);
+    output_string(KS->out, what_am_i_doing );
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+
+
+/******************************
+*     Person-related calls    *
+******************************/
+
+/*
+ *  Create a new person.  Returns 0 if any error occured.
+ */
+extern void
+output_create_person (const String  name,
+		      const String  passwd )
+{
+    output_packet_header(call_fnc_create_person);
+    output_string(KS->out, name );
+    output_string( KS->out, passwd );
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_get_person_stat (Pers_no	        person)
+{
+    output_packet_header(call_fnc_get_person_stat);
+    fprintf(KS->out, " %lu\n", (u_long) person);
+    fflush(KS->out);
+}
+
+extern  void
+output_get_created_texts(Pers_no       pers_no,
+			 Local_text_no first,
+			 u_long        len )
+{
+    output_packet_header(call_fnc_get_created_texts);
+    fprintf(KS->out, " %lu %lu %lu\n",
+	    (u_long) pers_no,
+	    (u_long) first,
+	    (u_long) len);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_get_membership (Pers_no		  person,
+		       u_short		  first,
+		       u_short		  no_of_confs,
+		       Bool		  want_read_texts )
+{
+    output_packet_header(call_fnc_get_membership);
+    fprintf(KS->out, " %lu %lu %lu %lu\n",
+	    (u_long)person,
+	    (u_long)first,
+	    (u_long)no_of_confs,
+	    (u_long)want_read_texts);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_set_priv_bits (Pers_no	 person,
+		      Priv_bits  privileges )
+{
+    output_packet_header(call_fnc_set_priv_bits);
+    fprintf(KS->out, " %lu", (u_long) person);
+    output_priv_bits( KS->out, privileges );
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_set_passwd (Pers_no	  person,
+		   const String   old_pwd,
+		   const String   new_pwd )
+{
+    output_packet_header(call_fnc_set_passwd);
+    fprintf(KS->out, " %lu", (u_long) person);
+    output_string( KS->out, old_pwd );
+    output_string( KS->out, new_pwd );
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_query_read_texts (Pers_no	   pers_no,
+			 Conf_no	   conf_no)
+{
+    output_packet_header(call_fnc_query_read_texts);
+    fprintf(KS->out, " %lu %lu\n", (u_long) pers_no, (u_long) conf_no);
+    fflush(KS->out);
+}
+
+
+
+
+/****************************************
+*	Conference-related calls	*
+****************************************/
+
+
+extern  void
+output_create_conf (const String  name,
+		    Conf_type	  type )
+{
+    output_packet_header(call_fnc_create_conf);
+    output_string( KS->out, name );
+    output_conf_type( KS->out, type );
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_delete_conf (Conf_no	conf )
+{
+    output_packet_header(call_fnc_delete_conf);
+    fprintf(KS->out, " %lu\n", (u_long) conf);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_lookup_name (const String   name)
+{
+    output_packet_header(call_fnc_lookup_name);
+    output_string( KS->out, name );
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+
+
+extern  void
+output_get_conf_stat (Conf_no  conf_no)
+{
+    output_packet_header(call_fnc_get_conf_stat);
+    fprintf(KS->out, " %lu\n", (u_long) conf_no);
+    fflush(KS->out);
+}
+
+extern  void
+output_get_members (Conf_no	  conf,
+		    u_short	  first,
+		    u_short	  no_of_members)
+{
+    output_packet_header(call_fnc_get_members);
+    fprintf(KS->out, " %lu %lu %lu\n", (u_long) conf, (u_long) first,
+	    (u_long) no_of_members);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_add_member (Conf_no	conf_no,
+		   Pers_no	pers_no,
+		   u_char	priority,
+		   u_short	where	)
+{
+    output_packet_header(call_fnc_add_member);
+    fprintf(KS->out, " %lu %lu %lu %lu\n", (u_long) conf_no, (u_long) pers_no,
+	    (u_long) priority, (u_long) where);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_sub_member (Conf_no	conf_no,
+		   Pers_no	pers_no )
+{
+    output_packet_header(call_fnc_sub_member);
+    fprintf(KS->out, " %lu %lu\n", (u_long) conf_no, (u_long) pers_no);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_set_unread (Conf_no   conf_no,
+		   Text_no   no_of_unread)
+{
+    output_packet_header(call_fnc_set_unread);
+    fprintf(KS->out, " %lu %lu\n", (u_long) conf_no, (u_long) no_of_unread);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_set_presentation (Conf_no   conf_no,
+			 Text_no   text_no )
+{
+    output_packet_header(call_fnc_set_presentation);
+    fprintf(KS->out, " %lu %lu\n", (u_long) conf_no, (u_long) text_no);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_set_etc_motd (Conf_no	  conf_no,
+		     Text_no	  text_no )
+{
+    output_packet_header(call_fnc_set_etc_motd);
+    fprintf(KS->out, " %lu %lu\n", (u_long) conf_no, (u_long) text_no);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_set_supervisor (Conf_no	  conf_no,
+		       Conf_no	  admin	)
+{
+    output_packet_header(call_fnc_set_supervisor);
+    fprintf(KS->out, " %lu %lu\n", (u_long) conf_no, (u_long) admin);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_set_permitted_submitters (Conf_no  conf_no,
+				 Conf_no  perm_sub )
+{
+    output_packet_header(call_fnc_set_permitted_submitters);
+    fprintf(KS->out, " %lu %lu\n", (u_long) conf_no, (u_long) perm_sub);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_set_super_conf (Conf_no	  conf_no,
+		       Conf_no	  super_conf )
+{
+    output_packet_header(call_fnc_set_super_conf);
+    fprintf(KS->out, " %lu %lu\n", (u_long) conf_no, (u_long) super_conf);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_set_conf_type (Conf_no	 conf_no,
+		      Conf_type  type	)
+{
+    output_packet_header(call_fnc_set_conf_type);
+    fprintf(KS->out, " %lu", (u_long) conf_no);
+    output_conf_type(KS->out, type);
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_set_garb_nice (Conf_no	 conf_no,
+		      Garb_nice  nice	)
+{
+    output_packet_header(call_fnc_set_garb_nice);
+    fprintf(KS->out, " %lu %lu\n", (u_long) conf_no, (u_long) nice);
+    fflush(KS->out);
+}
+
+
+
+
+/********************************
+*     Calls to handle marks     *
+********************************/
+
+
+extern  void
+output_get_marks (void)
+{
+    output_packet_header(call_fnc_get_marks);
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+
+
+extern  void
+output_mark_text (Text_no  text,
+		  u_char   mark_type )
+{
+    output_packet_header(call_fnc_mark_text);
+    fprintf(KS->out, " %lu %lu\n", (u_long) text, (u_long) mark_type);
+    fflush(KS->out);
+}
+
+
+
+
+
+/*******************************
+*     Calls to handle texts    *
+*******************************/
+
+
+extern  void
+output_get_text (Text_no      text,
+		 String_size  start_char,
+		 String_size  end_char)
+{
+    output_packet_header(call_fnc_get_text);
+    fprintf(KS->out, " %lu %lu %lu\n", (u_long)text,
+	    (u_long)start_char, (u_long)end_char);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_get_text_stat (Text_no    text)
+{
+    output_packet_header(call_fnc_get_text_stat);
+    fprintf(KS->out, " %lu\n", (u_long)text);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_mark_as_read (Conf_no		    conference,
+		     int		    no_of_texts,
+		     const Local_text_no  * text_arr   )
+{
+    int i;
+    
+    output_packet_header(call_fnc_mark_as_read);
+    fprintf(KS->out, " %lu %lu", (u_long) conference, (u_long) no_of_texts);
+    fprintf(KS->out, " {");
+    for ( i = 0; i < no_of_texts; i++ )
+	fprintf(KS->out, " %lu", (u_long)text_arr[ i ]);
+    fprintf(KS->out, " }\n");
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_create_text (const String       message,
+		    u_short	       no_of_misc,
+		    const Misc_info  * misc	     )
+{
+    int i;
+    
+    output_packet_header(call_fnc_create_text);
+    output_string( KS->out, message );
+    fprintf(KS->out, " %lu {", (u_long)no_of_misc);
+    for ( i = 0; i < no_of_misc; i++ )
+	output_misc_info(KS->out, misc[ i ]);
+    fprintf(KS->out, " }\n");
+    fflush(KS->out);
+}
+
+extern  void
+output_create_anonymous_text (const String       message,
+			      u_short	       no_of_misc,
+			      const Misc_info  * misc	     )
+{
+    int i;
+    
+    output_packet_header(call_fnc_create_text);
+    output_string( KS->out, message );
+    fprintf(KS->out, " %lu {", (u_long)no_of_misc);
+    for ( i = 0; i < no_of_misc; i++ )
+	output_misc_info(KS->out, misc[ i ]);
+    fprintf(KS->out, " }\n");
+    fflush(KS->out);
+}
+
+
+extern void
+output_delete_text( Text_no text_no )
+{
+    output_packet_header(call_fnc_delete_text);
+    fprintf(KS->out, " %lu\n", (u_long) text_no);
+    fflush(KS->out);
+}
+
+
+
+
+extern  void
+output_add_recipient (Text_no	  text_no,
+		      Conf_no	  conf_no,
+		      Info_type  type	)
+{
+    output_packet_header(call_fnc_add_recipient);
+    fprintf(KS->out, " %lu %lu %lu\n", (u_long) text_no,
+	    (u_long) conf_no, (u_long) type);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_sub_recipient (Text_no	  text_no,
+		      Conf_no	  conf_no )
+{
+    output_packet_header(call_fnc_sub_recipient);
+    fprintf(KS->out, " %lu %lu\n", (u_long) text_no, (u_long) conf_no);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_add_comment (Text_no	  comment,
+		    Text_no 	  comment_to )
+{
+    output_packet_header(call_fnc_add_comment);
+    fprintf(KS->out, " %lu %lu\n", (u_long) comment, (u_long) comment_to);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_sub_comment (Text_no	  comment,
+		    Text_no	  comment_to )
+{
+    output_packet_header(call_fnc_sub_comment);
+    fprintf(KS->out, " %lu %lu\n", (u_long) comment, (u_long) comment_to);
+    fflush(KS->out);
+}
+
+extern  void
+output_add_footnote (Text_no	  footnote,
+		     Text_no 	  footnote_to )
+{
+    output_packet_header(call_fnc_add_footnote);
+    fprintf(KS->out, " %lu %lu\n", (u_long) footnote, (u_long) footnote_to);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_sub_footnote (Text_no	  footnote,
+		     Text_no	  footnote_to )
+{
+    output_packet_header(call_fnc_sub_footnote);
+    fprintf(KS->out, " %lu %lu\n", (u_long) footnote, (u_long) footnote_to);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_get_map (Conf_no	       conf_no,
+		Local_text_no  first_local_no,
+		Local_text_no  no_of_texts)
+{
+    output_packet_header(call_fnc_get_map);
+    fprintf(KS->out, " %lu %lu %lu\n", (u_long) conf_no,
+	    (u_long) first_local_no, (u_long) no_of_texts);
+    fflush(KS->out);
+}
+
+
+
+extern  void
+output_get_time ( void )
+{
+    output_packet_header(call_fnc_get_time);
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+extern  void
+output_who_is_on ( void )
+{
+    output_packet_header(call_fnc_who_is_on);
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+extern  void
+output_get_info ( void )
+{
+    output_packet_header(call_fnc_get_info);
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+extern void
+output_set_motd_of_lyskom (Text_no motd)
+{
+    output_packet_header(call_fnc_set_motd_of_lyskom);
+    fprintf(KS->out, " %lu\n", (u_long) motd);
+    fflush(KS->out);
+}
+
+
+extern void
+output_enable (u_char ena_level)
+{
+    output_packet_header(call_fnc_enable);
+    fprintf(KS->out, " %lu\n", (u_long) ena_level);
+    fflush(KS->out);
+}
+
+
+extern void
+output_sync (void) 
+{
+    output_packet_header(call_fnc_sync);
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+
+extern void
+output_shutdown (int exit_val) 
+{
+    output_packet_header(call_fnc_shutdown);
+    fprintf(KS->out, " %lu\n", (u_long) exit_val);
+    fflush(KS->out);
+}
+
+
+extern void
+output_broadcast (const String message) 
+{
+    output_packet_header(call_fnc_broadcast);
+    output_string(KS->out, message);
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+extern void
+output_send_message (Pers_no recipient,
+		     const String message) 
+{
+    output_packet_header(call_fnc_send_message);
+    fprintf(KS->out, " %lu\n", (u_long) recipient);
+    output_string(KS->out, message);
+    putc('\n', KS->out);
+    fflush(KS->out);
+}
+
+void
+output_get_unread_confs (Pers_no pers_no)
+{
+    output_packet_header(call_fnc_get_unread_confs);
+    fprintf(KS->out, " %lu\n", (u_long) pers_no);
+    fflush(KS->out);
+}
+
diff --git a/src/libraries/libclient/output.h b/src/libraries/libclient/output.h
new file mode 100644
index 0000000000000000000000000000000000000000..18d3c706afff2196147551883885fd6e2c71973a
--- /dev/null
+++ b/src/libraries/libclient/output.h
@@ -0,0 +1,299 @@
+/*
+ * $Id: output.h,v 1.1 1993/10/06 12:10:29 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+ * $Id: output.h,v 1.1 1993/10/06 12:10:29 linus Exp $
+ *
+ *  output.h  --  initiate call to client.
+ *
+ *  Created by ceder 1990-07-17
+ */
+
+#ifndef _OUTPUT_H_ALREADY_INCLUDED__
+#define _OUTPUT_H_ALREADY_INCLUDED__
+
+extern  void
+output_login_old (Pers_no	person,
+		  const String	passwd );
+
+extern  void
+output_login (Pers_no		person,
+	      const String	passwd,
+	      Bool		visible);
+
+
+extern  void
+output_logout (void);
+
+
+extern  void
+output_pepsi (Conf_no	conference );
+
+
+
+extern  void
+output_change_name (Conf_no       conf_no,
+		    const String  new_name);
+
+extern  void
+output_change_what_i_am_doing (const String  what_am_i_doing );
+
+
+
+/******************************
+*     Person-related calls    *
+******************************/
+
+/*
+ *  Create a new person.  Returns 0 if any error occured.
+ */
+extern  void
+output_create_person (const String  name,
+		      const String  passwd );
+
+extern  void
+output_get_person_stat (Pers_no	     person);
+
+extern  void
+output_get_created_texts(Pers_no       pers_no,
+			Local_text_no first,
+			u_long        len );
+
+extern  void
+output_get_membership (Pers_no		  person,
+		       u_short		  first,
+		       u_short		  no_of_confs,
+		       Bool		  want_read_texts );
+		       
+extern  void
+output_set_priv_bits (Pers_no	 person,
+		      Priv_bits  privileges );
+
+
+extern  void
+output_set_passwd (Pers_no	  person,
+		   const String   old_pwd,
+		   const String   new_pwd );
+
+extern  void
+output_query_read_texts (Pers_no	   pers_no,
+		     Conf_no	   conf_no);
+
+
+
+/****************************************
+*	Conference-related calls	*
+****************************************/
+
+
+extern  void
+output_create_conf (const String  name,
+		    Conf_type	  type );
+
+
+extern  void
+output_delete_conf (Conf_no	conf );
+
+
+extern  void
+output_lookup_name (const String   name);
+
+
+
+extern  void
+output_get_conf_stat (Conf_no		  conf_no);
+
+
+extern  void
+output_get_members (Conf_no	  conf,
+		    u_short	  first,
+		    u_short	  no_of_members);
+
+extern  void
+output_add_member (Conf_no	conf_no,
+		   Pers_no	pers_no,
+		   u_char	priority,
+		   u_short	where	);
+
+
+extern  void
+output_sub_member (Conf_no	conf_no,
+		   Pers_no	pers_no );
+
+
+extern  void
+output_set_unread (Conf_no   conf_no,
+		   Text_no   no_of_unread);
+
+extern  void
+output_set_presentation (Conf_no   conf_no,
+			 Text_no   text_no );
+
+extern  void
+output_set_etc_motd (Conf_no	  conf_no,
+		     Text_no	  text_no );
+
+
+extern  void
+output_set_supervisor (Conf_no	  conf_no,
+		       Conf_no	  admin	);
+
+extern  void
+output_set_permitted_submitters (Conf_no  conf_no,
+				 Conf_no  perm_sub );
+
+extern  void
+output_set_super_conf (Conf_no	  conf_no,
+		       Conf_no	  super_conf );
+
+extern  void
+output_set_conf_type (Conf_no	 conf_no,
+		      Conf_type  type	);
+
+extern  void
+output_set_garb_nice (Conf_no	 conf_no,
+		      Garb_nice  nice	);
+
+
+
+/********************************
+*     Calls to handle marks     *
+********************************/
+
+
+extern  void
+output_get_marks (void);
+
+
+
+extern  void
+output_mark_text (Text_no  text,
+		  u_char   mark_type );
+
+
+
+
+/*******************************
+*     Calls to handle texts    *
+*******************************/
+
+
+extern  void
+output_get_text (Text_no      text,
+		 String_size  start_char,
+		 String_size  end_char);
+
+
+extern  void
+output_get_text_stat (Text_no    text);
+
+extern  void
+output_mark_as_read (Conf_no		    conference,
+		     int		    no_of_texts,
+		     const Local_text_no  * text_arr   );
+
+
+extern  void
+output_create_text (const String       message,
+		    u_short	       no_of_misc,
+		    const Misc_info  * misc	     );
+
+extern  void
+output_create_anonymous_text (const String       message,
+			      u_short	       no_of_misc,
+			      const Misc_info  * misc	     );
+
+extern void
+output_delete_text( Text_no text_no );
+
+
+
+extern  void
+output_add_recipient (Text_no	  text_no,
+		      Conf_no	  conf_no,
+		      Info_type  type	);
+
+extern  void
+output_sub_recipient (Text_no	  text_no,
+		      Conf_no	  conf_no );
+
+
+extern  void
+output_add_comment (Text_no	  comment,
+		    Text_no 	  comment_to );
+
+
+extern  void
+output_sub_comment (Text_no	  comment,
+		    Text_no	  comment_to );
+
+
+extern  void
+output_add_footnote (Text_no	  footnote,
+		     Text_no 	  footnote_to );
+
+
+extern  void
+output_sub_footnote (Text_no	  footnote,
+		     Text_no	  footnote_to );
+
+extern  void
+output_get_map (Conf_no	       conf_no,
+		Local_text_no  first_local_no,
+		Local_text_no  no_of_texts);
+
+
+extern  void
+output_get_time ( void );
+
+extern  void
+output_who_is_on ( void );
+
+extern  void
+output_get_info ( void );
+
+
+extern void
+output_set_motd_of_lyskom (Text_no motd);
+
+extern void
+output_enable (u_char ena_level);
+
+extern void
+output_sync (void);
+
+extern void
+output_shutdown (int exit_val);
+
+extern void
+output_broadcast (const String message);
+
+extern void
+output_send_message (Pers_no recipient,
+		     const String message);
+
+void
+output_get_unread_confs (Pers_no pers_no);
+
+#endif	/*  _OUTPUT_H_ALREADY_INCLUDED__  */
diff --git a/src/libraries/libclient/parse.c b/src/libraries/libclient/parse.c
new file mode 100644
index 0000000000000000000000000000000000000000..92b306fc43b80ad0663b3cf84a938b1c2c0ba6fc
--- /dev/null
+++ b/src/libraries/libclient/parse.c
@@ -0,0 +1,1052 @@
+/*
+ * $Id: parse.c,v 1.1 1993/10/06 12:10:35 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+ * parse.c  -  receive objects from an isc connection.
+ *
+ * Written by ceder 1990-07-13
+ */
+
+static char *rcsid = "$Id: parse.c,v 1.1 1993/10/06 12:10:35 linus Exp $";
+
+/*
+ * KNOWN BUGS: Does not read in the array when returning KOM_SERVER_NO_MEM.
+ *	       Thus the client will be out of sync after that error.
+ * SOLUTION:   Use skip_token from parse-async.c (not yet written).
+ */
+/* Error checking is poor. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+/* #include <time.h> included from kom-types.h */
+
+#include <kom-types.h>
+#include <kom-errno.h>
+#include <services.h>
+
+#include "client-malloc.h"
+#include "parse.h"
+#include "async.h"
+
+
+#define REALLOC(ptr, size)	(((ptr) == NULL) ?		\
+					  isc_malloc (size)		\
+					: isc_realloc ((ptr), (size)))
+
+
+/* +++ Should have some error checking here. */
+
+u_long
+parse_long(FILE *fp)
+{
+    u_long res=0;
+
+    fscanf(fp, " %lu", &res);
+    return res;
+}
+
+
+void
+skipwhite(FILE *fp)
+{
+    int c;
+
+    while ( isspace(c = getc(fp)) )
+	;
+
+    ungetc(c, fp);
+}
+
+
+Success
+parse_person (FILE *fp,
+	      Person *person)
+{
+    if ( parse_string(fp, &person->username) != OK
+	|| parse_priv_bits (fp, &person->privileges) != OK
+	|| parse_personal_flags (fp, &person->flags) != OK )
+    {
+	return FAILURE;
+    }
+
+    parse_time(fp, &person -> last_login);
+
+    person -> user_area		= parse_long(fp);
+    person -> total_time_present = parse_long(fp);
+    person -> sessions		= parse_long(fp);
+    person -> created_lines	= parse_long(fp);
+    person -> created_bytes	= parse_long(fp);
+    person -> read_texts	= parse_long(fp);
+    person -> no_of_text_fetches = parse_long(fp);
+    person -> created_persons	= parse_long(fp);
+    person -> created_confs	= parse_long(fp);
+    person -> first_created_text = parse_long (fp);
+    person -> no_of_created_texts = parse_long (fp);
+    person -> no_of_marks	= parse_long (fp);
+    person -> no_of_confs	= parse_long (fp);
+
+    return OK;
+}
+
+Success
+parse_membership(FILE *fp,
+		 Membership *mship)
+{
+    int i;
+
+    parse_time(fp, &mship->last_time_read);
+    
+    mship->conf_no = parse_long(fp);
+    mship->priority = parse_long(fp);
+    mship->last_text_read = parse_long(fp);
+    mship->no_of_read = parse_long(fp);
+
+    if ( mship->no_of_read > 0)
+    {
+	skipwhite(fp);
+	switch(getc(fp))
+	{
+	case '{':
+	    mship->read_texts = REALLOC(mship->read_texts,
+					(mship->no_of_read
+					 * sizeof(Local_text_no)));
+	    
+	    if ( mship->read_texts == NULL )
+	    {
+		kom_errno = KOM_OUT_OF_MEMORY;
+		return FAILURE;
+	    }
+
+	    for ( i = 0; i < mship->no_of_read; i++)
+		mship->read_texts[ i ] = parse_long(fp);
+
+	    skipwhite(fp);
+	    if ( getc(fp) != '}' )
+	    {
+		kom_errno = KOM_SERVER_IS_CRAZY;
+		return FAILURE;
+	    }
+	    break;
+	    
+	case '*':
+	    isc_free(mship->read_texts);
+	    mship->read_texts = NULL;
+	    break;
+	    
+	default:
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+    }
+    else
+    {
+	skipwhite(fp);
+	if ( getc(fp) != '*' ) 
+	{
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+
+	isc_free(mship->read_texts);
+	mship->read_texts = NULL;
+    }
+
+    return OK;
+}
+
+	
+extern Success
+parse_membership_list(FILE *fp,
+		      Membership_list *result)
+{
+    int i;
+
+    /* First free all the read_texts. */
+
+    if ( result->confs != NULL )
+    {
+	for ( i = 0; i < result->no_of_confs; i++)
+	    isc_free(result->confs[ i ].read_texts);
+    }
+    
+    result->no_of_confs = parse_long(fp);
+
+    if ( result->no_of_confs > 0 )
+    {
+	skipwhite(fp);
+	switch(getc(fp))
+	{
+	case '{':
+	    result->confs = REALLOC(result->confs,
+				    (result->no_of_confs
+				     * sizeof(Membership)));
+	    if ( result->confs == NULL )
+	    {
+		kom_errno = KOM_OUT_OF_MEMORY;
+		return FAILURE;
+	    }
+
+	    for ( i = 0; i < result->no_of_confs; i++)
+	    {
+		result->confs[ i ] = EMPTY_MEMBERSHIP;
+		if ( parse_membership(fp, &result->confs[i]) != OK )
+		    return FAILURE;
+	    }
+	    
+	    skipwhite(fp);
+	    if ( getc(fp) != '}' )
+	    {
+		kom_errno = KOM_SERVER_IS_CRAZY;
+		return FAILURE;
+	    }
+	    
+	    break;
+	case '*':
+	    if ( result->confs != NULL )
+	    {
+		isc_free(result->confs);
+		result->confs = NULL;
+	    }
+	    break;
+	default:
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+    }
+    else
+    {
+	skipwhite(fp);
+	if ( getc(fp) != '*' ) 
+	{
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+	if ( result->confs != NULL )
+	{
+	    isc_free(result->confs);
+	    result->confs = NULL;
+	}
+    }
+    return OK;
+}
+
+
+extern Success
+parse_conf_list(FILE *fp,
+		Conf_list *result)
+{
+    int i;
+
+    result->no_of_confs = parse_long(fp);
+    if ( result->no_of_confs > 0 )
+    {
+	skipwhite(fp);
+	switch(getc(fp))
+	{
+	case '{':
+	    result->confs = REALLOC(result->confs,
+				    (result->no_of_confs
+				     * sizeof(Micro_conf)));
+	    if ( result->confs == NULL )
+	    {
+		kom_errno = KOM_OUT_OF_MEMORY;
+		return FAILURE;
+	    }
+	    
+	    for ( i = 0; i < result->no_of_confs; i++)
+		result->confs[ i ].conf_no = parse_long(fp);
+	    
+	    skipwhite(fp);
+	    if ( getc(fp) != '}' )
+	    {
+		kom_errno = KOM_SERVER_IS_CRAZY;
+		return FAILURE;
+	    }
+	    
+	    break;
+	case '*':
+	    if ( result->confs != NULL )
+	    {
+		isc_free(result->confs);
+		result->confs = NULL;
+	    }
+	    break;
+	default:
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+    }
+    else
+    {
+	skipwhite(fp);
+	if ( getc(fp) != '*' ) 
+	{
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+	if ( result->confs != NULL )
+	{
+	    isc_free(result->confs);
+	    result->confs = NULL;
+	}
+    }
+
+    if ( result->no_of_confs > 0 )
+    {
+	skipwhite(fp);
+	switch(getc(fp))
+	{
+	case '{':
+	    if ( result->confs == NULL )
+	    {			/* Always both conf_no and conf_type,
+				   nicht wahr? */
+		kom_errno = KOM_SERVER_IS_CRAZY;
+		return FAILURE;
+	    }
+	    
+	    for ( i = 0; i < result->no_of_confs; i++)
+		if ( parse_conf_type(fp, &result->confs[i].type) != OK )
+		{
+		    return FAILURE;
+		}
+	    
+	    skipwhite(fp);
+	    if ( getc(fp) != '}' )
+	    {
+		kom_errno = KOM_SERVER_IS_CRAZY;
+		return FAILURE;
+	    }
+	    
+	    break;
+	case '*':
+	    if ( result->confs != NULL )
+	    {
+		isc_free(result->confs);
+		kom_errno = KOM_SERVER_IS_CRAZY;
+		return FAILURE;
+	    }
+	    break;
+	default:
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+    }
+    else
+    {
+	skipwhite(fp);
+	if ( getc(fp) != '*' ) 
+	{
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+	if ( result->confs != NULL )
+	{
+	    isc_free(result->confs);
+	    result->confs = NULL;
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+    }
+    return OK;
+}
+
+extern Success
+parse_conference(FILE *fp,
+		 Conference *result)
+{
+    if ( parse_string(fp, &result->name) != OK
+	|| parse_conf_type(fp, &result->type) != OK)
+    {
+	return FAILURE;
+    }
+    
+    parse_time (fp, &result -> creation_time);
+    parse_time (fp, &result -> last_written );
+
+    result -> creator		= parse_long (fp);
+    result -> presentation	= parse_long (fp);
+    result -> supervisor	= parse_long (fp);
+    result -> permitted_submitters = parse_long (fp);
+    result -> super_conf	= parse_long (fp);
+    result -> msg_of_day	= parse_long (fp);
+    result -> nice		= parse_long (fp);
+    result -> no_of_members	= parse_long (fp);
+    result -> first_local_no	= parse_long (fp);
+    result -> no_of_texts	= parse_long (fp);
+
+    return OK;
+}
+
+extern Success
+parse_mark_list(FILE *fp,
+		Mark_list *result)
+{
+    int i;
+
+    result->no_of_marks = parse_long(fp);
+
+    if ( result->no_of_marks > 0 )
+    {
+	skipwhite(fp);
+	switch(getc(fp))
+	{
+	case '{':
+	    result->marks = REALLOC(result->marks,
+				    (result->no_of_marks
+				     * sizeof(Mark)));
+
+	    if ( result->marks == NULL )
+	    {
+		kom_errno = KOM_OUT_OF_MEMORY;
+		return FAILURE;
+	    }
+	    
+	    for ( i = 0; i < result->no_of_marks; i++)
+		if ( parse_mark(fp, &result->marks[ i ] ) != OK )
+		{
+		    return FAILURE;
+		}
+	    
+	    skipwhite(fp);
+	    if ( getc(fp) != '}' )
+	    {
+		kom_errno = KOM_SERVER_IS_CRAZY;
+		return FAILURE;
+	    }
+	    
+	    break;
+
+	case '*':
+	    if ( result->marks != NULL )
+	    {
+		isc_free(result->marks);
+		result->marks = NULL;
+	    }
+	    break;
+
+	default:
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+    }
+    else
+    {
+	skipwhite(fp);
+	if ( getc(fp) != '*' ) 
+	{
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+	if ( result->marks != NULL )
+	{
+	    isc_free(result->marks);
+	    result->marks = NULL;
+	}
+    }
+    return OK;
+}
+
+
+extern Success
+parse_text_stat(FILE *fp,
+		Text_stat *result)
+{
+    int i;
+
+    parse_time(fp, &result->creation_time);
+
+    result->author = parse_long(fp);
+    result->no_of_lines = parse_long(fp);
+    result->no_of_chars = parse_long(fp);
+    result->no_of_marks = parse_long(fp);
+    result->no_of_misc = parse_long(fp);
+
+    if ( result->no_of_misc > 0 )
+    {
+	skipwhite(fp);
+	switch(getc(fp))
+	{
+	case '{':
+	    result->misc_items = REALLOC(result->misc_items,
+				    (result->no_of_misc
+				     * sizeof(Misc_info)));
+
+	    if ( result->misc_items == NULL )
+	    {
+		kom_errno = KOM_OUT_OF_MEMORY;
+		return FAILURE;
+	    }
+	    
+	    for ( i = 0; i < result->no_of_misc; i++)
+		if ( parse_misc_info(fp, &result->misc_items[ i ]) != OK )
+		{
+		    return FAILURE;
+		}
+	    
+	    skipwhite(fp);
+	    if ( getc(fp) != '}' )
+	    {
+		kom_errno = KOM_SERVER_IS_CRAZY;
+		return FAILURE;
+	    }
+	    
+	    break;
+
+	case '*':
+	    if ( result->misc_items != NULL )
+	    {
+		isc_free(result->misc_items);
+		result->misc_items = NULL;
+	    }
+	    break;
+
+	default:
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+    }
+    else
+    {
+	skipwhite(fp);
+	if ( getc(fp) != '*' ) 
+	{
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+	if ( result->misc_items != NULL )
+	{
+	    isc_free(result->misc_items);
+	    result->misc_items = NULL;
+	}
+    }
+    return OK;
+}	
+
+
+extern Success
+parse_text_list(FILE *fp,
+		Text_list *result)
+{
+    int i;
+
+    result->first_local_no = parse_long(fp);
+    result->no_of_texts = parse_long(fp);
+
+    if ( result->no_of_texts > 0 )
+    {
+	skipwhite(fp);
+	switch(getc(fp))
+	{
+	case '{':
+	    result->texts = REALLOC(result->texts,
+				    (result->no_of_texts
+				     * sizeof(Text_no)));
+
+	    if ( result->texts == NULL )
+	    {
+		kom_errno = KOM_OUT_OF_MEMORY;
+		return FAILURE;
+	    }
+	    
+	    for ( i = 0; i < result->no_of_texts; i++)
+		result->texts[ i ] = parse_long(fp);
+	    
+	    skipwhite(fp);
+	    if ( getc(fp) != '}' )
+	    {
+		kom_errno = KOM_SERVER_IS_CRAZY;
+		return FAILURE;
+	    }
+	    
+	    break;
+
+	case '*':
+	    if ( result->texts != NULL )
+	    {
+		isc_free(result->texts);
+		result->texts = NULL;
+	    }
+	    break;
+
+	default:
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+    }
+    else
+    {
+	skipwhite(fp);
+	if ( getc(fp) != '*' ) 
+	{
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+	if ( result->texts != NULL )
+	{
+	    isc_free(result->texts);
+	    result->texts = NULL;
+	}
+    }
+    return OK;
+}
+    
+
+extern Success
+parse_info(FILE *fp,
+	   Info *result)
+{
+    result->version = parse_long(fp);
+    result->conf_pres_conf = parse_long(fp);
+    result->pers_pres_conf = parse_long(fp);
+    result->motd_conf = parse_long(fp);
+    result->kom_news_conf = parse_long(fp);
+    result->motd_of_lyskom = parse_long(fp);
+    return OK;
+}
+
+
+extern Success
+parse_string(FILE *fp,
+	     String *result)
+{
+    String_size i;
+    int c;
+    
+    result->len = parse_long(fp);
+
+    if ( getc(fp) != 'H' )
+    {
+	kom_errno = KOM_SERVER_IS_CRAZY;
+	return FAILURE;
+    }
+
+    result->string = REALLOC(result->string, result->len);
+
+    if ( result->string == NULL )
+    {
+	kom_errno = KOM_OUT_OF_MEMORY;
+	return FAILURE;
+    }
+    
+    for ( i = 0; i < result->len; i++ )
+    {
+	if ( (c=getc(fp)) == EOF )
+	{
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+	result->string[ i ] = c;
+    }
+    
+
+    return OK;
+}
+
+
+extern Success
+parse_member_list(FILE *fp,
+		  Member_list *result)
+{
+    int i;
+
+    result->no_of_members = parse_long(fp);
+    if ( result->no_of_members > 0 )
+    {
+	skipwhite(fp);
+	switch(getc(fp))
+	{
+	case '{':
+	    result->members = REALLOC(result->members,
+				      (result->no_of_members
+				       * sizeof(Member)));
+
+	    if ( result->members == NULL )
+	    {
+		kom_errno = KOM_OUT_OF_MEMORY;
+		return FAILURE;
+	    }
+	    
+	    for ( i = 0; i < result->no_of_members; i++)
+		if ( parse_member(fp, &result->members[ i ]) != OK )
+		{
+		    return FAILURE;
+		}
+	    
+	    
+	    skipwhite(fp);
+	    if ( getc(fp) != '}' )
+	    {
+		kom_errno = KOM_SERVER_IS_CRAZY;
+		return FAILURE;
+	    }
+	    
+	    break;
+
+	case '*':
+	    if ( result->members != NULL )
+	    {
+		isc_free(result->members);
+		result->members = NULL;
+	    }
+	    break;
+
+	default:
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+    }
+    else
+    {
+	skipwhite(fp);
+	if ( getc(fp) != '*' ) 
+	{
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+	if ( result->members != NULL )
+	{
+	    isc_free(result->members);
+	    result->members = NULL;
+	}
+    }
+    return OK;
+}
+
+
+extern Success
+parse_member(FILE *fp,
+	     Member *result)
+{
+    result->member = parse_long(fp);
+    return OK;
+}
+
+extern Success
+parse_mark(FILE *fp,
+	   Mark *result)
+{
+    result->text_no = parse_long(fp);
+    result->mark_type = parse_long(fp);
+    return OK;
+}
+
+extern Success
+parse_misc_info(FILE *fp, 
+		Misc_info *result)
+{
+    result->type = parse_long(fp);
+    
+    switch(result->type)
+    {
+    case recpt:
+	result->datum.recipient = parse_long(fp);
+	break;
+	
+    case cc_recpt:
+	result->datum.cc_recipient = parse_long(fp);
+	break;
+	
+    case loc_no:
+	result->datum.local_no = parse_long(fp);
+	break;
+	
+    case rec_time:
+	parse_time(fp, &result->datum.received_at);
+	break;
+	
+    case comm_to:
+	result->datum.comment_to = parse_long(fp);
+	break;
+	
+    case comm_in:
+	result->datum.commented_in = parse_long(fp);
+	break;
+	
+    case footn_to:
+	result->datum.footnote_to = parse_long(fp);
+	break;
+	
+    case footn_in:
+	result->datum.footnoted_in = parse_long(fp);
+	break;
+	
+    case sent_by:
+	result->datum.sender = parse_long(fp);
+	break;
+	
+    case sent_at:
+	parse_time(fp, &result->datum.sent_at);
+	break;
+
+    default:
+	fprintf(stderr, "parse_misc_info: Illegal misc\n");
+	fflush(stdout);
+	fflush(stderr);
+	abort();
+    }
+    return OK;
+}
+
+extern Success
+parse_priv_bits(FILE *fp,
+		Priv_bits *result)
+{
+    skipwhite(fp);
+
+    result->wheel = getc(fp) != '0';
+    result->admin = getc(fp) != '0';
+    result->statistic = getc(fp) != '0';
+    result->create_pers = getc(fp) != '0';
+    result->create_conf = getc(fp) != '0';
+    result->change_name = getc(fp) != '0';
+    result->extern_gw = getc(fp) != '0';
+    result->flg8 = getc(fp) != '0';
+    result->flg9 = getc(fp) != '0';
+    result->flg10 = getc(fp) != '0';
+    result->flg11 = getc(fp) != '0';
+    result->flg12 = getc(fp) != '0';
+    result->flg13 = getc(fp) != '0';
+    result->flg14 = getc(fp) != '0';
+    result->flg15 = getc(fp) != '0';
+    result->flg16 = getc(fp) != '0';
+
+    return OK;
+}
+
+
+extern Success
+parse_personal_flags(FILE *fp,
+		     Personal_flags *result)
+{
+    skipwhite(fp);
+    
+    result->unread_is_secret = getc(fp) != '0';
+    result->flg2 = getc(fp) != '0';
+    result->flg3 = getc(fp) != '0';
+    result->flg4 = getc(fp) != '0';
+    result->flg5 = getc(fp) != '0';
+    result->flg6 = getc(fp) != '0';
+    result->flg7 = getc(fp) != '0';
+    result->flg8 = getc(fp) != '0';
+
+    return OK;
+}	
+
+extern Success
+parse_conf_type(FILE *fp,
+		Conf_type *result)
+{
+    skipwhite(fp);
+    
+    result->rd_prot = getc(fp) != '0';
+    result->original = getc(fp) != '0';
+    result->secret = getc(fp) != '0';
+    result->letter_box = getc(fp) != '0';
+
+    return OK;
+}
+
+
+extern Success
+parse_who_info(FILE *fp,
+	       Who_info *result)
+{
+    result->person = parse_long(fp);
+    result->working_conference = parse_long(fp);
+    result->session_no = parse_long(fp);
+    
+    if ( parse_string(fp, &result->what_am_i_doing) != OK
+	|| parse_string(fp, &result->username) != OK )
+    {
+	kom_errno = KOM_SERVER_IS_CRAZY;
+	return FAILURE;
+    }
+
+    return OK;
+}
+
+    
+extern Success
+parse_who_info_list(FILE *fp,
+		     Who_info_list *result)
+{
+    int i;
+    
+    skipwhite(fp);
+
+    result->no_of_persons = parse_long(fp);
+    
+    if ( result->no_of_persons > 0 )
+    {
+	skipwhite(fp);
+	switch(getc(fp))
+	{
+	case '{':
+	    result->info = REALLOC(result->info,
+				   (result->no_of_persons
+				    * sizeof(Who_info)));
+
+	    if ( result->info == NULL )
+	    {
+		kom_errno = KOM_OUT_OF_MEMORY;
+		return FAILURE;
+	    }
+	    
+	    for ( i = 0; i < result->no_of_persons; i++)
+	    {
+		result->info[ i ] = EMPTY_WHO_INFO;
+		if ( parse_who_info(fp, &result->info[ i ]) != OK )
+		    return FAILURE;
+	    }
+	    
+	    
+	    skipwhite(fp);
+	    if ( getc(fp) != '}' )
+	    {
+		kom_errno = KOM_SERVER_IS_CRAZY;
+		return FAILURE;
+	    }
+	    
+	    break;
+
+	case '*':
+	    if ( result->info != NULL )
+	    {
+		isc_free(result->info);
+		result->info = NULL;
+	    }
+	    break;
+
+	default:
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+    }
+    else
+    {
+	skipwhite(fp);
+	if ( getc(fp) != '*' ) 
+	{
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+	if ( result->info != NULL )
+	{
+	    isc_free(result->info);
+	    result->info = NULL;
+	}
+    }
+    return OK;
+}
+    
+extern Success
+parse_conf_no_list(FILE *fp,
+		   Conf_no_list *result)
+{
+    int i;
+    
+    skipwhite(fp);
+
+    result->no_of_confs = parse_long(fp);
+    
+    if ( result->no_of_confs > 0 )
+    {
+	skipwhite(fp);
+	switch(getc(fp))
+	{
+	case '{':
+	    result->conf_nos = REALLOC(result->conf_nos,
+				       (result->no_of_confs
+					* sizeof(Conf_no)));
+
+	    if ( result->conf_nos == NULL )
+	    {
+		kom_errno = KOM_OUT_OF_MEMORY;
+		return FAILURE;
+	    }
+	    
+	    for ( i = 0; i < result->no_of_confs; i++)
+	    {
+		result->conf_nos[ i ] = parse_long(fp);
+	    }
+	    
+	    skipwhite(fp);
+	    if ( getc(fp) != '}' )
+	    {
+		kom_errno = KOM_SERVER_IS_CRAZY;
+		return FAILURE;
+	    }
+	    
+	    break;
+
+	case '*':
+	    if ( result->conf_nos != NULL )
+	    {
+		isc_free(result->conf_nos);
+		result->conf_nos = NULL;
+	    }
+	    break;
+
+	default:
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+    }
+    else
+    {
+	skipwhite(fp);
+	if ( getc(fp) != '*' ) 
+	{
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+	if ( result->conf_nos != NULL )
+	{
+	    isc_free(result->conf_nos);
+	    result->conf_nos = NULL;
+	}
+    }
+    return OK;
+}
+
+extern Success
+parse_time(FILE *fp, struct tm *timeptr)
+{
+    timeptr->tm_sec = parse_long(fp);
+    timeptr->tm_min = parse_long(fp);
+    timeptr->tm_hour = parse_long(fp);
+    timeptr->tm_mday = parse_long(fp);
+    timeptr->tm_mon = parse_long(fp);
+    timeptr->tm_year = parse_long(fp);
+    timeptr->tm_wday = parse_long(fp);
+    timeptr->tm_yday = parse_long(fp);
+    timeptr->tm_isdst = parse_long(fp);
+
+    return OK;
+}
diff --git a/src/libraries/libclient/parse.h b/src/libraries/libclient/parse.h
new file mode 100644
index 0000000000000000000000000000000000000000..8773229e69c40a7af3a09c445ef5c44d78a7c3d8
--- /dev/null
+++ b/src/libraries/libclient/parse.h
@@ -0,0 +1,131 @@
+/*
+ * $Id: parse.h,v 1.1 1993/10/06 12:10:41 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+ * $Id: parse.h,v 1.1 1993/10/06 12:10:41 linus Exp $
+ *
+ * parse.h  -  parse objects from an isc connection.
+ *
+ * Written by ceder 1990-07-13
+ */
+/* BUGS: Return values from realloc are not checked. */
+/* 	 %lu ain't always correct.	*/
+
+extern u_long
+parse_long(FILE *fp);
+
+extern Success
+parse_time(FILE *fp, struct tm *timeptr);
+
+extern void
+skipwhite(FILE *fp);
+
+
+extern Success
+parse_person(FILE *fp,
+	     Person *person);
+
+
+extern Success
+parse_membership(FILE *fp,
+		 Membership *mship);
+
+
+extern Success
+parse_membership_list(FILE *fp,
+		      Membership_list *result);
+
+
+extern Success
+parse_conf_list(FILE *fp,
+		Conf_list *result);
+
+
+extern Success
+parse_conference(FILE *fp,
+		 Conference *result);
+
+
+extern Success
+parse_mark_list(FILE *fp,
+		Mark_list *result);
+
+extern Success
+parse_text_stat(FILE *fp,
+		Text_stat *result);
+
+extern Success
+parse_text_list(FILE *fp,
+		Text_list *result);
+
+extern Success
+parse_info(FILE *fp,
+	   Info *result);
+
+extern Success 
+parse_string(FILE *fp,
+	     String *result);
+
+
+extern Success
+parse_member_list(FILE *fp,
+		  Member_list *result);
+
+extern Success
+parse_member(FILE *fp,
+	     Member *result);
+
+extern Success
+parse_mark(FILE *fp,
+	   Mark *result);
+
+
+extern Success
+parse_misc_info(FILE *fp,
+		Misc_info *result);
+
+
+extern Success
+parse_priv_bits(FILE *fp,
+		Priv_bits *result);
+
+extern Success
+parse_personal_flags(FILE *fp,
+		     Personal_flags *result);
+
+extern Success
+parse_conf_type(FILE *fp,
+		Conf_type *result);
+
+extern Success
+parse_who_info_list(FILE *fp,
+		    Who_info_list *result);
+
+extern Success
+parse_conf_no_list(FILE *fp,
+		   Conf_no_list *result);
+
+extern Success
+parse_who_info(FILE *fp,
+	       Who_info *result);
diff --git a/src/libraries/libclient/send.c b/src/libraries/libclient/send.c
new file mode 100644
index 0000000000000000000000000000000000000000..b648ab89bdaf4a56c0f51c5b895ed8d6ca43c4ea
--- /dev/null
+++ b/src/libraries/libclient/send.c
@@ -0,0 +1,168 @@
+/*
+ * $Id: send.c,v 1.1 1993/10/06 12:10:46 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+ * send.c  -  write objects throug an isc connection.
+ *
+ * Written by ceder 1990-07-13
+ */
+
+static char *rcsid = "$Id: send.c,v 1.1 1993/10/06 12:10:46 linus Exp $";
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <sys/types.h>
+#include <sys/file.h>
+#include <unistd.h>
+
+#include <kom-types.h>
+
+#include "send.h"
+
+extern void
+output_string(FILE *fp,
+	      String str)
+{
+    fprintf(fp, " %luH", (u_long)str.len);
+    fflush(fp);
+    write(fileno(fp), str.string, str.len);
+}
+
+
+extern void
+output_priv_bits(FILE *fp,
+		 Priv_bits bits)
+{
+    putc(' ', fp);
+    putc(bits.wheel + '0', fp);
+    putc(bits.admin + '0', fp);
+    putc(bits.statistic + '0', fp);
+    putc(bits.create_pers + '0', fp);
+    putc(bits.create_conf + '0', fp);
+    putc(bits.change_name + '0', fp);
+    putc(bits.extern_gw + '0', fp);
+    putc(bits.flg8 + '0', fp);
+    putc(bits.flg9 + '0', fp);
+    putc(bits.flg10 + '0', fp);
+    putc(bits.flg11 + '0', fp);
+    putc(bits.flg12 + '0', fp);
+    putc(bits.flg13 + '0', fp);
+    putc(bits.flg14 + '0', fp);
+    putc(bits.flg15 + '0', fp);
+    putc(bits.flg16 + '0', fp);
+}
+
+
+extern void
+output_personal_flags(FILE *fp,
+		      Personal_flags flags)
+{
+    putc(' ', fp);
+    putc(flags.unread_is_secret + '0', fp);
+    putc(flags.flg2 + '0', fp);
+    putc(flags.flg3 + '0', fp);
+    putc(flags.flg4 + '0', fp);
+    putc(flags.flg5 + '0', fp);
+    putc(flags.flg6 + '0', fp);
+    putc(flags.flg7 + '0', fp);
+    putc(flags.flg8 + '0', fp);
+}	
+
+extern void
+output_conf_type(FILE *fp,
+		 Conf_type type)
+{
+    putc(' ', fp);
+    putc(type.rd_prot + '0', fp);
+    putc(type.original + '0', fp);
+    putc(type.secret + '0', fp);
+    putc(type.letter_box + '0', fp);
+}
+
+
+
+extern void
+output_misc_info(FILE *fp, 
+		 Misc_info misc)
+{
+    fprintf(fp, " %lu", (u_long)misc.type);
+    
+    switch(misc.type)
+    {
+    case recpt:
+	fprintf(fp, " %lu", (u_long)misc.datum.recipient);
+	break;
+	
+    case cc_recpt:
+	fprintf(fp, " %lu", (u_long)misc.datum.cc_recipient);
+	break;
+	
+    case loc_no:
+	fprintf(fp, " %lu", (u_long)misc.datum.local_no);
+	break;
+	
+    case rec_time:
+	fprintf(stderr, "Internal error in LysKOM-klient: output_misc_info(): can't send a rec_time.\n");
+	abort();
+	break;
+	
+    case comm_to:
+	fprintf(fp, " %lu", (u_long)misc.datum.comment_to);
+	break;
+	
+    case comm_in:
+	fprintf(fp, " %lu", (u_long)misc.datum.commented_in);
+	break;
+	
+    case footn_to:
+	fprintf(fp, " %lu", (u_long)misc.datum.footnote_to);
+	break;
+	
+    case footn_in:
+	fprintf(fp, " %lu", (u_long)misc.datum.footnoted_in);
+	break;
+	
+    case sent_by:
+	fprintf(fp, " %lu", (u_long)misc.datum.sender);
+	break;
+	
+    case sent_at:
+	fprintf(stderr, "Internal error in LysKOM-klient: output_misc_info(): can't send a sent_at.\n");
+	abort();
+	break;
+
+    default:
+#ifdef CLIENT
+	fprintf(stderr, "output_misc_info: Illegal misc\n");
+	fflush(stdout);
+	fflush(stderr);
+	abort();
+#else
+	restart_kom("output_misc_info: Illegal misc\n");
+#endif
+    }
+}
+
diff --git a/src/libraries/libclient/send.h b/src/libraries/libclient/send.h
new file mode 100644
index 0000000000000000000000000000000000000000..3dfca551838c8bab39fad47c9d147709c8b88689
--- /dev/null
+++ b/src/libraries/libclient/send.h
@@ -0,0 +1,52 @@
+/*
+ * $Id: send.h,v 1.1 1993/10/06 12:10:51 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+ * $Id: send.h,v 1.1 1993/10/06 12:10:51 linus Exp $
+ *
+ * output.h  -  write objects throug an isc connection.
+ *
+ * Written by ceder 1990-07-13
+ */
+
+
+extern void
+output_string(FILE *fp,
+	      String str);
+
+extern void
+output_priv_bits(FILE *fp,
+		 Priv_bits bits);
+
+extern void
+output_personal_flags(FILE *fp,
+		      Personal_flags flags);
+extern void
+output_conf_type(FILE *fp,
+		 Conf_type type);
+
+
+extern void
+output_misc_info(FILE *fp, 
+		 Misc_info misc);
diff --git a/src/libraries/libclient/services.c b/src/libraries/libclient/services.c
new file mode 100644
index 0000000000000000000000000000000000000000..9f9a8e19bf4263dc71499d778666c0f6fc46bc54
--- /dev/null
+++ b/src/libraries/libclient/services.c
@@ -0,0 +1,627 @@
+/*
+ * $Id: services.c,v 1.1 1993/10/06 12:10:55 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/*
+ *  services.c  --  All the services the LysKOM server makes available
+ *		    for clients.
+ *
+ *  Created by ceder 1990-07-17
+ */
+
+static char *rcsid = "$Id: services.c,v 1.1 1993/10/06 12:10:55 linus Exp $";
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <ctype.h>
+
+#include <kom-types.h>
+#include <config.h>
+#include <services.h>
+#include <kom-errno.h>
+
+#include "client.h"
+#include "parse.h"
+#include "output.h"
+#include "services.h"
+#include "input.h"
+
+ISC *kom_server = NULL;
+#define KS kom_server
+
+
+free_function	 isc_free	= NULL;
+malloc_function	 isc_malloc	= NULL;
+realloc_function isc_realloc	= NULL;
+
+/*
+ * Session control
+ */
+extern  Success
+kom_open_connection (const char	* server )
+{
+    char *user;
+    char reply[7];
+    int i, c;
+    
+    user = cuserid(NULL);
+    if ( user == NULL )
+    {
+	fprintf(stderr, "Can't get user id with cuserid().\n");
+	fflush(stdout);
+	fflush(stderr);
+	abort();
+    }
+    
+    if ( (kom_server = isc_connect(server, 4894)) == NULL )
+    {
+	kom_errno = KOM_NO_CONNECT;
+	return FAILURE;
+    }
+    
+    fprintf(KS->out, "A%dH%s\n", strlen(user), user);
+    fflush(KS->out);
+
+    reply[ 6 ] = '\0';
+    for ( i = 0; i < 6; i++)
+    {
+	if ( !isascii(c = getc(KS->in)))
+	{
+	    isc_disconnect(KS);
+	    kom_errno = KOM_SERVER_IS_CRAZY;
+	    return FAILURE;
+	}
+	reply[ i ] = c;
+    }
+    
+    if ( strcmp(reply, "LysKOM") != 0 )
+    {
+	isc_disconnect(KS);
+	kom_errno = KOM_SERVER_IS_CRAZY;
+	return FAILURE;
+    }
+    return OK;    
+}
+
+
+/*
+ *  Set the functions to use for storage management.  These must
+ *  be call compatible with the normal functions malloc(),
+ *  realloc() and free().
+ */
+extern  void
+kom_set_storage_management (malloc_function	new_malloc,
+			    realloc_function	new_realloc,
+			    free_function	new_free)
+{
+    isc_malloc = new_malloc;
+    isc_realloc = new_realloc;
+    isc_free = new_free;
+}
+
+
+extern  Success
+kom_login_old (Pers_no	 person,
+	       const String	 passwd )
+{
+    output_login_old(person, passwd);
+    return input_header();
+}
+
+extern  Success
+kom_login (Pers_no	 person,
+	   const String	 passwd,
+	   Bool		 visible)
+{
+    output_login(person, passwd, visible);
+    return input_header();
+}
+
+
+extern  Success
+kom_logout (void)	/* can never fail */
+{
+    output_logout( );
+    return input_header( );
+}
+
+
+extern  Success
+kom_pepsi (Conf_no	conference )
+{
+    output_pepsi( conference );
+    return input_header( );
+}
+
+
+
+extern  Success
+kom_change_name (Conf_no       conf_no,
+		 const String  new_name)
+{
+    output_change_name( conf_no, new_name );
+    return input_header( );
+}
+
+extern  Success
+kom_change_what_i_am_doing (const String  what_am_i_doing )
+{
+    output_change_what_i_am_doing( what_am_i_doing );
+    return input_header();
+}
+
+
+
+/******************************
+*     Person-related calls    *
+******************************/
+
+/*
+ *  Create a new person.  Returns 0 if any error occured.
+ */
+extern  Pers_no
+kom_create_person (const String  name,
+		   const String  passwd )
+{
+    output_create_person( name, passwd );
+    if ( input_header( ) != OK )
+	return 0;
+
+    return parse_long( KS->in );
+}
+
+extern  Success
+kom_get_person_stat (Pers_no	      person,
+		     Person	    * result )
+{
+    output_get_person_stat( person );
+    return input_get_person_stat( result );
+}
+
+extern  Success
+kom_get_created_texts(Pers_no       pers_no,
+		      Local_text_no first,
+		      u_long        len,
+		      Text_list   * result)
+{
+    output_get_created_texts( pers_no, first, len );
+    return input_get_created_texts( result );
+}
+
+
+extern  Success
+kom_get_membership (Pers_no		  person,
+		    u_short		  first,
+		    u_short		  no_of_confs,
+		    Bool		  want_read_texts,
+		    Membership_list	* memberships )
+{
+    output_get_membership( person, first, no_of_confs, want_read_texts);
+    return input_get_membership( memberships );
+}
+
+extern  Success
+kom_set_priv_bits (Pers_no    person,
+		   Priv_bits  privileges )
+{
+    output_set_priv_bits( person, privileges );
+    return input_header( );
+}
+
+
+extern  Success
+kom_set_passwd (Pers_no	      person,
+		const String  old_pwd,
+		const String  new_pwd )
+{
+    output_set_passwd( person, old_pwd, new_pwd );
+    return input_header( );
+}
+
+
+extern  Success
+kom_query_read_texts (Pers_no      pers_no,
+		  Conf_no      conf_no,
+		  Membership * result   )
+{
+    output_query_read_texts( pers_no, conf_no );
+    return input_query_read_texts( result );
+}
+
+
+
+/****************************************
+*	Conference-related calls	*
+****************************************/
+
+
+extern  Conf_no
+kom_create_conf (const String  name,
+		 Conf_type     type )
+{
+    output_create_conf( name, type );
+    if ( input_header( ) != OK )
+	return 0;
+
+    return parse_long( KS->in );
+}
+
+
+extern  Success
+kom_delete_conf (Conf_no	conf )
+{
+    output_delete_conf( conf );
+    return input_header( );
+}
+
+
+extern  Success
+kom_lookup_name (const String   name,
+		 Conf_list     *result)
+{
+    output_lookup_name( name );
+    return input_lookup_name( result );
+}
+
+
+
+extern  Success
+kom_get_conf_stat (Conf_no	   conf_no,
+		   Conference    * result )
+{
+    output_get_conf_stat( conf_no );
+    return input_get_conf_stat( result );
+}
+
+extern  Success
+kom_get_members (Conf_no	  conf,
+		 u_short	  first,
+		 u_short	  no_of_members,
+		 Member_list	* members	)
+{
+    output_get_members(conf, first, no_of_members);
+    return input_get_members( members );
+}
+
+
+extern  Success
+kom_add_member (Conf_no	conf_no,
+		Pers_no	pers_no,
+		u_char	priority,
+		u_short	where	)
+{
+    output_add_member( conf_no, pers_no, priority, where );
+    return input_header( );
+}
+
+
+extern  Success
+kom_sub_member (Conf_no	conf_no,
+		Pers_no	pers_no )
+{
+    output_sub_member( conf_no, pers_no );
+    return input_header( );
+}
+
+extern  Success
+kom_set_unread (Conf_no   conf_no,
+		Text_no   no_of_unread)
+{
+    output_set_unread( conf_no, no_of_unread );
+    return input_header( );
+}
+
+extern  Success
+kom_set_presentation (Conf_no   conf_no,
+		      Text_no   text_no ) /* 0 to delete pres. */
+{
+    output_set_presentation( conf_no, text_no );
+    return input_header( );
+}
+
+extern  Success
+kom_set_etc_motd (Conf_no	  conf_no,
+		  Text_no	  text_no )
+{
+    output_set_etc_motd( conf_no, text_no );
+    return input_header( );
+}
+
+
+extern  Success
+kom_set_supervisor (Conf_no	  conf_no,
+		    Conf_no	  admin	)
+{
+    output_set_supervisor( conf_no, admin );
+    return input_header( );
+}
+
+extern  Success
+kom_set_permitted_submitters (Conf_no  conf_no,
+			      Conf_no  perm_sub )
+{
+    output_set_permitted_submitters( conf_no, perm_sub );
+    return input_header( );
+}
+
+extern  Success
+kom_set_super_conf (Conf_no	  conf_no,
+		    Conf_no	  super_conf )
+{
+    output_set_super_conf( conf_no, super_conf );
+    return input_header( );
+}
+
+extern  Success
+kom_set_conf_type (Conf_no    conf_no,
+		   Conf_type  type	)
+{
+    output_set_conf_type( conf_no, type );
+    return input_header( );
+}
+
+extern  Success
+kom_set_garb_nice (Conf_no    conf_no,
+		   Garb_nice  nice	)
+{
+    output_set_garb_nice( conf_no, nice );
+    return input_header( );
+}
+
+
+
+/********************************
+*     Calls to handle marks     *
+********************************/
+
+
+extern  Success
+kom_get_marks (Mark_list *result )
+{
+    output_get_marks( );
+    return input_get_marks( result );
+}
+
+
+
+extern  Success
+kom_mark_text (Text_no  text,
+	       u_char   mark_type )
+{
+    output_mark_text( text, mark_type );
+    return input_header( );
+}
+
+
+
+
+/*******************************
+*     Calls to handle texts    *
+*******************************/
+
+
+extern  Success
+kom_get_text (Text_no      text,
+	      String_size  start_char,
+	      String_size  end_char,
+	      String      *result)
+{
+    output_get_text( text, start_char, end_char );
+    return input_get_text( result );
+}
+
+
+extern  Success
+kom_get_text_stat (Text_no    text,
+		   Text_stat *result)
+{
+    output_get_text_stat( text );
+    return input_get_text_stat( result );
+}
+
+extern  Success
+kom_mark_as_read (Conf_no                conference,
+		  int		         no_of_texts,
+		  const Local_text_no  * text_arr   )
+{
+    output_mark_as_read( conference, no_of_texts, text_arr );
+    return input_header( );
+}
+
+
+extern  Text_no
+kom_create_text (const String       message,
+		     u_short	        no_of_misc,
+		     const Misc_info  * misc	     )
+{
+    output_create_text( message, no_of_misc, misc );
+    return input_create_text( );
+}
+
+extern  Text_no
+kom_create_anonymous_text (const String       message,
+			   u_short	        no_of_misc,
+			   const Misc_info  * misc	     )
+{
+    output_create_anonymous_text( message, no_of_misc, misc );
+    return input_create_anonymous_text( );
+}
+
+extern Success
+kom_delete_text( Text_no text_no )
+{
+    output_delete_text( text_no );
+    return input_header( );
+}
+
+
+
+extern  Success
+kom_add_recipient (Text_no    text_no,
+		   Conf_no    conf_no,
+		   Info_type  type	)
+{
+    output_add_recipient( text_no, conf_no, type );
+    return input_header( );
+}
+
+extern  Success
+kom_sub_recipient (Text_no	  text_no,
+		   Conf_no	  conf_no )
+{
+    output_sub_recipient( text_no, conf_no);
+    return input_header( );
+}
+
+
+extern  Success
+kom_add_comment (Text_no	  comment,
+		 Text_no 	  comment_to )
+{
+    output_add_comment( comment, comment_to );
+    return input_header( );
+}
+
+
+extern  Success
+kom_sub_comment (Text_no	  comment,
+		 Text_no	  comment_to )
+{
+    output_sub_comment( comment, comment_to );
+    return input_header( );
+}
+
+
+extern Success
+kom_add_footnote (Text_no	footnote,
+		  Text_no 	footnote_to )
+{
+    output_add_footnote( footnote, footnote_to );
+    return input_header();
+}
+
+
+extern Success
+kom_sub_footnote (Text_no footnote,
+		  Text_no parent )
+{
+    output_sub_footnote( footnote, parent );
+    return input_header();
+}
+
+
+extern  Success
+kom_get_map (Conf_no	     conf_no,
+	     Local_text_no   first_local_no,
+	     Local_text_no   no_of_texts,
+	     Text_list	   * result)
+{
+    output_get_map( conf_no, first_local_no, no_of_texts );
+    return input_get_map( result );
+}
+
+
+extern  Success
+kom_get_time ( struct tm  * clock )
+{
+    output_get_time( );
+    return input_get_time( clock );
+}
+
+extern  Success
+kom_who_is_on( Who_info_list *result )
+{
+    output_who_is_on( );
+    return input_who_is_on( result );
+}
+
+
+extern  Success
+kom_get_info (Info *result )
+{
+    output_get_info( );
+    return input_get_info( result );
+}
+
+
+extern Success
+kom_set_motd_of_lyskom (Text_no motd)
+{
+    output_set_motd_of_lyskom( motd );
+    return input_header( );
+}
+
+
+extern Success
+kom_enable (u_char ena_level)
+{
+    output_enable( ena_level );
+    return input_header( );
+}
+
+
+extern Success
+kom_sync (void) 
+{
+    output_sync( );
+    return input_header( );
+}
+
+
+extern Success
+kom_shutdown (int exit_val) 
+{
+    output_shutdown( exit_val );
+    return input_header( );
+}
+
+
+extern Success
+kom_broadcast (const String message)
+{
+    output_broadcast( message );
+    return input_header( );
+}
+
+extern Success
+kom_send_message (Pers_no recipient,
+		  const String message)
+{
+    output_send_message( recipient, message );
+    return input_header( );
+}
+
+extern Success
+kom_get_unread_confs(Pers_no       pers_no,
+		     Conf_no_list *result)
+{
+    output_get_unread_confs( pers_no );
+    return input_get_unread_confs( result );
+}
diff --git a/src/libraries/libclient/services.h b/src/libraries/libclient/services.h
new file mode 100644
index 0000000000000000000000000000000000000000..73676196625346d3520a06a041150e0bc7862642
--- /dev/null
+++ b/src/libraries/libclient/services.h
@@ -0,0 +1,26 @@
+/*
+ * $Id: services.h,v 1.1 1993/10/06 12:10:59 linus Exp $
+ * Copyright (C) 1991  Lysator Academic Computer Association.
+ *
+ * This file is part of the LysKOM server.
+ * 
+ * LysKOM 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 1, or (at your option) 
+ * any later version.
+ * 
+ * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
+ * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
+ * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
+ * MA 02139, USA.
+ *
+ * Please mail bug reports to bug-lyskom@lysator.liu.se. 
+ */
+/* $Id: services.h,v 1.1 1993/10/06 12:10:59 linus Exp $ */
+extern ISC *kom_server;