summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorStig Bakken <ssb@php.net>1999-04-21 23:11:20 +0000
committerStig Bakken <ssb@php.net>1999-04-21 23:11:20 +0000
commita297b95c9da1b6138523f9b707a0fafe60e0d327 (patch)
treea50bc7a551fe793e1e9403092c0ae2ed4907b053 /ext
parentf67a9bdc52c39eed6837aef8a1eca195549b1469 (diff)
downloadphp-git-a297b95c9da1b6138523f9b707a0fafe60e0d327.tar.gz
moved apache, com and hyperwave into ext/
Diffstat (limited to 'ext')
-rw-r--r--ext/apache/Makefile.am6
-rw-r--r--ext/apache/apache.c386
-rw-r--r--ext/apache/config.m45
-rw-r--r--ext/com/php3_COM.h22
-rw-r--r--ext/hyperwave/DList.h128
-rw-r--r--ext/hyperwave/Makefile.am6
-rw-r--r--ext/hyperwave/config.h.stub2
-rw-r--r--ext/hyperwave/config.m418
-rw-r--r--ext/hyperwave/dlist.c410
-rw-r--r--ext/hyperwave/hg_comm.c4701
-rw-r--r--ext/hyperwave/hg_comm.h196
-rw-r--r--ext/hyperwave/hw.c3062
-rw-r--r--ext/hyperwave/hw.h122
-rw-r--r--ext/hyperwave/hw_error.h117
-rw-r--r--ext/hyperwave/setup.stub6
-rw-r--r--ext/rpc/com/COM.c959
-rw-r--r--ext/rpc/com/php3_COM.h22
17 files changed, 10168 insertions, 0 deletions
diff --git a/ext/apache/Makefile.am b/ext/apache/Makefile.am
new file mode 100644
index 0000000000..c9006e13bb
--- /dev/null
+++ b/ext/apache/Makefile.am
@@ -0,0 +1,6 @@
+# $Id$
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_apache.a
+libphpext_apache_a_SOURCES=apache.c
+
diff --git a/ext/apache/apache.c b/ext/apache/apache.c
new file mode 100644
index 0000000000..614268d4be
--- /dev/null
+++ b/ext/apache/apache.c
@@ -0,0 +1,386 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
+ | Stig Sæther Bakken <ssb@guardian.no> |
+ | David Sklar <sklar@student.net> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+#ifdef THREAD_SAFE
+#include "tls.h"
+#endif
+#include "php.h"
+#include "functions/head.h"
+#include "php_globals.h"
+#include "php_ini.h"
+#include "mod_php3.h"
+
+#include <stdlib.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+#if APACHE
+#include "http_request.h"
+#include "build-defs.h"
+
+extern module *top_module;
+
+void php3_virtual(INTERNAL_FUNCTION_PARAMETERS);
+void php3_getallheaders(INTERNAL_FUNCTION_PARAMETERS);
+void php3_apachelog(INTERNAL_FUNCTION_PARAMETERS);
+void php3_info_apache(void);
+void php3_apache_note(INTERNAL_FUNCTION_PARAMETERS);
+void php3_apache_lookup_uri(INTERNAL_FUNCTION_PARAMETERS);
+
+function_entry apache_functions[] = {
+ {"virtual", php3_virtual, NULL},
+ {"getallheaders", php3_getallheaders, NULL},
+ {"apache_note", php3_apache_note,NULL},
+ {"apache_lookup_uri", php3_apache_lookup_uri,NULL},
+ {NULL, NULL, NULL}
+};
+
+
+static PHP_INI_MH(OnChangeApacheInt)
+{
+ long *p;
+ char *base = (char *) &php_apache_info;
+
+ p = (long *) (base+(size_t) mh_arg);
+
+ if (new_value) {
+ *p = atoi(new_value);
+ return SUCCESS;
+ } else {
+ return FAILURE;
+ }
+}
+
+
+static PHP_INI_MH(OnChangeApacheString)
+{
+ char **p;
+ char *base = (char *) &php_apache_info;
+
+ p = (char **) (base+(size_t) mh_arg);
+
+ if (new_value) {
+ *p = new_value;
+ return SUCCESS;
+ } else {
+ return FAILURE;
+ }
+}
+
+PHP_INI_BEGIN()
+ PHP_INI_ENTRY("xbithack", "0", PHP_INI_ALL, OnChangeApacheInt, (void *) XtOffsetOf(php_apache_info_struct, xbithack))
+ PHP_INI_ENTRY("engine", "1", PHP_INI_ALL, OnChangeApacheInt, (void *) XtOffsetOf(php_apache_info_struct, engine))
+ PHP_INI_ENTRY("last_modified", "0", PHP_INI_ALL, OnChangeApacheInt, (void *) XtOffsetOf(php_apache_info_struct, last_modified))
+ PHP_INI_ENTRY("dav_script", NULL, PHP_INI_ALL, OnChangeApacheString, (void *) XtOffsetOf(php_apache_info_struct, dav_script))
+PHP_INI_END()
+
+
+static int php_apache_minit(INIT_FUNC_ARGS)
+{
+ REGISTER_INI_ENTRIES();
+ return SUCCESS;
+}
+
+
+static int php_apache_mshutdown(SHUTDOWN_FUNC_ARGS)
+{
+ UNREGISTER_INI_ENTRIES();
+ return SUCCESS;
+}
+
+
+php3_module_entry apache_module_entry = {
+ "Apache", apache_functions, php_apache_minit, php_apache_mshutdown, NULL, NULL, php3_info_apache, STANDARD_MODULE_PROPERTIES
+};
+
+/* {{{ proto string apache_note(string note_name [, string note_value])
+ Get and set Apache request notes */
+void php3_apache_note(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *arg_name,*arg_val;
+ char *note_val;
+ int arg_count = ARG_COUNT(ht);
+TLS_VARS;
+
+ if (arg_count<1 || arg_count>2 ||
+ getParameters(ht,arg_count,&arg_name,&arg_val) == FAILURE ) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_string(arg_name);
+ note_val = (char *) table_get(GLOBAL(php3_rqst)->notes,arg_name->value.str.val);
+
+ if (arg_count == 2) {
+ convert_to_string(arg_val);
+ table_set(GLOBAL(php3_rqst)->notes,arg_name->value.str.val,arg_val->value.str.val);
+ }
+
+ if (note_val) {
+ RETURN_STRING(note_val,1);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+void php3_info_apache(void) {
+ module *modp = NULL;
+#if !defined(WIN32) && !defined(WINNT)
+ char name[64];
+ char *p;
+#endif
+ server_rec *serv = GLOBAL(php3_rqst)->server;
+ extern char server_root[MAX_STRING_LEN];
+ extern uid_t user_id;
+ extern char *user_name;
+ extern gid_t group_id;
+ extern int max_requests_per_child;
+
+#if WIN32|WINNT
+ PUTS("Apache for Windows 95/NT<br>");
+#else
+ php3_printf("<tt>APACHE_INCLUDE=%s<br>\n", PHP_APACHE_INCLUDE);
+ php3_printf("APACHE_TARGET=%s<br></tt>\n", PHP_APACHE_TARGET);
+#endif
+ php3_printf("Apache Version: <b>%s</b><br>",SERVER_VERSION);
+#ifdef APACHE_RELEASE
+ php3_printf("Apache Release: <b>%d</b><br>",APACHE_RELEASE);
+#endif
+ php3_printf("Apache API Version: <b>%d</b><br>",MODULE_MAGIC_NUMBER);
+ php3_printf("Hostname/port: <b>%s:%u</b><br>\n",serv->server_hostname,serv->port);
+#if !defined(WIN32) && !defined(WINNT)
+ php3_printf("User/Group: <b>%s(%d)/%d</b><br>\n",user_name,(int)user_id,(int)group_id);
+ php3_printf("Max Requests: <b>per child: %d &nbsp;&nbsp; keep alive: %s &nbsp;&nbsp; max per connection: %d</b><br>\n",max_requests_per_child,serv->keep_alive ? "on":"off", serv->keep_alive_max);
+#endif
+ php3_printf("Timeouts: <b>connection: %d &nbsp;&nbsp; keep-alive: %d</b><br>",serv->timeout,serv->keep_alive_timeout);
+#if !defined(WIN32) && !defined(WINNT)
+ php3_printf("Server Root: <b>%s</b><br>\n",server_root);
+
+ PUTS("Loaded modules: ");
+ for(modp = top_module; modp; modp = modp->next) {
+ strncpy(name, modp->name, sizeof(name) - 1);
+ if ((p = strrchr(name, '.'))) {
+ *p='\0'; /* Cut off ugly .c extensions on module names */
+ }
+ PUTS(name);
+ if (modp->next) {
+ PUTS(", ");
+ }
+ }
+#endif
+ PUTS("<br></td?</tr>\n");
+}
+
+/* This function is equivalent to <!--#include virtual...-->
+ * in mod_include. It does an Apache sub-request. It is useful
+ * for including CGI scripts or .shtml files, or anything else
+ * that you'd parse through Apache (for .phtml files, you'd probably
+ * want to use <?Include>. This only works when PHP is compiled
+ * as an Apache module, since it uses the Apache API for doing
+ * sub requests.
+ */
+/* {{{ proto int virtual(string filename)
+ Perform an Apache sub-request */
+void php3_virtual(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *filename;
+ request_rec *rr = NULL;
+TLS_VARS;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht,1,&filename) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_string(filename);
+
+ if (!(rr = sub_req_lookup_uri (filename->value.str.val, GLOBAL(php3_rqst)))) {
+ php3_error(E_WARNING, "Unable to include '%s' - URI lookup failed", filename->value.str.val);
+ if (rr) destroy_sub_req (rr);
+ RETURN_FALSE;
+ }
+
+ if (rr->status != 200) {
+ php3_error(E_WARNING, "Unable to include '%s' - error finding URI", filename->value.str.val);
+ if (rr) destroy_sub_req (rr);
+ RETURN_FALSE;
+ }
+
+ /* Cannot include another PHP file because of global conflicts */
+ if (rr->content_type &&
+ !strcmp(rr->content_type, PHP3_MIME_TYPE)) {
+ php3_error(E_WARNING, "Cannot include a PHP file "
+ "(use <code>&lt;?include \"%s\"&gt;</code> instead)", filename->value.str.val);
+ if (rr) destroy_sub_req (rr);
+ RETURN_FALSE;
+ }
+
+ if (run_sub_req(rr)) {
+ php3_error(E_WARNING, "Unable to include '%s' - request execution failed", filename->value.str.val);
+ if (rr) destroy_sub_req (rr);
+ RETURN_FALSE;
+ } else {
+ if (rr) destroy_sub_req (rr);
+ RETURN_TRUE;
+ }
+}
+/* }}} */
+
+/* {{{ proto array getallheaders(void)
+ Fetch all HTTP request headers */
+void php3_getallheaders(INTERNAL_FUNCTION_PARAMETERS)
+{
+ array_header *env_arr;
+ table_entry *tenv;
+ int i;
+
+ if (array_init(return_value) == FAILURE) {
+ RETURN_FALSE;
+ }
+ env_arr = table_elts(php3_rqst->headers_in);
+ tenv = (table_entry *)env_arr->elts;
+ for (i = 0; i < env_arr->nelts; ++i) {
+ if (!tenv[i].key ||
+ (PG(safe_mode) &&
+ !strncasecmp(tenv[i].key, "authorization", 13))) {
+ continue;
+ }
+ if (add_assoc_string(return_value, tenv[i].key,(tenv[i].val==NULL) ? "" : tenv[i].val, 1)==FAILURE) {
+ RETURN_FALSE;
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto class apache_lookup_uri(string URI)
+ Perform a partial request of the given URI to obtain information about it */
+void php3_apache_lookup_uri(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *filename;
+ request_rec *rr=NULL;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht,1,&filename) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_string(filename);
+
+ if(!(rr = sub_req_lookup_uri(filename->value.str.val, GLOBAL(php3_rqst)))) {
+ php3_error(E_WARNING, "URI lookup failed", filename->value.str.val);
+ RETURN_FALSE;
+ }
+ object_init(return_value);
+ add_property_long(return_value,"status",rr->status);
+ if (rr->the_request) {
+ add_property_string(return_value,"the_request",rr->the_request,1);
+ }
+ if (rr->status_line) {
+ add_property_string(return_value,"status_line",rr->status_line,1);
+ }
+ if (rr->method) {
+ add_property_string(return_value,"method",rr->method,1);
+ }
+ if (rr->content_type) {
+ add_property_string(return_value,"content_type",(char *)rr->content_type,1);
+ }
+ if (rr->handler) {
+ add_property_string(return_value,"handler",(char *)rr->handler,1);
+ }
+ if (rr->uri) {
+ add_property_string(return_value,"uri",rr->uri,1);
+ }
+ if (rr->filename) {
+ add_property_string(return_value,"filename",rr->filename,1);
+ }
+ if (rr->path_info) {
+ add_property_string(return_value,"path_info",rr->path_info,1);
+ }
+ if (rr->args) {
+ add_property_string(return_value,"args",rr->args,1);
+ }
+ if (rr->boundary) {
+ add_property_string(return_value,"boundary",rr->boundary,1);
+ }
+ add_property_long(return_value,"no_cache",rr->no_cache);
+ add_property_long(return_value,"no_local_copy",rr->no_local_copy);
+ add_property_long(return_value,"allowed",rr->allowed);
+ add_property_long(return_value,"sent_bodyct",rr->sent_bodyct);
+ add_property_long(return_value,"bytes_sent",rr->bytes_sent);
+ add_property_long(return_value,"byterange",rr->byterange);
+ add_property_long(return_value,"clength",rr->clength);
+
+#if MODULE_MAGIC_NUMBER >= 19980324
+ if (rr->unparsed_uri) {
+ add_property_string(return_value,"unparsed_uri",rr->unparsed_uri,1);
+ }
+ if(rr->mtime) {
+ add_property_long(return_value,"mtime",rr->mtime);
+ }
+#endif
+ if(rr->request_time) {
+ add_property_long(return_value,"request_time",rr->request_time);
+ }
+
+ destroy_sub_req(rr);
+}
+/* }}} */
+
+#if 0
+This function is most likely a bad idea. Just playing with it for now.
+
+void php3_apache_exec_uri(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *filename;
+ request_rec *rr=NULL;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht,1,&filename) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_string(filename);
+
+ if(!(rr = ap_sub_req_lookup_uri(filename->value.str.val, GLOBAL(php3_rqst)))) {
+ php3_error(E_WARNING, "URI lookup failed", filename->value.str.val);
+ RETURN_FALSE;
+ }
+ RETVAL_LONG(ap_run_sub_req(rr));
+ ap_destroy_sub_req(rr);
+}
+#endif
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/apache/config.m4 b/ext/apache/config.m4
new file mode 100644
index 0000000000..e878cdbb8b
--- /dev/null
+++ b/ext/apache/config.m4
@@ -0,0 +1,5 @@
+dnl $Id$
+
+if test -n "$APACHE_INCLUDE"; then
+ PHP_EXTENSION(apache)
+fi
diff --git a/ext/com/php3_COM.h b/ext/com/php3_COM.h
new file mode 100644
index 0000000000..ed9cc4f526
--- /dev/null
+++ b/ext/com/php3_COM.h
@@ -0,0 +1,22 @@
+#ifndef _PHP3_COM_H
+#define _PHP3_COM_H
+
+#if WIN32|WINNT
+
+extern int php3_minit_COM(INIT_FUNC_ARGS);
+extern int php3_mshutdown_COM(SHUTDOWN_FUNC_ARGS);
+extern void php3_COM_load(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_COM_invoke(INTERNAL_FUNCTION_PARAMETERS);
+
+PHP_FUNCTION(com_propget);
+PHP_FUNCTION(com_propput);
+extern php3_module_entry COM_module_entry;
+#define COM_module_ptr &COM_module_entry
+
+#else
+
+#define COM_module_ptr NULL
+
+#endif /* Win32|WINNT */
+
+#endif /* _PHP3_COM_H */
diff --git a/ext/hyperwave/DList.h b/ext/hyperwave/DList.h
new file mode 100644
index 0000000000..e574638e18
--- /dev/null
+++ b/ext/hyperwave/DList.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+*
+* Copyright (C) 1991 Kendall Bennett.
+* All rights reserved.
+*
+* Filename: $RCSfile$
+* Version: $Revision$
+*
+* Language: ANSI C
+* Environment: any
+*
+* Description: Header file for doubly linked list routines.
+*
+* $Id$
+*
+* Revision History:
+* -----------------
+*
+* $Log$
+* Revision 1.1.1.1 1999/04/07 21:03:20 zeev
+* PHP 4.0
+*
+* Revision 1.1.1.1 1999/03/17 04:29:11 andi
+* PHP4
+*
+* Revision 1.1.1.1 1998/12/21 07:56:22 andi
+* Trying to start the zend CVS tree
+*
+* Revision 1.2 1998/08/14 15:51:12 shane
+* Some work on getting hyperwave to work on windows. hg_comm needs a lot of work.
+*
+* Mainly, signals, fnctl, bzero, bcopy, etc are not portable functions. Most of this
+* will have to be rewriten for windows.
+*
+* Revision 1.1 1998/08/12 09:29:16 steinm
+* First version of Hyperwave module.
+*
+* Revision 1.5 91/12/31 19:40:54 kjb
+*
+* Modified include files directories.
+*
+* Revision 1.4 91/09/27 03:10:41 kjb
+* Added compatibility with C++.
+*
+* Revision 1.3 91/09/26 10:07:16 kjb
+* Took out extern references
+*
+* Revision 1.2 91/09/01 19:37:20 ROOT_DOS
+* Changed DLST_TAIL macro so that it returns a pointer to the REAL last
+* node of the list, not the dummy last node (l->z).
+*
+* Revision 1.1 91/09/01 18:38:23 ROOT_DOS
+* Initial revision
+*
+****************************************************************************/
+
+#ifndef __DLIST_H
+#define __DLIST_H
+
+#ifndef __DEBUG_H
+/*#include "debug.h"*/
+#endif
+
+/*---------------------- Macros and type definitions ----------------------*/
+
+typedef struct DLST_BUCKET {
+ struct DLST_BUCKET *next;
+ struct DLST_BUCKET *prev;
+ } DLST_BUCKET;
+
+typedef struct {
+ int count; /* Number of elements currently in list */
+ DLST_BUCKET *head; /* Pointer to head element of list */
+ DLST_BUCKET *z; /* Pointer to last node of list */
+ DLST_BUCKET hz[2]; /* Space for head and z nodes */
+ } DLIST;
+
+/* Return a pointer to the user space given the address of the header of
+ * a node.
+ */
+
+#define DLST_USERSPACE(h) ((void*)((DLST_BUCKET*)(h) + 1))
+
+/* Return a pointer to the header of a node, given the address of the
+ * user space.
+ */
+
+#define DLST_HEADER(n) ((DLST_BUCKET*)(n) - 1)
+
+/* Return a pointer to the user space of the list's head node. This user
+ * space does not actually exist, but it is useful to be able to address
+ * it to enable insertion at the start of the list.
+ */
+
+#define DLST_HEAD(l) DLST_USERSPACE((l)->head)
+
+/* Return a pointer to the user space of the last node in list. */
+
+#define DLST_TAIL(l) DLST_USERSPACE((l)->z->prev)
+
+/* Determine if a list is empty
+ */
+
+#define DLST_EMPTY(l) ((l)->count == 0)
+
+/*-------------------------- Function Prototypes --------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *dlst_newnode(int size);
+void dlst_freenode(void *node);
+DLIST *dlst_init(void);
+void dlst_kill(DLIST *l,void (*freeNode)(void *node));
+void dlst_insertafter(DLIST *l,void *node,void *after);
+void *dlst_deletenext(DLIST *l,void *node);
+void *dlst_first(DLIST *l);
+void *dlst_last(DLIST *l);
+void *dlst_next(void *prev);
+void *dlst_prev(void *next);
+void dlst_mergesort(DLIST *l,int (*cmp_func)(void*,void*));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ext/hyperwave/Makefile.am b/ext/hyperwave/Makefile.am
new file mode 100644
index 0000000000..c5be33e128
--- /dev/null
+++ b/ext/hyperwave/Makefile.am
@@ -0,0 +1,6 @@
+# $Id$
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_hyperwave.a
+libphpext_hyperwave_a_SOURCES=hw.c hg_comm.c
+
diff --git a/ext/hyperwave/config.h.stub b/ext/hyperwave/config.h.stub
new file mode 100644
index 0000000000..d8e8bf43ab
--- /dev/null
+++ b/ext/hyperwave/config.h.stub
@@ -0,0 +1,2 @@
+/* Define if you want Hyperwave support */
+#define HYPERWAVE 0
diff --git a/ext/hyperwave/config.m4 b/ext/hyperwave/config.m4
new file mode 100644
index 0000000000..ef48f24954
--- /dev/null
+++ b/ext/hyperwave/config.m4
@@ -0,0 +1,18 @@
+dnl $Id$
+
+AC_MSG_CHECKING(for Hyperwave support)
+AC_ARG_WITH(hyperwave,
+[ --with-hyperwave Include Hyperwave support],
+[
+ if test "$withval" != "no"; then
+ AC_DEFINE(HYPERWAVE,1)
+ AC_MSG_RESULT(yes)
+ PHP_EXTENSION(hyperwave)
+ else
+ AC_DEFINE(HYPERWAVE,0)
+ AC_MSG_RESULT(no)
+ fi
+],[
+ AC_DEFINE(HYPERWAVE,0)
+ AC_MSG_RESULT(no)
+])
diff --git a/ext/hyperwave/dlist.c b/ext/hyperwave/dlist.c
new file mode 100644
index 0000000000..27c1305664
--- /dev/null
+++ b/ext/hyperwave/dlist.c
@@ -0,0 +1,410 @@
+/****************************************************************************
+*
+* Copyright (C) 1991 Kendall Bennett.
+* All rights reserved.
+*
+* Filename: $RCSfile$
+* Version: $Revision$
+*
+* Language: ANSI C
+* Environment: any
+*
+* Description: Module to implement doubly linked lists. Includes a routine
+* to peform a mergesort on the doubly linked list.
+*
+* $Id$
+*
+* Revision History:
+* -----------------
+*
+* $Log$
+* Revision 1.1.1.1 1999/04/07 21:03:31 zeev
+* PHP 4.0
+*
+* Revision 1.1.1.1 1999/03/17 04:29:11 andi
+* PHP4
+*
+* Revision 1.1.1.1 1998/12/21 07:56:22 andi
+* Trying to start the zend CVS tree
+*
+* Revision 1.1 1998/08/12 09:29:16 steinm
+* First version of Hyperwave module.
+*
+* Revision 1.5 91/12/31 19:39:49 kjb
+* Modified include file directories.
+*
+* Revision 1.4 91/10/28 03:16:39 kjb
+* Ported to the Iris.
+*
+* Revision 1.3 91/09/27 03:09:18 kjb
+* Cosmetic change.
+*
+* Revision 1.2 91/09/03 18:27:42 ROOT_DOS
+* Ported to UNIX.
+*
+* Revision 1.1 91/09/01 18:35:23 ROOT_DOS
+* Initial revision
+*
+****************************************************************************/
+
+#ifndef MSVC5
+#include "config.h"
+#endif
+
+#if HYPERWAVE
+
+#include <stdio.h>
+#include <malloc.h>
+#include <signal.h>
+#include "debug.h"
+#include "DList.h"
+
+PUBLIC void *dlst_newnode(int size)
+/****************************************************************************
+*
+* Function: dlst_newnode
+* Parameters: size - Amount of memory to allocate for node
+* Returns: Pointer to the allocated node's user space.
+*
+* Description: Allocates the memory required for a node, adding a small
+* header at the start of the node. We return a reference to
+* the user space of the node, as if it had been allocated via
+* malloc().
+*
+****************************************************************************/
+{
+ DLST_BUCKET *node;
+
+ if ( !(node = (DLST_BUCKET*)malloc(size + sizeof(DLST_BUCKET))) ) {
+ fprintf(stderr,"Not enough memory to allocate list node.\n");
+/* raise(SIGABRT);*/
+ return NULL;
+ }
+
+ return DLST_USERSPACE(node); /* Return pointer to user space */
+}
+
+PUBLIC void dlst_freenode(void *node)
+/****************************************************************************
+*
+* Function: dlst_freenode
+* Parameters: node - Node to free.
+*
+* Description: Frees a node previously allocated with lst_newnode().
+*
+****************************************************************************/
+{
+ free(DLST_HEADER(node));
+}
+
+PUBLIC DLIST *dlst_init(void)
+/****************************************************************************
+*
+* Function: dlst_init
+* Returns: Pointer to a newly created list.
+*
+* Description: Initialises a list and returns a pointer to it.
+*
+****************************************************************************/
+{
+ DLIST *l;
+
+ if ((l = (DLIST*)malloc(sizeof(DLIST))) != NULL) {
+ l->count = 0;
+ l->head = &(l->hz[0]);
+ l->z = &(l->hz[1]);
+ l->head->next = l->z->next = l->z;
+ l->z->prev = l->head->prev = l->head;
+ }
+ else {
+ fprintf(stderr,"Insufficient memory to allocate list\n");
+ /*raise(SIGABRT);*/
+ return NULL;
+ }
+
+ return l;
+}
+
+PUBLIC void dlst_kill(DLIST *l,void (*freeNode)(void *node))
+/****************************************************************************
+*
+* Function: dlst_kill
+* Parameters: l - List to kill
+* freeNode - Pointer to user routine to free a node
+*
+* Description: Kills the list l, by deleting all of the elements contained
+* within the list one by one and then deleting the list
+* itself. Note that we call the user supplied routine
+* (*freeNode)() to free each list node. This allows the user
+* program to perform any extra processing needed to kill each
+* node (if each node contains pointers to other items on the
+* heap for example). If no extra processing is required, just
+* pass the address of dlst_freenode(), ie:
+*
+* dlst_kill(myList,dlst_freenode);
+*
+****************************************************************************/
+{
+ DLST_BUCKET *n,*p;
+
+ n = l->head->next;
+ while (n != l->z) { /* Free all nodes in list */
+ p = n;
+ n = n->next;
+ (*freeNode)(DLST_USERSPACE(p));
+ }
+ free(l); /* Free the list itself */
+}
+
+PUBLIC void dlst_insertafter(DLIST *l,void *node,void *after)
+/****************************************************************************
+*
+* Function: lst_insertafter
+* Parameters: l - List to insert node into
+* node - Pointer to user space of node to insert
+* after - Pointer to user space of node to insert node after
+*
+* Description: Inserts a new node into the list after the node 'after'. To
+* insert a new node at the beginning of the list, user the
+* macro DLST_HEAD in place of 'after'. ie:
+*
+* dlst_insertafter(mylist,node,DLST_HEAD(mylist));
+*
+****************************************************************************/
+{
+ DLST_BUCKET *n = DLST_HEADER(node),*a = DLST_HEADER(after);
+
+ n->next = a->next;
+ a->next = n;
+ n->prev = a;
+ n->next->prev = n;
+ l->count++;
+}
+
+PUBLIC void *dlst_deletenext(DLIST *l,void *node)
+/****************************************************************************
+*
+* Function: lst_deletenext
+* Parameters: l - List to delete node from.
+* node - Node to delete the next node from
+* Returns: Pointer to the deleted node's userspace.
+*
+* Description: Removes the node AFTER 'node' from the list l.
+*
+****************************************************************************/
+{
+ DLST_BUCKET *n = DLST_HEADER(node);
+
+ node = DLST_USERSPACE(n->next);
+ n->next->next->prev = n;
+ n->next = n->next->next;
+ l->count--;
+ return node;
+}
+
+PUBLIC void *dlst_first(DLIST *l)
+/****************************************************************************
+*
+* Function: dlst_first
+* Parameters: l - List to obtain first node from
+* Returns: Pointer to first node in list, NULL if list is empty.
+*
+* Description: Returns a pointer to the user space of the first node in
+* the list. If the list is empty, we return NULL.
+*
+****************************************************************************/
+{
+ DLST_BUCKET *n;
+
+ n = l->head->next;
+ return (n == l->z ? NULL : DLST_USERSPACE(n));
+}
+
+PUBLIC void *dlst_last(DLIST *l)
+/****************************************************************************
+*
+* Function: dlst_last
+* Parameters: l - List to obtain last node from
+* Returns: Pointer to last node in list, NULL if list is empty.
+*
+* Description: Returns a pointer to the user space of the last node in
+* the list. If the list is empty, we return NULL.
+*
+****************************************************************************/
+{
+ DLST_BUCKET *n;
+
+ n = l->z->prev;
+ return (n == l->head ? NULL : DLST_USERSPACE(n));
+}
+
+PUBLIC void *dlst_next(void *prev)
+/****************************************************************************
+*
+* Function: dlst_next
+* Parameters: prev - Previous node in list to obtain next node from
+* Returns: Pointer to the next node in the list, NULL at end of list.
+*
+* Description: Returns a pointer to the user space of the next node in the
+* list given a pointer to the user space of the previous node.
+* If we have reached the end of the list, we return NULL. The
+* end of the list is detected when the next pointer of a node
+* points back to itself, as does the dummy last node's next
+* pointer. This enables us to detect the end of the list
+* without needed access to the list data structure itself.
+*
+* NOTE: We do no checking to ensure that 'prev' is NOT a
+* NULL pointer.
+*
+****************************************************************************/
+{
+ DLST_BUCKET *n = DLST_HEADER(prev);
+
+ n = n->next;
+ return (n == n->next ? NULL : DLST_USERSPACE(n));
+}
+
+PUBLIC void *dlst_prev(void *next)
+/****************************************************************************
+*
+* Function: dlst_prev
+* Parameters: next - Next node in list to obtain previous node from
+* Returns: Pointer to the previous node in the list, NULL at start list.
+*
+* Description: Returns a pointer to the user space of the prev node in the
+* list given a pointer to the user space of the next node.
+* If we have reached the start of the list, we return NULL. The
+* start of the list is detected when the prev pointer of a node
+* points back to itself, as does the dummy head node's prev
+* pointer. This enables us to detect the start of the list
+* without needed access to the list data structure itself.
+*
+* NOTE: We do no checking to ensure that 'next' is NOT a
+* NULL pointer.
+*
+****************************************************************************/
+{
+ DLST_BUCKET *n = DLST_HEADER(next);
+
+ n = n->prev;
+ return (n == n->prev ? NULL : DLST_USERSPACE(n));
+}
+
+/* Static globals required by merge() */
+
+static DLST_BUCKET *z;
+static int (*cmp)(void*,void*);
+
+PRIVATE DLST_BUCKET *merge(DLST_BUCKET *a,DLST_BUCKET *b,DLST_BUCKET **end)
+/****************************************************************************
+*
+* Function: merge
+* Parameters: a,b - Sublist's to merge
+* Returns: Pointer to the merged sublists.
+*
+* Description: Merges two sorted lists of nodes together into a single
+* sorted list.
+*
+****************************************************************************/
+{
+ DLST_BUCKET *c;
+
+ /* Go through the lists, merging them together in sorted order */
+
+ c = z;
+ while (a != z && b != z) {
+ if ((*cmp)(DLST_USERSPACE(a),DLST_USERSPACE(b)) <= 0) {
+ c->next = a; c = a; a = a->next;
+ }
+ else {
+ c->next = b; c = b; b = b->next;
+ }
+ };
+
+ /* If one of the lists is not exhausted, then re-attach it to the end
+ * of the newly merged list
+ */
+
+ if (a != z) c->next = a;
+ if (b != z) c->next = b;
+
+ /* Set *end to point to the end of the newly merged list */
+
+ while (c->next != z) c = c->next;
+ *end = c;
+
+ /* Determine the start of the merged lists, and reset z to point to
+ * itself
+ */
+
+ c = z->next; z->next = z;
+ return c;
+}
+
+PUBLIC void dlst_mergesort(DLIST *l,int (*cmp_func)(void*,void*))
+/****************************************************************************
+*
+* Function: dlst_mergesort
+* Parameters: l - List to merge sort
+* cmp_func - Function to compare two user spaces
+*
+* Description: Mergesort's all the nodes in the list. 'cmp' must point to
+* a comparison function that can compare the user spaces of
+* two different nodes. 'cmp' should work the same as
+* strcmp(), in terms of the values it returns. Rather than
+* waste processing time keeping the previous pointers up to
+* date while performing the mergesort, we simply run through
+* the list at the end of the sort to fix the previous pointers.
+*
+****************************************************************************/
+{
+ int i,N;
+ DLST_BUCKET *a,*b; /* Pointers to sublists to merge */
+ DLST_BUCKET *c; /* Pointer to end of sorted sublists */
+ DLST_BUCKET *head; /* Pointer to dummy head node for list */
+ DLST_BUCKET *todo; /* Pointer to sublists yet to be sorted */
+ DLST_BUCKET *t; /* Temporary */
+
+ /* Set up globals required by merge() and pointer to head */
+
+ z = l->z; cmp = cmp_func; head = l->head;
+
+ for (N = 1,a = z; a != head->next; N = N + N) {
+ todo = head->next; c = head;
+ while (todo != z) {
+
+ /* Build first sublist to be merged, and splice from main list
+ */
+
+ a = t = todo;
+ for (i = 1; i < N; i++) t = t->next;
+ b = t->next; t->next = z; t = b;
+
+ /* Build second sublist to be merged and splice from main list
+ */
+
+ for (i = 1; i < N; i++) t = t->next;
+ todo = t->next; t->next = z;
+
+ /* Merge the two sublists created, and set 'c' to point to the
+ * end of the newly merged sublists.
+ */
+
+ c->next = merge(a,b,&t); c = t;
+ }
+ }
+
+ /* Fix the previous pointers for the list */
+
+ a = b = l->head;
+ b = b->next;
+ while (1) {
+ b->prev = a;
+ if (b == z)
+ break;
+ a = a->next;
+ b = b->next;
+ }
+}
+
+#endif
diff --git a/ext/hyperwave/hg_comm.c b/ext/hyperwave/hg_comm.c
new file mode 100644
index 0000000000..171ea9e778
--- /dev/null
+++ b/ext/hyperwave/hg_comm.c
@@ -0,0 +1,4701 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of the GNU General Public License as published by |
+ | the Free Software Foundation; either version 2 of the License, or |
+ | (at your option) any later version. |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU General Public License |
+ | along with this program; if not, write to the Free Software |
+ | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
+ +----------------------------------------------------------------------+
+ | Authors: Uwe Steinmann |
+ | |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+/* #define HW_DEBUG */
+
+#include <stdlib.h>
+
+#if WIN32|WINNT
+#include "win95nt.h"
+#else
+#include "config.h"
+#endif
+
+#if HYPERWAVE
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#if WIN32|WINNT
+# include <winsock2.h>
+# define EWOULDBLOCK WSAEWOULDBLOCK
+# define ETIMEDOUT WSAETIMEDOUT
+# define bcopy memcpy
+# define bzero(a,b) memset(a,0,b)
+#else
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <netdb.h>
+# include <unistd.h>
+# include <sys/param.h>
+#endif
+#include <fcntl.h>
+#include <errno.h>
+#include <alloc.h>
+#include "hg_comm.h"
+#include "DList.h"
+#include "php.h"
+#include "head.h"
+
+static int set_nonblocking(int fd);
+static int set_blocking(int fd);
+
+static int hg_read_exact(int sockfd, char *buf, int size);
+static int hg_read(int sockfd, char *buf, int size);
+static int hg_write(int sockfd, char *buf, int size);
+
+static int send_hg_msg(int sockfd, hg_msg *msg, int length);
+static void build_msg_header(hg_msg *msg, int length, int version_msgid, int msg_type);
+static char *build_msg_int(char *buf, int val);
+static char *build_msg_str(char *buf, char *str);
+static int swap(int val);
+
+
+int version = VERSION;
+/* F_DISTRIBUTED has the effect that all object ids are
+ virtual. This means whenever an object is requested a
+ new id is generated for this session. Wavemaster and
+ Harmony set this flag. How do I know? tcpdump tells
+ a lot if investigate the output.
+ int version = VERSION | F_DISTRIBUTED; */
+/* int version = VERSION | F_DISTRIBUTED | F_COMPRESSED; */
+static int msgid = 1;
+static int sock_flags = -1;
+static int non_blocking = 0;
+static int swap_on = 0;
+static int rtimeout = 40;
+static int wtimeout = 40;
+static int lowerror = 0;
+
+/***********************************************************************
+* Function fnInsStr() *
+* *
+* Insert string in string at position. The old string will be freed *
+* with efree!!! The new string is allocated with malloc. *
+* Parameter: string *str: string in which insstr is to be inserted *
+* int pos: Position where string is to inserted (0=first) *
+* string *insstr: string to be inserted *
+* Return: pointer to new string or NULL. If NULL is returned the *
+* memory for the old string has not been freed. *
+***********************************************************************/
+char *fnInsStr(char *str, int pos, char *insstr)
+{
+ char *newstr, *ptr;
+
+ if((str == NULL) || (insstr == NULL))
+ return NULL;
+ if(pos > (int)strlen(str))
+ return NULL;
+
+ if(insstr[0] == '\0')
+ return str;
+
+ if(NULL == (newstr = malloc(strlen(str) + strlen(insstr) + 1))) {
+ lowerror = LE_MALLOC;
+ return NULL;
+ }
+
+ ptr = newstr;
+ memcpy(newstr, str, pos);
+ ptr += pos;
+ strcpy(ptr, insstr);
+ ptr += strlen(insstr);
+ strcpy(ptr, str+pos);
+
+ free(str);
+ return newstr;
+}
+
+/***********************************************************************
+* Function fnAddAnchor() *
+* *
+* Inserts new anchor into anchor list. *
+* Parameter: DLIST pList: Anchor list *
+* int objectID: object ID of Anchor *
+* int start: start position *
+* int end: end position *
+* Return: Pointer to new anchor, NULL if error *
+***********************************************************************/
+ANCHOR *fnAddAnchor(DLIST *pAnchorList,
+ int objectID,
+ int start, int end)
+{
+ ANCHOR *cur_ptr;
+
+ if((cur_ptr = (ANCHOR *) dlst_newnode(sizeof(ANCHOR))) == NULL) {
+ return NULL;
+ }
+
+ memset(cur_ptr, 0, sizeof(ANCHOR));
+ cur_ptr->start = start;
+ cur_ptr->end = end;
+ cur_ptr->id = objectID;
+ cur_ptr->destdocname = NULL;
+ cur_ptr->nameanchor = NULL;
+ cur_ptr->link = NULL;
+ cur_ptr->tagattr = NULL;
+ cur_ptr->htmlattr = NULL;
+ cur_ptr->codebase = NULL;
+ cur_ptr->code = NULL;
+ cur_ptr->keyword = NULL;
+ cur_ptr->fragment = NULL;
+
+ dlst_insertafter(pAnchorList, cur_ptr, DLST_HEAD(pAnchorList));
+
+ return(cur_ptr);
+}
+
+/***********************************************************************
+* Function fnDeleteAnchor() *
+* *
+* Inserts new anchor into anchor list. *
+* Parameter: ptr: pointer to node *
+* Return: void *
+***********************************************************************/
+void fnDeleteAnchor(ANCHOR *ptr)
+{
+
+ if(ptr->destdocname) efree(ptr->destdocname);
+ if(ptr->nameanchor) efree(ptr->nameanchor);
+ if(ptr->link) efree(ptr->link);
+ if(ptr->tagattr) efree(ptr->tagattr);
+ if(ptr->htmlattr) efree(ptr->htmlattr);
+ if(ptr->codebase) efree(ptr->codebase);
+ if(ptr->code) efree(ptr->code);
+ if(ptr->keyword) efree(ptr->keyword);
+ if(ptr->fragment) efree(ptr->fragment);
+
+ dlst_freenode(ptr);
+}
+
+/***********************************************************************
+* Function fnCmpAnchors() *
+* *
+* Compares to Anchors by its start position *
+* Parameter: ANCHOR a1: First Anchor *
+* ANCHOR a2: Second Anchor *
+* Return: As strcmp *
+***********************************************************************/
+int fnCmpAnchors(ANCHOR *a1, ANCHOR *a2)
+{
+ if(a1->start < a2->start)
+ return -1;
+ if(a1->start == a2->start) {
+ /* It's importent to check this case as well, because a link with
+ a bigger end has to be inserted first.
+ */
+ if(a1->end < a2->end)
+ return -1;
+ /* If both start and end are equal (yes, it is possible)
+ we will Src Anchor before a Dest anchor. There has been
+ a case where an IMG was surrounded by a NAME which was
+ surrounded by a HREF. In such a case the HREF doesn't
+ work.
+ */
+ if(a1->end == a2->end) {
+ if(a1->tanchor > a2->tanchor)
+ return -1;
+ }
+ }
+
+ return 1;
+}
+
+/***********************************************************************
+* Function fnCreateAnchorList() *
+* *
+* Returns a list of Anchors converted from an object record *
+* Parameter: char **anchors: object records of anchors *
+* char **dest: object records of destinations *
+* int ancount: number of anchors *
+* Return: List of Anchors, NULL if error *
+***********************************************************************/
+DLIST *fnCreateAnchorList(char **anchors, char **docofanchorrec, char **reldestrec, int ancount, int anchormode)
+{
+ int start, end, i, destid, anchordestid, objectID;
+ ANCHOR *cur_ptr = NULL;
+ DLIST *pAnchorList = dlst_init();
+
+ for(i=ancount-1; i>=0; i--) {
+ char *object = NULL;
+ char *docofanchorptr = NULL;
+ char *reldestptr = NULL;
+ char *str, *str1, link[200];
+
+ if(NULL != anchors[i]) {
+ object = anchors[i];
+ docofanchorptr = docofanchorrec[i];
+ reldestptr = reldestrec[i];
+
+ /* Determine Position. Doesn't matter if Src or Dest */
+ str = strstr(object, "Position");
+ str += 9;
+ sscanf(str, "0x%X 0x%X", &start, &end);
+
+ /* Determine ObjectID */
+ objectID = 0;
+ if(NULL != (str = strstr(object, "ObjectID"))) {
+ str += 9;
+ sscanf(str, "0x%X", &objectID);
+ }
+
+ cur_ptr = fnAddAnchor(pAnchorList, objectID, start, end);
+
+ /* Determine Type of Anchor */
+ str = strstr(object, "TAnchor");
+ str += 8;
+ if(*str == 'S') {
+ char destdocname[200];
+ char nameanchor[200];
+ cur_ptr->tanchor = 1;
+
+ cur_ptr->destdocname = NULL;
+ if(NULL != (str = strstr(object, "Dest"))) {
+ char *tempptr;
+
+ /* No need to care about the value of Dest, because we take the info
+ from docofanchorptr.
+ Since the anchor has a destination there are two possibilities.
+ 1. The destination is an anchor or
+ 2. or the destination is a document already.
+ In both cases docofanchorptr has the proper info because GETDOCBYANCHOR
+ is such a nice message.
+ */
+ switch(anchormode) {
+ case 0:
+ tempptr = docofanchorptr;
+ break;
+ default:
+ tempptr = reldestptr;
+ }
+ if(NULL != tempptr) {
+ /* It's always nice to deal with names, so let's first check
+ for a name. If there is none we take the ObjectID.
+ */
+ if(NULL != (str = strstr(tempptr, "Name="))) {
+ str += 5;
+ } else if(NULL != (str = strstr(tempptr, "ObjectID="))) {
+ str += 9;
+ }
+ if(sscanf(str, "%s\n", destdocname)) {
+ cur_ptr->destdocname = estrdup(destdocname);
+ }
+ destid = 0;
+ if(NULL != (str = strstr(tempptr, "ObjectID="))) {
+ str += 9;
+ sscanf(str, "0x%X", &destid);
+ }
+ }
+ }
+
+ /* Get the Id of the anchor destination and the document id that belongs
+ to that anchor. We need that soon in order to determine if the anchor
+ points to a document or a dest anchor in a document.
+ */
+ anchordestid = 0;
+ if(NULL != (str = strstr(object, "Dest="))) {
+ str += 5;
+ sscanf(str, "0x%X", &anchordestid);
+ }
+
+ /* if anchordestid != destid then the destination is an anchor in a document whose
+ name (objectID) is already in destdocname. We will have to extend the link
+ by '#...'
+ */
+ cur_ptr->nameanchor = NULL;
+ if(anchordestid != destid) {
+ if(NULL != (str = strstr(object, "Dest="))) {
+ str += 5;
+ if(sscanf(str, "%s\n", nameanchor))
+ cur_ptr->nameanchor = estrdup(nameanchor);
+ }
+ }
+
+ if(!cur_ptr->destdocname) {
+ cur_ptr->link = NULL;
+ if(NULL != (str = strstr(object, "Hint=URL:"))) {
+ str += 9;
+ if(sscanf(str, "%s\n", link))
+ cur_ptr->link = estrdup(link);
+ } else if(NULL != (str = strstr(object, "Hint="))) {
+ str += 5;
+ if(sscanf(str, "%s\n", link))
+ cur_ptr->link = estrdup(link);
+ }
+ }
+
+ cur_ptr->fragment = NULL;
+ if(NULL != (str = strstr(object, "Fragment="))) {
+ str += 9;
+ if(sscanf(str, "%s\n", link))
+ cur_ptr->fragment = estrdup(link);
+ }
+
+ cur_ptr->htmlattr = NULL;
+ if(NULL != (str = strstr(object, "HtmlAttr="))) {
+ str += 9;
+ str1 = str;
+ while((*str1 != '\n') && (*str1 != '\0'))
+ str1++;
+ cur_ptr->htmlattr = emalloc(str1 - str + 1);
+ strncpy(cur_ptr->htmlattr, str, str1 - str);
+ cur_ptr->htmlattr[str1 - str] = '\0';
+ }
+
+ if(NULL != (str = strstr(object, "LinkType="))) {
+ str += 9;
+ if(strncmp(str, "background", 10) == 0)
+ cur_ptr->linktype=HW_BACKGROUND_LINK;
+ else
+ if(strncmp(str, "intag", 5) == 0) {
+ cur_ptr->linktype=HW_INTAG_LINK;
+ cur_ptr->tagattr = NULL;
+ if(NULL != (str = strstr(object, "TagAttr="))) {
+ str += 8;
+ str1 = str;
+ while((*str1 != '\n') && (*str1 != '\0'))
+ str1++;
+ cur_ptr->tagattr = emalloc(str1 - str + 1);
+ memcpy(cur_ptr->tagattr, str, str1 - str);
+ cur_ptr->tagattr[str1 - str] = '\0';
+ }
+ } else
+ if(strncmp(str, "applet", 6) == 0) {
+ cur_ptr->linktype=HW_APPLET_LINK;
+ cur_ptr->codebase = NULL;
+ if(NULL != (str = strstr(object, "CodeBase="))) {
+ str += 9;
+ str1 = str;
+ while((*str1 != '\n') && (*str1 != '\0'))
+ str1++;
+ cur_ptr->codebase = emalloc(str1 - str + 1);
+ memcpy(cur_ptr->codebase, str, str1 - str);
+ cur_ptr->codebase[str1 - str] = '\0';
+ }
+ cur_ptr->code = NULL;
+ if(NULL != (str = strstr(object, "Code="))) {
+ str += 5;
+ str1 = str;
+ while((*str1 != '\n') && (*str1 != '\0'))
+ str1++;
+ cur_ptr->code = emalloc(str1 - str + 1);
+ memcpy(cur_ptr->code, str, str1 - str);
+ cur_ptr->code[str1 - str] = '\0';
+ }
+ } else
+ cur_ptr->linktype=HW_DEFAULT_LINK;
+ } else
+ cur_ptr->linktype=HW_DEFAULT_LINK;
+
+ } else { /* Destination Anchor */
+ char nameanchor[200];
+
+ cur_ptr->tanchor = 2;
+ cur_ptr->link = NULL;
+
+ /* Here is the only additional info for the name attribute */
+ cur_ptr->nameanchor = NULL;
+ if(NULL != (str = strstr(object, "ObjectID="))) {
+ str += 9;
+ if(sscanf(str, "%s\n", nameanchor))
+ cur_ptr->nameanchor = estrdup(nameanchor);
+ }
+
+ cur_ptr->keyword = NULL;
+ if(NULL != (str = strstr(object, "Keyword="))) {
+ str += 8;
+ if(sscanf(str, "%s\n", nameanchor))
+ cur_ptr->keyword = estrdup(nameanchor);
+ }
+
+ }
+
+ efree(anchors[i]);
+ if(docofanchorrec[i]) efree(docofanchorrec[i]);
+ if(reldestrec[i]) efree(reldestrec[i]);
+ }
+ }
+ return pAnchorList;
+}
+
+/***********************************************************************
+* Function fnInsAnchorsIntoText() *
+* *
+* Returns the text document with all anchors inserted form list *
+* Parameter: char *text: text without anchors *
+* DList *pAnchorList: list of anchors *
+* Return: Text with anchors *
+***********************************************************************/
+char *fnInsAnchorsIntoText(char *text, DLIST *pAnchorList, char **bodytag) {
+ ANCHOR *cur_ptr;
+ char bgstr[100], istr[200];
+ char *scriptname;
+ char *newtext;
+ int offset = 0;
+ int laststart=0;
+
+#if APACHE
+ {
+ int j;
+ array_header *arr = table_elts(GLOBAL(php3_rqst)->subprocess_env);
+ table_entry *elts = (table_entry *)arr->elts;
+
+ for (j=0; j < arr->nelts; j++) {
+ if(0 == strcmp(elts[j].key, "SCRIPT_NAME"))
+ break;
+ }
+ scriptname = elts[j].val;
+ }
+#else
+ scriptname = getenv("SCRIPT_FILENAME");
+#endif
+
+ newtext = text;
+ bgstr[0] = '\0';
+ dlst_mergesort(pAnchorList, fnCmpAnchors);
+
+ cur_ptr = (ANCHOR *) dlst_last(pAnchorList);
+ while(NULL != cur_ptr) {
+ istr[0] = '\0';
+ if(cur_ptr->tanchor == 1) { /* Src Anchor */
+ if(laststart >= cur_ptr->end)
+ offset = 0;
+ if((cur_ptr->link != NULL) && (cur_ptr->link[0] != '\0')) {
+ /* The link is only set if the Link points to an external document */
+ switch(cur_ptr->linktype) {
+ case HW_BACKGROUND_LINK:
+ sprintf(bgstr, " background='%s'", cur_ptr->link);
+ break;
+ case HW_INTAG_LINK:
+ sprintf(istr, " %s='%s' start=%d", cur_ptr->tagattr, cur_ptr->link, cur_ptr->start);
+ offset -= 4; /* because there is no closing tag </A> */
+/* laststart = cur_ptr->start; */
+ break;
+ case HW_APPLET_LINK:
+ if(cur_ptr->codebase)
+ sprintf(istr, " CODEBASE='%s' CODE='%s'", cur_ptr->codebase, cur_ptr->code);
+ else
+ sprintf(istr, " CODEBASE='/' CODE='%s'", cur_ptr->code);
+ break;
+ default:
+ newtext = fnInsStr(newtext, cur_ptr->end+offset, "</A>");
+ sprintf(istr, "<A HREF='%s' %s offset=%d>", cur_ptr->link, cur_ptr->htmlattr == NULL ? "" : cur_ptr->htmlattr, offset);
+ }
+ } else {
+ switch(cur_ptr->linktype) {
+ case HW_BACKGROUND_LINK:
+ if(NULL != cur_ptr->destdocname)
+ sprintf(bgstr, " background='%s/%s'", scriptname == NULL ? "" : scriptname, cur_ptr->destdocname);
+ else
+ sprintf(bgstr, "");
+ break;
+ case HW_INTAG_LINK:
+ if(cur_ptr->fragment)
+/* sprintf(istr, " %s='%s/%s#%s'", cur_ptr->tagattr, scriptname == NULL ? "." : scriptname, cur_ptr->destdocname, cur_ptr->fragment);*/
+ sprintf(istr, " %s='#%s'", cur_ptr->tagattr, cur_ptr->fragment);
+ else
+ sprintf(istr, " %s='%s/%s'", cur_ptr->tagattr, scriptname == NULL ? "." : scriptname, cur_ptr->destdocname);
+ offset -= 4; /* because there is no closing tag </A> */
+/* laststart = cur_ptr->start; */
+ break;
+ case HW_APPLET_LINK:
+ if(cur_ptr->codebase)
+/* sprintf(istr, " CODEBASE='%s%s' CODE='%s'", scriptname == NULL ? "" : scriptname, cur_ptr->codebase, cur_ptr->code); */
+ sprintf(istr, " CODEBASE='%s' CODE='%s'", cur_ptr->codebase, cur_ptr->code);
+ else
+ sprintf(istr, " CODEBASE='/' CODE='%s'", cur_ptr->code);
+ break;
+ default:
+ newtext = fnInsStr(newtext, cur_ptr->end+offset, "</A>");
+
+ if(cur_ptr->nameanchor)
+ sprintf(istr, "<A HREF='%s/%s#%s' %s>", scriptname == NULL ? "schade" : scriptname, cur_ptr->destdocname, cur_ptr->nameanchor, cur_ptr->htmlattr == NULL ? "" : cur_ptr->htmlattr);
+ else
+ if(cur_ptr->fragment)
+ sprintf(istr, "<A HREF='%s/%s#%s' %s>", scriptname == NULL ? "" : scriptname, cur_ptr->destdocname, cur_ptr->fragment, cur_ptr->htmlattr == NULL ? "" : cur_ptr->htmlattr);
+ else
+ sprintf(istr, "<A HREF='%s/%s' %s offset=%d>", scriptname == NULL ? "" : scriptname, cur_ptr->destdocname, cur_ptr->htmlattr == NULL ? "" : cur_ptr->htmlattr, offset);
+ }
+ }
+ newtext = fnInsStr(newtext, cur_ptr->start, istr);
+ /* In case there are several TAGS nested, we accumulate the offset
+ You wonder what the 4 means? It's the length of </A> */
+ offset += strlen(istr) + 4;
+ laststart = cur_ptr->start;
+ } else {
+ if(laststart >= cur_ptr->end)
+ offset = 0;
+ newtext = fnInsStr(newtext, cur_ptr->end+offset, "</a>");
+
+ /* If we have a keyword, we assume we had a fragment which has been used
+ instead of the destdocname
+ */
+ if(cur_ptr->keyword)
+ sprintf(istr, "<A NAME='%s'>", cur_ptr->keyword);
+ else if(cur_ptr->nameanchor)
+ sprintf(istr, "<A NAME='%s'>", cur_ptr->nameanchor);
+ newtext = fnInsStr(newtext, cur_ptr->start, istr);
+ /* In case there are several TAGS nested, we accumulate the offset
+ You wonder what the 4 means? It's the length of </A> */
+ offset += strlen(istr) + 4;
+ laststart = cur_ptr->start;
+ }
+ cur_ptr = (ANCHOR *) dlst_prev(cur_ptr);
+ }
+ sprintf(istr, "<BODY %s>", bgstr);
+ *bodytag = estrdup(istr);
+ return(newtext);
+}
+
+/***********************************************************************
+* Function fnAttributeValue() *
+* *
+* Returns the value of an attribute *
+* Parameter: char *object: object record *
+* char *attrname: attribute name *
+* Return: char*: attribute value, NULL if name not found *
+***********************************************************************/
+char *fnAttributeValue(char *object, char *attrname)
+{
+ char *str, *str1, *attrvalue;
+ int len;
+
+ str = strstr(object, attrname);
+ if(NULL == str)
+ return(NULL);
+ str += strlen(attrname);
+ str++;
+ str1 = str;
+ while((*str1 != '\0') && (*str1 != '\n'))
+ str1++;
+ len = str1 - str;
+ if(NULL == (attrvalue = emalloc(len+1))) {
+ lowerror = LE_MALLOC;
+ return NULL;
+ }
+ memcpy(attrvalue, str, len);
+ attrvalue[len] = '\0';
+ return(attrvalue);
+}
+
+/***********************************************************************
+* Function fnAttributeCompare() *
+* *
+* Checks if an attribute in an objrec has a certain value *
+* Parameter: char *object: object record *
+* char *attrname: attribute name *
+* char *value: value of attribute *
+* Return: char*: as strcmp *
+***********************************************************************/
+int fnAttributeCompare(char *object, char *attrname, char *value)
+{
+ char *str, *str1;
+ int len;
+
+ if((NULL == object) || (NULL == attrname) || (NULL == value))
+ return -2;
+
+ /* Find the attribute Name and make sure it is followed by
+ a '=' sign and preceded by a '\n';
+ */
+ str = strstr(object, attrname);
+ if((NULL == str) ||
+ (str[strlen(attrname)] != '=') ||
+ (str[-1] != '\n')) {
+ return(-2);
+ }
+ str += strlen(attrname); /* skip the attribute name */
+ str++; /* skip the equal sign */
+
+ /* Search for end of attribute value */
+ str1 = str;
+ while((*str1 != '\0') && (*str1 != '\n'))
+ str1++;
+ len = str1 - str;
+ return(strncmp(str, value, len));
+}
+
+/*********************************************************************
+* Function fnCOpenDataCon() *
+* *
+* Opens data connection on client side. This function is called *
+* right after the client has requested any data from the server *
+* Parameter: int sockfd: socket of control connection *
+* int *port: port of control und data connection *
+* Return : sockfd on success, <0 if error *
+*********************************************************************/
+static int fnCOpenDataCon(int sockfd, int *port)
+ {
+ int fd;
+ struct sockaddr_in serv_addr;
+ int len;
+ int option = 1;
+
+/* len = sizeof(com_addr);
+ if(getsockname(sockfd, (struct sockaddr *) &com_addr, &len) < 0)
+ {
+ return(-1);
+ }
+
+ *port = htons(com_addr.sin_port); */
+
+ /*
+ ** Open a TCP socket (an Internet stream socket)
+ */
+ if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ return(-1);
+ }
+
+ /*
+ ** Make sure that address may be reused
+ */
+#if defined(SUN) || (WIN32|WINNT)
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&option, sizeof(option));
+#else
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
+#endif
+
+ /*
+ ** Open connection aktiv
+ ** Let bind() select a port number
+ */
+ bzero((char *) &serv_addr, sizeof(serv_addr));
+ if(bind(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
+ {
+ return(-1);
+ }
+
+ /*
+ ** Get the port number bind selected
+ */
+ len = sizeof (serv_addr);
+ if(getsockname(fd, (struct sockaddr *)&serv_addr, &len) < 0)
+ {
+ return(-1);
+ }
+ *port = ntohs(serv_addr.sin_port);
+
+ listen(fd, 5);
+
+ return(fd);
+ }
+
+/*======================================================================
+ *
+ * Read/write routines with timeout detection.
+ *
+ * Usage: write_to(fd, buffer, n, timeout)
+ * read_to(fd, buffer, n, timeout)
+ *
+ * David Chavez
+ * Engineering Services & Software
+ * 7841 New Salem Street
+ * San Diego, CA 92126
+ * USA
+ *
+ * dec@essw.com
+ *
+ *====================================================================*/
+#if WIN32|WINNT
+#include <time.h>
+#else
+#include <sys/fcntl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#endif
+#include <errno.h>
+#include <signal.h>
+
+#if !(WIN32|WINNT)
+static sigset_t newmask, oldmask, zeromask;
+#endif
+
+static int set_noblock(int fd)
+{
+#if WIN32|WINNT
+ u_long argp=1;
+
+ return ioctlsocket (fd, FIONBIO , &argp);
+#else
+
+ sigemptyset(&zeromask);
+ sigemptyset(&newmask);
+ sigaddset(&newmask, SIGHUP);
+ sigaddset(&newmask, SIGUSR1);
+ sigaddset(&newmask, SIGUSR2);
+ if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) return -1;
+
+ return fcntl(fd, F_SETFL, O_NONBLOCK | O_NDELAY /* | FNBIO*/);
+#endif
+}
+
+int write_to(int fd, void *buffer, int n, int timeout)
+{
+ int nrem, nw;
+ char *bptr;
+ int error;
+#if defined(SYSV) || (WIN32|WINNT)
+ int width = 20;
+#else
+ int width = getdtablesize();
+#endif
+ fd_set writefds;
+ struct timeval select_timeout;
+
+ select_timeout.tv_sec = timeout;
+#if WIN32|WINNT
+ select_timeout.tv_usec = 0;
+#else /* is this just a typo? */
+ select_timeout.tv_usec = 0.;
+#endif
+
+ /* Set fd to non-blocking */
+
+ if (set_noblock(fd) != 0) return -1;
+
+ /* Write to fd until no more can be written */
+
+ FD_ZERO(&writefds);
+
+ FD_SET((unsigned int)fd, &writefds);
+
+ for( nrem = n, bptr = buffer; nrem;)
+ {
+ if(( error = select(width,
+ (fd_set *) 0,
+ &writefds,
+ (fd_set *) 0,
+ &select_timeout)) <= 0 && errno != EINTR) break;
+
+ if(errno != EINTR && ( nw = write(fd, bptr, nrem)) <= 0) {
+ /*
+ * check for error number - and keep trying to
+ * write
+ */
+ if(errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR)
+ {
+ continue;
+ }
+ else
+ {
+ error = nw;
+ break;
+ }
+ } else {
+ nrem -= nw;
+ bptr += nw;
+ }
+ }
+#if !(WIN32|WINNT)
+ if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) return -1;
+#endif
+ if( ! error ) {
+ errno = ETIMEDOUT;
+ return(-2);
+ } else if (error < 0) {
+ return(error);
+ } else {
+ return(n);
+ }
+}
+
+int read_to(int fd, char *buffer, int n, int timeout)
+ {
+ int nrem, nread, nr;
+ char *bptr;
+ int error;
+
+#if defined(SYSV) || (WIN32|WINNT)
+ int width = 20;
+#else
+ int width = getdtablesize();
+#endif
+ fd_set readfds;
+ struct timeval select_timeout;
+
+ select_timeout.tv_sec = timeout;
+#if WIN32|WINNT
+ select_timeout.tv_usec = 0;
+#else
+ select_timeout.tv_usec = 0.;
+#endif
+
+ /* Set fd to non-blocking */
+
+ if (set_noblock(fd) != 0) return -1;
+
+ FD_ZERO(&readfds);
+
+ FD_SET((unsigned int)fd, &readfds);
+
+ for( nrem = n, bptr = buffer, nread = 0; nrem;)
+ {
+ if(( error = select(width,
+ &readfds,
+ (fd_set *) 0,
+ (fd_set *) 0,
+ &select_timeout)) <= 0 && errno != EINTR) break;
+
+ if(errno != EINTR && (nr = read (fd, bptr, nrem)) < 0)
+ {
+ /*
+ * check for error number - and keep trying to
+ * read
+ */
+ if(errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR)
+ {
+ continue;
+ }
+ else
+ {
+ error = nr;
+ break;
+ }
+ }
+ else if(nr == 0)
+ {
+ break;
+ }
+ else
+ {
+ nread += nr;
+ bptr += nr;
+ nrem -= nr;
+ }
+ }
+
+#if !(WIN32|WINNT)
+ if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) return -1;
+#endif
+ if( ! error )
+ {
+ errno = ETIMEDOUT;
+ return(-2);
+ }
+ else if ( error < 0)
+ {
+ return(-1);
+ }
+ else
+ {
+ return(nread);
+ }
+ }
+
+void set_swap(int do_swap)
+{
+ swap_on = do_swap;
+}
+
+/***********************************************************************
+* Function open_hg_connection() *
+* *
+***********************************************************************/
+int open_hg_connection(char *server_name, int port)
+{
+ int sockfd;
+ int option = 1;
+ struct sockaddr_in server_addr;
+ struct hostent *hp;
+ if ( (hp = gethostbyname(server_name)) == NULL ) {
+ return(-1);
+ }
+
+ bzero((char *)&server_addr, sizeof(server_addr));
+ server_addr.sin_family = AF_INET;
+ if ( port != 0 )
+ server_addr.sin_port = htons(port);
+ else
+ server_addr.sin_port = htons(HG_SERVER_PORT);
+ bcopy(hp->h_addr, (char *) &server_addr.sin_addr, hp->h_length);
+
+ if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
+ return(-2);
+ }
+
+#if defined(SUN) || (WIN32|WINNT)
+ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&option, sizeof(option));
+#else
+ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
+#endif /* SUN */
+
+ if (connect(sockfd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
+ close(sockfd);
+ return(-3);
+ }
+
+#if !(WIN32|WINNT)
+ if ( (sock_flags = fcntl(sockfd, F_GETFL, 0)) == -1 )
+#endif
+
+ if ( set_nonblocking(sockfd) == -1 ) {
+ return(-4);
+ }
+
+ return(sockfd);
+}
+
+
+/***********************************************************************
+* Function initialize_hg_connection() *
+* *
+***********************************************************************/
+int initialize_hg_connection(int sockfd, int *do_swap, int *version, char **userdata, char **server_string, char *username, char *password)
+{
+ char buf, c;
+ char *tmp;
+ hg_msg *ready_msg, *retmsg, msg;
+ int i = 0x01;
+ int length;
+
+ *do_swap = 0;
+ buf = 'T';
+ if ( hg_write(sockfd, &buf, 1) == -1 ) {
+ return(-2);
+ }
+
+ if ( hg_read_exact(sockfd, &buf, 1) == -1 ) {
+ return(-3);
+ }
+ if ( buf == 'F' ) {
+ return(-4);
+ }
+ if ( buf != 'T' ) {
+ return(-5);
+ }
+
+ buf = c = ( *(char *)&i ) ? 'l' : 'B';
+ if ( hg_write(sockfd, &buf, 1) == -1 ) {
+ return(-6);
+ }
+ if ( hg_read_exact(sockfd, &buf, 1) == -1 ) {
+ return(-7);
+ }
+ if ( c != buf ) {
+ swap_on = 1;
+ *do_swap = 1;
+ } else {
+ swap_on = 0;
+ *do_swap = 0;
+ }
+
+ if ( send_ready(sockfd) == -1) {
+ return(-8);
+ }
+
+ /* Receive return from Ready message */
+ if ( (ready_msg = recv_ready(sockfd)) == NULL ) {
+ return(-9);
+ }
+
+ if ((ready_msg->version_msgid & F_VERSION) < VERSION)
+ return(-8);
+ *version = ready_msg->version_msgid;
+ *server_string = strdup(ready_msg->buf+4);
+ efree(ready_msg->buf);
+ efree(ready_msg);
+
+ /* If we have a username and password then do the identification. */
+ if((NULL != username) && (NULL != password)) {
+ length = HEADER_LENGTH + sizeof(int) + strlen(username) + 1 + strlen(password) + 1;
+
+ build_msg_header(&msg, length, msgid++, IDENTIFY_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, 0);
+ tmp = build_msg_str(tmp, username);
+ tmp = build_msg_str(tmp, password);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-10);
+ }
+ efree(msg.buf);
+ }
+
+ if((NULL != username) && (NULL != password)) {
+ /* Receive return form identify message */
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL )
+ return(-11);
+
+ *userdata = retmsg->buf;
+ efree(retmsg);
+ }
+
+ return(0);
+}
+
+
+static int set_nonblocking(int fd)
+{
+#if WIN32|WINNT
+ unsigned int argp=0;
+
+/* if ( sock_flags == -1 )
+ getsockopt (fd, SOL_SOCKET, optname, optval, optlen);
+*/ if(ioctlsocket (fd, FIONBIO , &argp) == -1)
+ return(-1);
+#else
+ if ( sock_flags == -1 )
+ sock_flags = fcntl(fd, F_GETFL, 0);
+ if ( fcntl(fd, F_SETFL, O_NONBLOCK) == -1 )
+ return(-1);
+#endif
+ non_blocking = 1;
+ return(0);
+}
+
+
+static int set_blocking(int fd)
+{
+#if WIN32|WINNT
+ unsigned int argp=1;
+
+ if(ioctlsocket (fd, FIONBIO , &argp) == -1)
+ return(-1);
+#else
+ if ( fcntl(fd, F_SETFL, sock_flags) == -1 )
+ return(-1);
+#endif
+ return(0);
+}
+
+
+static int hg_read_exact(int sockfd, char *buf, int size)
+{
+ int len = 0;
+
+ len = read_to(sockfd, (void *) buf, size, rtimeout);
+ if ( len < 0 )
+ return -1;
+ return(0);
+}
+
+
+static int hg_read(int sockfd, char *buf, int size)
+{
+ int try = 0;
+ int len = 0;
+
+ if ( !non_blocking )
+ set_nonblocking(sockfd);
+ while ( len == 0 ) {
+ len = recv(sockfd, (void *) buf, size, 0);
+ if ( len == -1 ) {
+ if ( (errno == EAGAIN) || (errno == EWOULDBLOCK) ) {
+ if ( ++try > 5 )
+ return(-1);
+ sleep(1);
+ }
+ else return(-1);
+ }
+ }
+ return(len);
+}
+
+
+static int hg_write(int sockfd, char *buf, int size)
+{
+ int try = 0;
+ int len = 0;
+
+ if ( !non_blocking )
+ set_nonblocking(sockfd);
+ while ( size > 0 ) {
+ len = send(sockfd, (void *) buf, size, 0);
+ if ( len == -1 ) {
+ if ( (errno == EAGAIN) || (errno == EWOULDBLOCK) ) {
+ if ( ++try > 5 )
+ return(-1);
+ sleep(1);
+ }
+ else return(-1);
+ }
+ else {
+ size -= len;
+ buf += len;
+ try = 0;
+ }
+ }
+ return(0);
+}
+
+
+hg_msg *recv_hg_msg(int sockfd)
+{
+ hg_msg *msg;
+
+ if ( (msg = (hg_msg *)emalloc(sizeof(hg_msg))) == NULL ) {
+/* php3_printf("recv_hg_msg"); */
+ lowerror = LE_MALLOC;
+ return(NULL);
+ }
+
+ if ( hg_read_exact(sockfd, (char *)&(msg->length), 4) == -1 ) {
+/* php3_printf("recv_hg_msg: hg_read (1) returned -1\n"); */
+ efree(msg);
+ return(NULL);
+ }
+
+ if ( hg_read_exact(sockfd, (char *)&(msg->version_msgid), 4) == -1 ) {
+/* php3_printf("recv_hg_msg: hg_read (2) returned -1\n"); */
+ efree(msg);
+ return(NULL);
+ }
+
+ if ( hg_read_exact(sockfd, (char *)&(msg->msg_type), 4) == -1 ) {
+/* php3_printf("recv_hg_msg: hg_read (3) returned -1\n"); */
+ efree(msg);
+ return(NULL);
+ }
+
+ if ( msg->length > HEADER_LENGTH ) {
+ if ( (msg->buf = (char *) emalloc(msg->length-HEADER_LENGTH)) == NULL ) {
+/* php3_printf("recv_hg_msg"); */
+ lowerror = LE_MALLOC;
+ efree(msg);
+ return(NULL);
+ }
+ if ( hg_read_exact(sockfd, msg->buf, msg->length-HEADER_LENGTH) == -1 ) {
+/* php3_printf("recv_hg_msg: hg_read (4) returned -1\n"); */
+ efree(msg->buf);
+ efree(msg);
+ return(NULL);
+ }
+ }
+ else
+ msg->buf = NULL;
+
+#ifdef HW_DEBUG
+ php3_printf("<B> Recv msg: </B>type = %d -- id = %d<BR>\n", msg->msg_type, msg->version_msgid);
+#endif
+ return(msg);
+}
+
+
+hg_msg *recv_ready(int sockfd)
+{
+ hg_msg *ready_msg;
+
+ if ( (ready_msg = recv_hg_msg(sockfd)) == NULL ) {
+/* php3_printf("recv_ready: recv_hg_msg returned NULL\n"); */
+ return(NULL);
+ }
+ if ( ready_msg->msg_type != READY_MESSAGE ) {
+/* php3_printf("recv_ready: recv_hg_msg returned wrong message: %d, %d \n", ready_msg->length, ready_msg->msg_type); */
+ efree(ready_msg);
+ return(NULL);
+ }
+
+ return(ready_msg);
+}
+
+
+hg_msg *recv_command(int sockfd)
+{
+ hg_msg *comm_msg;
+
+ if ( (comm_msg = recv_hg_msg(sockfd)) == NULL ) {
+/* fprintf(stderr, "recv_command: recv_hg_msg returned NULL\n"); */
+ return(NULL);
+ }
+ if ( comm_msg->msg_type != COMMAND_MESSAGE ) {
+/* fprintf(stderr, "recv_command: recv_hg_msg returned wrong message\n"); */
+ return(NULL);
+ }
+
+ return(comm_msg);
+}
+
+int send_dummy(int sockfd, hw_objectID objectID, int msgid, char **attributes)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, msgid);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ *attributes = NULL;
+ return(-1);
+ }
+
+ if(0 == (int) *(retmsg->buf)) {
+ *attributes = estrdup(retmsg->buf+sizeof(int));
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ error = *((int *) retmsg->buf);
+ *attributes = NULL;
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+
+ return(0);
+}
+
+static int bh_send_deleteobject(int sockfd, hw_objectID objectID) {
+ hg_msg msg;
+ int length;
+ char *tmp;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, DELETEOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+ efree(msg.buf);
+
+ return(msgid-1);
+}
+
+static int uh_send_deleteobject(int sockfd) {
+ hg_msg *retmsg;
+ int error;
+
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ return(-1);
+ }
+
+ if(NULL == retmsg->buf) {
+ efree(retmsg);
+ return -1;
+ }
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return(error);
+}
+
+int send_deleteobject(int sockfd, hw_objectID objectID)
+{
+ if(0 > bh_send_deleteobject(sockfd, objectID))
+ return -1;
+ return(uh_send_deleteobject(sockfd));
+}
+
+static int bh_send_changeobject(int sockfd, hw_objectID objectID, char *mod) {
+ hg_msg msg;
+ int length;
+ char *tmp;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID) + strlen(mod) + 1;
+
+ build_msg_header(&msg, length, msgid++, CHANGEOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+ tmp = build_msg_str(tmp, mod);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+ efree(msg.buf);
+
+ return(msgid-1);
+}
+
+static int uh_send_changeobject(int sockfd) {
+ hg_msg *retmsg;
+ int error;
+
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ return(-1);
+ }
+
+ error = *((int *) retmsg->buf);
+ return(error);
+}
+
+int send_changeobject(int sockfd, hw_objectID objectID, char *modification)
+{
+ if(0 > bh_send_changeobject(sockfd, objectID, modification))
+ return -1;
+ return(uh_send_changeobject(sockfd));
+}
+
+static int bh_send_getobject(int sockfd, hw_objectID objectID) {
+ hg_msg msg;
+ int length;
+ char *tmp;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+ efree(msg.buf);
+
+ return(msgid-1);
+}
+
+static int uh_send_getobject(int sockfd, char **attributes) {
+ hg_msg *retmsg;
+ int error;
+
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ *attributes = NULL;
+ return(-1);
+ }
+
+ if(0 == (int) *(retmsg->buf)) {
+ *attributes = estrdup(retmsg->buf+sizeof(int));
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ error = *((int *) retmsg->buf);
+ *attributes = NULL;
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+
+ return(0);
+}
+
+int send_getobject(int sockfd, hw_objectID objectID, char **attributes)
+{
+ if(0 > bh_send_getobject(sockfd, objectID))
+ return -1;
+ return(uh_send_getobject(sockfd, attributes));
+}
+
+int send_getandlock(int sockfd, hw_objectID objectID, char **attributes)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETANDLOCK_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ *attributes = NULL;
+ return(-1);
+ }
+
+ if(0 == (error = (int) *(retmsg->buf))) {
+ *attributes = estrdup(retmsg->buf+sizeof(int));
+ } else {
+ *attributes = NULL;
+ }
+
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+}
+
+int send_insertobject(int sockfd, char *objrec, char *parms, hw_objectID *objectID)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+ int *ptr;
+
+ length = HEADER_LENGTH + strlen(objrec) + 1 + strlen(parms) + 1;
+
+ build_msg_header(&msg, length, msgid++, INSERTOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_str(msg.buf, objrec);
+ tmp = build_msg_str(tmp, parms);
+/*fprintf(stderr,"objrec = %s, parms = %s\n", objrec, parms); */
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ *objectID = 0;
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(0 == (error = *ptr)) {
+ ptr++;
+ *objectID = *ptr;
+ } else {
+ *objectID = 0;
+ }
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+}
+
+int send_unlock(int sockfd, hw_objectID objectID)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, UNLOCK_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ return(-1);
+ }
+
+ error = (int) *(retmsg->buf);
+
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+}
+
+int send_incollections(int sockfd, int retcol, int cobjids, hw_objectID *objectIDs, int ccollids, hw_objectID *collIDs, int *count, hw_objectID **retIDs)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+ int *ptr, *ptr1, i;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID) + (cobjids + ccollids) * sizeof(hw_objectID) + 2 * sizeof(int);
+
+ build_msg_header(&msg, length, msgid++, INCOLLECTIONS_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+ lowerror = LE_MALLOC;
+ return(-3);
+ }
+
+ tmp = build_msg_int(msg.buf, retcol);
+ tmp = build_msg_int(tmp, cobjids);
+ for(i=0; i<cobjids; i++)
+ tmp = build_msg_int(tmp, objectIDs[i]);
+ tmp = build_msg_int(tmp, ccollids);
+ for(i=0; i<ccollids; i++)
+ tmp = build_msg_int(tmp, collIDs[i]);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-2);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if(retmsg == NULL) {
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = *ptr;
+ ptr++;
+ if(NULL != (*retIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ ptr1 = *retIDs;
+ for(i=0; i<*count; ptr++, i++)
+ ptr1[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ if(retmsg->buf) efree(retmsg->buf);
+ if(retmsg) efree(retmsg);
+ return error;
+ }
+ return(0);
+}
+
+
+int send_inscoll(int sockfd, hw_objectID objectID, char *objrec, hw_objectID *new_objectID)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+ int *ptr;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID) + strlen(objrec) + 1;
+
+ build_msg_header(&msg, length, msgid++, INSCOLL_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+ lowerror = LE_MALLOC;
+ return(-3);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+ tmp = build_msg_str(tmp, objrec);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-2);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if(retmsg == NULL) {
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(0 != (error = *ptr)) {
+ efree(retmsg->buf);
+ efree(retmsg);
+ *new_objectID = 0;
+ return error;
+ }
+
+ ptr++;
+ *new_objectID = *ptr;
+ return 0;
+}
+
+int send_insdoc(int sockfd, hw_objectID objectID, char *objrec, char *text, hw_objectID *new_objectID)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+ int *ptr;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID) + strlen(objrec) + 1;
+ if(text) {
+ length += strlen(text);
+ length++;
+ }
+
+ build_msg_header(&msg, length, msgid++, INSDOC_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+ lowerror = LE_MALLOC;
+ return(-3);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+ tmp = build_msg_str(tmp, objrec);
+ if(text)
+ tmp = build_msg_str(tmp, text);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-2);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if(retmsg == NULL) {
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(0 != (error = *ptr)) {
+ efree(retmsg->buf);
+ efree(retmsg);
+ *new_objectID = 0;
+ return error;
+ }
+
+ ptr++;
+ *new_objectID = *ptr;
+ return 0;
+}
+
+int send_getdestforanchorsobj(int sockfd, char **anchorrec, char ***destrec, int count);
+int send_getreldestforanchorsobj(int sockfd, char **anchorrec, char ***reldestrec, int count, int rootID, int thisID);
+
+int send_gettext(int sockfd, hw_objectID objectID, int mode, int rootid, char **objattr, char **bodytag, char **text, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, *ptr, ancount, error;
+ char *tmp, *attributes, *documenttype;
+ char **anchors;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if(retmsg == NULL) {
+ attributes = NULL;
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(*ptr == 0) {
+ attributes = estrdup(retmsg->buf+sizeof(int));
+ efree(retmsg);
+ efree(retmsg->buf);
+ } else {
+ error = *ptr;
+ attributes = NULL;
+ efree(retmsg);
+ efree(retmsg->buf);
+ return error;
+ }
+
+ length = HEADER_LENGTH + strlen(attributes) + 1;
+ build_msg_header(&msg, length, msgid++, GETTEXT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_str(msg.buf, attributes);
+
+ documenttype = fnAttributeValue(attributes, "DocumentType");
+ *objattr = strdup(attributes);
+ efree(attributes);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if (retmsg == NULL) {
+ *text = NULL;
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(*ptr == 0) {
+ ptr++;
+ *count = retmsg->length-HEADER_LENGTH-sizeof(int);
+ if(NULL != (*text = malloc(*count + 1))) {
+ memcpy(*text, retmsg->buf+sizeof(int), *count);
+/* *text[*count] = 0; */
+ } else {
+ efree(retmsg);
+ efree(retmsg->buf);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *ptr;
+ efree(retmsg);
+ efree(retmsg->buf);
+ *text = NULL;
+ return(error);
+ }
+ efree(retmsg);
+ efree(retmsg->buf);
+
+ if((documenttype != NULL) && (strcmp(documenttype, "Image") != 0)) {
+ if(send_getanchorsobj(sockfd, objectID, &anchors, &ancount) == 0) {
+ char **destrec, **reldestrec;
+ DLIST *pAnchorList;
+
+ send_getdestforanchorsobj(sockfd, anchors, &destrec, ancount);
+ send_getreldestforanchorsobj(sockfd, anchors, &reldestrec, ancount, rootid, objectID);
+ pAnchorList = fnCreateAnchorList(anchors, destrec, reldestrec, ancount, mode);
+ /* Free only the array, the objrecs has been freed in fnCreateAnchorList() */
+ if(anchors) efree(anchors);
+ if(destrec) efree(destrec);
+ if(reldestrec) efree(reldestrec);
+
+ if(pAnchorList != NULL) {
+ char *newtext;
+ char *body;
+
+ newtext = fnInsAnchorsIntoText(*text, pAnchorList, &body);
+ dlst_kill(pAnchorList, fnDeleteAnchor);
+ *bodytag = strdup(body);
+ efree(body);
+ *text = newtext;
+ *count = strlen(newtext);
+ }
+ }
+ }
+
+ if(documenttype) efree(documenttype);
+ return(0);
+}
+
+int send_edittext(int sockfd, char *objattr, char *text)
+{
+ hg_msg msg, *retmsg;
+ int length, *ptr, error;
+ char *tmp, *path, *objid;
+ hw_objectID objectID;
+
+ objid = fnAttributeValue(objattr, "ObjectID=");
+ if(objid == NULL)
+ return(-1);
+ if(!sscanf(objid, "0x%x", &objectID))
+ return(-1);
+
+ path = fnAttributeValue(objattr, "Path=");
+ if(path == NULL)
+ return(-1);
+ length = HEADER_LENGTH + sizeof(hw_objectID) + strlen(path) + 1 + 1 + strlen(text) + 1;
+
+ build_msg_header(&msg, length, msgid++, EDITTEXT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+ tmp = build_msg_str(tmp, path);
+ tmp = build_msg_str(tmp, "");
+ tmp = build_msg_str(tmp, text);
+
+ if(path) efree(path);
+ if(objid) efree(objid);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if (retmsg == NULL) {
+ *text = '\0';
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ error = *ptr;
+ efree(retmsg);
+ efree(retmsg->buf);
+ return(error);
+}
+
+int send_getcgi(int sockfd, hw_objectID objectID, char *cgi_env_str, char **objattr, char **text, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, *ptr, error, new_attr_len;
+ char *tmp, *attributes, *new_attr;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if(retmsg == NULL) {
+ attributes = NULL;
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(*ptr == 0) {
+ attributes = estrdup(retmsg->buf+sizeof(int));
+ efree(retmsg);
+ efree(retmsg->buf);
+ } else {
+ error = *ptr;
+ attributes = NULL;
+ efree(retmsg);
+ efree(retmsg->buf);
+ return error;
+ }
+
+ new_attr_len = strlen(attributes) + strlen(cgi_env_str) + 2;
+ new_attr = malloc(new_attr_len);
+ strcpy(new_attr, attributes);
+ strcat(new_attr, cgi_env_str);
+ length = HEADER_LENGTH + strlen(new_attr) + 1 + sizeof(int);
+ build_msg_header(&msg, length, msgid++, GETCGI_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_str(msg.buf, new_attr);
+ tmp = build_msg_int(tmp, 0);
+
+ *objattr = strdup(attributes);
+ efree(attributes);
+ free(new_attr);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if (retmsg == NULL) {
+ *text = NULL;
+ return(-1);
+ }
+
+ /* Attention: It looks like the documentation is not quite right.
+ According to the docs the buffer starts with an integer which
+ is followed by the output of the cgi script. This seems not to
+ be true. There is another integer right after the error.
+ The output of the cgi script is also preceded by the 'Content-type'
+ header. */
+ ptr = (int *) retmsg->buf;
+ if(*ptr++ == 1024) {
+ *count = *ptr++;
+ if(NULL != (*text = malloc(*count + 1))) {
+ memcpy(*text, ptr, *count);
+ } else {
+ efree(retmsg);
+ efree(retmsg->buf);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *ptr + 1024; /* move errors to >2024 */
+ efree(retmsg);
+ efree(retmsg->buf);
+ *text = NULL;
+ return(error);
+ }
+ efree(retmsg);
+ efree(retmsg->buf);
+
+ return(0);
+}
+
+int send_getremote(int sockfd, hw_objectID objectID, char **objattr, char **text, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, *ptr, error;
+ char *tmp, *attributes;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if(retmsg == NULL) {
+ attributes = NULL;
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(*ptr == 0) {
+ attributes = estrdup(retmsg->buf+sizeof(int));
+ efree(retmsg);
+ efree(retmsg->buf);
+ } else {
+ error = *ptr;
+ attributes = NULL;
+ efree(retmsg);
+ efree(retmsg->buf);
+ return error;
+ }
+
+ length = HEADER_LENGTH + strlen(attributes) + 1 + sizeof(int);
+ build_msg_header(&msg, length, msgid++, GETREMOTE_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_str(msg.buf, attributes);
+ tmp = build_msg_int(tmp, 0);
+
+ *objattr = strdup(attributes);
+ efree(attributes);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if (retmsg == NULL) {
+ *text = NULL;
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(*ptr == 1024) {
+ *count = retmsg->length-HEADER_LENGTH-sizeof(int)-sizeof(int);
+ if(NULL != (*text = malloc(*count + 1))) {
+ memcpy(*text, ptr+2, *count);
+/* *text[*count] = 0; */
+ } else {
+ efree(retmsg);
+ efree(retmsg->buf);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *ptr + 1024; /* move errors to >2024 */
+ efree(retmsg);
+ efree(retmsg->buf);
+ *text = NULL;
+ return(error);
+ }
+ efree(retmsg);
+ efree(retmsg->buf);
+
+ return(0);
+}
+
+int send_getremotechildren(int sockfd, char *attributes, char **text, int **childIDs, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, *ptr, *ptr1, error;
+ char *tmp;
+
+/* length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if(retmsg == NULL) {
+ attributes = NULL;
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(*ptr == 0) {
+ attributes = estrdup(retmsg->buf+sizeof(int));
+ efree(retmsg);
+ efree(retmsg->buf);
+ } else {
+ error = *ptr;
+ attributes = NULL;
+ efree(retmsg);
+ efree(retmsg->buf);
+ return error;
+ }
+*/
+ length = HEADER_LENGTH + strlen(attributes) + 1 + sizeof(int);
+ build_msg_header(&msg, length, msgid++, GETREMOTECHILDREN_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_str(msg.buf, attributes);
+ tmp = build_msg_int(tmp, 0);
+
+/* efree(attributes); */
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if (retmsg == NULL) {
+ *childIDs = NULL;
+ return(-1);
+ }
+ ptr = (int *) retmsg->buf;
+ if(*ptr++ == 1024) {
+ int i, remlen, sum;
+ *count = *ptr;
+ ptr++;
+ if(NULL != (*childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ ptr1 = *childIDs;
+ sum = 0;
+ for(i=0; i<*count; ptr++, i++) {
+ ptr1[i] = *ptr;
+ sum += *ptr;
+ }
+ } else {
+ efree(retmsg);
+ efree(retmsg->buf);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ remlen = retmsg->length - HEADER_LENGTH - *count * sizeof(int) - 2 * sizeof(int);
+/*ptr1[i-1] = remlen; */
+/*ptr1[i-2] = sum; */
+/*ptr1[i-3] = *count; */
+ if(NULL != (*text = emalloc(remlen + 1))) {
+ memcpy(*text, ptr, remlen);
+ } else {
+ efree(childIDs);
+ efree(retmsg);
+ efree(retmsg->buf);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ *childIDs = NULL;
+ *text = NULL;
+ return error;
+ }
+ return(0);
+}
+
+int send_mvcpdocscollscoll(int sockfd, hw_objectID *objectIDs, int count, int from, int dest, int cpmv, int doccoll)
+{
+ hg_msg msg, *retmsg;
+ int length, i, error;
+ char *tmp;
+
+ if(count <= 0)
+ return 0;
+
+ /* HEADER_LENGTH + cpmv + from + dest + count + nr of obj */
+ length = HEADER_LENGTH + sizeof(hw_objectID) + sizeof(hw_objectID) + sizeof(hw_objectID) + sizeof(hw_objectID) + count * sizeof(hw_objectID);
+
+ switch(doccoll) {
+ case DOCUMENT:
+ build_msg_header(&msg, length, msgid++, MVCPDOCSCOLL_MESSAGE);
+ break;
+ case COLLECTION:
+ build_msg_header(&msg, length, msgid++, MVCPCOLLSCOLL_MESSAGE);
+ break;
+ }
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, cpmv);
+ tmp = build_msg_int(tmp, from);
+ tmp = build_msg_int(tmp, dest);
+ tmp = build_msg_int(tmp, count);
+ for(i=0; i<count;i++)
+ tmp = build_msg_int(tmp,objectIDs[i]);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ return(-1);
+ }
+
+ efree(retmsg);
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ return(error);
+}
+
+int send_docbyanchor(int sockfd, hw_objectID objectID, hw_objectID *anchorID)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+ int *ptr;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETDOCBYANCHOR_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ error = *ptr++;
+ if(error == 0) {
+ *anchorID = *ptr;
+ } else {
+ *anchorID = 0;
+ }
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+}
+
+int send_docbyanchorobj(int sockfd, hw_objectID objectID, char **objrec)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+ int *ptr, anchorID;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETDOCBYANCHOR_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ error = *ptr++;
+ if(error == 0) {
+ anchorID = *ptr;
+ } else {
+ anchorID = 0;
+ }
+ efree(retmsg->buf);
+ efree(retmsg);
+
+ if(0 > bh_send_getobject(sockfd, anchorID))
+ return -1;
+ return(uh_send_getobject(sockfd, objrec));
+}
+
+int send_children(int sockfd, hw_objectID objectID, hw_objectID **childIDs, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, i, error;
+ char *tmp;
+ int *ptr, *ptr1;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, CHILDREN_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if (-1 == send_hg_msg(sockfd, &msg, length)) {
+ efree(msg.buf);
+ return(-2);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ return(-3);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = *ptr++;
+ if(NULL != (*childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ ptr1 = *childIDs;
+ for(i=0; i<*count; ptr++, i++)
+ ptr1[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+
+ return(0);
+}
+
+int send_childrenobj(int sockfd, hw_objectID objectID, char ***childrec, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, i, error;
+ char *tmp, **objptr;
+ int *childIDs = NULL;
+ int *ptr;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, CHILDREN_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL )
+ return(-1);
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = *ptr++;
+ if(NULL != (childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ for(i=0; i<*count; ptr++, i++)
+ childIDs[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+
+ /* Now get for each child collection the object record */
+ for(i=0; i<*count; i++) {
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+ build_msg_header(&msg, length, childIDs[i], GETOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+ efree(childIDs);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, childIDs[i]);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(childIDs);
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ }
+ efree(childIDs);
+
+ if(NULL == (objptr = (char **) emalloc(*count * sizeof(hw_objrec *)))) {
+ /* if emalloc fails, get at least all remaining messages from server */
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ *childrec = NULL;
+ lowerror = LE_MALLOC;
+ return(-1);
+ } else {
+ *childrec = objptr;
+
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg != NULL ) {
+ if(0 == (int) *(retmsg->buf)) {
+ *objptr = estrdup(retmsg->buf+sizeof(int));
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ *objptr = NULL;
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ }
+ }
+ }
+
+ return(0);
+}
+
+int send_getchildcoll(int sockfd, hw_objectID objectID, hw_objectID **childIDs, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+ int *ptr, i, *ptr1;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETCHILDCOLL_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = *ptr++;
+ if(NULL != (*childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ ptr1 = *childIDs;
+ for(i=0; i<*count; ptr++, i++)
+ ptr1[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+
+ return(0);
+}
+
+int send_getchildcollobj(int sockfd, hw_objectID objectID, char ***childrec, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, i, error;
+ char *tmp, **objptr;
+ int *childIDs = NULL;
+ int *ptr;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETCHILDCOLL_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL )
+ return(-1);
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = *ptr++;
+ if(NULL != (childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ for(i=0; i<*count; ptr++, i++)
+ childIDs[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+
+ /* Now get for each child collection the object record */
+ for(i=0; i<*count; i++) {
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+ build_msg_header(&msg, length, childIDs[i], GETOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+ efree(childIDs);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, childIDs[i]);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(childIDs);
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ }
+ efree(childIDs);
+
+ if(NULL == (objptr = (char **) emalloc(*count * sizeof(hw_objrec *)))) {
+ /* if emalloc fails, get at least all remaining messages from server */
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ *childrec = NULL;
+ lowerror = LE_MALLOC;
+ return(-1);
+ } else {
+ *childrec = objptr;
+
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg != NULL ) {
+ if(0 == (int) *(retmsg->buf)) {
+ *objptr = estrdup(retmsg->buf+sizeof(int));
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ *objptr = NULL;
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ }
+ }
+ }
+
+ return(0);
+}
+
+int send_getchilddoccoll(int sockfd, hw_objectID objectID, hw_objectID **childIDs, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETCHILDDOCCOLL_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ } else {
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg != NULL ) {
+ int *ptr, i, *ptr1;
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = *ptr++;
+ if(NULL != (*childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ ptr1 = *childIDs;
+ for(i=0; i<*count; ptr++, i++)
+ ptr1[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+ }
+ }
+
+ return(0);
+
+}
+
+int send_getchilddoccollobj(int sockfd, hw_objectID objectID, hw_objrec ***childrec, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, i, error;
+ char *tmp, **objptr;
+ int *childIDs = NULL;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETCHILDDOCCOLL_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+ efree(msg.buf);
+
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg != NULL ) {
+ int *ptr, i;
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg->buf) efree(retmsg->buf);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = *ptr++;
+ if(NULL != (childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ for(i=0; i<*count; ptr++, i++)
+ childIDs[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+ }
+
+ /* Now get for each child collection the object record */
+ for(i=0; i<*count; i++) {
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+ build_msg_header(&msg, length, childIDs[i], GETOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, childIDs[i]);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ }
+
+ if(NULL == (objptr = (char **) emalloc(*count * sizeof(hw_objrec *)))) {
+ /* if emalloc fails, get at least all remaining messages from server */
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ *childrec = NULL;
+ lowerror = LE_MALLOC;
+ return(-1);
+ } else {
+ *childrec = objptr;
+
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg != NULL ) {
+ if(0 == (int) *(retmsg->buf)) {
+ *objptr = estrdup(retmsg->buf+sizeof(int));
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ *objptr = NULL;
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ }
+ }
+ }
+
+ return(0);
+}
+
+int send_getanchors(int sockfd, hw_objectID objectID, int **anchorIDs, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+ int *ptr, i, *ptr1;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETANCHORS_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+ efree(msg.buf);
+
+ if (NULL == (retmsg = recv_hg_msg(sockfd)))
+ return(-1);
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = *ptr++;
+ if(NULL != (*anchorIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ ptr1 = *anchorIDs;
+ for(i=0; i<*count; ptr++, i++)
+ ptr1[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+
+ return(0);
+}
+
+int send_getanchorsobj(int sockfd, hw_objectID objectID, char ***childrec, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+ int *ptr, i, *ptr1;
+ int *anchorIDs = NULL;
+ char **objptr;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, 50, GETANCHORS_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+ efree(msg.buf);
+
+ if (NULL == (retmsg = recv_hg_msg(sockfd)))
+ return(-1);
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = *ptr++;
+ if(NULL != (anchorIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ ptr1 = anchorIDs;
+ for(i=0; i<*count; ptr++, i++)
+ ptr1[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+
+ /* Now get for each anchor the object record */
+ for(i=0; i<*count; i++) {
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+ build_msg_header(&msg, length, anchorIDs[i], GETOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, anchorIDs[i]);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ }
+ if(anchorIDs) efree(anchorIDs);
+
+ if(NULL == (objptr = (char **) emalloc(*count * sizeof(hw_objrec *)))) {
+ /* if emalloc fails, get at least all remaining messages from server */
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ *childrec = NULL;
+ lowerror = LE_MALLOC;
+ return(-1);
+ } else {
+ *childrec = objptr;
+
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg != NULL ) {
+ if(0 == (int) *(retmsg->buf)) {
+ *objptr = estrdup(retmsg->buf+sizeof(int));
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ *objptr = NULL;
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ }
+ }
+ }
+
+ return(0);
+}
+
+int send_getdestforanchorsobj(int sockfd, char **anchorrec, char ***destrec, int count)
+{
+ int i;
+ char *objptr, **destptr;
+ char *str;
+ int objectID;
+
+ if(NULL == (destptr = (char **) emalloc(count * sizeof(hw_objrec *)))) {
+ lowerror = LE_MALLOC;
+ return -1;
+ }
+
+ /* Now get for each anchor the object record of its destination */
+ for(i=0; i<count; i++) {
+ /* if you retrieve the anchors you sometimes get more than actually accessible.
+ This happens for the object 0x29a9c. */
+ if((NULL != anchorrec[i]) && (NULL != (str = fnAttributeValue(anchorrec[i], "Dest")))) {
+ sscanf(str, "0x%x", &objectID);
+ efree(str);
+
+ if(0 > send_docbyanchorobj(sockfd, objectID, &objptr)) {
+ efree(destptr);
+ return -1;
+ }
+ destptr[i] = objptr;
+ /* if we can't get the object rec of the dest, than this document
+ is probably not accessible for us. For later functions simply
+ set anchorrec[i] to NULL */
+ if(destptr[i] == NULL) {
+ if(anchorrec[i]) efree(anchorrec[i]);
+ anchorrec[i] = NULL;
+ }
+ } else {
+ destptr[i] = NULL;
+ }
+ }
+ *destrec = destptr;
+
+ return(0);
+}
+
+int send_getreldestforanchorsobj(int sockfd, char **anchorrec, char ***reldestrec, int count, int rootID, int thisID)
+{
+ int i;
+ char *docofanchorptr, **reldestptr;
+ char *str;
+ int destobjectID;
+
+ if(NULL == (reldestptr = (char **) emalloc(count * sizeof(char *)))) {
+ lowerror = LE_MALLOC;
+ return -1;
+ }
+
+ /* Now get for each anchor the object record of its destination */
+ for(i=0; i<count; i++) {
+ /* if you retrieve the anchors you sometimes get more than actually accessible.
+ */
+ if((NULL != anchorrec[i]) && (NULL != (str = fnAttributeValue(anchorrec[i], "Dest")))) {
+ sscanf(str, "0x%x", &destobjectID);
+ efree(str);
+
+ if(0 > send_docbyanchorobj(sockfd, destobjectID, &docofanchorptr)) {
+ efree(reldestptr);
+ return -1;
+ }
+ reldestptr[i] = docofanchorptr;
+ /* if we can't get the object rec of the dest, than this document
+ is probably not accessible for us. For later functions simply
+ set anchorrec[i] to NULL */
+ if(reldestptr[i] == NULL) {
+ if(anchorrec[i]) efree(anchorrec[i]);
+ anchorrec[i] = NULL;
+ } else {
+ int j, k, *retthisIDs, *retdestIDs, equaltill, mincount, countthis, countdest, destdocid;
+ char destdocname[200];
+ char anchorstr[300];
+ char temp[200];
+ char *strptr;
+
+ if(NULL != (str = strstr(docofanchorptr, "Name="))) {
+ str += 5;
+ sscanf(str, "%s\n", destdocname);
+ }
+ if(NULL != (str = strstr(docofanchorptr, "ObjectID="))) {
+ str += 9;
+ sscanf(str, "0x%X", &destdocid);
+ }
+
+ send_incollections(sockfd, 1, 1, &thisID, 1, &rootID, &countthis, &retthisIDs);
+ send_incollections(sockfd, 1, 1, &destdocid, 1, &rootID, &countdest, &retdestIDs);
+
+fprintf(stderr, "%d: ", thisID);
+for(k=0; k<countthis; k++)
+ fprintf(stderr,"%d, ", retthisIDs[k]);
+fprintf(stderr,"\n");
+fprintf(stderr,"%d: ", destdocid);
+for(k=0; k<countdest; k++)
+ fprintf(stderr,"%d: %d, ", destdocid, retdestIDs[k]);
+fprintf(stderr,"\n");
+
+ mincount = (countthis < countdest) ? countthis : countdest;
+ for(j=0; (j<mincount) && (retthisIDs[j]==retdestIDs[j]); j++)
+ ;
+ equaltill = j;
+ strcpy(anchorstr, "Name=");
+ for(j=equaltill; j<countthis; j++)
+ strcat(anchorstr, "../");
+ strcat(anchorstr, "./");
+ for(j=equaltill; j<countdest; j++) {
+ char *temprec, tempname[100], objectidstr[100];
+ send_getobject(sockfd, retdestIDs[j], &temprec);
+ if(NULL != (str = strstr(temprec, "Name="))) {
+ str += 5;
+ sscanf(str, "%s\n", tempname);
+ } else if(NULL != (str = strstr(temprec, "ObjectID="))) {
+ str += 9;
+ sscanf(str, "%s\n", tempname);
+ }
+
+ sprintf(temp, "%s", tempname);
+ strptr = temp;
+ while(*strptr != '\0') {
+ if(*strptr == '/')
+ *strptr = '_';
+ strptr++;
+ }
+fprintf(stderr, "Adding '%s' to '%s'\n", temp, anchorstr);
+ strcat(anchorstr, temp);
+ strcat(anchorstr, "/");
+fprintf(stderr, "Is now '%s'\n", anchorstr);
+ efree(temprec);
+ }
+ /* if the anchor destination is a collection it may not be added anymore. */
+ if(destdocid != retdestIDs[countdest-1]) {
+ strptr = destdocname;
+ while(*strptr != '\0') {
+ if(*strptr == '/')
+ *strptr = '_';
+ strptr++;
+ }
+ strcat(anchorstr, destdocname);
+ } else {
+ strcat(anchorstr, "index.html");
+ }
+ strcat(anchorstr, "\n");
+ sprintf(temp, "ObjectID=0x%x", destdocid);
+ strcat(anchorstr, temp);
+fprintf(stderr, "%s\n", anchorstr);
+ efree(retthisIDs);
+ efree(retdestIDs);
+ reldestptr[i] = estrdup(anchorstr);
+ }
+ } else {
+ reldestptr[i] = NULL;
+ }
+ }
+ *reldestrec = reldestptr;
+
+ return(0);
+}
+
+int fn_findpath(int sockfd, int *retIDs, int count, int id) {
+ int *pathIDs;
+ int *parentIDs, pcount, pid;
+ int u, j, i;
+
+ if(NULL == (pathIDs = emalloc(count * sizeof(int)))) {
+ lowerror = LE_MALLOC;
+ return -1;
+ }
+ u = count-1;
+ pid = id;
+ pcount = 1;
+ /* FIXME but parentIDs is not set at this point, why checking it? */
+ while((u >= 0) && (pcount != 0) && (parentIDs != NULL) && (pid != 0)) {
+/*fprintf(stderr, "Get parents for %d\n", pid); */
+ if(0 != send_getparents(sockfd, pid, &parentIDs, &pcount)) {
+ efree(pathIDs);
+ return -1;
+ }
+ pid = 0;
+ for(i=0; i<pcount; i++) {
+ for(j=0; j<count; j++) {
+ if(parentIDs[i] == retIDs[j]) {
+ pathIDs[u--] = retIDs[j];
+ pid = retIDs[j];
+ }
+ }
+ }
+ if(pid == 0)
+ fprintf(stderr, "parent not found in list\n");
+ if(parentIDs) efree(parentIDs);
+ }
+/*fprintf(stderr, "sorted path: "); */
+ for(i=0; i<count; i++) {
+ retIDs[i] = pathIDs[i];
+/*fprintf(stderr, "%d, ", retIDs[i]); */
+ }
+/*fprintf(stderr, "\n"); */
+ efree(pathIDs);
+ return 0;
+}
+
+/********************************************************************
+* function getrellink() *
+* *
+* Returns the link to point from document with ID sourceID to *
+* document with id destID. *
+********************************************************************/
+int getrellink(int sockfd, int rootID, int thisID, int destID, char **reldeststr) {
+ int i, j, k, *retthisIDs, *retdestIDs, equaltill, count, mincount, countthis, countdest, destdocid;
+ char anchorstr[300];
+ char temp[200];
+ char *strptr;
+
+ send_incollections(sockfd, 1, 1, &thisID, 1, &rootID, &countthis, &retthisIDs);
+ send_incollections(sockfd, 1, 1, &destID, 1, &rootID, &countdest, &retdestIDs);
+
+
+fprintf(stderr, "%d: ", thisID);
+for(k=0; k<countthis; k++)
+ fprintf(stderr,"%d, ", retthisIDs[k]);
+fprintf(stderr,"\n");
+fprintf(stderr,"%d: ", destID);
+for(k=0; k<countdest; k++)
+ fprintf(stderr,"%d, ", retdestIDs[k]);
+fprintf(stderr,"\n");
+
+ /*
+ ** The message incollections returned a list of collections
+ ** in which the destID or thisID is contained. Unfortunately
+ ** this list ist not the path for the destID or thisID, but
+ ** a sorted list of collection IDs. If for example you are
+ ** looking for an ID 20 which has a path 1 -> 5 -> 4 -> 20
+ ** (this means: 20 is child of 4, 4 is child of 5, 5 is child
+ ** of 1) it will return 1,4,5 instead of 1,5,4
+ ** Consequently, we have to create the correct path, by checking
+ ** for the parents and identifying it in the list.
+ ** But there is another problem. If the id for which the list of
+ ** of collection is generated is a colletion itself, it will
+ ** show up in the list as well. In order to make the algorithmn
+ ** work proberly it has to be the last member of the list.
+ */
+ for(i=0; i<countdest; i++)
+ if(retdestIDs[i] == destID) {
+ retdestIDs[i] = retdestIDs[countdest-1];
+ retdestIDs[countdest-1] = destID;
+ }
+ count = (retdestIDs[countdest-1] == destID) ? countdest-1 : countdest;
+ if(0 != fn_findpath(sockfd, retdestIDs, count, destID)) {
+ efree(retthisIDs);
+ efree(retdestIDs);
+ return -1;
+ }
+ for(i=0; i<countthis; i++)
+ if(retthisIDs[i] == thisID) {
+ retthisIDs[i] = retthisIDs[countthis-1];
+ retthisIDs[countthis-1] = thisID;
+ }
+ count = (retthisIDs[countthis-1] == thisID) ? countthis-1 : countthis;
+ if(0 != fn_findpath(sockfd, retthisIDs, count, thisID)) {
+ efree(retthisIDs);
+ efree(retdestIDs);
+ return -1;
+ }
+
+ mincount = (countthis < countdest) ? countthis : countdest;
+fprintf(stderr,"mincount = %d\n", mincount);
+ for(j=0; (j<mincount) && (retthisIDs[j]==retdestIDs[j]); j++)
+ ;
+ equaltill = j;
+fprintf(stderr, "first unequal = %d\n", j);
+ strcpy(anchorstr, "");
+ for(j=equaltill; j<countthis; j++)
+ strcat(anchorstr, "../");
+ strcat(anchorstr, "./");
+ for(j=equaltill; j<countdest; j++) {
+ char *temprec, *str, tempname[100], objectidstr[100];
+ if(0 == send_getobject(sockfd, retdestIDs[j], &temprec)) {
+ if(NULL != (str = strstr(temprec, "Name="))) {
+ str += 5;
+ sscanf(str, "%s\n", tempname);
+ } else if(NULL != (str = strstr(temprec, "ObjectID="))) {
+ str += 9;
+ sscanf(str, "%s\n", tempname);
+ }
+
+ sprintf(temp, "%s", tempname);
+ strptr = temp;
+ while(*strptr != '\0') {
+ if(*strptr == '/')
+ *strptr = '_';
+ strptr++;
+ }
+fprintf(stderr, "Adding '%s' (%d) to '%s'\n", temp, retdestIDs[j], anchorstr);
+ strcat(anchorstr, temp);
+ strcat(anchorstr, "/");
+fprintf(stderr, "Is now '%s'\n", anchorstr);
+ efree(temprec);
+ } else {
+ strcat(anchorstr, "No access/");
+ }
+ }
+ /* if the anchor destination is a collection it may not be added anymore. */
+ if(destID != retdestIDs[countdest-1]) {
+ char destdocname[100], *str;
+ send_getobject(sockfd, destID, &str);
+ if(NULL != (strptr = strstr(str, "Name="))) {
+ strptr += 5;
+ sscanf(strptr, "%s\n", destdocname);
+ }
+ strptr = destdocname;
+ while(*strptr != '\0') {
+ if(*strptr == '/')
+ *strptr = '_';
+ strptr++;
+ }
+ strcat(anchorstr, destdocname);
+ efree(str);
+ } else {
+/* strcat(anchorstr, "index.html"); */
+ }
+/*fprintf(stderr, "%s\n", anchorstr); */
+ efree(retthisIDs);
+ efree(retdestIDs);
+ *reldeststr = estrdup(anchorstr);
+ return 0;
+}
+
+int send_identify(int sockfd, char *name, char *passwd, char **userdata) {
+ hg_msg msg, *retmsg;
+ int length;
+ char *tmp;
+
+ length = HEADER_LENGTH + sizeof(int) + strlen(name) + 1 + strlen(passwd) + 1;
+
+ build_msg_header(&msg, length, msgid++, IDENTIFY_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, 0);
+ tmp = build_msg_str(tmp, name);
+ tmp = build_msg_str(tmp, passwd);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL )
+ return(-1);
+
+ *userdata = (char *) retmsg->buf;
+ efree(retmsg);
+
+ return(0);
+}
+
+int send_getobjbyquery(int sockfd, char *query, int maxhits, hw_objectID **childIDs, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+ int *ptr, i, *ptr1;
+
+ length = HEADER_LENGTH + strlen(query) + 1;
+
+ build_msg_header(&msg, length, msgid++, GETOBJBYQUERY_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_str(msg.buf, query);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL )
+ return(-1);
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = (*ptr < maxhits) ? *ptr : maxhits;
+ ptr++;
+ if(NULL != (*childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ ptr1 = *childIDs;
+ for(i=0; i<*count; ptr++, i++)
+ ptr1[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+ return(0);
+}
+
+int send_getobjbyqueryobj(int sockfd, char *query, int maxhits, char ***childrec, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, i, error;
+ char *tmp;
+ int *childIDs = NULL;
+ char **objptr;
+ int *ptr, *ptr1;
+
+ length = HEADER_LENGTH + strlen(query) + 1;
+
+ build_msg_header(&msg, length, msgid++, GETOBJBYQUERY_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_str(msg.buf, query);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL )
+ return(-1);
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = (*ptr < maxhits) ? *ptr : maxhits;
+ ptr++;
+ if(NULL != (childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ ptr1 = childIDs;
+ for(i=0; i<*count; ptr++, i++)
+ ptr1[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+
+ /* Now get for each child collection the object record */
+ for(i=0; i<*count; i++) {
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+ build_msg_header(&msg, length, childIDs[i], GETOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ efree(childIDs);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, childIDs[i]);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ efree(childIDs);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ }
+ efree(childIDs);
+
+ if(NULL == (objptr = (char **) emalloc(*count * sizeof(hw_objrec *)))) {
+ /* if emalloc fails, get at least all remaining messages from server */
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ *childrec = NULL;
+ lowerror = LE_MALLOC;
+ return(-1);
+ } else {
+ *childrec = objptr;
+
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg != NULL ) {
+ if(0 == (int) *(retmsg->buf)) {
+ *objptr = estrdup(retmsg->buf+sizeof(int));
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ *objptr = NULL;
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ }
+ }
+ }
+
+ return(0);
+}
+
+int send_getobjbyquerycoll(int sockfd, hw_objectID collID, char *query, int maxhits, hw_objectID **childIDs, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, error;
+ char *tmp;
+ int *ptr, i, *ptr1;
+
+ length = HEADER_LENGTH + strlen(query) + 1 + sizeof(int) + sizeof(collID);
+
+ build_msg_header(&msg, length, msgid++, GETOBJBYQUERYCOLL_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, 1);
+ tmp = build_msg_int(tmp, collID);
+ tmp = build_msg_str(tmp, query);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL )
+ return(-1);
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = (*ptr < maxhits) ? *ptr : maxhits;
+ ptr++;
+ if(NULL != (*childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ ptr1 = *childIDs;
+ for(i=0; i<*count; ptr++, i++)
+ ptr1[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+ return(0);
+}
+
+int send_getobjbyquerycollobj(int sockfd, hw_objectID collID, char *query, int maxhits, char ***childrec, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, i, error;
+ char *tmp;
+ hw_objectID *childIDs = NULL;
+ char **objptr;
+ int *ptr, *ptr1;
+
+ length = HEADER_LENGTH + strlen(query) + 1 + sizeof(int) + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETOBJBYQUERYCOLL_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, 1);
+ tmp = build_msg_int(tmp, collID);
+ tmp = build_msg_str(tmp, query);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL )
+ return -1;
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = (*ptr < maxhits) ? *ptr : maxhits;
+ ptr++;
+ if(NULL != (childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ ptr1 = childIDs;
+ for(i=0; i<*count; ptr++, i++)
+ ptr1[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+
+ /* Now get for each child collection the object record */
+ for(i=0; i<*count; i++) {
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+ build_msg_header(&msg, length, childIDs[i], GETOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ efree(childIDs);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, childIDs[i]);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ efree(childIDs);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ }
+ efree(childIDs);
+
+ if(NULL == (objptr = (char **) emalloc(*count * sizeof(hw_objrec *)))) {
+ /* if emalloc fails, get at least all remaining messages from server */
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ *childrec = NULL;
+ lowerror = LE_MALLOC;
+ return(-1);
+ } else {
+ *childrec = objptr;
+
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg != NULL ) {
+ if(0 == (int) *(retmsg->buf)) {
+ *objptr = estrdup(retmsg->buf+sizeof(int));
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ *objptr = NULL;
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ }
+ }
+ }
+
+ return(0);
+}
+
+int send_getparents(int sockfd, hw_objectID objectID, hw_objectID **childIDs, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, i, error;
+ char *tmp;
+ int *ptr, *ptr1;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETPARENT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if (-1 == send_hg_msg(sockfd, &msg, length)) {
+ efree(msg.buf);
+ return(-2);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ return(-3);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = *ptr++;
+ if(NULL != (*childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ ptr1 = *childIDs;
+ for(i=0; i<*count; ptr++, i++)
+ ptr1[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+
+ return(0);
+}
+
+int send_getparentsobj(int sockfd, hw_objectID objectID, char ***childrec, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, i, error;
+ char *tmp;
+ hw_objectID *childIDs = NULL;
+ char **objptr;
+ int *ptr;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETPARENT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if (-1 == send_hg_msg(sockfd, &msg, length)) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = *ptr++;
+ if(NULL != (childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ for(i=0; i<*count; ptr++, i++)
+ childIDs[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+
+ /* Now get for each parent the object record */
+ for(i=0; i<*count; i++) {
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+ build_msg_header(&msg, length, childIDs[i], GETOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, childIDs[i]);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ }
+ efree(childIDs);
+
+ if(NULL == (objptr = (char **) emalloc(*count * sizeof(hw_objrec *)))) {
+ /* if emalloc fails, get at least all remaining messages from server */
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ *childrec = NULL;
+ lowerror = LE_MALLOC;
+ return(-1);
+ } else {
+ *childrec = objptr;
+
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg != NULL ) {
+ if(0 == (int) *(retmsg->buf)) {
+ *objptr = estrdup(retmsg->buf+sizeof(int));
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ *objptr = NULL;
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ }
+ }
+ }
+ return(0);
+}
+
+int send_pipedocument(int sockfd, char *host, hw_objectID objectID, int mode, int rootid, char **objattr, char **bodytag, char **text, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, len;
+ char *tmp, header[80], *head_ptr, *sizestr;
+ struct sockaddr_in serv_addr;
+ struct hostent *hostptr;
+ char *hostip = NULL;
+ char *attributes = NULL;
+ char *documenttype;
+ char **anchors;
+ int newfd, fd, port, size, error, ancount;
+ int *ptr;
+
+ if(-1 == (fd = fnCOpenDataCon(sockfd, &port))) {
+ /* not set yet efree(msg.buf); */
+ return(-1);
+ }
+
+ /*
+ ** Get information about host
+ */
+ if(host) {
+ if((hostptr = gethostbyname(host)) == NULL) {
+ php3_error(E_WARNING, "gethostbyname failed for %s", host);
+ close(fd);
+ return(-1);
+ }
+ } else {
+ close(fd);
+ return(-1);
+ }
+
+ switch(hostptr->h_addrtype) {
+ struct in_addr *ptr1;
+ char *ptr;
+ case AF_INET:
+ ptr = hostptr->h_addr_list[0];
+ ptr1 = (struct in_addr *) ptr;
+ hostip = inet_ntoa(*ptr1);
+ break;
+ default:
+ close(fd);
+ return(-1);
+ break;
+ }
+
+ /* Bottom half of send_getobject */
+ if(0 > bh_send_getobject(sockfd, objectID)) {
+ close(fd);
+ return -1;
+ }
+
+ /* Upper half of send_getobject */
+ if(0 > (error = uh_send_getobject(sockfd, &attributes))) {
+ close(fd);
+ return error;
+ }
+
+ length = HEADER_LENGTH + sizeof(hw_objectID) + sizeof(int) + strlen(hostip) + 1 + strlen("Refno=0x12345678") + 1;
+ build_msg_header(&msg, length, msgid++, PIPEDOCUMENT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+ tmp = build_msg_int(tmp, port);
+ tmp = build_msg_str(tmp, hostip);
+ tmp = build_msg_str(tmp, "Refno=0x12345678");
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ if(attributes) efree(attributes);
+ efree(msg.buf);
+ close(fd);
+ return(-1);
+ }
+ efree(msg.buf);
+
+ /* Just check if the command was understood */
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ if(attributes) efree(attributes);
+ close(fd);
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if((ptr == NULL) || (*ptr != 0)) {
+ error = *ptr;
+ efree(retmsg);
+ if(retmsg->buf) efree(retmsg->buf);
+ if(attributes) efree(attributes);
+ close(fd);
+ return(error);
+ }
+
+ efree(retmsg);
+ efree(retmsg->buf);
+
+ /* passively open the data connection. The HG server is probably
+ already waiting for us.
+ */
+ len = sizeof(serv_addr);
+ if((newfd = accept(fd, (struct sockaddr *) &serv_addr, &len)) < 0) {
+/* php3_printf("client: can't open data connection to server\n"); */
+ if(attributes) efree(attributes);
+ close(fd);
+ return(-1);
+ } else {
+ close(fd);
+ }
+
+ /* First of all read the header */
+ head_ptr = header;
+ while((read_to(newfd, head_ptr, 1, rtimeout) == 1) && (*head_ptr != '\0')) {
+ head_ptr++;
+ }
+
+ /* Let's see how big the document is and read it into var text */
+ sizestr = strstr(header, "sz=");
+ if(sizestr) {
+ sizestr += 3;
+ sscanf(sizestr, "%d\n", &size);
+ *count = size;
+ if((size != 0) && (NULL != (*text = malloc(size+1)))) {
+ read_to(newfd, *text, size, rtimeout);
+ (*text)[size] = '\0';
+ }
+ } else {
+ *text = NULL;
+ }
+
+ /* close the data connection */
+ close(newfd);
+
+ documenttype = fnAttributeValue(attributes, "DocumentType");
+
+ /* Make a copy with strdup (not estrdup), because we want to
+ keep the attributes in hw_document struct.
+ */
+ *objattr = strdup(attributes);
+ efree(attributes);
+
+ if((documenttype != NULL) && (!strcmp(documenttype, "text") != 0)) {
+ if(send_getanchorsobj(sockfd, objectID, &anchors, &ancount) == 0) {
+ char **destrec, **reldestrec;
+ DLIST *pAnchorList = NULL;
+
+ send_getdestforanchorsobj(sockfd, anchors, &destrec, ancount);
+ send_getreldestforanchorsobj(sockfd, anchors, &reldestrec, ancount, rootid, objectID);
+ pAnchorList = fnCreateAnchorList(anchors, destrec, reldestrec, ancount, mode);
+ /* Free only the array, the objrecs has been freed in fnCreateAnchorList() */
+ if(anchors) efree(anchors);
+ if(destrec) efree(destrec);
+ if(reldestrec) efree(reldestrec);
+
+ if(pAnchorList != NULL) {
+ char *newtext;
+ char *body;
+
+ newtext = fnInsAnchorsIntoText(*text, pAnchorList, &body);
+ dlst_kill(pAnchorList, fnDeleteAnchor);
+ *bodytag = strdup(body);
+ efree(body);
+ *text = newtext;
+ *count = strlen(newtext);
+ }
+ }
+ } else {
+ *bodytag = NULL;
+ }
+
+ if(documenttype) efree(documenttype);
+ return(0);
+}
+
+int send_pipecgi(int sockfd, char *host, hw_objectID objectID, char *cgi_env_str, char **objattr, char **text, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, len, new_attr_len;
+ char *tmp, header[80], *head_ptr, *sizestr;
+ struct sockaddr_in serv_addr;
+ struct hostent *hostptr;
+ char *hostip = NULL;
+ char *attributes = NULL;
+ char *documenttype, *new_attr;
+ int newfd, fd, port, size, error;
+ int *ptr;
+
+ if(-1 == (fd = fnCOpenDataCon(sockfd, &port))) {
+ /* not set yet? efree(msg.buf); */
+ return(-1);
+ }
+
+ /*
+ ** Get information about host
+ */
+ if(host) {
+ if((hostptr = gethostbyname(host)) == NULL) {
+ php3_error(E_WARNING, "gethostbyname failed for %s", host);
+ close(fd);
+ return(-1);
+ }
+ } else {
+ close(fd);
+ return(-1);
+ }
+
+ switch(hostptr->h_addrtype) {
+ struct in_addr *ptr1;
+ char *ptr;
+ case AF_INET:
+ ptr = hostptr->h_addr_list[0];
+ ptr1 = (struct in_addr *) ptr;
+ hostip = inet_ntoa(*ptr1);
+ break;
+ default:
+/* php3_printf(stderr, "unknown address type\n"); */
+ break;
+ }
+
+ /* Bottom half of send_getobject */
+ if(0 > bh_send_getobject(sockfd, objectID)) {
+ close(fd);
+ return -1;
+ }
+
+ /* Upper half of send_getobject */
+ if(0 > (error = uh_send_getobject(sockfd, &attributes))) {
+ close(fd);
+ return error;
+ }
+
+ new_attr_len = strlen(attributes) + strlen(cgi_env_str) + 2;
+ new_attr = malloc(new_attr_len);
+ strcpy(new_attr, attributes);
+ strcat(new_attr, cgi_env_str);
+ length = HEADER_LENGTH + strlen(new_attr) + 1 + sizeof(int) + strlen(hostip) + 1 + sizeof(int) + sizeof(int);
+ build_msg_header(&msg, length, msgid++, PIPECGI_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+ if(attributes) efree(attributes);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_str(msg.buf, hostip);
+ tmp = build_msg_int(tmp, port);
+ tmp = build_msg_str(tmp, new_attr);
+ tmp = build_msg_int(tmp, 1);
+ tmp = build_msg_int(tmp, 0x12345678);
+ free(new_attr);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ if(attributes) efree(attributes);
+ efree(msg.buf);
+ close(fd);
+ return(-1);
+ }
+ efree(msg.buf);
+
+ /* Just check if the command was understood */
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ if(attributes) efree(attributes);
+ close(fd);
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if((ptr == NULL) || (*ptr != 0)) {
+ efree(retmsg);
+ if(retmsg->buf) efree(retmsg->buf);
+ if(attributes) efree(attributes);
+ close(fd);
+ return(-1);
+ }
+
+ efree(retmsg);
+ efree(retmsg->buf);
+
+ /* passively open the data connection. The HG server is probably
+ already waiting for us.
+ */
+ len = sizeof(serv_addr);
+ if((newfd = accept(fd, (struct sockaddr *) &serv_addr, &len)) < 0) {
+ if(attributes) efree(attributes);
+ close(fd);
+ return(-1);
+ } else {
+ close(fd);
+ }
+
+ /* First of all read the header */
+ head_ptr = header;
+ while((read_to(newfd, head_ptr, 1, rtimeout) == 1) && (*head_ptr != '\0')) {
+ head_ptr++;
+ }
+
+ /* Let's see how big the document is and read it into var text */
+ sizestr = strstr(header, "sz=");
+ if(sizestr) {
+ sizestr += 3;
+ sscanf(sizestr, "%d\n", &size);
+ *count = size;
+ if((size != 0) && (NULL != (*text = malloc(size+1)))) {
+ read_to(newfd, *text, size, rtimeout);
+ }
+ } else {
+ *text = NULL;
+ }
+
+ /* close the data connection */
+ close(newfd);
+
+ documenttype = fnAttributeValue(attributes, "DocumentType");
+
+ /* Make a copy with strdup (not estrdup), because we want to
+ keep the attributes in hw_document struct.
+ */
+ *objattr = strdup(attributes);
+ efree(attributes);
+
+ if(documenttype) efree(documenttype);
+ return(0);
+}
+
+int send_putdocument(int sockfd, char *host, hw_objectID parentID, char *objectRec, char *text, int count)
+{
+ hg_msg msg, *retmsg;
+ int length, len;
+ char *tmp, header[80], parms[30], *head_ptr;
+ struct sockaddr_in serv_addr;
+ struct hostent *hostptr;
+ char *hostip = NULL;
+ int newfd, fd, port, objectID, error;
+ int *ptr;
+
+ /* First of all we have to insert the document record */
+ sprintf(parms, "Parent=0x%x", parentID);
+ length = HEADER_LENGTH + strlen(objectRec) + 1 + strlen(parms) + 1;
+
+ build_msg_header(&msg, length, msgid++, INSERTOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_str(msg.buf, objectRec);
+ tmp = build_msg_str(tmp, parms);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if(0 == (error = *ptr)) {
+ ptr++;
+ objectID = *ptr;
+ } else {
+ efree(retmsg);
+ if(retmsg->buf) efree(retmsg->buf);
+ return(error);
+ }
+
+ efree(retmsg->buf);
+ efree(retmsg);
+
+ /*
+ ** Get information about host
+ */
+ if(host) {
+ if((hostptr = gethostbyname(host)) == NULL) {
+ php3_error(E_WARNING, "gethostbyname failed for %s", host);
+ /* close(fd); fd is not set yet */
+ return(-1);
+ }
+ } else {
+ /* close(fd); fd is not set yet */
+ return(-1);
+ }
+
+ switch(hostptr->h_addrtype) {
+ struct in_addr *ptr1;
+ char *ptr;
+ case AF_INET:
+ ptr = hostptr->h_addr_list[0];
+ ptr1 = (struct in_addr *) ptr;
+ hostip = inet_ntoa(*ptr1);
+ break;
+ default:
+/* fprintf(stderr, "unknown address type\n"); */
+ break;
+ }
+
+ if(-1 == (fd = fnCOpenDataCon(sockfd, &port))) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ /* Start building the PUTDOCUMENT message. I works even if
+ the Refno is skipped. I guess the path can be omitted too. */
+ length = HEADER_LENGTH + sizeof(hw_objectID) + sizeof(int) + strlen(hostip) + 1 + strlen("Hyperwave") + 1+ strlen("Refno=0x12345678") + 1;
+
+ build_msg_header(&msg, length, msgid++, PUTDOCUMENT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+ tmp = build_msg_int(tmp, port);
+ tmp = build_msg_str(tmp, hostip);
+ tmp = build_msg_str(tmp, "Hyperwave");
+ tmp = build_msg_str(tmp, "Refno=0x12345678");
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ close(fd);
+ return(-1);
+ }
+ efree(msg.buf);
+
+ /* passively open the data connection. The HG server is probably
+ already waiting for us.
+ */
+ len = sizeof(serv_addr);
+ if((newfd = accept(fd, (struct sockaddr *) &serv_addr, &len)) < 0) {
+ close(fd);
+ return(-1);
+ } else {
+ close(fd);
+ }
+
+ /* First of all write the header. According to the documentation
+ there should be a header first. Well, after some investigation
+ with tcpdump I found out, that Harmony and wavemaster don't
+ sent it. The also do not sent the Refno in the PUTDOCUMENT msg.
+ Anyway, we sent both. */
+ head_ptr = header;
+ sprintf(header, "HGHDR\nsz=%d\nref=12345678\n", count);
+ len = strlen(header) + 1;
+ if(len != write_to(newfd, header, len, wtimeout)) {
+ close(newfd);
+ return(-1);
+ }
+
+ /* And now the document */
+ if(count != write_to(newfd, text, count, wtimeout)) {
+ close(newfd);
+ return(-1);
+ }
+
+ /* The data connection has to be close before the return
+ msg can be read. The server will not sent it before. */
+ close(newfd);
+
+ /* Just check if the command was understood */
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ close(fd);
+ return(-1);
+ }
+
+ ptr = (int *) retmsg->buf;
+ if((ptr == NULL) || (*ptr != 0)) {
+ efree(retmsg);
+ if(retmsg->buf) efree(retmsg->buf);
+ close(fd);
+ return(-1);
+ }
+
+ efree(retmsg);
+ efree(retmsg->buf);
+
+ return(0);
+}
+
+int send_getsrcbydest(int sockfd, hw_objectID objectID, char ***childrec, int *count)
+{
+ hg_msg msg, *retmsg;
+ int length, i, error;
+ char *tmp;
+ int *childIDs = NULL;
+ char **objptr;
+ int *ptr, *ptr1;
+
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+
+ build_msg_header(&msg, length, msgid++, GETSRCBYDEST_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, objectID);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL )
+ return(-1);
+
+ ptr = (int *) retmsg->buf;
+ if(ptr == NULL) {
+ if(retmsg) efree(retmsg);
+ return -1;
+ }
+ if(*ptr++ == 0) {
+ *count = *ptr;
+ ptr++;
+ if(NULL != (childIDs = emalloc(*count * sizeof(hw_objectID)))) {
+ ptr1 = childIDs;
+ for(i=0; i<*count; ptr++, i++)
+ ptr1[i] = *ptr;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ efree(retmsg->buf);
+ efree(retmsg);
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+ } else {
+ error = *((int *) retmsg->buf);
+ efree(retmsg->buf);
+ efree(retmsg);
+ return error;
+ }
+
+ /* Now get for each source the object record */
+ for(i=0; i<*count; i++) {
+ length = HEADER_LENGTH + sizeof(hw_objectID);
+ build_msg_header(&msg, length, childIDs[i], GETOBJECT_MESSAGE);
+
+ if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ tmp = build_msg_int(msg.buf, childIDs[i]);
+
+ if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
+ efree(msg.buf);
+ return(-1);
+ }
+
+ efree(msg.buf);
+ }
+
+ if(NULL == (objptr = (char **) emalloc(*count * sizeof(hw_objrec *)))) {
+ /* if emalloc fails, get at least all remaining messages from server */
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ *childrec = NULL;
+ lowerror = LE_MALLOC;
+ return(-1);
+ } else {
+ *childrec = objptr;
+
+ for(i=0; i<*count; i++) {
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg != NULL ) {
+ if(0 == (int) *(retmsg->buf)) {
+ *objptr = estrdup(retmsg->buf+sizeof(int));
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ } else {
+ *objptr = NULL;
+ objptr++;
+ efree(retmsg->buf);
+ efree(retmsg);
+ }
+ }
+ }
+ }
+
+ return(0);
+}
+
+char *get_hw_info(hw_connection *conn)
+ {
+ char temp[200];
+ int len;
+ struct sockaddr_in serv_addr;
+
+ len = sizeof (serv_addr);
+ if(getsockname(conn->socket, (struct sockaddr *)&serv_addr, &len) < 0)
+ return(NULL);
+
+ sprintf(temp, "%s, %s, %d, %s, %d, %d", conn->server_string, conn->hostname,
+ conn->version, conn->username,
+ serv_addr.sin_port, conn->swap_on);
+ return(estrdup(temp));
+ }
+
+static int send_hg_msg(int sockfd, hg_msg *msg, int length)
+{
+ char *buf, *tmp;
+
+#ifdef HW_DEBUG
+ php3_printf("<B>Sending msg: </B>type = %d -- id = %d<BR>\n", msg->msg_type, msg->version_msgid);
+#endif
+ if ( length < HEADER_LENGTH ) {
+/* fprintf(stderr, "send_hg_msg: bad msg\n"); */
+ return(-1);
+ }
+
+ if ( (tmp = buf = (char *)emalloc(length)) == NULL ) {
+/* perror("send_hg_msg"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+ memcpy(tmp, (char *) &(msg->length), 4);
+ tmp += 4;
+ memcpy(tmp, (char *) &(msg->version_msgid), 4);
+ tmp += 4;
+ memcpy(tmp, (char *) &(msg->msg_type), 4);
+ if ( msg->length > HEADER_LENGTH ) {
+ tmp += 4;
+ memcpy(tmp, msg->buf, length-HEADER_LENGTH);
+ }
+
+ if ( hg_write(sockfd, buf, length) == -1 ) {
+ efree(buf);
+ return(-1);
+ }
+
+ efree(buf);
+ return(0);
+}
+
+
+int send_ready(int sockfd)
+{
+ hg_msg ready_msg;
+
+ build_msg_header(&ready_msg, HEADER_LENGTH, version, READY_MESSAGE);
+ ready_msg.buf = NULL;
+
+ if ( send_hg_msg(sockfd, &ready_msg, HEADER_LENGTH) == -1 ) {
+ return(-1);
+ }
+
+ return(0);
+}
+
+
+int send_command(int sockfd, int command, char **answer)
+{
+ hg_msg comm_msg, *retmsg;
+ char *comm_str, *tmp;
+ int respond = 1;
+ int length;
+
+ if ( command == STAT_COMMAND )
+ comm_str = STAT_COMMAND_STR;
+ else
+ comm_str = WHO_COMMAND_STR;
+ length = HEADER_LENGTH + sizeof(respond) + strlen(comm_str) + 1;
+
+ build_msg_header(&comm_msg, length, msgid++, COMMAND_MESSAGE);
+
+ if ( (comm_msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
+/* perror("send_command"); */
+ lowerror = LE_MALLOC;
+ return(-1);
+ }
+
+
+ tmp = build_msg_int(comm_msg.buf, respond);
+ tmp = build_msg_str(tmp, comm_str);
+
+
+ if ( send_hg_msg(sockfd, &comm_msg, length) == -1 ) {
+ efree(comm_msg.buf);
+ return(-1);
+ }
+ efree(comm_msg.buf);
+
+ /* Just check if the command was understood */
+ retmsg = recv_hg_msg(sockfd);
+ if ( retmsg == NULL ) {
+ return(-1);
+ }
+
+ efree(retmsg);
+ *answer = retmsg->buf;
+
+ return(0);
+}
+
+
+static void build_msg_header(hg_msg *msg, int length, int version_msgid, int msg_type)
+{
+ if ( swap_on ) {
+ msg->length = swap(length);
+ msg->version_msgid = swap(version_msgid);
+ msg->msg_type = swap(msg_type);
+ }
+ else {
+ msg->length = length;
+ msg->version_msgid = version_msgid;
+ msg->msg_type = msg_type;
+ }
+}
+
+
+static char *build_msg_int(char *buf, int val) {
+ int tmp;
+
+#ifdef HW_DEBUG
+ php3_printf(" Added int to header: <B>%d</B><BR>\n", val);
+#endif
+ tmp = swap_on ? swap(val) : val;
+ memcpy(buf, (char *)&tmp, 4);
+
+ return(buf+4);
+}
+
+
+static char *build_msg_str(char *buf, char *str)
+{
+ int len = strlen(str)+1;
+
+#ifdef HW_DEBUG
+ php3_printf(" Added str to header: <B>%s</B> (%d)<BR>\n", str, strlen(str));
+#endif
+
+ memcpy(buf, str, len);
+
+ return(buf+len);
+}
+
+
+static int swap(int val)
+{
+ int tmp;
+
+ ((char*)&tmp)[0] = ((char*)&val)[3];
+ ((char*)&tmp)[1] = ((char*)&val)[2];
+ ((char*)&tmp)[2] = ((char*)&val)[1];
+ ((char*)&tmp)[3] = ((char*)&val)[0];
+
+ return(tmp);
+}
+
+
+void close_hg_connection(int sockfd)
+{
+ shutdown(sockfd, 2);
+ close(sockfd);
+}
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * End:
+ */
+
diff --git a/ext/hyperwave/hg_comm.h b/ext/hyperwave/hg_comm.h
new file mode 100644
index 0000000000..d4e1892677
--- /dev/null
+++ b/ext/hyperwave/hg_comm.h
@@ -0,0 +1,196 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of the GNU General Public License as published by |
+ | the Free Software Foundation; either version 2 of the License, or |
+ | (at your option) any later version. |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU General Public License |
+ | along with this program; if not, write to the Free Software |
+ | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
+ +----------------------------------------------------------------------+
+ | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
+ +----------------------------------------------------------------------+
+ */
+
+
+/* $Id$ */
+
+#ifndef _HG_COMM_H
+#define _HG_COMM_H
+
+#if HYPERWAVE
+
+#include "hw_error.h"
+#define HG_SERVER_PORT 418
+
+#define F_DISTRIBUTED 0x80000000
+#define F_COMPRESSED 0x40000000
+#define F_VERSION 0x00003fff
+#define VERSION 717L /* 7.05 */
+
+#define HEADER_LENGTH 12
+
+#define STAT_COMMAND_STR "stat"
+#define WHO_COMMAND_STR "who"
+#define STAT_COMMAND 1
+#define WHO_COMMAND 2
+
+#define GETDOCBYANCHOR_MESSAGE 2
+#define GETCHILDCOLL_MESSAGE 3
+#define GETPARENT_MESSAGE 4
+#define GETCHILDDOCCOLL_MESSAGE 5
+#define GETOBJECT_MESSAGE 7
+#define GETANCHORS_MESSAGE 8
+#define GETOBJBYQUERY_MESSAGE 9
+#define GETOBJBYQUERYCOLL_MESSAGE 10
+#define GETTEXT_MESSAGE 12
+#define INSDOC_MESSAGE 14
+#define INSCOLL_MESSAGE 17
+#define GETSRCBYDEST_MESSAGE 19
+#define MVCPDOCSCOLL_MESSAGE 22
+#define MVCPCOLLSCOLL_MESSAGE 23
+#define IDENTIFY_MESSAGE 24
+#define READY_MESSAGE 25
+#define COMMAND_MESSAGE 26
+#define CHANGEOBJECT_MESSAGE 27
+#define EDITTEXT_MESSAGE 28
+#define GETANDLOCK_MESSAGE 29
+#define UNLOCK_MESSAGE 30
+#define INCOLLECTIONS_MESSAGE 31
+#define INSERTOBJECT_MESSAGE 32
+#define PIPEDOCUMENT_MESSAGE 36
+#define DELETEOBJECT_MESSAGE 37
+#define PUTDOCUMENT_MESSAGE 38
+#define GETREMOTE_MESSAGE 39
+#define GETREMOTECHILDREN_MESSAGE 40
+#define CHILDREN_MESSAGE 44
+#define GETCGI_MESSAGE 45
+#define PIPECGI_MESSAGE 46
+
+#define HW_DEFAULT_LINK 0
+#define HW_IMAGE_LINK 1
+#define HW_BACKGROUND_LINK 2
+#define HW_INTAG_LINK 3
+#define HW_APPLET_LINK 4
+
+#define COPY 0
+#define MOVE 1
+#define DOCUMENT 0
+#define COLLECTION 1
+
+/* Low error messages */
+#define LE_MALLOC -1
+
+typedef struct {
+ int id; /* object ID of anchor */
+ int tanchor; /* Type of anchor. Can be 1=Src, 2=Dest */
+ int start; /* start of anchor */
+ int end; /* end of anchor */
+ char *nameanchor; /* name tag attribute of destination document */
+ /* if anchor is of type Src the following are used as well */
+ char *destdocname; /* name of destination document */
+ char *link; /* url for external destination */
+ int linktype; /* type of link. see above */
+ char *tagattr; /* more attributes of tag, like Border=0 */
+ char *htmlattr; /* */
+ char *codebase; /* codebase of applet */
+ char *code; /* code of applet */
+ char *fragment; /* name link of Src */
+
+ /* if anchor is of type Dest the following are used as well */
+ char *keyword; /* name link of Dest */
+ } ANCHOR;
+
+typedef struct {
+ int length;
+ int version_msgid;
+ int msg_type;
+ char *buf;
+} hg_msg;
+
+typedef struct {
+ int socket;
+ int swap_on;
+ int version;
+ char *server_string;
+ char *hostname;
+ char *username;
+ int lasterror;
+ int linkroot;
+} hw_connection;
+
+typedef int hw_objectID;
+typedef char hw_objrec;
+
+extern void set_swap(int do_swap);
+extern int open_hg_connection(char *server_name, int port);
+extern void close_hg_connection(int sockfd);
+extern int initialize_hg_connection(int sockfd, int *do_swap, int *version, char **userdata, char **server_string, char *username, char *password);
+
+extern int send_ready(int sockfd);
+extern int send_command(int sockfd, int command, char **answer);
+
+extern hg_msg *recv_hg_msg(int sockfd);
+extern hg_msg *recv_ready(int sockfd);
+extern hg_msg *recv_command(int sockfd);
+
+extern char *fnInsStr(char *str, int pos, char *insstr);
+extern int fnAttributeCompare(char *object, char *attrname, char *value);
+extern int getrellink(int sockfd, int rootID, int thisID, int destID, char **reldesstr);
+
+extern int send_deleteobject(int sockfd, hw_objectID objectID);
+extern int send_changeobject(int sockfd, hw_objectID objectID, char *mod);
+extern int send_getobject(int sockfd, hw_objectID objectID, char **attributes);
+extern int send_getandlock(int sockfd, hw_objectID objectID, char **attributes);
+extern int send_unlock(int sockfd, hw_objectID objectID);
+extern int send_gettext(int sockfd, hw_objectID objectID, int mode, int rootid, char **objattr, char **bodytag, char **text, int *count);
+extern int send_edittext(int sockfd, char *objattr, char *text);
+extern int send_getcgi(int sockfd, hw_objectID objectID, char *cgi_env_str, char **objattr, char **text, int *count);
+extern int send_getremote(int sockfd, hw_objectID objectID, char **objattr, char **text, int *count);
+extern int send_getremotechildren(int sockfd, char *attributes, char **text, int **childIDs, int *count);
+extern int send_docbyanchor(int sockfd, hw_objectID objectID, hw_objectID *anchorID);
+extern int send_docbyanchorobj(int sockfd, hw_objectID objectID, char **objrec);
+extern int send_mvcpdocscollscoll(int sockfd, hw_objectID *objectIDs, int count, int from, int dest, int cpmv, int docscoll);
+extern int send_childrenobj(int sockfd, hw_objectID objectID, char ***childrec, int *count);
+extern int send_getchildcoll(int sockfd, int objectID, hw_objectID **childIDs, int *count);
+extern int send_getchildcollobj(int sockfd, hw_objectID objectID, hw_objrec ***childrec, int *count);
+extern int send_getchilddoccoll(int sockfd, hw_objectID objectID, hw_objectID **childIDs, int *count);
+extern int send_getchilddoccollobj(int sockfd, hw_objectID objectID, hw_objrec ***childrec, int *count);
+extern int send_getanchors(int sockfd, hw_objectID objectID, hw_objectID **anchorIDs, int *count);
+extern int send_getanchorsobj(int sockfd, hw_objectID objectID, char ***childrec, int *count);
+extern int send_getobjbyquery(int sockfd, char *query, int maxhits, hw_objectID **childIDs, int *count);
+extern int send_getobjbyqueryobj(int sockfd, char *query, int maxhits, char ***childrec, int *count);
+extern int send_getobjbyquerycoll(int sockfd, hw_objectID collID, char *query, int maxhits, hw_objectID **childIDs, int *count);
+extern int send_getobjbyquerycollobj(int sockfd, hw_objectID collID, char *query, int maxhits, char ***childrec, int *count);
+extern int send_identify(int sockfd, char *name, char *passwd, char **userdata);
+extern int send_getparents(int sockfd, hw_objectID objectID, hw_objectID **childIDs, int *count);
+extern int send_children(int sockfd, hw_objectID objectID, hw_objectID **childIDs, int *count);
+extern int send_getparentsobj(int sockfd, hw_objectID objectID, char ***childrec, int *count);
+extern int send_pipedocument(int sockfd, char *hostname, hw_objectID objectID, int mode, int rootid, char** objattr, char **bodytag, char **text, int *count);
+extern int send_pipecgi(int sockfd, char *host, hw_objectID objectID, char *cgi_env_str, char **objattr, char **text, int *count);
+extern int send_putdocument(int sockfd, char *hostname, hw_objectID objectID, char *objectRec, char *text, int count);
+extern int send_inscoll(int sockfd, hw_objectID objectID, char *objrec, hw_objectID *new_objectID);
+extern int send_insertobject(int sockfd, char *objrec, char *parms, hw_objectID *objectID);
+extern int send_insdoc(int sockfd, hw_objectID objectID, char *objrec, char *text, hw_objectID *new_objectID);
+extern int send_incollections(int sockfd, int retcol, int cobjids, hw_objectID *objectIDs, int ccollids, hw_objectID *collIDs, int *count, hw_objectID **retIDs);
+extern int send_getsrcbydest(int sockfd, hw_objectID objid, char ***childrec, int *count);
+extern int send_dummy(int sockfd, hw_objectID objectID, int msgid, char **attributes);
+extern char *get_hw_info(hw_connection *conn);
+
+#define send_mvcpdocscoll(sockfd,objectIDs,count,from,dest,mvcp) \
+ send_mvcpdocscollscoll(sockfd,objectIDs,count,from,dest,mvcp,DOCUMENT)
+#define send_mvcpcollscoll(sockfd,objectIDs,count,from,dest,mvcp) \
+ send_mvcpdocscollscoll(sockfd,objectIDs,count,from,dest,mvcp,COLLECTION)
+
+#endif
+#endif
diff --git a/ext/hyperwave/hw.c b/ext/hyperwave/hw.c
new file mode 100644
index 0000000000..db1da999db
--- /dev/null
+++ b/ext/hyperwave/hw.c
@@ -0,0 +1,3062 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of the GNU General Public License as published by |
+ | the Free Software Foundation; either version 2 of the License, or |
+ | (at your option) any later version. |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU General Public License |
+ | along with this program; if not, write to the Free Software |
+ | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
+ +----------------------------------------------------------------------+
+ | Authors: Uwe Steinmann |
+ | |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+#if COMPILE_DL
+#include "dl/phpdl.h"
+#endif
+
+#include <stdlib.h>
+
+#if !(WIN32|WINNT)
+#include "config.h"
+#endif
+#include "php.h"
+#include "functions/head.h"
+
+#if HYPERWAVE
+
+
+#include "hw.h"
+
+#if APACHE
+# ifndef DEBUG
+# undef palloc
+# endif
+#endif
+
+hw_module php3_hw_module;
+
+function_entry hw_functions[] = {
+ {"hw_connect", php3_hw_connect, NULL},
+ {"hw_pconnect", php3_hw_pconnect, NULL},
+ {"hw_close", php3_hw_close, NULL},
+ {"hw_root", php3_hw_root, NULL},
+ {"hw_info", php3_hw_info, NULL},
+ {"hw_connection_info", php3_hw_connection_info, NULL},
+ {"hw_error", php3_hw_error, NULL},
+ {"hw_errormsg", php3_hw_errormsg, NULL},
+ {"hw_getparentsobj", php3_hw_getparentsobj, NULL},
+ {"hw_getparents", php3_hw_getparents, NULL},
+ {"hw_children", php3_hw_children, NULL},
+ {"hw_childrenobj", php3_hw_childrenobj, NULL},
+ {"hw_getchildcoll", php3_hw_getchildcoll, NULL},
+ {"hw_getchildcollobj", php3_hw_getchildcollobj, NULL},
+ {"hw_getobject", php3_hw_getobject, NULL},
+ {"hw_getandlock", php3_hw_getandlock, NULL},
+ {"hw_unlock", php3_hw_unlock, NULL},
+ {"hw_gettext", php3_hw_gettext, NULL},
+ {"hw_edittext", php3_hw_edittext, NULL},
+ {"hw_getcgi", php3_hw_getcgi, NULL},
+ {"hw_getremote", php3_hw_getremote, NULL},
+ {"hw_getremotechildren", php3_hw_getremotechildren, NULL},
+ {"hw_pipedocument", php3_hw_pipedocument, NULL},
+ {"hw_pipecgi", php3_hw_pipecgi, NULL},
+ {"hw_insertdocument", php3_hw_insertdocument, NULL},
+ {"hw_mv", php3_hw_mv, NULL},
+ {"hw_cp", php3_hw_cp, NULL},
+ {"hw_deleteobject", php3_hw_deleteobject, NULL},
+ {"hw_changeobject", php3_hw_changeobject, NULL},
+ {"hw_docbyanchor", php3_hw_docbyanchor, NULL},
+ {"hw_docbyanchorobj", php3_hw_docbyanchorobj, NULL},
+ {"hw_getobjectbyquery", php3_hw_getobjectbyquery, NULL},
+ {"hw_getobjectbyqueryobj", php3_hw_getobjectbyqueryobj, NULL},
+ {"hw_getobjectbyquerycoll", php3_hw_getobjectbyquerycoll, NULL},
+ {"hw_getobjectbyquerycollobj", php3_hw_getobjectbyquerycollobj,NULL},
+ {"hw_getchilddoccoll", php3_hw_getchilddoccoll, NULL},
+ {"hw_getchilddoccollobj", php3_hw_getchilddoccollobj, NULL},
+ {"hw_getanchors", php3_hw_getanchors, NULL},
+ {"hw_getanchorsobj", php3_hw_getanchorsobj, NULL},
+ {"hw_getusername", php3_hw_getusername, NULL},
+ {"hw_setlinkroot", php3_hw_setlinkroot, NULL},
+ {"hw_identify", php3_hw_identify, NULL},
+ {"hw_free_document", php3_hw_free_document, NULL},
+ {"hw_new_document", php3_hw_new_document, NULL},
+ {"hw_output_document", php3_hw_output_document, NULL},
+ {"hw_outputdocument", php3_hw_output_document, NULL},
+ {"hw_document_size", php3_hw_document_size, NULL},
+ {"hw_documentsize", php3_hw_document_size, NULL},
+ {"hw_document_attributes", php3_hw_document_attributes, NULL},
+ {"hw_documentattributes", php3_hw_document_attributes, NULL},
+ {"hw_document_bodytag", php3_hw_document_bodytag, NULL},
+ {"hw_documentbodytag", php3_hw_document_bodytag, NULL},
+ {"hw_document_content", php3_hw_document_content, NULL},
+ {"hw_objrec2array", php3_hw_objrec2array, NULL},
+ {"hw_array2objrec", php3_hw_array2objrec, NULL},
+ {"hw_incollections", php3_hw_incollections, NULL},
+ {"hw_inscoll", php3_hw_inscoll, NULL},
+ {"hw_insertobject", php3_hw_insertobject, NULL},
+ {"hw_insdoc", php3_hw_insdoc, NULL},
+ {"hw_getsrcbydestobj", php3_hw_getsrcbydestobj, NULL},
+ {"hw_getrellink", php3_hw_getrellink, NULL},
+ {"hw_who", php3_hw_who, NULL},
+ {"hw_stat", php3_hw_stat, NULL},
+ {"hw_dummy", php3_hw_dummy, NULL},
+ {NULL, NULL, NULL}
+};
+
+php3_module_entry hw_module_entry = {
+ "HyperWave", hw_functions, php3_minit_hw, NULL, NULL, NULL, php3_info_hw, 0, 0, 0, NULL
+};
+
+void print_msg(hg_msg *msg, char *str, int txt);
+
+#if COMPILE_DL
+DLEXPORT php3_module_entry *get_module(void) { return &hw_module_entry; }
+#endif
+
+void _close_hw_link(hw_connection *conn)
+{
+ if(conn->hostname)
+ free(conn->hostname);
+ if(conn->username)
+ free(conn->username);
+ close(conn->socket);
+ free(conn);
+ php3_hw_module.num_links--;
+}
+
+void _close_hw_plink(hw_connection *conn)
+{
+ if(conn->hostname)
+ free(conn->hostname);
+ if(conn->username)
+ free(conn->username);
+ close(conn->socket);
+ free(conn);
+ php3_hw_module.num_links--;
+ php3_hw_module.num_persistent--;
+}
+
+void _free_hw_document(hw_document *doc)
+{
+ if(doc->data)
+ free(doc->data);
+ if(doc->attributes)
+ free(doc->attributes);
+ if(doc->bodytag)
+ free(doc->bodytag);
+ free(doc);
+}
+
+/* creates an array in return value and frees all memory
+ * Also adds as an assoc. array at the end of the return array with
+ * statistics.
+ */
+int make_return_objrec(pval **return_value, char **objrecs, int count)
+{
+ pval stat_arr;
+ int i;
+ int hidden, collhead, fullcollhead, total;
+ int collheadnr, fullcollheadnr;
+
+ if (array_init(*return_value) == FAILURE) {
+ /* Ups, failed! Let's at least free the memory */
+ for(i=0; i<count; i++)
+ efree(objrecs[i]);
+ efree(objrecs);
+ return -1;
+ }
+
+ hidden = collhead = fullcollhead = total = 0;
+ collheadnr = fullcollheadnr = -1;
+ for(i=0; i<count; i++) {
+ /* Fill the array with entries. No need to free objrecs[i], since
+ * it is not duplicated in add_next_index_string().
+ */
+ if(NULL != objrecs[i]) {
+ if(0 == fnAttributeCompare(objrecs[i], "PresentationHints", "Hidden"))
+ hidden++;
+ if(0 == fnAttributeCompare(objrecs[i], "PresentationHints", "CollectionHead")) {
+ collhead++;
+ collheadnr = total;
+ }
+ if(0 == fnAttributeCompare(objrecs[i], "PresentationHints", "FullCollectionHead")) {
+ fullcollhead++;
+ fullcollheadnr = total;
+ }
+ total++;
+ add_next_index_string(*return_value, objrecs[i], 0);
+ }
+ }
+ efree(objrecs);
+
+ /* Array for statistics */
+ if (array_init(&stat_arr) == FAILURE) {
+ return -1;
+ }
+
+ add_assoc_long(&stat_arr, "Hidden", hidden);
+ add_assoc_long(&stat_arr, "CollectionHead", collhead);
+ add_assoc_long(&stat_arr, "FullCollectionHead", fullcollhead);
+ add_assoc_long(&stat_arr, "Total", total);
+ add_assoc_long(&stat_arr, "CollectionHeadNr", collheadnr);
+ add_assoc_long(&stat_arr, "FullCollectionHeadNr", fullcollheadnr);
+
+ /* Add the stat array */
+ _php3_hash_next_index_insert((*return_value)->value.ht, &stat_arr, sizeof(pval), NULL);
+
+ /* The title array can now be freed, but I don't know how */
+ return 0;
+}
+
+/*
+** creates an array return value from object record
+*/
+int make_return_array_from_objrec(pval **return_value, char *objrec) {
+ pval title_arr, desc_arr;
+ char *attrname, *str, *temp, language[3], *title;
+ int iTitle, iDesc;
+ int hasTitle = 0;
+ int hasDescription = 0;
+
+ if (array_init(*return_value) == FAILURE) {
+ (*return_value)->type = IS_STRING;
+ (*return_value)->value.str.val = empty_string;
+ (*return_value)->value.str.len = 0;
+ return -1;
+ }
+
+ /* Array for titles. Only if we have at least one title */
+/* if(0 == strncmp(objrec, "Title=", 6)) { */
+ if (array_init(&title_arr) == FAILURE) {
+ return -1;
+ }
+ hasTitle = 1;
+/* } */
+
+ /* Array for Descriptions. Only if we have at least one description */
+/* if(0 == strncmp(objrec, "Description=", 12)) { */
+ if (array_init(&desc_arr) == FAILURE) {
+ return -1;
+ }
+ hasDescription = 1;
+/* } */
+
+ /* Fill Array of titles and descriptions */
+ temp = estrdup(objrec);
+ attrname = strtok(temp, "\n");
+ while(attrname != NULL) {
+ str = attrname;
+ iTitle = 0;
+ iDesc = 0;
+ if(0 == strncmp(attrname, "Title=", 6)) {
+ str += 6;
+ iTitle = 1;
+ } else if(0 == strncmp(attrname, "Description=", 12)) {
+ str += 12;
+ iDesc = 1;
+ }
+ if(iTitle || iDesc) { /* Poor error check if end of string */
+ if(str[2] == ':') {
+ str[2] = '\0';
+ strcpy(language, str);
+ str += 3;
+ } else
+ strcpy(language, "xx");
+
+ title = str;
+/* while((*str != '=') && (*str != '\0'))
+ str++;
+ *str = '\0';
+*/ if(iTitle)
+ add_assoc_string(&title_arr, language, title, 1);
+ else
+ add_assoc_string(&desc_arr, language, title, 1);
+ }
+ attrname = strtok(NULL, "\n");
+ }
+ efree(temp);
+
+ /* Add the title array, if we have one */
+ if(hasTitle) {
+ _php3_hash_update((*return_value)->value.ht, "Title", 6, &title_arr, sizeof(pval), NULL);
+
+ /* The title array can now be freed, but I don't know how */
+ }
+
+ if(hasDescription) {
+ /* Add the description array, if we have one */
+ _php3_hash_update((*return_value)->value.ht, "Description", 12, &desc_arr, sizeof(pval), NULL);
+
+ /* The description array can now be freed, but I don't know how */
+ }
+
+ /* All other attributes. Make a another copy first */
+ temp = estrdup(objrec);
+ attrname = strtok(temp, "\n");
+ while(attrname != NULL) {
+ str = attrname;
+ /* We don't want to insert titles a second time */
+ if((0 != strncmp(attrname, "Title=", 6)) &&
+ (0 != strncmp(attrname, "Description=", 12))) {
+ while((*str != '=') && (*str != '\0'))
+ str++;
+ *str = '\0';
+ str++;
+ add_assoc_string(*return_value, attrname, str, 1);
+ }
+ attrname = strtok(NULL, "\n");
+ }
+ efree(temp);
+
+ return(0);
+}
+
+static char * make_objrec_from_array(HashTable *lht) {
+ int i, count, keytype;
+ ulong length;
+ char *key, str[1024], *objrec = NULL;
+ pval *keydata;
+
+ if(NULL == lht)
+ return NULL;
+
+ if(0 == (count = _php3_hash_num_elements(lht)))
+ return NULL;
+
+ _php3_hash_internal_pointer_reset(lht);
+ objrec = malloc(1);
+ *objrec = '\0';
+ for(i=0; i<count; i++) {
+ keytype = _php3_hash_get_current_key(lht, &key, &length);
+ if(HASH_KEY_IS_STRING == keytype) {
+ _php3_hash_get_current_data(lht, (void **) &keydata);
+ switch(keydata->type) {
+ case IS_STRING:
+ sprintf(str, "%s=%s\n", key, keydata->value.str.val);
+ break;
+ case IS_LONG:
+ sprintf(str, "%s=0x%lX\n", key, keydata->value.lval);
+ break;
+ }
+ efree(key);
+ objrec = realloc(objrec, strlen(objrec)+strlen(str)+1);
+ strcat(objrec, str);
+ }
+ _php3_hash_move_forward(lht);
+ }
+ return objrec;
+}
+
+static int * make_ints_from_array(HashTable *lht) {
+ int i, count;
+ int *objrec = NULL;
+ pval *keydata;
+
+ if(NULL == lht)
+ return NULL;
+
+ if(0 == (count = _php3_hash_num_elements(lht)))
+ return NULL;
+
+ _php3_hash_internal_pointer_reset(lht);
+ if(NULL == (objrec = emalloc(count*sizeof(int))))
+ return NULL;
+ for(i=0; i<count; i++) {
+ _php3_hash_get_current_data(lht, (void **) &keydata);
+ switch(keydata->type) {
+ case IS_LONG:
+ objrec[i] = keydata->value.lval;
+ break;
+ default:
+ objrec[i] = 0;
+ }
+ _php3_hash_move_forward(lht);
+ }
+ return objrec;
+}
+
+int php3_minit_hw(INIT_FUNC_ARGS) {
+
+ if (cfg_get_long("hw.allow_persistent",&php3_hw_module.allow_persistent)==FAILURE) {
+ php3_hw_module.allow_persistent=1;
+ }
+ if (cfg_get_long("hw.max_persistent",&php3_hw_module.max_persistent)==FAILURE) {
+ php3_hw_module.max_persistent=-1;
+ }
+ if (cfg_get_long("hw.max_links",&php3_hw_module.max_links)==FAILURE) {
+ php3_hw_module.max_links=-1;
+ }
+ php3_hw_module.num_persistent=0;
+ php3_hw_module.le_socketp = register_list_destructors(_close_hw_link,NULL);
+ php3_hw_module.le_psocketp = register_list_destructors(NULL,_close_hw_plink);
+ php3_hw_module.le_document = register_list_destructors(_free_hw_document,NULL);
+
+ return SUCCESS;
+}
+
+static void php3_hw_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
+{
+ pval *argv[4];
+ int argc;
+ int sockfd;
+ int port = 0;
+ char *host = NULL;
+ char *userdata = NULL;
+ char *server_string = NULL;
+ char *username = NULL;
+ char *password = NULL;
+ char *hashed_details;
+ char *str = NULL;
+ char buffer[20];
+ int hashed_details_length;
+ hw_connection *ptr;
+ int do_swap;
+ int version = 0;
+ TLS_VARS;
+
+ argc = ARG_COUNT(ht);
+ switch(argc) {
+ case 2:
+ if (getParametersArray(ht, argc, argv) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ break;
+ case 4:
+ if (getParametersArray(ht, argc, argv) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ break;
+ default:
+ WRONG_PARAM_COUNT;
+ }
+
+ /* Host: */
+ convert_to_string(argv[0]);
+ host = (char *) estrndup(argv[0]->value.str.val,argv[0]->value.str.len);
+
+ /* Port: */
+ convert_to_long(argv[1]);
+ port = argv[1]->value.lval;
+
+ /* Username and Password */
+ if(argc > 2) {
+ /* Username */
+ convert_to_string(argv[2]);
+ username = (char *) estrndup(argv[2]->value.str.val,argv[2]->value.str.len);
+ /* Password */
+ convert_to_string(argv[3]);
+ password = (char *) estrndup(argv[3]->value.str.val,argv[3]->value.str.len);
+ }
+
+ /* Create identifier string for connection */
+ sprintf(buffer, "%d", port);
+ hashed_details_length = strlen(host)+strlen(buffer)+8;
+ if(NULL == (hashed_details = (char *) emalloc(hashed_details_length+1))) {
+ if(host) efree(host);
+ if(password) efree(password);
+ if(username) efree(username);
+ php3_error(E_ERROR, "Could not get memory for connection details");
+ RETURN_FALSE;
+ }
+ sprintf(hashed_details,"hw_%s_%d",host,port);
+
+ if (persistent) {
+ list_entry *le;
+
+ /* try to find if we already have this link in our persistent list */
+ if (_php3_hash_find(plist, hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) {
+ list_entry new_le;
+
+ if (php3_hw_module.max_links!=-1 && php3_hw_module.num_links>=php3_hw_module.max_links) {
+ php3_error(E_ERROR,"Hyperwave: Too many open links (%d)",php3_hw_module.num_links);
+ if(host) efree(host);
+ if(username) efree(username);
+ if(password) efree(password);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+ if (php3_hw_module.max_persistent!=-1 && php3_hw_module.num_persistent>=php3_hw_module.max_persistent) {
+ php3_error(E_ERROR,"Hyperwave: Too many open persistent links (%d)",php3_hw_module.num_persistent);
+ if(host) efree(host);
+ if(username) efree(username);
+ if(password) efree(password);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+
+ if ( (sockfd = open_hg_connection(host, port)) < 0 ) {
+ php3_error(E_ERROR, "Could not open connection to %s, Port: %d (retval=%d)", host, port, sockfd);
+ if(host) efree(host);
+ if(username) efree(username);
+ if(password) efree(password);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+
+ if(NULL == (ptr = malloc(sizeof(hw_connection)))) {
+ php3_error(E_ERROR, "Could not get memory for connection structure");
+ if(host) efree(host);
+ if(username) efree(username);
+ if(password) efree(password);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+
+ if(0 != (ptr->lasterror = initialize_hg_connection(sockfd, &do_swap, &version, &userdata, &server_string, username, password))) {
+ php3_error(E_ERROR, "Could not initalize hyperwave connection");
+ if(host) efree(host);
+ if(username) efree(username);
+ if(password) efree(password);
+ if(userdata) efree(userdata);
+ if(server_string) free(server_string);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+
+ if(username) efree(username);
+ if(password) efree(password);
+
+ ptr->version = version;
+ ptr->server_string = server_string;
+ ptr->socket = sockfd;
+ ptr->swap_on = do_swap;
+ ptr->linkroot = 0;
+ ptr->hostname = strdup(host);
+ ptr->username = strdup("anonymous");
+
+ new_le.ptr = (void *) ptr;
+ new_le.type = php3_hw_module.le_psocketp;;
+
+ if (_php3_hash_update(plist,hashed_details,hashed_details_length+1,(void *) &new_le, sizeof(list_entry), NULL)==FAILURE) {
+ php3_error(E_ERROR, "Could not hash table with connection details");
+ if(host) efree(host);
+ if(username) efree(username);
+ if(password) efree(password);
+ if(server_string) free(server_string);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+
+ php3_hw_module.num_links++;
+ php3_hw_module.num_persistent++;
+ } else {
+ /*php3_printf("Found already open connection\n"); */
+ if (le->type != php3_hw_module.le_psocketp) {
+ RETURN_FALSE;
+ }
+ ptr = le->ptr;
+ }
+
+ return_value->value.lval = php3_list_insert(ptr,php3_hw_module.le_psocketp);
+ return_value->type = IS_LONG;
+
+ } else {
+ list_entry *index_ptr,new_index_ptr;
+
+ /* first we check the hash for the hashed_details key. if it exists,
+ * it should point us to the right offset where the actual hyperwave link sits.
+ * if it doesn't, open a new hyperwave link, add it to the resource list,
+ * and add a pointer to it with hashed_details as the key.
+ */
+ if (_php3_hash_find(list,hashed_details,hashed_details_length+1,(void **) &index_ptr)==SUCCESS) {
+ int type,link;
+ void *ptr;
+
+ if (index_ptr->type != le_index_ptr) {
+ RETURN_FALSE;
+ }
+ link = (int) index_ptr->ptr;
+ ptr = (hw_connection *) php3_list_find(link,&type); /* check if the link is still there */
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ return_value->value.lval = php3_hw_module.default_link = link;
+ return_value->type = IS_LONG;
+ efree(hashed_details);
+ if(username) efree(username);
+ if(password) efree(password);
+ if(host) efree(host);
+ return;
+ } else {
+ _php3_hash_del(list,hashed_details,hashed_details_length+1);
+ }
+ }
+
+ if ( (sockfd = open_hg_connection(host, port)) < 0 ) {
+ php3_error(E_ERROR, "Could not open connection to %s, Port: %d (retval=%d", host, port, sockfd);
+ if(host) efree(host);
+ if(username) efree(username);
+ if(password) efree(password);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+
+ if(NULL == (ptr = malloc(sizeof(hw_connection)))) {
+ if(host) efree(host);
+ if(username) efree(username);
+ if(password) efree(password);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+
+ if(0 != (ptr->lasterror = initialize_hg_connection(sockfd, &do_swap, &version, &userdata, &server_string, username, password))) {
+ php3_error(E_ERROR, "Could not initalize hyperwave connection");
+ if(host) efree(host);
+ if(username) efree(username);
+ if(password) efree(password);
+ if(userdata) efree(userdata);
+ if(server_string) free(server_string);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+
+ if(username) efree(username);
+ if(password) efree(password);
+
+ ptr->version = version;
+ ptr->server_string = server_string;
+ ptr->socket = sockfd;
+ ptr->swap_on = do_swap;
+ ptr->linkroot = 0;
+ ptr->hostname = strdup(host);
+ ptr->username = strdup("anonymous");
+
+ return_value->value.lval = php3_list_insert(ptr,php3_hw_module.le_socketp);
+ return_value->type = IS_LONG;
+
+ new_index_ptr.ptr = (void *) return_value->value.lval;
+ new_index_ptr.type = le_index_ptr;
+ if (_php3_hash_update(list,hashed_details,hashed_details_length+1,(void *) &new_index_ptr, sizeof(list_entry), NULL)==FAILURE) {
+ php3_error(E_ERROR, "Could not update connection details in hash table");
+ if(host) efree(host);
+ efree(hashed_details);
+ RETURN_FALSE;
+ }
+
+ }
+
+ efree(hashed_details);
+ if(host) efree(host);
+ php3_hw_module.default_link=return_value->value.lval;
+
+ /* At this point we have a working connection. If userdata was given
+ we are also indentified.
+ If there is no userdata because hw_connect was called without username
+ and password, we don't evaluate userdata.
+ */
+ if(NULL == userdata)
+ return;
+
+ if(ptr->username) free(ptr->username);
+ str = userdata;
+ while((*str != 0) && (*str != ' '))
+ str++;
+ if(*str != '\0')
+ ptr->username = strdup(++str);
+ else
+ ptr->username = NULL;
+ efree(userdata);
+}
+
+/* Start of user level functions */
+/* ***************************** */
+/* {{{ proto int hw_connect(string host, int port [string username [, string password]])
+ Connect to the Hyperwave server */
+void php3_hw_connect(INTERNAL_FUNCTION_PARAMETERS)
+{
+ php3_hw_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
+}
+/* }}} */
+
+/* {{{ proto int hw_pconnect(string host, int port [string username [, string password]])
+ Connect to the Hyperwave server persistent */
+void php3_hw_pconnect(INTERNAL_FUNCTION_PARAMETERS)
+{
+ php3_hw_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
+}
+/* }}} */
+
+/* {{{ proto void hw_close(int link)
+ Close connection to Hyperwave server */
+void php3_hw_close(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1;
+ int id, type;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ id=arg1->value.lval;
+ ptr = php3_list_find(id,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+ php3_list_delete(id);
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void hw_info(int link)
+ Outputs info string */
+void php3_hw_info(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *arg1;
+ int id, type;
+ hw_connection *ptr;
+ char *str;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ id=arg1->value.lval;
+ ptr = php3_list_find(id,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+ if(NULL != (str = get_hw_info(ptr))) {
+ /*
+ php3_printf("%s\n", str);
+ efree(str);
+ */
+ return_value->value.str.len = strlen(str);
+ return_value->value.str.val = str;
+ return_value->type = IS_STRING;
+ return;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto int hw_error(int link)
+ Returns last error number */
+void php3_hw_error(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *arg1;
+ int id, type;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ id=arg1->value.lval;
+ ptr = php3_list_find(id,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+ RETURN_LONG(ptr->lasterror);
+}
+/* }}} */
+
+/* {{{ proto string hw_errormsg(int link)
+ Returns last error message */
+void php3_hw_errormsg(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *arg1;
+ int id, type;
+ hw_connection *ptr;
+ char errstr[100];
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ id=arg1->value.lval;
+ ptr = php3_list_find(id,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ switch(ptr->lasterror) {
+ case 0:
+ sprintf(errstr, "No error");
+ break;
+ case NOACCESS:
+ sprintf(errstr, "No access");
+ break;
+ case NODOCS:
+ sprintf(errstr, "No documents");
+ break;
+ case NONAME:
+ sprintf(errstr, "No collection name");
+ break;
+ case NODOC:
+ sprintf(errstr, "Object is not a document");
+ break;
+ case NOOBJ:
+ sprintf(errstr, "No object received");
+ break;
+ case NOCOLLS:
+ sprintf(errstr, "No collections received");
+ break;
+ case DBSTUBNG:
+ sprintf(errstr, "Connection to low-level database failed");
+ break;
+ case NOTFOUND:
+ sprintf(errstr, "Object not found");
+ break;
+ case EXIST:
+ sprintf(errstr, "Collection already exists");
+ break;
+ case FATHERDEL:
+ sprintf(errstr, "parent collection disappeared");
+ break;
+ case FATHNOCOLL:
+ sprintf(errstr, "parent collection not a collection");
+ break;
+ case NOTEMPTY:
+ sprintf(errstr, "Collection not empty");
+ break;
+ case DESTNOCOLL:
+ sprintf(errstr, "Destination not a collection");
+ break;
+ case SRCEQDEST:
+ sprintf(errstr, "Source equals destination");
+ break;
+ case REQPEND:
+ sprintf(errstr, "Request pending");
+ break;
+ case TIMEOUT:
+ sprintf(errstr, "Timeout");
+ break;
+ case NAMENOTUNIQUE:
+ sprintf(errstr, "Name not unique");
+ break;
+ case WRITESTOPPED:
+ sprintf(errstr, "Database now read-only; try again later");
+ break;
+ case LOCKED:
+ sprintf(errstr, "Object locked; try again later");
+ break;
+ default:
+ sprintf(errstr, "Unknown error: %d", ptr->lasterror);
+ }
+ RETURN_STRING(errstr, 1);
+}
+/* }}} */
+
+/* {{{ proto hw_root(void)
+ Returns object id of root collection */
+void php3_hw_root(INTERNAL_FUNCTION_PARAMETERS)
+{
+ TLS_VARS;
+ return_value->value.lval = 0;
+ return_value->type = IS_LONG;
+}
+/* }}} */
+
+char *php3_hw_command(INTERNAL_FUNCTION_PARAMETERS, int comm) {
+ pval *arg1;
+ int link, type;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+ return NULL;
+ }
+ convert_to_long(arg1);
+ link=arg1->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ return NULL;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ char *object = NULL;
+ if (0 != (ptr->lasterror = send_command(ptr->socket, comm, &object)))
+ return NULL;
+
+ return object;
+ }
+}
+
+/* {{{ proto string hw_stat(int link)
+ Returns status string */
+void php3_hw_stat(INTERNAL_FUNCTION_PARAMETERS) {
+ char *object;
+
+ object = php3_hw_command(INTERNAL_FUNCTION_PARAM_PASSTHRU, STAT_COMMAND);
+ if(object == NULL)
+ RETURN_FALSE;
+
+ return_value->value.str.val = object;
+ return_value->value.str.len = strlen(object);
+ return_value->type = IS_STRING;
+}
+/* }}} */
+
+/* {{{ proto array hw_who(int link)
+ Returns names and info of users loged in */
+void php3_hw_who(INTERNAL_FUNCTION_PARAMETERS) {
+ pval user_arr;
+ char *object, *ptr, *temp, *attrname;
+ int i;
+
+ object = php3_hw_command(INTERNAL_FUNCTION_PARAM_PASSTHRU, WHO_COMMAND);
+ if(object == NULL)
+ RETURN_FALSE;
+
+ ptr = object;
+
+ while((*ptr != '\0') && (*ptr != '\n'))
+ ptr++;
+ while((*ptr != '\0') && (*ptr != '\n'))
+ ptr++;
+ if(*ptr == '\0') {
+ efree(object);
+ RETURN_FALSE;
+ }
+
+ if (array_init(return_value) == FAILURE) {
+ efree(object);
+ RETURN_FALSE;
+ }
+
+ temp = estrdup(ptr);
+ attrname = strtok(temp, "\n");
+ i = 0;
+ while(attrname != NULL) {
+ char *name;
+
+ if (array_init(&user_arr) == FAILURE) {
+ efree(object);
+ RETURN_FALSE;
+ }
+
+ ptr = attrname;
+ if(*ptr == '*')
+ add_assoc_long(&user_arr, "self", 1);
+ else
+ add_assoc_long(&user_arr, "self", 0);
+
+ ptr++;
+ name = ptr;
+ while((*ptr != '\0') && (*ptr != ' '))
+ ptr++;
+ *ptr = '\0';
+ add_assoc_string(&user_arr, "id", name, 1);
+
+ ptr++;
+ name = ptr;
+ while((*ptr != '\0') && (*ptr != ' '))
+ ptr++;
+ *ptr = '\0';
+ add_assoc_string(&user_arr, "name", name, 1);
+
+ ptr++;
+ while((*ptr != '\0') && (*ptr == ' '))
+ ptr++;
+
+ name = ptr;
+ while((*ptr != '\0') && (*ptr != ' '))
+ ptr++;
+ *ptr = '\0';
+ add_assoc_string(&user_arr, "system", name, 1);
+
+ ptr++;
+ while((*ptr != '\0') && (*ptr == ' '))
+ ptr++;
+
+ name = ptr;
+ while((*ptr != '\0') && (*ptr != ' '))
+ ptr++;
+ *ptr = '\0';
+ add_assoc_string(&user_arr, "onSinceDate", name, 1);
+
+ ptr++;
+ while((*ptr != '\0') && (*ptr == ' '))
+ ptr++;
+
+ name = ptr;
+ while((*ptr != '\0') && (*ptr != ' '))
+ ptr++;
+ *ptr = '\0';
+ add_assoc_string(&user_arr, "onSinceTime", name, 1);
+
+ ptr++;
+ while((*ptr != '\0') && (*ptr == ' '))
+ ptr++;
+
+ name = ptr;
+ while((*ptr != '\0') && (*ptr != ' '))
+ ptr++;
+ *ptr = '\0';
+ add_assoc_string(&user_arr, "TotalTime", name, 1);
+
+ /* Add the user array */
+ _php3_hash_index_update(return_value->value.ht, i++, &user_arr, sizeof(pval), NULL);
+
+ /* The user array can now be freed, but I don't know how */
+
+ attrname = strtok(NULL, "\n");
+ }
+ efree(temp);
+ efree(object);
+
+}
+/* }}} */
+
+void php3_hw_dummy(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2, *arg3;
+ int link, id, type, msgid;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ convert_to_long(arg3);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ msgid=arg3->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ char *object = NULL;
+ if (0 != (ptr->lasterror = send_dummy(ptr->socket, id, msgid, &object)))
+ RETURN_FALSE;
+
+php3_printf("%s", object);
+ return_value->value.str.val = object;
+ return_value->value.str.len = strlen(object);
+ return_value->type = IS_STRING;
+ }
+}
+
+/* {{{ proto string hw_getobject(int link, int objid)
+ Returns object record */
+void php3_hw_getobject(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ char *object = NULL;
+ if (0 != (ptr->lasterror = send_getobject(ptr->socket, id, &object)))
+ RETURN_FALSE;
+
+ RETURN_STRING(object, 0);
+ /*
+ make_return_array_from_objrec(&return_value, object);
+ efree(object);
+ */
+ }
+}
+/* }}} */
+
+/* {{{ proto int hw_insertobject(int link, string objrec, string parms)
+ Inserts an object */
+void php3_hw_insertobject(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2, *arg3;
+ int link, type;
+ char *objrec, *parms;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_string(arg2);
+ convert_to_string(arg3);
+ link=arg1->value.lval;
+ objrec=arg2->value.str.val;
+ parms=arg3->value.str.val;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ int objid;
+ if (0 != (ptr->lasterror = send_insertobject(ptr->socket, objrec, parms, &objid)))
+ RETURN_FALSE;
+
+ RETURN_LONG(objid);
+ }
+}
+/* }}} */
+
+/* {{{ proto string hw_getandlock(int link, int objid)
+ Returns object record and locks object */
+void php3_hw_getandlock(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ char *object = NULL;
+ char *attrname, *str;
+ if (0 != (ptr->lasterror = send_getandlock(ptr->socket, id, &object)))
+ RETURN_FALSE;
+
+ RETURN_STRING(object, 0);
+ }
+}
+/* }}} */
+
+/* {{{ proto void hw_unlock(int link, int objid)
+ Unlocks object */
+void php3_hw_unlock(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = send_unlock(ptr->socket, id)))
+ RETURN_FALSE;
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void hw_deleteobject(int link, int objid)
+ Deletes object */
+void php3_hw_deleteobject(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = send_deleteobject(ptr->socket, id)))
+ RETURN_FALSE;
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void hw_changeobject(int link, int objid, array attributes)
+ Changes attributes of an object */
+void php3_hw_changeobject(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2, *arg3;
+ int link, id, type, i;
+ hw_connection *ptr;
+ char *modification, *oldobjrec, buf[200];
+ HashTable *newobjarr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1); /* Connection */
+ convert_to_long(arg2); /* object ID */
+ convert_to_array(arg3); /* Array with new attributes */
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ newobjarr=arg3->value.ht;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ /* get the old object record */
+ if(0 != (ptr->lasterror = send_getobject(ptr->socket, id, &oldobjrec)))
+ RETURN_FALSE;
+
+ _php3_hash_internal_pointer_reset(newobjarr);
+ modification = strdup("");
+ for(i=0; i<_php3_hash_num_elements(newobjarr); i++) {
+ char *key, *str, *str1, newattribute[200];
+ pval *data;
+ int j, noinsert=1;
+ ulong ind;
+
+ _php3_hash_get_current_key(newobjarr, &key, &ind);
+ _php3_hash_get_current_data(newobjarr, (void *) &data);
+ switch(data->type) {
+ case IS_STRING:
+ if(strlen(data->value.str.val) == 0)
+ noinsert = 0;
+ else
+ sprintf(newattribute, "%s=%s", key, data->value.str.val);
+ break;
+ default:
+ sprintf(newattribute, "%s", "");
+ }
+
+ if(!noinsert) {
+ modification = fnInsStr(modification, 0, "\\");
+ modification = fnInsStr(modification, 0, newattribute);
+ modification = fnInsStr(modification, 0, "add ");
+
+ /* Retrieve the old attribute from object record */
+ if(NULL != (str = strstr(oldobjrec, key))) {
+ str1 = str;
+ j = 0;
+ while((str1 != NULL) && (*str1 != '\n')) {
+ buf[j++] = *str1++;
+ }
+ buf[j] = '\0';
+ modification = fnInsStr(modification, 0, "\\");
+ modification = fnInsStr(modification, 0, buf);
+ modification = fnInsStr(modification, 0, "rem ");
+ }
+ }
+ efree(key);
+ _php3_hash_move_forward(newobjarr);
+ }
+ efree(oldobjrec);
+
+ set_swap(ptr->swap_on);
+ modification[strlen(modification)-1] = '\0';
+/* php3_printf("0x%X, %s", id, modification); */
+ if (0 != (ptr->lasterror = send_changeobject(ptr->socket, id, modification)))
+ RETURN_FALSE;
+ free(modification);
+ RETURN_TRUE;
+}
+/* }}} */
+
+void php3_hw_mvcp(INTERNAL_FUNCTION_PARAMETERS, int mvcp) {
+ pval *arg1, *arg2, *arg3, *arg4, **objvIDs;
+ int link, type, dest=0, from=0;
+ HashTable *src_arr;
+ hw_connection *ptr;
+ int collIDcount, docIDcount, i, *docIDs, *collIDs;
+ TLS_VARS;
+
+ switch(mvcp) {
+ case MOVE: /* Move also has fromID */
+ if (ARG_COUNT(ht) != 4 || getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE)
+ WRONG_PARAM_COUNT;
+ break;
+ case COPY:
+ if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE)
+ WRONG_PARAM_COUNT;
+ break;
+ }
+ convert_to_long(arg1);
+ convert_to_array(arg2);
+ convert_to_long(arg3);
+ link=arg1->value.lval;
+ src_arr=arg2->value.ht;
+ switch(mvcp) {
+ case MOVE: /* Move also has fromID, which is arg3 --> arg4 becomes destID */
+ convert_to_long(arg4);
+ from=arg3->value.lval;
+ dest=arg4->value.lval;
+ break;
+ case COPY: /* No fromID for Copy needed --> arg3 is destID */
+ dest=arg3->value.lval;
+ from = 0;
+ break;
+ }
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+
+ if(NULL == (objvIDs = emalloc(_php3_hash_num_elements(src_arr) * sizeof(pval *)))) {
+ RETURN_FALSE;
+ }
+
+ if(getParametersArray(src_arr, _php3_hash_num_elements(src_arr), objvIDs) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ if(NULL == (collIDs = emalloc(_php3_hash_num_elements(src_arr) * sizeof(int)))) {
+ efree(objvIDs);
+ RETURN_FALSE;
+ }
+
+ if(NULL == (docIDs = emalloc(_php3_hash_num_elements(src_arr) * sizeof(int)))) {
+ efree(objvIDs);
+ efree(collIDs);
+ RETURN_FALSE;
+ }
+
+ collIDcount = docIDcount = 0;
+ for(i=0; i<_php3_hash_num_elements(src_arr); i++) {
+ char *objrec;
+ if(objvIDs[i]->type == IS_LONG) {
+ if(0 != (ptr->lasterror = send_getobject(ptr->socket, objvIDs[i]->value.lval, &objrec))) {
+ efree(objvIDs);
+ efree(collIDs);
+ efree(docIDs);
+ RETURN_FALSE;
+ }
+ if(0 == fnAttributeCompare(objrec, "DocumentType", "collection"))
+ collIDs[collIDcount++] = objvIDs[i]->value.lval;
+ else
+ docIDs[docIDcount++] = objvIDs[i]->value.lval;
+ efree(objrec);
+ }
+ }
+ efree(objvIDs);
+
+ if (0 != (ptr->lasterror = send_mvcpdocscoll(ptr->socket, docIDs, docIDcount, from, dest, mvcp))) {
+ efree(collIDs);
+ efree(docIDs);
+ RETURN_FALSE;
+ }
+
+ if (0 != (ptr->lasterror = send_mvcpcollscoll(ptr->socket, collIDs, collIDcount, from, dest, mvcp))) {
+ efree(collIDs);
+ efree(docIDs);
+ RETURN_FALSE;
+ }
+
+ efree(collIDs);
+ efree(docIDs);
+
+ RETURN_LONG(docIDcount + collIDcount);
+}
+
+/* {{{ proto void hw_mv(int link, array objrec, int from, int dest)
+ Moves object */
+void php3_hw_mv(INTERNAL_FUNCTION_PARAMETERS) {
+ php3_hw_mvcp(INTERNAL_FUNCTION_PARAM_PASSTHRU, MOVE);
+}
+/* }}} */
+
+/* {{{ proto void hw_cp(int link, array objrec, int dest)
+ Copies object */
+void php3_hw_cp(INTERNAL_FUNCTION_PARAMETERS) {
+ php3_hw_mvcp(INTERNAL_FUNCTION_PARAM_PASSTHRU, COPY);
+}
+/* }}} */
+
+/* {{{ proto hwdoc hw_gettext(int link, int objid[, int rootid])
+ Returns text document. Links are relative to rootid if given */
+void php3_hw_gettext(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *argv[3];
+ int argc, link, id, type, mode;
+ int rootid = 0;
+ hw_document *doc;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ argc = ARG_COUNT(ht);
+ if((argc > 3) || (argc < 2))
+ WRONG_PARAM_COUNT;
+
+ if (getParametersArray(ht, argc, argv) == FAILURE)
+ RETURN_FALSE;
+
+ convert_to_long(argv[0]);
+ convert_to_long(argv[1]);
+ if(argc == 3) {
+ convert_to_long(argv[2]);
+ rootid = argv[2]->value.lval;
+ mode = 1;
+ } else
+ mode = 0;
+ link=argv[0]->value.lval;
+ id=argv[1]->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ char *object = NULL;
+ char *attributes = NULL;
+ char *bodytag = NULL;
+ int count;
+ /* !!!! memory for object and attributes is allocated with malloc !!!! */
+ if (0 != (ptr->lasterror = send_gettext(ptr->socket, id, mode, rootid, &attributes, &bodytag, &object, &count)))
+ RETURN_FALSE;
+ doc = malloc(sizeof(hw_document));
+ doc->data = object;
+ doc->attributes = attributes;
+ doc->bodytag = bodytag;
+ doc->size = count;
+ return_value->value.lval = php3_list_insert(doc,php3_hw_module.le_document);
+ return_value->type = IS_LONG;
+ }
+}
+/* }}} */
+
+/* {{{ proto void hw_edittext(int link, hwdoc doc)
+ Modifies text document */
+void php3_hw_edittext(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, doc, type;
+ hw_connection *ptr;
+ hw_document *docptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ ptr = php3_list_find(link,&type);
+
+ /* FIXME id is not set anywhere */
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ doc=arg2->value.lval;
+ docptr = php3_list_find(doc,&type);
+
+ /* FIXME id is not set anywhere */
+ if(!docptr || (type!=php3_hw_module.le_document)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ if (0 != (ptr->lasterror = send_edittext(ptr->socket, docptr->attributes, docptr->data))) {
+ RETURN_FALSE;
+ }
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto hwdoc hw_getcgi(int link, int objid)
+ Returns the output of a cgi script */
+void php3_hw_getcgi(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ hw_document *doc;
+ hw_connection *ptr;
+ char cgi_env_str[1000];
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ char *object = NULL;
+ char *attributes = NULL;
+ int count;
+
+ /* Here is another undocument function of Hyperwave.
+ If you call a cgi script with getcgi-message, you will
+ have to provide the complete cgi enviroment, since it is
+ only known to the webserver (or wavemaster). This is done
+ by extending the object record with the following incomplete
+ string. It should contain any enviroment variable a cgi script
+ requires.
+ */
+#if (WIN32|WINNT)
+ sprintf(cgi_env_str, "CGI_REQUEST_METHOD=%s\nCGI_PATH_INFO=%s\nCGI_QUERY_STRING=%s",
+ getenv("REQUEST_METHOD"),
+ getenv("PATH_INFO"),
+ getenv("QUERY_STRING"));
+#else
+ sprintf(cgi_env_str, "CGI_REQUEST_METHOD=%s\nCGI_PATH_INFO=%s\nCGI_QUERY_STRING=%s",
+ GLOBAL(request_info).request_method,
+ GLOBAL(request_info).path_info,
+ GLOBAL(request_info).query_string);
+#endif
+ /* !!!! memory for object and attributes is allocated with malloc !!!! */
+ if (0 != (ptr->lasterror = send_getcgi(ptr->socket, id, cgi_env_str, &attributes, &object, &count)))
+ RETURN_FALSE;
+ doc = malloc(sizeof(hw_document));
+ doc->data = object;
+ doc->attributes = attributes;
+ doc->bodytag = NULL;
+ doc->size = count;
+ return_value->value.lval = php3_list_insert(doc,php3_hw_module.le_document);
+ return_value->type = IS_LONG;
+ }
+}
+/* }}} */
+
+/* {{{ proto hwdoc hw_getremote(int link, int objid)
+ Returns the output of a remote document */
+void php3_hw_getremote(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ hw_document *doc;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ char *object = NULL;
+ char *attributes = NULL;
+ int count;
+ /* !!!! memory for object and attributes is allocated with malloc !!!! */
+ if (0 != (ptr->lasterror = send_getremote(ptr->socket, id, &attributes, &object, &count)))
+ RETURN_FALSE;
+ doc = malloc(sizeof(hw_document));
+ doc->data = object;
+ doc->attributes = attributes;
+ doc->bodytag = NULL;
+ doc->size = count;
+ return_value->value.lval = php3_list_insert(doc,php3_hw_module.le_document);
+ return_value->type = IS_LONG;
+ }
+}
+/* }}} */
+
+/* {{{ proto [array|hwdoc] hw_getremotechildren(int link, int objid)
+ Returns the remote document if only one or an array of object records */
+void php3_hw_getremotechildren(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, type, i;
+ hw_connection *ptr;
+ char *objrec;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_string(arg2);
+ link=arg1->value.lval;
+ objrec=arg2->value.str.val;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d", link);
+ RETURN_FALSE;
+ }
+ set_swap(ptr->swap_on);
+ {
+ int count, *offsets;
+ char *remainder, *ptr1;
+ if (0 != (ptr->lasterror = send_getremotechildren(ptr->socket, objrec, &remainder, &offsets, &count)))
+ RETURN_FALSE;
+
+ if(strncmp(remainder, "ObjectID=0 ", 10)) {
+ hw_document *doc;
+ remainder[offsets[0]-18] = '\0';
+/*php3_printf("offset = %d, remainder = %s---", offsets[0], remainder);*/
+ doc = malloc(sizeof(hw_document));
+ doc->data = strdup(remainder);
+ doc->attributes = strdup(objrec);
+ doc->bodytag = NULL;
+ doc->size = offsets[0]-18;
+ return_value->value.lval = php3_list_insert(doc,php3_hw_module.le_document);
+ return_value->type = IS_LONG;
+ } else {
+ if (array_init(return_value) == FAILURE) {
+ efree(offsets);
+ RETURN_FALSE;
+ }
+
+ ptr1 = remainder;
+ for(i=0; i<count; i++) {
+ *(ptr1+offsets[i]-1) = '\0';
+ add_index_string(return_value, i, ptr1, 1);
+ ptr1 += offsets[i];
+ }
+ }
+
+ efree(offsets);
+ efree(remainder);
+ }
+}
+/* }}} */
+
+/* {{{ proto void hw_setlinkroot(int link, int rootid)
+ Set the id to which links are calculated */
+void php3_hw_setlinkroot(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, type, rootid;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link = arg1->value.lval;
+ rootid = arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ ptr->linkroot = rootid;
+ RETURN_LONG(rootid);
+}
+/* }}} */
+
+/* {{{ proto hwdoc hw_pipedocument(int link, int objid)
+ Returns document */
+void php3_hw_pipedocument(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *argv[3];
+ int link, id, type, argc, mode;
+ int rootid = 0;
+ hw_connection *ptr;
+ hw_document *doc;
+#if APACHE
+ server_rec *serv = GLOBAL(php3_rqst)->server;
+#endif
+ TLS_VARS;
+
+ argc = ARG_COUNT(ht);
+ if((argc > 2) || (argc < 2))
+ WRONG_PARAM_COUNT;
+
+ if (getParametersArray(ht, argc, argv) == FAILURE)
+ RETURN_FALSE;
+
+ convert_to_long(argv[0]);
+ convert_to_long(argv[1]);
+/* if(argc == 3) {
+ convert_to_long(argv[2]);
+ rootid = argv[2]->value.lval;
+ if(rootid != 0)
+ mode = 1;
+ }
+*/ link=argv[0]->value.lval;
+ id=argv[1]->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d", link);
+ RETURN_FALSE;
+ }
+
+ mode = 0;
+ if(ptr->linkroot > 0)
+ mode = 1;
+ rootid = ptr->linkroot;
+
+ set_swap(ptr->swap_on);
+ {
+ char *object = NULL;
+ char *attributes = NULL;
+ char *bodytag = NULL;
+ int count;
+ /* !!!! memory for object, bodytag and attributes is allocated with malloc !!!! */
+ if (0 != (ptr->lasterror = send_pipedocument(ptr->socket,
+#if APACHE
+ serv->server_hostname,
+#else
+ getenv("HOST"),
+#endif
+ id, mode, rootid, &attributes, &bodytag, &object, &count)))
+ RETURN_FALSE;
+
+ doc = malloc(sizeof(hw_document));
+ doc->data = object;
+ doc->attributes = attributes;
+ doc->bodytag = bodytag;
+ doc->size = count;
+fprintf(stderr, "size = %d\n", count);
+ return_value->value.lval = php3_list_insert(doc,php3_hw_module.le_document);
+ return_value->type = IS_LONG;
+ }
+} /* }}} */
+
+/* {{{ proto hwdoc hw_pipecgi(int link, int objid)
+ Returns output of cgi script */
+void php3_hw_pipecgi(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ hw_connection *ptr;
+ hw_document *doc;
+ char cgi_env_str[1000];
+#if APACHE
+ server_rec *serv = GLOBAL(php3_rqst)->server;
+#endif
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ char *object = NULL;
+ char *attributes = NULL;
+ int count;
+
+#if (WIN32|WINNT)
+ sprintf(cgi_env_str, "CGI_REQUEST_METHOD=%s\nCGI_PATH_INFO=%s\nCGI_QUERY_STRING=%s",
+ getenv("REQUEST_METHOD"),
+ getenv("PATH_INFO"),
+ getenv("QUERY_STRING"));
+#else
+ sprintf(cgi_env_str, "CGI_REQUEST_METHOD=%s\nCGI_PATH_INFO=%s\nCGI_QUERY_STRING=%s",
+ GLOBAL(request_info).request_method,
+ GLOBAL(request_info).path_info,
+ GLOBAL(request_info).query_string);
+#endif
+ /* !!!! memory for object, bodytag and attributes is allocated with malloc !!!! */
+ if (0 != (ptr->lasterror = send_pipecgi(ptr->socket,
+#if APACHE
+ serv->server_hostname,
+#else
+ getenv("HOST"),
+#endif
+ id, cgi_env_str, &attributes, &object, &count)))
+ RETURN_FALSE;
+
+ doc = malloc(sizeof(hw_document));
+ doc->data = object;
+ doc->attributes = attributes;
+ doc->bodytag = NULL;
+ doc->size = count;
+ return_value->value.lval = php3_list_insert(doc,php3_hw_module.le_document);
+ return_value->type = IS_LONG;
+ }
+} /* }}} */
+
+/* {{{ proto void hw_insertdocument(int link, int parentid, hwdoc doc)
+ Insert new document */
+void php3_hw_insertdocument(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2, *arg3;
+ int link, id, doc, type;
+ hw_connection *ptr;
+ hw_document *docptr;
+#if APACHE
+ server_rec *serv = GLOBAL(php3_rqst)->server;
+#endif
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ convert_to_long(arg3);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find connection identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ doc=arg3->value.lval;
+ docptr = php3_list_find(doc,&type);
+ if(!docptr || (type!=php3_hw_module.le_document)) {
+ php3_error(E_WARNING,"Unable to find document identifier %d",doc);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ if (0 != (ptr->lasterror = send_putdocument(ptr->socket,
+#if APACHE
+ serv->server_hostname,
+#else
+ getenv("HOST"),
+#endif
+ id, docptr->attributes, docptr->data, docptr->size))) {
+ RETURN_FALSE;
+ }
+ }
+ RETURN_TRUE;
+} /* }}} */
+
+/* {{{ proto hwdoc hw_new_document(int link, string data, string objrec, int size)
+ Create a new document */
+void php3_hw_new_document(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2, *arg3;
+ hw_document *doc;
+
+ if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_string(arg1);
+ convert_to_string(arg2);
+ convert_to_long(arg3);
+
+ doc = malloc(sizeof(hw_document));
+ doc->data = malloc(arg3->value.lval);
+ memcpy(doc->data, arg2->value.str.val, arg3->value.lval);
+ doc->attributes = strdup(arg1->value.str.val);
+ doc->bodytag = NULL;
+ doc->size = arg3->value.lval;
+ return_value->value.lval = php3_list_insert(doc,php3_hw_module.le_document);
+ return_value->type = IS_LONG;
+} /* }}} */
+
+/* {{{ proto void hw_free_document(hwdoc doc)
+ Frees memory of document */
+void php3_hw_free_document(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1;
+ int id, type;
+ hw_document *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ id=arg1->value.lval;
+ ptr = php3_list_find(id,&type);
+ if(!ptr || (type!=php3_hw_module.le_document)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+ php3_list_delete(id);
+ RETURN_TRUE;
+} /* }}} */
+
+/* {{{ proto void hw_output_document(hwdoc doc)
+ Prints document */
+void php3_hw_output_document(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1;
+ int id, type, count;
+ hw_document *ptr;
+ char *ptr1;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ id=arg1->value.lval;
+ ptr = php3_list_find(id,&type);
+ if(!ptr || (type!=php3_hw_module.le_document)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ ptr1 = ptr->data;
+ count = 0;
+ while(count < ptr->size) {
+ php3_write(ptr1++, 1);
+ count++;
+ }
+
+ RETURN_TRUE;
+} /* }}} */
+
+/* {{{ proto string hw_document_bodytag(hwdoc doc [, string prefix])
+ Return bodytag prefixed by prefix */
+void php3_hw_document_bodytag(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *argv[2];
+ int id, type, argc;
+ hw_document *ptr;
+ char *temp, *str = NULL;
+ TLS_VARS;
+
+ argc = ARG_COUNT(ht);
+ if((argc > 2) || (argc < 1))
+ WRONG_PARAM_COUNT;
+
+ if (getParametersArray(ht, argc, argv) == FAILURE)
+ RETURN_FALSE;
+
+ convert_to_long(argv[0]);
+ id=argv[0]->value.lval;
+ ptr = php3_list_find(id,&type);
+ if(!ptr || (type!=php3_hw_module.le_document)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ if(argc == 2) {
+ convert_to_string(argv[1]);
+ str=argv[1]->value.str.val;
+ }
+
+ if(str != NULL) {
+ temp = emalloc(argv[1]->value.str.len + strlen(ptr->bodytag) + 2);
+ strcpy(temp, ptr->bodytag);
+ strcpy(temp+strlen(ptr->bodytag)-1, str);
+ strcpy(temp+strlen(ptr->bodytag)-1+argv[1]->value.str.len, ">\n");
+ RETURN_STRING(temp, 0);
+ } else {
+ RETURN_STRING(ptr->bodytag, 1);
+ }
+} /* }}} */
+
+/* {{{ proto string hw_document_content(hwdoc doc)
+ Returns content of document */
+void php3_hw_document_content(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *argv[1];
+ int id, type, argc;
+ hw_document *ptr;
+ TLS_VARS;
+
+ argc = ARG_COUNT(ht);
+ if(argc != 1)
+ WRONG_PARAM_COUNT;
+
+ if (getParametersArray(ht, argc, argv) == FAILURE)
+ RETURN_FALSE;
+
+ convert_to_long(argv[0]);
+ id=argv[0]->value.lval;
+ ptr = php3_list_find(id,&type);
+ if(!ptr || (type!=php3_hw_module.le_document)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ RETURN_STRING(ptr->data, 1);
+} /* }}} */
+
+/* {{{ proto int hw_document_content(hwdoc doc)
+ Returns size of document */
+void php3_hw_document_size(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1;
+ int id, type;
+ hw_document *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ id=arg1->value.lval;
+ ptr = php3_list_find(id,&type);
+ if(!ptr || (type!=php3_hw_module.le_document)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ RETURN_LONG(ptr->size);
+} /* }}} */
+
+/* {{{ proto string hw_document_content(hwdoc doc)
+ Returns object record of document */
+void php3_hw_document_attributes(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1;
+ int id, type;
+ hw_document *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ id=arg1->value.lval;
+ ptr = php3_list_find(id,&type);
+ if(!ptr || (type!=php3_hw_module.le_document)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ RETURN_STRING(ptr->attributes, 1);
+/* make_return_array_from_objrec(&return_value, ptr->attributes); */
+} /* }}} */
+
+/* {{{ proto array hw_getparentsobj(int link, int objid)
+ Returns array of parent object records */
+void php3_hw_getparentsobj(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ int count;
+ char **childObjRecs = NULL;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+
+ if (0 != (ptr->lasterror = send_getparentsobj(ptr->socket, id, &childObjRecs, &count))) {
+ php3_error(E_WARNING, "send_command (getparentsobj) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ /* create return value and free all memory */
+ if( 0 > make_return_objrec(&return_value, childObjRecs, count))
+ RETURN_FALSE;
+} /* }}} */
+
+/* {{{ proto array hw_getparents(int link, int objid)
+ Returns array of parent object ids */
+void php3_hw_getparents(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ int count;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ int *childIDs = NULL;
+ int i;
+
+ if (0 != (ptr->lasterror = send_getparents(ptr->socket, id, &childIDs, &count))) {
+ php3_error(E_WARNING, "send_command (getparents) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ if (array_init(return_value) == FAILURE) {
+ efree(childIDs);
+ RETURN_FALSE;
+ }
+
+ for(i=0; i<count; i++) {
+ add_index_long(return_value, i, childIDs[i]);
+ }
+ efree(childIDs);
+ }
+
+} /* }}} */
+
+/* {{{ proto array hw_children(int link, int objid)
+ Returns array of children object ids */
+void php3_hw_children(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ int count;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ int *childIDs = NULL;
+ int i;
+
+ if (0 != (ptr->lasterror = send_children(ptr->socket, id, &childIDs, &count))){
+ php3_error(E_WARNING, "send_command (getchildcoll) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ if (array_init(return_value) == FAILURE) {
+ efree(childIDs);
+ RETURN_FALSE;
+ }
+
+ for(i=0; i<count; i++) {
+ add_index_long(return_value, i, childIDs[i]);
+ }
+ efree(childIDs);
+ }
+
+} /* }}} */
+
+/* {{{ proto array hw_children(int link, int objid)
+ Returns array of children object records */
+void php3_hw_childrenobj(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ int count;
+ char **childObjRecs = NULL;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+
+ if (0 != (ptr->lasterror = send_childrenobj(ptr->socket, id, &childObjRecs, &count))) {
+ php3_error(E_WARNING, "send_command (getchildcollobj) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ /* create return value and free all memory */
+ if( 0 > make_return_objrec(&return_value, childObjRecs, count))
+ RETURN_FALSE;
+} /* }}} */
+
+/* {{{ proto array hw_childcoll(int link, int objid)
+ Returns array of child collection object ids */
+void php3_hw_getchildcoll(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ int count;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ int *childIDs = NULL;
+ int i;
+
+ if (0 != (ptr->lasterror = send_getchildcoll(ptr->socket, id, &childIDs, &count))){
+ php3_error(E_WARNING, "send_command (getchildcoll) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ if (array_init(return_value) == FAILURE) {
+ efree(childIDs);
+ RETURN_FALSE;
+ }
+
+ for(i=0; i<count; i++) {
+ add_index_long(return_value, i, childIDs[i]);
+ }
+ efree(childIDs);
+ }
+
+} /* }}} */
+
+/* {{{ proto array hw_childcollobj(int link, int objid)
+ Returns array of child collection object records */
+void php3_hw_getchildcollobj(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ int count;
+ char **childObjRecs = NULL;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+
+ if (0 != (ptr->lasterror = send_getchildcollobj(ptr->socket, id, &childObjRecs, &count))) {
+ php3_error(E_WARNING, "send_command (getchildcollobj) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ /* create return value and free all memory */
+ if( 0 > make_return_objrec(&return_value, childObjRecs, count))
+ RETURN_FALSE;
+} /* }}} */
+
+/* {{{ proto int hw_docbyanchor(int link, int anchorid)
+ Returns objid of document belonging to anchorid */
+void php3_hw_docbyanchor(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ int objectID;
+ if (0 != (ptr->lasterror = send_docbyanchor(ptr->socket, id, &objectID)))
+ RETURN_FALSE;
+
+ RETURN_LONG(objectID);
+ }
+} /* }}} */
+
+/* {{{ proto array hw_docbyanchorobj(int link, int anchorid)
+ Returns object record of document belonging to anchorid */
+void php3_hw_docbyanchorobj(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ char *object = NULL;
+ if (0 != (ptr->lasterror = send_docbyanchorobj(ptr->socket, id, &object)))
+ RETURN_FALSE;
+
+ RETURN_STRING(object, 0);
+ /*
+ make_return_array_from_objrec(&return_value, object);
+ efree(object);
+ */
+ }
+} /* }}} */
+
+/* {{{ proto array hw_getobjectbyquery(int link, string query, int maxhits)
+ Search for query and return maxhits objids */
+void php3_hw_getobjectbyquery(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2, *arg3;
+ int link, type, maxhits;
+ char *query;
+ int count, i;
+ int *childIDs = NULL;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_string(arg2);
+ convert_to_long(arg3);
+ link=arg1->value.lval;
+ query=arg2->value.str.val;
+ maxhits=arg3->value.lval;
+ if (maxhits < 0) maxhits=0x7FFFFFFF;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = send_getobjbyquery(ptr->socket, query, maxhits, &childIDs, &count))) {
+ php3_error(E_WARNING, "send_command (getchildcoll) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ if (array_init(return_value) == FAILURE) {
+ efree(childIDs);
+ RETURN_FALSE;
+ }
+
+ for(i=0; i<count; i++)
+ add_index_long(return_value, i, childIDs[i]);
+ efree(childIDs);
+} /* }}} */
+
+/* {{{ proto array hw_getobjectbyqueryobj(int link, string query, int maxhits)
+ Search for query and return maxhits object records */
+void php3_hw_getobjectbyqueryobj(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2, *arg3;
+ int link, type, maxhits;
+ char *query;
+ int count;
+ char **childObjRecs = NULL;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_string(arg2);
+ convert_to_long(arg3);
+ link=arg1->value.lval;
+ query=arg2->value.str.val;
+ maxhits=arg3->value.lval;
+ if (maxhits < 0) maxhits=0x7FFFFFFF;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = send_getobjbyqueryobj(ptr->socket, query, maxhits, &childObjRecs, &count))) {
+ php3_error(E_WARNING, "send_command (getchildcoll) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ /* create return value and free all memory */
+ if( 0 > make_return_objrec(&return_value, childObjRecs, count))
+ RETURN_FALSE;
+} /* }}} */
+
+/* {{{ proto array hw_getobjectbyquerycoll(int link, int collid, string query, int maxhits)
+ Search for query in collection and return maxhits objids */
+void php3_hw_getobjectbyquerycoll(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2, *arg3, *arg4;
+ int link, id, type, maxhits;
+ char *query;
+ int count, i;
+ hw_connection *ptr;
+ int *childIDs = NULL;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 4 || getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ convert_to_string(arg3);
+ convert_to_long(arg4);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ query=arg3->value.str.val;
+ maxhits=arg4->value.lval;
+ if (maxhits < 0) maxhits=0x7FFFFFFF;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = send_getobjbyquerycoll(ptr->socket, id, query, maxhits, &childIDs, &count))) {
+ php3_error(E_WARNING, "send_command (getchildcoll) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ if (array_init(return_value) == FAILURE) {
+ efree(childIDs);
+ RETURN_FALSE;
+ }
+
+ for(i=0; i<count; i++)
+ add_index_long(return_value, i, childIDs[i]);
+ efree(childIDs);
+} /* }}} */
+
+/* {{{ proto array hw_getobjectbyquerycollobj(int link, int collid, string query, int maxhits)
+ Search for query in collection and return maxhits object records */
+void php3_hw_getobjectbyquerycollobj(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2, *arg3, *arg4;
+ int link, id, type, maxhits;
+ char *query;
+ int count;
+ hw_connection *ptr;
+ char **childObjRecs = NULL;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 4 || getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ convert_to_string(arg3);
+ convert_to_long(arg4);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ query=arg3->value.str.val;
+ maxhits=arg4->value.lval;
+ if (maxhits < 0) maxhits=0x7FFFFFFF;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = send_getobjbyquerycollobj(ptr->socket, id, query, maxhits, &childObjRecs, &count))) {
+ php3_error(E_WARNING, "send_command (getchildcoll) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ /* create return value and free all memory */
+ if( 0 > make_return_objrec(&return_value, childObjRecs, count))
+ RETURN_FALSE;
+} /* }}} */
+
+/* {{{ proto array hw_getchilddoccoll(int link, int objid)
+ Returns all children ids which are documents */
+void php3_hw_getchilddoccoll(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ int count, i;
+ int *childIDs = NULL;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = send_getchilddoccoll(ptr->socket, id, &childIDs, &count))) {
+ php3_error(E_WARNING, "send_command (getchilddoccoll) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ if (array_init(return_value) == FAILURE) {
+ efree(childIDs);
+ RETURN_FALSE;
+ }
+
+ for(i=0; i<count; i++)
+ add_index_long(return_value, i, childIDs[i]);
+ efree(childIDs);
+} /* }}} */
+
+/* {{{ proto array hw_getchilddoccollobj(int link, int objid)
+ Returns all children object records which are documents */
+void php3_hw_getchilddoccollobj(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ int count;
+ char **childObjRecs = NULL;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = send_getchilddoccollobj(ptr->socket, id, &childObjRecs, &count))) {
+ php3_error(E_WARNING, "send_command (getchilddoccollobj) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ /* create return value and free all memory */
+ if( 0 > make_return_objrec(&return_value, childObjRecs, count))
+ RETURN_FALSE;
+
+} /* }}} */
+
+/* {{{ proto array hw_getanchors(int link, int objid)
+ Return all anchors of object */
+void php3_hw_getanchors(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ int count, i;
+ int *anchorIDs = NULL;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = send_getanchors(ptr->socket, id, &anchorIDs, &count))) {
+ php3_error(E_WARNING, "send_command (getanchors) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ if (array_init(return_value) == FAILURE) {
+ efree(anchorIDs);
+ RETURN_FALSE;
+ }
+
+ for(i=0; i<count; i++)
+ add_index_long(return_value, i, anchorIDs[i]);
+ efree(anchorIDs);
+} /* }}} */
+
+/* {{{ proto array hw_getanchorsobj(int link, int objid)
+ Return all object records of anchors of object */
+void php3_hw_getanchorsobj(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, id, type;
+ int count;
+ char **anchorObjRecs = NULL;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = (hw_connection *) php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",id);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = send_getanchorsobj(ptr->socket, id, &anchorObjRecs, &count))) {
+ php3_error(E_WARNING, "send_command (getanchors) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ /* create return value and free all memory */
+ if( 0 > make_return_objrec(&return_value, anchorObjRecs, count))
+ RETURN_FALSE;
+} /* }}} */
+
+/* {{{ proto string hw_getusername(int link)
+ Returns the current user name */
+void php3_hw_getusername(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1;
+ int link, type;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ link = arg1->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ return_value->value.str.val = estrdup(ptr->username);
+ return_value->value.str.len = strlen(ptr->username);
+ return_value->type = IS_STRING;
+} /* }}} */
+
+
+/* {{{ proto void hw_identify(int link, string username, string password)
+ Identifies at Hyperwave server */
+void php3_hw_identify(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2, *arg3;
+ int link, type;
+ char *name, *passwd, *userdata;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_string(arg2);
+ convert_to_string(arg3);
+ link = arg1->value.lval;
+ name=arg2->value.str.val;
+ passwd=arg3->value.str.val;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ {
+ char *str;
+
+ if (0 != (ptr->lasterror = send_identify(ptr->socket, name, passwd, &userdata))) {
+ php3_error(E_WARNING, "send_identify returned -1\n");
+ if(ptr->username) free(ptr->username);
+ ptr->username = NULL;
+ RETURN_FALSE;
+ }
+
+ return_value->value.str.val = userdata;
+ return_value->value.str.len = strlen(userdata);
+ return_value->type = IS_STRING;
+ if(ptr->username) free(ptr->username);
+ str = userdata;
+ while((*str != 0) && (*str != ' '))
+ str++;
+ if(*str != '\0')
+ ptr->username = strdup(++str);
+ else
+ ptr->username = NULL;
+ }
+}
+/* }}} */
+
+/* {{{ proto array hw_objrec2array(string objrec)
+ Returns object array of object record*/
+void php3_hw_objrec2array(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_string(arg1);
+ make_return_array_from_objrec(&return_value, arg1->value.str.val);
+}
+/* }}} */
+
+/* {{{ proto string hw_array2objrec(array objarr)
+ Returns object record of object array */
+void php3_hw_array2objrec(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1;
+ char *objrec, *retobj;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_string(arg1);
+ objrec = make_objrec_from_array(arg1->value.ht);
+ if(objrec) {
+ retobj = estrdup(objrec);
+ free(objrec);
+ RETURN_STRING(retobj, 0);
+ } else
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto array hw_incollections(int link, array objids, array collids, int para)
+ Returns object ids which are in collections */
+void php3_hw_incollections(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2, *arg3, *arg4;
+ int type, link, i;
+ hw_connection *ptr;
+ int cobjids, ccollids, *objectIDs, *collIDs, cretids, *retIDs, retcoll;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 4 || getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_array(arg2);
+ convert_to_array(arg3);
+ convert_to_long(arg4);
+ link = arg1->value.lval;
+ retcoll=arg4->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ cobjids = _php3_hash_num_elements(arg2->value.ht);
+ if(NULL == (objectIDs = make_ints_from_array(arg2->value.ht))) {
+ php3_error(E_WARNING, "Could not create Int Array from Array\n");
+ RETURN_FALSE;
+ }
+
+ ccollids = _php3_hash_num_elements(arg3->value.ht);
+ if(NULL == (collIDs = make_ints_from_array(arg3->value.ht))) {
+ php3_error(E_WARNING, "Could not create Int Array from Array\n");
+ efree(objectIDs);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = send_incollections(ptr->socket, retcoll,
+ cobjids, objectIDs,
+ ccollids, collIDs,
+ &cretids, &retIDs))) {
+ if(objectIDs) efree(objectIDs);
+ if(collIDs) efree(collIDs);
+ RETURN_FALSE;
+ }
+
+ if(objectIDs) efree(objectIDs);
+ if(collIDs) efree(collIDs);
+
+ if (array_init(return_value) == FAILURE) {
+ efree(retIDs);
+ RETURN_FALSE;
+ }
+
+ for(i=0; i<cretids; i++)
+ add_index_long(return_value, i, retIDs[i]);
+ efree(retIDs);
+
+}
+/* }}} */
+
+/* {{{ proto void hw_inscoll(int link, int parentid, array objarr)
+ Inserts collection */
+void php3_hw_inscoll(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2, *arg3;
+ char *objrec;
+ int id, newid, type, link;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ convert_to_array(arg3);
+ link = arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ if(NULL == (objrec = make_objrec_from_array(arg3->value.ht))) {
+ php3_error(E_WARNING, "Could not create Object Record from Array\n");
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = send_inscoll(ptr->socket, id, objrec, &newid))) {
+ if(objrec) free(objrec);
+ RETURN_FALSE;
+ }
+
+ if(objrec) free(objrec);
+ RETURN_LONG(newid);
+}
+/* }}} */
+
+/* {{{ proto void hw_inscoll(int link, int parentid, array objarr [, string text])
+ Inserts document */
+void php3_hw_insdoc(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *argv[4];
+ char *objrec, *text;
+ int id, newid, type, link, argc;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ argc = ARG_COUNT(ht);
+ if((argc < 3) || (argc > 4))
+ WRONG_PARAM_COUNT;
+
+ if (getParametersArray(ht, argc, argv) == FAILURE)
+ WRONG_PARAM_COUNT;
+
+ convert_to_long(argv[0]);
+ convert_to_long(argv[1]);
+ convert_to_string(argv[2]);
+ if(argc == 4) {
+ convert_to_string(argv[3]);
+ text = argv[3]->value.str.val;
+ } else {
+ text = NULL;
+ }
+ link = argv[0]->value.lval;
+ id = argv[1]->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ objrec = argv[2]->value.str.val;
+ if (0 != (ptr->lasterror = send_insdoc(ptr->socket, id, objrec, text, &newid))) {
+ RETURN_FALSE;
+ }
+
+ RETURN_LONG(newid);
+}
+/* }}} */
+
+/* {{{ proto int hw_getsrcbydestobj(int link, int destid)
+ Returns object id of source docuent by destination anchor */
+void php3_hw_getsrcbydestobj(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2;
+ int link, type, id;
+ int count;
+ char **childObjRecs = NULL;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ link=arg1->value.lval;
+ id=arg2->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = send_getsrcbydest(ptr->socket, id, &childObjRecs, &count))) {
+ php3_error(E_WARNING, "send_command (getsrcbydest) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ /* create return value and free all memory */
+ if( 0 > make_return_objrec(&return_value, childObjRecs, count))
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string hw_getrellink(int link, int rootid, int sourceid, int destid)
+ Get link form source to dest relative to rootid */
+void php3_hw_getrellink(INTERNAL_FUNCTION_PARAMETERS) {
+ pval *arg1, *arg2, *arg3, *arg4;
+ int link, type;
+ int rootid, destid, sourceid;
+ char *anchorstr;
+ hw_connection *ptr;
+ TLS_VARS;
+
+ if (ARG_COUNT(ht) != 4 || getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ convert_to_long(arg2);
+ convert_to_long(arg3);
+ convert_to_long(arg4);
+ link=arg1->value.lval;
+ rootid=arg2->value.lval;
+ sourceid=arg3->value.lval;
+ destid=arg4->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ set_swap(ptr->swap_on);
+ if (0 != (ptr->lasterror = getrellink(ptr->socket, rootid, sourceid, destid, &anchorstr))) {
+ php3_error(E_WARNING, "command (getrellink) returned -1\n");
+ RETURN_FALSE;
+ }
+
+ RETURN_STRING(anchorstr, 0);
+}
+/* }}} */
+
+
+void php3_info_hw()
+{
+ php3_printf("HG-CSP Version: 7.17");
+}
+
+void php3_hw_connection_info(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *arg1;
+ hw_connection *ptr;
+ int link, type;
+
+ if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+ convert_to_long(arg1);
+ link=arg1->value.lval;
+ ptr = php3_list_find(link,&type);
+ if(!ptr || (type!=php3_hw_module.le_socketp && type!=php3_hw_module.le_psocketp)) {
+ php3_error(E_WARNING,"Unable to find file identifier %d",link);
+ RETURN_FALSE;
+ }
+
+ php3_printf("Hyperwave Info:\nhost=%s,\nserver string=%s\nversion=%d\nswap=%d\n", ptr->hostname, ptr->server_string, ptr->version, ptr->swap_on);
+}
+
+void print_msg(hg_msg *msg, char *str, int txt)
+{
+ char *ptr;
+ int i;
+
+ fprintf(stdout, "\nprint_msg: >>%s<<\n", str);
+ fprintf(stdout, "print_msg: length = %d\n", msg->length);
+ fprintf(stdout, "print_msg: msgid = %d\n", msg->version_msgid);
+ fprintf(stdout, "print_msg: msg_type = %d\n", msg->msg_type);
+ if ( msg->length > HEADER_LENGTH ) {
+ ptr = msg->buf;
+ for ( i = 0; i < msg->length-HEADER_LENGTH; i++ ) {
+ if ( *ptr == '\n' )
+ fprintf(stdout, "%c", *ptr++);
+ else if ( iscntrl(*ptr) )
+ {fprintf(stdout, "."); ptr++;}
+ else
+ fprintf(stdout, "%c", *ptr++);
+ }
+ }
+ fprintf(stdout, "\n\n");
+}
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * End:
+ */
diff --git a/ext/hyperwave/hw.h b/ext/hyperwave/hw.h
new file mode 100644
index 0000000000..21c2e6ad07
--- /dev/null
+++ b/ext/hyperwave/hw.h
@@ -0,0 +1,122 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of the GNU General Public License as published by |
+ | the Free Software Foundation; either version 2 of the License, or |
+ | (at your option) any later version. |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU General Public License |
+ | along with this program; if not, write to the Free Software |
+ | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
+ +----------------------------------------------------------------------+
+ | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
+ +----------------------------------------------------------------------+
+ */
+
+
+/* $Id$ */
+
+#ifndef _HW_H
+#define _HW_H
+
+#if HYPERWAVE
+#include "hg_comm.h"
+
+extern php3_module_entry hw_module_entry;
+#define hw_module_ptr &hw_module_entry
+
+typedef struct {
+ long default_link;
+ long num_links,num_persistent;
+ long max_links,max_persistent;
+ long allow_persistent;
+ int le_socketp, le_psocketp, le_document;
+} hw_module;
+
+extern hw_module php3_hw_module;
+
+typedef struct {
+ int size;
+ char *data;
+ char *attributes;
+ char *bodytag;
+} hw_document;
+
+extern hw_connection php3_hw_connection;
+
+extern int php3_minit_hw(INIT_FUNC_ARGS);
+extern void php3_hw_connect(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_pconnect(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_close(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_root(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_info(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_error(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_errormsg(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_mv(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_cp(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_deleteobject(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_changeobject(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getparents(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getparentsobj(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_children(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_childrenobj(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getchildcoll(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getchildcollobj(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getobject(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getandlock(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_unlock(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_gettext(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_edittext(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getcgi(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getremote(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getremotechildren(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_pipedocument(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_pipecgi(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_insertdocument(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_docbyanchorobj(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_docbyanchor(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getobjectbyquery(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getobjectbyqueryobj(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getobjectbyquerycoll(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getobjectbyquerycollobj(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getchilddoccoll(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getchilddoccollobj(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getanchors(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getanchorsobj(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getusername(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_setlinkroot(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_inscoll(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_incollections(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_insertobject(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_insdoc(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_identify(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_free_document(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_new_document(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_output_document(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_document_size(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_document_attributes(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_document_bodytag(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_document_content(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_objrec2array(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_array2objrec(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_connection_info(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_info_hw(void);
+extern void php3_hw_getsrcbydestobj(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_getrellink(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_dummy(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_who(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_hw_stat(INTERNAL_FUNCTION_PARAMETERS);
+#else
+#define hw_module_ptr NULL
+#endif /* HYPERWAVE */
+#endif /* _HW_H */
+
diff --git a/ext/hyperwave/hw_error.h b/ext/hyperwave/hw_error.h
new file mode 100644
index 0000000000..9730995e31
--- /dev/null
+++ b/ext/hyperwave/hw_error.h
@@ -0,0 +1,117 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 3.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of the GNU General Public License as published by |
+ | the Free Software Foundation; either version 2 of the License, or |
+ | (at your option) any later version. |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU General Public License |
+ | along with this program; if not, write to the Free Software |
+ | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
+ +----------------------------------------------------------------------+
+ | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
+ +----------------------------------------------------------------------+
+ */
+
+
+/* $Id$ */
+#ifndef _HW_ERROR_H
+#define _HW_ERROR_H
+
+#if HYPERWAVE
+
+#define NOACCESS 1 /* Access denied */
+#define NODOCS 2 /* No documents */
+#define NONAME 3 /* No collection name */
+#define NODOC 4 /* Object is not a document */
+#define NOOBJ 5 /* No object received */
+#define NOCOLLS 6 /* No collections received */
+#define DBSTUBNG 7 /* Connection to low-level database failed */
+#define NOTFOUND 8 /* Object not found */
+#define EXIST 9 /* Collection already exists */
+#define FATHERDEL 10 /* parent collection disappeared */
+#define FATHNOCOLL 11 /* parent collection not a collection */
+#define NOTEMPTY 12 /* Collection not empty */
+#define DESTNOCOLL 13 /* Destination not a collection */
+#define SRCEQDEST 14 /* Source equals destination */
+#define REQPEND 15 /* Request pending */
+#define TIMEOUT 16 /* Timeout */
+#define NAMENOTUNIQUE 17 /* Name not unique */
+#define WRITESTOPPED 18 /* Database now read-only; try again later */
+#define LOCKED 19 /* Object locked; try again later */
+#define CHANGEBASEFLD 20 /* Change of base-attribute */
+#define NOTREMOVED 21 /* Attribute not removed */
+#define FLDEXISTS 22 /* Attribute exists */
+#define CMDSYNTAX 23 /* Syntax error in command */
+#define NOLANGUAGE 24 /* No or unknown language specified */
+#define WRGTYPE 25 /* Wrong type in object */
+#define WRGVERSION 26 /* Client version too old */
+#define CONNECTION 27 /* No connection to other server */
+#define SYNC 28 /* Synchronization error */
+#define NOPATH 29 /* No path entry */
+#define WRGPATH 30 /* Wrong path entry */
+#define PASSWD 31 /* Wrong password (server-to-server server authentication) */
+#define LC_NO_MORE_USERS 32 /* No more users for license */
+#define LC_NO_MORE_DOCS 33 /* No more documents for this session and license */
+#define RSERV_NRESP 34 /* Remote server not responding */
+#define Q_OVERFLOW 35 /* Query overflow */
+#define USR_BREAK 36 /* Break by user */
+#define N_IMPL 37 /* Not implemented */
+#define WRG_VALUE 38 /* Wrong value */
+#define INSUFF_FUNDS 39 /* Insufficient funds */
+#define REORG 40 /* Reorganization in progress */
+#define USER_LIMIT 41 /* Limit of simultaneous users reached */
+#define FTCONNECT 513 /* No connection to fulltext server */
+#define FTTIMEOUT 514 /* Connection timed out */
+#define FTINDEX 515 /* Something wrong with fulltext index */
+#define FTSYNTAX 516 /* Query syntax error */
+#define REQUESTPENDING 1025 /* Request pending */
+#define NOCONNECTION 1026 /* No connection to document server */
+#define WRONGVERSION 1027 /* Wrong protocol version */
+#define NOTINITIALIZED 1028 /* Not initialized */
+#define BADREQUEST 1029 /* Bad request */
+#define BADLRN 1030 /* Bad document number */
+#define OPENSTORE_WRITE 1031 /* Cannot write to local store */
+#define OPENSTORE_READ 1032 /* Cannot read from local store */
+#define READSTORE 1033 /* Store read error */
+#define WRITESTORE 1034 /* Write error */
+#define CLOSESTORE 1035 /* Close error */
+#define BADPATH 1036 /* Bad path */
+#define NOPATHDC 1037 /* No path */
+#define OPENFILE 1038 /* Cannot open file */
+#define READFILE 1039 /* Cannot read from file // same */
+#define WRITEFILE 1040 /* Cannot write to file */
+#define CONNECTCLIENT 1041 /* Could not connect to client */
+#define ACCEPT 1042 /* Could not accept connection */
+#define READSOCKET 1043 /* Could not read from socket */
+#define WRITESOCKET 1044 /* Could not write to socket */
+#define TOOMUCHDATA 1046 /* Received too much data */
+#define TOOFEWDATA 1047 /* Received too few data // ... */
+#define NOTIMPLEMENTED 1049 /* Not implemented */
+#define USERBREAK 1050 /* User break */
+#define INTERNAL 1051 /* Internal error */
+#define INVALIDOBJECT 1052 /* Invalid object */
+#define JOBTIMEOUT 1053 /* Job timed out */
+#define OPENPORT 1054 /* Cannot open port // ... for several resons */
+#define NODATA 1055 /* Received no data */
+#define NOPORT 1056 /* No port to handle this request */
+#define NOTCACHED 1057 /* Document not cached */
+#define BADCACHETYPE 1058 /* Bad cache type */
+#define OPENCACHE_WRITE 1059 /* Cannot write to cache */
+#define OPENCACHE_READ 1060 /* Cannot read from cache // same */
+#define NOSOURCE 1061 /* Do not know what to read */
+#define CLOSECACHE 1062 /* Could not insert into cache */
+#define CONNECTREMOTE 1063 /* Could not connect to remote server */
+#define LOCKREFUSED 1064 /* Lock refused // could not lock the stores */
+
+#endif
+#endif
diff --git a/ext/hyperwave/setup.stub b/ext/hyperwave/setup.stub
new file mode 100644
index 0000000000..51099054d1
--- /dev/null
+++ b/ext/hyperwave/setup.stub
@@ -0,0 +1,6 @@
+# $Source$
+# $Id$
+
+define_option with-hyperwave 'Hyperwave support?' yesno no \
+' Whether to build with Hyperwave support. More\n
+ information about Hyperwave can be found at http://www.hyperwave.com.'
diff --git a/ext/rpc/com/COM.c b/ext/rpc/com/COM.c
new file mode 100644
index 0000000000..17e4a28f3b
--- /dev/null
+++ b/ext/rpc/com/COM.c
@@ -0,0 +1,959 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP HTML Embedded Scripting Language Version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997,1998 PHP Development Team (See Credits file) |
+ +----------------------------------------------------------------------+
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of one of the following licenses: |
+ | |
+ | A) the GNU General Public License as published by the Free Software |
+ | Foundation; either version 2 of the License, or (at your option) |
+ | any later version. |
+ | |
+ | B) the PHP License as published by the PHP Development Team and |
+ | included in the distribution in the file: LICENSE |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of both licenses referred to here. |
+ | If you did not, or have any questions about PHP licensing, please |
+ | contact core@php.net. |
+ +----------------------------------------------------------------------+
+ | Author: Zeev Suraski <zeev@zend.com> |
+ +----------------------------------------------------------------------+
+ */
+
+
+/*
+ * This module implements support for COM components that support the IDispatch
+ * interface. Both local (COM) and remote (DCOM) components can be accessed.
+ *
+ * Type libraries can be loaded (in order for PHP to recognize automation constants)
+ * by specifying a typelib_file in the PHP .ini file. That file should contain
+ * paths to type libraries, one in every line. By default, constants are registered
+ * as case-sensitive. If you want them to be defined as case-insensitive, add
+ * #case_insensitive or #cis at the end of the type library path.
+ *
+ * This is also the first module to demonstrate Zend's OO syntax overloading
+ * capabilities. CORBA coders are invited to write a CORBA module as well!
+ *
+ * Zeev
+ */
+
+#if WIN32|WINNT
+
+#define _WIN32_DCOM
+
+#include "php.h"
+#include "php3_COM.h"
+#include "zend_compile.h"
+#include "php_ini.h"
+
+#include "objbase.h"
+#include "olestd.h"
+#include <ctype.h>
+
+
+static int le_idispatch;
+
+function_entry COM_functions[] = {
+ {"com_load", php3_COM_load, NULL},
+ {"com_invoke", php3_COM_invoke, NULL},
+
+ PHP_FE(com_propget, NULL)
+ PHP_FE(com_propput, NULL)
+
+ PHP_NAMED_FE(com_get, php3_com_propget, NULL)
+ PHP_NAMED_FE(com_propset, php3_com_propput, NULL)
+ PHP_NAMED_FE(com_set, php3_com_propput, NULL)
+
+ {NULL, NULL, NULL}
+};
+
+php3_module_entry COM_module_entry = {
+ "Win32 COM", COM_functions, php3_minit_COM, php3_mshutdown_COM, NULL, NULL, NULL, STANDARD_MODULE_PROPERTIES
+};
+
+void php_register_COM_class();
+
+static int php_COM_load_typelib(char *typelib_name, int mode);
+
+static char *_php3_COM_error_message(HRESULT hr)
+{
+ void *pMsgBuf;
+
+ if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
+ hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pMsgBuf, 0, NULL)) {
+ char error_string[] = "No description available";
+
+ pMsgBuf = LocalAlloc(LMEM_FIXED, sizeof(error_string));
+ memcpy(pMsgBuf, error_string, sizeof(error_string));
+ }
+
+ return pMsgBuf;
+}
+
+
+static OLECHAR *php_char_to_OLECHAR(char *C_str, uint strlen)
+{
+ OLECHAR *unicode_str = (OLECHAR *) emalloc(sizeof(OLECHAR)*(strlen+1));
+ OLECHAR *unicode_ptr = unicode_str;
+
+ while (*C_str) {
+ *unicode_ptr++ = (unsigned short) *C_str++;
+ }
+ *unicode_ptr = 0;
+
+ return unicode_str;
+}
+
+
+char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int persistent)
+{
+ uint length = OLESTRLEN(unicode_str);
+ char *C_str = (char *) pemalloc(length+1, persistent), *p = C_str;
+
+ while (*unicode_str) {
+ *p++ = (char) *unicode_str++;
+ }
+ *p = 0;
+
+ if (out_length) {
+ *out_length = length;
+ }
+
+ return C_str;
+}
+
+
+static char *_php3_string_from_clsid(CLSID *clsid)
+{
+ LPOLESTR ole_clsid;
+ char *clsid_str;
+
+ StringFromCLSID(clsid, &ole_clsid);
+ //s_clsid = OLE2A(ole_clsid);
+ clsid_str = php_OLECHAR_to_char(ole_clsid, NULL, 0);
+ LocalFree(ole_clsid);
+
+ return clsid_str;
+}
+
+
+static void _php3_idispatch_destructor(IDispatch *i_dispatch)
+{
+ i_dispatch->lpVtbl->Release(i_dispatch);
+}
+
+
+static PHP_INI_MH(OnTypelibFileChange)
+{
+ FILE *typelib_file;
+ char *typelib_name_buffer;
+#if SUPPORT_INTERACTIVE
+ int interactive;
+ ELS_FETCH();
+
+ interactive = EG(interactive);
+#endif
+
+
+ if (!new_value || (typelib_file=fopen(new_value, "r"))==NULL) {
+ return FAILURE;
+ }
+
+#if SUPPORT_INTERACTIVE
+ if (interactive) {
+ printf("Loading type libraries...");
+ fflush(stdout);
+ }
+#endif
+
+ typelib_name_buffer = (char *) malloc(sizeof(char)*1024);
+
+ while (fgets(typelib_name_buffer, 1024, typelib_file)) {
+ char *typelib_name;
+ char *modifier;
+ int mode = CONST_PERSISTENT|CONST_CS;
+
+ if (typelib_name_buffer[0]==';') {
+ continue;
+ }
+ typelib_name = strtok(typelib_name_buffer, "\r\n"); /* get rid of newlines */
+ typelib_name = strtok(typelib_name, "#");
+ modifier = strtok(NULL, "#");
+ if (modifier) {
+ if (!strcmp(modifier, "cis") || !strcmp(modifier, "case_insensitive")) {
+ mode &= ~CONST_CS;
+ }
+ }
+#if SUPPORT_INTERACTIVE
+ if (interactive) {
+ printf("\rLoading %-60s\r", typelib_name);
+ }
+#endif
+ php_COM_load_typelib(typelib_name, mode);
+ }
+
+ free(typelib_name_buffer);
+ fclose(typelib_file);
+
+#if SUPPORT_INTERACTIVE
+ if (interactive) {
+ printf("\r%70s\r", "");
+ }
+#endif
+
+ return SUCCESS;
+}
+
+
+PHP_INI_BEGIN()
+ PHP_INI_ENTRY("allow_dcom", "0", PHP_INI_SYSTEM, NULL, NULL)
+ PHP_INI_ENTRY("typelib_file", NULL, PHP_INI_SYSTEM, OnTypelibFileChange, NULL)
+PHP_INI_END()
+
+
+int php3_minit_COM(INIT_FUNC_ARGS)
+{
+ CoInitialize(NULL);
+ le_idispatch = register_list_destructors(_php3_idispatch_destructor,NULL);
+ php_register_COM_class();
+ REGISTER_INI_ENTRIES();
+ return SUCCESS;
+}
+
+
+int php3_mshutdown_COM(SHUTDOWN_FUNC_ARGS)
+{
+ CoUninitialize();
+ UNREGISTER_INI_ENTRIES();
+ return SUCCESS;
+}
+
+
+void php3_COM_load(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval *module_name, *server_name=NULL;
+ CLSID clsid;
+ HRESULT hr;
+ OLECHAR *ProgID;
+ IDispatch FAR *i_dispatch = NULL;
+ char *error_message;
+ char *clsid_str;
+
+ switch (ARG_COUNT(ht)) {
+ case 1:
+ getParameters(ht, 1, &module_name);
+ break;
+ case 2:
+ if (!INI_INT("allow_dcom")) {
+ php3_error(E_WARNING, "DCOM is disabled");
+ RETURN_FALSE;
+ }
+ getParameters(ht, 2, &module_name, &server_name);
+ convert_to_string(server_name);
+ break;
+ default:
+ WRONG_PARAM_COUNT;
+ break;
+ }
+
+ convert_to_string(module_name);
+ ProgID = php_char_to_OLECHAR(module_name->value.str.val, module_name->value.str.len);
+ hr=CLSIDFromProgID(ProgID, &clsid);
+ efree(ProgID);
+
+ // obtain CLSID
+ if (FAILED(hr)) {
+ error_message = _php3_COM_error_message(hr);
+ php3_error(E_WARNING,"Invalid ProgID: %s\n", error_message);
+ LocalFree(error_message);
+ RETURN_FALSE;
+ }
+
+ // obtain IDispatch
+ if (!server_name) {
+ hr=CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, (void **) &i_dispatch);
+ } else {
+ COSERVERINFO server_info;
+ MULTI_QI pResults;
+
+ server_info.dwReserved1=0;
+ server_info.dwReserved2=0;
+ server_info.pwszName = php_char_to_OLECHAR(server_name->value.str.val, server_name->value.str.len);
+ server_info.pAuthInfo=NULL;
+
+ pResults.pIID = &IID_IDispatch;
+ pResults.pItf = NULL;
+ pResults.hr = S_OK;
+ hr=CoCreateInstanceEx(&clsid, NULL, CLSCTX_SERVER, &server_info, 1, &pResults);
+ if (SUCCEEDED(hr)) {
+ hr = pResults.hr;
+ i_dispatch = (IDispatch *) pResults.pItf;
+ }
+ efree(server_info.pwszName);
+ }
+ if (FAILED(hr)) {
+ error_message = _php3_COM_error_message(hr);
+ clsid_str = _php3_string_from_clsid(&clsid);
+ php3_error(E_WARNING,"Unable to obtain IDispatch interface for CLSID %s: %s",clsid_str,error_message);
+ LocalFree(error_message);
+ efree(clsid_str);
+ RETURN_FALSE;
+ }
+
+ RETURN_LONG(php3_list_insert(i_dispatch,le_idispatch));
+}
+
+
+static void php_variant_to_pval(VARIANTARG *var_arg, pval *pval_arg, int persistent)
+{
+ switch (var_arg->vt) {
+ case VT_EMPTY:
+ var_uninit(pval_arg);
+ break;
+ case VT_UI1:
+ pval_arg->value.lval = (long) var_arg->bVal;
+ pval_arg->type = IS_LONG;
+ break;
+ case VT_I2:
+ pval_arg->value.lval = (long) var_arg->iVal;
+ pval_arg->type = IS_LONG;
+ break;
+ case VT_I4:
+ pval_arg->value.lval = var_arg->lVal;
+ pval_arg->type = IS_LONG;
+ break;
+ case VT_R4:
+ pval_arg->value.dval = (double) var_arg->fltVal;
+ pval_arg->type = IS_DOUBLE;
+ break;
+ case VT_R8:
+ pval_arg->value.dval = var_arg->dblVal;
+ pval_arg->type = IS_DOUBLE;
+ break;
+ case VT_BOOL:
+
+ if (var_arg->boolVal & 0xFFFF) {
+ pval_arg->value.lval = 1;
+ } else {
+
+ pval_arg->value.lval = 0;
+ }
+
+ pval_arg->type = IS_BOOL;
+ break;
+ case VT_BSTR:
+ pval_arg->value.str.val = php_OLECHAR_to_char(var_arg->bstrVal, &pval_arg->value.str.len, persistent);
+ pval_arg->type = IS_STRING;
+ break;
+ case VT_UNKNOWN:
+ case VT_DISPATCH:
+ /* possibly, return IDispatch as a new COM object. right now - just get rid of it */
+ var_arg->pdispVal->lpVtbl->Release(var_arg->pdispVal);
+ var_reset(pval_arg);
+ break;
+ default:
+ php3_error(E_WARNING,"Unsupported variant type");
+ var_reset(pval_arg);
+ break;
+ }
+}
+
+
+static void _php3_pval_to_variant(pval *pval_arg, VARIANTARG *var_arg)
+{
+ OLECHAR *unicode_str;
+
+ switch (pval_arg->type) {
+ case IS_OBJECT:
+ case IS_ARRAY:
+ var_arg->vt = VT_EMPTY;
+ break;
+ case IS_LONG:
+ case IS_BOOL:
+ var_arg->vt = VT_I4; // assuming 32-bit platform
+ var_arg->lVal = pval_arg->value.lval;
+ break;
+ case IS_DOUBLE:
+ var_arg->vt = VT_R8; // assuming 64-bit double precision
+ var_arg->dblVal = pval_arg->value.dval;
+ break;
+ case IS_STRING:
+ unicode_str = php_char_to_OLECHAR(pval_arg->value.str.val, pval_arg->value.str.len);
+ var_arg->bstrVal = SysAllocString(unicode_str);
+ var_arg->vt = VT_BSTR;
+ efree(unicode_str);
+ break;
+ }
+}
+
+
+
+int do_COM_invoke(IDispatch *i_dispatch, pval *function_name, VARIANTARG *var_result, pval **arguments, int arg_count)
+{
+ DISPID dispid;
+ HRESULT hr;
+ OLECHAR *funcname;
+ char *error_message;
+ VARIANTARG *variant_args;
+ int current_arg, current_variant;
+ DISPPARAMS dispparams;
+
+ funcname = php_char_to_OLECHAR(function_name->value.str.val, function_name->value.str.len);
+
+ hr = i_dispatch->lpVtbl->GetIDsOfNames(i_dispatch, &IID_NULL, &funcname,
+ 1, LOCALE_SYSTEM_DEFAULT, &dispid);
+
+ if (FAILED(hr)) {
+ error_message = _php3_COM_error_message(hr);
+ php3_error(E_WARNING,"Unable to lookup %s: %s\n", function_name->value.str.val, error_message);
+ LocalFree(error_message);
+ efree(funcname);
+ return FAILURE;
+ }
+
+ variant_args = (VARIANTARG *) emalloc(sizeof(VARIANTARG)*arg_count);
+
+ for (current_arg=0; current_arg<arg_count; current_arg++) {
+ current_variant = arg_count - current_arg - 1;
+ _php3_pval_to_variant(arguments[current_arg], &variant_args[current_variant]);
+ }
+
+
+ dispparams.rgvarg = variant_args;
+ dispparams.rgdispidNamedArgs = NULL;
+ dispparams.cArgs = arg_count;
+ dispparams.cNamedArgs = 0;
+
+ hr = i_dispatch->lpVtbl->Invoke(i_dispatch, dispid, &IID_NULL,
+ LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD,
+ &dispparams, var_result, NULL, 0);
+
+ if (FAILED(hr)) {
+ error_message = _php3_COM_error_message(hr);
+ php3_error(E_WARNING,"Invoke() failed: %s\n", error_message);
+ LocalFree(error_message);
+ efree(funcname);
+ efree(variant_args);
+ return FAILURE;
+ }
+
+ efree(variant_args);
+ efree(funcname);
+ return SUCCESS;
+}
+
+
+void php3_COM_invoke(INTERNAL_FUNCTION_PARAMETERS)
+{
+ pval **arguments;
+ pval *object, *function_name;
+ IDispatch *i_dispatch;
+ int type;
+ int arg_count = ARG_COUNT(ht);
+ VARIANTARG var_result;
+
+ if (arg_count<2) {
+ WRONG_PARAM_COUNT;
+ }
+ arguments = (pval **) emalloc(sizeof(pval *)*arg_count);
+ if (getParametersArray(ht, arg_count, arguments)==FAILURE) {
+ RETURN_FALSE;
+ }
+
+ object = arguments[0];
+ function_name = arguments[1];
+
+ /* obtain i_dispatch interface */
+ convert_to_long(object);
+ i_dispatch = php3_list_find(object->value.lval, &type);
+ if (!i_dispatch || (type!=le_idispatch)) {
+ php3_error(E_WARNING,"%d is not a COM object handler", function_name->value.str.val);
+ RETURN_FALSE;
+ }
+
+ /* obtain property/method handler */
+ convert_to_string(function_name);
+
+ if (do_COM_invoke(i_dispatch, function_name, &var_result, arguments+2, arg_count-2)==FAILURE) {
+ RETURN_FALSE;
+ }
+ efree(arguments);
+
+ php_variant_to_pval(&var_result, return_value, 0);
+}
+
+
+
+static int do_COM_offget(VARIANTARG *var_result, VARIANTARG *array, pval *arg_property, int cleanup)
+{
+ switch (array->vt) {
+ case VT_DISPATCH: { /* a Collection, possibly */
+ pval function_name;
+ IDispatch *i_dispatch = array->pdispVal;
+ int retval;
+
+ function_name.value.str.val = "Item";
+ function_name.value.str.len = 4;
+ function_name.type = IS_STRING;
+ retval = do_COM_invoke(i_dispatch, &function_name, var_result, &arg_property, 1);
+ if (cleanup) {
+ i_dispatch->lpVtbl->Release(i_dispatch);
+ }
+ return retval;
+ }
+ }
+ return FAILURE;
+}
+
+
+static int do_COM_propget(VARIANTARG *var_result, IDispatch *i_dispatch, pval *arg_property, int cleanup)
+{
+ DISPID dispid;
+ HRESULT hr;
+ OLECHAR *propname;
+ char *error_message;
+ DISPPARAMS dispparams;
+
+
+ /* obtain property handler */
+ propname = php_char_to_OLECHAR(arg_property->value.str.val, arg_property->value.str.len);
+
+ hr = i_dispatch->lpVtbl->GetIDsOfNames(i_dispatch, &IID_NULL, &propname,
+ 1, LOCALE_SYSTEM_DEFAULT, &dispid);
+
+ if (FAILED(hr)) {
+ error_message = _php3_COM_error_message(hr);
+ php3_error(E_WARNING,"Unable to lookup %s: %s\n", arg_property->value.str.val, error_message);
+ LocalFree(error_message);
+ efree(propname);
+ if (cleanup) {
+ i_dispatch->lpVtbl->Release(i_dispatch);
+ }
+ return FAILURE;
+ }
+
+ dispparams.cArgs = 0;
+ dispparams.cNamedArgs = 0;
+
+ hr = i_dispatch->lpVtbl->Invoke(i_dispatch, dispid, &IID_NULL,
+ LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET,
+ &dispparams, var_result, NULL, 0);
+
+ if (FAILED(hr)) {
+ error_message = _php3_COM_error_message(hr);
+ php3_error(E_WARNING,"PropGet() failed: %s\n", error_message);
+ LocalFree(error_message);
+ efree(propname);
+ if (cleanup) {
+ i_dispatch->lpVtbl->Release(i_dispatch);
+ }
+ return FAILURE;
+ }
+
+ efree(propname);
+ if (cleanup) {
+ i_dispatch->lpVtbl->Release(i_dispatch);
+ }
+ return SUCCESS;
+}
+
+
+
+static void do_COM_propput(pval *return_value, IDispatch *i_dispatch, pval *arg_property, pval *value)
+{
+ DISPID dispid;
+ HRESULT hr;
+ OLECHAR *propname;
+ char *error_message;
+ VARIANTARG var_result;
+ DISPPARAMS dispparams;
+ VARIANTARG new_value;
+ DISPID mydispid = DISPID_PROPERTYPUT;
+
+
+ /* obtain property handler */
+ propname = php_char_to_OLECHAR(arg_property->value.str.val, arg_property->value.str.len);
+
+ hr = i_dispatch->lpVtbl->GetIDsOfNames(i_dispatch, &IID_NULL, &propname,
+ 1, LOCALE_SYSTEM_DEFAULT, &dispid);
+
+ if (FAILED(hr)) {
+ error_message = _php3_COM_error_message(hr);
+ php3_error(E_WARNING,"Unable to lookup %s: %s\n", arg_property->value.str.val, error_message);
+ LocalFree(error_message);
+ efree(propname);
+ RETURN_FALSE;
+ }
+
+
+ _php3_pval_to_variant(value, &new_value);
+ dispparams.rgvarg = &new_value;
+ dispparams.rgdispidNamedArgs = &mydispid;
+ dispparams.cArgs = 1;
+ dispparams.cNamedArgs = 1;
+
+ hr = i_dispatch->lpVtbl->Invoke(i_dispatch, dispid, &IID_NULL,
+ LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT,
+ &dispparams, NULL, NULL, 0);
+
+ dispparams.cArgs = 0;
+ dispparams.cNamedArgs = 0;
+
+ hr = i_dispatch->lpVtbl->Invoke(i_dispatch, dispid, &IID_NULL,
+ LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET,
+ &dispparams, &var_result, NULL, 0);
+
+ if (FAILED(hr)) {
+ error_message = _php3_COM_error_message(hr);
+ php3_error(E_WARNING,"PropPut() failed: %s\n", error_message);
+ LocalFree(error_message);
+ efree(propname);
+ RETURN_FALSE;
+ }
+
+ php_variant_to_pval(&var_result, return_value, 0);
+
+ efree(propname);
+}
+
+
+PHP_FUNCTION(com_propget)
+{
+ pval *arg_idispatch, *arg_property;
+ int type;
+ IDispatch *i_dispatch;
+ VARIANTARG var_result;
+
+ if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &arg_idispatch, &arg_property)==FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ /* obtain i_dispatch interface */
+ convert_to_long(arg_idispatch);
+ /* obtain i_dispatch interface */
+ i_dispatch = php3_list_find(arg_idispatch->value.lval,&type);
+ if (!i_dispatch || (type!=le_idispatch)) {
+ php3_error(E_WARNING,"%d is not a COM object handler", arg_idispatch->value.lval);
+ }
+ convert_to_string(arg_property);
+
+ if (do_COM_propget(&var_result, i_dispatch, arg_property, 0)==FAILURE) {
+ RETURN_FALSE;
+ }
+ php_variant_to_pval(&var_result, return_value, 0);
+}
+
+
+PHP_FUNCTION(com_propput)
+{
+ pval *arg_idispatch, *arg_property, *arg_value;
+ int type;
+ IDispatch *i_dispatch;
+
+ if (ARG_COUNT(ht)!=3 || getParameters(ht, 3, &arg_idispatch, &arg_property, &arg_value)==FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ /* obtain i_dispatch interface */
+ convert_to_long(arg_idispatch);
+ /* obtain i_dispatch interface */
+ i_dispatch = php3_list_find(arg_idispatch->value.lval,&type);
+ if (!i_dispatch || (type!=le_idispatch)) {
+ php3_error(E_WARNING,"%d is not a COM object handler", arg_idispatch->value.lval);
+ }
+ convert_to_string(arg_property);
+
+ do_COM_propput(return_value, i_dispatch, arg_property, arg_value);
+}
+
+
+VARIANTARG _php_COM_get_property_handler(zend_property_reference *property_reference)
+{
+ zend_overloaded_element *overloaded_property;
+ zend_llist_element *element;
+ pval **idispatch_handle;
+ pval *object = *property_reference->object;
+ IDispatch *i_dispatch;
+ int type;
+ VARIANTARG var_result;
+
+ /*printf("Reading a property from a TestClass object:\n");*/
+
+
+ /* fetch the IDispatch interface */
+ zend_hash_index_find(object->value.obj.properties, 0, (void **) &idispatch_handle);
+ i_dispatch = php3_list_find((*idispatch_handle)->value.lval,&type);
+ if (!i_dispatch || (type!=le_idispatch)) {
+ /* bail out */
+ }
+
+ var_result.vt = VT_DISPATCH;
+ var_result.pdispVal = i_dispatch;
+
+ for (element=property_reference->elements_list.head; element; element=element->next) {
+ overloaded_property = (zend_overloaded_element *) element->data;
+ switch (overloaded_property->type) {
+ case IS_ARRAY:
+ if (do_COM_offget(&var_result, &var_result, &overloaded_property->element, element!=property_reference->elements_list.head)==FAILURE) {
+ /* bail out */
+ }
+ /*printf("Array offset: ");*/
+ break;
+ case IS_OBJECT:
+ if (var_result.vt != VT_DISPATCH) {
+ /* bail out */
+ } else {
+ if (do_COM_propget(&var_result, var_result.pdispVal, &overloaded_property->element, element!=property_reference->elements_list.head)==FAILURE) {
+ /* bail out */
+ }
+ /*printf("Object property: ");*/
+ }
+ break;
+ case IS_METHOD:
+ return var_result;
+ break;
+ }
+ /*
+ switch (overloaded_property->element.type) {
+ case IS_LONG:
+ printf("%d (numeric)\n", overloaded_property->element.value.lval);
+ break;
+ case IS_STRING:
+ printf("'%s'\n", overloaded_property->element.value.str.val);
+ break;
+ }
+ */
+ pval_destructor(&overloaded_property->element);
+ }
+ return var_result;
+}
+
+
+pval php_COM_get_property_handler(zend_property_reference *property_reference)
+{
+ pval result;
+ VARIANTARG var_result = _php_COM_get_property_handler(property_reference);
+
+ php_variant_to_pval(&var_result, &result, 0);
+ return result;
+}
+
+
+int php_COM_set_property_handler(zend_property_reference *property_reference, pval *value)
+{
+ pval result;
+ zend_overloaded_element *overloaded_property;
+ zend_llist_element *element;
+ pval **idispatch_handle;
+ pval *object = *property_reference->object;
+ IDispatch *i_dispatch;
+ int type;
+ VARIANTARG var_result;
+
+ /*printf("Reading a property from a TestClass object:\n");*/
+
+
+ /* fetch the IDispatch interface */
+ zend_hash_index_find(object->value.obj.properties, 0, (void **) &idispatch_handle);
+ i_dispatch = php3_list_find((*idispatch_handle)->value.lval,&type);
+ if (!i_dispatch || (type!=le_idispatch)) {
+ /* bail out */
+ }
+ var_result.vt = VT_DISPATCH;
+ var_result.pdispVal = i_dispatch;
+
+ for (element=property_reference->elements_list.head; element && element!=property_reference->elements_list.tail; element=element->next) {
+ overloaded_property = (zend_overloaded_element *) element->data;
+ switch (overloaded_property->type) {
+ case IS_ARRAY:
+ /*printf("Array offset: ");*/
+ break;
+ case IS_OBJECT:
+ if (var_result.vt != VT_DISPATCH) {
+ /* bail out */
+ } else {
+ do_COM_propget(&var_result, i_dispatch, &overloaded_property->element, element!=property_reference->elements_list.head);
+ /*printf("Object property: ");*/
+ }
+ break;
+ case IS_METHOD:
+ /* this shouldn't happen */
+ return FAILURE;
+ }
+ /*
+ switch (overloaded_property->element.type) {
+ case IS_LONG:
+ printf("%d (numeric)\n", overloaded_property->element.value.lval);
+ break;
+ case IS_STRING:
+ printf("'%s'\n", overloaded_property->element.value.str.val);
+ break;
+ }
+ */
+ pval_destructor(&overloaded_property->element);
+ }
+
+ if (var_result.vt != VT_DISPATCH) {
+ return FAILURE;
+ }
+ overloaded_property = (zend_overloaded_element *) element->data;
+ do_COM_propput(&result, var_result.pdispVal, &overloaded_property->element, value);
+ pval_destructor(&overloaded_property->element);
+ return SUCCESS;
+}
+
+
+
+void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
+{
+ zend_overloaded_element *overloaded_property;
+ pval *object = *property_reference->object;
+ zend_overloaded_element *function_name = (zend_overloaded_element *) property_reference->elements_list.tail->data;
+
+ if (zend_llist_count(&property_reference->elements_list)==1
+ && !strcmp(function_name->element.value.str.val, "com")) { /* constructor */
+ pval *object_handle;
+
+ php3_COM_load(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ if (!zend_is_true(return_value)) {
+ var_reset(object);
+ return;
+ }
+ object_handle = (pval *) emalloc(sizeof(pval));
+ *object_handle = *return_value;
+ pval_copy_constructor(object_handle);
+ object_handle->refcount = 1;
+ object_handle->is_ref=0;
+ zend_hash_index_update(object->value.obj.properties, 0, &object_handle, sizeof(pval *), NULL);
+ pval_destructor(&function_name->element);
+ } else {
+ VARIANTARG object_handle = _php_COM_get_property_handler(property_reference);
+ pval **arguments;
+ int arg_count = ARG_COUNT(ht);
+ VARIANTARG var_result;
+
+ if (object_handle.vt != VT_DISPATCH) {
+ /* that shouldn't happen */
+ return;
+ }
+ arguments = (pval **) emalloc(sizeof(pval *)*arg_count);
+ getParametersArray(ht, arg_count, arguments);
+
+ if (do_COM_invoke((IDispatch *) object_handle.pdispVal, &function_name->element, &var_result, arguments, arg_count)==FAILURE) {
+ RETVAL_FALSE;
+ }
+ pval_destructor(&function_name->element);
+ efree(arguments);
+ php_variant_to_pval(&var_result, return_value, 0);
+ }
+
+ for (overloaded_property = (zend_overloaded_element *) zend_llist_get_first(&property_reference->elements_list);
+ overloaded_property;
+ overloaded_property = (zend_overloaded_element *) zend_llist_get_next(&property_reference->elements_list)) {
+ switch (overloaded_property->type) {
+ case IS_ARRAY:
+ break;
+ case IS_OBJECT:
+ break;
+ case IS_METHOD:
+
+ break;
+ }
+ }
+}
+
+
+void php_register_COM_class()
+{
+ zend_class_entry class_entry, *registered_class;
+
+ class_entry.name = strdup("COM");
+ class_entry.name_length = sizeof("COM")-1;
+
+ class_entry.handle_property_get = php_COM_get_property_handler;
+ class_entry.handle_property_set = php_COM_set_property_handler;
+ class_entry.handle_function_call = php_COM_call_function_handler;
+ registered_class = register_internal_class(&class_entry);
+}
+
+
+static int php_COM_load_typelib(char *typelib_name, int mode)
+{
+ ITypeLib *TypeLib;
+ ITypeComp *TypeComp;
+ OLECHAR *p;
+ int i;
+ int interfaces;
+ ELS_FETCH();
+
+ p = php_char_to_OLECHAR(typelib_name, strlen(typelib_name));
+
+ if (FAILED(LoadTypeLib(p, &TypeLib))) {
+ efree(p);
+ return FAILURE;
+ }
+
+ interfaces = TypeLib->lpVtbl->GetTypeInfoCount(TypeLib);
+
+ TypeLib->lpVtbl->GetTypeComp(TypeLib, &TypeComp);
+ for (i=0; i<interfaces; i++) {
+ TYPEKIND pTKind;
+
+ TypeLib->lpVtbl->GetTypeInfoType(TypeLib, i, &pTKind);
+ if (pTKind==TKIND_ENUM) {
+ ITypeInfo *TypeInfo;
+ VARDESC *pVarDesc;
+ UINT NameCount;
+ int j;
+#if 0
+ BSTR bstr_EnumId;
+ char *EnumId;
+
+ TypeLib->lpVtbl->GetDocumentation(TypeLib, i, &bstr_EnumId, NULL, NULL, NULL);
+ EnumId = php_OLECHAR_to_char(bstr_EnumId, NULL, 0);
+ printf("Enumeration %d - %s:\n", i, EnumId);
+ efree(EnumId);
+#endif
+
+ TypeLib->lpVtbl->GetTypeInfo(TypeLib, i, &TypeInfo);
+
+ j=0;
+ while (TypeInfo->lpVtbl->GetVarDesc(TypeInfo, j, &pVarDesc)==S_OK) {
+ BSTR bstr_ids;
+ char *ids;
+ zend_constant c;
+
+ TypeInfo->lpVtbl->GetNames(TypeInfo, pVarDesc->memid, &bstr_ids, 1, &NameCount);
+ if (NameCount!=1) {
+ j++;
+ continue;
+ }
+ LocalFree(bstr_ids);
+ ids = php_OLECHAR_to_char(bstr_ids, NULL, 1);
+ c.name_len = strlen(ids)+1;
+ c.name = ids;
+ php_variant_to_pval(pVarDesc->lpvarValue, &c.value, 1);
+ c.flags = mode;
+
+ zend_register_constant(&c ELS_CC);
+ //printf("%s -> %ld\n", ids, pVarDesc->lpvarValue->lVal);
+ j++;
+ }
+ TypeInfo->lpVtbl->Release(TypeInfo);
+ }
+ }
+
+
+ TypeLib->lpVtbl->Release(TypeLib);
+ efree(p);
+ return SUCCESS;
+}
+
+#endif
diff --git a/ext/rpc/com/php3_COM.h b/ext/rpc/com/php3_COM.h
new file mode 100644
index 0000000000..ed9cc4f526
--- /dev/null
+++ b/ext/rpc/com/php3_COM.h
@@ -0,0 +1,22 @@
+#ifndef _PHP3_COM_H
+#define _PHP3_COM_H
+
+#if WIN32|WINNT
+
+extern int php3_minit_COM(INIT_FUNC_ARGS);
+extern int php3_mshutdown_COM(SHUTDOWN_FUNC_ARGS);
+extern void php3_COM_load(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_COM_invoke(INTERNAL_FUNCTION_PARAMETERS);
+
+PHP_FUNCTION(com_propget);
+PHP_FUNCTION(com_propput);
+extern php3_module_entry COM_module_entry;
+#define COM_module_ptr &COM_module_entry
+
+#else
+
+#define COM_module_ptr NULL
+
+#endif /* Win32|WINNT */
+
+#endif /* _PHP3_COM_H */