speechd-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/6] move src/c/clients to src/clients


From: william hubbs
Subject: [PATCH 1/6] move src/c/clients to src/clients
Date: Wed, 15 Sep 2010 15:55:03 -0500

From: William Hubbs <address@hidden>
To: address@hidden

---
 configure.ac                      |    6 +-
 src/Makefile.am                   |    4 +-
 src/c/Makefile.am                 |    2 +-
 src/c/clients/Makefile.am         |    5 -
 src/c/clients/say/Makefile.am     |   10 -
 src/c/clients/say/options.c       |  201 ---------------
 src/c/clients/say/options.h       |   71 ------
 src/c/clients/say/say.c           |  244 -------------------
 src/c/clients/spdsend/ChangeLog   |   11 -
 src/c/clients/spdsend/Makefile.am |    5 -
 src/c/clients/spdsend/README      |   26 --
 src/c/clients/spdsend/client.c    |  109 ---------
 src/c/clients/spdsend/common.c    |   87 -------
 src/c/clients/spdsend/server.c    |  487 -------------------------------------
 src/c/clients/spdsend/spdsend.c   |  155 ------------
 src/c/clients/spdsend/spdsend.h   |   76 ------
 src/clients/Makefile.am           |    5 +
 src/clients/say/Makefile.am       |   10 +
 src/clients/say/options.c         |  201 +++++++++++++++
 src/clients/say/options.h         |   71 ++++++
 src/clients/say/say.c             |  244 +++++++++++++++++++
 src/clients/spdsend/ChangeLog     |   11 +
 src/clients/spdsend/Makefile.am   |    5 +
 src/clients/spdsend/README        |   26 ++
 src/clients/spdsend/client.c      |  109 +++++++++
 src/clients/spdsend/common.c      |   87 +++++++
 src/clients/spdsend/server.c      |  487 +++++++++++++++++++++++++++++++++++++
 src/clients/spdsend/spdsend.c     |  155 ++++++++++++
 src/clients/spdsend/spdsend.h     |   76 ++++++
 29 files changed, 1493 insertions(+), 1493 deletions(-)
 delete mode 100644 src/c/clients/Makefile.am
 delete mode 100644 src/c/clients/say/Makefile.am
 delete mode 100644 src/c/clients/say/options.c
 delete mode 100644 src/c/clients/say/options.h
 delete mode 100644 src/c/clients/say/say.c
 delete mode 100644 src/c/clients/spdsend/ChangeLog
 delete mode 100644 src/c/clients/spdsend/Makefile.am
 delete mode 100644 src/c/clients/spdsend/README
 delete mode 100644 src/c/clients/spdsend/client.c
 delete mode 100644 src/c/clients/spdsend/common.c
 delete mode 100644 src/c/clients/spdsend/server.c
 delete mode 100644 src/c/clients/spdsend/spdsend.c
 delete mode 100644 src/c/clients/spdsend/spdsend.h
 create mode 100644 src/clients/Makefile.am
 create mode 100644 src/clients/say/Makefile.am
 create mode 100644 src/clients/say/options.c
 create mode 100644 src/clients/say/options.h
 create mode 100644 src/clients/say/say.c
 create mode 100644 src/clients/spdsend/ChangeLog
 create mode 100644 src/clients/spdsend/Makefile.am
 create mode 100644 src/clients/spdsend/README
 create mode 100644 src/clients/spdsend/client.c
 create mode 100644 src/clients/spdsend/common.c
 create mode 100644 src/clients/spdsend/server.c
 create mode 100644 src/clients/spdsend/spdsend.c
 create mode 100644 src/clients/spdsend/spdsend.h

diff --git a/configure.ac b/configure.ac
index cfe6aaf..dab09c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -426,9 +426,9 @@ AC_CONFIG_FILES([Makefile
        src/audio/static_plugins.c
        src/c/Makefile
        src/c/api/Makefile
-       src/c/clients/Makefile
-       src/c/clients/say/Makefile
-       src/c/clients/spdsend/Makefile
+       src/clients/Makefile
+       src/clients/say/Makefile
+       src/clients/spdsend/Makefile
        src/common/Makefile
        src/modules/Makefile
        src/python/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 5bb50ef..bd04add 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,11 +10,11 @@ EXTRA_DIST = cl/ChangeLog cl/README cl/configuration.lisp 
cl/elisp.lisp \
              guile/ChangeLog guile/Makefile guile/README guile/gssip.scm.in \
              guile/gssip.c guile/gssip.h
 
-SUBDIRS=common server audio c modules tests
+SUBDIRS=common server audio c modules clients tests
 
 if HAVE_PYTHON
 SUBDIRS += python
 endif
 
-DIST_SUBDIRS=common server audio c modules tests python
+DIST_SUBDIRS=common server audio c modules clients tests python
 
diff --git a/src/c/Makefile.am b/src/c/Makefile.am
index f227e99..7372a27 100644
--- a/src/c/Makefile.am
+++ b/src/c/Makefile.am
@@ -1,5 +1,5 @@
 ## Process this file with automake to produce Makefile.in
 
-SUBDIRS= api clients
+SUBDIRS= api
 
 
diff --git a/src/c/clients/Makefile.am b/src/c/clients/Makefile.am
deleted file mode 100644
index 195af21..0000000
--- a/src/c/clients/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-SUBDIRS= say spdsend
-
-
diff --git a/src/c/clients/say/Makefile.am b/src/c/clients/say/Makefile.am
deleted file mode 100644
index efb4bca..0000000
--- a/src/c/clients/say/Makefile.am
+++ /dev/null
@@ -1,10 +0,0 @@
-
-localedir = $(datadir)/locale
-inc_local = "-I$(top_srcdir)/include/"
-c_api = $(top_builddir)/src/c/api
-
-AM_CFLAGS = -DLOCALEDIR=\"$(localedir)\" $(inc_local) @glib_include@ 
-I$(top_srcdir)/src/c/api
-
-bin_PROGRAMS = spd-say
-spd_say_SOURCES = say.c options.c options.h
-spd_say_LDADD = $(c_api)/libspeechd.la -lpthread @EXTRA_SOCKET_LIBS@
diff --git a/src/c/clients/say/options.c b/src/c/clients/say/options.c
deleted file mode 100644
index a869f9d..0000000
--- a/src/c/clients/say/options.c
+++ /dev/null
@@ -1,201 +0,0 @@
- /*
- * options.c - Parse and process possible command line options
- *
- * Copyright (C) 2003 Brailcom, o.p.s.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this package; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * $Id: options.c,v 1.9 2006-07-11 16:12:26 hanke Exp $
- */
-
-/* NOTE: Be careful not to include options.h, we would
-   get repetitive initializations warnings */
-
-#define PACKAGE "spd-say"
-#define VERSION "0.4"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include "options.h"
-
-void
-options_print_help(char *argv[])
-{
-    assert(argv);
-    assert(argv[0]);
-
-    printf("Usage: %s [options] \"some text\"\n", argv[0]);
-    printf("Speech Dispatcher Say -- a simple client for speech synthesis (GNU 
GPL)\n\n");
-    printf(
-          "-r, --rate             -     Set the rate of the speech\n"
-           "                               (between -100 and +100, default: 
0)\n"
-          "-p, --pitch            -     Set the pitch of the speech\n"
-          "                               (between -100 and +100, default: 
0)\n"
-          "-i, --volume           -     Set the volume (intensity) of the 
speech\n"
-           "                               (between -100 and +100, default: 0) 
\n"
-          "-o, --output-module    -     Set the output module\n"
-          "-l, --language         -     Set the language (iso code)\n"
-          "-t, --voice-type       -     Set the prefered voice type\n"
-           "                               (male1, male2, male3, female1, 
female2\n"
-          "                                female3, child_male, 
child_female)\n"
-          "-m, --punctuation-mode -     Set the punctuation mode (none, some, 
all) \n"
-          "-s, --spelling         -     Spell the message\n"
-           "-x, --ssml             -     Set SSML mode on (default: off)\n"
-           "\n"
-           "-e, --pipe-mode        -     Pipe from stdin to stdout plus Speech 
Dispatcher\n"
-           "-P, --priority         -     Set priority of the message 
(important, message,\n"
-           "                                text, notification, progress; 
default: text)\n"
-           "-N, --application-name -     Set the application name used to 
estabilish\n"
-           "                                the connection to specified string 
value\n"
-           "                                (default: spd-say)\n"
-           "-n, --connection-name  -     Set the connection name used to 
estabilish\n"
-           "                                the connection to specified string 
value\n"
-          "                                (default: main)\n"
-           "\n"
-          "-w, --wait             -     Wait till the message is spoken or 
discarded\n"
-           "-S, --stop             -     Stop speaking the message being 
spoken\n"
-           "                                in Speech Dispatcher\n"
-           "-C, --cancel           -     Cancel all messages in Speech 
Dispatcher\n"
-           "\n"
-          "-v, --version          -     Print version and copyright info\n"
-          "-h, --help             -     Print this info\n"
-           "\n"
-          "Copyright (C) 2003 Brailcom, o.p.s.\n"
-          "This is free software; you can redistribute it and/or modify it\n"
-          "under the terms of the GNU General Public License as published by\n"
-          "the Free Software Foundation; either version 2, or (at your 
option)\n"
-          "any later version. Please see COPYING for more details.\n\n"
-          "Please report bugs to <speechd at bugs.freebsoft.org>\n\n"
-          );
-    
-}
-
-void
-options_print_version()
-{
-    printf("spd-say: "PACKAGE" "VERSION"\n");
-    printf("Copyright (C) 2002-2006 Brailcom, o.p.s.\n"
-           "spd-say comes with ABSOLUTELY NO WARRANTY.\n"
-           "You may redistribute copies of spd-say\n"
-           "under the terms of the GNU General Public License.\n"
-           "For more information about these matters, see the file named 
COPYING.\n"
-           );
-}
-
-#define OPT_SET_INT(param) \
-    val = strtol(optarg, &tail_ptr, 10); \
-    if(tail_ptr != optarg){ \
-        param = val; \
-    }else{ \
-        printf("Syntax error or bad parameter!\n"); \
-        options_print_help(argv); \
-        exit(1); \
-    }
-
-#define OPT_SET_STR(param) \
-    if(optarg != NULL){ \
-        param = (char*) strdup(optarg); \
-    }else{ \
-        printf("Missing argument!\n"); \
-        options_print_help(argv); \
-        exit(1); \
-    }
-
-int
-options_parse(int argc, char *argv[])
-{
-    char* tail_ptr;
-    int c_opt;
-    int option_index;
-    int val;
-
-    assert (argc>0);
-    assert(argv);
-
-    while(1){
-        option_index = 0;
-    
-        c_opt = getopt_long(argc, argv, short_options, long_options,
-                            &option_index);
-        if (c_opt == -1) break;
-        switch(c_opt){
-        case 'r':
-            OPT_SET_INT(rate);
-            break;
-        case 'p':
-            OPT_SET_INT(pitch);
-            break;
-        case 'i':
-            OPT_SET_INT(volume);
-            break;
-        case 'l':
-            OPT_SET_STR(language);
-            break;
-        case 'o':
-            OPT_SET_STR(output_module);
-            break;
-        case 't':
-            OPT_SET_STR(voice_type);
-            break;
-        case 'm':
-            OPT_SET_STR(punctuation_mode);
-            break;
-       case 's':
-           spelling = 1;
-           break;
-        case 'e':
-            pipe_mode = 1;
-            break;
-       case 'P':
-           OPT_SET_STR(priority);
-           break;
-        case 'x':
-            ssml_mode = 1;
-            break;
-       case 'N':
-           OPT_SET_STR(application_name);
-           break;
-       case 'n':
-           OPT_SET_STR(connection_name);
-           break;
-       case 'w':
-           wait_till_end = 1;
-           break;
-       case 'S':
-           stop_previous = 1;
-           break;
-       case 'C':
-           cancel_previous = 1;
-           break;
-        case 'v':
-            options_print_version(argv);
-            exit(0);
-            break;
-        case 'h':
-            options_print_help(argv);
-            exit(0);
-            break;
-        default:
-            printf("Unrecognized option\n");
-            options_print_help(argv);
-            exit(1);
-        }
-    }
-    return 0;
-}
-#undef SPD_OPTION_SET_INT
diff --git a/src/c/clients/say/options.h b/src/c/clients/say/options.h
deleted file mode 100644
index d9e6b4e..0000000
--- a/src/c/clients/say/options.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * options.h - Defines possible command line options
- *
- * Copyright (C) 2003 Brailcom, o.p.s.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this package; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * $Id: options.h,v 1.10 2006-07-11 16:12:27 hanke Exp $
- */
-
-#include <getopt.h>
-
-signed int rate;
-signed int pitch;
-signed int volume;
-
-char *output_module;
-char *language;
-char *voice_type;
-char *punctuation_mode;
-char *priority;
-int pipe_mode;
-int ssml_mode;
-int spelling;
-int wait_till_end;
-int stop_previous;
-int cancel_previous;
-
-char *application_name;
-char *connection_name;
-
-static struct option long_options[] = {
-    {"rate", 1, 0, 'r'},
-    {"pitch", 1, 0, 'p'},
-    {"volume", 1, 0, 'i'},
-    {"output-module", 1, 0, 'o'},
-    {"language", 1, 0, 'l'},
-    {"voice-type", 1, 0, 't'},
-    {"punctuation-mode", 1, 0, 'm'},
-    {"spelling", 0, 0, 's'},
-    {"ssml", 0, 0, 'x'},
-    {"pipe-mode", 0, 0, 'e'},
-    {"priority", 1, 0, 'P'},
-    {"application-name", 1, 0, 'N'},
-    {"connection-name", 1, 0, 'n'},
-    {"wait", 0, 0, 'w'},
-    {"stop", 1, 0, 'S'},
-    {"cancel", 1, 0, 'C'},
-    {"version", 0, 0, 'v'},
-    {"help", 0, 0, 'h'},
-    {0, 0, 0, 0}
-};
-
-static char* short_options = "r:p:i:l:o:t:m:sxeP:N:n:wSCvh";
-
-int options_parse(int argc, char *argv[]);
-void options_print_version();
-void options_print_help(char *argv[]);
diff --git a/src/c/clients/say/say.c b/src/c/clients/say/say.c
deleted file mode 100644
index 50670c7..0000000
--- a/src/c/clients/say/say.c
+++ /dev/null
@@ -1,244 +0,0 @@
-
-/*
- * say.c - Super-simple Speech Dispatcher client
- *
- * Copyright (C) 2001, 2002, 2003, 2007 Brailcom, o.p.s.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this package; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * $Id: say.c,v 1.16 2007-05-03 09:43:12 hanke Exp $
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <semaphore.h>
-#include <errno.h>
-#include <getopt.h>
-#include "libspeechd.h"
-#include "options.h"
-
-
-#define MAX_LINELEN 16384
-
-sem_t semaphore;
-
-/* Callback for Speech Dispatcher notifications */
-void end_of_speech(size_t msg_id, size_t client_id, SPDNotificationType type)
-{
-    sem_post(&semaphore);
-}
-
-int main(int argc, char **argv) {
-    SPDConnection *conn;
-    SPDPriority spd_priority;
-    int err;
-    char *error;
-    int msg_arg_required = 0;
-    int ret;
-    int option_ret;
-    char *line;
-
-    rate = -101;
-    pitch = -101;
-    volume = -101;
-    language = NULL;
-    voice_type = NULL;
-    punctuation_mode = NULL;
-    spelling = -2;
-    ssml_mode = 0;
-    wait_till_end = 0;
-    stop_previous = 0;
-    cancel_previous = 0;
-    pipe_mode = 0;
-    priority = NULL;
-    application_name = NULL;
-    connection_name = NULL;
-
-    option_ret = options_parse(argc, argv);
-
-    /* Check if the text to say or options are specified in the argument */
-    msg_arg_required = (pipe_mode != 1) && (stop_previous != 1)
-                       && (cancel_previous != 1);
-    if ((optind >= argc) && msg_arg_required) {
-        options_print_help(argv);
-        return 1;
-    }
-
-    /* Open a connection to Speech Dispatcher */
-    conn = spd_open2(application_name ? application_name : "spd-say",
-                    connection_name ? connection_name : "main",
-                    NULL, SPD_MODE_THREADED, NULL, 1, &error);
-    if (conn == NULL){
-      fprintf(stderr, "Failed to connect to Speech Dispatcher:\n%s\n", error);
-      exit(1);
-    }
-
-    if (stop_previous) spd_stop_all(conn);
-    if (cancel_previous) spd_cancel_all(conn);
-
-    /* Set the desired parameters */
-
-    if (language != NULL)
-        if(spd_set_language(conn, language))
-            printf("Invalid language!\n");
-
-    if (output_module != NULL)
-        if(spd_set_output_module(conn, output_module))
-            printf("Invalid output module!\n");
-
-    if (voice_type != NULL){
-        if (!strcmp(voice_type, "male1")){
-            if(spd_set_voice_type(conn, SPD_MALE1))
-                printf("Can't set this voice!\n");
-        }
-        else if(!strcmp(voice_type, "male2")){
-            if(spd_set_voice_type(conn, SPD_MALE2))
-                printf("Can't set this voice!\n");
-        }
-        else if(!strcmp(voice_type, "male3")){
-            if(spd_set_voice_type(conn, SPD_MALE3))
-            printf("Can't set this voice!\n");
-        }
-        else if(!strcmp(voice_type, "female1")){
-            if(spd_set_voice_type(conn, SPD_FEMALE1))
-                printf("Can't set this voice!\n");
-        }
-        else if(!strcmp(voice_type, "female2")){
-            if(spd_set_voice_type(conn, SPD_FEMALE2))
-                printf("Can't set this voice!\n");
-        }
-        else if(!strcmp(voice_type, "female3")){
-            if(spd_set_voice_type(conn, SPD_FEMALE3))
-                printf("Can't set this voice!\n");
-        }
-        else if(!strcmp(voice_type, "child_male")){
-            if(spd_set_voice_type(conn, SPD_CHILD_MALE))
-                printf("Can't set this voice!\n");
-        }
-        else if(!strcmp(voice_type, "child_female")){
-            if(spd_set_voice_type(conn, SPD_CHILD_FEMALE))
-                printf("Can't set this voice!\n");
-        }else{
-            printf("Invalid voice\n");
-        }
-    }
-
-    if (ssml_mode)
-        if(spd_execute_command(conn, "SET SELF SSML_MODE ON"))
-            printf("Failed to set SSML mode.\n");
-
-    if (rate != -101)
-        if(spd_set_voice_rate(conn, rate))
-            printf("Invalid rate!\n");
-
-    if (pitch != -101)
-        if(spd_set_voice_pitch(conn, pitch))
-            printf("Invalid pitch!\n");
-
-    if (volume != -101)
-        if(spd_set_volume(conn, volume))
-            printf("Invalid volume!\n");
-
-    if (spelling == 1)
-        if(spd_set_spelling(conn, SPD_SPELL_ON))
-            printf("Can't set spelling to on!\n");
-
-    if (punctuation_mode != NULL){
-        if (!strcmp(punctuation_mode, "none")){
-            if(spd_set_punctuation(conn, SPD_PUNCT_NONE))
-                printf("Can't set this punctuation mode!\n");
-        }
-        else if(!strcmp(punctuation_mode, "some")){
-            if(spd_set_punctuation(conn, SPD_PUNCT_SOME))
-                printf("Can't set this punctuation mode!\n");
-        }
-        else if(!strcmp(punctuation_mode, "all")){
-            if(spd_set_punctuation(conn, SPD_PUNCT_ALL))
-                printf("Can't set this punctuation mode!\n");
-        }else{
-            printf("Invalid punctuation mode.\n");
-        }
-    }
-
-    /* Set default priority... */
-    if (1 == pipe_mode)
-        spd_priority = SPD_MESSAGE;
-    else
-        spd_priority = SPD_TEXT;
-    /* ...and look if it wasn't overriden */
-    if (priority != NULL){
-        if (!strcmp(priority, "important")) spd_priority = SPD_IMPORTANT;
-        else if (!strcmp(priority, "message")) spd_priority = SPD_MESSAGE;
-        else if (!strcmp(priority, "text")) spd_priority = SPD_TEXT;
-        else if (!strcmp(priority, "notification")) spd_priority = 
SPD_NOTIFICATION;
-        else if (!strcmp(priority, "progress")) spd_priority = SPD_PROGRESS;
-        else{
-            printf("Invalid priority.\n");
-        }
-    }
-
-    if (wait_till_end){
-        ret = sem_init(&semaphore, 0, 0);
-        if (ret < 0){
-            fprintf(stderr, "Can't initialize semaphore: %s", strerror(errno));
-            return 0;
-        }
-
-        /* Notify when the message is canceled or the speech terminates */
-        conn->callback_end = end_of_speech;
-        conn->callback_cancel = end_of_speech;
-        spd_set_notification_on(conn, SPD_END);
-        spd_set_notification_on(conn, SPD_CANCEL);
-    }
-
-    /* In pipe mode, read from stdin, write to stdout, and also to Speech 
Dispatcher. */
-    if (pipe_mode == 1) {
-        line = (char *) malloc( MAX_LINELEN );
-        while (NULL != fgets(line, MAX_LINELEN, stdin)) {
-            fputs(line, stdout);
-            if (0 == strncmp(line, "!-!", 3)) {
-                /* Remove EOL */
-                line[strlen(line)-1] = 0;
-                spd_execute_command(conn, line + 3);
-            } else {
-                spd_say(conn, spd_priority, line);
-                if (wait_till_end) sem_wait(&semaphore);
-            }
-        }
-        free(line);
-
-    } else {
-        /* Say the message with priority "text" */
-        /* Or do nothing in case of -C or -S with no message. */
-        if (optind < argc) {
-         err = spd_sayf(conn, spd_priority, (char*) argv[optind]);
-         if (err == -1){
-           fprintf(stderr, "Speech Dispatcher failed to say message");
-           exit(1);
-         }
-
-          /* Wait till the callback is called */
-          if (wait_till_end) sem_wait(&semaphore);
-        }
-    }
-
-    /* Close the connection */
-    spd_close(conn);
-
-    return 0;
-}
diff --git a/src/c/clients/spdsend/ChangeLog b/src/c/clients/spdsend/ChangeLog
deleted file mode 100644
index f58cc8f..0000000
--- a/src/c/clients/spdsend/ChangeLog
+++ /dev/null
@@ -1,11 +0,0 @@
-2008-02-01  Hynek Hanke  <hanke at mach>
-
-       * server.c (serve): Correct type for client_address_len.
-
-2006-07-25  root  <hanke at brailcom.org>
-
-       * README: speechd
-
-2004-09-08  Milan Zamazal  <pdm at brailcom.org>
-
-       * server.c (do_send_data): Close the connection on error.
diff --git a/src/c/clients/spdsend/Makefile.am 
b/src/c/clients/spdsend/Makefile.am
deleted file mode 100644
index 0dc9eee..0000000
--- a/src/c/clients/spdsend/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-
-bin_PROGRAMS = spdsend
-spdsend_SOURCES = spdsend.h spdsend.c server.c client.c common.c 
-spdsend_LDADD = -lpthread @EXTRA_SOCKET_LIBS@
-
diff --git a/src/c/clients/spdsend/README b/src/c/clients/spdsend/README
deleted file mode 100644
index 8d0a95f..0000000
--- a/src/c/clients/spdsend/README
+++ /dev/null
@@ -1,26 +0,0 @@
-This is a simple command line client to Speech Dispatcher.  It may be useful in
-programs, which don't want to use direct socket communication with Speech
-Dispatcher for some reason.
-
-To compile the program, just run `make'.  To install it, run `make install'.
-
-The following operations are supported:
-
-$ spdsend --open HOST PORT
-
-  Open new connection to Speech Dispatcher running at HOST:PORT and print the
-  connection identifier on the standard output.
-
-$ spdsend --close CONNECTION
-
-  Close the given Speech Dispatcher CONNECTION.
-
-$ spdsend --send CONNECTION
-
-  Read an SSIP command from standard input, forward it to Speech Dispatcher
-  CONNECTION and print the answer on the standard output.
-
-You can send your bug reports, patches, suggestions, etc. to the mailing list
-speechd at lists.freebsoft.org.
-
--- Milan Zamazal <pdm at freebsoft.org>
diff --git a/src/c/clients/spdsend/client.c b/src/c/clients/spdsend/client.c
deleted file mode 100644
index 232ab79..0000000
--- a/src/c/clients/spdsend/client.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* client.c -- Client part of spdsend
-   Author: Milan Zamazal <pdm at brailcom.org>
-*/
-
-/* Copyright (C) 2004 Brailcom, o.p.s.
-
-   COPYRIGHT NOTICE
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the Free
-   Software Foundation; either version 2, or (at your option) any later
-   version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-   for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
-*/
-
-
-#include "spdsend.h"
-
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-
-
-static Success send_header (Stream s, Action action, Connection_Id id)
-{
-  if (write_data (s, &action, sizeof (Action)) == OK &&
-      write_data (s, &id, sizeof (Connection_Id)) == OK)
-    return OK;
-  else
-    return ERROR;
-}
-
-#define SEND_HEADER(action)                      \
-  if (send_header (s, action, id) == ERROR) \
-    return ERROR
-
-static Success send_open_header (Stream s, const char *host, int port)
-{
-  int hostlen = strlen (host);
-  Action action = A_OPEN;
-  
-  if (write_data (s, &action, sizeof (Action)) == OK &&
-      write_data (s, &port, sizeof (int)) == OK &&
-      write_data (s, &hostlen, sizeof (int)) == OK &&
-      write_data (s, host, hostlen) == OK)
-    return OK;
-  else
-    return ERROR;
-}
-
-
-static Connection_Id read_reply (Stream s)
-{
-  Result result;
-  Connection_Id id;
-  
-  if (read_data (s, &result, sizeof (Result)) != sizeof (Result))
-    return NONE;
-  if (result != OK_CODE)
-    return NONE;
-  
-  if (read_data (s, &id, sizeof (Connection_Id)) != sizeof (Connection_Id))
-    return NONE;
-  
-  return id;
-}
-
-
-/* External functions */
-
-
-extern Success open_connection (Stream s, const char *host, int port)
-{
-  if (send_open_header (s, host, port) == ERROR)
-    return ERROR;
-  {
-    Connection_Id id = read_reply (s);
-    if (id == NONE)
-      return ERROR;
-    printf ("%d\n", id);
-  }
-  return OK;
-}
-
-extern Success close_connection (Stream s, Connection_Id id)
-{
-  SEND_HEADER (A_CLOSE);
-  return (read_reply (s) == OK ? OK : ERROR);
-}
-
-extern Success send_command (Stream s, Connection_Id id)
-{
-  SEND_HEADER (A_DATA);
-  if (read_reply (s) == NONE)
-    return ERROR;
-  if (forward_data (0, s, TRUE) == OK &&
-      forward_data (s, 1, FALSE) == OK)
-    return OK;
-  else
-    return ERROR;
-}
diff --git a/src/c/clients/spdsend/common.c b/src/c/clients/spdsend/common.c
deleted file mode 100644
index aab7543..0000000
--- a/src/c/clients/spdsend/common.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* common.c -- Common parts of the client and the server
-   Author: Milan Zamazal <pdm at brailcom.org>
-*/
-
-/* Copyright (C) 2004 Brailcom, o.p.s.
-
-   COPYRIGHT NOTICE
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the Free
-   Software Foundation; either version 2, or (at your option) any later
-   version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-   for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
-*/
-
-
-#include <limits.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include "spdsend.h"
-
-
-const long CONNECTION_ID_MIN = 1;
-const long CONNECTION_ID_MAX = 1000;
-
-const int EXIT_OK = 0;
-const int EXIT_ERROR = 1;
-
-
-extern Success write_data (Stream s, const void *buffer, size_t size)
-{
-  int written;
-
-  for ( ; size > 0; size -= written, buffer += written)
-    {
-      written = write (s, buffer, size);
-      if (written < 0)
-        return ERROR;
-    }
-  
-  return OK;
-}
-
-extern int read_data (Stream s, void *buffer, size_t max_size)
-{
-  size_t nread = 0, n;
-
-  while (nread < max_size)
-    {
-      n = read (s, buffer, max_size);
-      if (n < 0)
-        return NONE;
-      if (n == 0)
-        break;
-      nread += n;
-      buffer += n;
-      max_size -= n;
-    }
-  
-  return nread;
-}
-
-extern Success forward_data (Stream from, Stream to, bool closep)
-{    
-  const size_t buffer_size = 4096;
-  char buffer[buffer_size];
-  ssize_t n;
-
-  while ((n = read (from, buffer, buffer_size)) > 0)
-    {
-      if (write_data (to, buffer, n) == ERROR)
-        return ERROR;
-    }
-  if (closep)
-    shutdown (to, SHUT_WR);
-  
-  return (n == NONE ? ERROR : OK);
-}
diff --git a/src/c/clients/spdsend/server.c b/src/c/clients/spdsend/server.c
deleted file mode 100644
index 1b45f01..0000000
--- a/src/c/clients/spdsend/server.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/* server.c -- Server part of spdsend
-   Author: Milan Zamazal <pdm at brailcom.org>
-*/
-
-/* Copyright (C) 2004 Brailcom, o.p.s.
-
-   COPYRIGHT NOTICE
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the Free
-   Software Foundation; either version 2, or (at your option) any later
-   version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-   for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
-*/
-
-
-#include "spdsend.h"
-
-#ifndef USE_THREADS
-#define USE_THREADS 1
-#endif
-
-#include <errno.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#if USE_THREADS
-#include <pthread.h>
-#endif
-#include <pwd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#if !(defined(__GLIBC__) && defined(_GNU_SOURCE))
-/* Added by Willie Walker - TEMP_FAILURE_RETRY, strndup, and getline
- * are gcc-isms
- */
-ssize_t getline (char **lineptr, size_t *n, FILE *f);
-#endif
-
-/* Utilities */
-
-
-static void system_error (const char *message)
-{
-  perror (message);
-  exit (1);
-}
-
-
-/* Connection management */
-
-
-Stream *connections;
-#if USE_THREADS
-pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
-
-
-static Stream get_connection (Connection_Id id)
-{
-  return connections[id];
-}
-
-static void set_connection (Connection_Id id, Stream s)
-{
-#if USE_THREADS
-  pthread_mutex_lock (&connections_mutex);
-#endif
-  connections[id] = s;
-#if USE_THREADS
-  pthread_mutex_unlock (&connections_mutex);
-#endif
-}
-
-static Connection_Id new_connection (Stream s)
-{
-#if USE_THREADS
-  pthread_mutex_lock (&connections_mutex);
-#endif
-  int id;
-  for (id = CONNECTION_ID_MIN;
-       id < CONNECTION_ID_MAX && connections[id] != NONE;
-       id++)
-    ;
-  if (id >= CONNECTION_ID_MAX)
-    return NONE;
-  connections[id] = s;
-#if USE_THREADS
-  pthread_mutex_unlock (&connections_mutex);
-#endif
-  return id;
-}
-
-static Connection_Id do_open_connection (const char *host, int port)
-{
-  int sock = socket (AF_INET, SOCK_STREAM, 0);
-  
-  {
-    struct sockaddr_in name;
-    name.sin_family = AF_INET;
-    name.sin_port = htons (port);
-    {
-      struct hostent *hostinfo;
-      hostinfo = gethostbyname (host);
-      if (hostinfo == NULL)
-        return NONE;
-      name.sin_addr = *(struct in_addr *) hostinfo->h_addr;
-    }
-    if (connect (sock, (struct sockaddr *)&name, sizeof (name)) < 0)
-      return NONE;
-    {
-      int arg = 1;
-      setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &arg, sizeof(int));
-    }
-  }
-  
-  {
-    Connection_Id id = new_connection (sock);
-    if (id == NONE)
-      close (sock);
-    return id;
-  }
-}
-
-static Success do_close_connection (Connection_Id id)
-{
-  Stream c = get_connection (id);
-  if (c == NONE)
-    return ERROR;
-  close (c);
-  set_connection (id, NONE);
-  return OK;
-}
-
-static Success do_send_data (Connection_Id id, Stream from, Stream to,
-                             Success (*forwarder) (Stream, Stream, bool))
-{
-  int sock = get_connection (id);
-  if (sock == NONE)
-    return ERROR;
-  if (from == NONE)
-    from = sock;
-  else if (to == NONE)
-    to = sock;
-  {
-    Success result = ((*forwarder) (from, to, FALSE));
-    if (result != OK)
-      do_close_connection (id);
-    return result;
-  }
-}
-
-
-/* Processing requests */
-
-/* Protocol:
-
-   Client request:
-     First comes the action code, of the type Action.
-     If Action is A_OPEN, the following data follows:
-       int port, int strlen(hostname), hostname
-     Else:
-       Connection_Id
-     Then, if Action is A_DATA, the SSIP lines follow.
-     
-   Server answer:
-     The result code, of the type Result.
-     If Result is OK, Connection_Id follows.
-     Additionally, if Action is A_DATA, SSIP reply follows.
-*/
-
-static Success report (Stream s, Result code)
-{
-  return write_data (s, &code, sizeof (Result));
-}
-
-static Success report_ok (Stream s, Connection_Id id)
-{
-  if (report (s, OK_CODE) == OK &&
-      write_data (s, &id, sizeof (Connection_Id)) == OK)
-    return OK;
-  else
-    return ERROR;
-}
-
-static Success report_error (Stream s)
-{
-  return report (s, ER_CODE);
-}
-
-
-static Connection_Id read_id (Stream s)
-{
-  Connection_Id id;
-  if (read_data (s, &id, sizeof (Connection_Id)) == ERROR)
-    return NONE;
-  return id;
-}
-
-
-static Success forward_ssip_answer (Stream from, Stream to, bool _closep)
-{
-  int result = OK;
-  FILE *f = fdopen (from, "r");
-  size_t line_size = 256;
-  char *line = malloc (line_size);
-  if (line == NULL)
-    system_error ("memory allocation");
-
-  while (1)
-    {
-      int n = getline (&line, &line_size, f);
-      if (n < 0 || write_data (to, line, n) == ERROR)
-        {
-          result = ERROR;
-          break;
-        }
-      if (n > 3 && line[3] == ' ')
-        break;
-    }
-
-  free (line);
-  return result;
-}
-
-
-static void process_open (Stream s)
-{
-  Connection_Id id;
-  int port;
-  int hostlen;
-  
-  if (read_data (s, &port, sizeof (int)) != sizeof (int))
-    {
-      report_error (s);
-      return;
-    }
-  if (read_data (s, &hostlen, sizeof (int)) != sizeof (int))
-    {
-      report_error (s);
-      return;
-    }
-  {
-    char *host = malloc (hostlen+1);
-    if (host == NULL)
-      system_error ("memory allocation");
-    if (read_data (s, host, hostlen) != hostlen)
-      {
-        free (host);
-        report_error (s);
-        return;
-      }
-    host[hostlen] = '\0';
-    id = do_open_connection (host, port);
-    free (host);
-  }
-
-  if (id == NONE)
-    report_error (s);
-  else
-    report_ok (s, id);
-}
-
-static void process_close (Stream s)
-{
-  Connection_Id id = read_id (s);
-  if (id != NONE && do_close_connection (id) == OK)
-    report_ok (s, id);
-  else
-    report_error (s);
-}
-
-static void process_data (Stream s)
-{
-  Connection_Id id = read_id (s);
-  if (id != NONE)
-    report_ok (s, id);
-  else
-    report_error (s);
-
-  if (do_send_data (id, s, NONE, forward_data) == OK)
-    do_send_data (id, NONE, s, forward_ssip_answer);
-}
-
-
-static void process_request (Stream s)
-{
-  Action action;
-
-  if (read_data (s, &action, sizeof (Action)) == NONE)
-    return;
-  
-  if (action == A_OPEN)
-    process_open (s);
-  else if (action == A_CLOSE)
-    process_close (s);
-  else if (action == A_DATA)
-    process_data (s);
-  else
-    report_error (s);
-  
-  close (s);
-}
-
-#if USE_THREADS
-static void *process_request_thread (void *s)
-{
-  Stream s_deref = *((Stream *) s);
-  free (s);
-  pthread_detach (pthread_self ());
-  process_request (s_deref);
-  return NULL;
-}
-#endif
-
-
-/* Starting the server */
-
-
-static const char *login_name ()
-{
-  return getpwuid (getuid ()) -> pw_name;
-}
-
-static const char *server_socket_name ()
-{
-  char *name;
-  if (asprintf (&name, "/tmp/spdsend-server.%s", login_name ()) < 0)
-    system_error ("memory allocation");
-  return name;
-}
-
-static void serve ()
-{
-  struct sockaddr_un name;
-  int sock;
-  size_t size;
-  const char *filename = server_socket_name ();
-     
-  sock = socket (PF_LOCAL, SOCK_STREAM, 0);
-  if (sock < 0)
-    system_error ("socket creation");
-  
-  name.sun_family = AF_LOCAL;
-  strncpy (name.sun_path, filename, sizeof (name.sun_path));
-  name.sun_path[sizeof (name.sun_path) - 1] = '\0';
-  size = (offsetof (struct sockaddr_un, sun_path)
-          + strlen (name.sun_path) + 1);
-  if (bind (sock, (struct sockaddr *) &name, size) < 0)
-    system_error ("bind");
-  if (listen (sock, LISTEN_QUEUE_LENGTH) < 0)
-    system_error ("listen");
-  
-  while (1)
-    {
-      struct sockaddr_un client_address;
-      socklen_t client_address_len = sizeof (client_address);
-      Stream *s = malloc (sizeof (Stream));
-      if (s == NULL)
-        system_error ("memory allocation");
-      *s = accept (sock, (struct sockaddr *)&client_address,
-                   &client_address_len);
-      if (*s < 0)
-        break;
-      {
-#if USE_THREADS
-        pthread_t tid;
-#endif
-#if USE_THREADS
-        pthread_create (&tid, NULL, &process_request_thread, s);
-#else
-        process_request (*s);
-#endif
-      }
-    }
-}
-
-static void daemonize ()
-{
-  int ret = 0;
-  if (fork () != 0)
-    exit (0);
-  setsid ();
-  signal (SIGHUP, SIG_IGN);
-  if (fork () != 0)
-    exit (0);
-  if ((ret = chdir ("/")) != 0)
-    fputs("server.c:daemonize: could not chdir", stderr);
-    exit (1);
-  umask (0);
-  {
-    int i;
-    for (i = 0; i < 4; i++)
-      close (i);
-  }
-}
-
-static void init_connections ()
-{
-  connections = malloc (CONNECTION_ID_MAX * sizeof (Connection_Id));
-  if (connections == NULL)
-    system_error ("memory allocation");
-  {
-    int i;
-    for (i = CONNECTION_ID_MIN; i < CONNECTION_ID_MAX; i++)
-      connections[i] = NONE;
-  }
-#if USE_THREADS
-  pthread_mutex_init (&connections_mutex, NULL);
-#endif
-}
-
-static void start_server ()
-{
-  const char *socket_name = server_socket_name ();
-  unlink (socket_name);
-  
-  {
-    int pid = fork ();
-    if (pid == -1)
-      system_error ("fork");
-
-    if (pid == 0)
-      {
-        daemonize ();
-        init_connections ();
-        serve ();
-        unlink (socket_name);
-        exit (0);
-      }
-    else
-      sleep (1);
-  }
-}
-
-static int connect_server ()
-{    
-  struct sockaddr_un name;
-  int sock = socket (AF_LOCAL, SOCK_STREAM, 0);
-  int name_size;
-  name.sun_family = AF_LOCAL;
-  strncpy (name.sun_path, server_socket_name (), sizeof (name.sun_path));
-  name.sun_path[sizeof (name.sun_path) - 1] = '\0';
-  name_size = (offsetof (struct sockaddr_un, sun_path)
-               + strlen (name.sun_path) + 1);
-     
-  if (connect (sock, (struct sockaddr *)&name, name_size) < 0)
-    return NONE;
-  else
-    return sock;
-}
-
-
-/* External functions */
-
-
-Stream open_server ()
-{
-  Stream s;
-
-  s = connect_server ();
-  if (s == NONE)
-    {
-      start_server ();
-      s = connect_server ();
-    }
-  if (s == NONE)
-    return NONE;
-
-  return s;
-}
-
diff --git a/src/c/clients/spdsend/spdsend.c b/src/c/clients/spdsend/spdsend.c
deleted file mode 100644
index 708096a..0000000
--- a/src/c/clients/spdsend/spdsend.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/* spdsend.c -- Send SSIP commands to Speech Dispatcher
-   Author: Milan Zamazal <pdm at brailcom.org>
-*/
-
-/* Copyright (C) 2004 Brailcom, o.p.s.
-
-   COPYRIGHT NOTICE
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the Free
-   Software Foundation; either version 2, or (at your option) any later
-   version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-   for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
-*/
-
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "spdsend.h"
-
-
-const char *const VERSION = "0.0.0";
-
-#if !(defined(__GLIBC__) && defined(_GNU_SOURCE))
-/* Added by Willie Walker - getline is a gcc-ism */
-#define BUFFER_LEN 256
-ssize_t getline (char **lineptr, size_t *n, FILE *f)
-{
-        char ch;
-        size_t m = 0;
-        ssize_t buf_len = 0;
-        char * buf = NULL;
-        char * p = NULL;
-
-       if (errno != 0) {
-               errno = 0;
-       }
-        while ( (ch = getc(f)) !=EOF )
-        {
-                if (errno != 0)
-                        return -1;
-                if ( m++ >= buf_len )
-                {
-                        buf_len += BUFFER_LEN;
-                        buf = (char *) realloc(buf, buf_len + 1);
-                        if ( buf == NULL )
-                        {
-                                return -1;
-                        }
-                        p = buf + buf_len - BUFFER_LEN;
-                }
-                *p = ch;
-                p++;
-                if ( ch == '\n' )
-                        break;
-        }
-        if ( m == 0 )
-        {
-                return -1;
-        } else {
-                *p = '\0';
-                *lineptr = buf;
-                *n = m;
-                return m;
-        }
-}
-#endif /* !(defined(__GLIBC__) && defined(_GNU_SOURCE)) */
-
-static void usage (const char *const message)
-{
-  if (message != NULL)
-    fprintf (stderr, "spdsend: %s\n", message);
-  fprintf (stderr,
-           "usage: spdsend { --open SERVER PORT | --close ID | --send ID }\n");
-  exit (EXIT_ERROR);
-}
-
-
-static long string_to_number (const char *string,
-                              long low_limit, long high_limit)
-{
-  char *tailptr;
-  errno = 0;
-  long int number = strtol (string, &tailptr, 0);
-  if (errno || *tailptr || number < low_limit || number > high_limit)
-    usage ("Invalid parameter");
-  return number;
-}
-
-
-int main (int argc, char **argv)
-{
-  if (argc < 2)
-    usage ("Invalid number of arguments");
-
-  {    
-    const char *const action = argv[1];    
-    Success (*function) (Stream, Connection_Id);
-    Connection_Id conn_id;
-    char *host;
-    int port;
-
-    if (! strcmp (action, "--version"))
-      {
-        printf ("spdsend %s\n", VERSION);
-        exit (EXIT_OK);
-      }
-    
-    const int action_is_open = strcmp (action, "--open") == 0;
-    if (action_is_open)
-      {
-        if (argc != 4)
-          usage ("Invalid number of arguments");
-        host = argv[2];
-        port = string_to_number (argv[3], 0, 65535);
-      }
-    else
-      {
-        if (argc != 3)
-          usage ("Invalid number of arguments");
-        conn_id = string_to_number (argv[2], CONNECTION_ID_MIN,
-                                    CONNECTION_ID_MAX);
-        if (! strcmp (action, "--close"))
-          function = close_connection;
-        else if (! strcmp (action, "--send"))
-          function = send_command;
-        else
-          usage ("Invalid option");
-      }
-    
-    {
-      Stream server = open_server ();
-      if (server == NONE)
-        return EXIT_ERROR;
-      
-      {
-        int result = (action_is_open
-                      ? open_connection (server, host, port)
-                      : function (server, conn_id));
-        return (result == OK ? EXIT_OK : EXIT_ERROR);
-      }
-    }
-  }
-}
diff --git a/src/c/clients/spdsend/spdsend.h b/src/c/clients/spdsend/spdsend.h
deleted file mode 100644
index 8794eb7..0000000
--- a/src/c/clients/spdsend/spdsend.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Declarations for spdsend
-   Author: Milan Zamazal <pdm at brailcom.org>
-*/
-
-/* Copyright (C) 2004 Brailcom, o.p.s.
-
-   COPYRIGHT NOTICE
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the Free
-   Software Foundation, version 2 of the License.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-   for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
-*/
-
-
-#ifndef __SPDSEND_H
-
-#define __SPDSEND_H
-
-
-#define _GNU_SOURCE
-
-#include <stddef.h>
-
-
-/* Configuration */
-
-#ifndef LISTEN_QUEUE_LENGTH
-#define LISTEN_QUEUE_LENGTH 100
-#endif
-
-/* Types */
-
-typedef enum { FALSE, TRUE } bool;
-typedef int Stream;
-typedef int Connection_Id;
-
-typedef enum { OK, ERROR } Success;
-#define NONE -1
-
-/* common.c */
-
-extern Success write_data (Stream s, const void *buffer, size_t size);
-extern int read_data (Stream s, void *buffer, size_t max_size);
-extern Success forward_data (Stream from, Stream to, bool closep);
-
-typedef enum { A_OPEN, A_CLOSE, A_DATA } Action;
-
-typedef enum { OK_CODE, ER_CODE } Result;
-
-extern const long CONNECTION_ID_MIN;
-extern const long CONNECTION_ID_MAX;
-
-extern const int EXIT_OK;
-extern const int EXIT_ERROR;
-
-/* server.c */
-
-extern Stream open_server ();
-
-/* client.c */
-
-extern Success open_connection (Stream server, const char *host, int port);
-extern Success close_connection (Stream server, Connection_Id id);
-extern Success send_command (Stream server, Connection_Id id);
-
-
-#endif
diff --git a/src/clients/Makefile.am b/src/clients/Makefile.am
new file mode 100644
index 0000000..195af21
--- /dev/null
+++ b/src/clients/Makefile.am
@@ -0,0 +1,5 @@
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS= say spdsend
+
+
diff --git a/src/clients/say/Makefile.am b/src/clients/say/Makefile.am
new file mode 100644
index 0000000..efb4bca
--- /dev/null
+++ b/src/clients/say/Makefile.am
@@ -0,0 +1,10 @@
+
+localedir = $(datadir)/locale
+inc_local = "-I$(top_srcdir)/include/"
+c_api = $(top_builddir)/src/c/api
+
+AM_CFLAGS = -DLOCALEDIR=\"$(localedir)\" $(inc_local) @glib_include@ 
-I$(top_srcdir)/src/c/api
+
+bin_PROGRAMS = spd-say
+spd_say_SOURCES = say.c options.c options.h
+spd_say_LDADD = $(c_api)/libspeechd.la -lpthread @EXTRA_SOCKET_LIBS@
diff --git a/src/clients/say/options.c b/src/clients/say/options.c
new file mode 100644
index 0000000..a869f9d
--- /dev/null
+++ b/src/clients/say/options.c
@@ -0,0 +1,201 @@
+ /*
+ * options.c - Parse and process possible command line options
+ *
+ * Copyright (C) 2003 Brailcom, o.p.s.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this package; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $Id: options.c,v 1.9 2006-07-11 16:12:26 hanke Exp $
+ */
+
+/* NOTE: Be careful not to include options.h, we would
+   get repetitive initializations warnings */
+
+#define PACKAGE "spd-say"
+#define VERSION "0.4"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "options.h"
+
+void
+options_print_help(char *argv[])
+{
+    assert(argv);
+    assert(argv[0]);
+
+    printf("Usage: %s [options] \"some text\"\n", argv[0]);
+    printf("Speech Dispatcher Say -- a simple client for speech synthesis (GNU 
GPL)\n\n");
+    printf(
+          "-r, --rate             -     Set the rate of the speech\n"
+           "                               (between -100 and +100, default: 
0)\n"
+          "-p, --pitch            -     Set the pitch of the speech\n"
+          "                               (between -100 and +100, default: 
0)\n"
+          "-i, --volume           -     Set the volume (intensity) of the 
speech\n"
+           "                               (between -100 and +100, default: 0) 
\n"
+          "-o, --output-module    -     Set the output module\n"
+          "-l, --language         -     Set the language (iso code)\n"
+          "-t, --voice-type       -     Set the prefered voice type\n"
+           "                               (male1, male2, male3, female1, 
female2\n"
+          "                                female3, child_male, 
child_female)\n"
+          "-m, --punctuation-mode -     Set the punctuation mode (none, some, 
all) \n"
+          "-s, --spelling         -     Spell the message\n"
+           "-x, --ssml             -     Set SSML mode on (default: off)\n"
+           "\n"
+           "-e, --pipe-mode        -     Pipe from stdin to stdout plus Speech 
Dispatcher\n"
+           "-P, --priority         -     Set priority of the message 
(important, message,\n"
+           "                                text, notification, progress; 
default: text)\n"
+           "-N, --application-name -     Set the application name used to 
estabilish\n"
+           "                                the connection to specified string 
value\n"
+           "                                (default: spd-say)\n"
+           "-n, --connection-name  -     Set the connection name used to 
estabilish\n"
+           "                                the connection to specified string 
value\n"
+          "                                (default: main)\n"
+           "\n"
+          "-w, --wait             -     Wait till the message is spoken or 
discarded\n"
+           "-S, --stop             -     Stop speaking the message being 
spoken\n"
+           "                                in Speech Dispatcher\n"
+           "-C, --cancel           -     Cancel all messages in Speech 
Dispatcher\n"
+           "\n"
+          "-v, --version          -     Print version and copyright info\n"
+          "-h, --help             -     Print this info\n"
+           "\n"
+          "Copyright (C) 2003 Brailcom, o.p.s.\n"
+          "This is free software; you can redistribute it and/or modify it\n"
+          "under the terms of the GNU General Public License as published by\n"
+          "the Free Software Foundation; either version 2, or (at your 
option)\n"
+          "any later version. Please see COPYING for more details.\n\n"
+          "Please report bugs to <speechd at bugs.freebsoft.org>\n\n"
+          );
+    
+}
+
+void
+options_print_version()
+{
+    printf("spd-say: "PACKAGE" "VERSION"\n");
+    printf("Copyright (C) 2002-2006 Brailcom, o.p.s.\n"
+           "spd-say comes with ABSOLUTELY NO WARRANTY.\n"
+           "You may redistribute copies of spd-say\n"
+           "under the terms of the GNU General Public License.\n"
+           "For more information about these matters, see the file named 
COPYING.\n"
+           );
+}
+
+#define OPT_SET_INT(param) \
+    val = strtol(optarg, &tail_ptr, 10); \
+    if(tail_ptr != optarg){ \
+        param = val; \
+    }else{ \
+        printf("Syntax error or bad parameter!\n"); \
+        options_print_help(argv); \
+        exit(1); \
+    }
+
+#define OPT_SET_STR(param) \
+    if(optarg != NULL){ \
+        param = (char*) strdup(optarg); \
+    }else{ \
+        printf("Missing argument!\n"); \
+        options_print_help(argv); \
+        exit(1); \
+    }
+
+int
+options_parse(int argc, char *argv[])
+{
+    char* tail_ptr;
+    int c_opt;
+    int option_index;
+    int val;
+
+    assert (argc>0);
+    assert(argv);
+
+    while(1){
+        option_index = 0;
+    
+        c_opt = getopt_long(argc, argv, short_options, long_options,
+                            &option_index);
+        if (c_opt == -1) break;
+        switch(c_opt){
+        case 'r':
+            OPT_SET_INT(rate);
+            break;
+        case 'p':
+            OPT_SET_INT(pitch);
+            break;
+        case 'i':
+            OPT_SET_INT(volume);
+            break;
+        case 'l':
+            OPT_SET_STR(language);
+            break;
+        case 'o':
+            OPT_SET_STR(output_module);
+            break;
+        case 't':
+            OPT_SET_STR(voice_type);
+            break;
+        case 'm':
+            OPT_SET_STR(punctuation_mode);
+            break;
+       case 's':
+           spelling = 1;
+           break;
+        case 'e':
+            pipe_mode = 1;
+            break;
+       case 'P':
+           OPT_SET_STR(priority);
+           break;
+        case 'x':
+            ssml_mode = 1;
+            break;
+       case 'N':
+           OPT_SET_STR(application_name);
+           break;
+       case 'n':
+           OPT_SET_STR(connection_name);
+           break;
+       case 'w':
+           wait_till_end = 1;
+           break;
+       case 'S':
+           stop_previous = 1;
+           break;
+       case 'C':
+           cancel_previous = 1;
+           break;
+        case 'v':
+            options_print_version(argv);
+            exit(0);
+            break;
+        case 'h':
+            options_print_help(argv);
+            exit(0);
+            break;
+        default:
+            printf("Unrecognized option\n");
+            options_print_help(argv);
+            exit(1);
+        }
+    }
+    return 0;
+}
+#undef SPD_OPTION_SET_INT
diff --git a/src/clients/say/options.h b/src/clients/say/options.h
new file mode 100644
index 0000000..d9e6b4e
--- /dev/null
+++ b/src/clients/say/options.h
@@ -0,0 +1,71 @@
+/*
+ * options.h - Defines possible command line options
+ *
+ * Copyright (C) 2003 Brailcom, o.p.s.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this package; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $Id: options.h,v 1.10 2006-07-11 16:12:27 hanke Exp $
+ */
+
+#include <getopt.h>
+
+signed int rate;
+signed int pitch;
+signed int volume;
+
+char *output_module;
+char *language;
+char *voice_type;
+char *punctuation_mode;
+char *priority;
+int pipe_mode;
+int ssml_mode;
+int spelling;
+int wait_till_end;
+int stop_previous;
+int cancel_previous;
+
+char *application_name;
+char *connection_name;
+
+static struct option long_options[] = {
+    {"rate", 1, 0, 'r'},
+    {"pitch", 1, 0, 'p'},
+    {"volume", 1, 0, 'i'},
+    {"output-module", 1, 0, 'o'},
+    {"language", 1, 0, 'l'},
+    {"voice-type", 1, 0, 't'},
+    {"punctuation-mode", 1, 0, 'm'},
+    {"spelling", 0, 0, 's'},
+    {"ssml", 0, 0, 'x'},
+    {"pipe-mode", 0, 0, 'e'},
+    {"priority", 1, 0, 'P'},
+    {"application-name", 1, 0, 'N'},
+    {"connection-name", 1, 0, 'n'},
+    {"wait", 0, 0, 'w'},
+    {"stop", 1, 0, 'S'},
+    {"cancel", 1, 0, 'C'},
+    {"version", 0, 0, 'v'},
+    {"help", 0, 0, 'h'},
+    {0, 0, 0, 0}
+};
+
+static char* short_options = "r:p:i:l:o:t:m:sxeP:N:n:wSCvh";
+
+int options_parse(int argc, char *argv[]);
+void options_print_version();
+void options_print_help(char *argv[]);
diff --git a/src/clients/say/say.c b/src/clients/say/say.c
new file mode 100644
index 0000000..50670c7
--- /dev/null
+++ b/src/clients/say/say.c
@@ -0,0 +1,244 @@
+
+/*
+ * say.c - Super-simple Speech Dispatcher client
+ *
+ * Copyright (C) 2001, 2002, 2003, 2007 Brailcom, o.p.s.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this package; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $Id: say.c,v 1.16 2007-05-03 09:43:12 hanke Exp $
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <getopt.h>
+#include "libspeechd.h"
+#include "options.h"
+
+
+#define MAX_LINELEN 16384
+
+sem_t semaphore;
+
+/* Callback for Speech Dispatcher notifications */
+void end_of_speech(size_t msg_id, size_t client_id, SPDNotificationType type)
+{
+    sem_post(&semaphore);
+}
+
+int main(int argc, char **argv) {
+    SPDConnection *conn;
+    SPDPriority spd_priority;
+    int err;
+    char *error;
+    int msg_arg_required = 0;
+    int ret;
+    int option_ret;
+    char *line;
+
+    rate = -101;
+    pitch = -101;
+    volume = -101;
+    language = NULL;
+    voice_type = NULL;
+    punctuation_mode = NULL;
+    spelling = -2;
+    ssml_mode = 0;
+    wait_till_end = 0;
+    stop_previous = 0;
+    cancel_previous = 0;
+    pipe_mode = 0;
+    priority = NULL;
+    application_name = NULL;
+    connection_name = NULL;
+
+    option_ret = options_parse(argc, argv);
+
+    /* Check if the text to say or options are specified in the argument */
+    msg_arg_required = (pipe_mode != 1) && (stop_previous != 1)
+                       && (cancel_previous != 1);
+    if ((optind >= argc) && msg_arg_required) {
+        options_print_help(argv);
+        return 1;
+    }
+
+    /* Open a connection to Speech Dispatcher */
+    conn = spd_open2(application_name ? application_name : "spd-say",
+                    connection_name ? connection_name : "main",
+                    NULL, SPD_MODE_THREADED, NULL, 1, &error);
+    if (conn == NULL){
+      fprintf(stderr, "Failed to connect to Speech Dispatcher:\n%s\n", error);
+      exit(1);
+    }
+
+    if (stop_previous) spd_stop_all(conn);
+    if (cancel_previous) spd_cancel_all(conn);
+
+    /* Set the desired parameters */
+
+    if (language != NULL)
+        if(spd_set_language(conn, language))
+            printf("Invalid language!\n");
+
+    if (output_module != NULL)
+        if(spd_set_output_module(conn, output_module))
+            printf("Invalid output module!\n");
+
+    if (voice_type != NULL){
+        if (!strcmp(voice_type, "male1")){
+            if(spd_set_voice_type(conn, SPD_MALE1))
+                printf("Can't set this voice!\n");
+        }
+        else if(!strcmp(voice_type, "male2")){
+            if(spd_set_voice_type(conn, SPD_MALE2))
+                printf("Can't set this voice!\n");
+        }
+        else if(!strcmp(voice_type, "male3")){
+            if(spd_set_voice_type(conn, SPD_MALE3))
+            printf("Can't set this voice!\n");
+        }
+        else if(!strcmp(voice_type, "female1")){
+            if(spd_set_voice_type(conn, SPD_FEMALE1))
+                printf("Can't set this voice!\n");
+        }
+        else if(!strcmp(voice_type, "female2")){
+            if(spd_set_voice_type(conn, SPD_FEMALE2))
+                printf("Can't set this voice!\n");
+        }
+        else if(!strcmp(voice_type, "female3")){
+            if(spd_set_voice_type(conn, SPD_FEMALE3))
+                printf("Can't set this voice!\n");
+        }
+        else if(!strcmp(voice_type, "child_male")){
+            if(spd_set_voice_type(conn, SPD_CHILD_MALE))
+                printf("Can't set this voice!\n");
+        }
+        else if(!strcmp(voice_type, "child_female")){
+            if(spd_set_voice_type(conn, SPD_CHILD_FEMALE))
+                printf("Can't set this voice!\n");
+        }else{
+            printf("Invalid voice\n");
+        }
+    }
+
+    if (ssml_mode)
+        if(spd_execute_command(conn, "SET SELF SSML_MODE ON"))
+            printf("Failed to set SSML mode.\n");
+
+    if (rate != -101)
+        if(spd_set_voice_rate(conn, rate))
+            printf("Invalid rate!\n");
+
+    if (pitch != -101)
+        if(spd_set_voice_pitch(conn, pitch))
+            printf("Invalid pitch!\n");
+
+    if (volume != -101)
+        if(spd_set_volume(conn, volume))
+            printf("Invalid volume!\n");
+
+    if (spelling == 1)
+        if(spd_set_spelling(conn, SPD_SPELL_ON))
+            printf("Can't set spelling to on!\n");
+
+    if (punctuation_mode != NULL){
+        if (!strcmp(punctuation_mode, "none")){
+            if(spd_set_punctuation(conn, SPD_PUNCT_NONE))
+                printf("Can't set this punctuation mode!\n");
+        }
+        else if(!strcmp(punctuation_mode, "some")){
+            if(spd_set_punctuation(conn, SPD_PUNCT_SOME))
+                printf("Can't set this punctuation mode!\n");
+        }
+        else if(!strcmp(punctuation_mode, "all")){
+            if(spd_set_punctuation(conn, SPD_PUNCT_ALL))
+                printf("Can't set this punctuation mode!\n");
+        }else{
+            printf("Invalid punctuation mode.\n");
+        }
+    }
+
+    /* Set default priority... */
+    if (1 == pipe_mode)
+        spd_priority = SPD_MESSAGE;
+    else
+        spd_priority = SPD_TEXT;
+    /* ...and look if it wasn't overriden */
+    if (priority != NULL){
+        if (!strcmp(priority, "important")) spd_priority = SPD_IMPORTANT;
+        else if (!strcmp(priority, "message")) spd_priority = SPD_MESSAGE;
+        else if (!strcmp(priority, "text")) spd_priority = SPD_TEXT;
+        else if (!strcmp(priority, "notification")) spd_priority = 
SPD_NOTIFICATION;
+        else if (!strcmp(priority, "progress")) spd_priority = SPD_PROGRESS;
+        else{
+            printf("Invalid priority.\n");
+        }
+    }
+
+    if (wait_till_end){
+        ret = sem_init(&semaphore, 0, 0);
+        if (ret < 0){
+            fprintf(stderr, "Can't initialize semaphore: %s", strerror(errno));
+            return 0;
+        }
+
+        /* Notify when the message is canceled or the speech terminates */
+        conn->callback_end = end_of_speech;
+        conn->callback_cancel = end_of_speech;
+        spd_set_notification_on(conn, SPD_END);
+        spd_set_notification_on(conn, SPD_CANCEL);
+    }
+
+    /* In pipe mode, read from stdin, write to stdout, and also to Speech 
Dispatcher. */
+    if (pipe_mode == 1) {
+        line = (char *) malloc( MAX_LINELEN );
+        while (NULL != fgets(line, MAX_LINELEN, stdin)) {
+            fputs(line, stdout);
+            if (0 == strncmp(line, "!-!", 3)) {
+                /* Remove EOL */
+                line[strlen(line)-1] = 0;
+                spd_execute_command(conn, line + 3);
+            } else {
+                spd_say(conn, spd_priority, line);
+                if (wait_till_end) sem_wait(&semaphore);
+            }
+        }
+        free(line);
+
+    } else {
+        /* Say the message with priority "text" */
+        /* Or do nothing in case of -C or -S with no message. */
+        if (optind < argc) {
+         err = spd_sayf(conn, spd_priority, (char*) argv[optind]);
+         if (err == -1){
+           fprintf(stderr, "Speech Dispatcher failed to say message");
+           exit(1);
+         }
+
+          /* Wait till the callback is called */
+          if (wait_till_end) sem_wait(&semaphore);
+        }
+    }
+
+    /* Close the connection */
+    spd_close(conn);
+
+    return 0;
+}
diff --git a/src/clients/spdsend/ChangeLog b/src/clients/spdsend/ChangeLog
new file mode 100644
index 0000000..f58cc8f
--- /dev/null
+++ b/src/clients/spdsend/ChangeLog
@@ -0,0 +1,11 @@
+2008-02-01  Hynek Hanke  <hanke at mach>
+
+       * server.c (serve): Correct type for client_address_len.
+
+2006-07-25  root  <hanke at brailcom.org>
+
+       * README: speechd
+
+2004-09-08  Milan Zamazal  <pdm at brailcom.org>
+
+       * server.c (do_send_data): Close the connection on error.
diff --git a/src/clients/spdsend/Makefile.am b/src/clients/spdsend/Makefile.am
new file mode 100644
index 0000000..0dc9eee
--- /dev/null
+++ b/src/clients/spdsend/Makefile.am
@@ -0,0 +1,5 @@
+
+bin_PROGRAMS = spdsend
+spdsend_SOURCES = spdsend.h spdsend.c server.c client.c common.c 
+spdsend_LDADD = -lpthread @EXTRA_SOCKET_LIBS@
+
diff --git a/src/clients/spdsend/README b/src/clients/spdsend/README
new file mode 100644
index 0000000..8d0a95f
--- /dev/null
+++ b/src/clients/spdsend/README
@@ -0,0 +1,26 @@
+This is a simple command line client to Speech Dispatcher.  It may be useful in
+programs, which don't want to use direct socket communication with Speech
+Dispatcher for some reason.
+
+To compile the program, just run `make'.  To install it, run `make install'.
+
+The following operations are supported:
+
+$ spdsend --open HOST PORT
+
+  Open new connection to Speech Dispatcher running at HOST:PORT and print the
+  connection identifier on the standard output.
+
+$ spdsend --close CONNECTION
+
+  Close the given Speech Dispatcher CONNECTION.
+
+$ spdsend --send CONNECTION
+
+  Read an SSIP command from standard input, forward it to Speech Dispatcher
+  CONNECTION and print the answer on the standard output.
+
+You can send your bug reports, patches, suggestions, etc. to the mailing list
+speechd at lists.freebsoft.org.
+
+-- Milan Zamazal <pdm at freebsoft.org>
diff --git a/src/clients/spdsend/client.c b/src/clients/spdsend/client.c
new file mode 100644
index 0000000..232ab79
--- /dev/null
+++ b/src/clients/spdsend/client.c
@@ -0,0 +1,109 @@
+/* client.c -- Client part of spdsend
+   Author: Milan Zamazal <pdm at brailcom.org>
+*/
+
+/* Copyright (C) 2004 Brailcom, o.p.s.
+
+   COPYRIGHT NOTICE
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2, or (at your option) any later
+   version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
+*/
+
+
+#include "spdsend.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+
+static Success send_header (Stream s, Action action, Connection_Id id)
+{
+  if (write_data (s, &action, sizeof (Action)) == OK &&
+      write_data (s, &id, sizeof (Connection_Id)) == OK)
+    return OK;
+  else
+    return ERROR;
+}
+
+#define SEND_HEADER(action)                      \
+  if (send_header (s, action, id) == ERROR) \
+    return ERROR
+
+static Success send_open_header (Stream s, const char *host, int port)
+{
+  int hostlen = strlen (host);
+  Action action = A_OPEN;
+  
+  if (write_data (s, &action, sizeof (Action)) == OK &&
+      write_data (s, &port, sizeof (int)) == OK &&
+      write_data (s, &hostlen, sizeof (int)) == OK &&
+      write_data (s, host, hostlen) == OK)
+    return OK;
+  else
+    return ERROR;
+}
+
+
+static Connection_Id read_reply (Stream s)
+{
+  Result result;
+  Connection_Id id;
+  
+  if (read_data (s, &result, sizeof (Result)) != sizeof (Result))
+    return NONE;
+  if (result != OK_CODE)
+    return NONE;
+  
+  if (read_data (s, &id, sizeof (Connection_Id)) != sizeof (Connection_Id))
+    return NONE;
+  
+  return id;
+}
+
+
+/* External functions */
+
+
+extern Success open_connection (Stream s, const char *host, int port)
+{
+  if (send_open_header (s, host, port) == ERROR)
+    return ERROR;
+  {
+    Connection_Id id = read_reply (s);
+    if (id == NONE)
+      return ERROR;
+    printf ("%d\n", id);
+  }
+  return OK;
+}
+
+extern Success close_connection (Stream s, Connection_Id id)
+{
+  SEND_HEADER (A_CLOSE);
+  return (read_reply (s) == OK ? OK : ERROR);
+}
+
+extern Success send_command (Stream s, Connection_Id id)
+{
+  SEND_HEADER (A_DATA);
+  if (read_reply (s) == NONE)
+    return ERROR;
+  if (forward_data (0, s, TRUE) == OK &&
+      forward_data (s, 1, FALSE) == OK)
+    return OK;
+  else
+    return ERROR;
+}
diff --git a/src/clients/spdsend/common.c b/src/clients/spdsend/common.c
new file mode 100644
index 0000000..aab7543
--- /dev/null
+++ b/src/clients/spdsend/common.c
@@ -0,0 +1,87 @@
+/* common.c -- Common parts of the client and the server
+   Author: Milan Zamazal <pdm at brailcom.org>
+*/
+
+/* Copyright (C) 2004 Brailcom, o.p.s.
+
+   COPYRIGHT NOTICE
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2, or (at your option) any later
+   version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
+*/
+
+
+#include <limits.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "spdsend.h"
+
+
+const long CONNECTION_ID_MIN = 1;
+const long CONNECTION_ID_MAX = 1000;
+
+const int EXIT_OK = 0;
+const int EXIT_ERROR = 1;
+
+
+extern Success write_data (Stream s, const void *buffer, size_t size)
+{
+  int written;
+
+  for ( ; size > 0; size -= written, buffer += written)
+    {
+      written = write (s, buffer, size);
+      if (written < 0)
+        return ERROR;
+    }
+  
+  return OK;
+}
+
+extern int read_data (Stream s, void *buffer, size_t max_size)
+{
+  size_t nread = 0, n;
+
+  while (nread < max_size)
+    {
+      n = read (s, buffer, max_size);
+      if (n < 0)
+        return NONE;
+      if (n == 0)
+        break;
+      nread += n;
+      buffer += n;
+      max_size -= n;
+    }
+  
+  return nread;
+}
+
+extern Success forward_data (Stream from, Stream to, bool closep)
+{    
+  const size_t buffer_size = 4096;
+  char buffer[buffer_size];
+  ssize_t n;
+
+  while ((n = read (from, buffer, buffer_size)) > 0)
+    {
+      if (write_data (to, buffer, n) == ERROR)
+        return ERROR;
+    }
+  if (closep)
+    shutdown (to, SHUT_WR);
+  
+  return (n == NONE ? ERROR : OK);
+}
diff --git a/src/clients/spdsend/server.c b/src/clients/spdsend/server.c
new file mode 100644
index 0000000..1b45f01
--- /dev/null
+++ b/src/clients/spdsend/server.c
@@ -0,0 +1,487 @@
+/* server.c -- Server part of spdsend
+   Author: Milan Zamazal <pdm at brailcom.org>
+*/
+
+/* Copyright (C) 2004 Brailcom, o.p.s.
+
+   COPYRIGHT NOTICE
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2, or (at your option) any later
+   version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
+*/
+
+
+#include "spdsend.h"
+
+#ifndef USE_THREADS
+#define USE_THREADS 1
+#endif
+
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#if USE_THREADS
+#include <pthread.h>
+#endif
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#if !(defined(__GLIBC__) && defined(_GNU_SOURCE))
+/* Added by Willie Walker - TEMP_FAILURE_RETRY, strndup, and getline
+ * are gcc-isms
+ */
+ssize_t getline (char **lineptr, size_t *n, FILE *f);
+#endif
+
+/* Utilities */
+
+
+static void system_error (const char *message)
+{
+  perror (message);
+  exit (1);
+}
+
+
+/* Connection management */
+
+
+Stream *connections;
+#if USE_THREADS
+pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+
+static Stream get_connection (Connection_Id id)
+{
+  return connections[id];
+}
+
+static void set_connection (Connection_Id id, Stream s)
+{
+#if USE_THREADS
+  pthread_mutex_lock (&connections_mutex);
+#endif
+  connections[id] = s;
+#if USE_THREADS
+  pthread_mutex_unlock (&connections_mutex);
+#endif
+}
+
+static Connection_Id new_connection (Stream s)
+{
+#if USE_THREADS
+  pthread_mutex_lock (&connections_mutex);
+#endif
+  int id;
+  for (id = CONNECTION_ID_MIN;
+       id < CONNECTION_ID_MAX && connections[id] != NONE;
+       id++)
+    ;
+  if (id >= CONNECTION_ID_MAX)
+    return NONE;
+  connections[id] = s;
+#if USE_THREADS
+  pthread_mutex_unlock (&connections_mutex);
+#endif
+  return id;
+}
+
+static Connection_Id do_open_connection (const char *host, int port)
+{
+  int sock = socket (AF_INET, SOCK_STREAM, 0);
+  
+  {
+    struct sockaddr_in name;
+    name.sin_family = AF_INET;
+    name.sin_port = htons (port);
+    {
+      struct hostent *hostinfo;
+      hostinfo = gethostbyname (host);
+      if (hostinfo == NULL)
+        return NONE;
+      name.sin_addr = *(struct in_addr *) hostinfo->h_addr;
+    }
+    if (connect (sock, (struct sockaddr *)&name, sizeof (name)) < 0)
+      return NONE;
+    {
+      int arg = 1;
+      setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &arg, sizeof(int));
+    }
+  }
+  
+  {
+    Connection_Id id = new_connection (sock);
+    if (id == NONE)
+      close (sock);
+    return id;
+  }
+}
+
+static Success do_close_connection (Connection_Id id)
+{
+  Stream c = get_connection (id);
+  if (c == NONE)
+    return ERROR;
+  close (c);
+  set_connection (id, NONE);
+  return OK;
+}
+
+static Success do_send_data (Connection_Id id, Stream from, Stream to,
+                             Success (*forwarder) (Stream, Stream, bool))
+{
+  int sock = get_connection (id);
+  if (sock == NONE)
+    return ERROR;
+  if (from == NONE)
+    from = sock;
+  else if (to == NONE)
+    to = sock;
+  {
+    Success result = ((*forwarder) (from, to, FALSE));
+    if (result != OK)
+      do_close_connection (id);
+    return result;
+  }
+}
+
+
+/* Processing requests */
+
+/* Protocol:
+
+   Client request:
+     First comes the action code, of the type Action.
+     If Action is A_OPEN, the following data follows:
+       int port, int strlen(hostname), hostname
+     Else:
+       Connection_Id
+     Then, if Action is A_DATA, the SSIP lines follow.
+     
+   Server answer:
+     The result code, of the type Result.
+     If Result is OK, Connection_Id follows.
+     Additionally, if Action is A_DATA, SSIP reply follows.
+*/
+
+static Success report (Stream s, Result code)
+{
+  return write_data (s, &code, sizeof (Result));
+}
+
+static Success report_ok (Stream s, Connection_Id id)
+{
+  if (report (s, OK_CODE) == OK &&
+      write_data (s, &id, sizeof (Connection_Id)) == OK)
+    return OK;
+  else
+    return ERROR;
+}
+
+static Success report_error (Stream s)
+{
+  return report (s, ER_CODE);
+}
+
+
+static Connection_Id read_id (Stream s)
+{
+  Connection_Id id;
+  if (read_data (s, &id, sizeof (Connection_Id)) == ERROR)
+    return NONE;
+  return id;
+}
+
+
+static Success forward_ssip_answer (Stream from, Stream to, bool _closep)
+{
+  int result = OK;
+  FILE *f = fdopen (from, "r");
+  size_t line_size = 256;
+  char *line = malloc (line_size);
+  if (line == NULL)
+    system_error ("memory allocation");
+
+  while (1)
+    {
+      int n = getline (&line, &line_size, f);
+      if (n < 0 || write_data (to, line, n) == ERROR)
+        {
+          result = ERROR;
+          break;
+        }
+      if (n > 3 && line[3] == ' ')
+        break;
+    }
+
+  free (line);
+  return result;
+}
+
+
+static void process_open (Stream s)
+{
+  Connection_Id id;
+  int port;
+  int hostlen;
+  
+  if (read_data (s, &port, sizeof (int)) != sizeof (int))
+    {
+      report_error (s);
+      return;
+    }
+  if (read_data (s, &hostlen, sizeof (int)) != sizeof (int))
+    {
+      report_error (s);
+      return;
+    }
+  {
+    char *host = malloc (hostlen+1);
+    if (host == NULL)
+      system_error ("memory allocation");
+    if (read_data (s, host, hostlen) != hostlen)
+      {
+        free (host);
+        report_error (s);
+        return;
+      }
+    host[hostlen] = '\0';
+    id = do_open_connection (host, port);
+    free (host);
+  }
+
+  if (id == NONE)
+    report_error (s);
+  else
+    report_ok (s, id);
+}
+
+static void process_close (Stream s)
+{
+  Connection_Id id = read_id (s);
+  if (id != NONE && do_close_connection (id) == OK)
+    report_ok (s, id);
+  else
+    report_error (s);
+}
+
+static void process_data (Stream s)
+{
+  Connection_Id id = read_id (s);
+  if (id != NONE)
+    report_ok (s, id);
+  else
+    report_error (s);
+
+  if (do_send_data (id, s, NONE, forward_data) == OK)
+    do_send_data (id, NONE, s, forward_ssip_answer);
+}
+
+
+static void process_request (Stream s)
+{
+  Action action;
+
+  if (read_data (s, &action, sizeof (Action)) == NONE)
+    return;
+  
+  if (action == A_OPEN)
+    process_open (s);
+  else if (action == A_CLOSE)
+    process_close (s);
+  else if (action == A_DATA)
+    process_data (s);
+  else
+    report_error (s);
+  
+  close (s);
+}
+
+#if USE_THREADS
+static void *process_request_thread (void *s)
+{
+  Stream s_deref = *((Stream *) s);
+  free (s);
+  pthread_detach (pthread_self ());
+  process_request (s_deref);
+  return NULL;
+}
+#endif
+
+
+/* Starting the server */
+
+
+static const char *login_name ()
+{
+  return getpwuid (getuid ()) -> pw_name;
+}
+
+static const char *server_socket_name ()
+{
+  char *name;
+  if (asprintf (&name, "/tmp/spdsend-server.%s", login_name ()) < 0)
+    system_error ("memory allocation");
+  return name;
+}
+
+static void serve ()
+{
+  struct sockaddr_un name;
+  int sock;
+  size_t size;
+  const char *filename = server_socket_name ();
+     
+  sock = socket (PF_LOCAL, SOCK_STREAM, 0);
+  if (sock < 0)
+    system_error ("socket creation");
+  
+  name.sun_family = AF_LOCAL;
+  strncpy (name.sun_path, filename, sizeof (name.sun_path));
+  name.sun_path[sizeof (name.sun_path) - 1] = '\0';
+  size = (offsetof (struct sockaddr_un, sun_path)
+          + strlen (name.sun_path) + 1);
+  if (bind (sock, (struct sockaddr *) &name, size) < 0)
+    system_error ("bind");
+  if (listen (sock, LISTEN_QUEUE_LENGTH) < 0)
+    system_error ("listen");
+  
+  while (1)
+    {
+      struct sockaddr_un client_address;
+      socklen_t client_address_len = sizeof (client_address);
+      Stream *s = malloc (sizeof (Stream));
+      if (s == NULL)
+        system_error ("memory allocation");
+      *s = accept (sock, (struct sockaddr *)&client_address,
+                   &client_address_len);
+      if (*s < 0)
+        break;
+      {
+#if USE_THREADS
+        pthread_t tid;
+#endif
+#if USE_THREADS
+        pthread_create (&tid, NULL, &process_request_thread, s);
+#else
+        process_request (*s);
+#endif
+      }
+    }
+}
+
+static void daemonize ()
+{
+  int ret = 0;
+  if (fork () != 0)
+    exit (0);
+  setsid ();
+  signal (SIGHUP, SIG_IGN);
+  if (fork () != 0)
+    exit (0);
+  if ((ret = chdir ("/")) != 0)
+    fputs("server.c:daemonize: could not chdir", stderr);
+    exit (1);
+  umask (0);
+  {
+    int i;
+    for (i = 0; i < 4; i++)
+      close (i);
+  }
+}
+
+static void init_connections ()
+{
+  connections = malloc (CONNECTION_ID_MAX * sizeof (Connection_Id));
+  if (connections == NULL)
+    system_error ("memory allocation");
+  {
+    int i;
+    for (i = CONNECTION_ID_MIN; i < CONNECTION_ID_MAX; i++)
+      connections[i] = NONE;
+  }
+#if USE_THREADS
+  pthread_mutex_init (&connections_mutex, NULL);
+#endif
+}
+
+static void start_server ()
+{
+  const char *socket_name = server_socket_name ();
+  unlink (socket_name);
+  
+  {
+    int pid = fork ();
+    if (pid == -1)
+      system_error ("fork");
+
+    if (pid == 0)
+      {
+        daemonize ();
+        init_connections ();
+        serve ();
+        unlink (socket_name);
+        exit (0);
+      }
+    else
+      sleep (1);
+  }
+}
+
+static int connect_server ()
+{    
+  struct sockaddr_un name;
+  int sock = socket (AF_LOCAL, SOCK_STREAM, 0);
+  int name_size;
+  name.sun_family = AF_LOCAL;
+  strncpy (name.sun_path, server_socket_name (), sizeof (name.sun_path));
+  name.sun_path[sizeof (name.sun_path) - 1] = '\0';
+  name_size = (offsetof (struct sockaddr_un, sun_path)
+               + strlen (name.sun_path) + 1);
+     
+  if (connect (sock, (struct sockaddr *)&name, name_size) < 0)
+    return NONE;
+  else
+    return sock;
+}
+
+
+/* External functions */
+
+
+Stream open_server ()
+{
+  Stream s;
+
+  s = connect_server ();
+  if (s == NONE)
+    {
+      start_server ();
+      s = connect_server ();
+    }
+  if (s == NONE)
+    return NONE;
+
+  return s;
+}
+
diff --git a/src/clients/spdsend/spdsend.c b/src/clients/spdsend/spdsend.c
new file mode 100644
index 0000000..708096a
--- /dev/null
+++ b/src/clients/spdsend/spdsend.c
@@ -0,0 +1,155 @@
+/* spdsend.c -- Send SSIP commands to Speech Dispatcher
+   Author: Milan Zamazal <pdm at brailcom.org>
+*/
+
+/* Copyright (C) 2004 Brailcom, o.p.s.
+
+   COPYRIGHT NOTICE
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2, or (at your option) any later
+   version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
+*/
+
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "spdsend.h"
+
+
+const char *const VERSION = "0.0.0";
+
+#if !(defined(__GLIBC__) && defined(_GNU_SOURCE))
+/* Added by Willie Walker - getline is a gcc-ism */
+#define BUFFER_LEN 256
+ssize_t getline (char **lineptr, size_t *n, FILE *f)
+{
+        char ch;
+        size_t m = 0;
+        ssize_t buf_len = 0;
+        char * buf = NULL;
+        char * p = NULL;
+
+       if (errno != 0) {
+               errno = 0;
+       }
+        while ( (ch = getc(f)) !=EOF )
+        {
+                if (errno != 0)
+                        return -1;
+                if ( m++ >= buf_len )
+                {
+                        buf_len += BUFFER_LEN;
+                        buf = (char *) realloc(buf, buf_len + 1);
+                        if ( buf == NULL )
+                        {
+                                return -1;
+                        }
+                        p = buf + buf_len - BUFFER_LEN;
+                }
+                *p = ch;
+                p++;
+                if ( ch == '\n' )
+                        break;
+        }
+        if ( m == 0 )
+        {
+                return -1;
+        } else {
+                *p = '\0';
+                *lineptr = buf;
+                *n = m;
+                return m;
+        }
+}
+#endif /* !(defined(__GLIBC__) && defined(_GNU_SOURCE)) */
+
+static void usage (const char *const message)
+{
+  if (message != NULL)
+    fprintf (stderr, "spdsend: %s\n", message);
+  fprintf (stderr,
+           "usage: spdsend { --open SERVER PORT | --close ID | --send ID }\n");
+  exit (EXIT_ERROR);
+}
+
+
+static long string_to_number (const char *string,
+                              long low_limit, long high_limit)
+{
+  char *tailptr;
+  errno = 0;
+  long int number = strtol (string, &tailptr, 0);
+  if (errno || *tailptr || number < low_limit || number > high_limit)
+    usage ("Invalid parameter");
+  return number;
+}
+
+
+int main (int argc, char **argv)
+{
+  if (argc < 2)
+    usage ("Invalid number of arguments");
+
+  {    
+    const char *const action = argv[1];    
+    Success (*function) (Stream, Connection_Id);
+    Connection_Id conn_id;
+    char *host;
+    int port;
+
+    if (! strcmp (action, "--version"))
+      {
+        printf ("spdsend %s\n", VERSION);
+        exit (EXIT_OK);
+      }
+    
+    const int action_is_open = strcmp (action, "--open") == 0;
+    if (action_is_open)
+      {
+        if (argc != 4)
+          usage ("Invalid number of arguments");
+        host = argv[2];
+        port = string_to_number (argv[3], 0, 65535);
+      }
+    else
+      {
+        if (argc != 3)
+          usage ("Invalid number of arguments");
+        conn_id = string_to_number (argv[2], CONNECTION_ID_MIN,
+                                    CONNECTION_ID_MAX);
+        if (! strcmp (action, "--close"))
+          function = close_connection;
+        else if (! strcmp (action, "--send"))
+          function = send_command;
+        else
+          usage ("Invalid option");
+      }
+    
+    {
+      Stream server = open_server ();
+      if (server == NONE)
+        return EXIT_ERROR;
+      
+      {
+        int result = (action_is_open
+                      ? open_connection (server, host, port)
+                      : function (server, conn_id));
+        return (result == OK ? EXIT_OK : EXIT_ERROR);
+      }
+    }
+  }
+}
diff --git a/src/clients/spdsend/spdsend.h b/src/clients/spdsend/spdsend.h
new file mode 100644
index 0000000..8794eb7
--- /dev/null
+++ b/src/clients/spdsend/spdsend.h
@@ -0,0 +1,76 @@
+/* Declarations for spdsend
+   Author: Milan Zamazal <pdm at brailcom.org>
+*/
+
+/* Copyright (C) 2004 Brailcom, o.p.s.
+
+   COPYRIGHT NOTICE
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the Free
+   Software Foundation, version 2 of the License.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
+*/
+
+
+#ifndef __SPDSEND_H
+
+#define __SPDSEND_H
+
+
+#define _GNU_SOURCE
+
+#include <stddef.h>
+
+
+/* Configuration */
+
+#ifndef LISTEN_QUEUE_LENGTH
+#define LISTEN_QUEUE_LENGTH 100
+#endif
+
+/* Types */
+
+typedef enum { FALSE, TRUE } bool;
+typedef int Stream;
+typedef int Connection_Id;
+
+typedef enum { OK, ERROR } Success;
+#define NONE -1
+
+/* common.c */
+
+extern Success write_data (Stream s, const void *buffer, size_t size);
+extern int read_data (Stream s, void *buffer, size_t max_size);
+extern Success forward_data (Stream from, Stream to, bool closep);
+
+typedef enum { A_OPEN, A_CLOSE, A_DATA } Action;
+
+typedef enum { OK_CODE, ER_CODE } Result;
+
+extern const long CONNECTION_ID_MIN;
+extern const long CONNECTION_ID_MAX;
+
+extern const int EXIT_OK;
+extern const int EXIT_ERROR;
+
+/* server.c */
+
+extern Stream open_server ();
+
+/* client.c */
+
+extern Success open_connection (Stream server, const char *host, int port);
+extern Success close_connection (Stream server, Connection_Id id);
+extern Success send_command (Stream server, Connection_Id id);
+
+
+#endif
-- 
1.7.2.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]