mirror of
https://github.com/php/php-src.git
synced 2024-11-29 21:04:10 +08:00
89279afdd3
(This used to cause a segm fault)
5777 lines
137 KiB
C
5777 lines
137 KiB
C
/*
|
|
+----------------------------------------------------------------------+
|
|
| PHP version 4.0 |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
|
|
+----------------------------------------------------------------------+
|
|
| This source file is subject to version 2.02 of the PHP license, |
|
|
| that is bundled with this package in the file LICENSE, and is |
|
|
| available at through the world-wide-web at |
|
|
| http://www.php.net/license/2_02.txt. |
|
|
| If you did not receive a copy of the PHP license and are unable to |
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
| license@php.net so we can mail you a copy immediately. |
|
|
+----------------------------------------------------------------------+
|
|
| Authors: Uwe Steinmann |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
/* $Id$ */
|
|
|
|
/* #define HW_DEBUG */
|
|
|
|
#include <stdlib.h>
|
|
#include "php.h"
|
|
#include "php_globals.h"
|
|
#include "SAPI.h"
|
|
|
|
#if HYPERWAVE
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#ifdef PHP_WIN32
|
|
# 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 "hg_comm.h"
|
|
#include "ext/standard/head.h"
|
|
|
|
/* Defining hw_optimize does optimize the send_objectbyidquery() function.
|
|
Instead of getting the complete return message including the objectrecords
|
|
with recv_hg_msg(), only the header of the return message is fetched.
|
|
The object records itself are fetched as they are needed straight from
|
|
the socket. This method requires less memory and is twice as fast because
|
|
reading from the net seems to be a bottleneck which has less impact if
|
|
the processing of the data is done in parallel.
|
|
*/
|
|
#define hw_optimize
|
|
|
|
/* Define hw_less_server_stress does reduce the stress on the hw server, by
|
|
using send_objectbyidquery() instead of send_getobject() multiple times.
|
|
send_objectbyidquery() gets a bunch of object records with one message.
|
|
This also reduced the number of lines in the servers log files.
|
|
Unfortunately this is not faster unless hw_optimize is defined, because
|
|
getting object records with multiple send_getobject() is already optimized.
|
|
First all request messages for each object are send and the the answers
|
|
are read. This gives the server the possibility to answer request already
|
|
while more request are comming in.
|
|
*/
|
|
#define hw_less_server_stress
|
|
|
|
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 = HW_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 the output is investigated. The bit is also
|
|
need to allow access on other server through the local
|
|
server. The hw_mapid() function won't work unless you
|
|
set F_DISTRIBUTED */
|
|
/* int version = HW_VERSION | F_DISTRIBUTED; */
|
|
/* int version = HW_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 *
|
|
***********************************************************************/
|
|
#ifdef newlist
|
|
ANCHOR *fnAddAnchor(zend_llist *pAnchorList,
|
|
int objectID,
|
|
int start, int end)
|
|
#else
|
|
ANCHOR *fnAddAnchor(DLIST *pAnchorList,
|
|
int objectID,
|
|
int start, int end)
|
|
#endif
|
|
{
|
|
ANCHOR *cur_ptr;
|
|
|
|
#ifdef newlist
|
|
ANCHOR **ptr;
|
|
if(NULL == (cur_ptr = (ANCHOR *) emalloc(sizeof(ANCHOR))))
|
|
return NULL;
|
|
#else
|
|
if((cur_ptr = (ANCHOR *) dlst_newnode(sizeof(ANCHOR))) == NULL) {
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
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;
|
|
|
|
#ifdef newlist
|
|
zend_llist_prepend_element(pAnchorList, &cur_ptr);
|
|
ptr = (ANCHOR **) zend_llist_get_first(pAnchorList);
|
|
#else
|
|
dlst_insertafter(pAnchorList, cur_ptr, PHP_DLST_HEAD(pAnchorList));
|
|
#endif
|
|
|
|
return(cur_ptr);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* Function fnDeleteAnchor() *
|
|
* *
|
|
* Inserts new anchor into anchor list. *
|
|
* Parameter: ptr: pointer to node *
|
|
* Return: void *
|
|
***********************************************************************/
|
|
#ifdef newlist
|
|
void fnDeleteAnchor(void *ptr1)
|
|
#else
|
|
void fnDeleteAnchor(ANCHOR *ptr)
|
|
#endif
|
|
{
|
|
#ifdef newlist
|
|
ANCHOR **ptr2, *ptr;
|
|
ptr2 = (ANCHOR **) ptr1;
|
|
ptr = *ptr2;
|
|
#endif
|
|
|
|
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);
|
|
|
|
#ifdef newlist
|
|
efree(ptr);
|
|
#else
|
|
dlst_freenode(ptr);
|
|
#endif
|
|
}
|
|
|
|
/***********************************************************************
|
|
* Function fnListAnchor() *
|
|
* *
|
|
* Lists all anchors in anchor list. *
|
|
* Parameter: ptr: pointer to list *
|
|
* Return: void *
|
|
***********************************************************************/
|
|
#ifdef newlist
|
|
void fnListAnchor(zend_llist *pAnchorList)
|
|
#else
|
|
void fnListAnchor(DLIST *pAnchorList)
|
|
#endif
|
|
{
|
|
#ifdef newlist
|
|
ANCHOR *cur_ptr, **ptr;
|
|
ptr = (ANCHOR **) zend_llist_get_last(pAnchorList);
|
|
if(ptr)
|
|
cur_ptr = *ptr;
|
|
while(ptr) {
|
|
fprintf(stderr, "0x%X->0x%X ", (int) ptr, (int) cur_ptr);
|
|
#else
|
|
ANCHOR *cur_ptr;
|
|
cur_ptr = (ANCHOR *) dlst_last(pAnchorList);
|
|
while(cur_ptr) {
|
|
fprintf(stderr, "0x%X ", (int) cur_ptr);
|
|
#endif
|
|
|
|
fprintf(stderr, "%d, %d, %s, %s, %s, %s %s\n", cur_ptr->start,
|
|
cur_ptr->end,
|
|
cur_ptr->tanchor == 1 ? "src" : "dest",
|
|
cur_ptr->destdocname,
|
|
cur_ptr->nameanchor,
|
|
cur_ptr->link,
|
|
cur_ptr->tagattr);
|
|
#ifdef newlist
|
|
ptr = (ANCHOR **) zend_llist_get_prev(pAnchorList);
|
|
if(ptr)
|
|
cur_ptr = *ptr;
|
|
#else
|
|
cur_ptr = (ANCHOR *) dlst_prev(cur_ptr);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* Function fnCmpAnchors() *
|
|
* *
|
|
* Compares to Anchors by its start position *
|
|
* Parameter: ANCHOR a1: First Anchor *
|
|
* ANCHOR a2: Second Anchor *
|
|
* Return: As strcmp *
|
|
***********************************************************************/
|
|
#ifdef newlist
|
|
int fnCmpAnchors(const void *e1, const void *e2)
|
|
{
|
|
ANCHOR *a1, **aa1, *a2, **aa2;
|
|
zend_llist_element **ee1, **ee2;
|
|
ee1 = (zend_llist_element **) e1;
|
|
ee2 = (zend_llist_element **) e2;
|
|
aa1 = (ANCHOR **) (*ee1)->data;
|
|
aa2 = (ANCHOR **) (*ee2)->data;
|
|
a1 = *aa1;
|
|
a2 = *aa2;
|
|
#else
|
|
int fnCmpAnchors(ANCHOR *a1, ANCHOR *a2)
|
|
{
|
|
#endif
|
|
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() *
|
|
* Uses either docofanchorrec or reldestrec to create a list of anchors *
|
|
* depending on anchormode *
|
|
* *
|
|
* Returns a list of Anchors converted from an object record *
|
|
* Parameter: int objectID: the object for which the list is created *
|
|
* char **anchors: object records of anchors *
|
|
* char **docofanchorrec: Name of destination absolut *
|
|
* char **reldestrec: Name of destination relativ to current *
|
|
* object *
|
|
* int ancount: number of anchors *
|
|
* int anchormode: 0 = use absolut dest, else rel. dest *
|
|
* Return: List of Anchors, NULL if error *
|
|
***********************************************************************/
|
|
#ifdef newlist
|
|
zend_llist *fnCreateAnchorList(hw_objectID objID, char **anchors, char **docofanchorrec, char **reldestrec, int ancount, int anchormode)
|
|
#else
|
|
DLIST *fnCreateAnchorList(hw_objectID objID, char **anchors, char **docofanchorrec, char **reldestrec, int ancount, int anchormode)
|
|
#endif
|
|
{
|
|
int start, end, i, destid, anchordestid, objectID;
|
|
ANCHOR *cur_ptr = NULL;
|
|
#ifdef newlist
|
|
zend_llist *pAnchorList;
|
|
pAnchorList = (zend_llist *) emalloc(sizeof(zend_llist));
|
|
zend_llist_init(pAnchorList, sizeof(char *), fnDeleteAnchor, 0);
|
|
#else
|
|
DLIST *pAnchorList = dlst_init();
|
|
#endif
|
|
|
|
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];
|
|
if(reldestrec) /* FIXME reldestrec may only be NULL if anchormode != 0 */
|
|
reldestptr = reldestrec[i];
|
|
|
|
/* Determine Position. Doesn't matter if Src or Dest
|
|
The Position field should always be there. Though there
|
|
are case in which the position has no meaning, e.g. if
|
|
a document is annotated and the annotation text doesn't
|
|
contain a link of type annotation,
|
|
In such a case the Position has the value 'invisible' */
|
|
str = strstr(object, "Position");
|
|
str += 9;
|
|
if((str != 9) && (0 != strncmp(str, "invisible", 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) {
|
|
destid = 0;
|
|
if(NULL != (str = strstr(tempptr, "ObjectID="))) {
|
|
str += 9;
|
|
sscanf(str, "0x%X", &destid);
|
|
}
|
|
/* This is basically for NAME tags. There is no need
|
|
to add the destname if it is the document itself.
|
|
*/
|
|
/* if(destid == objID) {
|
|
cur_ptr->destdocname = NULL;
|
|
} else { */
|
|
/* 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);
|
|
}
|
|
/* } */
|
|
}
|
|
}
|
|
|
|
/* 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);
|
|
}
|
|
|
|
{
|
|
char *htmlattr, *str2;
|
|
int offset;
|
|
str1 = object;
|
|
htmlattr = emalloc(strlen(object)); /* alloc mem big enough for htmlattr */
|
|
htmlattr[0] = '\0';
|
|
offset = 0;
|
|
while(NULL != (str = strstr(str1, "HtmlAttr="))) {
|
|
str += 9;
|
|
str1 = str;
|
|
while((*str1 != '\n') && (*str1 != '\0'))
|
|
str1++;
|
|
/* Find the '=' in the HTML attr and make sure it is part of the
|
|
attr and not somewhere in the objrec. */
|
|
if((NULL != (str2 = strchr(str, '='))) && (str2 < str1)) {
|
|
str2++;
|
|
strncpy(&htmlattr[offset], str, str2 - str);
|
|
offset = offset + (str2 - str);
|
|
htmlattr[offset++] = '"';
|
|
strncpy(&htmlattr[offset], str2, str1 - str2);
|
|
offset = offset + (str1 - str2);
|
|
htmlattr[offset++] = '"';
|
|
htmlattr[offset++] = ' ';
|
|
htmlattr[offset] = '\0';
|
|
}
|
|
}
|
|
if(offset){
|
|
/* remove last space */
|
|
htmlattr[offset-1] = '\0';
|
|
cur_ptr->htmlattr = estrdup(htmlattr);
|
|
}
|
|
efree(htmlattr);
|
|
}
|
|
|
|
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)
|
|
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 *
|
|
***********************************************************************/
|
|
#define BUFFERLEN 200
|
|
#ifdef newlist
|
|
char *fnInsAnchorsIntoText(char *text, zend_llist *pAnchorList, char **bodytag, char **urlprefix) {
|
|
ANCHOR **ptr;
|
|
#else
|
|
char *fnInsAnchorsIntoText(char *text, DLIST *pAnchorList, char **bodytag, char **urlprefix) {
|
|
#endif
|
|
ANCHOR *cur_ptr;
|
|
char bgstr[BUFFERLEN], istr[BUFFERLEN];
|
|
char **scriptname;
|
|
char *newtext;
|
|
int offset = 0;
|
|
int laststart=0;
|
|
char emptystring[BUFFERLEN];
|
|
int i;
|
|
|
|
emptystring[0] = '\0';
|
|
|
|
/* The following is very tricky and depends on how rewriting is setup on your webserver.
|
|
If you skip the scriptname in the url you will have to map each hyperwave name
|
|
to http://<hwname>. This may not always be a good idea. The best solution is
|
|
probably to provide a prefix for such
|
|
a case which is an optional parameter to hw_gettext() or hw_pipedocument().
|
|
FIXME: Currently, the variable SCRIPT_NAME is empty thouht SCRIPT_URL is
|
|
not. In our case this is OK, since as mentioned above it is better to have no
|
|
SCRIPT_NAME than to have if rewriting is on.
|
|
*/
|
|
if(urlprefix) {
|
|
scriptname = urlprefix;
|
|
} else {
|
|
zval **script_name;
|
|
scriptname = emalloc(5*sizeof(char *));
|
|
if (zend_hash_find(&EG(symbol_table), "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void **) &script_name)==FAILURE)
|
|
for(i=0; i<5; i++)
|
|
scriptname[i] = &emptystring;
|
|
else {
|
|
convert_to_string_ex(script_name);
|
|
for(i=0; i<5; i++)
|
|
scriptname[i] = (*script_name)->value.str.val;
|
|
}
|
|
|
|
#if 0
|
|
#if APACHE
|
|
{
|
|
int j;
|
|
array_header *arr = table_elts(((request_rec *) SG(server_context))->subprocess_env);
|
|
table_entry *elts = (table_entry *)arr->elts;
|
|
|
|
for (j=0; j < arr->nelts; j++) {
|
|
if((0 == strcmp(elts[j].key, "SCRIPT_NAME")) ||
|
|
(0 == strcmp(elts[j].key, "SCRIPT_URL")))
|
|
break;
|
|
}
|
|
scriptname = elts[j].val;
|
|
}
|
|
#else
|
|
scriptname = getenv("SCRIPT_FILENAME");
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
newtext = text;
|
|
bgstr[0] = '\0';
|
|
#ifdef newlist
|
|
zend_llist_sort(pAnchorList, fnCmpAnchors);
|
|
ptr = (ANCHOR **) zend_llist_get_last(pAnchorList);
|
|
if(ptr)
|
|
cur_ptr = *ptr;
|
|
while(NULL != ptr) {
|
|
#else
|
|
dlst_mergesort(pAnchorList, fnCmpAnchors);
|
|
cur_ptr = (ANCHOR *) dlst_last(pAnchorList);
|
|
while(NULL != cur_ptr) {
|
|
#endif
|
|
|
|
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:
|
|
snprintf(istr, BUFFERLEN, " background='%s'", cur_ptr->link);
|
|
break;
|
|
case HW_INTAG_LINK:
|
|
snprintf(istr, BUFFERLEN, " %s='%s'", cur_ptr->tagattr, cur_ptr->link);
|
|
offset -= 4; /* because there is no closing tag </A> */
|
|
/* laststart = cur_ptr->start; */
|
|
break;
|
|
case HW_APPLET_LINK:
|
|
if(cur_ptr->codebase)
|
|
snprintf(istr, BUFFERLEN, " CODEBASE='%s' CODE='%s'", cur_ptr->codebase, cur_ptr->code);
|
|
else
|
|
snprintf(istr, BUFFERLEN, " CODEBASE='/' CODE='%s'", cur_ptr->code);
|
|
break;
|
|
default:
|
|
newtext = fnInsStr(newtext, cur_ptr->end+offset, "</A>");
|
|
if(cur_ptr->fragment)
|
|
snprintf(istr, BUFFERLEN, "<A HREF='%s#%s'", cur_ptr->link, cur_ptr->fragment);
|
|
else
|
|
snprintf(istr, BUFFERLEN, "<A HREF='%s'", cur_ptr->link);
|
|
if(cur_ptr->htmlattr) {
|
|
strncat(istr, " ", BUFFERLEN - 1 - strlen(istr));
|
|
strncat(istr, cur_ptr->htmlattr, BUFFERLEN - 1 - strlen(istr));
|
|
}
|
|
strncat(istr, ">", BUFFERLEN - 1 - strlen(istr));
|
|
}
|
|
} else {
|
|
switch(cur_ptr->linktype) {
|
|
case HW_BACKGROUND_LINK:
|
|
if(NULL != cur_ptr->destdocname) {
|
|
snprintf(istr, BUFFERLEN, " background='%s/%s'", scriptname[HW_BACKGROUND_LINK], cur_ptr->destdocname);
|
|
} else
|
|
istr[0] = '\0';
|
|
break;
|
|
case HW_INTAG_LINK:
|
|
if(cur_ptr->fragment)
|
|
snprintf(istr, BUFFERLEN, " %s='#%s'", cur_ptr->tagattr, cur_ptr->fragment);
|
|
else
|
|
snprintf(istr, BUFFERLEN, " %s='%s/%s'", cur_ptr->tagattr, scriptname[HW_INTAG_LINK], 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)
|
|
/* snprintf(istr, BUFFERLEN, " CODEBASE='%s%s' CODE='%s'", scriptname == NULL ? "" : scriptname, cur_ptr->codebase, cur_ptr->code); */
|
|
snprintf(istr, BUFFERLEN, " CODEBASE='%s%s' CODE='%s'", scriptname[HW_APPLET_LINK], cur_ptr->codebase, cur_ptr->code);
|
|
else
|
|
snprintf(istr, BUFFERLEN, " CODEBASE='/' CODE='%s'", cur_ptr->code);
|
|
break;
|
|
default:
|
|
newtext = fnInsStr(newtext, cur_ptr->end+offset, "</A>");
|
|
|
|
if(cur_ptr->nameanchor)
|
|
snprintf(istr, BUFFERLEN, "<A HREF='%s/%s#%s'", scriptname[HW_DEFAULT_LINK], cur_ptr->destdocname, cur_ptr->nameanchor);
|
|
else if(cur_ptr->fragment)
|
|
snprintf(istr, BUFFERLEN, "<A HREF=\"%s/%s#%s\"", scriptname[HW_DEFAULT_LINK], cur_ptr->destdocname, cur_ptr->fragment);
|
|
else
|
|
snprintf(istr, BUFFERLEN, "<A HREF='%s/%s'", scriptname[HW_DEFAULT_LINK], cur_ptr->destdocname);
|
|
|
|
if(cur_ptr->htmlattr) {
|
|
strncat(istr, " ", BUFFERLEN - 1 - strlen(istr));
|
|
strncat(istr, cur_ptr->htmlattr, BUFFERLEN - 1 - strlen(istr));
|
|
}
|
|
strncat(istr, ">", BUFFERLEN - 1 - strlen(istr));
|
|
}
|
|
}
|
|
} 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)
|
|
snprintf(istr, BUFFERLEN, "<A NAME='%s'>", cur_ptr->keyword);
|
|
else if(cur_ptr->nameanchor)
|
|
snprintf(istr, BUFFERLEN, "<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;
|
|
#ifdef newlist
|
|
ptr = (ANCHOR **) zend_llist_get_prev(pAnchorList);
|
|
if(ptr)
|
|
cur_ptr = *ptr;
|
|
#else
|
|
cur_ptr = (ANCHOR *) dlst_prev(cur_ptr);
|
|
#endif
|
|
}
|
|
snprintf(istr, BUFFERLEN, "<BODY %s>", bgstr);
|
|
*bodytag = estrdup(istr);
|
|
if(scriptname != urlprefix) efree(scriptname);
|
|
return(newtext);
|
|
}
|
|
#undef BUFFERLEN
|
|
|
|
/***********************************************************************
|
|
* 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)) == SOCK_ERR)
|
|
{
|
|
return(-1);
|
|
}
|
|
|
|
/*
|
|
** Make sure that address may be reused
|
|
*/
|
|
#if defined(SUN) || defined(PHP_WIN32)
|
|
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
|
|
*
|
|
*====================================================================*/
|
|
#ifdef PHP_WIN32
|
|
#include <time.h>
|
|
#else
|
|
#include <sys/fcntl.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
#endif
|
|
#include <errno.h>
|
|
#include <signal.h>
|
|
|
|
#ifndef PHP_WIN32
|
|
static sigset_t newmask, oldmask, zeromask;
|
|
#endif
|
|
|
|
static int set_noblock(int fd)
|
|
{
|
|
#ifdef PHP_WIN32
|
|
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=0;
|
|
char *bptr;
|
|
int error=0;
|
|
#if defined(SYSV) || defined(PHP_WIN32)
|
|
int width = 20;
|
|
#else
|
|
int width = getdtablesize();
|
|
#endif
|
|
fd_set writefds;
|
|
struct timeval select_timeout;
|
|
|
|
select_timeout.tv_sec = timeout;
|
|
#ifdef PHP_WIN32
|
|
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;
|
|
}
|
|
}
|
|
#ifndef PHP_WIN32
|
|
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=0;
|
|
char *bptr;
|
|
int error=0;
|
|
|
|
#if defined(SYSV) || defined(PHP_WIN32)
|
|
int width = 20;
|
|
#else
|
|
int width = getdtablesize();
|
|
#endif
|
|
fd_set readfds;
|
|
struct timeval select_timeout;
|
|
|
|
select_timeout.tv_sec = timeout;
|
|
#ifdef PHP_WIN32
|
|
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;
|
|
}
|
|
}
|
|
|
|
#ifndef PHP_WIN32
|
|
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 ( NULL == server_name )
|
|
return(-1);
|
|
|
|
if ( (hp = gethostbyname(server_name)) == NULL ) {
|
|
return(-2);
|
|
}
|
|
|
|
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); */
|
|
server_addr.sin_addr = *(struct in_addr *) hp->h_addr;
|
|
|
|
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == SOCK_ERR ) {
|
|
return(-3);
|
|
}
|
|
|
|
#if defined(SUN) || defined(PHP_WIN32)
|
|
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) {
|
|
HWSOCK_FCLOSE(sockfd);
|
|
return(-4);
|
|
}
|
|
|
|
#ifndef PHP_WIN32
|
|
if ( (sock_flags = fcntl(sockfd, F_GETFL, 0)) == -1 )
|
|
#endif
|
|
|
|
if ( set_nonblocking(sockfd) == -1 ) {
|
|
HWSOCK_FCLOSE(sockfd);
|
|
return(-5);
|
|
}
|
|
|
|
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) < HW_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)
|
|
{
|
|
#ifdef PHP_WIN32
|
|
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)
|
|
{
|
|
#ifdef PHP_WIN32
|
|
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(len);
|
|
}
|
|
|
|
|
|
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);
|
|
php_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);
|
|
php_sleep(1);
|
|
}
|
|
else return(-1);
|
|
}
|
|
else {
|
|
size -= len;
|
|
buf += len;
|
|
try = 0;
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
hg_msg *recv_hg_msg_head(int sockfd)
|
|
{
|
|
hg_msg *msg;
|
|
|
|
if ( (msg = (hg_msg *)emalloc(sizeof(hg_msg))) == NULL ) {
|
|
lowerror = LE_MALLOC;
|
|
return(NULL);
|
|
}
|
|
|
|
if ( hg_read_exact(sockfd, (char *)&(msg->length), 4) == -1 ) {
|
|
efree(msg);
|
|
return(NULL);
|
|
}
|
|
|
|
if ( hg_read_exact(sockfd, (char *)&(msg->version_msgid), 4) == -1 ) {
|
|
efree(msg);
|
|
return(NULL);
|
|
}
|
|
|
|
if ( hg_read_exact(sockfd, (char *)&(msg->msg_type), 4) == -1 ) {
|
|
efree(msg);
|
|
return(NULL);
|
|
}
|
|
|
|
#ifdef HW_DEBUG
|
|
php_printf("<B> Recv msg: </B>type = %d -- id = %d<BR>\n", msg->msg_type, msg->version_msgid);
|
|
#endif
|
|
return(msg);
|
|
}
|
|
|
|
|
|
hg_msg *recv_hg_msg(int sockfd)
|
|
{
|
|
hg_msg *msg;
|
|
|
|
if ( (msg = (hg_msg *)emalloc(sizeof(hg_msg))) == NULL ) {
|
|
/* php_printf("recv_hg_msg"); */
|
|
lowerror = LE_MALLOC;
|
|
return(NULL);
|
|
}
|
|
|
|
if ( hg_read_exact(sockfd, (char *)&(msg->length), 4) == -1 ) {
|
|
/* php_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 ) {
|
|
/* php_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 ) {
|
|
/* php_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 ) {
|
|
/* php_printf("recv_hg_msg"); */
|
|
lowerror = LE_MALLOC;
|
|
efree(msg);
|
|
return(NULL);
|
|
}
|
|
if ( hg_read_exact(sockfd, msg->buf, msg->length-HEADER_LENGTH) == -1 ) {
|
|
/* php_printf("recv_hg_msg: hg_read (4) returned -1\n"); */
|
|
efree(msg->buf);
|
|
efree(msg);
|
|
return(NULL);
|
|
}
|
|
}
|
|
else
|
|
msg->buf = NULL;
|
|
|
|
#ifdef HW_DEBUG
|
|
php_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 ) {
|
|
/* php_printf("recv_ready: recv_hg_msg returned NULL\n"); */
|
|
return(NULL);
|
|
}
|
|
if ( ready_msg->msg_type != READY_MESSAGE ) {
|
|
/* php_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 ) {
|
|
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);
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
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));
|
|
}
|
|
|
|
int send_groupchangeobject(int sockfd, hw_objectID objectID, char *modification)
|
|
{
|
|
hw_objectID *childIDs;
|
|
int count, i, error;
|
|
|
|
if(0 == (error = send_lock(sockfd, objectID))) {
|
|
send_changeobject(sockfd, objectID, modification);
|
|
send_unlock(sockfd, objectID);
|
|
}/* else
|
|
fprintf(stderr, "Could not lock 0x%X (error = %d)\n", objectID, error); */
|
|
|
|
if(0 == send_children(sockfd, objectID, &childIDs, &count)) {
|
|
/* fprintf(stderr, "Changing Children of 0x%X\n", objectID); */
|
|
for(i=0; i<count; i++)
|
|
if(0 > send_groupchangeobject(sockfd, childIDs[i], modification))
|
|
/* fprintf(stderr, "Cannot change 0x%X\n", objectID) */;
|
|
if(childIDs)
|
|
efree(childIDs);
|
|
}/* else
|
|
fprintf(stderr, "No Children of 0x%X\n", objectID); */
|
|
return(0);
|
|
}
|
|
|
|
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 ) {
|
|
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_lock(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++, GETANDLOCK_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);
|
|
}
|
|
|
|
error = *((int *) retmsg->buf);
|
|
|
|
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;
|
|
int length;
|
|
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);
|
|
return 0;
|
|
}
|
|
|
|
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;
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
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;
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
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, char *urlprefix)
|
|
{
|
|
hg_msg msg, *retmsg;
|
|
int length, *ptr, ancount, error;
|
|
char *tmp, *attributes, *documenttype;
|
|
char **anchors;
|
|
int i;
|
|
|
|
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->buf);
|
|
efree(retmsg);
|
|
} else {
|
|
error = *ptr;
|
|
attributes = NULL;
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
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->buf);
|
|
efree(retmsg);
|
|
lowerror = LE_MALLOC;
|
|
return(-1);
|
|
}
|
|
} else {
|
|
error = *ptr;
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
*text = NULL;
|
|
return(error);
|
|
}
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
|
|
if((documenttype != NULL) && (strcmp(documenttype, "Image") != 0)) {
|
|
if(send_getanchorsobj(sockfd, objectID, &anchors, &ancount) == 0) {
|
|
char **destrec, **reldestrec;
|
|
#ifdef newlist
|
|
zend_llist *pAnchorList;
|
|
#else
|
|
DLIST *pAnchorList;
|
|
#endif
|
|
|
|
/* Get dest as relative and absolut path */
|
|
send_getdestforanchorsobj(sockfd, anchors, &destrec, ancount);
|
|
send_getreldestforanchorsobj(sockfd, anchors, &reldestrec, ancount, rootid, objectID);
|
|
pAnchorList = fnCreateAnchorList(objectID, 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 = NULL;
|
|
char **prefixarray;
|
|
|
|
prefixarray = emalloc(5*sizeof(char *));
|
|
for(i=0; i<5; i++)
|
|
prefixarray[i] = urlprefix;
|
|
|
|
newtext = fnInsAnchorsIntoText(*text, pAnchorList, &body, prefixarray);
|
|
|
|
efree(prefixarray);
|
|
#ifdef newlist
|
|
zend_llist_destroy(pAnchorList);
|
|
efree(pAnchorList);
|
|
#else
|
|
dlst_kill(pAnchorList, fnDeleteAnchor);
|
|
#endif
|
|
*bodytag = strdup(body);
|
|
if(body) efree(body);
|
|
*text = newtext;
|
|
*count = strlen(newtext);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(documenttype) efree(documenttype);
|
|
return(0);
|
|
}
|
|
|
|
send_insertanchors(char **text, int *count, char **anchors, char **destrec, int ancount, char **urlprefix, char **bodytag) {
|
|
char **reldestrec = NULL;
|
|
int mode = 0;
|
|
hw_objectID objectID = 0;
|
|
#ifdef newlist
|
|
zend_llist *pAnchorList = NULL;
|
|
#else
|
|
DLIST *pAnchorList = NULL;
|
|
#endif
|
|
pAnchorList = fnCreateAnchorList(objectID, 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 = NULL;
|
|
|
|
newtext = fnInsAnchorsIntoText(*text, pAnchorList, &body, urlprefix);
|
|
|
|
#ifdef newlist
|
|
zend_llist_destroy(pAnchorList);
|
|
efree(pAnchorList);
|
|
#else
|
|
dlst_kill(pAnchorList, fnDeleteAnchor);
|
|
#endif
|
|
*bodytag = strdup(body);
|
|
if(body) efree(body);
|
|
fprintf(stderr, "bodytag = %s\n", *bodytag);
|
|
*text = newtext;
|
|
*count = strlen(newtext);
|
|
}
|
|
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(-2);
|
|
|
|
path = fnAttributeValue(objattr, "Path");
|
|
if(path == NULL)
|
|
return(-3);
|
|
|
|
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(-4);
|
|
}
|
|
|
|
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(-5);
|
|
}
|
|
|
|
efree(msg.buf);
|
|
retmsg = recv_hg_msg(sockfd);
|
|
if (retmsg == NULL) {
|
|
*text = '\0';
|
|
return(-6);
|
|
}
|
|
|
|
ptr = (int *) retmsg->buf;
|
|
error = *ptr;
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
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->buf);
|
|
efree(retmsg);
|
|
} else {
|
|
error = *ptr;
|
|
attributes = NULL;
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
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->buf);
|
|
efree(retmsg);
|
|
lowerror = LE_MALLOC;
|
|
return(-1);
|
|
}
|
|
} else {
|
|
error = *ptr + 1024; /* move errors to >2024 */
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
*text = NULL;
|
|
return(error);
|
|
}
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
|
|
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 ) {
|
|
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->buf);
|
|
efree(retmsg);
|
|
} else {
|
|
error = *ptr;
|
|
attributes = NULL;
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
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 ) {
|
|
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->buf);
|
|
efree(retmsg);
|
|
lowerror = LE_MALLOC;
|
|
return(-1);
|
|
}
|
|
} else {
|
|
error = *ptr + 1024; /* move errors to >2024 */
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
*text = NULL;
|
|
return(error);
|
|
}
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
|
|
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->buf);
|
|
efree(retmsg);
|
|
} else {
|
|
error = *ptr;
|
|
attributes = NULL;
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
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->buf);
|
|
efree(retmsg);
|
|
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->buf);
|
|
efree(retmsg);
|
|
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);
|
|
}
|
|
|
|
error = *((int *) retmsg->buf);
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
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 ) {
|
|
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 */
|
|
#ifdef hw_less_server_stress
|
|
if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) {
|
|
efree(childIDs);
|
|
return -2;
|
|
}
|
|
efree(childIDs);
|
|
#else
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
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 */
|
|
#ifdef hw_less_server_stress
|
|
if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) {
|
|
efree(childIDs);
|
|
return -2;
|
|
}
|
|
efree(childIDs);
|
|
#else
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
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 */
|
|
#ifdef hw_less_server_stress
|
|
if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) {
|
|
efree(childIDs);
|
|
return -2;
|
|
}
|
|
efree(childIDs);
|
|
#else
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
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 */
|
|
#ifdef hw_less_server_stress
|
|
if(0 != send_objectbyidquery(sockfd, anchorIDs, count, NULL, childrec)) {
|
|
efree(anchorIDs);
|
|
return -2;
|
|
}
|
|
efree(anchorIDs);
|
|
#else
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
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.
|
|
*/
|
|
if((NULL != anchorrec[i]) && (NULL != (str = fnAttributeValue(anchorrec[i], "Dest")))) {
|
|
sscanf(str, "0x%x", &objectID);
|
|
efree(str);
|
|
|
|
/* Using send_docbyanchorobj() makes sense because the Destination can
|
|
be both, an anchor or a document. If it is a document you get the
|
|
objectrecord of that document. If it is an anchor the function
|
|
graps the document which belongs to the anchor
|
|
and you get also the objectrecord of that document.
|
|
*/
|
|
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);
|
|
|
|
/* See note in send_getdestforanchorsobj() at same position in source code */
|
|
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, *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];
|
|
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);
|
|
efree(reldestptr[i]);
|
|
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;
|
|
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];
|
|
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_objectbyidquery(int sockfd, hw_objectID *IDs, int *count, char *query, char ***objrecs)
|
|
{
|
|
hg_msg msg, *retmsg;
|
|
int length, error;
|
|
char *tmp, *str;
|
|
int *ptr, i, *ptr1;
|
|
int *offsets, *childIDs;
|
|
char **childrec;
|
|
|
|
if(*count <= 0) {
|
|
*objrecs = emalloc(0);
|
|
return(0);
|
|
}
|
|
length = HEADER_LENGTH + sizeof(int) + sizeof(int) + *count * sizeof(hw_objectID);
|
|
if(query)
|
|
length = length + strlen(query) + 1;
|
|
|
|
build_msg_header(&msg, length, msgid++, OBJECTBYIDQUERY_MESSAGE);
|
|
|
|
if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
|
|
lowerror = LE_MALLOC;
|
|
return(-1);
|
|
}
|
|
|
|
tmp = build_msg_int(msg.buf, 1);
|
|
tmp = build_msg_int(tmp, *count);
|
|
for(i=0; i<*count; i++)
|
|
tmp = build_msg_int(tmp, IDs[i]);
|
|
if(query)
|
|
tmp = build_msg_str(tmp, query);
|
|
|
|
if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
|
|
efree(msg.buf);
|
|
return(-1);
|
|
}
|
|
efree(msg.buf);
|
|
|
|
#ifdef hw_optimize
|
|
{
|
|
int hg_error;
|
|
int c, allc;
|
|
|
|
allc = 0;
|
|
retmsg = recv_hg_msg_head(sockfd);
|
|
if ( retmsg == NULL )
|
|
return(-1);
|
|
|
|
/* read error field */
|
|
if ( (c = hg_read_exact(sockfd, (char *) &hg_error, 4)) == -1 ) {
|
|
if(retmsg) efree(retmsg);
|
|
return(-2);
|
|
}
|
|
allc += c;
|
|
|
|
if(hg_error) {
|
|
if(retmsg) efree(retmsg);
|
|
return(-3);
|
|
}
|
|
|
|
/* read count field */
|
|
if ( (c = hg_read_exact(sockfd, (char *) count, 4)) == -1 ) {
|
|
if(retmsg) efree(retmsg);
|
|
return(-2);
|
|
}
|
|
allc += c;
|
|
|
|
if(NULL != (childIDs = emalloc(*count * sizeof(hw_objectID)))) {
|
|
if((c = hg_read_exact(sockfd, (char *) childIDs, *count * sizeof(hw_objectID))) == -1) {
|
|
efree(childIDs);
|
|
if(retmsg) efree(retmsg);
|
|
return(-3);
|
|
}
|
|
} else {
|
|
efree(retmsg);
|
|
lowerror = LE_MALLOC;
|
|
return(-4);
|
|
}
|
|
allc += c;
|
|
|
|
if(NULL != (offsets = emalloc(*count * sizeof(int)))) {
|
|
if((c = hg_read_exact(sockfd, (char *) offsets, *count * sizeof(int))) == -1) {
|
|
efree(childIDs);
|
|
efree(offsets);
|
|
if(retmsg) efree(retmsg);
|
|
return(-5);
|
|
}
|
|
} else {
|
|
efree(retmsg);
|
|
efree(childIDs);
|
|
lowerror = LE_MALLOC;
|
|
return(-6);
|
|
}
|
|
allc += c;
|
|
|
|
str = (char *)ptr;
|
|
if(NULL == (childrec = (char **) emalloc(*count * sizeof(hw_objrec *)))) {
|
|
efree(offsets);
|
|
efree(childIDs);
|
|
efree(retmsg);
|
|
lowerror = LE_MALLOC;
|
|
return(-1);
|
|
} else {
|
|
for(i=0; i<*count; i++) {
|
|
char *ptr;
|
|
childrec[i] = emalloc(offsets[i] + 1);
|
|
ptr = childrec[i];
|
|
c = hg_read_exact(sockfd, (char *) ptr, offsets[i]);
|
|
ptr[c] = '\0';
|
|
allc += c;
|
|
}
|
|
/* Reading the trailing '\0' */
|
|
c = hg_read_exact(sockfd, (char *) &hg_error, 1);
|
|
*objrecs = childrec;
|
|
}
|
|
}
|
|
#else
|
|
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) {
|
|
error = *((int *) retmsg->buf);
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
return error;
|
|
}
|
|
|
|
*count = *ptr++;
|
|
if(NULL != (childIDs = emalloc(*count * sizeof(hw_objectID)))) {
|
|
ptr1 = childIDs;
|
|
for(i=0; i<*count; ptr++, i++)
|
|
ptr1[i] = *ptr;
|
|
if(NULL != (offsets = emalloc(*count * sizeof(int)))) {
|
|
ptr1 = offsets;
|
|
for(i=0; i<*count; ptr++, i++)
|
|
ptr1[i] = *ptr;
|
|
} else {
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
efree(childIDs);
|
|
lowerror = LE_MALLOC;
|
|
return(-1);
|
|
}
|
|
} else {
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
lowerror = LE_MALLOC;
|
|
return(-1);
|
|
}
|
|
|
|
str = (char *)ptr;
|
|
if(NULL == (childrec = (char **) emalloc(*count * sizeof(hw_objrec *)))) {
|
|
efree(offsets);
|
|
efree(childIDs);
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
lowerror = LE_MALLOC;
|
|
return(-1);
|
|
} else {
|
|
for(i=0; i<*count; i++) {
|
|
char *ptr;
|
|
childrec[i] = emalloc(offsets[i] + 1);
|
|
ptr = childrec[i];
|
|
memcpy(ptr, str, offsets[i]);
|
|
ptr[offsets[i]] = '\0';
|
|
str += offsets[i];
|
|
}
|
|
*objrecs = childrec;
|
|
}
|
|
|
|
efree(retmsg->buf);
|
|
#endif
|
|
|
|
efree(retmsg);
|
|
efree(childIDs);
|
|
efree(offsets);
|
|
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(-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 -4;
|
|
}
|
|
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(-5);
|
|
}
|
|
} else {
|
|
error = *((int *) retmsg->buf);
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
return error;
|
|
}
|
|
|
|
/* Now get for each child collection the object record */
|
|
#ifdef hw_less_server_stress
|
|
if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) {
|
|
efree(childIDs);
|
|
return -2;
|
|
}
|
|
efree(childIDs);
|
|
#else
|
|
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(-6);
|
|
}
|
|
|
|
tmp = build_msg_int(msg.buf, childIDs[i]);
|
|
|
|
if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
|
|
efree(msg.buf);
|
|
efree(childIDs);
|
|
return(-7);
|
|
}
|
|
|
|
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(-8);
|
|
} 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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
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 */
|
|
#ifdef hw_less_server_stress
|
|
if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) {
|
|
if(childIDs) efree(childIDs);
|
|
return -2;
|
|
}
|
|
if(childIDs) efree(childIDs);
|
|
#else
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
return(0);
|
|
}
|
|
|
|
int send_getobjbyftquery(int sockfd, char *query, int maxhits, hw_objectID **childIDs, float **weights, int *count)
|
|
{
|
|
hg_msg msg, *retmsg;
|
|
int length, error;
|
|
char *tmp;
|
|
int *ptr, i, *ptr1;
|
|
float *ptr2;
|
|
|
|
length = HEADER_LENGTH + strlen(query) + 1;
|
|
|
|
build_msg_header(&msg, length, msgid++, GETOBJBYFTQUERY_MESSAGE);
|
|
|
|
if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
|
|
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;
|
|
if(NULL != (*weights = emalloc(*count * sizeof(float)))) {
|
|
ptr2 = *weights;
|
|
for(i=0; i<*count; i++) {
|
|
ptr1[i] = *ptr++;
|
|
ptr2[i] = (float) *ptr++;
|
|
}
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
} else {
|
|
efree(*childIDs);
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
lowerror = LE_MALLOC;
|
|
return(-1);
|
|
}
|
|
} 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_getobjbyftqueryobj(int sockfd, char *query, int maxhits, char ***childrec, float **weights, int *count)
|
|
{
|
|
hg_msg msg, *retmsg;
|
|
int length, i, error;
|
|
char *tmp;
|
|
int *childIDs = NULL;
|
|
char **objptr;
|
|
int *ptr, *ptr1;
|
|
float *ptr2;
|
|
|
|
length = HEADER_LENGTH + strlen(query) + 1;
|
|
|
|
build_msg_header(&msg, length, msgid++, GETOBJBYFTQUERY_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(-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 -4;
|
|
}
|
|
if(*ptr++ == 0) {
|
|
*count = (*ptr < maxhits) ? *ptr : maxhits;
|
|
ptr++;
|
|
if(NULL != (childIDs = emalloc(*count * sizeof(hw_objectID)))) {
|
|
ptr1 = childIDs;
|
|
if(NULL != (*weights = emalloc(*count * sizeof(float)))) {
|
|
ptr2 = *weights;
|
|
for(i=0; i<*count; i++) {
|
|
ptr1[i] = *ptr++;
|
|
ptr2[i] = (float) *ptr++;
|
|
}
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
} else {
|
|
efree(childIDs);
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
lowerror = LE_MALLOC;
|
|
return(-5);
|
|
}
|
|
} else {
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
lowerror = LE_MALLOC;
|
|
return(-5);
|
|
}
|
|
} else {
|
|
error = *((int *) retmsg->buf);
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
return error;
|
|
}
|
|
|
|
/* Now get for each child collection the object record */
|
|
#ifdef hw_less_server_stress
|
|
if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) {
|
|
efree(childIDs);
|
|
efree(*weights);
|
|
return -2;
|
|
}
|
|
efree(childIDs);
|
|
#else
|
|
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);
|
|
efree(*weights);
|
|
lowerror = LE_MALLOC;
|
|
return(-6);
|
|
}
|
|
|
|
tmp = build_msg_int(msg.buf, childIDs[i]);
|
|
|
|
if ( send_hg_msg(sockfd, &msg, length) == -1 ) {
|
|
efree(msg.buf);
|
|
efree(childIDs);
|
|
efree(*weights);
|
|
return(-7);
|
|
}
|
|
|
|
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(-8);
|
|
} 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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
return(0);
|
|
}
|
|
|
|
int send_getobjbyftquerycoll(int sockfd, hw_objectID collID, char *query, int maxhits, hw_objectID **childIDs, float **weights, int *count)
|
|
{
|
|
hg_msg msg, *retmsg;
|
|
int length, error;
|
|
char *tmp;
|
|
int *ptr, i, *ptr1;
|
|
float *ptr2;
|
|
|
|
length = HEADER_LENGTH + strlen(query) + 1 + sizeof(int) + sizeof(collID);
|
|
|
|
build_msg_header(&msg, length, msgid++, GETOBJBYFTQUERYCOLL_MESSAGE);
|
|
|
|
if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
|
|
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;
|
|
if(NULL != (*weights = emalloc(*count * sizeof(float)))) {
|
|
ptr2 = *weights;
|
|
for(i=0; i<*count; i++) {
|
|
ptr1[i] = *ptr++;
|
|
ptr2[i] = (float) *ptr++;
|
|
}
|
|
} else {
|
|
efree(*childIDs);
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
lowerror = LE_MALLOC;
|
|
return(-1);
|
|
}
|
|
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_getobjbyftquerycollobj(int sockfd, hw_objectID collID, char *query, int maxhits, char ***childrec, float **weights, int *count)
|
|
{
|
|
hg_msg msg, *retmsg;
|
|
int length, i, error;
|
|
char *tmp;
|
|
hw_objectID *childIDs = NULL;
|
|
char **objptr;
|
|
int *ptr, *ptr1;
|
|
float *ptr2;
|
|
|
|
length = HEADER_LENGTH + strlen(query) + 1 + sizeof(int) + sizeof(hw_objectID);
|
|
|
|
build_msg_header(&msg, length, msgid++, GETOBJBYFTQUERYCOLL_MESSAGE);
|
|
|
|
if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
|
|
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;
|
|
if(NULL != (*weights = emalloc(*count * sizeof(float)))) {
|
|
ptr2 = *weights;
|
|
for(i=0; i<*count; i++) {
|
|
ptr1[i] = *ptr++;
|
|
ptr2[i] = (float) *ptr++;
|
|
}
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
} else {
|
|
efree(childIDs);
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
lowerror = LE_MALLOC;
|
|
return(-1);
|
|
}
|
|
} 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 */
|
|
#ifdef hw_less_server_stress
|
|
if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) {
|
|
if(childIDs) efree(childIDs);
|
|
if(*weights) efree(weights);
|
|
return -2;
|
|
}
|
|
if(childIDs) efree(childIDs);
|
|
#else
|
|
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);
|
|
efree(*weights);
|
|
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);
|
|
efree(*weights);
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
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 */
|
|
#ifdef hw_less_server_stress
|
|
if(0 != send_objectbyidquery(sockfd, childIDs, count, NULL, childrec)) {
|
|
efree(childIDs);
|
|
return -2;
|
|
}
|
|
efree(childIDs);
|
|
#else
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
return(0);
|
|
}
|
|
|
|
int send_pipedocument(int sockfd, char *host, hw_objectID objectID, int mode, int rootid, char **objattr, char **bodytag, char **text, int *count, char **urlprefix)
|
|
{
|
|
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) {
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-2);
|
|
}
|
|
} else {
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-2);
|
|
}
|
|
|
|
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:
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-3);
|
|
break;
|
|
}
|
|
|
|
/* Bottom half of send_getobject */
|
|
if(0 > bh_send_getobject(sockfd, objectID)) {
|
|
HWSOCK_FCLOSE(fd);
|
|
return -4;
|
|
}
|
|
|
|
/* Upper half of send_getobject */
|
|
if(0 > (error = uh_send_getobject(sockfd, &attributes))) {
|
|
HWSOCK_FCLOSE(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 ) {
|
|
if(attributes) efree(attributes);
|
|
lowerror = LE_MALLOC;
|
|
return(-5);
|
|
}
|
|
|
|
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);
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-6);
|
|
}
|
|
efree(msg.buf);
|
|
|
|
/* Just check if the command was understood */
|
|
retmsg = recv_hg_msg(sockfd);
|
|
if ( retmsg == NULL ) {
|
|
if(attributes) efree(attributes);
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-7);
|
|
}
|
|
|
|
ptr = (int *) retmsg->buf;
|
|
if((ptr == NULL) || (*ptr != 0)) {
|
|
error = *ptr;
|
|
if(retmsg->buf) efree(retmsg->buf);
|
|
efree(retmsg);
|
|
if(attributes) efree(attributes);
|
|
HWSOCK_FCLOSE(fd);
|
|
return(error);
|
|
}
|
|
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
|
|
/* 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) {
|
|
/* php_printf("client: can't open data connection to server\n"); */
|
|
if(attributes) efree(attributes);
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-8);
|
|
} else {
|
|
HWSOCK_FCLOSE(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 */
|
|
HWSOCK_FCLOSE(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;
|
|
#ifdef newlist
|
|
zend_llist *pAnchorList = NULL;
|
|
#else
|
|
DLIST *pAnchorList = NULL;
|
|
#endif
|
|
|
|
/* Get dest as relative and absolut path */
|
|
send_getdestforanchorsobj(sockfd, anchors, &destrec, ancount);
|
|
send_getreldestforanchorsobj(sockfd, anchors, &reldestrec, ancount, rootid, objectID);
|
|
pAnchorList = fnCreateAnchorList(objectID, 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 = NULL;
|
|
|
|
newtext = fnInsAnchorsIntoText(*text, pAnchorList, &body, urlprefix);
|
|
#ifdef newlist
|
|
zend_llist_destroy(pAnchorList);
|
|
efree(pAnchorList);
|
|
#else
|
|
dlst_kill(pAnchorList, fnDeleteAnchor);
|
|
#endif
|
|
*bodytag = strdup(body);
|
|
if(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) {
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-1);
|
|
}
|
|
} else {
|
|
HWSOCK_FCLOSE(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:
|
|
/* php_printf(stderr, "unknown address type\n"); */
|
|
break;
|
|
}
|
|
|
|
/* Bottom half of send_getobject */
|
|
if(0 > bh_send_getobject(sockfd, objectID)) {
|
|
HWSOCK_FCLOSE(fd);
|
|
return -1;
|
|
}
|
|
|
|
/* Upper half of send_getobject */
|
|
if(0 > (error = uh_send_getobject(sockfd, &attributes))) {
|
|
HWSOCK_FCLOSE(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);
|
|
HWSOCK_FCLOSE(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);
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-1);
|
|
}
|
|
|
|
ptr = (int *) retmsg->buf;
|
|
if((ptr == NULL) || (*ptr != 0)) {
|
|
if(retmsg->buf) efree(retmsg->buf);
|
|
efree(retmsg);
|
|
if(attributes) efree(attributes);
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-1);
|
|
}
|
|
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
|
|
/* 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);
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-1);
|
|
} else {
|
|
HWSOCK_FCLOSE(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 */
|
|
HWSOCK_FCLOSE(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, hw_objectID *objectID)
|
|
{
|
|
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, 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(-2);
|
|
}
|
|
|
|
efree(msg.buf);
|
|
retmsg = recv_hg_msg(sockfd);
|
|
if ( retmsg == NULL ) {
|
|
return(-3);
|
|
}
|
|
|
|
ptr = (int *) retmsg->buf;
|
|
if(0 == (error = *ptr)) {
|
|
ptr++;
|
|
*objectID = *ptr;
|
|
} else {
|
|
if(retmsg->buf) efree(retmsg->buf);
|
|
efree(retmsg);
|
|
return(error);
|
|
}
|
|
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
|
|
/*
|
|
** Get information about host
|
|
*/
|
|
if(host) {
|
|
if((hostptr = gethostbyname(host)) == NULL) {
|
|
/* close(fd); fd is not set yet */
|
|
return(-4);
|
|
}
|
|
} else {
|
|
/* close(fd); fd is not set yet */
|
|
return(-5);
|
|
}
|
|
|
|
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(-6);
|
|
}
|
|
|
|
/* 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(-7);
|
|
}
|
|
|
|
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);
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-8);
|
|
}
|
|
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) {
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-9);
|
|
} else {
|
|
HWSOCK_FCLOSE(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)) {
|
|
HWSOCK_FCLOSE(newfd);
|
|
return(-10);
|
|
}
|
|
|
|
/* And now the document */
|
|
if(count != write_to(newfd, text, count, wtimeout)) {
|
|
HWSOCK_FCLOSE(newfd);
|
|
return(-11);
|
|
}
|
|
|
|
/* The data connection has to be close before the return
|
|
msg can be read. The server will not sent it before. */
|
|
HWSOCK_FCLOSE(newfd);
|
|
|
|
/* Just check if the command was understood */
|
|
retmsg = recv_hg_msg(sockfd);
|
|
if ( retmsg == NULL ) {
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-12);
|
|
}
|
|
|
|
ptr = (int *) retmsg->buf;
|
|
if((ptr == NULL) || (*ptr != 0)) {
|
|
if(retmsg->buf) efree(retmsg->buf);
|
|
efree(retmsg);
|
|
HWSOCK_FCLOSE(fd);
|
|
return(-13);
|
|
}
|
|
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
|
|
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"); */
|
|
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_mapid(int sockfd, int servid, hw_objectID id, int *virtid)
|
|
{
|
|
hg_msg msg, *retmsg;
|
|
int length, error;
|
|
char *tmp;
|
|
int *ptr;
|
|
|
|
length = HEADER_LENGTH + 2 * sizeof(hw_objectID);
|
|
|
|
build_msg_header(&msg, length, msgid++, HG_MAPID);
|
|
|
|
if ( (msg.buf = (char *)emalloc(length-HEADER_LENGTH)) == NULL ) {
|
|
lowerror = LE_MALLOC;
|
|
return(-1);
|
|
}
|
|
|
|
tmp = build_msg_int(msg.buf, servid);
|
|
tmp = build_msg_int(tmp, id);
|
|
|
|
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) {
|
|
*virtid = *ptr;
|
|
} else {
|
|
error = *((int *) retmsg->buf);
|
|
efree(retmsg->buf);
|
|
efree(retmsg);
|
|
return error;
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
#define BUFFERLEN 200
|
|
char *get_hw_info(hw_connection *conn) {
|
|
char temp[BUFFERLEN];
|
|
int len;
|
|
struct sockaddr_in serv_addr;
|
|
|
|
len = sizeof (serv_addr);
|
|
if(getsockname(conn->socket, (struct sockaddr *)&serv_addr, &len) < 0)
|
|
return(NULL);
|
|
|
|
snprintf(temp, BUFFERLEN, "%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));
|
|
}
|
|
#undef BUFFERLEN
|
|
|
|
static int send_hg_msg(int sockfd, hg_msg *msg, int length)
|
|
{
|
|
char *buf, *tmp;
|
|
|
|
#ifdef HW_DEBUG
|
|
php_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);
|
|
}
|
|
|
|
*answer = retmsg->buf;
|
|
efree(retmsg);
|
|
|
|
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
|
|
php_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
|
|
php_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);
|
|
HWSOCK_FCLOSE(sockfd);
|
|
}
|
|
|
|
#endif
|
|
|
|
/*
|
|
* Local variables:
|
|
* tab-width: 4
|
|
* End:
|
|
*/
|
|
|