/* +----------------------------------------------------------------------+ | 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 #include "php.h" #include "php_globals.h" #include "SAPI.h" #if HYPERWAVE #include #include #include #ifdef PHP_WIN32 # include # define EWOULDBLOCK WSAEWOULDBLOCK # define ETIMEDOUT WSAETIMEDOUT # define bcopy memcpy # define bzero(a,b) memset(a,0,b) #else # include # include # include # include # include #endif #include #include #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() * * * * 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 **dest: object records of destinations * * int ancount: number of anchors * * 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]; 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(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[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; /* 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://. 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; if (zend_hash_find(&EG(symbol_table), "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void **) &script_name)==FAILURE) scriptname = NULL; else { convert_to_string_ex(script_name); scriptname = (*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(bgstr, 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 */ /* 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, ""); if(cur_ptr->fragment) snprintf(istr, BUFFERLEN, "link, cur_ptr->fragment); else snprintf(istr, BUFFERLEN, "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(bgstr, BUFFERLEN, " background='%s/%s'", scriptname == NULL ? "" : scriptname, cur_ptr->destdocname); else bgstr[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 == NULL ? "." : scriptname, cur_ptr->destdocname); offset -= 4; /* because there is no closing tag */ /* 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' 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, ""); if(cur_ptr->nameanchor) snprintf(istr, BUFFERLEN, "destdocname, cur_ptr->nameanchor); else if(cur_ptr->fragment) snprintf(istr, BUFFERLEN, "destdocname, cur_ptr->fragment); else snprintf(istr, BUFFERLEN, "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, ""); /* 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, "", cur_ptr->keyword); else if(cur_ptr->nameanchor) snprintf(istr, BUFFERLEN, "", 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 */ 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, "", bgstr); *bodytag = estrdup(istr); 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 #else #include #include #include #endif #include #include #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(" Recv msg: type = %d -- id = %d
\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(" Recv msg: type = %d -- id = %d
\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 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; ibuf; 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; 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 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; newtext = fnInsAnchorsIntoText(*text, pAnchorList, &body, urlprefix); #ifdef newlist zend_llist_destroy(pAnchorList); efree(pAnchorList); #else dlst_kill(pAnchorList, fnDeleteAnchor); #endif *bodytag = strdup(body); efree(body); *text = newtext; *count = strlen(newtext); } } } if(documenttype) efree(documenttype); return(0); } int send_edittext(int sockfd, char *objattr, char *text) { hg_msg msg, *retmsg; int length, *ptr, error; char *tmp, *path, *objid; hw_objectID objectID; objid = fnAttributeValue(objattr, "ObjectID"); if(objid == NULL) return(-1); if(!sscanf(objid, "0x%x", &objectID)) return(-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; ibuf); 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 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 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= 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 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; ibuf; 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_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 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; newtext = fnInsAnchorsIntoText(*text, pAnchorList, &body, urlprefix); #ifdef newlist zend_llist_destroy(pAnchorList); efree(pAnchorList); #else dlst_kill(pAnchorList, fnDeleteAnchor); #endif *bodytag = strdup(body); efree(body); *text = newtext; *count = strlen(newtext); } } } else { *bodytag = NULL; } if(documenttype) efree(documenttype); return(0); } int send_pipecgi(int sockfd, char *host, hw_objectID objectID, char *cgi_env_str, char **objattr, char **text, int *count) { hg_msg msg, *retmsg; int length, len, new_attr_len; char *tmp, header[80], *head_ptr, *sizestr; struct sockaddr_in serv_addr; struct hostent *hostptr; char *hostip = NULL; char *attributes = NULL; char *documenttype, *new_attr; int newfd, fd, port, size, error; int *ptr; if(-1 == (fd = fnCOpenDataCon(sockfd, &port))) { /* not set yet? efree(msg.buf); */ return(-1); } /* ** Get information about host */ if(host) { if((hostptr = gethostbyname(host)) == NULL) { 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("Sending msg: type = %d -- id = %d
\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: %d
\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: %s (%d)
\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: */