summaryrefslogtreecommitdiff
path: root/ext/hyperwave/hg_comm.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/hyperwave/hg_comm.c')
-rw-r--r--ext/hyperwave/hg_comm.c4701
1 files changed, 4701 insertions, 0 deletions
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:
+ */
+