📄 hw.c
字号:
} efree(temp); /* Add the title array, if we have one */ if(hasTitle) { zend_hash_update(Z_ARRVAL_PP(return_value), "Title", 6, &title_arr, sizeof(zval *), NULL); } else { efree(title_arr); } if(hasDescription) { /* Add the description array, if we have one */ zend_hash_update(Z_ARRVAL_PP(return_value), "Description", 12, &desc_arr, sizeof(zval *), NULL); } else { efree(desc_arr); } if(hasKeyword) { /* Add the keyword array, if we have one */ zend_hash_update(Z_ARRVAL_PP(return_value), "Keyword", 8, &keyword_arr, sizeof(zval *), NULL); } else { efree(keyword_arr); } if(hasGroup) { /* Add the Group array, if we have one */ zend_hash_update(Z_ARRVAL_PP(return_value), "Group", 6, &group_arr, sizeof(zval *), NULL); } else { efree(group_arr); } /* All other attributes. Make a another copy first */ temp = estrdup(objrec); attrname = php_strtok_r(temp, "\n", &strtok_buf); while(attrname != NULL) { str = attrname; /* We don't want to insert titles, descr., keywords a second time */ if((0 != strncmp(attrname, "Title=", 6)) && (0 != strncmp(attrname, "Description=", 12)) && (0 != strncmp(attrname, "Group=", 6)) && (0 != strncmp(attrname, "Keyword=", 8))) { while((*str != '=') && (*str != '\0')) str++; *str = '\0'; str++; add_assoc_string(*return_value, attrname, str, 1); } attrname = php_strtok_r(NULL, "\n", &strtok_buf); } efree(temp); return(0);}/* }}} */#define BUFFERLEN 1024/* {{{ make_objrec_from_array */static char * make_objrec_from_array(HashTable *lht, char delim) { int i, count, keytype; ulong idx; uint length; char *key, str[BUFFERLEN], *objrec = NULL; zval *keydata, **keydataptr; if(NULL == lht) return NULL; if(0 == (count = zend_hash_num_elements(lht))) return NULL; if(delim == 0) delim = '='; zend_hash_internal_pointer_reset(lht); objrec = malloc(1); *objrec = '\0'; for(i=0; i<count; i++) { keytype = zend_hash_get_current_key_ex(lht, &key, &length, &idx, 0, NULL);/* if(HASH_KEY_IS_STRING == keytype) { */ zend_hash_get_current_data(lht, (void **) &keydataptr); keydata = *keydataptr; switch(Z_TYPE_P(keydata)) { case IS_STRING: if(HASH_KEY_IS_STRING == keytype) snprintf(str, BUFFERLEN, "%s%c%s\n", key, delim, Z_STRVAL_P(keydata)); else if(HASH_KEY_IS_LONG == keytype) snprintf(str, BUFFERLEN, "%ld%c%s\n", idx, delim, Z_STRVAL_P(keydata)); else snprintf(str, BUFFERLEN, "%s\n", Z_STRVAL_P(keydata)); break; case IS_LONG: if(HASH_KEY_IS_STRING == keytype) snprintf(str, BUFFERLEN, "%s%c0x%lX\n", key, delim, Z_LVAL_P(keydata)); else if(HASH_KEY_IS_LONG == keytype) snprintf(str, BUFFERLEN, "%ld%c%s\n", idx, delim, Z_STRVAL_P(keydata)); else snprintf(str, BUFFERLEN, "0x%lX\n", Z_LVAL_P(keydata)); break; case IS_ARRAY: { int i, len, keylen, count; char *strarr, *ptr, *ptr1; count = zend_hash_num_elements(Z_ARRVAL_P(keydata)); if(count > 0) { strarr = make_objrec_from_array(Z_ARRVAL_P(keydata), ':'); len = strlen(strarr) - 1; keylen = strlen(key); if(NULL == (ptr = malloc(len + 1 + count*(keylen+1)))) { free(objrec); return(NULL); } ptr1 = ptr; *ptr1 = '\0'; strcpy(ptr1, key); ptr1 += keylen; *ptr1++ = '='; for(i=0; i<len; i++) { *ptr1++ = strarr[i]; if(strarr[i] == '\n') { strcpy(ptr1, key); ptr1 += keylen; *ptr1++ = '='; }/* else if(strarr[i] == '=') ptr1[-1] = ':'; */ } *ptr1++ = '\n'; *ptr1 = '\0'; strlcpy(str, ptr, sizeof(str)); } break; } } objrec = realloc(objrec, strlen(objrec)+strlen(str)+1); strcat(objrec, str);/* } */ zend_hash_move_forward(lht); } return objrec;}/* }}} */#undef BUFFERLEN/* {{{ make_ints_from_array */static int * make_ints_from_array(HashTable *lht) { int i, count; int *objids = NULL; zval **keydata; if(NULL == lht) return NULL; if(0 == (count = zend_hash_num_elements(lht))) return NULL; zend_hash_internal_pointer_reset(lht); if(NULL == (objids = emalloc(count*sizeof(int)))) return NULL; for(i=0; i<count; i++) { zend_hash_get_current_data(lht, (void **) &keydata); switch(Z_TYPE_PP(keydata)) { case IS_LONG: objids[i] = Z_LVAL_PP(keydata); break; default: objids[i] = 0; } zend_hash_move_forward(lht); } return objids;}/* }}} *//* {{{ make_strs_from_array */static char **make_strs_from_array(HashTable *arrht) { char **carr = NULL; char **ptr; zval *data, **dataptr; zend_hash_internal_pointer_reset(arrht); if(NULL == (carr = emalloc(zend_hash_num_elements(arrht) * sizeof(char *)))) return(NULL); ptr = carr; /* Iterate through hash */ while(zend_hash_get_current_data(arrht, (void **) &dataptr) == SUCCESS) { data = *dataptr; switch(Z_TYPE_P(data)) { case IS_STRING: *ptr = estrdup(Z_STRVAL_P(data));/*fprintf(stderr, "carr[] = %s\n", *ptr); */ break; default: *ptr = NULL; } ptr++; zend_hash_move_forward(arrht); } return(carr);}/* }}} */#define BUFFERLEN 30/* {{{ php_hw_do_connect */static void php_hw_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent){ zval **argv[4]; int argc; int sockfd; int port = 0; char *host = NULL; char *userdata = NULL; char *server_string = NULL; char *username = NULL; char *password = NULL; char *hashed_details; char *str = NULL; char buffer[BUFFERLEN]; int hashed_details_length; hw_connection *ptr; int do_swap; int version = 0; argc = ZEND_NUM_ARGS(); switch(argc) { case 2: case 4: if (zend_get_parameters_array_ex(argc, argv) == FAILURE) { WRONG_PARAM_COUNT; } break; default: WRONG_PARAM_COUNT; } /* Host: */ convert_to_string_ex(argv[0]); host = (char *) estrndup(Z_STRVAL_PP(argv[0]), Z_STRLEN_PP(argv[0])); /* Port: */ convert_to_long_ex(argv[1]); port = Z_LVAL_PP(argv[1]); /* Username and Password */ if(argc > 2) { /* Username */ convert_to_string_ex(argv[2]); username = (char *) estrndup(Z_STRVAL_PP(argv[2]), Z_STRLEN_PP(argv[2])); /* Password */ convert_to_string_ex(argv[3]); password = (char *) estrndup(Z_STRVAL_PP(argv[3]), Z_STRLEN_PP(argv[3])); } /* Create identifier string for connection */ snprintf(buffer, BUFFERLEN, "%d", port); hashed_details_length = strlen(host)+strlen(buffer)+8; if(NULL == (hashed_details = (char *) emalloc(hashed_details_length+1))) { if(host) efree(host); if(password) efree(password); if(username) efree(username); php_error(E_ERROR, "%s(): Could not get memory for connection details", get_active_function_name(TSRMLS_C)); RETURN_FALSE; } sprintf(hashed_details, "hw_%s_%d", host, port); if (persistent) { list_entry *le; /* try to find if we already have this link in our persistent list */ if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) { list_entry new_le; if (HwSG(max_links)!=-1 && HwSG(num_links)>=HwSG(max_links)) { php_error(E_ERROR, "%s(): Too many open links (%ld)", get_active_function_name(TSRMLS_C), HwSG(num_links)); if(host) efree(host); if(username) efree(username); if(password) efree(password); efree(hashed_details); RETURN_FALSE; } if (HwSG(max_persistent!=-1) && HwSG(num_persistent)>=HwSG(max_persistent)) { php_error(E_ERROR, "%s(): Too many open persistent links (%ld)", get_active_function_name(TSRMLS_C), HwSG(num_persistent)); if(host) efree(host); if(username) efree(username); if(password) efree(password); efree(hashed_details); RETURN_FALSE; } if ( (sockfd = open_hg_connection(host, port)) < 0 ) { php_error(E_ERROR, "%s(): Could not open connection to %s, Port: %d (retval=%d, errno=%d)", get_active_function_name(TSRMLS_C), host, port, sockfd, errno); if(host) efree(host); if(username) efree(username); if(password) efree(password); efree(hashed_details); RETURN_FALSE; } if(NULL == (ptr = malloc(sizeof(hw_connection)))) { php_error(E_ERROR, "%s(): Could not get memory for connection structure", get_active_function_name(TSRMLS_C)); if(host) efree(host); if(username) efree(username); if(password) efree(password); efree(hashed_details); RETURN_FALSE; } if(0 != (ptr->lasterror = initialize_hg_connection(sockfd, &do_swap, &version, &userdata, &server_string, username, password))) { php_error(E_ERROR, "%s(): Could not initalize hyperwave connection", get_active_function_name(TSRMLS_C)); if(host) efree(host); if(username) efree(username); if(password) efree(password); if(userdata) efree(userdata); if(server_string) free(server_string); efree(hashed_details); RETURN_FALSE; } if(username) efree(username); if(password) efree(password); ptr->version = version; ptr->server_string = server_string; ptr->socket = sockfd; ptr->swap_on = do_swap; ptr->linkroot = 0; ptr->hostname = strdup(host); ptr->username = strdup("anonymous"); new_le.ptr = (void *) ptr; Z_TYPE(new_le) = le_psocketp; if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(list_entry), NULL)==FAILURE) { php_error(E_ERROR, "%s(): Could not hash table with connection details", get_active_function_name(TSRMLS_C)); if(host) efree(host); if(username) efree(username); if(password) efree(password); if(server_string) free(server_string); efree(hashed_details); RETURN_FALSE; } HwSG(num_links)++; HwSG(num_persistent)++; } else { /*php_printf("Found already open connection\n"); */ if (Z_TYPE_P(le) != le_psocketp) { RETURN_FALSE; } ptr = le->ptr; } Z_LVAL_P(return_value) = zend_list_insert(ptr, le_psocketp); Z_TYPE_P(return_value) = IS_RESOURCE; } else { list_entry *index_ptr, new_index_ptr; /* first we check the hash for the hashed_details key. if it exists, * it should point us to the right offset where the actual hyperwave link sits. * if it doesn't, open a new hyperwave link, add it to the resource list, * and add a pointer to it with hashed_details as the key. */ if (zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length+1, (void **) &index_ptr)==SUCCESS) { int type, link; void *ptr; if (Z_TYPE_P(index_ptr) != le_index_ptr) { RETURN_FALSE; } link = (int) index_ptr->ptr; ptr = (hw_connection *) zend_list_find(link, &type); /* check if the link is still there */ if(!ptr || (type!=le_socketp && type!=le_psocketp)) { Z_LVAL_P(return_value) = HwSG(default_link) = link; Z_TYPE_P(return_value) = IS_LONG; efree(hashed_details); if(username) efree(username); if(password) efree(password); if(host) efree(host); return; } else { zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length+1); } } if ( (sockfd = open_hg_connection(host, port)) < 0 ) { php_error(E_ERROR, "%s(): Could not open connection to %s, Port: %d (retval=%d", get_active_function_name(TSRMLS_C), host, port, sockfd); if(host) efree(host); if(username) efree(username); if(password) efree(password); efree(hashed_details); RETURN_FALSE; } if(NULL == (ptr = malloc(sizeof(hw_connection)))) { if(host) efree(host); if(username) efree(username); if(password) efree(password); efree(hashed_details); RETURN_FALSE; } if(0 != (ptr->lasterror = initialize_hg_connection(sockfd, &do_swap, &version, &userdata, &server_string, username, password))) { php_error(E_ERROR, "%s(): Could not initalize hyperwave connection", get_active_function_name(TSRMLS_C)); if(host) efree(host); if(username) efree(username); if(password) efree(password); if(userdata) efree(userdata); if(server_string) free(server_string); efree(hashed_details); RETURN_FALSE; } if(username) efree(username); if(password) efree(password); ptr->version = version; ptr->server_string = server_string; ptr->socket = sockfd; ptr->swap_on = do_swap; ptr->linkroot = 0; ptr->hostname = strdup(host); ptr->username = strdup("anonymous"); Z_LVAL_P(return_value) = zend_list_insert(ptr, le_socketp); Z_TYPE_P(return_value) = IS_RESOURCE; new_index_ptr.ptr = (void *) Z_LVAL_P(return_value); Z_TYPE(new_index_ptr) = le_index_ptr; if (zend_hash_update(&EG(regular_list), hashed_details, hashed_details_length+1, (void *) &new_index_ptr, sizeof(list_entry), NULL)==FAILURE) { php_error(E_ERROR, "%s(): Could not update connection details in hash table", get_active_function_name(TSRMLS_C)); if(host) efree(host); efree(hashed_details); RETURN_FALSE; } } efree(hashed_details); if(host) efree(host); HwSG(default_link)=Z_LVAL_P(return_value); /* At this point we have a working connection. If userdata was given we are also indentified. If there is no userdata because hw_connect was called without username and password, we don't evaluate userdata. */ if(NULL == userdata) return; if(ptr->username) free(ptr->username); str = userdata; while((*str != 0) && (*str != ' ')) str++; if(*str != '\0') ptr->username = strdup(++str); else ptr->username = NULL; efree(userdata);}/* }}} */#undef BUFFERLEN/* Start of user level functions *//* ***************************** *//* {{{ proto int hw_connect(string host, int port [string username [, string password]]) Connect to the Hyperwave server */PHP_FUNCTION(hw_connect){ php_hw_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto int hw_pconnect(string host, int port [, string username [, string password]]) Connect to the Hyperwave server persistent */PHP_FUNCTION(hw_pconnect){ php_hw_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -