CVS update: php31/ext/rpc

From: Date: Wed, 16 Sep 1998 23:11:05 +0000
Subject: CVS update: php31/ext/rpc
Groups: php.dev 
Request: Send a blank email to php-dev+get-1187@lists.php.net to get a copy of this message
Date: Wednesday September 16, 1998 @ 19:11 Author: ssb Update of /repository/php31/ext/rpc In directory asf:/u2/tmp/cvs-serv22334 Modified Files: php3_rpc.h rpc.c test.php3 Added Files: .cvsignore Log Message: Implemented rpc_call(). Usage: rpc_call(function[, parameters...]). Index: php31/ext/rpc/php3_rpc.h diff -c php31/ext/rpc/php3_rpc.h:1.1 php31/ext/rpc/php3_rpc.h:1.2 *** php31/ext/rpc/php3_rpc.h:1.1 Tue Sep 15 19:37:27 1998 --- php31/ext/rpc/php3_rpc.h Wed Sep 16 19:11:03 1998 *************** *** 27,40 **** +----------------------------------------------------------------------+ */ ! /* $Id: php3_rpc.h,v 1.1 1998/09/15 23:37:27 ssb Exp $ */ #define rpc_module_ptr &rpc_module_entry extern php3_module_entry rpc_module_entry; void php3_serialize(INTERNAL_FUNCTION_PARAMETERS); void php3_unserialize(INTERNAL_FUNCTION_PARAMETERS); /* * Local variables: --- 27,62 ---- +----------------------------------------------------------------------+ */ ! /* $Id: php3_rpc.h,v 1.2 1998/09/16 23:11:03 ssb Exp $ */ + #define RPC_NOP 0 + + /* function calling opcodes */ + #define RPC_FUNCTION_CALL 1 + #define RPC_FUNCTION_NPARAMS 2 + #define RPC_FUNCTION_PARAMETER 3 + #define RPC_RETURN_VALUE 4 + + /* value passing opcodes */ + #define RPC_TYPE_LONG 10 + #define RPC_TYPE_STRING 11 + #define RPC_TYPE_DOUBLE 12 + #define RPC_TYPE_ARRAY 13 + #define rpc_module_ptr &rpc_module_entry extern php3_module_entry rpc_module_entry; void php3_serialize(INTERNAL_FUNCTION_PARAMETERS); void php3_unserialize(INTERNAL_FUNCTION_PARAMETERS); + void php3_rpc_call(INTERNAL_FUNCTION_PARAMETERS); + + typedef struct { + char enabled; + char *host; + long port; + int socket; + } rpc_module; /* * Local variables: Index: php31/ext/rpc/rpc.c diff -c php31/ext/rpc/rpc.c:1.1 php31/ext/rpc/rpc.c:1.2 *** php31/ext/rpc/rpc.c:1.1 Tue Sep 15 19:37:28 1998 --- php31/ext/rpc/rpc.c Wed Sep 16 19:11:04 1998 *************** *** 27,62 **** +----------------------------------------------------------------------+ */ ! /* $Id: rpc.c,v 1.1 1998/09/15 23:37:28 ssb Exp $ */ #include "php.h" #include "internal_functions.h" #include <sys/types.h> #include <sys/socket.h> ! #include <sys/un.h> #include <stdio.h> #include "php3_rpc.h" function_entry rpc_functions[] = { { "serialize", php3_serialize, first_arg_allow_ref }, { "unserialize", php3_unserialize, first_arg_allow_ref }, { NULL, NULL, NULL } }; php3_module_entry rpc_module_entry = { ! "RPC", ! rpc_functions, ! NULL, ! NULL, ! NULL, ! NULL, ! NULL, ! STANDARD_MODULE_PROPERTIES }; static int rpc_connect_unix(char *path) { --- 27,226 ---- +----------------------------------------------------------------------+ */ ! /* $Id: rpc.c,v 1.2 1998/09/16 23:11:04 ssb Exp $ */ + #ifdef THREAD_SAFE + # include "tls.h" + #endif + #define IS_EXT_MODULE + #include "php.h" #include "internal_functions.h" #include <sys/types.h> #include <sys/socket.h> ! #ifdef HAVE_SYS_UN_H ! # include <sys/un.h> ! #endif ! #include <netinet/in.h> #include <stdio.h> + #ifdef HAVE_UNISTD_H + # include <unistd.h> + #endif #include "php3_rpc.h" + /* TODO: + * + * - Should drop htons() and similar functions in favor of + * of own data types with well-defined size in octets. + * The current version will not work between machines with + * different "unsigned short" and "unsigned long" sizes. + * + */ + + /* {{{ thread safety stuff */ + + #ifdef THREAD_SAFE + # define RPC_GLOBAL(a) rpc_globals->a + # define RPC_TLS_VARS \ + rpc_global_struct *rpc_globals = TlsGetValue(RPCTls); + + void *rpc_mutex; + DWORD RPCTls; + static int numthreads=0; + + typedef struct rpc_global_struct { + rpc_module php3_rpc_module; + } rpc_global_struct; + + #else /* !defined(THREAD_SAFE) */ + # define RPC_GLOBAL(a) a + # define RPC_TLS_VARS + + rpc_module php3_rpc_module; + + #endif /* defined(THREAD_SAFE) */ + + /* }}} */ + /* {{{ dynamic loading stuff */ + + #if COMPILE_DL + + php3_module_entry *get_module() { return &rpc_module_entry; }; + + # if (WIN32|WINNT) && defined(THREAD_SAFE) + + /* NOTE: You should have an rpc.def file where you export DllMain */ + BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, + LPVOID lpReserved) + { + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + if ((RPCTls = TlsAlloc()) == 0xFFFFFFFF){ + return 0; + } + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + case DLL_PROCESS_DETACH: + if (!TlsFree(RPCTls)) { + return 0; + } + break; + } + return 1; + } + + # endif /* thread safe on Windows */ + #endif /* COMPILE_DL */ + + /* }}} */ + + int php3_minit_rpc(INIT_FUNC_ARGS); + int php3_mshutdown_rpc(void); + void php3_info_rpc(void); + #ifdef HAVE_SYS_UN_H + static int rpc_connect_unix(char *); + #endif + static int rpc_connect_tcp(char *, int); + static void rpc_msg_opcode(char **, int *, int *, unsigned short); + static void rpc_msg_pval(char **, int *, int *, pval *); + static void rpc_msg_raw(char **, int *, int *, char *, int); + static void rpc_msg_long(char **, int *, int *, long); + + function_entry rpc_functions[] = { { "serialize", php3_serialize, first_arg_allow_ref }, { "unserialize", php3_unserialize, first_arg_allow_ref }, + { "rpc_call", php3_rpc_call, NULL }, { NULL, NULL, NULL } }; php3_module_entry rpc_module_entry = { ! "RPC", /* extension name */ ! rpc_functions, /* extension function list */ ! php3_minit_rpc, /* extension-wide startup function */ ! php3_mshutdown_rpc, /* extension-wide shutdown function */ ! NULL, /* per-request startup function */ ! NULL, /* per-request shutdown function */ ! php3_info_rpc, /* information function */ ! STANDARD_MODULE_PROPERTIES }; + int + php3_minit_rpc(INIT_FUNC_ARGS) + { + RPC_TLS_VARS; + + RPC_GLOBAL(php3_rpc_module).enabled = 1; + RPC_GLOBAL(php3_rpc_module).host = "/tmp/prc.sock"; + RPC_GLOBAL(php3_rpc_module).port = -1; + + if (RPC_GLOBAL(php3_rpc_module).enabled) { + int sock; + + #ifdef HAVE_SYS_UN_H + if (RPC_GLOBAL(php3_rpc_module).port == -1) { + sock = rpc_connect_unix(RPC_GLOBAL(php3_rpc_module).host); + } else { + sock = rpc_connect_tcp(RPC_GLOBAL(php3_rpc_module).host, + RPC_GLOBAL(php3_rpc_module).port); + } + #else + sock = rpc_connect_tcp(RPC_GLOBAL(php3_rpc_module).host, + RPC_GLOBAL(php3_rpc_module).port); + #endif + if (sock != -1) { + RPC_GLOBAL(php3_rpc_module).socket = sock; + } else { + /* fail silently */ + RPC_GLOBAL(php3_rpc_module).socket = -1; + } + } + + return SUCCESS; + } + + + int + php3_mshutdown_rpc() + { + if (RPC_GLOBAL(php3_rpc_module).socket != -1) { + close(RPC_GLOBAL(php3_rpc_module).socket); + RPC_GLOBAL(php3_rpc_module).socket = -1; + } + return SUCCESS; + } + + + void php3_info_rpc() + { + if (RPC_GLOBAL(php3_rpc_module).socket == -1) { + PUTS("No connection"); + } else { + #if HAVE_SYS_UN_H + if (RPC_GLOBAL(php3_rpc_module).port == -1) { + php3_printf("Connected to %s", + RPC_GLOBAL(php3_rpc_module).host); + } else { + php3_printf("Connected to %s port %d", + RPC_GLOBAL(php3_rpc_module).host, + RPC_GLOBAL(php3_rpc_module).port); + } + #else + php3_printf("Connected to %s port %d", + RPC_GLOBAL(php3_rpc_module).host, + RPC_GLOBAL(php3_rpc_module).port); + #endif + } + } + + + #ifdef HAVE_SYS_UN_H static int rpc_connect_unix(char *path) { *************** *** 68,116 **** saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0'; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) { ! perror("connect"); ! return -1; } return fd; } ! int ! php3i_serialize_string(pval *val, char **resultp, int *sizep) { ! unsigned short type; ! unsigned long size; ! type = htons(val->type); ! size = htonl((unsigned long)val->value.str.len); ! *sizep = sizeof(type) + sizeof(size) + val->value.str.len; ! *resultp = emalloc(*sizep); ! if (*resultp == NULL) { ! return FAILURE; } ! memcpy(*resultp, (char *)&type, sizeof(type)); ! memcpy(*resultp+sizeof(type), (char *)&size, sizeof(size)); ! memcpy(*resultp+sizeof(type)+sizeof(size), val->value.str.val, val->value.str.len); ! return SUCCESS; } int ! php3i_serialize_long(pval *val, char **resultp, int *sizep) { unsigned short type; ! unsigned long value; type = htons(val->type); ! value = htonl((unsigned long)val->value.lval); ! *sizep = sizeof(type) + sizeof(value); ! *resultp = emalloc(*sizep); ! if (*resultp == NULL) { ! return FAILURE; } ! memcpy(*resultp, (char *)&type, sizeof(type)); ! memcpy(*resultp+sizeof(type), (char *)&value, sizeof(value)); ! return SUCCESS; } --- 232,294 ---- saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0'; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) { ! return -1; } return fd; } + #endif ! static int ! rpc_connect_tcp(char *host, int port) { ! struct sockaddr_in saddr; ! int fd; ! memset(&saddr, 0, sizeof(saddr)); ! saddr.sin_addr.s_addr = lookup_hostname(host); ! saddr.sin_family = AF_INET; ! saddr.sin_port = htons((unsigned short)port); ! fd = socket(saddr.sin_family, SOCK_STREAM, 0); ! if (connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) { ! return -1; } ! return fd; } int ! php3i_serialize(pval *val, char **resultp, int *sizep) { unsigned short type; ! unsigned long size, value; type = htons(val->type); ! switch (val->type) { ! case IS_STRING: ! size = htonl((unsigned long)val->value.str.len); ! *sizep = sizeof(type) + sizeof(size) + val->value.str.len; ! *resultp = emalloc(*sizep); ! if (*resultp == NULL) { ! return FAILURE; ! } ! memcpy(*resultp, (char *)&type, sizeof(type)); ! memcpy(*resultp+sizeof(type), (char *)&size, sizeof(size)); ! memcpy(*resultp+sizeof(type)+sizeof(size), val->value.str.val, ! val->value.str.len); ! return SUCCESS; ! case IS_LONG: ! value = htonl((unsigned long)val->value.lval); ! *sizep = sizeof(type) + sizeof(value); ! *resultp = emalloc(*sizep); ! if (*resultp == NULL) { ! return FAILURE; ! } ! memcpy(*resultp, (char *)&type, sizeof(type)); ! memcpy(*resultp+sizeof(type), (char *)&value, sizeof(value)); ! return SUCCESS; } ! return FAILURE; /* unknown type */ } *************** *** 128,134 **** pos += sizeof(ntype); type = ntohs(ntype); switch (type) { ! case IS_STRING: { unsigned long nlen, len; val->type = type; --- 306,312 ---- pos += sizeof(ntype); type = ntohs(ntype); switch (type) { ! case RPC_TYPE_STRING: { unsigned long nlen, len; val->type = type; *************** *** 147,153 **** pos += len; break; } ! case IS_LONG: { unsigned long nvalue, value; val->type = type; --- 325,331 ---- pos += len; break; } ! case RPC_TYPE_LONG: { unsigned long nvalue, value; val->type = type; *************** *** 173,186 **** * * Strings: * <type><length><data> ! * type - set to IS_STRING for strings, network byte-order short * length - length of string (not counting terminating null), network * byte-order long * data - string data (without a terminating null) * * Longs: * <type><value> ! * type - set to IS_LONG for integers * value - integer value, network byte-order long * */ --- 351,364 ---- * * Strings: * <type><length><data> ! * type - set to RPC_TYPE_STRING for strings, network byte-order short * length - length of string (not counting terminating null), network * byte-order long * data - string data (without a terminating null) * * Longs: * <type><value> ! * type - set to RPC_TYPE_LONG for integers * value - integer value, network byte-order long * */ *************** *** 195,214 **** WRONG_PARAM_COUNT; } ! switch (arg->type) { ! case IS_STRING: ! if (php3i_serialize_string(arg, &result, &size) == FAILURE) { ! RETURN_FALSE; ! } ! break; ! case IS_LONG: ! if (php3i_serialize_long(arg, &result, &size) == FAILURE) { ! RETURN_FALSE; ! } ! break; ! default: ! php3_error(E_WARNING, "unsupported data type"); ! RETURN_FALSE; } RETVAL_STRINGL(result, size, 0); } --- 373,380 ---- WRONG_PARAM_COUNT; } ! if (php3i_serialize(arg, &result, &size) == FAILURE) { ! RETURN_FALSE; } RETVAL_STRINGL(result, size, 0); } *************** *** 231,236 **** --- 397,510 ---- if (php3i_unserialize(return_value, buffer, size) == FAILURE) { RETURN_FALSE; } + } + + + #define rpc_msg_short rpc_msg_opcode + + static void + rpc_msg_opcode(char **buffer, /* data buffer */ + int *pos, /* pointer to current buffer offset */ + int *size, /* pointer to buffer size */ + unsigned short opcode) /* opcode to append to the buffer */ + { + int len = sizeof(opcode); + char *juks; + + opcode = htons(opcode); + juks = (char *)&opcode; + rpc_msg_raw(buffer, pos, size, juks, len); + } + + + static void + rpc_msg_pval(char **buffer, /* data buffer */ + int *pos, /* pointer to current buffer offset */ + int *size, /* pointer to buffer size */ + pval *val) /* pval to serialize and append */ + { + int srl_size; + char *srl_buf; + + if (php3i_serialize(val, &srl_buf, &srl_size) == FAILURE) { + return; + } + rpc_msg_raw(buffer, pos, size, srl_buf, srl_size); + efree(srl_buf); + } + + + static void + rpc_msg_long(char **buffer, /* data buffer */ + int *pos, /* pointer to current buffer offset */ + int *size, /* pointer to buffer size */ + long value) /* value to append to the buffer */ + { + int len = sizeof(value); + char *juks; + + value = htonl(value); + juks = (char *)&value; + rpc_msg_raw(buffer, pos, size, juks, len); + } + + + static void + rpc_msg_raw(char **buffer, /* data buffer */ + int *pos, /* pointer to current buffer offset */ + int *size, /* pointer to buffer size */ + char *data, /* data to append to the buffer */ + int len) /* number of bytes to append */ + { + if ((*pos + len) >= *size) { + while ((*pos + len) >= *size) { + *size *= 2; + } + *buffer = erealloc(*buffer, *size); + } + memcpy(&(*buffer)[*pos], data, len); + *pos += len; + } + + + /* TODO: + * - check for references and use placeholders for those parameters + */ + void + php3_rpc_call(INTERNAL_FUNCTION_PARAMETERS) + { + pval **argv; + int argc, i, size, len, sock; + unsigned short opcode; + char *buf; + RPC_TLS_VARS; + + argc = ARG_COUNT(ht); + if (argc < 1) { + WRONG_PARAM_COUNT; + } + argv = emalloc(argc * sizeof(pval *)); + if (getParametersArray(ht, argc, argv) == FAILURE) { + WRONG_PARAM_COUNT; + } + sock = RPC_GLOBAL(php3_rpc_module).socket; + if (sock == -1) { + php3_error(E_WARNING, "no RPC server connection"); + RETURN_FALSE; + } + convert_to_string(argv[0]); + size = 50; /* size will be doubled every time the buffer is too small */ + buf = emalloc(size); + len = 0; + rpc_msg_opcode(&buf, &len, &size, RPC_FUNCTION_CALL); + rpc_msg_pval(&buf, &len, &size, argv[0]); + rpc_msg_opcode(&buf, &len, &size, RPC_FUNCTION_NPARAMS); + rpc_msg_short(&buf, &len, &size, argc - 1); + for (i = 1; i < argc; i++) { + rpc_msg_opcode(&buf, &len, &size, RPC_FUNCTION_PARAMETER); + rpc_msg_pval(&buf, &len, &size, argv[i]); + } + write(sock, buf, len); } /* Index: php31/ext/rpc/test.php3 diff -c php31/ext/rpc/test.php3:1.1 php31/ext/rpc/test.php3:1.2 *** php31/ext/rpc/test.php3:1.1 Tue Sep 15 19:37:28 1998 --- php31/ext/rpc/test.php3 Wed Sep 16 19:11:04 1998 *************** *** 11,14 **** --- 11,16 ---- printf("serialized: `%s' (%s)\n", rawurlencode($ser), gettype($ser)); printf("unserialized: `%s' (%s)\n", $uns, gettype($uns)); + rpc_call("testFunc", 2, 3, "bing"); + ?> -- PHP Development Mailing List http://www.php.net/ To unsubscribe send an empty message to php-dev-unsubscribe@lists.php.net For help: php-dev-help@lists.php.net

« previous php.dev (#1187) next »