[med-svn] [Git][med-team/libarb][upstream] 2 commits: New upstream version 6.0.6

Andreas Tille gitlab at salsa.debian.org
Fri Jun 7 11:03:41 BST 2019



Andreas Tille pushed to branch upstream at Debian Med / libarb


Commits:
dd8562c5 by Andreas Tille at 2019-06-07T09:46:45Z
New upstream version 6.0.6
- - - - -
8f7aae39 by Andreas Tille at 2019-06-07T10:01:42Z
New upstream version 6.0.6
- - - - -


18 changed files:

- + AISC_COM/AISC/Makefile
- + AISC_COM/C/Makefile
- + AISC_COM/C/aisc_extern.c
- + AISC_COM/C/aisc_extern_privat.h
- + AISC_COM/C/aisc_func_types.h
- + AISC_COM/C/aisc_global.h
- + AISC_COM/C/aisc_server.h
- + AISC_COM/C/client.c
- + AISC_COM/C/client.h
- + AISC_COM/C/client_privat.h
- + AISC_COM/C/client_types.h
- + AISC_COM/C/common.c
- + AISC_COM/C/common.h
- + AISC_COM/C/server.c
- + AISC_COM/C/server.h
- + AISC_COM/C/struct_man.c
- + AISC_COM/C/struct_man.h
- + AISC_COM/C/trace.h


Changes:

=====================================
AISC_COM/AISC/Makefile
=====================================
@@ -0,0 +1,179 @@
+THIS=AISC/Makefile
+MAKETHIS=$(MAKE) -f $(THIS)
+#MAKETHIS=$(MAKE) -d -f $(THIS)
+SED:=$(ARBHOME)/SH/arb_sed
+READLINK:=$(ARBHOME)/SH/arb_readlink
+
+.SUFFIXES: .o .c .h .aisc
+
+#where to find the creator files
+AISC=../AISC/aisc
+AISC_MKPT = ../AISC_MKPTPS/aisc_mkpt
+
+RUN_AISC:=$(AISC)
+# valgrinding like this breaks the build process (due to wrong exitcode)
+#RUN_AISC:=arb_valgrind -c 15 $(AISC)
+#RUN_AISC:=arb_valgrind -c 15 -l $(AISC)
+#RUN_AISC:=arb_valgrind -c 15 -l -r $(AISC)
+
+GEN_INCLUDES = GENH/aisc.h GENH/aisc_com.h
+INCLUDE_INCLUDES = aisc_include.header
+
+SERVER_OBJECTS = O/server.o O/struct_man.o O/aisc_extern.o
+
+GEN_SERVER_PROTO_OBJECTS = GENC/aisc_server.o
+GEN_SERVER_OTHER_OBJECTS = GENC/aisc_global.o
+GEN_SERVER_OBJECTS = $(GEN_SERVER_PROTO_OBJECTS) $(GEN_SERVER_OTHER_OBJECTS)
+
+GEN_SERVER_PROTO_SOURCES = $(GEN_SERVER_PROTO_OBJECTS:.o=.c)
+GEN_SERVER_SOURCES = $(GEN_SERVER_OBJECTS:.o=.c)
+
+GEN_SERVER_INCLUDES = C/aisc_server.h C/common.h
+GEN_SERVER_PROTO = GENH/aisc_server_proto.h
+GEN_SERVER_EXTERN_PROTO = GENH/aisc_server_extern.h
+
+SERVER_INCLUDES = $(GEN_INCLUDES) $(GEN_SERVER_INCLUDES) $(GEN_SERVER_PROTO) $(GEN_SERVER_EXTERN_PROTO)
+
+CLIENT_OBJECTS = O/client.o 
+CLIENT_INCLUDES = $(GEN_INCLUDES) C/client_privat.h C/client.h C/common.h
+
+COMMON_OBJECTS = O/common.o
+COMMON_INCLUDES = C/common.h
+
+AISC_EXTERNALS = C/aisc_extern.c $(PRIVATE_SERVER_OBJECTS:.o=.c)
+GLOBALS_AISC = GENH/global.aisc
+
+AISC_DEPENDS = AISC/*.pa $(MAIN_SOURCE) $(AISC) $(DUMPDIR) $(GLOBALS_AISC)
+
+IMPORT_PROTO = GENH/import_proto.h
+
+SERVER = server.a
+CLIENT = client.a
+COMMON = common.a
+
+AISC_SERVER_EXTERN = GENH/aisc_server_extern.aisc
+
+DUMPDIR=DUMP
+
+LINK_TO_OTHER_ARB=~/ARB.aisc_regression_test_vs# create this as symlink to other ARB checkout to activate regression test 
+FAIL_ON_CHANGE=1# 0=continue on change, 1=fail on change
+
+# ----------------------------------------
+
+COMPARE_WITH_OTHER_ARB:=$(shell $(READLINK) $(LINK_TO_OTHER_ARB))
+ifneq ($(COMPARE_WITH_OTHER_ARB),)
+THIS__COMDIR=$(shell pwd)
+COMDIRNAME=$(subst $(ARBHOME),,$(THIS__COMDIR))
+OTHER_COMDIR=$(subst //,/,$(COMPARE_WITH_OTHER_ARB)/$(COMDIRNAME))
+ifeq ($(FAIL_ON_CHANGE),0)
+REGR_FAILURE=(echo "$(THIS):57: Warning: regression on generated code (ignored)" || true)
+else
+REGR_FAILURE=(	echo "$(THIS):59: Error: regression on generated AISC code"; \
+		rm $(SERVER) $(CLIENT) $(COMMON); \
+		false) 
+endif
+endif
+
+# ----------------------------------------
+
+ifeq ($(AUTODEPENDS),1)
+all:
+	+test -f .depends || $(MAKETHIS) "AUTODEPENDS=0" .depends
+	+$(MAKETHIS) "AUTODEPENDS=2" all
+else
+all: directories
+	+$(MAKETHIS) realall
+
+endif
+
+realall: $(CLIENT) $(SERVER) $(COMMON) Makefile $(THIS)
+ifeq ($(COMPARE_WITH_OTHER_ARB),)
+	@echo "AISC regression tests are disabled ($(LINK_TO_OTHER_ARB) not found from AISC_COM/$(THIS))"
+else
+ ifeq ($(THIS__COMDIR),$(OTHER_COMDIR))
+	@echo "$(THIS):63: Warning: Skipping AISC regression tests (test versus self always ok)"
+ else
+	@echo "Running AISC regression tests (versus $(COMPARE_WITH_OTHER_ARB))"
+#       compare generated code using ../../SOURCE_TOOLS/check_dirs_equal.sh
+	@( \
+		../SOURCE_TOOLS/check_dirs_equal.sh $(THIS__COMDIR)/GENC $(OTHER_COMDIR)/GENC '*.c' && \
+		../SOURCE_TOOLS/check_dirs_equal.sh $(THIS__COMDIR)/GENH $(OTHER_COMDIR)/GENH '*.h' && \
+		../SOURCE_TOOLS/check_dirs_equal.sh $(THIS__COMDIR)/DUMP $(OTHER_COMDIR)/DUMP '*.dump' && \
+		echo "No change in generated code" \
+	) || $(REGR_FAILURE)
+ endif
+endif
+
+pregenerate: $(GEN_SERVER_SOURCES) $(SERVER_INCLUDES) $(CLIENT_INCLUDES) $(AISC_EXTERNALS)
+
+directories:
+	@mkdir -p GENH GENC O DUMP
+
+GENH:	directories
+GENC:	directories
+O:	directories
+DUMP:	directories
+
+$(SERVER): $(SERVER_OBJECTS) $(GEN_SERVER_OBJECTS) $(PRIVATE_SERVER_OBJECTS)
+	$(LINK_STATIC_LIB) $@ $^
+
+$(CLIENT): $(CLIENT_OBJECTS) $(GEN_CLIENT_OBJECTS)
+	$(LINK_STATIC_LIB) $@ $^
+
+$(COMMON): $(COMMON_OBJECTS)
+	$(LINK_STATIC_LIB) $@ $^ 
+
+$(GEN_SERVER_OBJECTS) $(PRIVATE_SERVER_OBJECTS): $(SERVER_INCLUDES) $(GEN_SERVER_SOURCES) $(PRIVATE_SERVER_OBJECTS:.o=.c)
+	$(COMPILER) -c -o $@ $(@:.o=.c) -IGENH -I. -IC -DAISC_SAVE_$(AISC_SAVE) $(POST_COMPILE)
+
+O/%.o: C/%.c $(GEN_INCLUDES) $(CLIENT_INCLUDES) C/server.h
+	$(COMPILER) -c -o $@ $< -IGENH -I. -IC $(POST_COMPILE)
+
+$(CLIENT_OBJECTS): $(CLIENT_OBJECTS:O/%.o=C/%.c) $(GEN_INCLUDES) $(CLIENT_INCLUDES)
+	$(CLIENTCOMPILER) -c -o $@ C/$(@F:.o=.c) -IGENH -I. -IC $(POST_COMPILE)
+
+$(DUMPDIR): 
+	mkdir -p $(DUMPDIR)
+
+$(GLOBALS_AISC).tmp: 
+	@echo "AISC_SAVE $(AISC_SAVE);" > $@
+
+$(GLOBALS_AISC): $(GLOBALS_AISC).tmp
+	$(ARBHOME)/SOURCE_TOOLS/mv_if_diff $(GLOBALS_AISC).tmp $(GLOBALS_AISC)
+
+GENH/%.h: AISC/%.pa $(AISC_DEPENDS) $(INCLUDE_INCLUDES) 
+	$(RUN_AISC) $< $(MAIN_SOURCE) $@
+
+GENC/%.c: AISC/%.pa $(AISC_DEPENDS) $(AISC_SERVER_EXTERN) $(GEN_SERVER_INCLUDES)
+	$(RUN_AISC) $< $(MAIN_SOURCE) $@ $(AISC_SERVER_EXTERN) $(IMPORT_PROTO) $(GLOBALS_AISC)
+
+$(IMPORT_PROTO): $(GEN_SERVER_PROTO_SOURCES)
+	echo $@
+
+$(AISC_SERVER_EXTERN): $(AISC_EXTERNALS) $(AISC_MKPT) $(THIS) 
+	rm -f $(AISC_SERVER_EXTERN)
+	$(AISC_MKPT) -a $(AISC_EXTERNALS) >$@
+
+$(GEN_SERVER_EXTERN_PROTO): $(AISC_EXTERNALS) $(AISC_MKPT) $(THIS)
+	rm -f $(GEN_SERVER_EXTERN_PROTO)
+	$(AISC_MKPT) -w $(subst GENH/,,$@) $(AISC_EXTERNALS) >$@
+
+$(GEN_SERVER_PROTO): $(GEN_SERVER_PROTO_SOURCES) $(AISC_MKPT) $(THIS)
+	rm -f $@
+	$(AISC_MKPT) -w $(subst GENH/,,$@) $(GEN_SERVER_PROTO_SOURCES) >$@
+
+clean:
+	@rm -f *.[ao] */*.[ao]
+	@rm -rf GENH GENC DUMP O
+	@rm -f .depends
+
+.depends:
+	$(MAKEDEPEND) $(MAKEDEPENDFLAGS) C/*.c GENC/*.c -I GENH -I C -f- -w1 2>/dev/null \
+		| grep -v ' /usr' \
+		| $(SED) -e 's/^C/O/ig' \
+		> .depends_new
+	$(ARBHOME)/SOURCE_TOOLS/mv_if_diff .depends_new .depends
+
+ifeq ($(AUTODEPENDS),2)
+include .depends
+endif


=====================================
AISC_COM/C/Makefile
=====================================
@@ -0,0 +1,41 @@
+
+all:
+	echo "Available targets: proto"
+
+GENERATED_HEADERS= \
+	aisc_extern_privat.h \
+	client.h \
+	common.h \
+	server.h \
+	struct_man.h \
+
+AISC_MKPT_FLAGS=-P -G
+MKPT_DEP=../../AISC_MKPTPS/aisc_mkpt Makefile
+
+proto:
+	$(MAKE) $(GENERATED_HEADERS)
+
+clean:
+	rm $(GENERATED_HEADERS)
+
+aisc_extern_privat.h: aisc_extern.c $(MKPT_DEP)  
+	$(ARBHOME)/AISC_MKPTPS/aisc_mkpt $(AISC_MKPT_FLAGS) -w $@ $< >$@.tmp
+	$(ARBHOME)/SOURCE_TOOLS/mv_if_diff $@.tmp $@
+
+client.h: client.c $(MKPT_DEP)
+	$(ARBHOME)/AISC_MKPTPS/aisc_mkpt $(AISC_MKPT_FLAGS) -w $@ $< >$@.tmp
+	$(ARBHOME)/SOURCE_TOOLS/mv_if_diff $@.tmp $@
+
+common.h: common.c $(MKPT_DEP)
+	$(ARBHOME)/AISC_MKPTPS/aisc_mkpt $(AISC_MKPT_FLAGS) -w $@ $< >$@.tmp
+	$(ARBHOME)/SOURCE_TOOLS/mv_if_diff $@.tmp $@
+
+struct_man.h: struct_man.c $(MKPT_DEP)
+	$(ARBHOME)/AISC_MKPTPS/aisc_mkpt $(AISC_MKPT_FLAGS) -w $@ $< >$@.tmp
+	$(ARBHOME)/SOURCE_TOOLS/mv_if_diff $@.tmp $@
+
+server.h: server.c $(MKPT_DEP)
+	$(ARBHOME)/AISC_MKPTPS/aisc_mkpt $(AISC_MKPT_FLAGS) -w $@ $< >$@.tmp
+	$(ARBHOME)/SOURCE_TOOLS/mv_if_diff $@.tmp $@
+
+


=====================================
AISC_COM/C/aisc_extern.c
=====================================
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <string.h>
+#include <aisc.h>
+#include <server.h>
+#include "aisc_extern_privat.h"
+
+extern int aisc_d_flags[];
+
+dll_public *create_dll_public() {
+    return 0;
+}
+
+int move_dll_header(const dll_header *sobj, dll_header *dobj) {
+    dobj->ident = strdup(sobj->ident);
+    return 0;
+}
+
+int get_COMMON_CNT(dll_header *THIS) {
+    int key = (int)(THIS->key) >> 16;
+    if (aisc_d_flags[key] == 0) return -1;
+    if (!((THIS->parent))) { return 0; }
+    return THIS->parent->cnt;
+}
+
+dllheader_ext *get_COMMON_PARENT(dll_header *THIS) {
+    int key = (int)(THIS->key) >> 16;
+    if (aisc_d_flags[key] == 0) return 0;
+    if (!THIS->parent) { return 0; }
+    return THIS->parent->parent;
+}
+
+dllheader_ext *get_COMMON_LAST(dll_header *THIS) {
+    int key = (int)(THIS->key) >> 16;
+    if (aisc_d_flags[key] == 0) return 0;
+    if (!THIS->parent) { return 0; }
+    return THIS->parent->last;
+}
+
+aisc_cstring aisc_get_keystring(int *obj) {
+    int i;
+    i = *obj>>16;
+    return aisc_get_object_names(i);
+}
+
+aisc_cstring aisc_get_keystring_dll_header(dll_header *x) {
+    return aisc_get_keystring((int*)x);
+}


=====================================
AISC_COM/C/aisc_extern_privat.h
=====================================
@@ -0,0 +1,25 @@
+/* This file is generated by aisc_mkpt.
+ * Any changes you make here will be overwritten later!
+ */
+
+#ifndef AISC_EXTERN_PRIVAT_H
+#define AISC_EXTERN_PRIVAT_H
+
+/* define ARB attributes: */
+#ifndef ATTRIBUTES_H
+# include <attributes.h>
+#endif
+
+
+/* aisc_extern.c */
+dll_public *create_dll_public(void);
+int move_dll_header(const dll_header *sobj, dll_header *dobj);
+int get_COMMON_CNT(dll_header *THIS);
+dllheader_ext *get_COMMON_PARENT(dll_header *THIS);
+dllheader_ext *get_COMMON_LAST(dll_header *THIS);
+aisc_cstring aisc_get_keystring(int *obj);
+aisc_cstring aisc_get_keystring_dll_header(dll_header *x);
+
+#else
+#error aisc_extern_privat.h included twice
+#endif /* AISC_EXTERN_PRIVAT_H */


=====================================
AISC_COM/C/aisc_func_types.h
=====================================
@@ -0,0 +1,30 @@
+// =============================================================== //
+//                                                                 //
+//   File      : aisc_func_types.h                                 //
+//   Purpose   :                                                   //
+//                                                                 //
+//   Coded by Ralf Westram (coder at reallysoft.de) in 2000           //
+//   Institute of Microbiology (Technical University Munich)       //
+//   http://www.arb-home.de/                                       //
+//                                                                 //
+// =============================================================== //
+
+#ifndef AISC_FUNC_TYPES_H
+#define AISC_FUNC_TYPES_H
+
+struct sigcontext;
+struct Hs_struct;
+
+#define aisc_talking_func_proto_void(func_name)     void func_name(long arg1, ...)
+#define aisc_talking_func_proto_long(func_name)     long func_name(long arg1, ...)
+#define aisc_talking_func_proto_longp(func_name)    long* func_name(long arg1, ...)
+#define aisc_talking_func_proto_double(func_name)   double func_name(long arg1, ...)
+
+typedef aisc_talking_func_proto_void((*aisc_destroy_callback));
+typedef aisc_talking_func_proto_long((*aisc_talking_func_long));
+typedef aisc_talking_func_proto_longp((*aisc_talking_func_longp));
+typedef aisc_talking_func_proto_double((*aisc_talking_func_double));
+
+#else
+#error aisc_func_types.h included twice
+#endif // AISC_FUNC_TYPES_H


=====================================
AISC_COM/C/aisc_global.h
=====================================
@@ -0,0 +1,78 @@
+// =============================================================== //
+//                                                                 //
+//   File      : aisc_global.h                                     //
+//   Purpose   :                                                   //
+//                                                                 //
+//   Coded by Ralf Westram (coder at reallysoft.de) in May 2007       //
+//   Institute of Microbiology (Technical University Munich)       //
+//   http://www.arb-home.de/                                       //
+//                                                                 //
+// =============================================================== //
+#ifndef AISC_GLOBAL_H
+#define AISC_GLOBAL_H
+
+#ifndef BYTESTRING_H
+#include <bytestring.h>
+#endif
+#ifndef ARBTOOLS_H
+#include <arbtools.h>
+#endif
+#ifndef ATTRIBUTES_H
+#include <attributes.h>
+#endif
+#ifndef ARB_ASSERT_H
+#include <arb_assert.h>
+#endif
+
+#define aisc_assert(cond) arb_assert(cond)
+
+// type mask
+#define AISC_TYPE_NONE   0x00000000
+#define AISC_TYPE_INT    0x01000000
+#define AISC_TYPE_DOUBLE 0x02000000
+#define AISC_TYPE_STRING 0x03000000
+#define AISC_TYPE_COMMON 0x04000000
+#define AISC_TYPE_BYTES  0x05000000
+
+#define AISC_VAR_TYPE_MASK 0xff000000
+#define AISC_OBJ_TYPE_MASK 0x00ff0000
+#define AISC_ATTR_MASK     0x0000ffff
+
+#define AISC_INDEX       0x1ff0000
+#define AISC_NO_ANSWER  -0x7fffffff
+
+#define AISC_COMMON      0
+
+union double_xfer { // workaround aliasing problems
+    double as_double;
+    int    as_int[2];
+};
+
+class AISC_Object : public Noncopyable {
+    int  type_id;
+    long remote_ptr; // this is a pointer to client-data in server-address-space (casted to long)
+
+    void *operator&() { return 0; } // forbid error-prone idiom (AISC_Object just was 'long' in the past). Instead use as_result_param()
+
+protected:
+
+    void set(int IF_ASSERTION_USED(remoteType), long remotePtr) { aisc_assert(remoteType == type_id); remote_ptr = remotePtr; }
+
+public:
+    AISC_Object(int type_) : type_id(type_), remote_ptr(0) {}
+
+    bool exists() const { return remote_ptr; }
+    long get() const { return remote_ptr; }
+    int type() const { return type_id; }
+
+    void clear() { remote_ptr = 0; }
+    void init(long remotePtr) { aisc_assert(!exists()); set(type_id, remotePtr); }
+
+    long *as_result_param() { return &remote_ptr; }
+
+};
+
+#else
+#error aisc_global.h included twice
+#endif // AISC_GLOBAL_H
+


=====================================
AISC_COM/C/aisc_server.h
=====================================
@@ -0,0 +1,25 @@
+// --------------------------------------------------------------------------------
+// start ../../AISC_COM/C/aisc_server.h
+//
+// [Note: This header isn't included directly, it's merged into generated code by AISC]
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <dupstr.h>
+#include <aisc.h>
+#include <aisc_com.h>
+
+#ifndef ATTRIBUTES_H
+#include <attributes.h>
+#endif
+#include <server.h>
+#include <aisc_server_proto.h>
+#include <aisc_server_extern.h>
+#include <import_proto.h>
+
+#include <struct_man.h>
+
+// end ../../AISC_COM/C/aisc_server.h
+// --------------------------------------------------------------------------------


=====================================
AISC_COM/C/client.c
=====================================
@@ -0,0 +1,677 @@
+// ===============================================================
+/*                                                                 */
+//   File      : client.c
+//   Purpose   :
+/*                                                                 */
+//   Institute of Microbiology (Technical University Munich)
+//   http://www.arb-home.de/
+/*                                                                 */
+// ===============================================================
+
+#include <netdb.h>
+#include <netinet/tcp.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+
+#include <unistd.h>
+#include <cstdarg>
+
+#include <arb_cs.h>
+
+#include "client_privat.h"
+#include "client.h"
+#include "common.h"
+
+#include "trace.h"
+
+#define aisc_assert(cond) arb_assert(cond)
+
+// AISC_MKPT_PROMOTE:#include <client_types.h>
+
+#define AISC_MAGIC_NUMBER_FILTER 0xffffff00
+
+static const char *err_connection_problems = "CONNECTION PROBLEMS";
+
+int aisc_core_on_error = 1;
+
+#define CORE()                                                  \
+    do {                                                        \
+        if (aisc_core_on_error) {                               \
+            ARB_SIGSEGV(true);                                  \
+        }                                                       \
+    } while (0)
+
+aisc_com *aisc_client_link;
+
+static int aisc_print_error_to_stderr = 1;
+static char errbuf[300];
+
+#define PRTERR(msg) if (aisc_print_error_to_stderr) fprintf(stderr, "%s: %s\n", msg, link->error);
+
+
+static int aisc_c_read(int socket, char *ptr, long size) {
+    long leftsize = size;
+    while (leftsize) {
+        long readsize = read(socket, ptr, (size_t)leftsize);
+        if (readsize<=0) return 0;
+        ptr += readsize;
+        leftsize -= readsize;
+    }
+    return size;
+}
+
+static int aisc_c_write(int socket, const char *ptr, int size) {
+    int leftsize = size;
+    while (leftsize) {
+        int writesize = write(socket, ptr, leftsize);
+        if (writesize<=0) return 0;
+        ptr += writesize;
+        leftsize -= writesize;
+    }
+    return size;
+}
+
+// -----------------------------
+//      bytestring handling
+
+
+static void aisc_c_add_to_bytes_queue(aisc_com *link, char *data, int size)
+{
+    aisc_bytes_list *bl = (aisc_bytes_list *)calloc(sizeof(*bl), 1);
+#ifndef NDEBUG
+    memset(bl, 0, sizeof(*bl)); // @@@ clear mem needed to avoid (rui's)
+#endif
+    bl->data = data;
+    bl->size = size;
+
+    if (link->aisc_client_bytes_first) {
+        link->aisc_client_bytes_last->next = bl;
+        link->aisc_client_bytes_last = bl;
+    }
+    else {
+        link->aisc_client_bytes_first = bl;
+        link->aisc_client_bytes_last = bl;
+    }
+}
+
+static int aisc_c_send_bytes_queue(aisc_com *link) {
+    int len;
+    aisc_bytes_list *bl, *bl_next;
+    for (bl = link->aisc_client_bytes_first; bl; bl=bl_next) {
+        bl_next = bl->next;
+        len = aisc_c_write(link->socket, bl->data, bl->size);
+        free(bl);
+        if (len<0)return 1;
+    };
+    link->aisc_client_bytes_first = link->aisc_client_bytes_last = NULL;
+    return 0;
+}
+
+// --------------------------
+//      message handling
+
+struct client_msg_queue {
+    client_msg_queue *next;
+    int               message_type;
+    char             *message;
+};
+
+static int aisc_add_message_queue(aisc_com *link, long size)
+{
+    client_msg_queue *msg    = (client_msg_queue *) calloc(sizeof(client_msg_queue), 1);
+    char             *buffer = (char *)calloc(sizeof(char), (size_t)size);
+    long              len    = aisc_c_read(link->socket, buffer, size);
+
+    if (len != size) {
+        link->error = err_connection_problems;
+        PRTERR("AISC_ERROR");
+        return 1;
+    }
+    msg->message = strdup(buffer+sizeof(long));
+    msg->message_type = (int)*(long *)buffer;
+    free(buffer);
+
+    if (link->message_queue == 0) {
+        link->message_queue = (int *)msg;
+    }
+    else {
+        client_msg_queue *mp;
+        for (mp = (client_msg_queue *)link->message_queue; mp->next; mp=mp->next) ;
+        mp->next = msg;
+    }
+    return 0;
+}
+
+static int aisc_check_error(aisc_com * link)
+{
+    int         len;
+    long        magic_number;
+    long        size;
+
+ aisc_check_next :
+
+    link->error = 0; // @@@ avoid (rui)
+    len = aisc_c_read(link->socket, (char *)(link->aisc_mes_buffer), 2*sizeof(long));
+    if (len != 2*sizeof(long)) {
+        link->error = err_connection_problems;
+        PRTERR("AISC_ERROR");
+        return 1;
+    }
+    if (link->aisc_mes_buffer[0] >= AISC_MESSAGE_BUFFER_LEN) {
+        link->error = err_connection_problems;
+        PRTERR("AISC_ERROR");
+        return 1;
+    }
+    magic_number = link->aisc_mes_buffer[1];
+    if ((unsigned long)(magic_number & AISC_MAGIC_NUMBER_FILTER) != (unsigned long)(link->magic & AISC_MAGIC_NUMBER_FILTER)) {
+        link->error = err_connection_problems;
+        PRTERR("AISC_ERROR");
+        return 1;
+    }
+    size = link->aisc_mes_buffer[0];
+    if (size) {
+        if (magic_number-link->magic == AISC_CCOM_MESSAGE) {
+            if (aisc_add_message_queue(link, size*sizeof(long))) return 1;
+            goto aisc_check_next;
+
+        }
+        len = aisc_c_read(link->socket, (char *)(link->aisc_mes_buffer), size * sizeof(long));
+        if (len != (long)(size*sizeof(long))) {
+            link->error = err_connection_problems;
+            PRTERR("AISC_ERROR");
+            return 1;
+        }
+        switch (magic_number-link->magic) {
+            case AISC_CCOM_OK:
+                return 0;
+            case AISC_CCOM_ERROR:
+                sprintf(errbuf, "SERVER_ERROR: %s", (char *)(link->aisc_mes_buffer));
+                link->error = errbuf;
+                PRTERR("AISC_ERROR");
+                return 1;
+            default:
+                return 0;
+        }
+    }
+    return 0;
+}
+
+
+
+static long aisc_init_client(aisc_com *link)
+{
+    int len, mes_cnt;
+    mes_cnt = 2;
+    link->aisc_mes_buffer[0] = mes_cnt-2;
+    link->aisc_mes_buffer[1] = AISC_INIT+link->magic;
+    len = aisc_c_write(link->socket, (const char *)link->aisc_mes_buffer, mes_cnt * sizeof(long));
+    if (!len) {
+        link->error = err_connection_problems;
+        PRTERR("AISC_CONN_ERROR");
+        return 0;
+    }
+    aisc_check_error(link);
+    return link->aisc_mes_buffer[0];
+}
+
+static void ignore_sigpipe(int) {
+}
+
+static void aisc_free_link(aisc_com *link) {
+    if (link->old_sigpipe_handler != SIG_ERR) { // failed to install -> do not uninstall
+        UNINSTALL_SIGHANDLER(SIGPIPE, ignore_sigpipe, link->old_sigpipe_handler, "aisc_free_link");
+    }
+    free(link);
+}
+
+aisc_com *aisc_open(const char *path, AISC_Object& main_obj, long magic, GB_ERROR *error) {
+    aisc_com   *link;
+    const char *err;
+
+    aisc_assert(error && !*error);
+    aisc_assert(!main_obj.exists()); // already initialized
+
+    link = (aisc_com *) calloc(sizeof(aisc_com), 1);
+    link->aisc_client_bytes_first = link->aisc_client_bytes_last = NULL;
+    link->magic = magic;
+    {
+        static char *unix_name = 0;
+        err = aisc_client_open_socket(path, TCP_NODELAY, 1, &link->socket, &unix_name);
+        freenull(unix_name);
+    }
+    if (err) {
+        if (*err) {
+            link->error = err;
+            PRTERR("ARB_DB_CLIENT_OPEN");
+        }
+        if (link->socket) {
+            shutdown(link->socket, SHUT_RDWR);
+            close(link->socket);
+        }
+        *error = link->error;
+        free(link);
+        aisc_assert(!(*error && main_obj.exists()));
+        return 0;
+    }
+
+    link->old_sigpipe_handler = INSTALL_SIGHANDLER(SIGPIPE, ignore_sigpipe, "aisc_open");
+
+    main_obj.init(aisc_init_client(link));
+    if (!main_obj.exists() || link->error) {
+        *error = link->error;
+        main_obj.clear();
+        aisc_free_link(link);
+        aisc_assert(!(*error && main_obj.exists()));
+        return 0;
+    }
+    aisc_client_link = link;
+    aisc_assert(!*error);
+    return link;
+}
+
+int aisc_close(aisc_com *link, AISC_Object& object) {
+    if (link) {
+        if (link->socket) {
+            link->aisc_mes_buffer[0] = 0;
+            link->aisc_mes_buffer[1] = 0;
+            link->aisc_mes_buffer[2] = 0;
+            aisc_c_write(link->socket, (const char *)link->aisc_mes_buffer, 3 * sizeof(long));
+            shutdown(link->socket, SHUT_RDWR);
+            close(link->socket);
+            link->socket = 0;
+        }
+        aisc_free_link(link);
+    }
+    object.clear();
+    return 0;
+}
+
+int aisc_get(aisc_com *link, int o_type, const AISC_Object& object, ...)
+{
+    // goes to header: __ATTR__SENTINEL
+    long    *arg_pntr[MAX_AISC_SET_GET];
+    long     arg_types[MAX_AISC_SET_GET];
+    long     mes_cnt;
+    long     arg_cnt;
+    va_list  parg;
+    long     type, o_t;
+    long     attribute, code;
+    long     count;
+    long     i, len;
+    long     size;
+
+    AISC_DUMP_SEP();
+
+    mes_cnt = 2;
+    arg_cnt = 0;
+    count   = 4;
+
+    link->aisc_mes_buffer[mes_cnt++] = object.get();
+    aisc_assert(object.type() == o_type);
+
+    va_start(parg, object);
+    while ((code=va_arg(parg, long))) {
+        attribute       = code & AISC_ATTR_MASK;
+        type            = code & AISC_VAR_TYPE_MASK;
+        o_t             = code & AISC_OBJ_TYPE_MASK;
+
+        if ((o_t != (int)o_type)) {
+            sprintf(errbuf, "ARG NR %li DON'T FIT OBJECT", count);
+            link->error = errbuf;
+            PRTERR("AISC_GET_ERROR");
+            CORE();
+            return      1;
+        };
+
+        if ((attribute > AISC_MAX_ATTR)) {
+            sprintf(errbuf, "ARG %li IS NOT AN ATTRIBUTE_TYPE", count);
+            link->error = errbuf;
+            PRTERR("AISC_GET_ERROR");
+            CORE();
+            return      1;
+        };
+        link->aisc_mes_buffer[mes_cnt++] = code;
+        arg_pntr[arg_cnt] = va_arg(parg, long *);
+        arg_types[arg_cnt++] = type;
+        count += 2;
+        if (arg_cnt>=MAX_AISC_SET_GET) {
+            sprintf(errbuf, "TOO MANY ARGS (>%i)", MAX_AISC_SET_GET);
+            link->error = errbuf;
+            PRTERR("AISC_GET_ERROR");
+            CORE();
+            return      1;
+        }
+    }
+    va_end(parg);
+    if (mes_cnt > 3) {
+        link->aisc_mes_buffer[0] = mes_cnt - 2;
+        link->aisc_mes_buffer[1] = AISC_GET+link->magic;
+        len = aisc_c_write(link->socket, (const char *)(link->aisc_mes_buffer), (size_t)(mes_cnt * sizeof(long)));
+        if (!len) {
+            link->error = err_connection_problems;
+            PRTERR("AISC_GET_ERROR");
+            return 1;
+        }
+
+        if (aisc_check_error(link)) return 1;
+        mes_cnt = 0;
+        for (i=0; i<arg_cnt; i++) {
+            switch (arg_types[i]) {
+                case AISC_TYPE_INT:
+                case AISC_TYPE_COMMON:
+                    AISC_DUMP(aisc_get, int, link->aisc_mes_buffer[mes_cnt]);
+                    arg_pntr[i][0] = link->aisc_mes_buffer[mes_cnt++];
+                    break;
+                case AISC_TYPE_DOUBLE:
+                    AISC_DUMP(aisc_get, double, *(double*)(char*)/*avoid aliasing problems*/&(link->aisc_mes_buffer[mes_cnt]));
+                    ((int*)arg_pntr[i])[0] = (int)(link->aisc_mes_buffer[mes_cnt++]);
+                    ((int*)arg_pntr[i])[1] = (int)(link->aisc_mes_buffer[mes_cnt++]);
+                    break;
+                case AISC_TYPE_STRING: {
+                    char *str       = strdup((char *)(&(link->aisc_mes_buffer[mes_cnt+1])));
+                    AISC_DUMP(aisc_get, charPtr, str);
+                    arg_pntr[i][0]  = (long)str;
+                    mes_cnt        += link->aisc_mes_buffer[mes_cnt] + 1;
+                    break;
+                }
+                case AISC_TYPE_BYTES:
+                    size = arg_pntr[i][1] = link->aisc_mes_buffer[mes_cnt++];
+                    AISC_DUMP(aisc_get, int, size);
+                    if (size) {
+                        arg_pntr[i][0] = (long)calloc(sizeof(char), (size_t)size);
+                        len = aisc_c_read(link->socket, (char *)(arg_pntr[i][0]), size);
+                        if (size!=len) {
+                            link->error = err_connection_problems;
+                            PRTERR("AISC_GET_ERROR");
+                        }
+#if defined(DUMP_COMMUNICATION)
+                        aisc_dump_hex("aisc_get bytestring: ", (char *)(arg_pntr[i][0]), size);
+#endif // DUMP_COMMUNICATION
+                    }
+                    else {
+                        arg_pntr[i][0] = 0;
+                    }
+                    break;
+
+                default:
+                    link->error = "UNKNOWN TYPE";
+                    PRTERR("AISC_GET_ERROR");
+                    CORE();
+                    return 1;
+            }
+        }
+
+    }
+    return 0;
+}
+
+long *aisc_debug_info(aisc_com *link, int o_type, const AISC_Object& object, int attribute)
+{
+    int mes_cnt;
+    int o_t;
+    int len;
+
+    mes_cnt = 2;
+    o_t     = attribute & AISC_OBJ_TYPE_MASK;
+    if ((o_t != (int)o_type)) {
+        link->error = "ATTRIBUTE DON'T FIT OBJECT";
+        PRTERR("AISC_DEBUG_ERROR");
+        CORE();
+        return 0;
+    };
+    attribute = attribute&0xffff;
+    if ((attribute > AISC_MAX_ATTR)) {
+        link->error = "CLIENT DEBUG NOT CORRECT TYPE";
+        PRTERR("AISC_DEBUG_ERROR");
+        CORE();
+        return 0;
+    };
+    aisc_assert(object.type() == o_type);
+    link->aisc_mes_buffer[mes_cnt++] = object.get();
+    link->aisc_mes_buffer[mes_cnt++] = attribute;
+    link->aisc_mes_buffer[0] = mes_cnt - 2;
+    link->aisc_mes_buffer[1] = AISC_DEBUG_INFO+link->magic;
+    len = aisc_c_write(link->socket, (const char *)(link->aisc_mes_buffer), mes_cnt * sizeof(long));
+    if (!len) {
+        link->error = err_connection_problems;
+        PRTERR("AISC_GET_ERROR");
+        return 0;
+    }
+    if (aisc_check_error(link)) return 0;
+    return &(link->aisc_mes_buffer[0]);
+}
+
+
+inline char *part_of(const char *str, size_t max_len, size_t str_len) {
+    aisc_assert(strlen(str) == str_len);
+    char *part;
+    if (str_len <= max_len) {
+        part = strdup(str);
+    }
+    else {
+        const int DOTS = 3;
+        int       copy = max_len-DOTS;
+
+        part = (char*)malloc(max_len+1);
+        memcpy(part, str, copy);
+        memset(part+copy, '.', DOTS);
+        
+        part[max_len] = 0;
+    }
+    return part;
+}
+
+static int aisc_collect_sets(aisc_com *link, int mes_cnt, va_list parg, int o_type, int count) {
+    int type, o_t; // @@@ fix locals
+    int attribute, code;
+    int len, ilen;
+    char        *str;
+    int arg_cnt = 0;
+
+    AISC_DUMP_SEP();
+
+    while ((code=va_arg(parg, int))) {
+        attribute       = code & AISC_ATTR_MASK;
+        type            = code & AISC_VAR_TYPE_MASK;
+        o_t             = code & AISC_OBJ_TYPE_MASK;
+
+        if (code != AISC_INDEX) {
+            if ((o_t != (int)o_type)) {
+                sprintf(errbuf, "ATTRIBUTE ARG NR %i DON'T FIT OBJECT", count);
+                link->error = errbuf;
+                PRTERR("AISC_SET_ERROR");
+                CORE();
+                return 0;
+            }
+            if ((attribute > AISC_MAX_ATTR)) {
+                sprintf(errbuf, "ARG %i IS NOT AN ATTRIBUTE_TYPE", count);
+                link->error = errbuf;
+                PRTERR("AISC_SET_ERROR");
+                CORE();
+                return 0;
+            }
+        }
+        link->aisc_mes_buffer[mes_cnt++] = code;
+        switch (type) {
+            case AISC_TYPE_INT:
+            case AISC_TYPE_COMMON:
+                link->aisc_mes_buffer[mes_cnt++] = va_arg(parg, long);
+                AISC_DUMP(aisc_collect_sets, int, link->aisc_mes_buffer[mes_cnt-1]);
+                break;
+            case AISC_TYPE_DOUBLE: {
+                double_xfer darg;
+
+                darg.as_double = va_arg(parg, double);
+                AISC_DUMP(aisc_collect_sets, double, darg.as_double);
+
+                link->aisc_mes_buffer[mes_cnt++] = darg.as_int[0];
+                link->aisc_mes_buffer[mes_cnt++] = darg.as_int[1];
+                break;
+            }
+            case AISC_TYPE_STRING:
+                str = va_arg(parg, char *);
+                AISC_DUMP(aisc_collect_sets, charPtr, str);
+                len = strlen(str)+1;
+                if (len > AISC_MAX_STRING_LEN) {
+                    char *strpart = part_of(str, AISC_MAX_STRING_LEN-40, len-1);
+                    sprintf(errbuf, "ARG %i: STRING \'%s\' TOO LONG", count+2, strpart);
+                    free(strpart);
+
+                    link->error = errbuf;
+                    PRTERR("AISC_SET_ERROR");
+                    CORE();
+
+                    return 0;
+                }
+                ilen = (len)/sizeof(long) + 1;
+                link->aisc_mes_buffer[mes_cnt++] = ilen;
+                memcpy((char *)(&(link->aisc_mes_buffer[mes_cnt])), str, len);
+                mes_cnt += ilen;
+                break;
+
+            case AISC_TYPE_BYTES:
+                {
+                    bytestring *bs;
+                    bs = va_arg(parg, bytestring *);
+                    AISC_DUMP(aisc_collect_sets, int, bs->size);
+                    if (bs->data && bs->size) {
+                        aisc_c_add_to_bytes_queue(link, bs->data, bs->size);
+#if defined(DUMP_COMMUNICATION)
+                        aisc_dump_hex("aisc_collect_sets bytestring: ", bs->data, bs->size);
+#endif // DUMP_COMMUNICATION
+                    }
+                    link->aisc_mes_buffer[mes_cnt++] = bs->size;              // size
+                    break;
+                }
+            default:
+                link->error = "UNKNOWN TYPE";
+                PRTERR("AISC_SET_ERROR");
+                CORE();
+                return 0;
+        }
+
+        count += 2;
+        if ((arg_cnt++) >= MAX_AISC_SET_GET) {
+            sprintf(errbuf, "TOO MANY ARGS (>%i)", MAX_AISC_SET_GET);
+            link->error = errbuf;
+            PRTERR("AISC_SET_ERROR");
+            CORE();
+            return      0;
+        }
+    }
+    return mes_cnt;
+}
+
+ // @@@ DRY aisc_put vs aisc_nput
+ // @@@ the difference between aisc_put and aisc_nput is: aisc_put may return an error from server
+
+int aisc_put(aisc_com *link, int o_type, const AISC_Object& object, ...) { // goes to header: __ATTR__SENTINEL
+    aisc_assert(object.type() == o_type);
+
+    int mes_cnt = 2;
+    link->aisc_mes_buffer[mes_cnt++] = object.get();
+    link->aisc_mes_buffer[mes_cnt++] = o_type;
+
+    va_list parg;
+    va_start(parg, object);
+    if (!(mes_cnt = aisc_collect_sets(link, mes_cnt, parg, o_type, 4))) return 1;
+
+    if (mes_cnt > 3) {
+        link->aisc_mes_buffer[0] = mes_cnt - 2;
+        link->aisc_mes_buffer[1] = AISC_SET+link->magic;
+        int len = aisc_c_write(link->socket, (const char *)(link->aisc_mes_buffer), mes_cnt * sizeof(long));
+        if (!len) {
+            link->error = err_connection_problems;
+            PRTERR("AISC_SET_ERROR");
+            return 1;
+        }
+        if (aisc_c_send_bytes_queue(link)) return 1;
+        if (aisc_check_error(link)) return 1;
+    }
+    return 0;
+}
+
+int aisc_nput(aisc_com *link, int o_type, const AISC_Object& object, ...) { // goes to header: __ATTR__SENTINEL
+    aisc_assert(object.type() == o_type);
+    
+    int mes_cnt = 2;
+    link->aisc_mes_buffer[mes_cnt++] = object.get();
+    link->aisc_mes_buffer[mes_cnt++] = o_type;
+
+    va_list parg;
+    va_start(parg, object);
+    if (!(mes_cnt = aisc_collect_sets(link, mes_cnt, parg, o_type, 4))) {
+        return 1;
+    }
+
+    if (mes_cnt > 3) {
+        link->aisc_mes_buffer[0] = mes_cnt - 2;
+        link->aisc_mes_buffer[1] = AISC_NSET+link->magic;
+        int len = aisc_c_write(link->socket, (const char *)(link->aisc_mes_buffer), mes_cnt * sizeof(long));
+        if (!len) {
+            link->error = err_connection_problems;
+            PRTERR("AISC_SET_ERROR");
+            return 1;
+        }
+        if (aisc_c_send_bytes_queue(link)) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+int aisc_create(aisc_com *link, int father_type, const AISC_Object& father,
+                int attribute,  int object_type, AISC_Object& object, ...)
+{
+    // goes to header: __ATTR__SENTINEL
+    // arguments in '...' set elements of CREATED object (not of father)
+    int mes_cnt;
+    int len;
+    va_list parg;
+    mes_cnt = 2;
+    if ((father_type&0xff00ffff)) {
+        link->error = "FATHER_TYPE UNKNOWN";
+        PRTERR("AISC_CREATE_ERROR");
+        CORE();
+        return 1;
+    }
+    if ((object_type&0xff00ffff)) {
+        link->error = "OBJECT_TYPE UNKNOWN";
+        PRTERR("AISC_CREATE_ERROR");
+        CORE();
+        return 1;
+    }
+    aisc_assert(father.type() == father_type);
+    aisc_assert(object.type() == object_type);
+    link->aisc_mes_buffer[mes_cnt++] = father_type;
+    link->aisc_mes_buffer[mes_cnt++] = father.get();
+    link->aisc_mes_buffer[mes_cnt++] = attribute;
+    link->aisc_mes_buffer[mes_cnt++] = object_type;
+    if (father_type != (attribute & AISC_OBJ_TYPE_MASK)) {
+        link->error = "ATTRIBUTE TYPE DON'T FIT OBJECT";
+        PRTERR("AISC_CREATE_ERROR");
+        CORE();
+        return 1;
+    }
+    va_start(parg, object);
+    if (!(mes_cnt = aisc_collect_sets(link, mes_cnt, parg, object_type, 7))) return 1;
+    link->aisc_mes_buffer[0] = mes_cnt - 2;
+    link->aisc_mes_buffer[1] = AISC_CREATE+link->magic;
+    len = aisc_c_write(link->socket, (const char *)(link->aisc_mes_buffer), mes_cnt * sizeof(long));
+    if (!len) {
+        link->error = err_connection_problems;
+        PRTERR("AISC_CREATE_ERROR");
+        return 1;
+    }
+    if (aisc_c_send_bytes_queue(link)) return 1;
+    if (aisc_check_error(link)) return 1;
+    object.init(link->aisc_mes_buffer[0]);
+    return 0;
+}
+
+/* --------------------------------------------------------------------------------
+ * Note: it's not possible to define unit tests here - they won't execute
+ * Instead put your tests into ../../SERVERCNTRL/servercntrl.cxx at UNIT_TESTS
+ */
+
+


=====================================
AISC_COM/C/client.h
=====================================
@@ -0,0 +1,28 @@
+/* This file is generated by aisc_mkpt.
+ * Any changes you make here will be overwritten later!
+ */
+
+#ifndef CLIENT_H
+#define CLIENT_H
+
+/* define ARB attributes: */
+#ifndef ATTRIBUTES_H
+# include <attributes.h>
+#endif
+
+
+/* client.c */
+
+#include <client_types.h>
+
+aisc_com *aisc_open(const char *path, AISC_Object& main_obj, long magic, GB_ERROR *error);
+int aisc_close(aisc_com *link, AISC_Object& object);
+int aisc_get(aisc_com *link, int o_type, const AISC_Object& object, ...) __ATTR__SENTINEL;
+long *aisc_debug_info(aisc_com *link, int o_type, const AISC_Object& object, int attribute);
+int aisc_put(aisc_com *link, int o_type, const AISC_Object& object, ...) __ATTR__SENTINEL;
+int aisc_nput(aisc_com *link, int o_type, const AISC_Object& object, ...) __ATTR__SENTINEL;
+int aisc_create(aisc_com *link, int father_type, const AISC_Object& father, int attribute, int object_type, AISC_Object& object, ...) __ATTR__SENTINEL;
+
+#else
+#error client.h included twice
+#endif /* CLIENT_H */


=====================================
AISC_COM/C/client_privat.h
=====================================
@@ -0,0 +1,74 @@
+// =============================================================== //
+//                                                                 //
+//   File      : client_privat.h                                   //
+//   Purpose   :                                                   //
+//                                                                 //
+//   Institute of Microbiology (Technical University Munich)       //
+//   http://www.arb-home.de/                                       //
+//                                                                 //
+// =============================================================== //
+
+#ifndef CLIENT_PRIVAT_H
+#define CLIENT_PRIVAT_H
+
+#ifndef AISC_GLOBAL_H
+#include "aisc_global.h"
+#endif
+
+
+#ifndef ARB_ASSERT_H
+#include <arb_assert.h>
+#endif
+#ifndef SIGHANDLER_H
+#include <SigHandler.h>
+#endif
+
+#define AISC_MAX_ATTR           4095
+#define MAX_AISC_SET_GET        16
+#define AISC_MAX_STRING_LEN     1024
+#define AISC_MESSAGE_BUFFER_LEN ((AISC_MAX_STRING_LEN/4+3)*(16+2))
+
+struct aisc_bytes_list {
+    char            *data;
+    int              size;
+    aisc_bytes_list *next;
+};
+
+struct aisc_com {
+    int         socket;
+    int         message_type;
+    char       *message;
+    int        *message_queue;
+    long        magic;
+    const char *error;
+
+    long             aisc_mes_buffer[AISC_MESSAGE_BUFFER_LEN];
+    aisc_bytes_list *aisc_client_bytes_first;
+    aisc_bytes_list *aisc_client_bytes_last;
+    SigHandler       old_sigpipe_handler;
+};
+
+#define AISC_MAGIC_NUMBER 0
+
+enum aisc_command_list {
+    AISC_GET         = AISC_MAGIC_NUMBER + 0,
+    AISC_SET         = AISC_MAGIC_NUMBER + 1,
+    AISC_NSET        = AISC_MAGIC_NUMBER + 2,
+    AISC_CREATE      = AISC_MAGIC_NUMBER + 3,
+    AISC_FIND        = AISC_MAGIC_NUMBER + 4,
+    AISC_COPY        = AISC_MAGIC_NUMBER + 5,
+    AISC_DELETE      = AISC_MAGIC_NUMBER + 6,
+    AISC_INIT        = AISC_MAGIC_NUMBER + 7,
+    AISC_DEBUG_INFO  = AISC_MAGIC_NUMBER + 8,
+    AISC_FORK_SERVER = AISC_MAGIC_NUMBER + 9
+};
+
+enum aisc_client_command_list {
+    AISC_CCOM_OK      = AISC_MAGIC_NUMBER + 0,
+    AISC_CCOM_ERROR   = AISC_MAGIC_NUMBER + 1,
+    AISC_CCOM_MESSAGE = AISC_MAGIC_NUMBER + 2
+};
+
+#else
+#error client_privat.h included twice
+#endif // CLIENT_PRIVAT_H


=====================================
AISC_COM/C/client_types.h
=====================================
@@ -0,0 +1,28 @@
+// ============================================================== //
+//                                                                //
+//   File      : client_types.h                                   //
+//   Purpose   : AISC types used by clients                       //
+//                                                                //
+//   Coded by Ralf Westram (coder at reallysoft.de) in August 2010   //
+//   Institute of Microbiology (Technical University Munich)      //
+//   http://www.arb-home.de/                                      //
+//                                                                //
+// ============================================================== //
+
+#ifndef CLIENT_TYPES_H
+#define CLIENT_TYPES_H
+
+#ifndef __cplusplus
+#error AISC clients no longer work in plain C
+#endif
+
+#ifndef AISC_GLOBAL_H
+#include <aisc_global.h>
+#endif
+#ifndef ARB_ASSERT_H
+#include <arb_assert.h>
+#endif
+
+#else
+#error client_types.h included twice
+#endif // CLIENT_TYPES_H


=====================================
AISC_COM/C/common.c
=====================================
@@ -0,0 +1,206 @@
+// ================================================================ //
+//                                                                  //
+//   File      : common.c                                           //
+//   Purpose   : Common code for server and client                  //
+//                                                                  //
+//   Institute of Microbiology (Technical University Munich)        //
+//   http://www.arb-home.de/                                        //
+//                                                                  //
+// ================================================================ //
+
+#include "common.h"
+
+#include <dupstr.h>
+#include <arb_cs.h>
+#include <arb_msg.h>
+#include <arb_assert.h>
+
+#include <netdb.h>
+#include <netinet/tcp.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+enum ClientOrServer { AISC_SERVER, AISC_CLIENT };
+
+inline const char *who(ClientOrServer cos) {
+    switch (cos) {
+        case AISC_SERVER: return "AISC_SERVER";
+        case AISC_CLIENT: return "AISC_CLIENT";
+    }
+    arb_assert(0);
+    return "<unknown>";
+}
+
+static GB_ERROR common_get_m_id(const char *path, char **m_name, int *id) {
+    GB_ERROR error = NULL;
+    if (!path) {
+        error = "missing hostname:socketid";
+    }
+    else {
+        if (strcmp(path, ":") == 0) {
+            path = getenv("SOCKET");
+            if (!path) {
+                error = "expected environment variable 'SOCKET' (needed to connect to ':')";
+            }
+        }
+
+        if (!error) {
+            const char *p = strchr(path, ':');
+            if (path[0] == '*' || path[0] == ':') {     // UNIX MODE
+                char buffer[128];
+                if (!p) {
+                    error = "missing ':' in *:socketid";
+                }
+                else {
+                    if (p[1] == '~') {
+                        sprintf(buffer, "%s%s", getenv("HOME"), p+2);
+                        *m_name = (char *)strdup(buffer);
+                    }
+                    else {
+                        *m_name = (char *)strdup(p+1);
+                    }
+                    *id = -1;
+                }
+            }
+            else {
+                if (!p) {
+                    error = "missing ':' in netname:socketid";
+                }
+                else {
+                    char *mn = (char *) calloc(sizeof(char), p - path + 1);
+                    strncpy(mn, path, p - path);
+
+                    /* @@@ falls hier in mn ein der Bereich von path bis p stehen soll, fehlt eine abschliesende 0 am String-Ende
+                       auf jeden Fall erzeugt der folgende strcmp einen (rui) */
+
+                    if (strcmp(mn, "localhost") == 0) freedup(mn, arb_gethostname());
+
+                    *m_name = mn;
+                    int i   = atoi(p + 1);
+                    if ((i < 1024) || (i > 32000)) {
+                        error = "socketnumber is not in range [1024..32000]";
+                    }
+                    else {
+                        *id = i;
+                    }
+                }
+            }
+        }
+    }
+    return error;
+}
+
+#define SOCKET_EXISTS_AND_CONNECT_WORKED ""
+
+static GB_ERROR common_open_socket(ClientOrServer cos, const char *path, int delay, int do_connect, int *psocket, char **unix_name) {
+    char     *mach_name = NULL;
+    int       socket_id;
+    GB_ERROR  error     = common_get_m_id(path, &mach_name, &socket_id);
+
+    if (!error) {
+        const char one = 1;
+        if (socket_id >= 0) {       // UNIX
+            sockaddr_in so_ad;
+            memset((char *)&so_ad, 0, sizeof(sockaddr_in));
+            *psocket = socket(PF_INET, SOCK_STREAM, 0);
+            if (*psocket <= 0) {
+                error = "failed to create socket"; // @@@ reason why
+            }
+            else {
+                struct hostent *he;
+                arb_gethostbyname(mach_name, he, error);
+                if (!error) {
+                    // simply take first address
+                    struct in_addr addr;
+                    addr.s_addr      = *(int *) (he->h_addr);
+                    so_ad.sin_addr   = addr;
+                    so_ad.sin_family = AF_INET;
+                    so_ad.sin_port   = htons(socket_id);    // @@@ = pb_socket
+                    if (do_connect) {
+                        if (connect(*psocket, (struct sockaddr*)&so_ad, 16)) {
+                            error = SOCKET_EXISTS_AND_CONNECT_WORKED;
+                        }
+                    }
+                    else {
+                        setsockopt(*psocket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+                        if (bind(*psocket, (struct sockaddr*)&so_ad, 16)) {
+                            error = "Could not open socket on Server (1)";
+                        }
+                    }
+                    if (!error) {
+                        if (delay == TCP_NODELAY) {
+                            static int optval;
+                            optval = 1;
+                            setsockopt(*psocket, IPPROTO_TCP, TCP_NODELAY, (char *)&optval, 4);
+                        }
+                        *unix_name = 0;
+                    }
+                }
+            }
+        }
+        else {
+            struct sockaddr_un so_ad;
+            *psocket = socket(PF_UNIX, SOCK_STREAM, 0);
+            if (*psocket <= 0) {
+                error = "cannot create socket"; // @@@ reason why
+            }
+            else {
+                so_ad.sun_family = AF_UNIX;
+                strcpy(so_ad.sun_path, mach_name);
+                if (do_connect) {
+                    if (connect(*psocket, (struct sockaddr*)&so_ad, strlen(mach_name)+2)) {
+                        error = SOCKET_EXISTS_AND_CONNECT_WORKED;
+                    }
+                }
+                else {
+                    FILE *test = fopen(mach_name, "r");
+                    if (test) {
+                        struct stat stt;
+                        if (!stat(path, &stt)) {
+                            if (S_ISREG(stt.st_mode)) {
+                                fprintf(stderr, "%X\n", stt.st_mode);
+                                error = "Socket already exists as a file";
+                            }
+                        }
+                        fclose(test);
+                    }
+
+                    if (!error) {
+                        if (unlink(mach_name) != 0) {
+                            printf("Warning: old socket file '%s' failed to unlink\n", mach_name);
+                        }
+                        if (cos == AISC_SERVER) {
+                            setsockopt(*psocket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+                        }
+                        if (bind(*psocket, (struct sockaddr*)&so_ad, strlen(mach_name)+2)) {
+                            error = "Could not open socket on Server (2)"; // @@@ reasons ?
+                        }
+                        if (!error && cos == AISC_SERVER) {
+                            if (chmod(mach_name, 0777)) {
+                                error = "Cannot change mode of socket"; // @@@ reasons!
+                            }
+                        }
+                    }
+                }
+
+                if (!error) reassign(*unix_name, mach_name);
+            }
+        }
+    }
+
+    free(mach_name);
+
+    if (error && *error) { // real error (see SOCKET_EXISTS_AND_CONNECT_WORKED)
+        error = GBS_global_string("%s-Error: %s", who(cos), error);
+    }
+    return error;
+}
+
+const char *aisc_client_open_socket(const char *path, int delay, int do_connect, int *psocket, char **unix_name) {
+    return common_open_socket(AISC_CLIENT, path, delay, do_connect, psocket, unix_name);
+}
+const char *aisc_server_open_socket(const char *path, int delay, int do_connect, int *psocket, char **unix_name) { // @@@ rename into aisc_server_open_socket
+    return common_open_socket(AISC_SERVER, path, delay, do_connect, psocket, unix_name);
+}
+


=====================================
AISC_COM/C/common.h
=====================================
@@ -0,0 +1,20 @@
+/* This file is generated by aisc_mkpt.
+ * Any changes you make here will be overwritten later!
+ */
+
+#ifndef COMMON_H
+#define COMMON_H
+
+/* define ARB attributes: */
+#ifndef ATTRIBUTES_H
+# include <attributes.h>
+#endif
+
+
+/* common.c */
+const char *aisc_client_open_socket(const char *path, int delay, int do_connect, int *psocket, char **unix_name);
+const char *aisc_server_open_socket(const char *path, int delay, int do_connect, int *psocket, char **unix_name);
+
+#else
+#error common.h included twice
+#endif /* COMMON_H */


=====================================
AISC_COM/C/server.c
=====================================
@@ -0,0 +1,1322 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <sys/stat.h>
+#include <limits.h>
+
+#include "trace.h"
+
+#define FD_SET_TYPE
+
+#if defined(DEBUG)
+// #define SERVER_TERMINATE_ON_CONNECTION_CLOSE
+#endif // DEBUG
+
+#include <signal.h>
+#include <sys/time.h>
+#include <netdb.h>
+#include <setjmp.h>
+
+#include <aisc_com.h>
+// AISC_MKPT_PROMOTE:#include <aisc_func_types.h>
+#include "server.h"
+
+#include <SigHandler.h>
+#include <arb_cs.h>
+#include <static_assert.h>
+#include "common.h"
+
+// AISC_MKPT_PROMOTE:#ifndef _STDIO_H
+// AISC_MKPT_PROMOTE:#include <stdio.h>
+// AISC_MKPT_PROMOTE:#endif
+
+#define aisc_assert(cond) arb_assert(cond)
+
+#define AISC_SERVER_OK 1
+#define AISC_SERVER_FAULT 0
+#define MAX_QUEUE_LEN 5
+
+#define AISC_MAGIC_NUMBER_FILTER 0xffffff00
+
+// -------------------------
+//      some structures
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    struct Socinf {
+        Socinf                *next;
+        int                    socket;
+        aisc_destroy_callback  destroy_callback;
+        long                   destroy_clientdata;
+        int                    lasttime;
+    };
+
+#ifdef __cplusplus
+}
+#endif
+
+struct pollfd;
+struct Hs_struct : virtual Noncopyable {
+    int            hso;
+    Socinf        *soci;
+    struct pollfd *fds;
+    unsigned long  nfds;
+    int            nsoc;
+    int            timeout;
+    int            fork;
+    char          *unix_name;
+
+    Hs_struct()
+        : hso(0),
+          soci(NULL),
+          fds(NULL),
+          nfds(0),
+          nsoc(0),
+          timeout(0),
+          fork(0),
+          unix_name(NULL)
+    {}
+    ~Hs_struct() { freenull(unix_name); }
+};
+
+struct aisc_bytes_list {
+    char            *data;
+    int              size;
+    aisc_bytes_list *next;
+};
+
+static aisc_bytes_list *aisc_server_bytes_first;
+static aisc_bytes_list *aisc_server_bytes_last;
+
+
+extern char  *aisc_object_names[];
+extern char **aisc_attribute_names_list[];
+
+extern aisc_talking_func_long  *aisc_talking_functions_get[];
+extern aisc_talking_func_long  *aisc_talking_functions_set[];
+extern aisc_talking_func_longp *aisc_talking_functions_copy[];
+extern aisc_talking_func_longp *aisc_talking_functions_find[];
+extern aisc_talking_func_longp *aisc_talking_functions_create[];
+extern aisc_talking_func_long   aisc_talking_functions_delete[];
+
+const char *aisc_server_error;
+
+const int   ERRORBUFSIZE = 256;
+static char error_buf[ERRORBUFSIZE];
+
+static int        aisc_server_con;
+static Hs_struct *aisc_server_hs;
+
+// -----------------------
+//      error handling
+
+void aisc_server_errorf(const char *templat, ...) {
+    // goes to header: __ATTR__FORMAT(1)
+    va_list parg;
+
+    va_start(parg, templat);
+    int printed = vsprintf(error_buf, templat, parg);
+
+    if (printed >= ERRORBUFSIZE) {
+        fprintf(stderr,
+                "Fatal: buffer overflow in aisc_server_errorf\n"
+                "Error was: ");
+        vfprintf(stderr, templat, parg);
+        fputs("\nTerminating..\n", stderr);
+        fflush(stderr);
+        exit(EXIT_FAILURE);
+    }
+    va_end(parg);
+
+    aisc_server_error = error_buf;
+}
+
+
+// -----------------------------
+//      valid memory tester
+
+static bool    sigsegv_occurred = false;
+static bool    catch_sigsegv    = 0;
+static jmp_buf return_after_segv;
+
+static const char *test_address_valid(void *address, long key)
+{
+    /* tests whether 'address' is a valid readable address
+     * if 'key' != 0 -> check if 'address' contains 'key'
+     *
+     * returns NULL or error string
+     */
+
+    static char  buf[256];
+    char        *result = buf;
+
+    sigsegv_occurred = false;
+    catch_sigsegv    = true;
+
+    // ----------------------------------------
+    // start of critical section
+    // (need volatile for modified local auto variables, see man longjump)
+    volatile long i       = 0;
+    volatile int  trapped = sigsetjmp(return_after_segv, 1);
+
+    if (trapped == 0) {       // normal execution
+        i = *(long *)address; // here a SIGSEGV may happen. Execution will continue in else-branch
+    }
+    else {                             // return after SEGV
+        aisc_assert(trapped == 666);   // oops - SEGV did not occur in mem access above!
+        aisc_assert(sigsegv_occurred); // oops - wrong handler installed ?
+    }
+    // end of critical section
+    // ----------------------------------------
+
+    catch_sigsegv = false;
+
+    if (sigsegv_occurred) {
+        sprintf(buf, "AISC memory manager error: can't access memory at address %p", address);
+    }
+    else {
+        if (key && i != key) {
+            sprintf(buf, "AISC memory manager error: object at address %p has wrong type (found: 0x%lx, expected: 0x%lx)",
+                    address, i, key);
+        }
+        else {
+            result = NULL;  // ok, address (and key) valid
+        }
+    }
+
+    return result;
+}
+
+static SigHandler old_sigsegv_handler;
+
+__ATTR__NORETURN static void aisc_server_sigsegv(int sig) {
+    sigsegv_occurred = true;
+    if (catch_sigsegv) {
+        siglongjmp(return_after_segv, 666); // never returns
+    }
+    // unexpected SEGV
+
+    UNINSTALL_SIGHANDLER(SIGSEGV, aisc_server_sigsegv, old_sigsegv_handler, "aisc_server_sigsegv");
+    old_sigsegv_handler(sig);
+    aisc_assert(0); // oops - old handler returned
+    abort();
+}
+
+// -----------------------------
+//      broken pipe handler
+
+static int pipe_broken;
+
+static void aisc_server_sigpipe(int) {
+    pipe_broken = 1;
+}
+
+// --------------------------
+//      new read command
+
+static int aisc_s_read(int socket, char *ptr, int size) {
+    int leftsize = size;
+    while (leftsize) {
+        int readsize = read(socket, ptr, leftsize);
+        if (readsize<=0) return 0;
+        ptr += readsize;
+        leftsize -= readsize;
+    }
+
+#if defined(DUMP_COMMUNICATION)
+    aisc_dump_hex("aisc_s_read: ", ptr-size, size);
+#endif // DUMP_COMMUNICATION
+
+    return size;
+}
+
+static int aisc_s_write(int socket, char *ptr, int size) {
+    int leftsize = size;
+    pipe_broken = 0;
+    while (leftsize) {
+        int writesize = write(socket, ptr, leftsize);
+        if (pipe_broken) {
+            fputs("AISC server: pipe broken\n", stderr);
+            return -1;
+        }
+        if (writesize<0) return -1;
+        ptr += writesize;
+        leftsize -= writesize;
+        if (leftsize) usleep(10000); // 10 ms
+    }
+
+#if defined(DUMP_COMMUNICATION)
+    aisc_dump_hex("aisc_s_write: ", ptr-size, size);
+#endif // DUMP_COMMUNICATION
+
+    return 0;
+}
+
+
+// ----------------------------------------------
+//      object+attr_names for error messages
+
+
+const char *aisc_get_object_names(long i)
+{
+    if ((i<0) || (i>=AISC_MAX_OBJECT) || (!aisc_object_names[i])) {
+        return "<unknown object>";
+    }
+    return aisc_object_names[i];
+}
+
+static const char *aisc_get_object_attribute(long i, long j)
+{
+    if ((i<0) || (i>=AISC_MAX_OBJECT) || (!aisc_attribute_names_list[i])) {
+        return "<null>";
+    }
+    if ((j<0) || (j>=AISC_MAX_ATTR) || (!aisc_attribute_names_list[i][j])) {
+        return "<unknown attribute>";
+    }
+    return aisc_attribute_names_list[i][j];
+}
+
+Hs_struct *open_aisc_server(const char *path, int timeout, int fork) {
+    Hs_struct *hs = new Hs_struct;
+    if (hs) {
+        hs->timeout = timeout;
+        hs->fork    = fork;
+
+        static int  so;
+        const char *err = aisc_server_open_socket(path, TCP_NODELAY, 0, &so, &hs->unix_name);
+
+        if (err) {
+            if (*err) printf("Error in open_aisc_server: %s\n", err);
+            shutdown(so, SHUT_RDWR);
+            close(so);
+            delete hs; hs = NULL;
+        }
+        else {
+            // install signal handlers
+            fprintf(stderr, "Installing signal handler from open_aisc_server\n"); fflush(stderr);
+            old_sigsegv_handler = INSTALL_SIGHANDLER(SIGSEGV, aisc_server_sigsegv, "open_aisc_server");
+            ASSERT_RESULT_PREDICATE(is_default_or_ignore_sighandler, INSTALL_SIGHANDLER(SIGPIPE, aisc_server_sigpipe, "open_aisc_server"));
+
+            aisc_server_bytes_first = 0;
+            aisc_server_bytes_last  = 0;
+            // simply take first address
+            if (listen(so, MAX_QUEUE_LEN) < 0) {
+                printf("Error in open_aisc_server: could not listen (errno=%i)\n", errno);
+                delete hs; hs = NULL;
+            }
+            else {
+                hs->hso = so;
+            }
+        }
+    }
+    return hs;
+}
+
+static void aisc_s_add_to_bytes_queue(char *data, int size) {
+    aisc_bytes_list *bl;
+    bl = (aisc_bytes_list *)calloc(sizeof(aisc_bytes_list), 1);
+    bl->data = data;
+    bl->size = size;
+
+    if (aisc_server_bytes_first) {
+        aisc_server_bytes_last->next = bl;
+        aisc_server_bytes_last = bl;
+    }
+    else {
+        aisc_server_bytes_first = bl;
+        aisc_server_bytes_last = bl;
+    }
+}
+
+static int aisc_s_send_bytes_queue(int socket) {
+    aisc_bytes_list *bl, *bl_next;
+    for (bl = aisc_server_bytes_first; bl; bl=bl_next) {
+        bl_next = bl->next;
+        if (aisc_s_write(socket, (char *)bl->data, bl->size)) return 1;
+        free(bl);
+    };
+    aisc_server_bytes_first = aisc_server_bytes_last = NULL;
+    return 0;
+}
+
+static long aisc_talking_get(long *in_buf, int size, long *out_buf, int) { // handles AISC_GET
+    aisc_server_error = NULL;
+
+    long in_pos      = 0;
+    long out_pos     = 0;
+    long object      = in_buf[in_pos++];
+    long object_type = (in_buf[in_pos] & AISC_OBJ_TYPE_MASK);
+    
+
+    if (object_type > (AISC_MAX_OBJECT*0x10000)) {
+        aisc_server_error = "UNKNOWN OBJECT";
+        object = 0;
+    }
+    else {
+        aisc_server_error = test_address_valid((void *)object, object_type);
+    }
+    object_type = object_type >> (16);
+
+    AISC_DUMP_SEP();
+    AISC_DUMP(aisc_talking_get, int, object_type);
+
+    long attribute = 0;
+    long erg       = 0;
+    while (!aisc_server_error && (in_pos < size)) {
+        long code = in_buf[in_pos];
+        long type = (code & AISC_VAR_TYPE_MASK);
+        attribute = (code & AISC_ATTR_MASK);
+
+        aisc_talking_func_long *functions = aisc_talking_functions_get[object_type];
+
+        if (!functions) {
+            aisc_server_error = "OBJECT HAS NO ATTRIBUTES";
+            attribute = 0;
+            break;
+        }
+        if (attribute > AISC_MAX_ATTR) {
+            sprintf(error_buf, "ATTRIBUTE %lx OUT of RANGE", attribute);
+            aisc_server_error = error_buf;
+            attribute = 0;
+            break;
+        }
+        aisc_talking_func_long function = functions[attribute];
+        if (!function) {
+            sprintf(error_buf, "DON'T KNOW ATTRIBUTE %li",
+                    attribute);
+            aisc_server_error = error_buf;
+            break;
+        }
+
+        AISC_DUMP(aisc_talking_get, int, attribute);
+        AISC_DUMP(aisc_talking_get, int, type);
+
+        double_xfer derg;
+        STATIC_ASSERT(sizeof(derg.as_double) <= sizeof(derg.as_int));
+        
+        if (type == AISC_TYPE_DOUBLE) {
+            aisc_talking_func_double dfunction = (aisc_talking_func_double) function;
+            derg.as_double = dfunction(object);
+        }
+        else {
+            erg = function(object);
+        }
+        if (aisc_server_error) {
+            break;
+        }
+        switch (type) {
+            case AISC_TYPE_INT:
+            case AISC_TYPE_COMMON:
+                AISC_DUMP(aisc_talking_get, int, erg);
+                out_buf[out_pos++] = erg;
+                break;
+
+            case AISC_TYPE_DOUBLE:
+                AISC_DUMP(aisc_talking_get, double, derg.as_double);
+                out_buf[out_pos++] = derg.as_int[0];
+                out_buf[out_pos++] = derg.as_int[1];
+                break;
+
+            case AISC_TYPE_STRING: {
+                if (!erg) erg = (long) "(null)";
+                long len = strlen((char *)erg);
+                if (len > AISC_MAX_STRING_LEN) {
+                    erg = (long) "(string too long)";
+                    len = strlen((char *)erg);
+                }
+
+                AISC_DUMP(aisc_talking_get, charPtr, (char*)erg);
+
+                len += 1;
+                len /= sizeof(long);
+                len++;
+                out_buf[out_pos++] = len;
+                strcpy((char *)&out_buf[out_pos], (char *)erg);
+                out_pos += len;
+                break;
+            }
+            case AISC_TYPE_BYTES:
+                {
+                    bytestring *bs = (bytestring *)erg;
+
+                    AISC_DUMP(aisc_talking_get, int, bs->size);
+#if defined(DUMP_COMMUNICATION)
+                    aisc_dump_hex("aisc_talking_get bytestring: ", bs->data, bs->size);
+#endif // DUMP_COMMUNICATION
+
+                    if (bs->data && bs->size)
+                        aisc_s_add_to_bytes_queue(bs->data, bs->size);
+                    out_buf[out_pos++] = bs->size;              // size
+                    break;
+                }
+            default:
+                aisc_server_error = "UNKNOWN TYPE";
+                break;
+        }
+        in_pos++;
+    }
+    if (aisc_server_error) {
+        sprintf((char *) out_buf, "AISC_GET_SERVER_ERROR %s: OBJECT:%s   ATTRIBUTE:%s",
+                aisc_server_error,
+                aisc_get_object_names(object_type),
+                aisc_get_object_attribute(object_type, attribute));
+        return -((strlen((char *)out_buf) + 1) / sizeof(long) + 1);
+    }
+    return out_pos;
+}
+
+static int aisc_server_index = -1;
+
+static void aisc_talking_set_index(int */*obj*/, int i) {
+    aisc_server_index = i;
+}
+
+int aisc_talking_get_index(int u, int o)
+{
+    if (aisc_server_index==-1) {
+        aisc_server_error = "AISC_SERVER_ERROR MISSING AN AISC_INDEX";
+        return -1;
+    }
+    if ((aisc_server_index<u) || (aisc_server_index>=o)) {
+        sprintf(error_buf, "AISC_SET_SERVER_ERROR: INDEX %i IS OUT OF RANGE [%i,%i]",
+                aisc_server_index, u, o);
+        aisc_server_error = error_buf;
+    }
+
+    AISC_DUMP(aisc_talking_get_index, int, aisc_server_index);
+
+    return aisc_server_index;
+}
+
+static long aisc_talking_sets(long *in_buf, int size, long *out_buf, long *object, int object_type) {
+    int   blen, bsize;
+    long  in_pos, out_pos;
+    long  code, attribute, type;
+
+    aisc_talking_func_long function;
+    aisc_talking_func_long *functions;
+    in_pos = out_pos = 0;
+    aisc_server_index = -1;
+    aisc_server_error   = NULL;
+    object_type         = (object_type & AISC_OBJ_TYPE_MASK);
+
+    attribute = 0;
+    if (object_type > (AISC_MAX_OBJECT*0x10000)) {
+        object_type = 0;
+        aisc_server_error = "UNKNOWN OBJECT";
+    }
+    else {
+        aisc_server_error = test_address_valid((void *)object, object_type);
+    }
+    object_type = object_type>>(16);
+    functions   = aisc_talking_functions_set[object_type];
+    if (!functions) {
+        sprintf(error_buf, "OBJECT %x HAS NO ATTRIBUTES",
+                object_type);
+        aisc_server_error = error_buf;
+    }
+
+    AISC_DUMP_SEP();
+    AISC_DUMP(aisc_talking_sets, int, object_type);
+
+    while (!aisc_server_error && (in_pos<size)) {
+        code      = in_buf[in_pos++];
+        attribute = code & AISC_ATTR_MASK;
+        type      = code & AISC_VAR_TYPE_MASK;
+        if (attribute > AISC_MAX_ATTR) {
+            sprintf(error_buf, "ATTRIBUTE %li DOESN'T EXIST",
+                    attribute);
+            aisc_server_error = error_buf;
+            attribute = 0;
+            break;
+        }
+        if (code == AISC_INDEX) {
+            function = (aisc_talking_func_long)aisc_talking_set_index;
+        }
+        else {
+            function = functions[attribute];
+        }
+        if (!function) {
+            sprintf(error_buf, "ATTRIBUTE %li DOESN'T EXIST",
+                    attribute);
+            aisc_server_error = error_buf;
+            break;
+        }
+
+        AISC_DUMP(aisc_talking_sets, int, attribute);
+        AISC_DUMP(aisc_talking_sets, int, type);
+
+        switch (type) {
+            case AISC_TYPE_INT:
+            case AISC_TYPE_COMMON:
+
+                AISC_DUMP(aisc_talking_sets, long, in_buf[in_pos]);
+
+                function((long)object, in_buf[in_pos++]);
+                break;
+            case AISC_TYPE_DOUBLE:
+                {
+                    double_xfer derg;
+                    derg.as_int[0] = in_buf[in_pos++];
+                    derg.as_int[1] = in_buf[in_pos++];
+                    
+                    AISC_DUMP(aisc_talking_sets, double, derg.as_double);
+
+                    function((long)object, derg.as_double);
+                    break;
+                }
+            case AISC_TYPE_STRING:
+                {
+                    char *str = strdup((char *)&(in_buf[in_pos+1]));
+
+                    AISC_DUMP(aisc_talking_sets, charPtr, str);
+
+                    function((long)object, str);
+                    in_pos    += in_buf[in_pos]+1;
+                    break;
+                }
+            case AISC_TYPE_BYTES:
+                bsize = (int)in_buf[in_pos++];
+
+                AISC_DUMP(aisc_talking_sets, int, bsize);
+
+                if (bsize) {
+                    long *ptr = (long*)calloc(sizeof(char), bsize);
+                    blen = aisc_s_read(aisc_server_con, (char *)ptr, bsize);
+                    if (bsize!=blen) {
+                        aisc_server_error = "CONNECTION PROBLEMS IN BYTESTRING";
+                        free(ptr);
+                    }
+                    else {
+                        bytestring bs;
+                        bs.data = (char *)ptr;
+                        bs.size = bsize;
+
+#if defined(DUMP_COMMUNICATION)
+                        aisc_dump_hex("aisc_talking_sets bytestring: ", (char*)ptr, bsize);
+#endif // DUMP_COMMUNICATION
+
+                        function((long)object, &bs);
+                    }
+                }
+                else {
+                    function((long)object, 0);
+                }
+                break;
+            default:
+                aisc_server_error = "UNKNOWN TYPE";
+                break;
+        }
+    }
+    if (aisc_server_error) {
+        sprintf((char *) out_buf, "AISC_SET_SERVER_ERROR %s: OBJECT:%s   ATTRIBUTE:%s",
+                aisc_server_error,
+                aisc_get_object_names(object_type),
+                aisc_get_object_attribute(object_type, attribute));
+        return -((strlen((char *)out_buf) + 1) / sizeof(long) + 1);
+    }
+    return 0;
+}
+
+static long aisc_talking_set(long *in_buf, int size, long *out_buf, int) { // handles AISC_SET
+    aisc_server_error = NULL;
+
+    int  in_pos      = 0;
+    long object      = in_buf[in_pos++];
+    int  object_type = ((int)in_buf[in_pos++]) & AISC_OBJ_TYPE_MASK;
+
+    return aisc_talking_sets(&(in_buf[in_pos]), size-in_pos, out_buf, (long *)object, object_type);
+}
+
+static long aisc_talking_nset(long *in_buf, int size, long *out_buf, int) { // handles AISC_NSET 
+    aisc_server_error = NULL;
+
+    int  in_pos      = 0;
+    long object      = in_buf[in_pos++];
+    int  object_type = (int)(in_buf[in_pos++] & AISC_OBJ_TYPE_MASK);
+
+    aisc_talking_sets(&(in_buf[in_pos]), size-in_pos, out_buf, (long *)object, object_type);
+    return AISC_NO_ANSWER;
+}
+
+static struct aisc_static_set_mem {
+    long *ibuf, *obuf;
+    int size, type;
+} md;
+
+long aisc_make_sets(long *obj)
+{
+    if (md.size>0) {
+        return aisc_talking_sets(md.ibuf, md.size, md.obuf, obj, md.type);
+    }
+    else {
+        return 0;
+    }
+}
+
+static long aisc_talking_create(long *in_buf, int size, long *out_buf, int) { // handles AISC_CREATE
+    aisc_server_error = NULL;
+
+    int  in_pos      = 0;
+    long father_type = in_buf[in_pos++];
+    long father      = in_buf[in_pos++];
+
+    long *erg = 0;
+    for (int i=0; i<1; i++) {
+        if ((father_type&0xff00ffff) ||
+            (((unsigned int)father_type& 0xff0000) >= (AISC_MAX_OBJECT*0x10000))) {
+            aisc_server_error = "AISC_CREATE_SERVER_ERROR: FATHER UNKNOWN";
+            break;
+        }
+        aisc_server_error = test_address_valid((void *)father, father_type);
+        if (aisc_server_error) break;
+
+        father_type                        = father_type>>16;
+        aisc_talking_func_longp *functions = aisc_talking_functions_create[father_type];
+
+        long code        = in_buf[in_pos++];
+        long attribute   = code & AISC_ATTR_MASK;
+        long object_type = in_buf[in_pos++];
+
+        if (!functions) {
+            sprintf(error_buf, "AISC_CREATE_SERVER_ERROR: FATHER %s DOESN'T HAVE TARGET-ATTRIBUTE %s",
+                    aisc_get_object_names(father_type), aisc_get_object_attribute(father_type, attribute));
+            aisc_server_error = error_buf;
+            break;
+        }
+        if (attribute > AISC_MAX_ATTR) {
+            aisc_server_error = "AISC_CREATE_SERVER_ERROR: UNKNOWN ATTRIBUTE";
+            break;
+        }
+        aisc_talking_func_longp function = functions[attribute];
+        if (!function) {
+            sprintf(error_buf, "AISC_CREATE_SERVER_ERROR: FATHER %s FATHER DOESN'T HAVE TARGET-ATTRIBUTE %s",
+                    aisc_get_object_names(father_type), aisc_get_object_attribute(father_type, attribute));
+            aisc_server_error = error_buf;
+            break;
+        }
+        md.ibuf = &(in_buf[in_pos]);
+        md.obuf = out_buf;
+        md.size = size - in_pos;
+        md.type = (int)object_type;
+        erg = function(father);
+    }
+    if (aisc_server_error) {
+        sprintf((char *) out_buf, "%s", aisc_server_error);
+        return -((strlen(aisc_server_error) + 1) / sizeof(long) + 1);
+    }
+    else {
+        out_buf[0] = (long)erg;
+        return 1;
+    }
+}
+
+static long aisc_talking_copy(long *in_buf, int size, long *out_buf, int /*max_size*/) { // handles AISC_COPY
+    aisc_server_error = NULL;
+
+    int  in_pos      = 0;
+    long object      = in_buf[in_pos++];
+    int  father_type = (int)in_buf[in_pos++];
+    long father      = in_buf[in_pos++];
+
+    long *erg = 0;
+    for (int i=0; i<1; i++) {
+        if ((father_type&0xff00ffff) ||
+             (((unsigned int)father_type& 0xff0000) >= (AISC_MAX_OBJECT*0x10000))) {
+            aisc_server_error = "AISC_COPY_SERVER_ERROR: FATHER UNKNOWN";
+            break;
+        }
+        aisc_server_error = test_address_valid((void *)father, father_type);
+        if (aisc_server_error) break;
+
+        father_type                        = father_type>>16;
+        aisc_talking_func_longp *functions = aisc_talking_functions_copy[father_type];
+
+        if (!functions) {
+            aisc_server_error = "AISC_COPY_SERVER_ERROR: FATHER DOESN'T HAVE TARGET-ATTRIBUTES";
+            break;
+        }
+
+        int code        = (int)in_buf[in_pos++];
+        int object_type = (int)in_buf[in_pos++];
+        int attribute   = code & AISC_ATTR_MASK;
+
+        if (attribute > AISC_MAX_ATTR) {
+            aisc_server_error = "AISC_COPY_SERVER_ERROR: UNKNOWN ATTRIBUTE";
+            break;
+        }
+        aisc_talking_func_longp function = functions[attribute];
+        if (!function) {
+            sprintf(error_buf, "AISC_COPY_SERVER_ERROR: FATHER %s DOESN'T HAVE TARGET-ATTRIBUTE %s",
+                    aisc_get_object_names(father_type), aisc_get_object_attribute(father_type, attribute));
+            aisc_server_error = error_buf;
+            break;
+        }
+        aisc_server_error = test_address_valid((void *)object, object_type);
+        if (aisc_server_error) break;
+
+        md.ibuf = &(in_buf[in_pos]);
+        md.obuf = out_buf;
+        md.size = size - in_pos;
+        md.type = object_type;
+        erg = function(father, object);
+    }
+    if (aisc_server_error) {
+        sprintf((char *) out_buf, "%s", aisc_server_error);
+        return -((strlen(aisc_server_error) + 1) / sizeof(long) + 1);
+    }
+    else {
+        out_buf[0] = (long)erg;
+        return 1;
+    }
+}
+
+static long aisc_talking_find(long *in_buf, int /*size*/, long *out_buf, int /*max_size*/) { // handles AISC_FIND
+    aisc_server_error = NULL;
+
+    int  in_pos      = 0;
+    long father_type = in_buf[in_pos++];
+    long father      = in_buf[in_pos++];
+
+    long *erg = 0;
+    for (int i = 0; i < 1; i++) {
+        if ((father_type & 0xff00ffff) ||
+            (((unsigned int) father_type & 0xff0000) >= (AISC_MAX_OBJECT*0x10000))) {
+            aisc_server_error = "AISC_FIND_SERVER_ERROR: FATHER UNKNOWN";
+            break;
+        }
+        aisc_server_error = test_address_valid((void *)father, father_type);
+        if (aisc_server_error)
+            break;
+
+        father_type = father_type>>16;
+        aisc_talking_func_longp *functions   = aisc_talking_functions_find[father_type];
+
+        long code      = in_buf[in_pos++];
+        long attribute = code & AISC_ATTR_MASK;
+
+        if (!functions) {
+            aisc_server_error = "AISC_FIND_SERVER_ERROR: FATHER DON'T KNOW ATTRIBUTES FOR SEARCH";
+            break;
+        }
+        if (attribute > AISC_MAX_ATTR) {
+            aisc_server_error = "AISC_FIND_SERVER_ERROR: UNKNOWN ATTRIBUTE";
+            break;
+        }
+        aisc_talking_func_longp function = functions[attribute];
+        if (!function) {
+            sprintf(error_buf, "AISC_FIND_SERVER_ERROR: FATHER %s DON'T KNOW ATTRIBUTE %s FOR SEARCH",
+                    aisc_get_object_names(father_type), aisc_get_object_attribute(father_type, attribute));
+            aisc_server_error = error_buf;
+            break;
+        }
+        if (in_buf[in_pos++]<=0) {
+            aisc_server_error = " AISC_FIND_SERVER_ERROR: CANNOT FIND EMPTY IDENT";
+            break;
+        }
+        erg = function(father, &(in_buf[in_pos]));
+    }
+    if (aisc_server_error) {
+        sprintf((char *) out_buf, "%s", aisc_server_error);
+        return -((strlen(aisc_server_error) + 1) / sizeof(long) + 1);
+    }
+    else {
+        out_buf[0] = (long) erg;
+        return 1;
+    }
+}
+
+extern int *aisc_main;
+
+static long aisc_talking_init(long */*in_buf*/, int /*size*/, long *out_buf, int /*max_size*/) { // handles AISC_INIT
+    aisc_server_error = NULL;
+    out_buf[0]        = (long)aisc_main;
+    return 1;
+}
+
+static long aisc_fork_server(long */*in_buf*/, int /*size*/, long */*out_buf*/, int /*max_size*/) { // handles AISC_FORK_SERVER
+    pid_t pid = fork();
+    return pid<0 ? 0 : pid; // return OK(=0) when fork does not work
+}
+
+static long aisc_talking_delete(long *in_buf, int /*size*/, long *out_buf, int /*max_size*/) { // handles AISC_DELETE
+    int             in_pos, out_pos;
+    long             object_type;
+
+    aisc_talking_func_long function;
+
+    int             i;
+    long             object;
+    in_pos = out_pos = 0;
+    aisc_server_error = NULL;
+    object_type = in_buf[in_pos++];
+    object_type = (object_type & AISC_OBJ_TYPE_MASK);
+    object = in_buf[in_pos++];
+    for (i = 0; i < 1; i++) {
+        if (object_type > (AISC_MAX_OBJECT*0x10000)) {
+            aisc_server_error = "AISC_GET_SERVER_ERROR: UNKNOWN OBJECT";
+        }
+        else {
+            aisc_server_error = test_address_valid((void *)object, object_type);
+        }
+        if (aisc_server_error)
+            break;
+        object_type = object_type >> (16);
+        function = aisc_talking_functions_delete[object_type];
+        if (!function) {
+            sprintf(error_buf, "AISC_SET_SERVER_ERROR: OBJECT %s cannot be deleted",
+                    aisc_object_names[object_type]);
+            aisc_server_error = error_buf;
+            break;
+        }
+        else {
+            function(object);
+        }
+    }
+    if (aisc_server_error) {
+        sprintf((char *) out_buf, "%s", aisc_server_error);
+        return -((strlen(aisc_server_error) + 1) / sizeof(long) + 1);
+    }
+    return 0;
+}
+
+static long aisc_talking_debug_info(long *in_buf, int /*size*/, long *out_buf, int /*max_size*/) { // handles AISC_DEBUG_INFO
+    int  in_pos, out_pos;
+    long object_type, attribute;
+
+    aisc_talking_func_long *functionsg;
+    aisc_talking_func_long *functionss;
+    aisc_talking_func_longp *functions;
+
+    int   i;
+    long *object;
+
+    in_pos            = out_pos = 0;
+    aisc_server_error = NULL;
+
+    for (i=0; i<256; i++) out_buf[i] = 0;
+    for (i = 0; i < 1; i++) {
+        object            = (long *)in_buf[in_pos++];
+        attribute         = in_buf[in_pos++];
+        aisc_server_error = test_address_valid((void *)object, 0);
+
+        if (aisc_server_error)
+            break;
+
+        object_type = *object;
+        if ((object_type > (AISC_MAX_OBJECT*0x10000)) || (object_type&0xff00ffff) || (object_type<0x00010000)) {
+            aisc_server_error = "AISC_DEBUGINFO_SERVER_ERROR: UNKNOWN OBJECT";
+            break;
+        }
+        attribute   &= AISC_ATTR_MASK;
+        object_type  = object_type>>16;
+
+        if (!aisc_talking_functions_delete[object_type]) { out_buf[0] = 1; };
+
+        if (!(functionsg=aisc_talking_functions_get[object_type])) {
+            out_buf[1] = 2;
+        }
+        else {
+            if (!functionsg[attribute])         out_buf[1] = 1;
+        };
+
+        if (!(functionss=aisc_talking_functions_set[object_type])) {
+            out_buf[2] = 2;
+        }
+        else {
+            if (!functionss[attribute])         out_buf[2] = 1;
+        };
+
+        if (!(functions=aisc_talking_functions_find[object_type])) {
+            out_buf[3] = 2;
+        }
+        else {
+            if (!functions[attribute])  out_buf[3] = 1;
+        };
+
+        if (!(functions=aisc_talking_functions_create[object_type])) {
+            out_buf[4] = 2;
+        }
+        else {
+            if (!functions[attribute])  out_buf[4] = 1;
+        };
+
+        if (!(functions=aisc_talking_functions_copy[object_type])) {
+            out_buf[5] = 2;
+        }
+        else {
+            if (!functions[attribute])  out_buf[5] = 1;
+        };
+
+    }
+    if (aisc_server_error) {
+        sprintf((char *) out_buf, "%s", aisc_server_error);
+        return -((strlen(aisc_server_error) + 1) / sizeof(long) + 1);
+    }
+    else {
+        return 20;
+    }
+}
+
+int aisc_broadcast(Hs_struct *hs, int message_type, const char *message)
+{
+    Socinf *si;
+    int     size    = message ? strlen(message) : 0;
+    int     sizeL   = (size+1+sizeof(long)-1) / sizeof(long); // number of longs needed to safely store string
+    long   *out_buf = (long *)calloc(sizeL+3, sizeof(long));
+
+    if (!message) {
+        out_buf[3] = 0;
+    }
+    else {
+        char *strStart = (char*)(out_buf+3);
+        int   pad      = sizeL*sizeof(long)-(size+1);
+
+        aisc_assert(pad >= 0);
+
+        memcpy(strStart, message, size+1);
+        if (pad) memset(strStart+size+1, 0, pad); // avoid to send uninitialized bytes
+    }
+
+    aisc_assert(sizeL >= 1);
+
+    out_buf[0] = sizeL+1;
+    out_buf[1] = AISC_CCOM_MESSAGE;
+    out_buf[2] = message_type;
+
+    for (si=hs->soci; si; si=si->next) {
+        aisc_s_write(si->socket, (char *)out_buf, (sizeL + 3) * sizeof(long));
+    }
+    free(out_buf);
+    return 0;
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    typedef long (*aisc_talking_function_type)(long*, int, long*, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+static aisc_talking_function_type aisc_talking_functions[] = {
+    aisc_talking_get,        // AISC_GET
+    aisc_talking_set,        // AISC_SET
+    aisc_talking_nset,       // AISC_NSET
+    aisc_talking_create,     // AISC_CREATE
+    aisc_talking_find,       // AISC_FIND
+    aisc_talking_copy,       // AISC_COPY
+    aisc_talking_delete,     // AISC_DELETE
+    aisc_talking_init,       // AISC_INIT
+    aisc_talking_debug_info, // AISC_DEBUG_INFO
+    aisc_fork_server         // AISC_FORK_SERVER
+};
+
+static int aisc_talking(int con) {
+    static long      buf[AISC_MESSAGE_BUFFER_LEN];
+    static long      out_buf[AISC_MESSAGE_BUFFER_LEN];
+    unsigned long    len;
+    static long      size;
+    long             magic_number;
+    len = aisc_s_read(con, (char *)buf, 2* sizeof(long));
+    if (len == 2*sizeof(long)) {
+        aisc_server_con = con;
+        if (buf[0] >= AISC_MESSAGE_BUFFER_LEN)
+            return AISC_SERVER_FAULT;
+        magic_number = buf[1];
+        if ((unsigned long)(magic_number & AISC_MAGIC_NUMBER_FILTER) != (unsigned long)(AISC_MAGIC_NUMBER & AISC_MAGIC_NUMBER_FILTER)) {
+            return AISC_SERVER_FAULT;
+        }
+        size = buf[0];
+
+        {
+            long expect = size*sizeof(long);
+            aisc_assert(expect >= 0);
+            aisc_assert(expect <= INT_MAX);
+
+            len = aisc_s_read(con, (char *)buf, (int)expect);
+            aisc_assert(len <= LONG_MAX);
+
+            if ((long)len != expect) {
+                printf(" ERROR in AISC_SERVER: Expected to get %li bytes from client (got %lu)\n", expect, len);
+                return AISC_SERVER_OK;
+            }
+        }
+        magic_number &= ~AISC_MAGIC_NUMBER_FILTER;
+        size          = (aisc_talking_functions[magic_number])
+            (buf, (int)size, out_buf + 2, AISC_MESSAGE_BUFFER_LEN - 2);
+        if (size >= 0) {
+            out_buf[1] = AISC_CCOM_OK;
+        }
+        else {
+            if (size == (long)AISC_NO_ANSWER) {
+                return AISC_SERVER_OK;
+            }
+            out_buf[1] = AISC_CCOM_ERROR;
+            size *= -1;
+        }
+        out_buf[0] = size;
+        if (aisc_s_write(con, (char *)out_buf, (int)(size + 2) * sizeof(long))) {
+            return AISC_SERVER_FAULT;
+        }
+        if (aisc_server_bytes_first) {
+            if (aisc_s_send_bytes_queue(con)) {
+                return AISC_SERVER_FAULT;
+            }
+        }
+        return AISC_SERVER_OK;
+    }
+    else {
+        return AISC_SERVER_FAULT;
+    }
+}
+
+Hs_struct *aisc_accept_calls(Hs_struct *hs)
+{
+    int             con;
+    int             anz, i;
+    Socinf         *si, *si_last = NULL, *sinext, *sptr;
+    fd_set          set, setex;
+    struct timeval  timeout;
+
+    if (!hs) {
+        fprintf(stderr, "AISC_SERVER_ERROR socket error (==0)\n");
+    }
+
+    timeout.tv_sec  = hs->timeout / 1000;
+    timeout.tv_usec = (hs->timeout % 1000) * 1000;
+
+    aisc_server_hs = hs;
+
+    while (hs) {
+        FD_ZERO(&set);
+        FD_ZERO(&setex);
+        FD_SET(hs->hso, &set);
+        FD_SET(hs->hso, &setex);
+
+        for (si=hs->soci, i=1; si; si=si->next, i++)
+        {
+            FD_SET(si->socket, &set);
+            FD_SET(si->socket, &setex);
+        }
+        if (hs->timeout >= 0) {
+            anz = select(FD_SETSIZE, FD_SET_TYPE &set, NULL, FD_SET_TYPE &setex, &timeout);
+        }
+        else {
+            anz = select(FD_SETSIZE, FD_SET_TYPE &set, NULL, FD_SET_TYPE &setex, 0);
+        }
+
+        if (anz==-1) {
+            printf("ERROR: poll in aisc_accept_calls\n");
+            return 0;
+        }
+        if (!anz) { // timed out
+            return hs;
+        }
+        // an event has occurred
+        if ((timeout.tv_usec>=0)&&(timeout.tv_usec<100000)) timeout.tv_usec = 100000;
+
+        if (FD_ISSET(hs->hso, &set)) {
+            con = accept(hs->hso, NULL, 0);
+            if (hs->fork) {
+                long id = fork();
+                if (!id) {
+                    return hs;
+                }
+            }
+
+            if (con>0) {
+                static int optval;
+                sptr = (Socinf *)calloc(sizeof(Socinf), 1);
+                if (!sptr) return 0;
+                sptr->next = hs->soci;
+                sptr->socket = con;
+                hs->soci=sptr;
+                hs->nsoc++;
+                optval = 1;
+                setsockopt(con, IPPROTO_TCP, TCP_NODELAY, (char *)&optval, 4);
+            }
+        }
+        else {
+            si_last = 0;
+
+            for (si=hs->soci; si; si_last=si, si=sinext) {
+                sinext = si->next;
+
+                if (FD_ISSET(si->socket, &set)) {
+                    if (AISC_SERVER_OK == aisc_talking(si->socket)) continue;
+                } else if (!FD_ISSET(si->socket, &setex)) continue;
+
+                if (close(si->socket) != 0) {
+                    printf("aisc_accept_calls: ");
+                    printf("couldn't close socket!\n");
+                }
+
+                hs->nsoc--;
+                if (si == hs->soci) {   // first one
+                    hs->soci = si->next;
+                }
+                else {
+                    si_last->next = si->next;
+                }
+                if (si->destroy_callback) {
+                    si->destroy_callback(si->destroy_clientdata);
+                }
+                free(si);
+#ifdef SERVER_TERMINATE_ON_CONNECTION_CLOSE
+                if (hs->nsoc == 0) { // no clients left
+                    if (hs->fork) exit(EXIT_SUCCESS); // child exits
+                    return hs; // parent exits
+                }
+                break;
+#else
+                // normal behavior
+                if (hs->nsoc == 0 && hs->fork) exit(EXIT_SUCCESS);
+                break;
+#endif
+            }
+        }
+    } // while main loop
+
+    return hs;
+}
+
+void aisc_server_shutdown(Hs_struct*& hs) {
+    Socinf *si;
+
+    for (si=hs->soci; si; si=si->next) {
+        shutdown(si->socket, SHUT_RDWR);
+        close(si->socket);
+    }
+    shutdown(hs->hso, SHUT_RDWR);
+    close(hs->hso);
+    if (hs->unix_name) unlink(hs->unix_name);
+    delete hs; hs = NULL;
+}
+
+void aisc_server_shutdown_and_exit(Hs_struct *hs, int exitcode) {
+    /* goes to header:
+     * __ATTR__NORETURN
+     * __ATTR__DEPRECATED_TODO("cause it hides a call to exit() inside a library")
+     */
+
+    aisc_server_shutdown(hs);
+    printf("Server terminates with code %i.\n", exitcode);
+    exit(exitcode);
+}
+
+
+// ---------------------------
+//      special functions
+
+
+int aisc_add_destroy_callback(aisc_destroy_callback callback, long clientdata) {        // call from server function
+    Socinf    *si;
+    int        socket = aisc_server_con;
+    Hs_struct *hs     = aisc_server_hs;
+    if (!hs)
+        return socket;
+    for (si = hs->soci; si; si = si->next) {
+        if (si->socket == socket) {
+            if (si->destroy_callback) {
+                fputs("Error: destroy_callback already bound (did you open two connections in client?)\n", stderr);
+                fputs("Note: calling bound and installing new destroy_callback\n", stderr);
+                si->destroy_callback(si->destroy_clientdata);
+            }
+
+            si->destroy_callback   = callback;
+            si->destroy_clientdata = clientdata;
+        }
+    }
+    return socket;
+}
+
+void aisc_remove_destroy_callback() {   // call from server function
+    Socinf    *si;
+    int        socket = aisc_server_con;
+    Hs_struct *hs     = aisc_server_hs;
+    if (!hs)
+        return;
+    for (si = hs->soci; si; si = si->next) {
+        if (si->socket == socket) {
+            si->destroy_callback = 0;
+            si->destroy_clientdata = 0;
+        }
+    }
+}
+
+int aisc_server_save_token(FILE *fd, const char *buffer, int maxsize) {
+    putc('{',fd);
+    const char *p = buffer;
+    while (maxsize-->0) {
+        int c = *(p++);
+        if (!c) break;
+        if (c=='}' || c == '\\') putc('\\',fd);
+        putc(c,fd);
+    }
+    putc('}',fd);
+    return 0;
+}
+
+int aisc_server_load_token(FILE *fd, char *buffer, int maxsize) {
+    int   in_brackets = 0;
+    char *p           = buffer;
+    int   result      = EOF;
+
+    while (maxsize-- > 0) {
+        int c = getc(fd);
+        if (c==EOF) break;
+        if (in_brackets) {
+            if (c=='\\') {
+                c = getc(fd);
+                *(p++) = c;
+            }
+            else if (c!='}') {
+                *(p++) = c;
+            }
+            else {
+                result = 0;
+                break;
+            }
+        }
+        else if (c=='{') { 
+            if (p!=buffer) {
+                *(p++) = '{';
+                *p=0;
+                return 0;
+            }
+            else {
+                in_brackets = 1; 
+            }
+        }
+        else if (c==' ' || c=='\n') {
+            if (p!=buffer) {
+                result = 0;
+                break;
+            }
+        }
+        else if (c=='}') {
+            *(p++) = '}';
+            result = 0;
+            break;
+        }
+        else {
+            *(p++) = c;
+        }
+    }
+    
+    *p = 0;
+    return result; // read error maxsize reached
+}


=====================================
AISC_COM/C/server.h
=====================================
@@ -0,0 +1,37 @@
+/* This file is generated by aisc_mkpt.
+ * Any changes you make here will be overwritten later!
+ */
+
+#ifndef SERVER_H
+#define SERVER_H
+
+/* define ARB attributes: */
+#ifndef ATTRIBUTES_H
+# include <attributes.h>
+#endif
+
+
+/* server.c */
+
+#include <aisc_func_types.h>
+#ifndef _STDIO_H
+#include <stdio.h>
+#endif
+
+void aisc_server_errorf(const char *templat, ...) __ATTR__FORMAT(1);
+const char *aisc_get_object_names(long i);
+Hs_struct *open_aisc_server(const char *path, int timeout, int fork);
+int aisc_talking_get_index(int u, int o);
+long aisc_make_sets(long *obj);
+int aisc_broadcast(Hs_struct *hs, int message_type, const char *message);
+Hs_struct *aisc_accept_calls(Hs_struct *hs);
+void aisc_server_shutdown(Hs_struct*& hs);
+void aisc_server_shutdown_and_exit(Hs_struct *hs, int exitcode) __ATTR__NORETURN __ATTR__DEPRECATED_TODO("cause it hides a call to exit() inside a library");
+int aisc_add_destroy_callback(aisc_destroy_callback callback, long clientdata);
+void aisc_remove_destroy_callback(void);
+int aisc_server_save_token(FILE *fd, const char *buffer, int maxsize);
+int aisc_server_load_token(FILE *fd, char *buffer, int maxsize);
+
+#else
+#error server.h included twice
+#endif /* SERVER_H */


=====================================
AISC_COM/C/struct_man.c
=====================================
@@ -0,0 +1,344 @@
+// ==============================================================
+/*                                                                */
+//   File      : struct_man.c
+//   Purpose   :
+/*                                                                */
+//   Institute of Microbiology (Technical University Munich)
+//   http://www.arb-home.de/
+ /*                                                                */
+ // ==============================================================
+
+
+#include <aisc.h>
+#include <struct_man.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// AISC_MKPT_PROMOTE:struct aisc_hash_node;
+
+// ---------------------
+//      hash tables
+
+
+#define CORE
+#define HASH_SIZE 103123
+#define TRF_HASH_SIZE 103123
+
+struct aisc_hash_node {
+    char           *key;
+    long            data;
+    aisc_hash_node *next;
+};
+
+
+static aisc_hash_node **aisc_init_hash(int size) {
+    struct aisc_hash_node **tab;
+    tab = (aisc_hash_node **) calloc(sizeof(aisc_hash_node *), size);
+    tab[0] = (aisc_hash_node *) calloc(sizeof(aisc_hash_node), 1);
+    tab[0]->data = size;
+    tab[0]->key = (char *)strdup("len_of_hash_table_(c) oliver_strunk 1.3.93");
+    return tab;
+}
+
+static int aisc_hash(const char *key, int size) {
+    unsigned int i, len, x;
+    len = strlen(key);
+    x = 0;
+    for (i=0; i<len; i++) {
+        x = x<<2 ^ key[i];
+    }
+    x = x%size;
+    return x;
+}
+
+static void aisc_free_key(aisc_hash_node **table, char *key) {
+    if (table && table[0]) {
+        long size = table[0]->data;
+        long i    = aisc_hash(key, (int)size);
+
+        aisc_hash_node *hn, *hhn;
+        for (hn = hhn = table[i]; hn; hn = hn->next) {
+            if (strcmp(key, hn->key)) {
+                hhn = hn;
+                continue;
+            }
+            if (hn != hhn)
+                hhn->next = hn->next;
+            else {
+                table[i] = hhn->next;
+            }
+            free(hn->key);
+            free(hn);
+            break;
+        }
+    }
+}
+
+static void aisc_free_hash(aisc_hash_node **table) {
+    long end = table[0]->data;
+    for (long i=0; i<end; i++) {
+        aisc_hash_node *hn, *hnn;
+        for (hn = table[i]; hn; hn=hnn) {
+            hnn = hn->next;
+            free(hn->key);
+            free(hn);
+        }
+    }
+    free(table);
+}
+
+
+static void aisc_insert_hash(aisc_hash_node **table, char *key, long data) {
+    long            size = table[0]->data;
+    long            i    = aisc_hash(key, (int)size);
+
+    aisc_hash_node *hnl  = 0;
+    aisc_hash_node *hn;
+    for (hn=table[i]; hn; hn=hn->next) {
+        hnl = hn;
+        if (strcmp(key, hn->key) == 0) {
+            hn->data = data;
+            return;
+        }
+    }
+    hn = (aisc_hash_node *)calloc(sizeof(aisc_hash_node), 1);
+    hn->key = (char *)strdup(key);
+    hn->data = data;
+    if (hnl) {
+        hnl->next = hn;
+    }
+    else {
+        table[i] = hn;
+    }
+}
+
+long aisc_read_hash(aisc_hash_node **table, const char *key) {
+    if (table && table[0]) {
+        long size = table[0]->data;
+        long i = aisc_hash(key, (int)size);
+        for (aisc_hash_node *hn=table[i]; hn; hn=hn->next) {
+            if (strcmp(key, hn->key) == 0) return hn->data;
+        }
+    }
+    return 0;
+}
+
+// ----------------------
+//      link control
+
+const char *aisc_link(dllpublic_ext *father, dllheader_ext *object) {
+    if (!object) {
+        CORE;
+        return "Object is (NULL)";
+    }
+    if (object->mh.parent) {
+        CORE;
+        return "Object already linked";
+    }
+    if (!father) {
+        CORE;
+        return "Parent is (NULL)";
+    }
+    if (father->key != object->mh.key) {
+        CORE;
+        return "Parent key doesn't match Object key";
+    }
+    if (object->mh.ident) {
+        if (strlen(object->mh.ident) <= 0) {
+            CORE;
+            return "Too short ident";
+        }
+        if (father->hash) {
+            if (aisc_read_hash((aisc_hash_node **)father->hash, object->mh.ident)) {
+                CORE;
+                return "Object already in list";
+            }
+            else {
+                aisc_insert_hash((aisc_hash_node **)father->hash, object->mh.ident, (long)object);
+            }
+        }
+        else {
+            father->hash = (long)aisc_init_hash(HASH_SIZE);
+            aisc_insert_hash((aisc_hash_node **)father->hash, object->mh.ident, (long)object);
+        }
+    }
+    object->next = object->previous = NULL;
+    if (!father->first) {
+        father->cnt   = 1;
+        father->first = object;
+        father->last  = object;
+    }
+    else {
+        father->cnt++;
+        object->previous   = father->last;
+        father->last->next = object;
+        father->last       = object;
+    }
+    object->mh.parent = father;
+    return 0;
+}
+
+
+
+const char *aisc_unlink(dllheader_ext *object) {
+    dllpublic_ext *father = (dllpublic_ext *)object->mh.parent;
+
+    if (!father) {
+        CORE;
+        return "Object not linked";
+    }
+    if (father->hash) {
+        aisc_free_key((aisc_hash_node **)father->hash, object->mh.ident);
+    }
+    if (father->cnt <= 0) {
+        CORE;
+        return "Parent count is 0";
+    }
+    if (object->previous) {
+        if (object->previous->next != object) {
+            CORE;
+            return "Fatal Error: Object is a copy, not original";
+        }
+        object->previous->next = object->next;
+    }
+    else {
+        father->first = object->next;
+    }
+    if (object->next) {
+        object->next->previous = object->previous;
+    }
+    else {
+        father->last = object->previous;
+    }
+    object->mh.parent = NULL;
+    object->previous  = NULL;
+    object->next      = NULL;
+
+    father->cnt--;
+    if (!father->cnt) {
+        if (father->hash) {
+            aisc_free_hash((aisc_hash_node **)father->hash);
+            father->hash = 0;
+        }
+    }
+    return 0;
+}
+
+long aisc_find_lib(dllpublic_ext *parent, char *ident)
+{
+    if (!parent->hash) return 0;
+    if (!ident) return 0;
+    return aisc_read_hash((aisc_hash_node **)parent->hash, ident);
+}
+
+
+struct trf_dest_struct {
+    struct trf_dest_struct *next;
+    long                   *dest;
+};
+
+struct trf_struct {
+    struct trf_struct      *next;
+    long                    new_item;
+    long                    old;
+    struct trf_dest_struct *dests;
+};
+
+static int trf_hash(long p)
+{
+    return (p+(p>>8))&(TRF_HASH_SIZE-1);
+}
+
+static int trf_level = 0;
+static struct trf_struct **trf_sp = 0;
+
+void trf_create(long old, long new_item) {
+    long i;
+    struct trf_struct *ts;
+    struct trf_dest_struct *tds, *ntds;
+    if (!trf_sp) return;
+    i = trf_hash(old);
+    for (ts = trf_sp[i]; ts; ts = ts->next) {
+        if (ts->old == old) {
+            if (ts->new_item && (ts->new_item != new_item)) {
+                GBK_terminate("ERROR IN trf_create");
+            }
+            else {
+                ts->new_item = new_item;
+                for (tds = ts->dests; tds; tds = ntds) {
+                    *tds->dest = new_item;
+                    ntds = tds->next;
+                    free(tds);
+                }
+            }
+            return;
+        }
+    }
+    ts = (struct trf_struct *)calloc(sizeof(struct trf_struct), 1);
+    ts->next = trf_sp[i];
+    trf_sp[i] = ts;
+    ts->new_item = new_item;
+    ts->old = old;
+}
+
+void trf_link(long old, long *dest)
+{
+    long i;
+    struct trf_struct *ts, *fts;
+    struct trf_dest_struct *tds;
+    if (!trf_sp) return;
+    i = trf_hash(old);
+    fts = 0;
+    for (ts = trf_sp[i]; ts; ts = ts->next) {
+        if (ts->old == old)     { fts = ts; break; }
+    }
+    if (!fts) {
+        ts = (struct trf_struct *)calloc(sizeof(struct trf_struct), 1);
+        ts->next = trf_sp[i];
+        trf_sp[i] = ts;
+        ts->old = old;
+        fts = ts;
+    }
+    tds = (struct trf_dest_struct *)calloc(sizeof(struct trf_dest_struct), 1);
+    tds->next = fts->dests;
+    fts->dests = tds;
+    tds->dest = dest;
+}
+
+void trf_begin() {
+    if (trf_level==0) {
+        trf_sp = (struct trf_struct **)calloc(sizeof(struct trf_struct *), TRF_HASH_SIZE);
+    }
+    trf_level ++;
+}
+
+void trf_commit(int errors) {
+    // if errors == 1 then print errors and CORE
+    struct trf_dest_struct *tds, *ntds;
+    struct trf_struct *ts, *nts;
+    trf_level--;
+    if (!trf_level) {
+        for (int i = 0; i < TRF_HASH_SIZE; i++) {
+            for (ts = trf_sp[i]; ts; ts = nts) {
+                if (errors) {
+                    if (ts->dests) {
+                        GBK_terminate("ERROR IN trf_commit");
+                    }
+                }
+                else {
+                    for (tds = ts->dests; tds; tds = ntds) {
+                        ntds = tds->next;
+                        free(tds);
+                    }
+                }
+                nts = ts->next;
+                free(ts);
+            }
+        }
+        free(trf_sp);
+        trf_sp = 0;
+    }
+}
+


=====================================
AISC_COM/C/struct_man.h
=====================================
@@ -0,0 +1,29 @@
+/* This file is generated by aisc_mkpt.
+ * Any changes you make here will be overwritten later!
+ */
+
+#ifndef STRUCT_MAN_H
+#define STRUCT_MAN_H
+
+/* define ARB attributes: */
+#ifndef ATTRIBUTES_H
+# include <attributes.h>
+#endif
+
+
+/* struct_man.c */
+
+struct aisc_hash_node;
+
+long aisc_read_hash(aisc_hash_node **table, const char *key);
+const char *aisc_link(dllpublic_ext *father, dllheader_ext *object);
+const char *aisc_unlink(dllheader_ext *object);
+long aisc_find_lib(dllpublic_ext *parent, char *ident);
+void trf_create(long old, long new_item);
+void trf_link(long old, long *dest);
+void trf_begin(void);
+void trf_commit(int errors);
+
+#else
+#error struct_man.h included twice
+#endif /* STRUCT_MAN_H */


=====================================
AISC_COM/C/trace.h
=====================================
@@ -0,0 +1,67 @@
+// =============================================================== //
+//                                                                 //
+//   File      : trace.h                                           //
+//   Purpose   :                                                   //
+//                                                                 //
+//   Coded by Ralf Westram (coder at reallysoft.de) in May 2007       //
+//   Institute of Microbiology (Technical University Munich)       //
+//   http://www.arb-home.de/                                       //
+//                                                                 //
+// =============================================================== //
+#ifndef TRACE_H
+#define TRACE_H
+
+#if defined(DEBUG)
+// #define DUMP_COMMUNICATION
+#endif // DEBUG
+
+// --------------------------------------------------------------------------------
+
+#if defined(DUMP_COMMUNICATION)
+
+static void aisc_dump_hex(const char *title, const char *data, int datasize) {
+    const unsigned char *udata = (const unsigned char *)data;
+    int d;
+
+    fprintf(stderr, "%s", title);
+    for (d = 0; d<datasize; d++) {
+        fprintf(stderr, "%02X", udata[d]);
+    }
+    fprintf(stderr, "\n");
+}
+
+static void aisc_dump_int(const char *where, const char *varname, int var) {
+    fprintf(stderr, "AISC_DUMP: %s: int    %s=%i ", where, varname, var);
+    aisc_dump_hex("Hex: ", (const char*)&var, sizeof(var));
+}
+static void aisc_dump_long(const char *where, const char *varname, long var) {
+    fprintf(stderr, "AISC_DUMP: %s: long   %s=%li ", where, varname, var);
+    aisc_dump_hex("Hex: ", (const char*)&var, sizeof(var));
+}
+static void aisc_dump_double(const char *where, const char *varname, double var) {
+    fprintf(stderr, "AISC_DUMP: %s: double %s=%f ", where, varname, (float)var);
+    aisc_dump_hex("Hex: ", (const char*)&var, sizeof(var));
+}
+static void aisc_dump_charPtr(const char *where, const char *varname, const char *var) {
+    fprintf(stderr, "AISC_DUMP: %s: cPtr   %s='%s' ", where, varname, var);
+    aisc_dump_hex("Hex: ", var, strlen(var)+1);
+}
+static void aisc_dump_voidPtr2(const char *where, const char *varname, void *var) {
+    fprintf(stderr, "AISC_DUMP: %s: ptr    %s=%p\n", where, varname, var);
+}
+
+#define aisc_dump_voidPtr(w, n, v) aisc_dump_voidPtr2(w, n, (void*)v)
+#define AISC_DUMP(where, type, var) aisc_dump_##type(#where, #var, var)
+#define AISC_DUMP_SEP() fprintf(stderr, "-----------------------------\n")
+
+#else
+#define AISC_DUMP(where, type, var)
+#define AISC_DUMP_SEP()
+#endif // DUMP_COMMUNICATION
+
+// --------------------------------------------------------------------------------
+
+#else
+#error trace.h included twice
+#endif // TRACE_H
+



View it on GitLab: https://salsa.debian.org/med-team/libarb/compare/030a422d48f58956f8e03a32db2aa60123db74c8...8f7aae391183c4a07623f5d68101d5c8d8a5e91a

-- 
View it on GitLab: https://salsa.debian.org/med-team/libarb/compare/030a422d48f58956f8e03a32db2aa60123db74c8...8f7aae391183c4a07623f5d68101d5c8d8a5e91a
You're receiving this email because of your account on salsa.debian.org.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20190607/99eb67ac/attachment-0001.html>


More information about the debian-med-commit mailing list