Browse Source

Remove all unneeded code inherited from klish

Serj Kalichev 4 years ago
parent
commit
4dcc7eb7f5
20 changed files with 0 additions and 5342 deletions
  1. 0 448
      bin/clish.c
  2. 0 194
      bin/konf.c
  3. 0 784
      bin/konfd.c
  4. 0 31
      bin/module.am
  5. 0 123
      bin/sigexec.c
  6. 0 580
      klish.xsd
  7. 0 16
      tinyrl/README
  8. 0 99
      tinyrl/history.h
  9. 0 482
      tinyrl/history/history.c
  10. 0 55
      tinyrl/history/history_entry.c
  11. 0 7
      tinyrl/history/module.am
  12. 0 9
      tinyrl/history/private.h
  13. 0 21
      tinyrl/module.am
  14. 0 47
      tinyrl/private.h
  15. 0 1657
      tinyrl/tinyrl.c
  16. 0 228
      tinyrl/tinyrl.h
  17. 0 141
      tinyrl/vt100.h
  18. 0 4
      tinyrl/vt100/module.am
  19. 0 7
      tinyrl/vt100/private.h
  20. 0 409
      tinyrl/vt100/vt100.c

+ 0 - 448
bin/clish.c

@@ -1,448 +0,0 @@
-/*
- * --------------------------------------
- * clish.c
- *
- * A console client for libclish
- * --------------------------------------
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <syslog.h>
-#include <fcntl.h>
-
-#if WITH_INTERNAL_GETOPT
-#include "libc/getopt.h"
-#else
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-#endif
-
-#include <signal.h>
-#if HAVE_LOCALE_H
-#include <locale.h>
-#endif
-#if HAVE_LANGINFO_CODESET
-#include <langinfo.h>
-#endif
-
-#include "lub/list.h"
-#include "lub/system.h"
-#include "lub/log.h"
-#include "lub/conv.h"
-#include "clish/shell.h"
-
-#define QUOTE(t) #t
-/* #define version(v) printf("%s\n", QUOTE(v)) */
-#define version(v) printf("%s\n", v)
-
-static void sighandler(int signo);
-static void help(int status, const char *argv0);
-
-/*--------------------------------------------------------- */
-int main(int argc, char **argv)
-{
-	int running;
-	int result = -1;
-	clish_shell_t *shell = NULL;
-
-	/* Command line options */
-	const char *socket_path = KONFD_SOCKET_PATH;
-	bool_t lockless = BOOL_FALSE;
-	bool_t stop_on_error = BOOL_FALSE;
-	bool_t interactive = BOOL_TRUE;
-	bool_t quiet = BOOL_FALSE;
-	bool_t utf8 = BOOL_FALSE;
-	bool_t bit8 = BOOL_FALSE;
-	bool_t log = BOOL_FALSE;
-	int log_facility = LOG_LOCAL0;
-	bool_t dryrun = BOOL_FALSE;
-	bool_t dryrun_config = BOOL_FALSE;
-	bool_t canon_out = BOOL_FALSE;
-	const char *xml_path = getenv("CLISH_PATH");
-	const char *view = getenv("CLISH_VIEW");
-	const char *viewid = getenv("CLISH_VIEWID");
-	const char *xslt_file = NULL;
-
-	FILE *outfd = stdout;
-	bool_t istimeout = BOOL_FALSE;
-	unsigned int timeout = 0;
-	bool_t cmd = BOOL_FALSE; /* -c option */
-	lub_list_t *cmds; /* Commands defined by -c */
-	lub_list_node_t *iter;
-	const char *histfile = "~/.clish_history";
-	char *histfile_expanded = NULL;
-	unsigned int histsize = 50;
-	clish_sym_t *sym = NULL;
-
-	/* Signal vars */
-	struct sigaction sigpipe_act;
-	sigset_t sigpipe_set;
-
-	static const char *shortopts = "hvs:ledx:w:i:bqu8oO:kKt:c:f:z:p:";
-#ifdef HAVE_GETOPT_LONG
-	static const struct option longopts[] = {
-		{"help",	0, NULL, 'h'},
-		{"version",	0, NULL, 'v'},
-		{"socket",	1, NULL, 's'},
-		{"lockless",	0, NULL, 'l'},
-		{"stop-on-error", 0, NULL, 'e'},
-		{"dry-run",	0, NULL, 'd'},
-		{"xml-path",	1, NULL, 'x'},
-		{"view",	1, NULL, 'w'},
-		{"viewid",	1, NULL, 'i'},
-		{"background",	0, NULL, 'b'},
-		{"quiet",	0, NULL, 'q'},
-		{"utf8",	0, NULL, 'u'},
-		{"8bit",	0, NULL, '8'},
-		{"log",		0, NULL, 'o'},
-		{"facility",	1, NULL, 'O'},
-		{"check",	0, NULL, 'k'},
-		{"canon-out",	0, NULL, 'K'},
-		{"timeout",	1, NULL, 't'},
-		{"command",	1, NULL, 'c'},
-		{"histfile",	1, NULL, 'f'},
-		{"histsize",	1, NULL, 'z'},
-		{"xslt",	1, NULL, 'p'},
-		{NULL,		0, NULL, 0}
-	};
-#endif
-
-	/* Ignore SIGPIPE */
-	sigemptyset(&sigpipe_set);
-	sigaddset(&sigpipe_set, SIGPIPE);
-	sigpipe_act.sa_flags = 0;
-	sigpipe_act.sa_mask = sigpipe_set;
-	sigpipe_act.sa_handler = &sighandler;
-	sigaction(SIGPIPE, &sigpipe_act, NULL);
-
-#if HAVE_LOCALE_H
-	/* Set current locale */
-	setlocale(LC_ALL, "");
-#endif
-
-	/* Var initialization */
-	cmds = lub_list_new(NULL, free);
-
-	/* Parse command line options */
-	while(1) {
-		int opt;
-#ifdef HAVE_GETOPT_LONG
-		opt = getopt_long(argc, argv, shortopts, longopts, NULL);
-#else
-		opt = getopt(argc, argv, shortopts);
-#endif
-		if (-1 == opt)
-			break;
-		switch (opt) {
-		case 's':
-			socket_path = optarg;
-			break;
-		case 'l':
-			lockless = BOOL_TRUE;
-			break;
-		case 'e':
-			stop_on_error = BOOL_TRUE;
-			break;
-		case 'b':
-			interactive = BOOL_FALSE;
-			break;
-		case 'q':
-			quiet = BOOL_TRUE;
-			break;
-		case 'u':
-			utf8 = BOOL_TRUE;
-			break;
-		case '8':
-			bit8 = BOOL_TRUE;
-			break;
-		case 'o':
-			log = BOOL_TRUE;
-			break;
-		case 'O':
-			if (lub_log_facility(optarg, &log_facility)) {
-				fprintf(stderr, "Error: Illegal syslog facility %s.\n", optarg);
-				help(-1, argv[0]);
-				goto end;
-			}
-			break;
-		case 'd':
-			dryrun = BOOL_TRUE;
-			break;
-		case 'x':
-			xml_path = optarg;
-			break;
-		case 'w':
-			view = optarg;
-			break;
-		case 'i':
-			viewid = optarg;
-			break;
-		case 'k':
-			lockless = BOOL_TRUE;
-			dryrun = BOOL_TRUE;
-			dryrun_config = BOOL_TRUE;
-			break;
-		case 'K':
-			lockless = BOOL_TRUE;
-			dryrun = BOOL_TRUE;
-			dryrun_config = BOOL_TRUE;
-			canon_out = BOOL_TRUE;
-			break;
-		case 't':
-			istimeout = BOOL_TRUE;
-			timeout = 0;
-			lub_conv_atoui(optarg, &timeout, 0);
-			break;
-		case 'c': {
-			char *str;
-			cmd = BOOL_TRUE;
-			quiet = BOOL_TRUE;
-			str = strdup(optarg);
-			lub_list_add(cmds, str);
-			}
-			break;
-		case 'f':
-			if (!strcmp(optarg, "/dev/null"))
-				histfile = NULL;
-			else
-				histfile = optarg;
-			break;
-		case 'z': {
-			histsize = 0;
-			lub_conv_atoui(optarg, &histsize, 0);
-			}
-			break;
-		case 'p':
-#ifdef HAVE_LIB_LIBXSLT
-			xslt_file = optarg;
-#else
-			fprintf(stderr, "Error: The klish was built without XSLT support.\n");
-			goto end;
-#endif
-			break;
-		case 'h':
-			help(0, argv[0]);
-			exit(0);
-			break;
-		case 'v':
-			version(VERSION);
-			exit(0);
-			break;
-		default:
-			help(-1, argv[0]);
-			goto end;
-			break;
-		}
-	}
-
-	/* Validate command line options */
-	if (utf8 && bit8) {
-		fprintf(stderr, "Error: The -u and -8 options can't be used together.\n");
-		goto end;
-	}
-
-	/* Create shell instance */
-	if (quiet) {
-		FILE *tmpfd = NULL;
-		if ((tmpfd = fopen("/dev/null", "w")))
-			outfd = tmpfd;
-	}
-	shell = clish_shell_new(NULL, outfd, stop_on_error);
-	if (!shell) {
-		fprintf(stderr, "Error: Can't run clish.\n");
-		goto end;
-	}
-	/* Load the XML files */
-	clish_xmldoc_start();
-	if (clish_shell_load_scheme(shell, xml_path, xslt_file))
-		goto end;
-	/* Set communication to the konfd */
-	clish_shell__set_socket(shell, socket_path);
-	/* Set lockless mode */
-	if (lockless)
-		clish_shell__set_lockfile(shell, NULL);
-	/* Set interactive mode */
-	if (!interactive)
-		clish_shell__set_interactive(shell, interactive);
-	/* Set startup view */
-	if (view)
-		clish_shell__set_startup_view(shell, view);
-	/* Set startup viewid */
-	if (viewid)
-		clish_shell__set_startup_viewid(shell, viewid);
-	/* Set UTF-8 or 8-bit mode */
-	if (utf8 || bit8)
-		clish_shell__set_utf8(shell, utf8);
-	else {
-#if HAVE_LANGINFO_CODESET
-		/* Autodetect encoding */
-		if (!strcmp(nl_langinfo(CODESET), "UTF-8"))
-			clish_shell__set_utf8(shell, BOOL_TRUE);
-#else
-		/* The default is 8-bit if locale is not supported */
-		clish_shell__set_utf8(shell, BOOL_FALSE);
-#endif
-	}
-	/* Set logging */
-	if (log) {
-		clish_shell__set_log(shell, log);
-		clish_shell__set_log_facility(shell, log_facility);
-	}
-	/* Set dry-run */
-	if (dryrun)
-		clish_shell__set_dryrun(shell, dryrun);
-	/* Set canonical output */
-	if (canon_out)
-		clish_shell__set_canon_out(shell, canon_out);
-	/* Set idle timeout */
-	if (istimeout)
-		clish_shell__set_idle_timeout(shell, timeout);
-	/* Set history settings */
-	clish_shell__stifle_history(shell, histsize);
-	if (histfile)
-		histfile_expanded = lub_system_tilde_expand(histfile);
-	if (histfile_expanded)
-		clish_shell__restore_history(shell, histfile_expanded);
-	/* Load plugins, link aliases and check access rights */
-	if (clish_shell_prepare(shell) < 0)
-		goto end;
-	/* Dryrun config and log hooks */
-	if (dryrun_config) {
-		if ((sym = clish_shell_get_hook(shell, CLISH_SYM_TYPE_CONFIG)))
-			clish_sym__set_permanent(sym, BOOL_FALSE);
-		if ((sym = clish_shell_get_hook(shell, CLISH_SYM_TYPE_LOG)))
-			clish_sym__set_permanent(sym, BOOL_FALSE);
-	}
-#ifdef DEBUG
-	clish_shell_dump(shell);
-#endif
-
-	/* Set source of command stream: files or interactive tty */
-	if(optind < argc) {
-		int i;
-		/* Run the commands from the files */
-		for (i = argc - 1; i >= optind; i--)
-			clish_shell_push_file(shell, argv[i], stop_on_error);
-	} else {
-		/* The interactive shell */
-		int tmpfd = dup(fileno(stdin));
-#ifdef FD_CLOEXEC
-		fcntl(tmpfd, F_SETFD, fcntl(tmpfd, F_GETFD) | FD_CLOEXEC);
-#endif
-		clish_shell_push_fd(shell, fdopen(tmpfd, "r"), stop_on_error);
-	}
-
-	/* Execute startup */
-	running = clish_shell_startup(shell);
-	if (running) {
-		fprintf(stderr, "Error: Can't startup clish.\n");
-		goto end;
-	}
-
-	if (cmd) {
-		/* Iterate cmds */
-		for(iter = lub_list__get_head(cmds);
-			iter; iter = lub_list_node__get_next(iter)) {
-			char *str = (char *)lub_list_node__get_data(iter);
-			result = clish_shell_forceline(shell, str, NULL);
-			if (stop_on_error && result)
-				break;
-		}
-	} else {
-		/* Main loop */
-		result = clish_shell_loop(shell);
-	}
-
-end:
-	/* Cleanup */
-	if (shell) {
-		if (histfile_expanded) {
-			clish_shell__save_history(shell, histfile_expanded);
-			free(histfile_expanded);
-		}
-		clish_shell_delete(shell);
-	}
-	if (quiet && (outfd != stdout))
-		fclose(outfd);
-
-	/* Delete each cmds element */
-	lub_list_free_all(cmds);
-
-	/* Stop XML engine */
-	clish_xmldoc_stop();
-
-	return result;
-}
-
-/*--------------------------------------------------------- */
-/* Print help message */
-static void help(int status, const char *argv0)
-{
-	const char *name = NULL;
-
-	if (!argv0)
-		return;
-
-	/* Find the basename */
-	name = strrchr(argv0, '/');
-	if (name)
-		name++;
-	else
-		name = argv0;
-
-	if (status != 0) {
-		fprintf(stderr, "Try `%s -h' for more information.\n",
-			name);
-	} else {
-		printf("Usage: %s [options] [script_file] [script_file] ...\n", name);
-		printf("CLI utility. Command line shell."
-			"The part of the klish project.\n");
-		printf("Options:\n");
-		printf("\t-v, --version\tPrint version.\n");
-		printf("\t-h, --help\tPrint this help.\n");
-		printf("\t-s <path>, --socket=<path>\tSpecify listen socket "
-			"\n\t\tof the konfd daemon.\n");
-		printf("\t-l, --lockless\tDon't use locking mechanism.\n");
-		printf("\t-e, --stop-on-error\tStop script execution on error.\n");
-		printf("\t-b, --background\tStart shell using non-interactive mode.\n");
-		printf("\t-q, --quiet\tDisable echo while executing commands\n\t\tfrom the file stream.\n");
-		printf("\t-d, --dry-run\tDon't actually execute ACTION scripts.\n");
-		printf("\t-x <path>, --xml-path=<path>\tPath to XML scheme files.\n");
-#ifdef HAVE_LIB_LIBXSLT
-		printf("\t-p <path>, --xslt=<path>\tProcess XML with specified XSLT stylesheet.\n");
-#endif
-		printf("\t-w <view_name>, --view=<view_name>\tSet the startup view.\n");
-		printf("\t-i <vars>, --viewid=<vars>\tSet the startup viewid variables.\n");
-		printf("\t-u, --utf8\tForce UTF-8 encoding.\n");
-		printf("\t-8, --8bit\tForce 8-bit encoding.\n");
-		printf("\t-o, --log\tEnable command logging to syslog's.\n");
-		printf("\t-O, --facility\tSyslog facility. Default is LOCAL0.\n");
-		printf("\t-k, --check\tCheck input files for syntax errors only.\n");
-		printf("\t-K, --canon-out\tCheck input files for syntax and print commands\n\t\tin canonical form - prepended with spaces indicates depth.\n");
-		printf("\t-t <timeout>, --timeout=<timeout>\tIdle timeout in seconds.\n");
-		printf("\t-c <command>, --command=<command>\tExecute specified command(s).\n\t\tMultiple options are possible.\n");
-		printf("\t-f <path>, --histfile=<path>\tFile to save command history.\n");
-		printf("\t-z <num>, --histsize=<num>\tCommand history size in lines.\n");
-	}
-}
-
-/*--------------------------------------------------------- */
-/*
- * Signal handler for SIGPIPE.
- * It's empty but it's needed to don't ignore SIGPIPE because
- * SIG_IGN will be inherited while ACTION execution.
- */
-static void sighandler(int signo)
-{
-	signo = signo; /* Happy compiler */
-
-	return;
-}

+ 0 - 194
bin/konf.c

@@ -1,194 +0,0 @@
-/*
- * konf.c
- *
- * The client to communicate to konfd configuration daemon.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-
-#if WITH_INTERNAL_GETOPT
-#include "libc/getopt.h"
-#else
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-#endif
-
-#include "konf/net.h"
-#include "konf/query.h"
-#include "konf/buf.h"
-#include "lub/string.h"
-
-#ifndef VERSION
-#define VERSION 1.2.2
-#endif
-#define QUOTE(t) #t
-#define version(v) printf("%s\n", v)
-
-static void help(int status, const char *argv0);
-
-static const char *escape_chars = "\"\\'";
-
-/*--------------------------------------------------------- */
-int main(int argc, char **argv)
-{
-	int res = -1;
-	konf_client_t *client = NULL;
-	konf_buf_t *buf = NULL;
-	char *line = NULL;
-	char *str = NULL;
-	const char *socket_path = KONFD_SOCKET_PATH;
-	int i = 0;
-
-	/* Signal vars */
-	struct sigaction sigpipe_act;
-	sigset_t sigpipe_set;
-
-	static const char *shortopts = "hvs:";
-#ifdef HAVE_GETOPT_LONG
-	static const struct option longopts[] = {
-		{"help",	0, NULL, 'h'},
-		{"version",	0, NULL, 'v'},
-		{"socket",	1, NULL, 's'},
-		{NULL,		0, NULL, 0}
-	};
-#endif
-
-	/* Ignore SIGPIPE */
-	sigemptyset(&sigpipe_set);
-	sigaddset(&sigpipe_set, SIGPIPE);
-	sigpipe_act.sa_flags = 0;
-	sigpipe_act.sa_mask = sigpipe_set;
-	sigpipe_act.sa_handler = SIG_IGN;
-	sigaction(SIGPIPE, &sigpipe_act, NULL);
-
-	/* Parse command line options */
-	while(1) {
-		int opt;
-#ifdef HAVE_GETOPT_LONG
-		opt = getopt_long(argc, argv, shortopts, longopts, NULL);
-#else
-		opt = getopt(argc, argv, shortopts);
-#endif
-		if (-1 == opt)
-			break;
-		switch (opt) {
-		case 's':
-			socket_path = optarg;
-			break;
-		case 'h':
-			help(0, argv[0]);
-			exit(0);
-			break;
-		case 'v':
-			version(VERSION);
-			exit(0);
-			break;
-		default:
-			help(-1, argv[0]);
-			exit(-1);
-			break;
-		}
-	}
-
-	/* Get request line from the args */
-	for (i = optind; i < argc; i++) {
-		char *space = NULL;
-		if (NULL != line)
-			lub_string_cat(&line, " ");
-		space = strchr(argv[i], ' ');
-		if (space)
-			lub_string_cat(&line, "\"");
-		str = lub_string_encode(argv[i], escape_chars);
-		lub_string_cat(&line, str);
-		lub_string_free(str);
-		if (space)
-			lub_string_cat(&line, "\"");
-	}
-	if (!line) {
-		help(-1, argv[0]);
-		goto err;
-	}
-#ifdef DEBUG
-	fprintf(stderr, "REQUEST: %s\n", line);
-#endif
-
-	if (!(client = konf_client_new(socket_path))) {
-		fprintf(stderr, "Error: Can't create internal data structures.\n");
-		goto err;
-	}
-
-	if (konf_client_connect(client) < 0) {
-		fprintf(stderr, "Error: Can't connect to %s socket.\n", socket_path);
-		goto err;
-	}
-
-	if (konf_client_send(client, line) < 0) {
-		fprintf(stderr, "Error: Can't send request to %s socket.\n", socket_path);
-		goto err;
-	}
-
-	if (konf_client_recv_answer(client, &buf) < 0) {
-		fprintf(stderr, "Error: The error code from the konfd daemon.\n");
-		goto err;
-	}
-
-	if (buf) {
-		konf_buf_lseek(buf, 0);
-		while ((str = konf_buf_preparse(buf))) {
-			if (strlen(str) == 0) {
-				lub_string_free(str);
-				break;
-			}
-			fprintf(stdout, "%s\n", str);
-			lub_string_free(str);
-		}
-		konf_buf_delete(buf);
-	}
-
-	res = 0;
-err:
-	lub_string_free(line);
-	konf_client_free(client);
-
-	return res;
-}
-
-/*--------------------------------------------------------- */
-/* Print help message */
-static void help(int status, const char *argv0)
-{
-	const char *name = NULL;
-
-	if (!argv0)
-		return;
-
-	/* Find the basename */
-	name = strrchr(argv0, '/');
-	if (name)
-		name++;
-	else
-		name = argv0;
-
-	if (status != 0) {
-		fprintf(stderr, "Try `%s -h' for more information.\n",
-			name);
-	} else {
-		printf("Usage: %s [options] -- <command for konfd daemon>\n", name);
-		printf("Utility for communication to the konfd "
-			"configuration daemon.\n");
-		printf("Options:\n");
-		printf("\t-v, --version\tPrint utility version.\n");
-		printf("\t-h, --help\tPrint this help.\n");
-		printf("\t-s <path>, --socket=<path>\tSpecify listen socket "
-			"of the konfd daemon.\n");
-	}
-}

+ 0 - 784
bin/konfd.c

@@ -1,784 +0,0 @@
-/*
- * konfd.c
- *
- * The konfd daemon to store user configuration commands.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <string.h>
-#include <sys/select.h>
-#include <signal.h>
-#include <syslog.h>
-
-#if WITH_INTERNAL_GETOPT
-#include "libc/getopt.h"
-#else
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-#endif
-
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-#ifdef HAVE_GRP_H
-#include <grp.h>
-#endif
-
-#include "konf/tree.h"
-#include "konf/query.h"
-#include "konf/buf.h"
-#include "konf/net.h"
-#include "lub/argv.h"
-#include "lub/string.h"
-#include "lub/log.h"
-
-#ifndef VERSION
-#define VERSION 1.2.2
-#endif
-#define QUOTE(t) #t
-#define version(v) printf("%s\n", v)
-
-#define KONFD_PIDFILE "/var/run/konfd.pid"
-
-/* UNIX socket path */
-/* Don't use UNIX_PATH_MAX due to portability issues */
-#define USOCK_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path)
-
-/* OpenBSD has no MSG_NOSIGNAL flag */
-#ifndef MSG_NOSIGNAL
-#define MSG_NOSIGNAL 0
-#endif
-
-/* Global signal vars */
-static volatile int sigterm = 0;
-static void sighandler(int signo);
-
-static void help(int status, const char *argv0);
-static char * process_query(konf_buf_t *tbuf, konf_tree_t * conf, char *str);
-int answer_send(int sock, const char *command);
-static int dump_running_config(int sock, konf_tree_t *conf, konf_query_t *query);
-int daemonize(int nochdir, int noclose);
-struct options *opts_init(void);
-void opts_free(struct options *opts);
-static int opts_parse(int argc, char *argv[], struct options *opts);
-static int create_listen_socket(const char *path,
-	uid_t uid, gid_t gid, mode_t mode);
-
-/* Command line options */
-struct options {
-	char *socket_path;
-	char *ro_path;
-	char *pidfile;
-	char *chroot;
-	int debug; /* Don't daemonize in debug mode */
-	uid_t uid;
-	gid_t gid;
-	int log_facility;
-};
-
-/*--------------------------------------------------------- */
-int main(int argc, char **argv)
-{
-	int retval = -1;
-	int i;
-	char *str;
-	konf_tree_t *conf;
-	lub_list_t *bufs;
-	konf_buf_t *tbuf;
-	struct options *opts = NULL;
-	int pidfd = -1;
-
-	/* Network vars */
-	int sock = -1;
-	int ro_sock = -1;
-	struct sockaddr_un raddr;
-	fd_set active_fd_set, read_fd_set;
-
-	/* Signal vars */
-	struct sigaction sig_act, sigpipe_act;
-	sigset_t sig_set, sigpipe_set;
-
-	/* Parse command line options */
-	opts = opts_init();
-	if (opts_parse(argc, argv, opts))
-		goto err;
-
-	/* Initialize syslog */
-	openlog(argv[0], LOG_CONS, opts->log_facility);
-	syslog(LOG_ERR, "Start daemon.\n");
-
-	/* Fork the daemon */
-	if (!opts->debug) {
-		/* Daemonize */
-		if (daemonize(0, 0) < 0) {
-			syslog(LOG_ERR, "Can't daemonize\n");
-			goto err;
-		}
-
-		/* Write pidfile */
-		if ((pidfd = open(opts->pidfile,
-			O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
-			S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
-			syslog(LOG_WARNING, "Can't open pidfile %s: %s",
-				opts->pidfile, strerror(errno));
-		} else {
-			char str[20];
-			snprintf(str, sizeof(str), "%u\n", getpid());
-			str[sizeof(str) - 1] = '\0';
-			if (write(pidfd, str, strlen(str)) < 0)
-				syslog(LOG_WARNING, "Can't write to %s: %s",
-					opts->pidfile, strerror(errno));
-			close(pidfd);
-		}
-	}
-
-	/* Create RW listen socket */
-	if ((sock = create_listen_socket(opts->socket_path,
-		opts->uid, opts->gid, 0660)) == -1) {
-		goto err;
-	}
-
-	/* Create RO listen socket */
-	if (opts->ro_path && (ro_sock = create_listen_socket(opts->ro_path,
-		opts->uid, opts->gid, 0666)) == -1) {
-		goto err;
-	}
-
-	/* Change GID */
-	if (opts->gid != getgid()) {
-		if (setgid(opts->gid)) {
-			syslog(LOG_ERR, "Can't set GID to %u: %s",
-				opts->gid, strerror(errno));
-			goto err;
-		}
-	}
-
-#ifdef HAVE_CHROOT
-	/* Chroot */
-	if (opts->chroot) {
-		if (chroot(opts->chroot) < 0) {
-			syslog(LOG_ERR, "Can't chroot to %s: %s",
-				opts->chroot, strerror(errno));
-			goto err;
-		}
-	}
-#endif
-
-	/* Change UID */
-	if (opts->uid != getuid()) {
-		if (setuid(opts->uid)) {
-			syslog(LOG_ERR, "Can't set UID to %u: %s",
-				opts->uid, strerror(errno));
-			goto err;
-		}
-	}
-
-	/* Create configuration tree */
-	conf = konf_tree_new("", 0);
-
-	/* Initialize the tree of buffers */
-	bufs = lub_list_new(konf_buf_compare, konf_buf_delete);
-
-	/* Set signal handler */
-	sigemptyset(&sig_set);
-	sigaddset(&sig_set, SIGTERM);
-	sigaddset(&sig_set, SIGINT);
-	sigaddset(&sig_set, SIGQUIT);
-
-	sig_act.sa_flags = 0;
-	sig_act.sa_mask = sig_set;
-	sig_act.sa_handler = &sighandler;
-	sigaction(SIGTERM, &sig_act, NULL);
-	sigaction(SIGINT, &sig_act, NULL);
-	sigaction(SIGQUIT, &sig_act, NULL);
-
-	/* Ignore SIGPIPE */
-	sigemptyset(&sigpipe_set);
-	sigaddset(&sigpipe_set, SIGPIPE);
-	sigpipe_act.sa_flags = 0;
-	sigpipe_act.sa_mask = sigpipe_set;
-	sigpipe_act.sa_handler = SIG_IGN;
-	sigaction(SIGPIPE, &sigpipe_act, NULL);
-
-	/* Initialize the set of active sockets. */
-	FD_ZERO(&active_fd_set);
-	FD_SET(sock, &active_fd_set);
-	if (ro_sock >= 0)
-		FD_SET(ro_sock, &active_fd_set);
-
-	/* Main loop */
-	while (!sigterm) {
-		int num;
-
-		/* Block until input arrives on one or more active sockets. */
-		read_fd_set = active_fd_set;
-		num = select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL);
-		if (num < 0) {
-			if (EINTR == errno)
-				continue;
-			break;
-		}
-		if (0 == num)
-			continue;
-
-		/* Service all the sockets with input pending. */
-		for (i = 0; i < FD_SETSIZE; ++i) {
-			if (!FD_ISSET(i, &read_fd_set))
-				continue;
-			/* Connection request on listen socket. */
-			if ((i == sock) || (i == ro_sock)) {
-				int new;
-				socklen_t size = sizeof(raddr);
-				new = accept(i, (struct sockaddr *)&raddr, &size);
-				if (new < 0)
-					continue;
-#ifdef DEBUG
-				fprintf(stderr, "------------------------------\n");
-				fprintf(stderr, "Connection established %u\n", new);
-#endif
-				konf_buftree_remove(bufs, new);
-				tbuf = konf_buf_new(new);
-				lub_list_add(bufs, tbuf);
-				/* In a case of RW socket we use buf's data pointer
-				  to indicate RW or RO socket. NULL=RO, not-NULL=RW */
-				if (i == sock)
-					konf_buf__set_data(tbuf, (void *)1);
-				FD_SET(new, &active_fd_set);
-			} else {
-				int nbytes;
-
-				tbuf = konf_buftree_find(bufs, i);
-				/* Data arriving on an already-connected socket. */
-				if ((nbytes = konf_buf_read(tbuf)) <= 0) {
-					close(i);
-					FD_CLR(i, &active_fd_set);
-					konf_buftree_remove(bufs, i);
-#ifdef DEBUG
-					fprintf(stderr, "Connection closed %u\n", i);
-#endif
-					continue;
-				}
-				while ((str = konf_buf_parse(tbuf))) {
-					char *answer;
-					if (!(answer = process_query(tbuf, conf, str)))
-						answer = strdup("-e");
-					free(str);
-					answer_send(i, answer);
-					free(answer);
-				}
-			}
-		}
-	}
-
-	/* Free resources */
-	konf_tree_delete(conf);
-
-	/* Delete bufs */
-	lub_list_free_all(bufs);
-
-	retval = 0;
-err:
-	/* Close RW socket */
-	if (sock >= 0) {
-		close(sock);
-		unlink(opts->socket_path);
-	}
-
-	/* Close RO socket */
-	if (ro_sock >= 0) {
-		close(ro_sock);
-		unlink(opts->ro_path);
-	}
-
-	/* Remove pidfile */
-	if (pidfd >= 0) {
-		if (unlink(opts->pidfile) < 0) {
-			syslog(LOG_ERR, "Can't remove pid-file %s: %s\n",
-			opts->pidfile, strerror(errno));
-		}
-	}
-
-	/* Free command line options */
-	opts_free(opts);
-
-	syslog(LOG_ERR, "Stop daemon.\n");
-
-	return retval;
-}
-
-/*--------- Create listen socket--------------------------- */
-static int create_listen_socket(const char *path,
-	uid_t uid, gid_t gid, mode_t mode)
-{
-	int sock = -1;
-	struct sockaddr_un laddr;
-	const int reuseaddr = 1;
-
-	if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
-		syslog(LOG_ERR, "Can't create socket: %s\n", strerror(errno));
-		goto err1;
-	}
-	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
-		&reuseaddr, sizeof(reuseaddr))) {
-		syslog(LOG_ERR, "Can't set socket options: %s\n", strerror(errno));
-		goto err1;
-	}
-	laddr.sun_family = AF_UNIX;
-	strncpy(laddr.sun_path, path, USOCK_PATH_MAX);
-	laddr.sun_path[USOCK_PATH_MAX - 1] = '\0';
-	if (bind(sock, (struct sockaddr *)&laddr, sizeof(laddr))) {
-		syslog(LOG_ERR, "Can't bind socket: %s\n", strerror(errno));
-		goto err1;
-	}
-	if (chown(path, uid, gid)) {
-		syslog(LOG_ERR, "Can't chown socket: %s\n", strerror(errno));
-		goto err2;
-	}
-	if (chmod(path, mode)) {
-		syslog(LOG_ERR, "Can't chmod socket: %s\n", strerror(errno));
-		goto err2;
-	}
-	if (listen(sock, 10)) {
-		syslog(LOG_ERR, "Can't listen socket: %s\n", strerror(errno));
-		goto err2;
-	}
-
-	return sock;
-
-err2:
-	unlink(path);
-err1:
-	if (sock >= 0)
-		close(sock);
-
-	return -1;
-}
-
-/*--------------------------------------------------------- */
-static char * process_query(konf_buf_t *tbuf, konf_tree_t * conf, char *str)
-{
-	int i;
-	int res;
-	konf_tree_t *iconf;
-	konf_tree_t *tmpconf;
-	konf_query_t *query;
-	char *retval = NULL;
-	konf_query_op_e ret = KONF_QUERY_OP_ERROR;
-
-#ifdef DEBUG
-	fprintf(stderr, "REQUEST: %s\n", str);
-#endif
-	/* Parse query */
-	query = konf_query_new();
-	res = konf_query_parse_str(query, str);
-	if (res < 0) {
-		konf_query_free(query);
-		return NULL;
-	}
-#ifdef DEBUG
-	konf_query_dump(query);
-#endif
-
-	/* Restrict RO socket for non-DUMP operation */
-	if (!konf_buf__get_data(tbuf) &&
-		(konf_query__get_op(query) != KONF_QUERY_OP_DUMP)) {
-#ifdef DEBUG
-		fprintf(stderr, "Permission denied. Read-only socket.\n");
-#endif
-		konf_query_free(query);
-		return NULL;
-	}
-
-	/* Go through the pwd */
-	iconf = conf;
-	for (i = 0; i < konf_query__get_pwdc(query); i++) {
-		if (!(iconf = konf_tree_find_conf(iconf,
-			konf_query__get_pwd(query, i), 0, 0))) {
-			iconf = NULL;
-			break;
-		}
-	}
-
-	if (!iconf) {
-#ifdef DEBUG
-		fprintf(stderr, "Unknown path.\n");
-#endif
-		konf_query_free(query);
-		return NULL;
-	}
-
-	switch (konf_query__get_op(query)) {
-
-	case KONF_QUERY_OP_SET:
-		if (konf_query__get_unique(query)) {
-			int exist = 0;
-			exist = konf_tree_del_pattern(iconf,
-				konf_query__get_line(query),
-				konf_query__get_unique(query),
-				konf_query__get_pattern(query),
-				konf_query__get_priority(query),
-				konf_query__get_seq(query),
-				konf_query__get_seq_num(query));
-			if (exist < 0)
-				break;
-			if (exist > 0) {
-				ret = KONF_QUERY_OP_OK;
-				break;
-			}
-		}
-		tmpconf = konf_tree_new_conf(iconf,
-			konf_query__get_line(query), konf_query__get_priority(query),
-			konf_query__get_seq(query), konf_query__get_seq_num(query));
-		if (!tmpconf)
-			break;
-		konf_tree__set_splitter(tmpconf, konf_query__get_splitter(query));
-		konf_tree__set_depth(tmpconf, konf_query__get_pwdc(query));
-		ret = KONF_QUERY_OP_OK;
-		break;
-
-	case KONF_QUERY_OP_UNSET:
-		if (konf_tree_del_pattern(iconf,
-			NULL,
-			BOOL_TRUE,
-			konf_query__get_pattern(query),
-			konf_query__get_priority(query),
-			konf_query__get_seq(query),
-			konf_query__get_seq_num(query)) < 0)
-			break;
-		ret = KONF_QUERY_OP_OK;
-		break;
-
-	case KONF_QUERY_OP_DUMP:
-		if (dump_running_config(konf_buf__get_fd(tbuf), iconf, query))
-			break;
-		ret = KONF_QUERY_OP_OK;
-		break;
-
-	default:
-		break;
-	}
-
-#ifdef DEBUG
-	/* Print whole tree */
-	konf_tree_fprintf(conf, stderr, NULL, -1, -1, BOOL_TRUE, BOOL_TRUE, 0);
-#endif
-
-	/* Free resources */
-	konf_query_free(query);
-
-	switch (ret) {
-	case KONF_QUERY_OP_OK:
-		lub_string_cat(&retval, "-o");
-		break;
-	case KONF_QUERY_OP_ERROR:
-		lub_string_cat(&retval, "-e");
-		break;
-	default:
-		lub_string_cat(&retval, "-e");
-		break;
-	};
-
-#ifdef DEBUG
-	fprintf(stderr, "ANSWER: %s\n", retval);
-#endif
-
-	return retval;
-}
-
-/*--------------------------------------------------------- */
-/*
- * Signal handler for temination signals (like SIGTERM, SIGINT, ...)
- */
-static void sighandler(int signo)
-{
-	signo = signo; /* Happy compiler */
-
-	sigterm = 1;
-}
-
-/*--------------------------------------------------------- */
-int answer_send(int sock, const char *command)
-{
-	if (!command) {
-		errno = EINVAL;
-		return -1;
-	}
-	return send(sock, command, strlen(command) + 1, MSG_NOSIGNAL);
-}
-
-/*--------------------------------------------------------- */
-static int dump_running_config(int sock, konf_tree_t *conf, konf_query_t *query)
-{
-	FILE *fd;
-	char *filename;
-	int dupsock = -1;
-
-	if ((filename = konf_query__get_path(query))) {
-		if (!(fd = fopen(filename, "w")))
-			return -1;
-	} else {
-		if ((dupsock = dup(sock)) < 0)
-			return -1;
-		fd = fdopen(dupsock, "w");
-	}
-	if (!filename) {
-		fprintf(fd, "-t\n");
-#ifdef DEBUG
-		fprintf(stderr, "ANSWER: -t\n");
-#endif
-	}
-	konf_tree_fprintf(conf,
-		fd,
-		konf_query__get_pattern(query),
-		konf_query__get_pwdc(query) - 1,
-		konf_query__get_depth(query),
-		konf_query__get_seq(query),
-		konf_query__get_splitter(query),
-		0);
-	if (!filename) {
-		fprintf(fd, "\n");
-#ifdef DEBUG
-		fprintf(stderr, "SEND DATA: \n");
-#endif
-	}
-
-	fclose(fd);
-
-	return 0;
-}
-
-/*--------------------------------------------------------- */
-/* Implement own simple daemon() to don't use Non-POSIX */
-int daemonize(int nochdir, int noclose)
-{
-	int fd;
-	int pid;
-
-	pid = fork();
-	if (-1 == pid)
-		return -1;
-	if (pid > 0)
-		_exit(0); /* Exit parent */
-	if (setsid() == -1)
-		return -1;
-	if (!nochdir) {
-		if (chdir("/"))
-			return -1;
-	}
-	if (!noclose) {
-		fd = open("/dev/null", O_RDWR, 0);
-		if (fd < 0)
-			return -1;
-		dup2(fd, STDIN_FILENO);
-		dup2(fd, STDOUT_FILENO);
-		dup2(fd, STDERR_FILENO);
-		if (fd > STDERR_FILENO)
-			close(fd);
-	}
-
-	return 0;
-}
-
-/*--------------------------------------------------------- */
-/* Initialize option structure by defaults */
-struct options *opts_init(void)
-{
-	struct options *opts = NULL;
-
-	opts = malloc(sizeof(*opts));
-	assert(opts);
-	opts->debug = 0; /* daemonize by default */
-	opts->socket_path = strdup(KONFD_SOCKET_PATH);
-	opts->ro_path = NULL;
-	opts->pidfile = strdup(KONFD_PIDFILE);
-	opts->chroot = NULL;
-	opts->uid = getuid();
-	opts->gid = getgid();
-	opts->log_facility = LOG_DAEMON;
-
-	return opts;
-}
-
-/*--------------------------------------------------------- */
-/* Free option structure */
-void opts_free(struct options *opts)
-{
-	if (opts->socket_path)
-		free(opts->socket_path);
-	if (opts->ro_path)
-		free(opts->ro_path);
-	if (opts->pidfile)
-		free(opts->pidfile);
-	if (opts->chroot)
-		free(opts->chroot);
-	free(opts);
-}
-
-/*--------------------------------------------------------- */
-/* Parse command line options */
-static int opts_parse(int argc, char *argv[], struct options *opts)
-{
-	static const char *shortopts = "hvs:S:p:u:g:dr:O:";
-#ifdef HAVE_GETOPT_LONG
-	static const struct option longopts[] = {
-		{"help",	0, NULL, 'h'},
-		{"version",	0, NULL, 'v'},
-		{"socket",	1, NULL, 's'},
-		{"ro-socket",	1, NULL, 'S'},
-		{"pid",		1, NULL, 'p'},
-		{"user",	1, NULL, 'u'},
-		{"group",	1, NULL, 'g'},
-		{"debug",	0, NULL, 'd'},
-		{"chroot",	1, NULL, 'r'},
-		{"facility",	1, NULL, 'O'},
-		{NULL,		0, NULL, 0}
-	};
-#endif
-	optind = 1;
-	while(1) {
-		int opt;
-#ifdef HAVE_GETOPT_LONG
-		opt = getopt_long(argc, argv, shortopts, longopts, NULL);
-#else
-		opt = getopt(argc, argv, shortopts);
-#endif
-		if (-1 == opt)
-			break;
-		switch (opt) {
-		case 's':
-			if (opts->socket_path)
-				free(opts->socket_path);
-			opts->socket_path = strdup(optarg);
-			break;
-		case 'S':
-			if (opts->ro_path)
-				free(opts->ro_path);
-			opts->ro_path = strdup(optarg);
-			break;
-		case 'p':
-			if (opts->pidfile)
-				free(opts->pidfile);
-			opts->pidfile = strdup(optarg);
-			break;
-		case 'r':
-#ifdef HAVE_CHROOT
-			if (opts->chroot)
-				free(opts->chroot);
-			opts->chroot = strdup(optarg);
-#else
-			fprintf(stderr, "Error: The --chroot option is not supported.\n");
-			return -1;
-#endif
-			break;
-		case 'd':
-			opts->debug = 1;
-			break;
-		case 'u': {
-#ifdef HAVE_PWD_H
-			struct passwd *pwd = getpwnam(optarg);
-			if (!pwd) {
-				fprintf(stderr, "Error: Can't identify user \"%s\"\n",
-					optarg);
-				return -1;
-			}
-			opts->uid = pwd->pw_uid;
-#else
-			fprintf(stderr, "The --user option is not supported.\n");
-			return -1;
-#endif
-			break;
-		}
-		case 'g': {
-#ifdef HAVE_GRP_H
-			struct group *grp = getgrnam(optarg);
-			if (!grp) {
-				fprintf(stderr, "Can't identify group \"%s\"\n",
-					optarg);
-				return -1;
-			}
-			opts->gid = grp->gr_gid;
-#else
-			fprintf(stderr, "The --group option is not supported.\n");
-			return -1;
-#endif
-			break;
-		}
-		case 'O':
-			if (lub_log_facility(optarg, &(opts->log_facility))) {
-				fprintf(stderr, "Error: Illegal syslog facility %s.\n", optarg);
-				help(-1, argv[0]);
-				exit(-1);
-			}
-			break;
-		case 'h':
-			help(0, argv[0]);
-			exit(0);
-			break;
-		case 'v':
-			version(VERSION);
-			exit(0);
-			break;
-		default:
-			help(-1, argv[0]);
-			exit(-1);
-			break;
-		}
-	}
-
-	return 0;
-}
-
-/*--------------------------------------------------------- */
-/* Print help message */
-static void help(int status, const char *argv0)
-{
-	const char *name = NULL;
-
-	if (!argv0)
-		return;
-
-	/* Find the basename */
-	name = strrchr(argv0, '/');
-	if (name)
-		name++;
-	else
-		name = argv0;
-
-	if (status != 0) {
-		fprintf(stderr, "Try `%s -h' for more information.\n",
-			name);
-	} else {
-		printf("Usage: %s [options]\n", name);
-		printf("Daemon to store user configuration (i.e. commands). "
-			"The part of the klish project.\n");
-		printf("Options:\n");
-		printf("\t-v, --version\tPrint version.\n");
-		printf("\t-h, --help\tPrint this help.\n");
-		printf("\t-d, --debug\tDebug mode. Don't daemonize.\n");
-		printf("\t-s <path>, --socket=<path>\tSpecify the UNIX socket "
-			"filesystem path to listen on.\n");
-		printf("\t-p <path>, --pid=<path>\tFile to save daemon's PID to.\n");
-		printf("\t-r <path>, --chroot=<path>\tDirectory to chroot.\n");
-		printf("\t-u <user>, --user=<user>\tExecute process as"
-			" specified user.\n");
-		printf("\t-g <group>, --group=<group>\tExecute process as"
-			" specified group.\n");
-		printf("\t-O, --facility\tSyslog facility. Default is DAEMON.\n");
-	}
-}

+ 0 - 31
bin/module.am

@@ -1,31 +0,0 @@
-## Process this file with automake to produce Makefile.in
-bin_PROGRAMS += \
-	bin/clish \
-	bin/konfd \
-	bin/konf \
-	bin/sigexec
-
-bin_clish_SOURCES = bin/clish.c
-bin_clish_LDADD = \
-	libclish.la \
-	libkonf.la \
-	libtinyrl.la \
-	liblub.la \
-	$(LIBOBJS) \
-	@CLISH_PLUGIN_BUILTIN_LIBS@
-
-bin_konfd_SOURCES = bin/konfd.c
-bin_konfd_LDADD = \
-	libkonf.la \
-	liblub.la \
-	$(LIBOBJS)
-
-bin_konf_SOURCES = bin/konf.c
-bin_konf_LDADD = \
-	libkonf.la \
-	liblub.la \
-	$(LIBOBJS)
-
-bin_sigexec_SOURCES = bin/sigexec.c
-bin_sigexec_LDADD = \
-	$(LIBOBJS)

+ 0 - 123
bin/sigexec.c

@@ -1,123 +0,0 @@
-/*
- * sigexec.c
- *
- * Programm to execute processes with unblocked signals.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>
-
-#if WITH_INTERNAL_GETOPT
-#include "libc/getopt.h"
-#else
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-#endif
-
-#ifndef VERSION
-#define VERSION 1.5.6
-#endif
-#define QUOTE(t) #t
-#define version(v) printf("%s\n", v)
-
-static void help(int status, const char *argv0);
-
-int main(int argc, char *argv[])
-{
-	char **child_argv;
-	sigset_t sigs;
-
-	static const char *shortopts = "+hv";
-#ifdef HAVE_GETOPT_LONG
-	static const struct option longopts[] = {
-		{"help",	0, NULL, 'h'},
-		{"version",	0, NULL, 'v'},
-		{NULL,		0, NULL, 0}
-	};
-#endif
-
-	while(1) {
-		int opt;
-#ifdef HAVE_GETOPT_LONG
-		opt = getopt_long(argc, argv, shortopts, longopts, NULL);
-#else
-		opt = getopt(argc, argv, shortopts);
-#endif
-		if (-1 == opt)
-			break;
-		switch (opt) {
-		case 0:
-			break;
-		case 'h':
-			help(0, argv[0]);
-			exit(0);
-			break;
-		case 'v':
-			version(VERSION);
-			exit(0);
-			break;
-		default:
-			help(1, argv[0]);
-			break;
-		}
-	}
-
-	child_argv = &argv[optind];
-	/* Check user command */
-	if (! child_argv[0]) {
-		fprintf(stderr, "Error: Nothing to execute.\n");
-		return 1;
-	}
-
-	/* Unblock signals */
-	sigemptyset(&sigs);
-	sigprocmask(SIG_SETMASK, &sigs, NULL);
-
-	/* Execute user command */
-/*	fprintf(stderr, "%s %s %s\n", child_argv[0], child_argv[1], child_argv[2]); */
-	if (execvp(child_argv[0], child_argv) < 0) {
-		fprintf(stderr, "Error: Cannot execute %s: %s\n",
-			child_argv[0], strerror(errno));
-		return 1;
-	}
-
-	return 0;
-}
-
-/*--------------------------------------------------------- */
-/* Print help message */
-static void help(int status, const char *argv0)
-{
-	const char *name = NULL;
-
-	if (!argv0)
-		return;
-
-	/* Find the basename */
-	name = strrchr(argv0, '/');
-	if (name)
-		name++;
-	else
-		name = argv0;
-
-	if (status != 0) {
-		fprintf(stderr, "Try `%s -h' for more information.\n",
-			name);
-	} else {
-		printf("Usage: %s [options] -- <command to execute>\n", name);
-		printf("Utility to execute process with unblocked signals.\n");
-		printf("Options:\n");
-		printf("\t-v, --version\tPrint utility version.\n");
-		printf("\t-h, --help\tPrint this help.\n");
-	}
-}

+ 0 - 580
klish.xsd

@@ -1,580 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://clish.sourceforge.net/XMLSchema" targetNamespace="http://clish.sourceforge.net/XMLSchema">
-
-
-	<xs:annotation>
-		<xs:appinfo>XML schema for klish configuration files</xs:appinfo>
-		<xs:documentation xml:lang="en">
-		The klish utility uses XML files for configuration. This schema
-		allows to validate klish XML files. To check XML files use the
-		following command:
-		'xmllint --schema /path/to/klish.xsd --noout *.xml'
-		</xs:documentation>
-		<xs:documentation xml:lang="ru">
-		Утилита klish использует формат XML для своих конфигурационных
-		файлов. Схема позволяет проверить эти конфигурационные XML файлы
-		на правильность. Следующая команда выполнит проверку:
-		'xmllint --schema /path/to/klish.xsd --noout *.xml'
-		</xs:documentation>
-	</xs:annotation>
-
-
-	<xs:element name="KLISH" type="klish_t"/>
-	<xs:element name="VIEW" type="view_t"/>
-	<xs:element name="COMMAND" type="command_t"/>
-	<xs:element name="FILTER" type="command_t"/>
-	<xs:element name="STARTUP" type="startup_t"/>
-	<xs:element name="ACTION" type="action_t"/>
-	<xs:element name="OVERVIEW" type="overview_t"/>
-	<xs:element name="DETAIL" type="detail_t"/>
-	<xs:element name="PTYPE" type="ptype_t"/>
-	<xs:element name="PARAM" type="param_t"/>
-	<xs:element name="NAMESPACE" type="namespace_t"/>
-	<xs:element name="VAR" type="var_t"/>
-	<xs:element name="WATCHDOG" type="wdog_t"/>
-	<xs:element name="HOTKEY" type="hotkey_t"/>
-	<xs:element name="PLUGIN" type="plugin_t"/>
-	<xs:element name="HOOK" type="hook_t"/>
-
-
-	<xs:complexType name="klish_t">
-		<xs:annotation>
-			<xs:documentation xml:lang="en">
-			'KLISH' is the top level container. Any object (command,
-			type, var) which are defined within this tag are global
-			in scope i.e. it is visible from all 'VIEW's.
-			</xs:documentation>
-			<xs:documentation xml:lang="ru">
-			Тег 'KLISH' - контейнер верхнего уровня. Все остальные
-			теги должны быть вложенными. Любой объект (команда,
-			тип, переменная т.д.), заданный внутри этого тега,
-			считается глобальным, т.е. видимым их любых 'VIEW".
-			</xs:documentation>
-		</xs:annotation>
-		<xs:sequence>
-			<xs:element ref="OVERVIEW" minOccurs="0"/>
-			<xs:element ref="STARTUP" minOccurs="0"/>
-			<xs:element ref="PTYPE" minOccurs="0" maxOccurs="unbounded"/>
-			<xs:element ref="COMMAND" minOccurs="0" maxOccurs="unbounded"/>
-			<xs:element ref="VIEW" minOccurs="0" maxOccurs="unbounded"/>
-			<xs:element ref="NAMESPACE" minOccurs="0" maxOccurs="unbounded"/>
-			<xs:element ref="VAR" minOccurs="0" maxOccurs="unbounded"/>
-			<xs:element ref="WATCHDOG" minOccurs="0" maxOccurs="1"/>
-			<xs:element ref="HOTKEY" minOccurs="0" maxOccurs="unbounded"/>
-			<xs:element ref="PLUGIN" minOccurs="0" maxOccurs="unbounded"/>
-			<xs:element ref="HOOK" minOccurs="0" maxOccurs="unbounded"/>
-		</xs:sequence>
-	</xs:complexType>
-
-<!--
-***********************************************************
-* Identify some attribute groups
-***********************************************************
--->
-	<xs:attributeGroup name="menu_item_g">
-		<xs:attribute name="name" type="xs:string" use="required"/>
-		<xs:attribute name="help" type="xs:string" use="required"/>
-	</xs:attributeGroup>
-
-<!--
-*******************************************************
-* <PTYPE> is used to define the syntax for a parameter type.
-*
-* name - a textual name for this type. This name can be used to
-*	reference this type within a <PARAM? ptype attribute.
-*
-* help - a textual string which describes the syntax of this type.
-*	When a parameter is filled out incorrectly on the CLI, this
-*	text will be used to prompt the user to fill out the value 
-*	correctly.
-*
-* pattern - A regular expression which defines the syntax of the type.
-*
-* method - The means by which the pattern is interpreted.
-*
-*	regexp [default] - A POSIX regular expression.
-*
-*	integer - A numeric definition "min..max"
-*
-*	select  - A list of possible values.
-*		The syntax of the string is of the form:
-*		"valueOne(ONE) valueTwo(TWO) valueThree(THREE)"
-*		where the text before the parethesis defines the syntax 
-*		that the user must use, and the value within the parenthesis 
-*		is the result expanded as a parameter value.
-*
-*	code - The PTYPE check is handled by user-defined code.
-*		The code can be defined by builtin func or ACTION.
-*
-* preprocess  - An optional directive to process the value entered before
-*	validating it. This can greatly simplify the regular expressions
-*	needed to match case insensitive values.
-*
-*	none [default] - do nothing
-*
-*	toupper - before validation convert to uppercase.
-*
-*	tolower - before validation convert to lowercase.
-*
-********************************************************
--->
-	<xs:simpleType name="ptype_method_e">
-		<xs:restriction base="xs:string">
-			<xs:enumeration value="regexp"/>
-			<xs:enumeration value="integer"/>
-			<xs:enumeration value="unsignedInteger"/>
-			<xs:enumeration value="select"/>
-			<xs:enumeration value="choice"/>
-			<xs:enumeration value="subcommand"/>
-			<xs:enumeration value="code"/>
-		</xs:restriction>
-	</xs:simpleType>
-
-	<xs:simpleType name="ptype_preprocess_e">
-		<xs:restriction base="xs:string">
-			<xs:enumeration value="none"/>
-			<xs:enumeration value="toupper"/>
-			<xs:enumeration value="tolower"/>
-		</xs:restriction>
-	</xs:simpleType>
-
-	<xs:complexType name="ptype_t">
-		<xs:sequence>
-			<xs:element ref="ACTION" minOccurs="0"/>
-		</xs:sequence>
-		<xs:attributeGroup ref="menu_item_g"/>
-		<xs:attribute name="pattern" type="xs:string"/>
-		<xs:attribute name="method" type="ptype_method_e" use="optional" default="regexp"/>
-		<xs:attribute name="preprocess" type="ptype_preprocess_e" use="optional" default="none"/>
-	</xs:complexType>
-
-<!--
-*******************************************************
-* <VIEW> defines the contents of a specific CLI view.
-*
-* name - a textual name for the view
-*
-* prompt - a textual definition of the prompt to be
-*	used whilst in this view.
-*	NB. The prompt may contain environment
-*	or dynamic variables which are expanded
-*	before display.
-*
-* [depth] - a depth of nested view (uses for config).
-*
-* [restore] - restore the depth or view of commands
-*	contained by this view
-*
-* [access] - access rights
-*
-********************************************************
--->
-
-	<xs:simpleType name="restore_t">
-		<xs:restriction base="xs:string">
-			<xs:enumeration value="none"/>
-			<xs:enumeration value="depth"/>
-			<xs:enumeration value="view"/>
-		</xs:restriction>
-	</xs:simpleType>
-
-	<xs:complexType name="view_t">
-		<xs:sequence>
-			<xs:element ref="NAMESPACE" minOccurs="0" maxOccurs="unbounded"/>
-			<xs:element ref="COMMAND" minOccurs="0" maxOccurs="unbounded"/>
-			<xs:element ref="HOTKEY" minOccurs="0" maxOccurs="unbounded"/>
-		</xs:sequence>
-		<xs:attribute name="name" type="xs:string" use="required"/>
-		<xs:attribute name="prompt" type="xs:string" use="optional"/>
-		<xs:attribute name="depth" type="xs:string" use="optional" default="0"/>
-		<xs:attribute name="restore" type="restore_t" use="optional" default="none"/>
-		<xs:attribute name="access" type="xs:string" use="optional"/>
-	</xs:complexType>
-
-<!--
-*******************************************************
-* <STARTUP> is used to define what happens when the CLI
-* is started. Any text held in a <DETAIL> sub-element will
-* be used as banner text, then any defined <ACTION> will be 
-* executed. This action may provide Message Of The Day (MOTD)
-* type behaviour.
-*
-* view - defines the view which will be transitioned to, on 
-*	successful execution of any <ACTION> tag.
-*
-* [viewid] - defined the new value of the ${VIEWID} variable to
-*	be used if a transition to a new view occurs.
-*
-* [default_shebang] - The default shebang for all commands.
-*
-* [timeout] - The idle timeout. The clish will exit if user
-*	have not press any key while this timeout.
-*
-* [lock] - The same as lock for COMMAND tag.
-*
-* [interrupt] - The same as interrupt for COMMAND tag.
-*
-* [default_plugin] - Use (or don't use) default plugin.
-*	It can be true or false.
-********************************************************
--->
-	<xs:complexType name="startup_t">
-		<xs:sequence>
-			<xs:element ref="DETAIL" minOccurs="0"/>
-			<xs:element ref="ACTION" minOccurs="0"/>
-		</xs:sequence>
-		<xs:attribute name="view" type="xs:string" use="required"/>
-		<xs:attribute name="viewid" type="xs:string" use="optional"/>
-		<xs:attribute name="default_shebang" type="xs:string" use="optional"/>
-		<xs:attribute name="timeout" type="xs:string" use="optional"/>
-		<xs:attribute name="default_plugin" type="xs:boolean" use="optional" default="true"/>
-	</xs:complexType>
-
-<!--
-*******************************************************
-* <COMMAND> is used to define a command within the CLI.
-*
-* name - a textual name for this command. (This may contain
-*	spaces e.g. "display acl")
-*
-* help - a textual string which describes the purpose of the
-*	command.
-*
-* [view] - defines the view which will be transitioned to, on 
-*	successful execution of any <ACTION> tag. By default the
-*	current view stays in scope.
-*
-* [viewid] - defined the new value of the ${VIEWID} variable to
-*	be used if a transition to a new view occurs. By default
-*	the viewid will retain it's current value.
-*
-* [access] - defines the user group/level to which execution of this 
-*	command is restricted. By default there is no restriction.
-*	The exact interpretation of this field is dependant on the
-*	client of libclish but for example the clish and tclish 
-*	applications map this to the UNIX user groups.
-*
-* [escape_chars] - defines the characters which will be escaped (e.g. \$) before
-*	being expanded as a variable. By default the following
-*	characters will be escaped `|$<>&()#
-*
-* [args] - defines a parameter name to be used to gather the rest of the
-*	command line after the formally defined parameters 
-*	(PARAM elements). The formatting of this parameter is a raw
-*	string containing as many words as there are on the rest of the
-*	command line.
-*
-* [args_help] - a textual string which describes the purpose of the 'args' 
-*	parameter. If the "args" attribute is given then this MUST be
-*	given also.
-*
-********************************************************
--->
-	<xs:complexType name="command_t">
-		<xs:sequence>
-			<xs:element ref="DETAIL" minOccurs="0"/>
-			<xs:element ref="PARAM" minOccurs="0" maxOccurs="unbounded"/>
-			<xs:element ref="ACTION" minOccurs="0"/>
-		</xs:sequence>
-		<xs:attributeGroup ref="menu_item_g"/>
-		<xs:attribute name="ref" type="xs:string" use="optional"/>
-		<xs:attribute name="view" type="xs:string" use="optional"/>
-		<xs:attribute name="viewid" type="xs:string" use="optional"/>
-		<xs:attribute name="access" type="xs:string" use="optional"/>
-		<xs:attribute name="args" type="xs:string" use="optional"/>
-		<xs:attribute name="args_help" type="xs:string" use="optional"/>
-		<xs:attribute name="escape_chars" type="xs:string" use="optional"/>
-	</xs:complexType>
-
-<!--
-*******************************************************
-* <PARAM> This tag is used to define a parameter for a command.
-*
-* name - a textual name for this parameter. 
-*
-* help - a textual string which describes the purpose of the
-*	parameter.
-*
-* ptype - Reference to a PTYPE name. This parameter will be 
-*	validated against the syntax specified for that type.
-*	The special value of "" indicates the parameter is a boolean flag.
-*	The verbatim presence of the texual name on the command line
-*	simply controls the conditional variable expansion for this 
-*	parameter.
-*
-* [mode] - Parameter mode. It can be "common", "switch" or "subcommand".
-*
-* [prefix] - defines the prefix for an optional parameter. A prefix
-*	with this value on the command line will signify the presence
-*	of an additional argument which will be validated as the
-*	value of this parameter.
-*
-* [optional] - Specify whether parameter is optional. The allowed values
-*	is "true" or "false". It's false by default.
-*
-* [order] - Used only together with "optional=true" field.
-*	If order="true" then user can't enter previously declared
-*	optional parameters after current validated parameter.
-*	The allowed values is "true" or "false". It's false by default.
-*
-* [default] - defines a default value for a parameter. Any parameters
-*	at the end of command line which have default values need 
-*	not explicitly be entered.
-*
-* [value] - defines the user's value for subcommand. If this option
-*	is defined the entered parameter will be compared to this
-*	value instead the "name" field. If this field is defined
-*	the mode of PARAM will be forced to "subcommand". The
-*	feature is implemented to support subcommands with the
-*	same names.
-*
-* [hidden] - define the visibility of the parameter while ${__line}
-*	and ${__params} auto variables expanding. The allowed values
-*	is "true" and "false".
-*
-* [test] - define the condition (see the description of 'test'
-*	utility) to process this parameter.
-*
-* [access]  - access rights
-*
-********************************************************
--->
-	<xs:simpleType name="param_mode_t">
-		<xs:restriction base="xs:string">
-			<xs:enumeration value="common"/>
-			<xs:enumeration value="switch"/>
-			<xs:enumeration value="subcommand"/>
-		</xs:restriction>
-	</xs:simpleType>
-
-	<xs:complexType name="param_t">
-		<xs:sequence>
-			<xs:element ref="PARAM" minOccurs="0" maxOccurs="unbounded"/>
-		</xs:sequence>
-		<xs:attributeGroup ref="menu_item_g"/>
-		<xs:attribute name="ptype" type="xs:string" use="required"/>
-		<xs:attribute name="default" type="xs:string" use="optional"/>
-		<xs:attribute name="prefix" type="xs:string" use="optional"/>
-		<xs:attribute name="mode" type="param_mode_t" use="optional" default="common"/>
-		<xs:attribute name="optional" type="xs:boolean" use="optional" default="false"/>
-		<xs:attribute name="order" type="xs:boolean" use="optional" default="false"/>
-		<xs:attribute name="value" type="xs:string" use="optional"/>
-		<xs:attribute name="hidden" type="xs:boolean" use="optional" default="false"/>
-		<xs:attribute name="test" type="xs:string" use="optional"/>
-		<xs:attribute name="completion" type="xs:string" use="optional"/>
-		<xs:attribute name="access" type="xs:string" use="optional"/>
-	</xs:complexType>
-
-<!--
-********************************************************
-* <ACTION> specifies the action to be taken for
-* a command.
-*
-* The textual contents of the tag are variable expanded
-* (environment, dynamic and parameter) the the resulting
-* text is interpreted by the client's script interpreter.
-*
-* In addition the optional 'builtin' attribute can specify
-* the name of an internal command which will be invoked
-* instead of the client's script handler.
-*
-* NB. for security reasons any special shell characters 
-* (e.g. $|<>`) are escaped before evaluation.
-*
-* [builtin] - specify the name of an internally registered
-*	function. The content of the ACTION tag is
-*	taken as the arguments to this builtin function.
-*
-* [shebang] - specify the programm to execute the action
-*	script.
-*
-* [lock="true/false"] - the boolean field that specify to lock lockfile while
-*	action execution or not. Default is true. In a case the
-*	LEGACY macro is specified while klish building the
-*	value of this field is inherited from COMMAND tag (if
-*	lock is not specified in ACTION).
-*
-* [interrupt="true/false"] - the boolean field that specify that action can be
-*	be interrupted by Ctrl^C. Default is false. In a case the
-*	LEGACY macro is specified while klish building the
-*	value of this field is inherited from COMMAND tag (if
-*	attr is not specified in ACTION).
-*
-* [interactive="true/false"] - specify is action interactive. The
-*	interactive ACTIONs can't be used with piped ("|") output.
-*
-********************************************************
--->
-	<xs:complexType name="action_t">
-		<xs:simpleContent>
-			<xs:extension base="xs:string">
-				<xs:attribute name="builtin" type="xs:string" use="optional"/>
-				<xs:attribute name="shebang" type="xs:string" use="optional"/>
-				<xs:attribute name="lock" type="xs:boolean" use="optional" default="true"/>
-				<xs:attribute name="interrupt" type="xs:boolean" use="optional" default="false"/>
-				<xs:attribute name="interactive" type="xs:boolean" use="optional" default="false"/>
-			</xs:extension>
-		</xs:simpleContent>
-	</xs:complexType>
-
-<!--
-********************************************************
-* <OVERVIEW> specifies a textual description of the shell.
-*
-* This should provide instructions about key bindings and
-* escape sequences which can be used in the CLI.
-*
-********************************************************
--->
-	<xs:simpleType name="overview_t">
-		<xs:restriction base="xs:string">
-			<xs:whiteSpace value="preserve"/>
-		</xs:restriction>
-	</xs:simpleType>
-
-<!--
-********************************************************
-* <DETAIL> specifies a textual description.
-*
-* This may be used within the scope of a <COMMAND> 
-* element, in which case it would typically contain 
-* detailed usage instructions including examples.
-*
-* This may also be used within the scope of a <STARTUP>
-* element, in which case the text is used as the banner
-* details which are displayed on shell startup. This is
-* shown before any specified <ACTION> is executed.
-*
-* This text may also be used in the production of user manuals.
-********************************************************
--->
-	<xs:simpleType name="detail_t">
-		<xs:restriction base="xs:string">
-			<xs:whiteSpace value="preserve"/>
-		</xs:restriction>
-	</xs:simpleType>
-
-<!--
-*******************************************************
-* <NAMESPACE> import commands from specific view to current view.
-*
-* ref - the view to import commands from
-*
-* [prefix] - the prefix for imported commands
-*
-* [prefix_help] - the help for namespace prefix
-*
-* [help] - a boolean flag to use imported
-*	commands while help
-*
-* [completion] - a boolean flag to use imported
-*	commands while completion
-*
-* [context_help] - a boolean flag to use imported
-*	commands while context help
-*
-* [inherit] - a boolean flag to inherit nested
-*	namespace commands recursively
-*
-* [access] - access rights
-*
-********************************************************
--->
-	<xs:complexType name="namespace_t">
-		<xs:attribute name="ref" type="xs:string" use="required"/>
-		<xs:attribute name="prefix" type="xs:string" use="optional"/>
-		<xs:attribute name="prefix_help" type="xs:string" use="optional"/>
-		<xs:attribute name="help" type="xs:boolean" use="optional" default="false"/>
-		<xs:attribute name="completion" type="xs:boolean" use="optional" default="true"/>
-		<xs:attribute name="context_help" type="xs:boolean" use="optional" default="false"/>
-		<xs:attribute name="inherit" type="xs:boolean" use="optional" default="true"/>
-		<xs:attribute name="access" type="xs:string" use="optional"/>
-	</xs:complexType>
-
-<!--
-*******************************************************
-* <VAR> Specify the variable.
-*
-*
-*
-********************************************************
--->
-	<xs:complexType name="var_t">
-		<xs:sequence>
-			<xs:element ref="ACTION" minOccurs="0"/>
-		</xs:sequence>
-		<xs:attribute name="name" type="xs:string" use="required"/>
-		<xs:attribute name="help" type="xs:string" use="optional"/>
-		<xs:attribute name="value" type="xs:string" use="optional"/>
-		<xs:attribute name="dynamic" type="xs:boolean" use="optional" default="false"/>
-	</xs:complexType>
-
-<!--
-*******************************************************
-* <WATCHDOG> is used to recover system after errors.
-*
-********************************************************
--->
-	<xs:complexType name="wdog_t">
-		<xs:sequence>
-			<xs:element ref="ACTION" minOccurs="1"/>
-		</xs:sequence>
-	</xs:complexType>
-
-<!--
-*******************************************************
-* <HOTKEY> is used to define hotkey actions
-*
-********************************************************
--->
-	<xs:complexType name="hotkey_t">
-		<xs:attribute name="key" type="xs:string" use="required"/>
-		<xs:attribute name="cmd" type="xs:string" use="required"/>
-	</xs:complexType>
-
-<!--
-*******************************************************
-* <PLUGIN> is used to dynamically load plugins
-*
-* [rtld_global] - A boolean RTLD_GLOBAL flag for dlopen()
-*	while plugin loading. Default is "false".
-*
-********************************************************
--->
-	<xs:complexType name="plugin_t">
-		<xs:simpleContent>
-			<xs:extension base="xs:string">
-				<xs:attribute name="name" type="xs:string" use="required"/>
-				<xs:attribute name="alias" type="xs:string" use="optional"/>
-				<xs:attribute name="file" type="xs:string" use="optional"/>
-				<xs:attribute name="rtld_global" type="xs:boolean" use="optional" default="false"/>
-			</xs:extension>
-		</xs:simpleContent>
-	</xs:complexType>
-
-<!--
-*******************************************************
-* <HOOK> is used to redefine internal hooks
-*
-* name - The name of internal hook (init, fini, access, log).
-*
-* [builtin] - specify the name of an internally registered
-*	function.
-*
-********************************************************
--->
-	<xs:simpleType name="hook_list_e">
-		<xs:restriction base="xs:string">
-			<xs:enumeration value="init"/>
-			<xs:enumeration value="fini"/>
-			<xs:enumeration value="access"/>
-			<xs:enumeration value="log"/>
-		</xs:restriction>
-	</xs:simpleType>
-
-	<xs:complexType name="hook_t">
-		<xs:attribute name="name" type="hook_list_e"/>
-		<xs:attribute name="builtin" type="xs:string" use="optional"/>
-	</xs:complexType>
-
-</xs:schema>

+ 0 - 16
tinyrl/README

@@ -1,16 +0,0 @@
-/**
-\defgroup tinyrl "Tiny Readline Library"
-@{
-
-This library provides a simple replacement of the "readline" functionality.
-
-The readline interface and implementation has some fundamental flaws when
-it comes to try and run it within a single memory space envrioment. e.g. vxWorks
-- The use of global variables prevents multiple sessions from co-existing.
-- The comprehensiveness of the library makes it large, and it contains 
-  more features than are needed in an embedded system.
-- It relies on other (large) libraries which are not typically available on an
-  embedded system e.g. termcap.
-
-@}
-*/

+ 0 - 99
tinyrl/history.h

@@ -1,99 +0,0 @@
- /**
-\ingroup tinyrl
-\defgroup tinyrl_history history
-@{
-
-\brief This class handles the maintenance of a historical list of command lines.
-
-*/
-#ifndef _tinyrl_history_h
-#define _tinyrl_history_h
-
-#include "lub/c_decl.h"
-#include "lub/types.h"
-
-_BEGIN_C_DECL
-/**************************************
- * tinyrl_history_entry class interface
- ************************************** */
-typedef struct _tinyrl_history_entry tinyrl_history_entry_t;
-
-extern const char *tinyrl_history_entry__get_line(const tinyrl_history_entry_t *
-						  instance);
-extern unsigned tinyrl_history_entry__get_index(const tinyrl_history_entry_t *
-						instance);
-
-/**************************************
- * tinyrl_history class interface
- ************************************** */
-typedef struct _tinyrl_history tinyrl_history_t;
-
-/**
- * This type is used for the iteration of history entries
- */
-typedef struct _tinyrl_history_iterator tinyrl_history_iterator_t;
-/**
- * CLIENTS MUST NOT USE THESE FIELDS DIRECTLY
- */
-struct _tinyrl_history_iterator {
-	const tinyrl_history_t *history;
-	unsigned offset;
-};
-
-extern tinyrl_history_t *tinyrl_history_new(unsigned stifle);
-
-extern void tinyrl_history_delete(tinyrl_history_t * instance);
-
-extern void tinyrl_history_add(tinyrl_history_t * instance, const char *line);
-
-extern tinyrl_history_entry_t *tinyrl_history_getfirst(const tinyrl_history_t *
-						       instance,
-						       tinyrl_history_iterator_t
-						       * iter);
-extern tinyrl_history_entry_t *tinyrl_history_getlast(const tinyrl_history_t *
-						      instance,
-						      tinyrl_history_iterator_t
-						      * iter);
-
-extern tinyrl_history_entry_t *tinyrl_history_getnext(tinyrl_history_iterator_t
-						      * iter);
-
-extern tinyrl_history_entry_t
-    *tinyrl_history_getprevious(tinyrl_history_iterator_t * iter);
-
-/*
-HISTORY LIST MANAGEMENT 
-*/
-extern tinyrl_history_entry_t *tinyrl_history_remove(tinyrl_history_t *
-						     instance, unsigned offset);
-extern void tinyrl_history_clear(tinyrl_history_t * instance);
-extern void tinyrl_history_stifle(tinyrl_history_t * instance, unsigned stifle);
-extern unsigned tinyrl_history_unstifle(tinyrl_history_t * instance);
-extern bool_t tinyrl_history_is_stifled(const tinyrl_history_t * instance);
-
-extern int tinyrl_history_save(const tinyrl_history_t *instance, const char *fname);
-extern int tinyrl_history_restore(tinyrl_history_t *instance, const char *fname);
-
-    /*
-       INFORMATION ABOUT THE HISTORY LIST 
-     */
-extern tinyrl_history_entry_t **tinyrl_history_list(const tinyrl_history_t *
-						    instance);
-extern tinyrl_history_entry_t *tinyrl_history_get(const tinyrl_history_t *
-						  instance, unsigned offset);
-
-/*
- * HISTORY EXPANSION 
- */
-typedef enum {
-	tinyrl_history_NO_EXPANSION,
-	tinyrl_history_EXPANDED
-} tinyrl_history_expand_t;
-
-extern tinyrl_history_expand_t
-tinyrl_history_expand(const tinyrl_history_t * instance,
-		      const char *string, char **output);
-
-_END_C_DECL
-#endif				/* _tinyrl_history_h */
-/** @} tinyrl_history */

+ 0 - 482
tinyrl/history/history.c

@@ -1,482 +0,0 @@
-/*
- * history.c
- * 
- * Simple non-readline hooks for the cli library
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <errno.h>
-
-#include "private.h"
-#include "lub/string.h"
-#include "tinyrl/history.h"
-
-struct _tinyrl_history {
-	tinyrl_history_entry_t **entries;	/* pointer entries */
-	unsigned length;	/* Number of elements within this array */
-	unsigned size;		/* Number of slots allocated in this array */
-	unsigned current_index;
-	unsigned stifle;
-};
-
-/*------------------------------------- */
-void tinyrl_history_init(tinyrl_history_t * this, unsigned stifle)
-{
-	this->entries = NULL;
-	this->stifle = stifle;
-	this->current_index = 1;
-	this->length = 0;
-	this->size = 0;
-}
-
-/*------------------------------------- */
-void tinyrl_history_fini(tinyrl_history_t * this)
-{
-	tinyrl_history_entry_t *entry;
-	tinyrl_history_iterator_t iter;
-
-	/* release the resource associated with each entry */
-	for (entry = tinyrl_history_getfirst(this, &iter);
-	     entry; entry = tinyrl_history_getnext(&iter)) {
-		tinyrl_history_entry_delete(entry);
-	}
-	/* release the list */
-	free(this->entries);
-	this->entries = NULL;
-}
-
-/*------------------------------------- */
-tinyrl_history_t *tinyrl_history_new(unsigned stifle)
-{
-	tinyrl_history_t *this = malloc(sizeof(tinyrl_history_t));
-	if (NULL != this) {
-		tinyrl_history_init(this, stifle);
-	}
-	return this;
-}
-
-/*------------------------------------- */
-void tinyrl_history_delete(tinyrl_history_t * this)
-{
-	tinyrl_history_fini(this);
-	free(this);
-}
-
-/*
-HISTORY LIST MANAGEMENT 
-*/
-/*------------------------------------- */
-/* insert a new entry at the current offset */
-static void insert_entry(tinyrl_history_t * this, const char *line)
-{
-	tinyrl_history_entry_t *new_entry =
-	    tinyrl_history_entry_new(line, this->current_index++);
-	assert(this->length);
-	assert(this->entries);
-	if (new_entry) {
-		this->entries[this->length - 1] = new_entry;
-	}
-}
-
-/*------------------------------------- */
-/*
- * This frees the specified entries from the 
- * entries vector. NB it doesn't perform any shuffling.
- * This function is inclusive of start and end
- */
-static void
-free_entries(const tinyrl_history_t * this, unsigned start, unsigned end)
-{
-	unsigned i;
-	assert(start <= end);
-	assert(end < this->length);
-
-	for (i = start; i <= end; i++) {
-		tinyrl_history_entry_t *entry = this->entries[i];
-		tinyrl_history_entry_delete(entry);
-		entry = NULL;
-	}
-}
-
-/*------------------------------------- */
-/*
- * This removes the specified entries from the 
- * entries vector. Shuffling up the array as necessary 
- * This function is inclusive of start and end
- */
-static void
-remove_entries(tinyrl_history_t * this, unsigned start, unsigned end)
-{
-	unsigned delta = (end - start) + 1;	/* number of entries being deleted */
-	/* number of entries to shuffle */
-	unsigned num_entries = (this->length - end) - 1;
-	assert(start <= end);
-	assert(end < this->length);
-
-	if (num_entries) {
-		/* move the remaining entries down to close the array */
-		memmove(&this->entries[start],
-			&this->entries[end + 1],
-			sizeof(tinyrl_history_entry_t *) * num_entries);
-	}
-	/* now fix up the length variables */
-	this->length -= delta;
-}
-
-/*------------------------------------- */
-/* 
-Search the current history buffer for the specified 
-line and if found remove it.
-*/
-static bool_t remove_duplicate(tinyrl_history_t * this, const char *line)
-{
-	bool_t result = BOOL_FALSE;
-	unsigned i;
-
-	for (i = 0; i < this->length; i++) {
-		tinyrl_history_entry_t *entry = this->entries[i];
-		if (0 == strcmp(line, tinyrl_history_entry__get_line(entry))) {
-			free_entries(this, i, i);
-			remove_entries(this, i, i);
-			result = BOOL_TRUE;
-			break;
-		}
-	}
-	return result;
-}
-
-/*------------------------------------- */
-/* 
-add an entry to the end of the current array 
-if there is no space returns -1 else 0
-*/
-static void append_entry(tinyrl_history_t * this, const char *line)
-{
-	if (this->length < this->size) {
-		this->length++;
-
-		insert_entry(this, line);
-	}
-}
-
-/*------------------------------------- */
-/*
- add a new history entry replacing the oldest one 
- */
-static void add_n_replace(tinyrl_history_t * this, const char *line)
-{
-	if (BOOL_FALSE == remove_duplicate(this, line)) {
-		/* free the oldest entry */
-		free_entries(this, 0, 0);
-		/* shuffle the array */
-		remove_entries(this, 0, 0);
-	}
-	/* add the new entry */
-	append_entry(this, line);
-}
-
-/*------------------------------------- */
-/* add a new history entry growing the array if necessary */
-static void add_n_grow(tinyrl_history_t * this, const char *line)
-{
-	if (this->size == this->length) {
-		/* increment the history memory by 10 entries each time we grow */
-		unsigned new_size = this->size + 10;
-		size_t nbytes;
-		tinyrl_history_entry_t **new_entries;
-
-		nbytes = sizeof(tinyrl_history_entry_t *) * new_size;
-		new_entries = realloc(this->entries, nbytes);
-		if (NULL != new_entries) {
-			this->size = new_size;
-			this->entries = new_entries;
-		}
-	}
-	(void)remove_duplicate(this, line);
-	append_entry(this, line);
-}
-
-/*------------------------------------- */
-void tinyrl_history_add(tinyrl_history_t * this, const char *line)
-{
-	if (this->length && (this->length == this->stifle)) {
-		add_n_replace(this, line);
-	} else {
-		add_n_grow(this, line);
-	}
-}
-
-/*------------------------------------- */
-tinyrl_history_entry_t *tinyrl_history_remove(tinyrl_history_t * this,
-					      unsigned offset)
-{
-	tinyrl_history_entry_t *result = NULL;
-
-	if (offset < this->length) {
-		result = this->entries[offset];
-		/* do the biz */
-		remove_entries(this, offset, offset);
-	}
-	return result;
-}
-
-/*------------------------------------- */
-void tinyrl_history_clear(tinyrl_history_t * this)
-{
-	/* free all the entries */
-	free_entries(this, 0, this->length - 1);
-	/* and shuffle the array */
-	remove_entries(this, 0, this->length - 1);
-}
-
-/*------------------------------------- */
-void tinyrl_history_stifle(tinyrl_history_t * this, unsigned stifle)
-{
-	/* 
-	 * if we are stifling (i.e. non zero value) then 
-	 * delete the obsolete entries
-	 */
-	if (stifle) {
-		if (stifle < this->length) {
-			unsigned num_deletes = this->length - stifle;
-			/* free the entries */
-			free_entries(this, 0, num_deletes - 1);
-			/* shuffle the array shut */
-			remove_entries(this, 0, num_deletes - 1);
-		}
-		this->stifle = stifle;
-	}
-}
-
-/*------------------------------------- */
-unsigned tinyrl_history_unstifle(tinyrl_history_t * this)
-{
-	unsigned result = this->stifle;
-
-	this->stifle = 0;
-
-	return result;
-}
-
-/*------------------------------------- */
-bool_t tinyrl_history_is_stifled(const tinyrl_history_t * this)
-{
-	return this->stifle ? BOOL_TRUE : BOOL_FALSE;
-}
-
-/*
-INFORMATION ABOUT THE HISTORY LIST 
-*/
-tinyrl_history_entry_t *tinyrl_history_get(const tinyrl_history_t * this,
-					   unsigned position)
-{
-	unsigned i;
-	tinyrl_history_entry_t *entry = NULL;
-	for (i = 0; i < this->length; i++) {
-		entry = this->entries[i];
-		if (position == tinyrl_history_entry__get_index(entry)) {
-			/* found it */
-			break;
-		}
-		entry = NULL;
-	}
-	return entry;
-}
-
-/*------------------------------------- */
-tinyrl_history_expand_t
-tinyrl_history_expand(const tinyrl_history_t * this,
-		      const char *string, char **output)
-{
-	tinyrl_history_expand_t result = tinyrl_history_NO_EXPANSION;	/* no expansion */
-	const char *p, *start;
-	char *buffer = NULL;
-	unsigned len;
-
-	for (p = string, start = string, len = 0; *p; p++, len++) {
-		/* perform pling substitution */
-		if (*p == '!') {
-			/* assume the last command to start with... */
-			unsigned offset = this->current_index - 1;
-			unsigned skip;
-			tinyrl_history_entry_t *entry;
-
-			/* this could be an escape sequence */
-			if (p[1] != '!') {
-				int tmp;
-				int res;
-				/* read the numeric identifier */
-				res = sscanf(p, "!%d", &tmp);
-				if ((0 == res) || (EOF == res)) {
-					/* error so ignore it */
-					break;
-				}
-
-				if (tmp < 0) {
-					/* this is a relative reference */
-					/*lint -e737 Loss of sign in promotion from int to unsigend int */
-					offset += tmp;	/* adding a negative substracts... */
-					/*lint +e737 */
-				} else {
-					/* this is an absolute reference */
-					offset = (unsigned)tmp;
-				}
-			}
-			if (len > 0) {
-				/* we need to add in some previous plain text */
-				lub_string_catn(&buffer, start, len);
-			}
-
-			/* skip the escaped chars */
-			p += skip = strspn(p, "!-0123456789");
-
-			/* try and find the history entry */
-			entry = tinyrl_history_get(this, offset);
-			if (NULL != entry) {
-				/* reset the non-escaped references */
-				start = p;
-				len = 0;
-				/* add the expanded text to the buffer */
-				result = tinyrl_history_EXPANDED;
-				lub_string_cat(&buffer,
-					       tinyrl_history_entry__get_line
-					       (entry));
-			} else {
-				/* we simply leave the unexpanded sequence */
-				len += skip;
-			}
-		}
-	}
-	/* add any left over plain text */
-	lub_string_catn(&buffer, start, len);
-	*output = buffer;
-
-	return result;
-}
-
-/*-------------------------------------*/
-tinyrl_history_entry_t *tinyrl_history_getfirst(const tinyrl_history_t * this,
-						tinyrl_history_iterator_t *
-						iter)
-{
-	tinyrl_history_entry_t *result = NULL;
-
-	iter->history = this;
-	iter->offset = 0;
-
-	if (this->length) {
-		result = this->entries[iter->offset];
-	}
-	return result;
-}
-
-/*-------------------------------------*/
-tinyrl_history_entry_t *tinyrl_history_getnext(tinyrl_history_iterator_t * iter)
-{
-	tinyrl_history_entry_t *result = NULL;
-
-	if (iter->offset < iter->history->length - 1) {
-		iter->offset++;
-		result = iter->history->entries[iter->offset];
-	}
-
-	return result;
-}
-
-/*-------------------------------------*/
-tinyrl_history_entry_t *tinyrl_history_getlast(const tinyrl_history_t * this,
-					       tinyrl_history_iterator_t * iter)
-{
-	iter->history = this;
-	iter->offset = this->length;
-
-	return tinyrl_history_getprevious(iter);
-}
-
-/*-------------------------------------*/
-tinyrl_history_entry_t *tinyrl_history_getprevious(tinyrl_history_iterator_t *
-						   iter)
-{
-	tinyrl_history_entry_t *result = NULL;
-
-	if (iter->offset) {
-		iter->offset--;
-		result = iter->history->entries[iter->offset];
-	}
-
-	return result;
-}
-
-/*-------------------------------------*/
-/* Save command history to specified file */
-int tinyrl_history_save(const tinyrl_history_t *this, const char *fname)
-{
-	tinyrl_history_entry_t *entry;
-	tinyrl_history_iterator_t iter;
-	FILE *f;
-
-	if (!fname) {
-		errno = EINVAL;
-		return -1;
-	}
-	if (!(f = fopen(fname, "w")))
-		return -1;
-	for (entry = tinyrl_history_getfirst(this, &iter);
-		entry; entry = tinyrl_history_getnext(&iter)) {
-		if (fprintf(f, "%s\n", tinyrl_history_entry__get_line(entry)) < 0)
-			return -1;
-	}
-	fclose(f);
-
-	return 0;
-}
-
-/*-------------------------------------*/
-/* Restore command history from specified file */
-int tinyrl_history_restore(tinyrl_history_t *this, const char *fname)
-{
-	FILE *f;
-	char *p;
-	int part_len = 300;
-	char *buf;
-	int buf_len = part_len;
-	int res = 0;
-
-	if (!fname) {
-		errno = EINVAL;
-		return -1;
-	}
-	if (!(f = fopen(fname, "r")))
-		return 0; /* Can't find history file */
-
-	buf = malloc(buf_len);
-	p = buf;
-	while (fgets(p, buf_len - (p - buf), f)) {
-		char *ptmp = NULL;
-		char *el = strchr(buf, '\n');
-		if (el) { /* The whole line was readed */
-			*el = '\0';
-			tinyrl_history_add(this, buf);
-			p = buf;
-			continue;
-		}
-		buf_len += part_len;
-		ptmp = realloc(buf, buf_len);
-		if (!ptmp) {
-			res = -1;
-			goto end;
-		}
-		buf = ptmp;
-		p = buf + buf_len - part_len - 1;
-	}
-end:
-	free(buf);
-	fclose(f);
-
-	return res;
-}
-
-
-/*-------------------------------------*/

+ 0 - 55
tinyrl/history/history_entry.c

@@ -1,55 +0,0 @@
-/* tinyrl_history_entry.c */
-#include "private.h"
-#include "lub/string.h"
-#include <stdlib.h>
-
-struct _tinyrl_history_entry {
-	char *line;
-	unsigned index;
-};
-/*------------------------------------- */
-static void
-entry_init(tinyrl_history_entry_t * this, const char *line, unsigned index)
-{
-	this->line = lub_string_dup(line);
-	this->index = index;
-}
-
-/*------------------------------------- */
-static void entry_fini(tinyrl_history_entry_t * this)
-{
-	lub_string_free(this->line);
-	this->line = NULL;
-}
-
-/*------------------------------------- */
-tinyrl_history_entry_t *tinyrl_history_entry_new(const char *line,
-						 unsigned index)
-{
-	tinyrl_history_entry_t *this = malloc(sizeof(tinyrl_history_entry_t));
-	if (NULL != this) {
-		entry_init(this, line, index);
-	}
-	return this;
-}
-
-/*------------------------------------- */
-void tinyrl_history_entry_delete(tinyrl_history_entry_t * this)
-{
-	entry_fini(this);
-	free(this);
-}
-
-/*------------------------------------- */
-const char *tinyrl_history_entry__get_line(const tinyrl_history_entry_t * this)
-{
-	return this->line;
-}
-
-/*------------------------------------- */
-unsigned tinyrl_history_entry__get_index(const tinyrl_history_entry_t * this)
-{
-	return this->index;
-}
-
-/*------------------------------------- */

+ 0 - 7
tinyrl/history/module.am

@@ -1,7 +0,0 @@
-## Process this file with automake to produce Makefile.in
-libtinyrl_la_SOURCES      +=                                     \
-                            tinyrl/history/history.c         \
-                            tinyrl/history/history_entry.c   \
-                            tinyrl/history/private.h
-
-			

+ 0 - 9
tinyrl/history/private.h

@@ -1,9 +0,0 @@
-/* private.h */
-#include "tinyrl/history.h"
-/**************************************
- * protected interface to tinyrl_history_entry class
- ************************************** */
-extern tinyrl_history_entry_t *tinyrl_history_entry_new(const char *line,
-							unsigned index);
-
-extern void tinyrl_history_entry_delete(tinyrl_history_entry_t * instance);

+ 0 - 21
tinyrl/module.am

@@ -1,21 +0,0 @@
-## Process this file with automake to generate Makefile.in
-lib_LTLIBRARIES += libtinyrl.la
-libtinyrl_la_LIBADD = liblub.la
-libtinyrl_la_DEPENDENCIES = liblub.la
-
-libtinyrl_la_SOURCES = \
-	tinyrl/tinyrl.c \
-	tinyrl/private.h
-
-nobase_include_HEADERS += \
-	tinyrl/tinyrl.h \
-	tinyrl/history.h \
-	tinyrl/vt100.h
-
-EXTRA_DIST += \
-	tinyrl/history/module.am \
-	tinyrl/vt100/module.am \
-	tinyrl/README
-
-include $(top_srcdir)/tinyrl/history/module.am
-include $(top_srcdir)/tinyrl/vt100/module.am

+ 0 - 47
tinyrl/private.h

@@ -1,47 +0,0 @@
-#include <termios.h>
-
-#include "tinyrl/tinyrl.h"
-#include "tinyrl/vt100.h"
-
-/* define the class member data and virtual methods */
-struct _tinyrl {
-	const char *line;
-	unsigned max_line_length;
-	char *prompt;
-	size_t prompt_size; /* strlen() */
-	size_t prompt_len; /* Symbol positions */
-	char *buffer;
-	size_t buffer_size;
-	bool_t done;
-	bool_t completion_over;
-	bool_t completion_error_over;
-	unsigned point;
-	unsigned end;
-	tinyrl_completion_func_t *attempted_completion_function;
-	tinyrl_timeout_fn_t *timeout_fn; /* timeout callback */
-	tinyrl_keypress_fn_t *keypress_fn; /* keypress callback */
-	int state;
-#define RL_STATE_COMPLETING (0x00000001)
-	char *kill_string;
-#define NUM_HANDLERS 256
-	tinyrl_key_func_t *handlers[NUM_HANDLERS];
-	tinyrl_key_func_t *hotkey_fn;
-
-	tinyrl_history_t *history;
-	tinyrl_history_iterator_t hist_iter;
-	tinyrl_vt100_t *term;
-	void *context;		/* context supplied by caller
-				 * to tinyrl_readline()
-				 */
-	char echo_char;
-	bool_t echo_enabled;
-	struct termios default_termios;
-	bool_t isatty;
-	char *last_buffer;	/* hold record of the previous
-				buffer for redisplay purposes */
-	unsigned int last_point; /* hold record of the previous
-				cursor position for redisplay purposes */
-	unsigned int last_line_size; /* The length of last_buffer */
-	unsigned int last_width; /* Last terminal width. For resize */
-	bool_t utf8;		/* Is the encoding UTF-8 */
-};

+ 0 - 1657
tinyrl/tinyrl.c

@@ -1,1657 +0,0 @@
-/*
- * tinyrl.c
- */
-
-/* make sure we can get fileno() */
-#undef __STRICT_ANSI__
-
-/* LIBC HEADERS */
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-/* POSIX HEADERS */
-#include <unistd.h>
-
-#include "lub/string.h"
-
-#include "private.h"
-
-/*-------------------------------------------------------- */
-static int utf8_wchar(const char *sp, unsigned long *sym_out)
-{
-	int i = 0;
-	int l = 0; /* Number of 0x10 UTF sequence bytes */
-	unsigned long sym = 0;
-	const unsigned char *p = (const unsigned char *)sp;
-
-	if (sym_out)
-		*sym_out = *p;
-
-	if (!*p)
-		return 0;
-
-	/* Check for first byte of UTF-8 */
-	if (!(*p & 0xc0))
-		return 1;
-
-	/* Analyze first byte */
-	if ((*p & 0xe0) == 0xc0) {
-		l = 1;
-		sym = (*p & 0x1f);
-	} else if ((*p & 0xf0) == 0xe0) {
-		l = 2;
-		sym = (*p & 0xf);
-	} else if ((*p & 0xf8) == 0xf0) {
-		l = 3;
-		sym = (*p & 7);
-	} else if ((*p & 0xfc) == 0xf8) {
-		l = 4;
-		sym = (*p & 3);
-	} else if ((*p & 0xfe) == 0xfc) {
-		l = 5;
-		sym = (*p & 1);
-	} else {
-		return 1;
-	}
-	p++;
-
-	/* Analyze next UTF-8 bytes */
-	for (i = 0; i < l; i++) {
-		sym <<= 6;
-		/* Check if it's really UTF-8 bytes */
-		if ((*p & 0xc0) != 0x80)
-			return 1;
-		sym |= (*p & 0x3f);
-		p++;
-	}
-
-	if (sym_out)
-		*sym_out = sym;
-	return (l + 1);
-}
-
-/*-------------------------------------------------------- */
-static int utf8_is_cjk(unsigned long sym)
-{
-	if (sym < 0x1100) /* Speed up for non-CJK chars */
-		return 0;
-
-	if (sym >= 0x1100 && sym <= 0x11FF) /* Hangul Jamo */
-		return 1;
-#if 0
-	if (sym >=0x2E80 && sym <= 0x2EFF) /* CJK Radicals Supplement */
-		return 1;
-	if (sym >=0x2F00 && sym <= 0x2FDF) /* Kangxi Radicals */
-		return 1;
-	if (sym >= 0x2FF0 && sym <= 0x2FFF) /* Ideographic Description Characters */
-		return 1;
-	if (sym >= 0x3000 && sym < 0x303F) /* CJK Symbols and Punctuation. The U+303f is half space */
-		return 1;
-	if (sym >= 0x3040 && sym <= 0x309F) /* Hiragana */
-		return 1;
-	if (sym >= 0x30A0 && sym <=0x30FF) /* Katakana */
-		return 1;
-	if (sym >= 0x3100 && sym <=0x312F) /* Bopomofo */
-		return 1;
-	if (sym >= 0x3130 && sym <= 0x318F) /* Hangul Compatibility Jamo */
-		return 1;
-	if (sym >= 0x3190 && sym <= 0x319F) /* Kanbun */
-		return 1;
-	if (sym >= 0x31A0 && sym <= 0x31BF) /* Bopomofo Extended */
-		return 1;
-	if (sym >= 0x31C0 && sym <= 0x31EF) /* CJK strokes */
-		return 1;
-	if (sym >= 0x31F0 && sym <= 0x31FF) /* Katakana Phonetic Extensions */
-		return 1;
-	if (sym >= 0x3200 && sym <= 0x32FF) /* Enclosed CJK Letters and Months */
-		return 1;
-	if (sym >= 0x3300 && sym <= 0x33FF) /* CJK Compatibility */
-		return 1;
-	if (sym >= 0x3400 && sym <= 0x4DBF) /* CJK Unified Ideographs Extension A */
-		return 1;
-	if (sym >= 0x4DC0 && sym <= 0x4DFF) /* Yijing Hexagram Symbols */
-		return 1;
-	if (sym >= 0x4E00 && sym <= 0x9FFF) /* CJK Unified Ideographs */
-		return 1;
-	if (sym >= 0xA000 && sym <= 0xA48F) /* Yi Syllables */
-		return 1;
-	if (sym >= 0xA490 && sym <= 0xA4CF) /* Yi Radicals */
-		return 1;
-#endif
-	/* Speed up previous block */
-	if (sym >= 0x2E80 && sym <= 0xA4CF && sym != 0x303F)
-		return 1;
-
-	if (sym >= 0xAC00 && sym <= 0xD7AF) /* Hangul Syllables */
-		return 1;
-	if (sym >= 0xF900 && sym <= 0xFAFF) /* CJK Compatibility Ideographs */
-		return 1;
-	if (sym >= 0xFE10 && sym <= 0xFE1F) /* Vertical Forms */
-		return 1;
-
-#if 0
-	if (sym >= 0xFE30 && sym <= 0xFE4F) /* CJK Compatibility Forms */
-		return 1;
-	if (sym >= 0xFE50 && sym <= 0xFE6F) /* Small Form Variants */
-		return 1;
-#endif
-	/* Speed up previous block */
-	if (sym >= 0xFE30 && sym <= 0xFE6F)
-		return 1;
-
-	if ((sym >= 0xFF00 && sym <= 0xFF60) ||
-		(sym >= 0xFFE0 && sym <= 0xFFE6)) /* Fullwidth Forms */
-		return 1;
-
-	if (sym >= 0x1D300 && sym <= 0x1D35F) /* Tai Xuan Jing Symbols */
-		return 1;
-	if (sym >= 0x20000 && sym <= 0x2B81F) /* CJK Unified Ideographs Extensions B, C, D */
-		return 1;
-	if (sym >= 0x2F800 && sym <= 0x2FA1F) /* CJK Compatibility Ideographs Supplement */
-		return 1;
-
-	return 0;
-}
-
-/*-------------------------------------------------------- */
-static void utf8_point_left(tinyrl_t * this)
-{
-	if (!this->utf8)
-		return;
-	while (this->point &&
-		(UTF8_10 == (this->line[this->point] & UTF8_MASK)))
-		this->point--;
-}
-
-/*-------------------------------------------------------- */
-static void utf8_point_right(tinyrl_t * this)
-{
-	if (!this->utf8)
-		return;
-	while ((this->point < this->end) &&
-		(UTF8_10 == (this->line[this->point] & UTF8_MASK)))
-		this->point++;
-}
-
-/*-------------------------------------------------------- */
-static unsigned int utf8_nsyms(const tinyrl_t *this, const char *str,
-	unsigned int num)
-{
-	unsigned int nsym = 0;
-	unsigned long sym = 0;
-	unsigned int i = 0;
-
-	if (!this->utf8)
-		return num;
-
-	while (i < num) {
-		if ('\0' == str[i])
-			break;
-		/* ASCII char */
-		if (!(UTF8_7BIT_MASK & str[i])) {
-			i++;
-			nsym++;
-			continue;
-		}
-		/* Multibyte */
-		i += utf8_wchar(&str[i], &sym);
-		if (utf8_is_cjk(sym)) /* CJK chars have double-width */
-			nsym += 2;
-		else
-			nsym += 1;
-	}
-
-	return nsym;
-}
-
-/*----------------------------------------------------------------------- */
-static void tty_set_raw_mode(tinyrl_t * this)
-{
-	struct termios new_termios;
-	int fd;
-
-	if (!tinyrl_vt100__get_istream(this->term))
-		return;
-	fd = fileno(tinyrl_vt100__get_istream(this->term));
-	if (tcgetattr(fd, &new_termios) < 0)
-		return;
-	new_termios.c_iflag = 0;
-	new_termios.c_oflag = OPOST | ONLCR;
-	new_termios.c_lflag = 0;
-	new_termios.c_cc[VMIN] = 1;
-	new_termios.c_cc[VTIME] = 0;
-	/* Do the mode switch */
-	(void)tcsetattr(fd, TCSADRAIN, &new_termios);
-}
-
-/*----------------------------------------------------------------------- */
-static void tty_restore_mode(const tinyrl_t * this)
-{
-	int fd;
-
-	if (!tinyrl_vt100__get_istream(this->term))
-		return;
-	fd = fileno(tinyrl_vt100__get_istream(this->term));
-	/* Do the mode switch */
-	(void)tcsetattr(fd, TCSADRAIN, &this->default_termios);
-}
-
-/*----------------------------------------------------------------------- */
-/*
-This is called whenever a line is edited in any way.
-It signals that if we are currently viewing a history line we should transfer it
-to the current buffer
-*/
-static void changed_line(tinyrl_t * this)
-{
-	/* if the current line is not our buffer then make it so */
-	if (this->line != this->buffer) {
-		/* replace the current buffer with the new details */
-		free(this->buffer);
-		this->line = this->buffer = lub_string_dup(this->line);
-		this->buffer_size = strlen(this->buffer);
-		assert(this->line);
-	}
-}
-
-/*----------------------------------------------------------------------- */
-static int tinyrl_timeout_default(tinyrl_t *this)
-{
-	this = this; /* Happy compiler */
-
-	/* Return -1 to close session on timeout */
-	return -1;
-}
-
-/*----------------------------------------------------------------------- */
-static bool_t tinyrl_key_default(tinyrl_t * this, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (key > 31) {
-		char tmp[2];
-		tmp[0] = (key & 0xFF), tmp[1] = '\0';
-		/* inject this text into the buffer */
-		result = tinyrl_insert_text(this, tmp);
-	} else {
-		/* Call the external hotkey analyzer */
-		if (this->hotkey_fn)
-			this->hotkey_fn(this, key);
-	}
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_interrupt(tinyrl_t * this, int key)
-{
-	tinyrl_crlf(this);
-	tinyrl_delete_text(this, 0, this->end);
-	this->done = BOOL_TRUE;
-	/* keep the compiler happy */
-	key = key;
-
-	return BOOL_TRUE;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_start_of_line(tinyrl_t * this, int key)
-{
-	/* set the insertion point to the start of the line */
-	this->point = 0;
-	/* keep the compiler happy */
-	key = key;
-	return BOOL_TRUE;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_end_of_line(tinyrl_t * this, int key)
-{
-	/* set the insertion point to the end of the line */
-	this->point = this->end;
-	/* keep the compiler happy */
-	key = key;
-	return BOOL_TRUE;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_kill(tinyrl_t * this, int key)
-{
-	/* release any old kill string */
-	lub_string_free(this->kill_string);
-
-	/* store the killed string */
-	this->kill_string = lub_string_dup(&this->buffer[this->point]);
-
-	/* delete the text to the end of the line */
-	tinyrl_delete_text(this, this->point, this->end);
-	/* keep the compiler happy */
-	key = key;
-	return BOOL_TRUE;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_yank(tinyrl_t * this, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (this->kill_string) {
-		/* insert the kill string at the current insertion point */
-		result = tinyrl_insert_text(this, this->kill_string);
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_crlf(tinyrl_t * this, int key)
-{
-	tinyrl_crlf(this);
-	this->done = BOOL_TRUE;
-	/* keep the compiler happy */
-	key = key;
-	return BOOL_TRUE;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_up(tinyrl_t * this, int key)
-{
-	bool_t result = BOOL_FALSE;
-	tinyrl_history_entry_t *entry = NULL;
-	if (this->line == this->buffer) {
-		/* go to the last history entry */
-		entry = tinyrl_history_getlast(this->history, &this->hist_iter);
-	} else {
-		/* already traversing the history list so get previous */
-		entry = tinyrl_history_getprevious(&this->hist_iter);
-	}
-	if (entry) {
-		/* display the entry moving the insertion point
-		 * to the end of the line 
-		 */
-		this->line = tinyrl_history_entry__get_line(entry);
-		this->point = this->end = strlen(this->line);
-		result = BOOL_TRUE;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_down(tinyrl_t * this, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (this->line != this->buffer) {
-		/* we are not already at the bottom */
-		/* the iterator will have been set up by the key_up() function */
-		tinyrl_history_entry_t *entry =
-		    tinyrl_history_getnext(&this->hist_iter);
-		if (!entry) {
-			/* nothing more in the history list */
-			this->line = this->buffer;
-		} else {
-			this->line = tinyrl_history_entry__get_line(entry);
-		}
-		/* display the entry moving the insertion point
-		 * to the end of the line 
-		 */
-		this->point = this->end = strlen(this->line);
-		result = BOOL_TRUE;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_left(tinyrl_t * this, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (this->point > 0) {
-		this->point--;
-		utf8_point_left(this);
-		result = BOOL_TRUE;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_right(tinyrl_t * this, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (this->point < this->end) {
-		this->point++;
-		utf8_point_right(this);
-		result = BOOL_TRUE;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_backspace(tinyrl_t *this, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (this->point) {
-		unsigned int end = --this->point;
-		utf8_point_left(this);
-		tinyrl_delete_text(this, this->point, end);
-		result = BOOL_TRUE;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_backword(tinyrl_t *this, int key)
-{
-	bool_t result = BOOL_FALSE;
-
-    /* remove current whitespace before cursor */
-	while (this->point > 0 && isspace(this->line[this->point - 1]))
-        tinyrl_key_backspace(this, KEY_BS);
-
-    /* delete word before cusor */
-	while (this->point > 0 && !isspace(this->line[this->point - 1]))
-        tinyrl_key_backspace(this, KEY_BS);
-
-	result = BOOL_TRUE;
-
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_delete(tinyrl_t * this, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (this->point < this->end) {
-		unsigned int begin = this->point++;
-		utf8_point_right(this);
-		tinyrl_delete_text(this, begin, this->point - 1);
-		result = BOOL_TRUE;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_clear_screen(tinyrl_t * this, int key)
-{
-	tinyrl_vt100_clear_screen(this->term);
-	tinyrl_vt100_cursor_home(this->term);
-	tinyrl_reset_line_state(this);
-
-	/* keep the compiler happy */
-	key = key;
-	this = this;
-	return BOOL_TRUE;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_erase_line(tinyrl_t * this, int key)
-{
-	unsigned int end;
-
-	/* release any old kill string */
-	lub_string_free(this->kill_string);
-
-	if (!this->point) {
-		this->kill_string = NULL;
-		return BOOL_TRUE;
-	}
-
-	end = this->point - 1;
-
-	/* store the killed string */
-	this->kill_string = malloc(this->point + 1);
-	memcpy(this->kill_string, this->buffer, this->point);
-	this->kill_string[this->point] = '\0';
-
-	/* delete the text from the start of the line */
-	tinyrl_delete_text(this, 0, end);
-	this->point = 0;
-
-	/* keep the compiler happy */
-	key = key;
-	this = this;
-
-	return BOOL_TRUE;
-}/*-------------------------------------------------------- */
-
-static bool_t tinyrl_escape_seq(tinyrl_t *this, const char *esc_seq)
-{
-	int key = 0;
-	bool_t result = BOOL_FALSE;
-
-	switch (tinyrl_vt100_escape_decode(this->term, esc_seq)) {
-	case tinyrl_vt100_CURSOR_UP:
-		result = tinyrl_key_up(this, key);
-		break;
-	case tinyrl_vt100_CURSOR_DOWN:
-		result = tinyrl_key_down(this, key);
-		break;
-	case tinyrl_vt100_CURSOR_LEFT:
-		result = tinyrl_key_left(this, key);
-		break;
-	case tinyrl_vt100_CURSOR_RIGHT:
-		result = tinyrl_key_right(this, key);
-		break;
-	case tinyrl_vt100_HOME:
-		result = tinyrl_key_start_of_line(this,key);
-		break;
-	case tinyrl_vt100_END:
-		result = tinyrl_key_end_of_line(this,key);
-		break;
-	case tinyrl_vt100_DELETE:
-		result = tinyrl_key_delete(this,key);
-		break;
-	case tinyrl_vt100_INSERT:
-	case tinyrl_vt100_PGDOWN:
-	case tinyrl_vt100_PGUP:
-	case tinyrl_vt100_UNKNOWN:
-		break;
-	}
-
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_tab(tinyrl_t * this, int key)
-{
-	bool_t result = BOOL_FALSE;
-	tinyrl_match_e status = tinyrl_complete_with_extensions(this);
-
-	switch (status) {
-	case TINYRL_COMPLETED_MATCH:
-	case TINYRL_MATCH:
-		/* everything is OK with the world... */
-		result = tinyrl_insert_text(this, " ");
-		break;
-	case TINYRL_NO_MATCH:
-	case TINYRL_MATCH_WITH_EXTENSIONS:
-	case TINYRL_AMBIGUOUS:
-	case TINYRL_COMPLETED_AMBIGUOUS:
-		/* oops don't change the result and let the bell ring */
-		break;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static void tinyrl_fini(tinyrl_t * this)
-{
-	/* delete the history session */
-	tinyrl_history_delete(this->history);
-
-	/* delete the terminal session */
-	tinyrl_vt100_delete(this->term);
-
-	/* free up any dynamic strings */
-	lub_string_free(this->buffer);
-	lub_string_free(this->kill_string);
-	lub_string_free(this->last_buffer);
-	lub_string_free(this->prompt);
-}
-
-/*-------------------------------------------------------- */
-static void tinyrl_init(tinyrl_t * this, FILE * istream, FILE * ostream,
-	unsigned int stifle, tinyrl_completion_func_t * complete_fn)
-{
-	int i;
-
-	for (i = 0; i < NUM_HANDLERS; i++) {
-		this->handlers[i] = tinyrl_key_default;
-	}
-	/* Default handlers */
-	this->handlers[KEY_CR] = tinyrl_key_crlf;
-	this->handlers[KEY_LF] = tinyrl_key_crlf;
-	this->handlers[KEY_ETX] = tinyrl_key_interrupt;
-	this->handlers[KEY_DEL] = tinyrl_key_backspace;
-	this->handlers[KEY_BS] = tinyrl_key_backspace;
-	this->handlers[KEY_EOT] = tinyrl_key_delete;
-	this->handlers[KEY_FF] = tinyrl_key_clear_screen;
-	this->handlers[KEY_NAK] = tinyrl_key_erase_line;
-	this->handlers[KEY_SOH] = tinyrl_key_start_of_line;
-	this->handlers[KEY_ENQ] = tinyrl_key_end_of_line;
-	this->handlers[KEY_VT] = tinyrl_key_kill;
-	this->handlers[KEY_EM] = tinyrl_key_yank;
-	this->handlers[KEY_HT] = tinyrl_key_tab;
-	this->handlers[KEY_ETB] = tinyrl_key_backword;
-
-	this->line = NULL;
-	this->max_line_length = 0;
-	this->prompt = NULL;
-	this->prompt_size = 0;
-	this->buffer = NULL;
-	this->buffer_size = 0;
-	this->done = BOOL_FALSE;
-	this->completion_over = BOOL_FALSE;
-	this->point = 0;
-	this->end = 0;
-	this->attempted_completion_function = complete_fn;
-	this->timeout_fn = tinyrl_timeout_default;
-	this->keypress_fn = NULL;
-	this->hotkey_fn = NULL;
-	this->state = 0;
-	this->kill_string = NULL;
-	this->echo_char = '\0';
-	this->echo_enabled = BOOL_TRUE;
-	this->last_buffer = NULL;
-	this->last_point = 0;
-	this->last_line_size = 0;
-	this->utf8 = BOOL_FALSE;
-
-	/* create the vt100 terminal */
-	this->term = tinyrl_vt100_new(NULL, ostream);
-	tinyrl__set_istream(this, istream);
-	this->last_width = tinyrl_vt100__get_width(this->term);
-
-	/* create the history */
-	this->history = tinyrl_history_new(stifle);
-}
-
-/*-------------------------------------------------------- */
-int tinyrl_printf(const tinyrl_t * this, const char *fmt, ...)
-{
-	va_list args;
-	int len;
-
-	va_start(args, fmt);
-	len = tinyrl_vt100_vprintf(this->term, fmt, args);
-	va_end(args);
-
-	return len;
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_delete(tinyrl_t * this)
-{
-	assert(this);
-	if (this) {
-		/* let the object tidy itself up */
-		tinyrl_fini(this);
-
-		/* release the memory associate with this instance */
-		free(this);
-	}
-}
-
-/*-------------------------------------------------------- */
-
-/*#####################################
- * EXPORTED INTERFACE
- *##################################### */
-/*----------------------------------------------------------------------- */
-int tinyrl_getchar(const tinyrl_t * this)
-{
-	return tinyrl_vt100_getchar(this->term);
-}
-
-/*----------------------------------------------------------------------- */
-static void tinyrl_internal_print(const tinyrl_t * this, const char *text)
-{
-	if (this->echo_enabled) {
-		/* simply echo the line */
-		tinyrl_vt100_printf(this->term, "%s", text);
-	} else {
-		/* replace the line with echo char if defined */
-		if (this->echo_char) {
-			unsigned int i = strlen(text);
-			while (i--) {
-				tinyrl_vt100_printf(this->term, "%c",
-					this->echo_char);
-			}
-		}
-	}
-}
-
-/*----------------------------------------------------------------------- */
-static void tinyrl_internal_position(const tinyrl_t *this, int prompt_len,
-	int line_len, unsigned int width)
-{
-	int rows, cols;
-
-	rows = ((line_len + prompt_len) / width) - (prompt_len / width);
-	cols = ((line_len + prompt_len) % width) - (prompt_len % width);
-	if (cols > 0)
-		tinyrl_vt100_cursor_back(this->term, cols);
-	else if (cols < 0)
-		tinyrl_vt100_cursor_forward(this->term, -cols);
-	if (rows > 0)
-		tinyrl_vt100_cursor_up(this->term, rows);
-	else if (rows < 0)
-		tinyrl_vt100_cursor_down(this->term, -rows);
-}
-
-/*-------------------------------------------------------- */
-/* Jump to first free line after current multiline input   */
-void tinyrl_multi_crlf(const tinyrl_t * this)
-{
-	unsigned int line_size = strlen(this->last_buffer);
-	unsigned int line_len = utf8_nsyms(this, this->last_buffer, line_size);
-	unsigned int count = utf8_nsyms(this, this->last_buffer, this->last_point);
-
-	tinyrl_internal_position(this, this->prompt_len + line_len,
-		- (line_len - count), this->last_width);
-	tinyrl_crlf(this);
-	tinyrl_vt100_oflush(this->term);
-}
-
-/*----------------------------------------------------------------------- */
-void tinyrl_redisplay(tinyrl_t * this)
-{
-	unsigned int line_size = strlen(this->line);
-	unsigned int line_len = utf8_nsyms(this, this->line, line_size);
-	unsigned int width = tinyrl_vt100__get_width(this->term);
-	unsigned int count, eq_chars = 0;
-	int cols;
-
-	/* Prepare print position */
-	if (this->last_buffer && (width == this->last_width)) {
-		unsigned int eq_len = 0;
-		/* If line and last line have the equal chars at begining */
-		eq_chars = lub_string_equal_part(this->line, this->last_buffer,
-			this->utf8);
-		eq_len = utf8_nsyms(this, this->last_buffer, eq_chars);
-		count = utf8_nsyms(this, this->last_buffer, this->last_point);
-		tinyrl_internal_position(this, this->prompt_len + eq_len,
-			count - eq_len, width);
-	} else {
-		/* Prepare to resize */
-		if (width != this->last_width) {
-			tinyrl_vt100_next_line(this->term);
-			tinyrl_vt100_erase_down(this->term);
-		}
-		tinyrl_vt100_printf(this->term, "%s", this->prompt);
-	}
-
-	/* Print current line */
-	tinyrl_internal_print(this, this->line + eq_chars);
-	cols = (this->prompt_len + line_len) % width;
-	if (!cols && (line_size - eq_chars))
-		tinyrl_vt100_next_line(this->term);
-	/* Erase down if current line is shorter than previous one */
-	if (this->last_line_size > line_size)
-		tinyrl_vt100_erase_down(this->term);
-	/* Move the cursor to the insertion point */
-	if (this->point < line_size) {
-		unsigned int pre_len = utf8_nsyms(this,
-			this->line, this->point);
-		count = utf8_nsyms(this, this->line + this->point,
-			line_size - this->point);
-		tinyrl_internal_position(this, this->prompt_len + pre_len,
-			count, width);
-	}
-
-	/* Update the display */
-	tinyrl_vt100_oflush(this->term);
-
-	/* Save the last line buffer */
-	lub_string_free(this->last_buffer);
-	this->last_buffer = lub_string_dup(this->line);
-	this->last_point = this->point;
-	this->last_width = width;
-	this->last_line_size = line_size;
-}
-
-/*----------------------------------------------------------------------- */
-tinyrl_t *tinyrl_new(FILE * istream, FILE * ostream,
-	unsigned int stifle, tinyrl_completion_func_t * complete_fn)
-{
-	tinyrl_t *this = NULL;
-
-	this = malloc(sizeof(tinyrl_t));
-	if (this)
-		tinyrl_init(this, istream, ostream, stifle, complete_fn);
-
-	return this;
-}
-
-/*----------------------------------------------------------------------- */
-static char *internal_insertline(tinyrl_t * this, char *buffer)
-{
-	char *p;
-	char *s = buffer;
-
-	/* strip any spurious '\r' or '\n' */
-	if ((p = strchr(buffer, '\r')))
-		*p = '\0';
-	if ((p = strchr(buffer, '\n')))
-		*p = '\0';
-	/* skip any whitespace at the beginning of the line */
-	if (0 == this->point) {
-		while (*s && isspace(*s))
-			s++;
-	}
-	if (*s) {
-		/* append this string to the input buffer */
-		(void)tinyrl_insert_text(this, s);
-	}
-	/* echo the command to the output stream */
-	tinyrl_redisplay(this);
-
-	return s;
-}
-
-/*----------------------------------------------------------------------- */
-static char *internal_readline(tinyrl_t * this,
-	void *context, const char *str)
-{
-	FILE *istream = tinyrl_vt100__get_istream(this->term);
-	char *result = NULL;
-	int lerrno = 0;
-
-	this->done = BOOL_FALSE;
-	this->point = 0;
-	this->end = 0;
-	this->buffer = lub_string_dup("");
-	this->buffer_size = strlen(this->buffer);
-	this->line = this->buffer;
-	this->context = context;
-
-	/* Interactive session */
-	if (this->isatty && !str) {
-		unsigned int utf8_cont = 0; /* UTF-8 continue bytes */
-		unsigned int esc_cont = 0; /* Escape sequence continues */
-		char esc_seq[10]; /* Buffer for ESC sequence */
-		char *esc_p = esc_seq;
-
-		/* Set the terminal into raw mode */
-		tty_set_raw_mode(this);
-		tinyrl_reset_line_state(this);
-
-		while (!this->done) {
-			int key;
-
-			key = tinyrl_getchar(this);
-
-			/* Error || EOF || Timeout */
-			if (key < 0) {
-				if ((VT100_TIMEOUT == key) &&
-					!this->timeout_fn(this))
-					continue;
-				/* It's time to finish the session */
-				this->done = BOOL_TRUE;
-				this->line = NULL;
-				lerrno = ENOENT;
-				continue;
-			}
-
-			/* Real key pressed */
-			/* Common callback for any key */
-			if (this->keypress_fn)
-				this->keypress_fn(this, key);
-
-			/* Check for ESC sequence. It's a special case. */
-			if (!esc_cont && (key == KEY_ESC)) {
-				esc_cont = 1; /* Start ESC sequence */
-				esc_p = esc_seq;
-				continue;
-			}
-			if (esc_cont) {
-				/* Broken sequence */
-				if (esc_p >= (esc_seq + sizeof(esc_seq) - 1)) {
-					esc_cont = 0;
-					continue;
-				}
-				/* Dump the control sequence into sequence buffer
-				   ANSI standard control sequences will end
-				   with a character between 64 - 126 */
-				*esc_p = key & 0xff;
-				esc_p++;
-				/* This is an ANSI control sequence terminator code */
-				if ((key != '[') && (key > 63)) {
-					*esc_p = '\0';
-					tinyrl_escape_seq(this, esc_seq);
-					esc_cont = 0;
-					tinyrl_redisplay(this);
-				}
-				continue;
-			}
-
-			/* Call the handler for this key */
-			if (!this->handlers[key](this, key))
-				tinyrl_ding(this);
-			if (this->done) /* Some handler set the done flag */
-				continue; /* It will break the loop */
-
-			if (this->utf8) {
-				if (!(UTF8_7BIT_MASK & key)) /* ASCII char */
-					utf8_cont = 0;
-				else if (utf8_cont && (UTF8_10 == (key & UTF8_MASK))) /* Continue byte */
-					utf8_cont--;
-				else if (UTF8_11 == (key & UTF8_MASK)) { /* First byte of multibyte char */
-					/* Find out number of char's bytes */
-					int b = key;
-					utf8_cont = 0;
-					while ((utf8_cont < 6) && (UTF8_10 != (b & UTF8_MASK))) {
-						utf8_cont++;
-						b = b << 1;
-					}
-				}
-			}
-			/* For non UTF-8 encoding the utf8_cont is always 0.
-			   For UTF-8 it's 0 when one-byte symbol or we get
-			   all bytes for the current multibyte character. */
-			if (!utf8_cont)
-				tinyrl_redisplay(this);
-		}
-		/* If the last character in the line (other than NULL)
-		   is a space remove it. */
-		if (this->end && this->line && isspace(this->line[this->end - 1]))
-			tinyrl_delete_text(this, this->end - 1, this->end);
-		/* Restores the terminal mode */
-		tty_restore_mode(this);
-
-	/* Non-interactive session */
-	} else {
-		char *s = NULL, buffer[80];
-		size_t len = sizeof(buffer);
-		char *tmp = NULL;
-
-		/* manually reset the line state without redisplaying */
-		lub_string_free(this->last_buffer);
-		this->last_buffer = NULL;
-
-		if (str) {
-			tmp = lub_string_dup(str);
-			internal_insertline(this, tmp);
-		} else {
-			while (istream && (sizeof(buffer) == len) &&
-				(s = fgets(buffer, sizeof(buffer), istream))) {
-				s = internal_insertline(this, buffer);
-				len = strlen(buffer) + 1; /* account for the '\0' */
-			}
-			if (!s || ((this->line[0] == '\0') && feof(istream))) {
-				/* time to finish the session */
-				this->line = NULL;
-				lerrno = ENOENT;
-			}
-		}
-
-		/*
-		 * check against fgets returning null as either error or end of file.
-		 * This is a measure to stop potential task spin on encountering an
-		 * error from fgets.
-		 */
-		if (this->line && !this->handlers[KEY_LF](this, KEY_LF)) {
-			/* an issue has occured */
-			this->line = NULL;
-			lerrno = ENOEXEC;
-		}
-		if (str)
-			lub_string_free(tmp);
-	}
-	/*
-	 * duplicate the string for return to the client 
-	 * we have to duplicate as we may be referencing a
-	 * history entry or our internal buffer
-	 */
-	result = this->line ? lub_string_dup(this->line) : NULL;
-
-	/* free our internal buffer */
-	free(this->buffer);
-	this->buffer = NULL;
-
-	if (!result)
-		errno = lerrno; /* get saved errno */
-	return result;
-}
-
-/*----------------------------------------------------------------------- */
-char *tinyrl_readline(tinyrl_t * this, void *context)
-{
-	return internal_readline(this, context, NULL);
-}
-
-/*----------------------------------------------------------------------- */
-char *tinyrl_forceline(tinyrl_t * this, void *context, const char *line)
-{
-	return internal_readline(this, context, line);
-}
-
-/*----------------------------------------------------------------------- */
-/*
- * Ensure that buffer has enough space to hold len characters,
- * possibly reallocating it if necessary. The function returns BOOL_TRUE
- * if the line is successfully extended, BOOL_FALSE if not.
- */
-bool_t tinyrl_extend_line_buffer(tinyrl_t * this, unsigned int len)
-{
-	bool_t result = BOOL_TRUE;
-	char *new_buffer;
-	size_t new_len = len;
-
-	if (this->buffer_size >= len)
-		return result;
-
-	/*
-	 * What we do depends on whether we are limited by
-	 * memory or a user imposed limit.
-	 */
-	if (this->max_line_length == 0) {
-		/* make sure we don't realloc too often */
-		if (new_len < this->buffer_size + 10)
-			new_len = this->buffer_size + 10;
-		/* leave space for terminator */
-		new_buffer = realloc(this->buffer, new_len + 1);
-
-		if (!new_buffer) {
-			tinyrl_ding(this);
-			result = BOOL_FALSE;
-		} else {
-			this->buffer_size = new_len;
-			this->line = this->buffer = new_buffer;
-		}
-	} else {
-		if (new_len < this->max_line_length) {
-
-			/* Just reallocate once to the max size */
-			new_buffer = realloc(this->buffer,
-				this->max_line_length);
-
-			if (!new_buffer) {
-				tinyrl_ding(this);
-				result = BOOL_FALSE;
-			} else {
-				this->buffer_size =
-					this->max_line_length - 1;
-				this->line = this->buffer = new_buffer;
-			}
-		} else {
-			tinyrl_ding(this);
-			result = BOOL_FALSE;
-		}
-	}
-
-	return result;
-}
-
-/*----------------------------------------------------------------------- */
-/*
- * Insert text into the line at the current cursor position.
- */
-bool_t tinyrl_insert_text(tinyrl_t * this, const char *text)
-{
-	unsigned int delta = strlen(text);
-
-	/*
-	 * If the client wants to change the line ensure that the line and buffer
-	 * references are in sync
-	 */
-	changed_line(this);
-
-	if ((delta + this->end) > (this->buffer_size)) {
-		/* extend the current buffer */
-		if (BOOL_FALSE ==
-			tinyrl_extend_line_buffer(this, this->end + delta))
-			return BOOL_FALSE;
-	}
-
-	if (this->point < this->end) {
-		/* move the current text to the right (including the terminator) */
-		memmove(&this->buffer[this->point + delta],
-			&this->buffer[this->point],
-			(this->end - this->point) + 1);
-	} else {
-		/* terminate the string */
-		this->buffer[this->end + delta] = '\0';
-	}
-
-	/* insert the new text */
-	strncpy(&this->buffer[this->point], text, delta);
-
-	/* now update the indexes */
-	this->point += delta;
-	this->end += delta;
-
-	return BOOL_TRUE;
-}
-
-/*----------------------------------------------------------------------- */
-/* 
- * A convenience function for displaying a list of strings in columnar
- * format on Readline's output stream. matches is the list of strings,
- * in argv format, such as a list of completion matches. len is the number
- * of strings in matches, and max is the length of the longest string in matches.
- * This function uses the setting of print-completions-horizontally to select
- * how the matches are displayed
- */
-void tinyrl_display_matches(const tinyrl_t *this,
-	char *const *matches, unsigned int len, size_t max)
-{
-	unsigned int width = tinyrl_vt100__get_width(this->term);
-	unsigned int cols, rows;
-
-	/* Find out column and rows number */
-	if (max < width)
-		cols = (width + 1) / (max + 1); /* allow for a space between words */
-	else
-		cols = 1;
-	rows = len / cols + 1;
-
-	assert(matches);
-	if (matches) {
-		unsigned int r, c;
-		len--, matches++; /* skip the subtitution string */
-		/* Print out a table of completions */
-		for (r = 0; r < rows && len; r++) {
-			for (c = 0; c < cols && len; c++) {
-				const char *match = *matches++;
-				len--;
-				if ((c + 1) == cols) /* Last str in row */
-					tinyrl_vt100_printf(this->term, "%s",
-						match);
-				else
-					tinyrl_vt100_printf(this->term, "%-*s ",
-						max, match);
-			}
-			tinyrl_crlf(this);
-		}
-	}
-}
-
-/*----------------------------------------------------------------------- */
-/*
- * Delete the text between start and end in the current line. (inclusive)
- * This adjusts the rl_point and rl_end indexes appropriately.
- */
-void tinyrl_delete_text(tinyrl_t * this, unsigned int start, unsigned int end)
-{
-	unsigned int delta;
-
-	/*
-	 * If the client wants to change the line ensure that the line and buffer
-	 * references are in sync
-	 */
-	changed_line(this);
-
-	/* make sure we play it safe */
-	if (start > end) {
-		unsigned int tmp = end;
-		start = end;
-		end = tmp;
-	}
-	if (end > this->end)
-		end = this->end;
-
-	delta = (end - start) + 1;
-
-	/* move any text which is left */
-	memmove(&this->buffer[start],
-		&this->buffer[start + delta], this->end - end);
-
-	/* now adjust the indexs */
-	if (this->point >= start) {
-		if (this->point > end) {
-			/* move the insertion point back appropriately */
-			this->point -= delta;
-		} else {
-			/* move the insertion point to the start */
-			this->point = start;
-		}
-	}
-	if (this->end > end)
-		this->end -= delta;
-	else
-		this->end = start;
-	/* put a terminator at the end of the buffer */
-	this->buffer[this->end] = '\0';
-}
-
-/*----------------------------------------------------------------------- */
-bool_t tinyrl_bind_key(tinyrl_t * this, int key, tinyrl_key_func_t * fn)
-{
-	bool_t result = BOOL_FALSE;
-
-	if ((key >= 0) && (key < 256)) {
-		/* set the key handling function */
-		this->handlers[key] = fn;
-		result = BOOL_TRUE;
-	}
-
-	return result;
-}
-
-/*-------------------------------------------------------- */
-/*
- * Returns an array of strings which is a list of completions for text.
- * If there are no completions, returns NULL. The first entry in the
- * returned array is the substitution for text. The remaining entries
- * are the possible completions. The array is terminated with a NULL pointer.
- *
- * entry_func is a function of two args, and returns a char *. 
- * The first argument is text. The second is a state argument;
- * it is zero on the first call, and non-zero on subsequent calls.
- * entry_func returns a NULL pointer to the caller when there are no 
- * more matches. 
- */
-char **tinyrl_completion(tinyrl_t * this,
-	const char *line, unsigned int start, unsigned int end,
-	tinyrl_compentry_func_t * entry_func)
-{
-	unsigned int state = 0;
-	size_t size = 1;
-	unsigned int offset = 1; /* Need at least one entry for the substitution */
-	char **matches = NULL;
-	char *match;
-	/* duplicate the string upto the insertion point */
-	char *text = lub_string_dupn(line, end);
-
-	/* now try and find possible completions */
-	while ((match = entry_func(this, text, start, state++))) {
-		if (size == offset) {
-			/* resize the buffer if needed - the +1 is for the NULL terminator */
-			size += 10;
-			matches =
-			    realloc(matches, (sizeof(char *) * (size + 1)));
-		}
-		/* not much we can do... */
-		if (!matches)
-			break;
-		matches[offset] = match;
-
-		/*
-		 * augment the substitute string with this entry
-		 */
-		if (1 == offset) {
-			/* let's be optimistic */
-			matches[0] = lub_string_dup(match);
-		} else {
-			char *p = matches[0];
-			size_t match_len = strlen(p);
-			/* identify the common prefix */
-			while ((tolower(*p) == tolower(*match)) && match_len--) {
-				p++, match++;
-			}
-			/* terminate the prefix string */
-			*p = '\0';
-		}
-		offset++;
-	}
-	/* be a good memory citizen */
-	lub_string_free(text);
-
-	if (matches)
-		matches[offset] = NULL;
-	return matches;
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_delete_matches(char **this)
-{
-	char **matches = this;
-	while (*matches) {
-		/* release the memory for each contained string */
-		free(*matches++);
-	}
-	/* release the memory for the array */
-	free(this);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_crlf(const tinyrl_t * this)
-{
-	tinyrl_vt100_printf(this->term, "\n");
-}
-
-/*-------------------------------------------------------- */
-/*
- * Ring the terminal bell, obeying the setting of bell-style.
- */
-void tinyrl_ding(const tinyrl_t * this)
-{
-	tinyrl_vt100_ding(this->term);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_reset_line_state(tinyrl_t * this)
-{
-	lub_string_free(this->last_buffer);
-	this->last_buffer = NULL;
-	this->last_line_size = 0;
-
-	tinyrl_redisplay(this);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_replace_line(tinyrl_t * this, const char *text, int clear_undo)
-{
-	size_t new_len = strlen(text);
-
-	/* ignored for now */
-	clear_undo = clear_undo;
-
-	/* ensure there is sufficient space */
-	if (tinyrl_extend_line_buffer(this, new_len)) {
-
-		/* overwrite the current contents of the buffer */
-		strcpy(this->buffer, text);
-
-		/* set the insert point and end point */
-		this->point = this->end = new_len;
-	}
-	tinyrl_redisplay(this);
-}
-
-/*-------------------------------------------------------- */
-static tinyrl_match_e
-tinyrl_do_complete(tinyrl_t * this, bool_t with_extensions)
-{
-	tinyrl_match_e result = TINYRL_NO_MATCH;
-	char **matches = NULL;
-	unsigned int start, end;
-	bool_t completion = BOOL_FALSE;
-	bool_t prefix = BOOL_FALSE;
-	int i = 0;
-
-	/* find the start and end of the current word */
-	start = end = this->point;
-	while (start && !isspace(this->line[start - 1]))
-		start--;
-
-	if (this->attempted_completion_function) {
-		this->completion_over = BOOL_FALSE;
-		this->completion_error_over = BOOL_FALSE;
-		/* try and complete the current line buffer */
-		matches = this->attempted_completion_function(this,
-			this->line, start, end);
-	}
-	if (!matches && (BOOL_FALSE == this->completion_over)) {
-		/* insert default completion call here... */
-	}
-	if (!matches)
-		return result;
-
-	/* identify and insert a common prefix if there is one */
-	if (0 != strncmp(matches[0], &this->line[start],
-		strlen(matches[0]))) {
-		/*
-		 * delete the original text not including
-		 * the current insertion point character
-		 */
-		if (this->end != end)
-			end--;
-		tinyrl_delete_text(this, start, end);
-		if (BOOL_FALSE == tinyrl_insert_text(this, matches[0]))
-			return TINYRL_NO_MATCH;
-		completion = BOOL_TRUE;
-	}
-	for (i = 1; matches[i]; i++) {
-		/* this is just a prefix string */
-		if (0 == lub_string_nocasecmp(matches[0], matches[i]))
-			prefix = BOOL_TRUE;
-	}
-	/* is there more than one completion? */
-	if (matches[2]) {
-		char **tmp = matches;
-		unsigned int max, len;
-		max = len = 0;
-		while (*tmp) {
-			size_t size = strlen(*tmp++);
-			len++;
-			if (size > max)
-				max = size;
-		}
-		if (completion)
-			result = TINYRL_COMPLETED_AMBIGUOUS;
-		else if (prefix)
-			result = TINYRL_MATCH_WITH_EXTENSIONS;
-		else
-			result = TINYRL_AMBIGUOUS;
-		if (with_extensions || !prefix) {
-			/* Either we always want to show extensions or
-			 * we haven't been able to complete the current line
-			 * and there is just a prefix, so let the user see the options
-			 */
-			tinyrl_crlf(this);
-			tinyrl_display_matches(this, matches, len, max);
-			tinyrl_reset_line_state(this);
-		}
-	} else {
-		result = completion ?
-			TINYRL_COMPLETED_MATCH : TINYRL_MATCH;
-	}
-	/* free the memory */
-	tinyrl_delete_matches(matches);
-	/* redisplay the line */
-	tinyrl_redisplay(this);
-
-	return result;
-}
-
-/*-------------------------------------------------------- */
-tinyrl_match_e tinyrl_complete_with_extensions(tinyrl_t * this)
-{
-	return tinyrl_do_complete(this, BOOL_TRUE);
-}
-
-/*-------------------------------------------------------- */
-tinyrl_match_e tinyrl_complete(tinyrl_t * this)
-{
-	return tinyrl_do_complete(this, BOOL_FALSE);
-}
-
-/*-------------------------------------------------------- */
-void *tinyrl__get_context(const tinyrl_t * this)
-{
-	return this->context;
-}
-
-/*--------------------------------------------------------- */
-const char *tinyrl__get_line(const tinyrl_t * this)
-{
-	return this->line;
-}
-
-/*--------------------------------------------------------- */
-tinyrl_history_t *tinyrl__get_history(const tinyrl_t * this)
-{
-	return this->history;
-}
-
-/*--------------------------------------------------------- */
-void tinyrl_completion_over(tinyrl_t * this)
-{
-	this->completion_over = BOOL_TRUE;
-}
-
-/*--------------------------------------------------------- */
-void tinyrl_completion_error_over(tinyrl_t * this)
-{
-	this->completion_error_over = BOOL_TRUE;
-}
-
-/*--------------------------------------------------------- */
-bool_t tinyrl_is_completion_error_over(const tinyrl_t * this)
-{
-	return this->completion_error_over;
-}
-
-/*--------------------------------------------------------- */
-void tinyrl_done(tinyrl_t * this)
-{
-	this->done = BOOL_TRUE;
-}
-
-/*--------------------------------------------------------- */
-void tinyrl_enable_echo(tinyrl_t * this)
-{
-	this->echo_enabled = BOOL_TRUE;
-}
-
-/*--------------------------------------------------------- */
-void tinyrl_disable_echo(tinyrl_t * this, char echo_char)
-{
-	this->echo_enabled = BOOL_FALSE;
-	this->echo_char = echo_char;
-}
-
-/*--------------------------------------------------------- */
-void tinyrl__set_istream(tinyrl_t * this, FILE * istream)
-{
-	tinyrl_vt100__set_istream(this->term, istream);
-	if (istream) {
-		int fd;
-		this->isatty = isatty(fileno(istream)) ? BOOL_TRUE : BOOL_FALSE;
-		/* Save terminal settings to restore on exit */
-		fd = fileno(istream);
-		tcgetattr(fd, &this->default_termios);
-	} else
-		this->isatty = BOOL_FALSE;
-}
-
-/*-------------------------------------------------------- */
-bool_t tinyrl__get_isatty(const tinyrl_t * this)
-{
-	return this->isatty;
-}
-
-/*-------------------------------------------------------- */
-FILE *tinyrl__get_istream(const tinyrl_t * this)
-{
-	return tinyrl_vt100__get_istream(this->term);
-}
-
-/*-------------------------------------------------------- */
-FILE *tinyrl__get_ostream(const tinyrl_t * this)
-{
-	return tinyrl_vt100__get_ostream(this->term);
-}
-
-/*-------------------------------------------------------- */
-const char *tinyrl__get_prompt(const tinyrl_t * this)
-{
-	return this->prompt;
-}
-
-/*-------------------------------------------------------- */
-void tinyrl__set_prompt(tinyrl_t *this, const char *prompt)
-{
-	if (this->prompt) {
-		lub_string_free(this->prompt);
-		this->prompt_size = 0;
-		this->prompt_len = 0;
-	}
-	this->prompt = lub_string_dup(prompt);
-	if (this->prompt) {
-		this->prompt_size = strlen(this->prompt);
-		this->prompt_len = utf8_nsyms(this, this->prompt,
-			this->prompt_size);
-	}
-}
-
-/*-------------------------------------------------------- */
-bool_t tinyrl__get_utf8(const tinyrl_t * this)
-{
-	return this->utf8;
-}
-
-/*-------------------------------------------------------- */
-void tinyrl__set_utf8(tinyrl_t * this, bool_t utf8)
-{
-	this->utf8 = utf8;
-}
-
-/*-------------------------------------------------------- */
-void tinyrl__set_timeout(tinyrl_t *this, int timeout)
-{
-	tinyrl_vt100__set_timeout(this->term, timeout);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl__set_timeout_fn(tinyrl_t *this,
-	tinyrl_timeout_fn_t *fn)
-{
-	this->timeout_fn = fn;
-}
-
-/*-------------------------------------------------------- */
-void tinyrl__set_keypress_fn(tinyrl_t *this,
-	tinyrl_keypress_fn_t *fn)
-{
-	this->keypress_fn = fn;
-}
-
-/*-------------------------------------------------------- */
-void tinyrl__set_hotkey_fn(tinyrl_t *this,
-	tinyrl_key_func_t *fn)
-{
-	this->hotkey_fn = fn;
-}
-
-/*-------------------------------------------------------- */
-bool_t tinyrl_is_quoting(const tinyrl_t * this)
-{
-	bool_t result = BOOL_FALSE;
-	/* count the quotes upto the current insertion point */
-	unsigned int i = 0;
-	while (i < this->point) {
-		if (result && (this->line[i] == '\\')) {
-			i++;
-			if (i >= this->point)
-				break;
-			i++;
-			continue;
-		}
-		if (this->line[i++] == '"') {
-			result = result ? BOOL_FALSE : BOOL_TRUE;
-		}
-	}
-	return result;
-}
-
-/*-------------------------------------------------------- */
-bool_t tinyrl_is_empty(const tinyrl_t *this)
-{
-	return (this->point == 0) ? BOOL_TRUE : BOOL_FALSE;
-}
-
-/*--------------------------------------------------------- */
-void tinyrl_limit_line_length(tinyrl_t * this, unsigned int length)
-{
-	this->max_line_length = length;
-}
-
-/*--------------------------------------------------------- */
-extern unsigned int tinyrl__get_width(const tinyrl_t *this)
-{
-	return tinyrl_vt100__get_width(this->term);
-}
-
-/*--------------------------------------------------------- */
-extern unsigned int tinyrl__get_height(const tinyrl_t *this)
-{
-	return tinyrl_vt100__get_height(this->term);
-}
-
-/*----------------------------------------------------------*/
-int tinyrl__save_history(const tinyrl_t *this, const char *fname)
-{
-	return tinyrl_history_save(this->history, fname);
-}
-
-/*----------------------------------------------------------*/
-int tinyrl__restore_history(tinyrl_t *this, const char *fname)
-{
-	return tinyrl_history_restore(this->history, fname);
-}
-
-/*----------------------------------------------------------*/
-void tinyrl__stifle_history(tinyrl_t *this, unsigned int stifle)
-{
-	tinyrl_history_stifle(this->history, stifle);
-}
-/*--------------------------------------------------------- */

+ 0 - 228
tinyrl/tinyrl.h

@@ -1,228 +0,0 @@
- /**
-\ingroup tinyrl
-\defgroup tinyrl_class tinyrl
-@{
-
-\brief This class provides instances which are capable of handling user input
-from a CLI in a "readline" like fashion.
-
-*/
-#ifndef _tinyrl_tinyrl_h
-#define _tinyrl_tinyrl_h
-
-#include <stdio.h>
-#include "lub/types.h"
-#include "lub/c_decl.h"
-#include "tinyrl/history.h"
-
-_BEGIN_C_DECL typedef struct _tinyrl tinyrl_t;
-typedef enum {
-    /**
-     * no possible completions were found
-     */
-	TINYRL_NO_MATCH = 0,
-    /**
-     * the provided string was already an exact match
-     */
-	TINYRL_MATCH,
-    /**
-     * the provided string was ambiguous and produced
-     * more than one possible completion
-     */
-	TINYRL_AMBIGUOUS,
-    /**
-     * the provided string was unambiguous and a 
-     * completion was performed
-     */
-	TINYRL_COMPLETED_MATCH,
-    /**
-     * the provided string was ambiguous but a partial
-     * completion was performed.
-     */
-	TINYRL_COMPLETED_AMBIGUOUS,
-    /**
-     * the provided string was an exact match for one
-     * possible value but there are other exetensions
-     * of the string available.
-     */
-	TINYRL_MATCH_WITH_EXTENSIONS
-} tinyrl_match_e;
-
-/* virtual methods */
-typedef char *tinyrl_compentry_func_t(tinyrl_t * instance,
-	const char *text, unsigned offset, unsigned state);
-typedef int tinyrl_hook_func_t(tinyrl_t * instance);
-
-typedef char **tinyrl_completion_func_t(tinyrl_t * instance,
-	const char *text, unsigned start, unsigned end);
-
-typedef int tinyrl_timeout_fn_t(tinyrl_t *instance);
-typedef int tinyrl_keypress_fn_t(tinyrl_t *instance, int key);
-
-/**
- * \return
- * - BOOL_TRUE if the action associated with the key has
- *   been performed successfully
- * - BOOL_FALSE if the action was not successful
- */
-typedef bool_t tinyrl_key_func_t(tinyrl_t * instance, int key);
-
-/* exported functions */
-extern tinyrl_t *tinyrl_new(FILE * instream,
-			    FILE * outstream,
-			    unsigned stifle,
-			    tinyrl_completion_func_t * complete_fn);
-
-/*lint -esym(534,tinyrl_printf)  Ignoring return value of function */
-extern int tinyrl_printf(const tinyrl_t * instance, const char *fmt, ...);
-
-extern void tinyrl_delete(tinyrl_t * instance);
-
-extern tinyrl_history_t *tinyrl__get_history(const tinyrl_t * instance);
-
-extern const char *tinyrl__get_prompt(const tinyrl_t * instance);
-extern void tinyrl__set_prompt(tinyrl_t *instance, const char *prompt);
-
-extern void tinyrl_done(tinyrl_t * instance);
-
-extern void tinyrl_completion_over(tinyrl_t * instance);
-
-extern void tinyrl_completion_error_over(tinyrl_t * instance);
-
-extern bool_t tinyrl_is_completion_error_over(const tinyrl_t * instance);
-
-extern void *tinyrl__get_context(const tinyrl_t * instance);
-
-/**
- * This operation returns the current line in use by the tinyrl instance
- * NB. the pointer will become invalid after any further operation on the 
- * instance.
- */
-extern const char *tinyrl__get_line(const tinyrl_t * instance);
-extern void tinyrl__set_istream(tinyrl_t * instance, FILE * istream);
-extern bool_t tinyrl__get_isatty(const tinyrl_t * instance);
-extern FILE *tinyrl__get_istream(const tinyrl_t * instance);
-extern FILE *tinyrl__get_ostream(const tinyrl_t * instance);
-extern bool_t tinyrl__get_utf8(const tinyrl_t * instance);
-extern void tinyrl__set_utf8(tinyrl_t * instance, bool_t utf8);
-extern void tinyrl__set_timeout(tinyrl_t *instance, int timeout);
-extern void tinyrl__set_timeout_fn(tinyrl_t *instance,
-	tinyrl_timeout_fn_t *fn);
-extern void tinyrl__set_keypress_fn(tinyrl_t *instance,
-	tinyrl_keypress_fn_t *fn);
-extern void tinyrl__set_hotkey_fn(tinyrl_t *instance,
-	tinyrl_key_func_t *fn);
-extern char *tinyrl_readline(tinyrl_t *instance, void *context);
-extern char *tinyrl_forceline(tinyrl_t *instance, 
-	void *context, const char *line);
-extern bool_t tinyrl_bind_key(tinyrl_t *instance, int key,
-	tinyrl_key_func_t *fn);
-extern void tinyrl_delete_matches(char **instance);
-extern char **tinyrl_completion(tinyrl_t *instance,
-	const char *line, unsigned start, unsigned end,
-	tinyrl_compentry_func_t *generator);
-extern void tinyrl_crlf(const tinyrl_t * instance);
-extern void tinyrl_multi_crlf(const tinyrl_t * instance);
-extern void tinyrl_ding(const tinyrl_t * instance);
-
-extern void tinyrl_reset_line_state(tinyrl_t * instance);
-
-extern bool_t tinyrl_insert_text(tinyrl_t * instance, const char *text);
-extern void
-tinyrl_delete_text(tinyrl_t * instance, unsigned start, unsigned end);
-extern void tinyrl_redisplay(tinyrl_t * instance);
-
-extern void
-tinyrl_replace_line(tinyrl_t * instance, const char *text, int clear_undo);
-
-/**
- * Complete the current word in the input buffer, displaying
- * a prompt to clarify any abiguity if necessary.
- *
- * \return
- * - the type of match performed.
- * \post
- * - If the current word is ambiguous then a list of 
- *   possible completions will be displayed.
- */
-extern tinyrl_match_e tinyrl_complete(tinyrl_t * instance);
-
-/**
- * Complete the current word in the input buffer, displaying
- * a prompt to clarify any abiguity or extra extensions if necessary.
- *
- * \return
- * - the type of match performed.
- * \post
- * - If the current word is ambiguous then a list of 
- *   possible completions will be displayed.
- * - If the current word is complete but there are extra
- *   completions which are an extension of that word then
- *   a list of these will be displayed.
- */
-extern tinyrl_match_e tinyrl_complete_with_extensions(tinyrl_t * instance);
-
-/**
- * Disable echoing of input characters when a line in input.
- * 
- */
-extern void tinyrl_disable_echo(
-	 /** 
-          * The instance on which to operate
-          */
-				       tinyrl_t * instance,
-	 /**
-          * The character to display instead of a key press.
-          *
-          * If this has the special value '/0' then the insertion point will not 
-          * be moved when keys are pressed.
-          */
-				       char echo_char);
-/**
- * Enable key echoing for this instance. (This is the default behaviour)
- */
-extern void tinyrl_enable_echo(
-	/** 
-         * The instance on which to operate
-         */
-				      tinyrl_t * instance);
-/**
- * Indicate whether the current insertion point is quoting or not
- */
-extern bool_t tinyrl_is_quoting(
-	/** 
-         * The instance on which to operate
-         */
-				       const tinyrl_t * instance);
-/**
- * Indicate whether the current insertion is empty or not
- */
-extern bool_t
-	tinyrl_is_empty(
-		/**
-		 * The instance on which to operate
-		 */
-		const tinyrl_t *instance
-	);
-/**
- * Limit maximum line length
- */
-extern void tinyrl_limit_line_length(
-	/** 
-         * The instance on which to operate
-         */
-					    tinyrl_t * instance,
-	/** 
-         * The length to limit to (0) is unlimited
-         */
-					    unsigned length);
-
-extern unsigned tinyrl__get_width(const tinyrl_t *instance);
-extern unsigned tinyrl__get_height(const tinyrl_t *instance);
-extern int tinyrl__save_history(const tinyrl_t *instance, const char *fname);
-extern int tinyrl__restore_history(tinyrl_t *instance, const char *fname);
-extern void tinyrl__stifle_history(tinyrl_t *instance, unsigned int stifle);
-
-_END_C_DECL
-#endif				/* _tinyrl_tinyrl_h */
-/** @} tinyrl_tinyrl */

+ 0 - 141
tinyrl/vt100.h

@@ -1,141 +0,0 @@
-/*
- * vt100.h
- *
- * A simple class representing a vt100 terminal
- */
-  /**
-\ingroup tinyrl
-\defgroup tinyrl_vt100 vt100
-@{
-
-\brief A simple class for controlling and interacting with a VT100 compatible
-terminal.
-
-This class has been implemented pragmatically in an as needed fashion, so 
-doesn't support all the features of a VT100 terminal.
-
-*/
-
-#ifndef _tinyrl_vt100_h
-#define _tinyrl_vt100_h
-
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "lub/c_decl.h"
-#include "lub/types.h"
-
-_BEGIN_C_DECL typedef struct _tinyrl_vt100 tinyrl_vt100_t;
-
-/* define the Key codes */
-#define KEY_NUL	0	/**< ^@	Null character */
-#define KEY_SOH	1	/**< ^A	Start of heading, = console interrupt */
-#define KEY_STX	2	/**< ^B	Start of text, maintenance mode on HP console */
-#define KEY_ETX	3	/**< ^C	End of text */
-#define KEY_EOT	4	/**< ^D	End of transmission, not the same as ETB */
-#define KEY_ENQ	5	/**< ^E	Enquiry, goes with ACK; old HP flow control */
-#define KEY_ACK	6	/**< ^F	Acknowledge, clears ENQ logon hand */
-#define KEY_BEL	7	/**< ^G	Bell, rings the bell... */
-#define KEY_BS	8	/**< ^H	Backspace, works on HP terminals/computers */
-#define KEY_HT	9	/**< ^I	Horizontal tab, move to next tab stop */
-#define KEY_LF	10	/**< ^J	Line Feed */
-#define KEY_VT	11	/**< ^K	Vertical tab */
-#define KEY_FF	12	/**< ^L	Form Feed, page eject */
-#define KEY_CR	13	/**< ^M	Carriage Return*/
-#define KEY_SO	14	/**< ^N	Shift Out, alternate character set */
-#define KEY_SI	15	/**< ^O	Shift In, resume defaultn character set */
-#define KEY_DLE	16	/**< ^P	Data link escape */
-#define KEY_DC1	17	/**< ^Q	XON, with XOFF to pause listings; "okay to send". */
-#define KEY_DC2	18	/**< ^R	Device control 2, block-mode flow control */
-#define KEY_DC3	19	/**< ^S	XOFF, with XON is TERM=18 flow control */
-#define KEY_DC4	20	/**< ^T	Device control 4 */
-#define KEY_NAK	21	/**< ^U	Negative acknowledge */
-#define KEY_SYN	22	/**< ^V	Synchronous idle */
-#define KEY_ETB	23	/**< ^W	End transmission block, not the same as EOT */
-#define KEY_CAN	24	/**< ^X	Cancel line, MPE echoes !!! */
-#define KEY_EM	25	/**< ^Y	End of medium, Control-Y interrupt */
-#define KEY_SUB	26	/**< ^Z	Substitute */
-#define KEY_ESC	27	/**< ^[	Escape, next character is not echoed */
-#define KEY_FS	28	/**< ^\	File separator */
-#define KEY_GS	29	/**< ^]	Group separator */
-#define KEY_RS	30	/**< ^^	Record separator, block-mode terminator */
-#define KEY_US	31	/**< ^_	Unit separator */
-
-#define KEY_DEL 127 /**< Delete (not a real control character...) */
-
-/**
- * This enumeration is used to identify the types of escape code 
- */
-typedef enum {
-	tinyrl_vt100_UNKNOWN, /**< Undefined escape sequence */
-	tinyrl_vt100_CURSOR_UP, /**< Move the cursor up */
-	tinyrl_vt100_CURSOR_DOWN, /**< Move the cursor down */
-	tinyrl_vt100_CURSOR_LEFT, /**< Move the cursor left */
-	tinyrl_vt100_CURSOR_RIGHT, /**< Move the cursor right */
-	tinyrl_vt100_HOME, /**< Move the cursor to the beginning of the line */
-	tinyrl_vt100_END, /**< Move the cursor to the end of the line */
-	tinyrl_vt100_INSERT, /**< No action at the moment */
-	tinyrl_vt100_DELETE, /**< Delete character on the right */
-	tinyrl_vt100_PGUP, /**< No action at the moment */
-	tinyrl_vt100_PGDOWN /**< No action at the moment */
-} tinyrl_vt100_escape_e;
-
-/* Return values from vt100_getchar() */
-#define VT100_EOF	-1
-#define VT100_TIMEOUT	-2
-#define VT100_ERR	-3
-
-extern tinyrl_vt100_t *tinyrl_vt100_new(FILE * instream, FILE * outstream);
-extern void tinyrl_vt100_delete(tinyrl_vt100_t * instance);
-
-/*lint -esym(534,tinyrl_vt100_printf) Ignoring return value of function */
-extern int tinyrl_vt100_printf(const tinyrl_vt100_t * instance, const char *fmt, ...
-    );
-extern int
-tinyrl_vt100_vprintf(const tinyrl_vt100_t * instance,
-		     const char *fmt, va_list args);
-
-extern int tinyrl_vt100_oflush(const tinyrl_vt100_t * instance);
-extern int tinyrl_vt100_ierror(const tinyrl_vt100_t * instance);
-extern int tinyrl_vt100_oerror(const tinyrl_vt100_t * instance);
-extern int tinyrl_vt100_ieof(const tinyrl_vt100_t * instance);
-extern int tinyrl_vt100_getchar(const tinyrl_vt100_t * instance);
-extern unsigned tinyrl_vt100__get_width(const tinyrl_vt100_t * instance);
-extern unsigned tinyrl_vt100__get_height(const tinyrl_vt100_t * instance);
-extern void tinyrl_vt100__set_timeout(tinyrl_vt100_t *instance, int timeout);
-extern void
-tinyrl_vt100__set_istream(tinyrl_vt100_t * instance, FILE * istream);
-extern FILE *tinyrl_vt100__get_istream(const tinyrl_vt100_t * instance);
-extern FILE *tinyrl_vt100__get_ostream(const tinyrl_vt100_t * instance);
-
-extern tinyrl_vt100_escape_e
-tinyrl_vt100_escape_decode(const tinyrl_vt100_t * instance, const char *esc_seq);
-extern void tinyrl_vt100_ding(const tinyrl_vt100_t * instance);
-extern void tinyrl_vt100_attribute_reset(const tinyrl_vt100_t * instance);
-extern void tinyrl_vt100_attribute_bright(const tinyrl_vt100_t * instance);
-extern void tinyrl_vt100_attribute_dim(const tinyrl_vt100_t * instance);
-extern void tinyrl_vt100_attribute_underscore(const tinyrl_vt100_t * instance);
-extern void tinyrl_vt100_attribute_blink(const tinyrl_vt100_t * instance);
-extern void tinyrl_vt100_attribute_reverse(const tinyrl_vt100_t * instance);
-extern void tinyrl_vt100_attribute_hidden(const tinyrl_vt100_t * instance);
-extern void tinyrl_vt100_erase_line(const tinyrl_vt100_t * instance);
-extern void tinyrl_vt100_clear_screen(const tinyrl_vt100_t * instance);
-extern void
-tinyrl_vt100_cursor_back(const tinyrl_vt100_t * instance, unsigned count);
-extern void
-tinyrl_vt100_cursor_forward(const tinyrl_vt100_t * instance, unsigned count);
-extern void
-tinyrl_vt100_cursor_up(const tinyrl_vt100_t * instance, unsigned count);
-extern void
-tinyrl_vt100_cursor_down(const tinyrl_vt100_t * instance, unsigned count);
-extern void tinyrl_vt100_scroll_up(const tinyrl_vt100_t *instance);
-extern void tinyrl_vt100_scroll_down(const tinyrl_vt100_t *instance);
-extern void tinyrl_vt100_next_line(const tinyrl_vt100_t *instance);
-extern void tinyrl_vt100_cursor_home(const tinyrl_vt100_t * instance);
-extern void tinyrl_vt100_cursor_save(const tinyrl_vt100_t * instance);
-extern void tinyrl_vt100_cursor_restore(const tinyrl_vt100_t * instance);
-extern void tinyrl_vt100_erase(const tinyrl_vt100_t * instance, unsigned count);
-extern void tinyrl_vt100_erase_down(const tinyrl_vt100_t * instance);
-_END_C_DECL
-#endif				/* _tinyrl_vt100_h */
-/** @} tinyrl_vt100 */

+ 0 - 4
tinyrl/vt100/module.am

@@ -1,4 +0,0 @@
-## Process this file with automake to produce Makefile.in
-libtinyrl_la_SOURCES += \
-	tinyrl/vt100/vt100.c \
-	tinyrl/vt100/private.h

+ 0 - 7
tinyrl/vt100/private.h

@@ -1,7 +0,0 @@
-#include "tinyrl/vt100.h"
-
-struct _tinyrl_vt100 {
-	FILE *istream;
-	FILE *ostream;
-	int   timeout; /* Input timeout in seconds */
-};

+ 0 - 409
tinyrl/vt100/vt100.c

@@ -1,409 +0,0 @@
-#undef __STRICT_ANSI__		/* we need to use fileno() */
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/select.h>
-#include <errno.h>
-
-#include "private.h"
-
-typedef struct {
-	const char* sequence;
-	tinyrl_vt100_escape_e code;
-} vt100_decode_t;
-
-/* This table maps the vt100 escape codes to an enumeration */
-static vt100_decode_t cmds[] = {
-	{"[A", tinyrl_vt100_CURSOR_UP},
-	{"[B", tinyrl_vt100_CURSOR_DOWN},
-	{"[C", tinyrl_vt100_CURSOR_RIGHT},
-	{"[D", tinyrl_vt100_CURSOR_LEFT},
-	{"[H", tinyrl_vt100_HOME},
-	{"[1~", tinyrl_vt100_HOME},
-	{"[F", tinyrl_vt100_END},
-	{"[4~", tinyrl_vt100_END},
-	{"[2~", tinyrl_vt100_INSERT},
-	{"[3~", tinyrl_vt100_DELETE},
-	{"[5~", tinyrl_vt100_PGUP},
-	{"[6~", tinyrl_vt100_PGDOWN},
-};
-
-/*--------------------------------------------------------- */
-tinyrl_vt100_escape_e tinyrl_vt100_escape_decode(const tinyrl_vt100_t *this,
-	const char *esc_seq)
-{
-	tinyrl_vt100_escape_e result = tinyrl_vt100_UNKNOWN;
-	unsigned int i;
-
-	/* Decode the sequence to macros */
-	for (i = 0; i < (sizeof(cmds) / sizeof(vt100_decode_t)); i++) {
-		if (strcmp(cmds[i].sequence, esc_seq))
-			continue;
-		result = cmds[i].code;
-		break;
-	}
-
-	this = this; /* Happy compiler */
-
-	return result;
-}
-
-/*-------------------------------------------------------- */
-int tinyrl_vt100_printf(const tinyrl_vt100_t * this, const char *fmt, ...)
-{
-	va_list args;
-	int len;
-
-	if (!this->ostream)
-		return 0;
-	va_start(args, fmt);
-	len = tinyrl_vt100_vprintf(this, fmt, args);
-	va_end(args);
-
-	return len;
-}
-
-/*-------------------------------------------------------- */
-int
-tinyrl_vt100_vprintf(const tinyrl_vt100_t * this, const char *fmt, va_list args)
-{
-	if (!this->ostream)
-		return 0;
-	return vfprintf(this->ostream, fmt, args);
-}
-
-/*-------------------------------------------------------- */
-int tinyrl_vt100_getchar(const tinyrl_vt100_t *this)
-{
-	unsigned char c;
-	int istream_fd;
-	fd_set rfds;
-	struct timeval tv;
-	int retval;
-	ssize_t res;
-
-	if (!this->istream)
-		return VT100_ERR;
-	istream_fd = fileno(this->istream);
-
-	/* Just wait for the input if no timeout */
-	if (this->timeout <= 0) {
-		while (((res = read(istream_fd, &c, 1)) < 0) &&
-			(EAGAIN == errno));
-		/* EOF or error */
-		if (res < 0)
-			return VT100_ERR;
-		if (!res)
-			return VT100_EOF;
-		return c;
-	}
-
-	/* Set timeout for the select() */
-	FD_ZERO(&rfds);
-	FD_SET(istream_fd, &rfds);
-	tv.tv_sec = this->timeout;
-	tv.tv_usec = 0;
-	while (((retval = select(istream_fd + 1, &rfds, NULL, NULL, &tv)) < 0) &&
-		(EAGAIN == errno));
-	/* Error or timeout */
-	if (retval < 0)
-		return VT100_ERR;
-	if (!retval)
-		return VT100_TIMEOUT;
-
-	res = read(istream_fd, &c, 1);
-	/* EOF or error */
-	if (res < 0)
-		return VT100_ERR;
-	if (!res)
-		return VT100_EOF;
-
-	return c;
-}
-
-/*-------------------------------------------------------- */
-int tinyrl_vt100_oflush(const tinyrl_vt100_t * this)
-{
-	if (!this->ostream)
-		return 0;
-	return fflush(this->ostream);
-}
-
-/*-------------------------------------------------------- */
-int tinyrl_vt100_ierror(const tinyrl_vt100_t * this)
-{
-	if (!this->istream)
-		return 0;
-	return ferror(this->istream);
-}
-
-/*-------------------------------------------------------- */
-int tinyrl_vt100_oerror(const tinyrl_vt100_t * this)
-{
-	if (!this->ostream)
-		return 0;
-	return ferror(this->ostream);
-}
-
-/*-------------------------------------------------------- */
-int tinyrl_vt100_ieof(const tinyrl_vt100_t * this)
-{
-	if (!this->istream)
-		return 0;
-	return feof(this->istream);
-}
-
-/*-------------------------------------------------------- */
-int tinyrl_vt100_eof(const tinyrl_vt100_t * this)
-{
-	if (!this->istream)
-		return 0;
-	return feof(this->istream);
-}
-
-/*-------------------------------------------------------- */
-unsigned int tinyrl_vt100__get_width(const tinyrl_vt100_t *this)
-{
-#ifdef TIOCGWINSZ
-	struct winsize ws;
-	int res;
-#endif
-
-	if(!this->ostream)
-		return 80;
-
-#ifdef TIOCGWINSZ
-	ws.ws_col = 0;
-	res = ioctl(fileno(this->ostream), TIOCGWINSZ, &ws);
-	if (res || !ws.ws_col)
-		return 80;
-	return ws.ws_col;
-#else
-	return 80;
-#endif
-}
-
-/*-------------------------------------------------------- */
-unsigned int tinyrl_vt100__get_height(const tinyrl_vt100_t *this)
-{
-#ifdef TIOCGWINSZ
-	struct winsize ws;
-	int res;
-#endif
-
-	if(!this->ostream)
-		return 25;
-
-#ifdef TIOCGWINSZ
-	ws.ws_row = 0;
-	res = ioctl(fileno(this->ostream), TIOCGWINSZ, &ws);
-	if (res || !ws.ws_row)
-		return 25;
-	return ws.ws_row;
-#else
-	return 25;
-#endif
-}
-
-/*-------------------------------------------------------- */
-static void
-tinyrl_vt100_init(tinyrl_vt100_t * this, FILE * istream, FILE * ostream)
-{
-	this->istream = istream;
-	this->ostream = ostream;
-	this->timeout = -1; /* No timeout by default */
-}
-
-/*-------------------------------------------------------- */
-static void tinyrl_vt100_fini(tinyrl_vt100_t * this)
-{
-	/* nothing to do yet... */
-	this = this;
-}
-
-/*-------------------------------------------------------- */
-tinyrl_vt100_t *tinyrl_vt100_new(FILE * istream, FILE * ostream)
-{
-	tinyrl_vt100_t *this = NULL;
-
-	this = malloc(sizeof(tinyrl_vt100_t));
-	if (this) {
-		tinyrl_vt100_init(this, istream, ostream);
-	}
-
-	return this;
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_delete(tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_fini(this);
-	/* release the memory */
-	free(this);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_ding(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c", KEY_BEL);
-	(void)tinyrl_vt100_oflush(this);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_attribute_reset(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c[0m", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_attribute_bright(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c[1m", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_attribute_dim(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c[2m", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_attribute_underscore(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c[4m", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_attribute_blink(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c[5m", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_attribute_reverse(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c[7m", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_attribute_hidden(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c[8m", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_erase_line(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c[2K", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_clear_screen(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c[2J", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_cursor_save(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c7", KEY_ESC); /* VT100 */
-/*	tinyrl_vt100_printf(this, "%c[s", KEY_ESC); */ /* ANSI */
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_cursor_restore(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c8", KEY_ESC); /* VT100 */
-/*	tinyrl_vt100_printf(this, "%c[u", KEY_ESC); */ /* ANSI */
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_cursor_forward(const tinyrl_vt100_t * this, unsigned count)
-{
-	tinyrl_vt100_printf(this, "%c[%dC", KEY_ESC, count);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_cursor_back(const tinyrl_vt100_t * this, unsigned count)
-{
-	tinyrl_vt100_printf(this, "%c[%dD", KEY_ESC, count);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_cursor_up(const tinyrl_vt100_t * this, unsigned count)
-{
-	tinyrl_vt100_printf(this, "%c[%dA", KEY_ESC, count);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_cursor_down(const tinyrl_vt100_t * this, unsigned count)
-{
-	tinyrl_vt100_printf(this, "%c[%dB", KEY_ESC, count);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_scroll_up(const tinyrl_vt100_t *this)
-{
-	tinyrl_vt100_printf(this, "%cD", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_scroll_down(const tinyrl_vt100_t *this)
-{
-	tinyrl_vt100_printf(this, "%cM", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_next_line(const tinyrl_vt100_t *this)
-{
-	tinyrl_vt100_printf(this, "%cE", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_cursor_home(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c[H", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_erase(const tinyrl_vt100_t * this, unsigned count)
-{
-	tinyrl_vt100_printf(this, "%c[%dP", KEY_ESC, count);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100__set_timeout(tinyrl_vt100_t *this, int timeout)
-{
-	this->timeout = timeout;
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100_erase_down(const tinyrl_vt100_t * this)
-{
-	tinyrl_vt100_printf(this, "%c[J", KEY_ESC);
-}
-
-/*-------------------------------------------------------- */
-void tinyrl_vt100__set_istream(tinyrl_vt100_t * this, FILE * istream)
-{
-	this->istream = istream;
-}
-
-/*-------------------------------------------------------- */
-FILE *tinyrl_vt100__get_istream(const tinyrl_vt100_t * this)
-{
-	return this->istream;
-}
-
-/*-------------------------------------------------------- */
-FILE *tinyrl_vt100__get_ostream(const tinyrl_vt100_t * this)
-{
-	return this->ostream;
-}
-
-/*-------------------------------------------------------- */