diff options
Diffstat (limited to 'ext/standard')
68 files changed, 16863 insertions, 0 deletions
diff --git a/ext/standard/Makefile.am b/ext/standard/Makefile.am new file mode 100644 index 0000000000..0a7617147b --- /dev/null +++ b/ext/standard/Makefile.am @@ -0,0 +1,11 @@ +## Process this file with automake to produce Makefile.in +INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend -I@top_srcdir@/functions +noinst_LIBRARIES=libphpext_standard.a +libphpext_standard_a_SOURCES=\ + base64.c basic_functions.c browscap.c datetime.c dir.c \ + dns.c exec.c file.c filestat.c formatted_print.c fsock.c \ + html.c image.c info.c link.c mail.c math.c md5.c microtime.c \ + pack.c pageinfo.c rand.c reg.c soundex.c string.c \ + syslog.c type.c uniqid.c url.c iptc.c var.c quot_print.c \ + cyr_convert.c + diff --git a/ext/standard/base64.c b/ext/standard/base64.c new file mode 100644 index 0000000000..392f2451ac --- /dev/null +++ b/ext/standard/base64.c @@ -0,0 +1,197 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Author: Jim Winstead (jimw@php.net) | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ + +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include <string.h> + +#include "php.h" +#include "base64.h" + +static char base64_table[] = + { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0' + }; +static char base64_pad = '='; + +unsigned char *_php3_base64_encode(const unsigned char *string, int length, int *ret_length) { + const unsigned char *current = string; + int i = 0; + unsigned char *result = (unsigned char *)emalloc(((length + 3 - length % 3) * 4 / 3 + 1) * sizeof(char)); + + while (length > 2) { /* keep going until we have less than 24 bits */ + result[i++] = base64_table[current[0] >> 2]; + result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)]; + result[i++] = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)]; + result[i++] = base64_table[current[2] & 0x3f]; + + current += 3; + length -= 3; /* we just handle 3 octets of data */ + } + + /* now deal with the tail end of things */ + if (length != 0) { + result[i++] = base64_table[current[0] >> 2]; + if (length > 1) { + result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)]; + result[i++] = base64_table[(current[1] & 0x0f) << 2]; + result[i++] = base64_pad; + } + else { + result[i++] = base64_table[(current[0] & 0x03) << 4]; + result[i++] = base64_pad; + result[i++] = base64_pad; + } + } + if(ret_length) { + *ret_length = i; + } + result[i] = '\0'; + return result; +} + +/* as above, but backwards. :) */ +unsigned char *_php3_base64_decode(const unsigned char *string, int length, int *ret_length) { + const unsigned char *current = string; + int ch, i = 0, j = 0, k; + + unsigned char *result = (unsigned char *)emalloc((length / 4 * 3 + 1) * sizeof(char)); + if (result == NULL) { + return NULL; + } + + /* run through the whole string, converting as we go */ + while ((ch = *current++) != '\0') { + if (ch == base64_pad) break; + ch = (int)strchr(base64_table, ch); + if (ch == 0) { + efree(result); + return NULL; + } + ch -= (int)base64_table; + + switch(i % 4) { + case 0: + result[j] = ch << 2; + break; + case 1: + result[j++] |= ch >> 4; + result[j] = (ch & 0x0f) << 4; + break; + case 2: + result[j++] |= ch >>2; + result[j] = (ch & 0x03) << 6; + break; + case 3: + result[j++] |= ch; + break; + } + i++; + } + + k = j; + /* mop things up if we ended on a boundary */ + if (ch == base64_pad) { + switch(i % 4) { + case 0: + case 1: + efree(result); + return NULL; + case 2: + k++; + case 3: + result[k++] = 0; + } + } + if(ret_length) { + *ret_length = j; + } + result[k] = '\0'; + return result; +} + +/* {{{ proto string base64_encode(string str) + Encodes string using MIME base64 algorithm */ +void php3_base64_encode(INTERNAL_FUNCTION_PARAMETERS) { + pval *string; + unsigned char *result; + int ret_length; + TLS_VARS; + + if (ARG_COUNT(ht)!=1 || getParameters(ht,1,&string) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(string); + result = _php3_base64_encode(string->value.str.val, string->value.str.len, &ret_length); + if (result != NULL) { + return_value->value.str.val = result; + return_value->value.str.len = ret_length; + return_value->type = IS_STRING; + } else { + RETURN_FALSE; + } +} +/* }}} */ + + +/* {{{ proto string base64_decode(string str) + Decodes string using MIME base64 algorithm */ +void php3_base64_decode(INTERNAL_FUNCTION_PARAMETERS) { + pval *string; + unsigned char *result; + int ret_length; + TLS_VARS; + + if (ARG_COUNT(ht)!=1 || getParameters(ht,1,&string) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(string); + result = _php3_base64_decode(string->value.str.val, string->value.str.len, &ret_length); + if (result != NULL) { + return_value->value.str.val = result; + return_value->value.str.len = ret_length; + return_value->type = IS_STRING; + } else { + RETURN_FALSE; + } +} +/* }}} */ + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/base64.h b/ext/standard/base64.h new file mode 100644 index 0000000000..9dc2312551 --- /dev/null +++ b/ext/standard/base64.h @@ -0,0 +1,47 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Author: Jim Winstead (jimw@php.net) | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ + +#ifndef _BASE64_h +#define _BASE64_h + +extern void php3_base64_decode(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_base64_encode(INTERNAL_FUNCTION_PARAMETERS); + +extern unsigned char *_php3_base64_encode(const unsigned char *, int, int *); +extern unsigned char *_php3_base64_decode(const unsigned char *, int, int *); + +#endif /* _BASE64_h */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c new file mode 100644 index 0000000000..5b7b807024 --- /dev/null +++ b/ext/standard/basic_functions.c @@ -0,0 +1,2153 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Andi Gutmans <andi@zend.com> | + | Zeev Suraski <zeev@zend.com> | + +----------------------------------------------------------------------+ + */ + + +#define HASH_OF(p) ((p)->type==IS_ARRAY ? (p)->value.ht : (((p)->type==IS_OBJECT ? (p)->value.obj.properties : NULL))) +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include "php_ini.h" +#include "internal_functions_registry.h" +#include "php3_standard.h" +#include "zend_operators.h" +#include <stdarg.h> +#include <stdlib.h> +#include <math.h> +#include <time.h> +#include <stdio.h> +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +#if HAVE_STRING_H +#include <string.h> +#else +#include <strings.h> +#endif +#include "safe_mode.h" +/* +#include "functions/basic_functions.h" +#include "functions/phpmath.h" +#include "functions/php3_string.h" +#include "functions/dns.h" +#include "functions/md5.h" +#include "functions/html.h" +#include "functions/post.h" +#include "functions/exec.h" +#include "functions/info.h" +#include "functions/url.h" +#include "functions/datetime.h" +#include "functions/fsock.h" +#include "functions/image.h" +#include "functions/php3_link.h" +#include "functions/php3_filestat.h" +#include "functions/microtime.h" +#include "functions/pageinfo.h" +#include "functions/uniqid.h" +#include "functions/base64.h" +#include "functions/php3_mail.h" +#include "functions/php3_var.h" +#include "functions/php3_iptc.h" +#include "functions/quot_print.h" +#include "functions/cyr_convert.h" +*/ +#if WIN32|WINNT +#include "win32/unistd.h" +#endif +#include "zend_globals.h" + +#include "php_globals.h" + +static unsigned char second_and_third_args_force_ref[] = { 3, BYREF_NONE, BYREF_FORCE, BYREF_FORCE }; +static unsigned char third_and_fourth_args_force_ref[] = { 4, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYREF_FORCE }; +static pval *user_compare_func_name; +static HashTable *user_shutdown_function_names; + +/* some prototypes for local functions */ +void user_shutdown_function_dtor(pval *user_shutdown_function_name); +int user_shutdown_function_executor(pval *user_shutdown_function_name); +void php3_call_shutdown_functions(void); + +function_entry basic_functions[] = { + {"intval", int_value, NULL}, + {"doubleval", double_value, NULL}, + {"strval", string_value, NULL}, + PHP_FE(define, NULL) + PHP_FE(defined, NULL) + {"short_tags", php3_toggle_short_open_tag, NULL}, + {"sleep", php3_sleep, NULL}, + {"usleep", php3_usleep, NULL}, + {"ksort", php3_key_sort, first_arg_force_ref}, + {"asort", php3_asort, first_arg_force_ref}, + {"arsort", php3_arsort, first_arg_force_ref}, + {"sort", php3_sort, first_arg_force_ref}, + {"rsort", php3_rsort, first_arg_force_ref}, + {"usort", php3_user_sort, first_arg_force_ref}, + {"uasort", php3_auser_sort, first_arg_force_ref}, + {"uksort", php3_user_key_sort, first_arg_force_ref}, + {"array_walk", php3_array_walk, first_arg_force_ref}, + {"sizeof", php3_count, first_arg_allow_ref}, + {"count", php3_count, first_arg_allow_ref}, + {"time", php3_time, NULL}, + {"mktime", php3_mktime, NULL}, + {"gmmktime", php3_gmmktime, NULL}, +#if HAVE_STRFTIME + {"strftime", php3_strftime, NULL}, +#endif + {"date", php3_date, NULL}, + {"gmdate", php3_gmdate, NULL}, + {"getdate", php3_getdate, NULL}, + {"checkdate", php3_checkdate, NULL}, + {"chr", php3_chr, NULL}, + {"ord", php3_ord, NULL}, + {"flush", php3_flush, NULL}, + {"end", array_end, first_arg_force_ref}, + {"prev", array_prev, first_arg_force_ref}, + {"next", array_next, first_arg_force_ref}, + {"reset", array_reset, first_arg_force_ref}, + {"current", array_current, first_arg_force_ref}, + {"key", array_current_key, first_arg_force_ref}, + {"each", array_each, first_arg_force_ref}, + {"gettype", php3_gettype, NULL}, + {"settype", php3_settype, first_arg_force_ref}, + {"min", php3_min, NULL}, + {"max", php3_max, NULL}, + + {"addslashes", php3_addslashes, NULL}, + {"chop", php3_chop, NULL}, + {"str_replace", php3_str_replace, NULL}, + {"chunk_split", php3_chunk_split, NULL}, + {"trim", php3_trim, NULL}, + {"ltrim", php3_ltrim, NULL}, + {"rtrim", php3_chop, NULL}, + {"pos", array_current, first_arg_force_ref}, + + {"fsockopen", php3_fsockopen, third_and_fourth_args_force_ref}, + {"getimagesize", php3_getimagesize, NULL}, + {"htmlspecialchars", php3_htmlspecialchars, NULL}, + {"htmlentities", php3_htmlentities, NULL}, + {"md5", php3_md5, NULL}, + + {"iptcparse", php3_iptcparse, NULL}, + {"parse_url", php3_parse_url, NULL}, + + {"parse_str", php3_parsestr, NULL}, + {"phpinfo", php3_info, NULL}, + {"phpversion", php3_version, NULL}, + {"strlen", php3_strlen, NULL}, + {"strcmp", php3_strcmp, NULL}, + {"strspn", php3_strspn, NULL}, + {"strcspn", php3_strcspn, NULL}, + {"strcasecmp", php3_strcasecmp, NULL}, + {"strtok", php3_strtok, NULL}, + {"strtoupper", php3_strtoupper, NULL}, + {"strtolower", php3_strtolower, NULL}, + {"strchr", php3_strstr, NULL}, + {"strpos", php3_strpos, NULL}, + {"strrpos", php3_strrpos, NULL}, + {"strrev", php3_strrev, NULL}, + {"hebrev", php3_hebrev, NULL}, + {"hebrevc", php3_hebrev_with_conversion,NULL}, + {"nl2br", php3_newline_to_br, NULL}, + {"basename", php3_basename, NULL}, + {"dirname", php3_dirname, NULL}, + {"stripslashes", php3_stripslashes, NULL}, + {"strstr", php3_strstr, NULL}, + {"stristr", php3_stristr, NULL}, + {"strrchr", php3_strrchr, NULL}, + {"substr", php3_substr, NULL}, + {"quotemeta", php3_quotemeta, NULL}, + {"urlencode", php3_urlencode, NULL}, + {"urldecode", php3_urldecode, NULL}, + {"rawurlencode", php3_rawurlencode, NULL}, + {"rawurldecode", php3_rawurldecode, NULL}, + {"ucfirst", php3_ucfirst, NULL}, + {"ucwords", php3_ucwords, NULL}, + {"strtr", php3_strtr, NULL}, + {"sprintf", php3_user_sprintf, NULL}, + {"printf", php3_user_printf, NULL}, + {"setlocale", php3_setlocale, NULL}, + + {"exec", php3_exec, second_and_third_args_force_ref}, + {"system", php3_system, second_arg_force_ref}, + {"escapeshellcmd", php3_escapeshellcmd, NULL}, + {"passthru", php3_passthru, second_arg_force_ref}, + PHP_FE(shell_exec, NULL) + + {"soundex", soundex, NULL}, + + {"rand", php3_rand, NULL}, + {"srand", php3_srand, NULL}, + {"getrandmax", php3_getrandmax, NULL}, + {"mt_rand", php3_mt_rand, NULL}, + {"mt_srand", php3_mt_srand, NULL}, + {"mt_getrandmax", php3_mt_getrandmax, NULL}, + {"gethostbyaddr", php3_gethostbyaddr, NULL}, + {"gethostbyname", php3_gethostbyname, NULL}, + {"gethostbynamel", php3_gethostbynamel, NULL}, +#if !(WIN32|WINNT)||HAVE_BINDLIB + {"checkdnsrr", php3_checkdnsrr, NULL}, + {"getmxrr", php3_getmxrr, second_and_third_args_force_ref}, +#endif + {"explode", php3_explode, NULL}, + {"implode", php3_implode, NULL}, + {"getenv", php3_getenv, NULL}, + {"error_reporting", php3_error_reporting, NULL}, + {"clearstatcache", php3_clearstatcache, NULL}, + + {"unlink", php3_unlink, NULL}, + + {"getmyuid", php3_getmyuid, NULL}, + {"getmypid", php3_getmypid, NULL}, + /*getmyiid is here for forward compatibility with 3.1 + See pageinfo.c in 3.1 for more information*/ + {"getmyiid", php3_getmypid, NULL}, + {"getmyinode", php3_getmyinode, NULL}, + {"getlastmod", php3_getlastmod, NULL}, + + {"base64_decode", php3_base64_decode, NULL}, + {"base64_encode", php3_base64_encode, NULL}, + + {"abs", php3_abs, NULL}, + {"ceil", php3_ceil, NULL}, + {"floor", php3_floor, NULL}, + {"round", php3_round, NULL}, + {"sin", php3_sin, NULL}, + {"cos", php3_cos, NULL}, + {"tan", php3_tan, NULL}, + {"asin", php3_asin, NULL}, + {"acos", php3_acos, NULL}, + {"atan", php3_atan, NULL}, + {"atan2", php3_atan2, NULL}, + {"pi", php3_pi, NULL}, + {"pow", php3_pow, NULL}, + {"exp", php3_exp, NULL}, + {"log", php3_log, NULL}, + {"log10", php3_log10, NULL}, + {"sqrt", php3_sqrt, NULL}, + {"deg2rad", php3_deg2rad, NULL}, + {"rad2deg", php3_rad2deg, NULL}, + {"bindec", php3_bindec, NULL}, + {"hexdec", php3_hexdec, NULL}, + {"octdec", php3_octdec, NULL}, + {"decbin", php3_decbin, NULL}, + {"decoct", php3_decoct, NULL}, + {"dechex", php3_dechex, NULL}, + {"base_convert",php3_base_convert, NULL}, + {"number_format", php3_number_format, NULL}, + +#if HAVE_PUTENV + {"putenv", php3_putenv, NULL}, +#endif + {"microtime", php3_microtime, NULL}, + {"uniqid", php3_uniqid, NULL}, + {"linkinfo", php3_linkinfo, NULL}, + {"readlink", php3_readlink, NULL}, + {"symlink", php3_symlink, NULL}, + {"link", php3_link, NULL}, + {"quoted_printable_decode", php3_quoted_printable_decode, NULL}, + {"convert_cyr_string", php3_convert_cyr_string, NULL}, + {"get_current_user", php3_get_current_user, NULL}, + {"set_time_limit", php3_set_time_limit, NULL}, + + {"get_cfg_var", php3_get_cfg_var, NULL}, + {"magic_quotes_runtime", php3_set_magic_quotes_runtime, NULL}, + {"set_magic_quotes_runtime", php3_set_magic_quotes_runtime, NULL}, + {"get_magic_quotes_gpc", php3_get_magic_quotes_gpc, NULL}, + {"get_magic_quotes_runtime", php3_get_magic_quotes_runtime, NULL}, + + {"is_long", php3_is_long, first_arg_allow_ref}, + {"is_int", php3_is_long, first_arg_allow_ref}, + {"is_integer", php3_is_long, first_arg_allow_ref}, + {"is_float", php3_is_double, first_arg_allow_ref}, + {"is_double", php3_is_double, first_arg_allow_ref}, + {"is_real", php3_is_double, first_arg_allow_ref}, + {"is_string", php3_is_string, first_arg_allow_ref}, + {"is_array", php3_is_array, first_arg_allow_ref}, + {"is_object", php3_is_object, first_arg_allow_ref}, + + {"leak", php3_leak, NULL}, + {"error_log", php3_error_log, NULL}, + {"call_user_func", php3_call_user_func, NULL}, + {"call_user_method", php3_call_user_method, NULL}, + + PHP_FE(var_dump, NULL) + PHP_FE(serialize, first_arg_allow_ref) + PHP_FE(unserialize, first_arg_allow_ref) + + PHP_FE(register_shutdown_function, NULL) + + PHP_FE(highlight_file, NULL) + PHP_NAMED_FE(show_source, php3_highlight_file, NULL) + PHP_FE(highlight_string, NULL) + + PHP_FE(ob_start, NULL) + PHP_FE(ob_end_flush, NULL) + PHP_FE(ob_end_clean, NULL) + PHP_FE(ob_get_contents, NULL) + + PHP_FE(ini_get, NULL) + PHP_FE(ini_alter, NULL) + PHP_FE(ini_restore, NULL) + + PHP_FE(print_r, NULL) + + {NULL, NULL, NULL} +}; + + +PHP_INI_BEGIN() + PHP_INI_ENTRY("highlight.string", "#foobar", PHP_INI_ALL, NULL, NULL) + PHP_INI_ENTRY("test2", "testing", PHP_INI_SYSTEM, NULL, NULL) +PHP_INI_END() + + +php3_module_entry basic_functions_module = { + "Basic Functions", /* extension name */ + basic_functions, /* function list */ + php3_minit_basic, /* process startup */ + php3_mshutdown_basic, /* process shutdown */ + php3_rinit_basic, /* request startup */ + php3_rshutdown_basic, /* request shutdown */ + NULL, /* extension info */ + STANDARD_MODULE_PROPERTIES +}; + +#if HAVE_PUTENV +static HashTable putenv_ht; + +static void _php3_putenv_destructor(putenv_entry *pe) +{ + if (pe->previous_value) { + putenv(pe->previous_value); + } else { +# if HAVE_UNSETENV + unsetenv(pe->key); +# else + char **env; + + for (env = environ; env != NULL && *env != NULL; env++) { + if (!strncmp(*env,pe->key,pe->key_len) && (*env)[pe->key_len]=='=') { /* found it */ + *env = ""; + break; + } + } +# endif + } + efree(pe->putenv_string); + efree(pe->key); +} +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +void test_class_startup(); + +int php3_minit_basic(INIT_FUNC_ARGS) +{ + TLS_VARS; + + REGISTER_DOUBLE_CONSTANT("M_PI", M_PI, CONST_CS | CONST_PERSISTENT); + test_class_startup(); + REGISTER_INI_ENTRIES(); + return SUCCESS; +} + + +int php3_mshutdown_basic(SHUTDOWN_FUNC_ARGS) +{ + UNREGISTER_INI_ENTRIES(); + return SUCCESS; +} + + +int php3_rinit_basic(INIT_FUNC_ARGS) +{ + TLS_VARS; + GLOBAL(strtok_string) = NULL; +#if HAVE_PUTENV + if (_php3_hash_init(&putenv_ht, 1, NULL, (void (*)(void *)) _php3_putenv_destructor, 0) == FAILURE) { + return FAILURE; + } +#endif + user_compare_func_name=NULL; + user_shutdown_function_names=NULL; + return SUCCESS; +} + + +int php3_rshutdown_basic(SHUTDOWN_FUNC_ARGS) +{ + TLS_VARS; + STR_FREE(GLOBAL(strtok_string)); +#if HAVE_PUTENV + _php3_hash_destroy(&putenv_ht); +#endif + return SUCCESS; +} + +/******************** + * System Functions * + ********************/ + +void php3_getenv(INTERNAL_FUNCTION_PARAMETERS) +{ +#if FHTTPD + int i; +#endif + pval *str; + char *ptr; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + +#if FHTTPD + ptr=NULL; + if (str->type == IS_STRING && req){ + for(i=0;i<req->nlines;i++){ + if (req->lines[i].paramc>1){ + if (req->lines[i].params[0]){ + if (!strcmp(req->lines[i].params[0], + str->value.str.val)){ + ptr=req->lines[i].params[1]; + i=req->nlines; + } + } + } + } + } + if (!ptr) ptr = getenv(str->value.str.val); + if (ptr +#else + + if (str->type == IS_STRING && +#if APACHE + ((ptr = (char *)table_get(GLOBAL(php3_rqst)->subprocess_env, str->value.str.val)) || (ptr = getenv(str->value.str.val))) +#endif +#if CGI_BINARY + (ptr = getenv(str->value.str.val)) +#endif + +#if USE_SAPI + (ptr = GLOBAL(sapi_rqst)->getenv(GLOBAL(sapi_rqst)->scid,str->value.str.val)) +#endif +#endif + ) { + RETURN_STRING(ptr,1); + } + RETURN_FALSE; +} + + +#if HAVE_PUTENV +void php3_putenv(INTERNAL_FUNCTION_PARAMETERS) +{ + + pval *str; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + + if (str->value.str.val && *(str->value.str.val)) { + int ret; + char *p,**env; + putenv_entry pe; + + pe.putenv_string = estrndup(str->value.str.val,str->value.str.len); + pe.key = str->value.str.val; + if ((p=strchr(pe.key,'='))) { /* nullify the '=' if there is one */ + *p='\0'; + } + pe.key_len = strlen(pe.key); + pe.key = estrndup(pe.key,pe.key_len); + + _php3_hash_del(&putenv_ht,pe.key,pe.key_len+1); + + /* find previous value */ + pe.previous_value = NULL; + for (env = environ; env != NULL && *env != NULL; env++) { + if (!strncmp(*env,pe.key,pe.key_len) && (*env)[pe.key_len]=='=') { /* found it */ + pe.previous_value = *env; + break; + } + } + + if ((ret=putenv(pe.putenv_string))==0) { /* success */ + _php3_hash_add(&putenv_ht,pe.key,pe.key_len+1,(void **) &pe,sizeof(putenv_entry),NULL); + RETURN_TRUE; + } else { + efree(pe.putenv_string); + efree(pe.key); + RETURN_FALSE; + } + } +} +#endif + + +void php3_error_reporting(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + int old_error_reporting; + ELS_FETCH(); + + old_error_reporting = EG(error_reporting); + switch (ARG_COUNT(ht)) { + case 0: + break; + case 1: + if (getParameters(ht,1,&arg) == FAILURE) { + RETURN_FALSE; + } + convert_to_long(arg); + EG(error_reporting)=arg->value.lval; + break; + default: + WRONG_PARAM_COUNT; + break; + } + + RETVAL_LONG(old_error_reporting); +} + +void php3_toggle_short_open_tag(INTERNAL_FUNCTION_PARAMETERS) +{ + /* has to be implemented within Zend */ +#if 0 + pval *value; + int ret; + TLS_VARS; + + ret = php3_ini.short_open_tag; + + if (ARG_COUNT(ht)!=1 || getParameters(ht,1,&value) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(value); + php3_ini.short_open_tag = value->value.lval; + RETURN_LONG(ret); +#endif +} + +/******************* + * Basic Functions * + *******************/ + +void int_value(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num, *arg_base; + int base; + + switch(ARG_COUNT(ht)) { + case 1: + if (getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + base = 10; + break; + case 2: + if (getParameters(ht, 2, &num, &arg_base) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg_base); + base = arg_base->value.lval; + break; + default: + WRONG_PARAM_COUNT; + } + + convert_to_long_base(num, base); + *return_value = *num; +} + + +void double_value(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(num); + *return_value = *num; +} + + +void string_value(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(num); + *return_value = *num; + pval_copy_constructor(return_value); +} + +static int array_key_compare(const void *a, const void *b) +{ + Bucket *first; + Bucket *second; + int min, r; + + first = *((Bucket **) a); + second = *((Bucket **) b); + + if (first->arKey == NULL && second->arKey == NULL) { + return (first->h - second->h); + } else if (first->arKey == NULL) { + return -1; + } else if (second->arKey == NULL) { + return 1; + } + min = MIN(first->nKeyLength, second->nKeyLength); + if ((r = memcmp(first->arKey, second->arKey, min)) == 0) { + return (first->nKeyLength - second->nKeyLength); + } else { + return r; + } +} + + +void php3_key_sort(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array; + HashTable *target_hash; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Wrong datatype in ksort() call"); + return; + } + if (!ParameterPassedByReference(ht,1)) { + php3_error(E_WARNING, "Array not passed by reference in call to ksort()"); + return; + } + if (_php3_hash_sort(target_hash, array_key_compare,0) == FAILURE) { + return; + } + RETURN_TRUE; +} + + +/* the current implementation of count() is a definite example of what + * user functions should NOT look like. It's a hack, until we get + * unset() to work right in 3.1 + */ +void php3_count(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array; + HashTable *target_hash; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + if (array->type == IS_STRING && array->value.str.val==undefined_variable_string) { + RETURN_LONG(0); + } else { + RETURN_LONG(1); + } + } + + RETURN_LONG(_php3_hash_num_elements(target_hash)); +} + + +/* Numbers are always smaller than strings int this function as it + * anyway doesn't make much sense to compare two different data types. + * This keeps it consistant and simple. + */ +static int array_data_compare(const void *a, const void *b) +{ + Bucket *f; + Bucket *s; + pval *first; + pval *second; + double dfirst, dsecond; + + f = *((Bucket **) a); + s = *((Bucket **) b); + + first = *((pval **) f->pData); + second = *((pval **) s->pData); + + if ((first->type == IS_LONG || first->type == IS_DOUBLE) && + (second->type == IS_LONG || second->type == IS_DOUBLE)) { + if (first->type == IS_LONG) { + dfirst = (double) first->value.lval; + } else { + dfirst = first->value.dval; + } + if (second->type == IS_LONG) { + dsecond = (double) second->value.lval; + } else { + dsecond = second->value.dval; + } + if (dfirst < dsecond) { + return -1; + } else if (dfirst == dsecond) { + return 0; + } else { + return 1; + } + } + if ((first->type == IS_LONG || first->type == IS_DOUBLE) && + second->type == IS_STRING) { + return -1; + } else if ((first->type == IS_STRING) && + (second->type == IS_LONG || second->type == IS_DOUBLE)) { + return 1; + } + if (first->type == IS_STRING && second->type == IS_STRING) { + return strcmp(first->value.str.val, second->value.str.val); + } + return 0; /* Anything else is equal as it can't be compared */ +} + +static int array_reverse_data_compare(const void *a, const void *b) +{ + return array_data_compare(a,b)*-1; +} + +void php3_asort(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array; + HashTable *target_hash; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Wrong datatype in asort() call"); + return; + } + if (!ParameterPassedByReference(ht,1)) { + php3_error(E_WARNING, "Array not passed by reference in call to asort()"); + return; + } + if (_php3_hash_sort(target_hash, array_data_compare,0) == FAILURE) { + return; + } + RETURN_TRUE; +} + +void php3_arsort(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array; + HashTable *target_hash; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Wrong datatype in arsort() call"); + return; + } + if (!ParameterPassedByReference(ht,1)) { + php3_error(E_WARNING, "Array not passed by reference in call to arsort()"); + return; + } + if (_php3_hash_sort(target_hash, array_reverse_data_compare,0) == FAILURE) { + return; + } + RETURN_TRUE; +} + +void php3_sort(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array; + HashTable *target_hash; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Wrong datatype in sort() call"); + return; + } + if (!ParameterPassedByReference(ht,1)) { + php3_error(E_WARNING, "Array not passed by reference in call to sort()"); + return; + } + if (_php3_hash_sort(target_hash, array_data_compare,1) == FAILURE) { + return; + } + RETURN_TRUE; +} + +void php3_rsort(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array; + HashTable *target_hash; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Wrong datatype in rsort() call"); + return; + } + if (!ParameterPassedByReference(ht,1)) { + php3_error(E_WARNING, "Array not passed by reference in call to rsort()"); + return; + } + if (_php3_hash_sort(target_hash, array_reverse_data_compare,1) == FAILURE) { + return; + } + RETURN_TRUE; +} + + +static int array_user_compare(const void *a, const void *b) +{ + Bucket *f; + Bucket *s; + pval *args[2]; + pval retval; + CLS_FETCH(); + + f = *((Bucket **) a); + s = *((Bucket **) b); + + args[0] = (pval *) f->pData; + args[1] = (pval *) s->pData; + + if (call_user_function(CG(function_table), NULL, user_compare_func_name, &retval, 2, args)==SUCCESS) { + convert_to_long(&retval); + return retval.value.lval; + } else { + return 0; + } +} + + +void php3_user_sort(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array; + pval *old_compare_func; + HashTable *target_hash; + TLS_VARS; + + old_compare_func = user_compare_func_name; + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &array, &user_compare_func_name) == FAILURE) { + user_compare_func_name = old_compare_func; + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Wrong datatype in usort() call"); + user_compare_func_name = old_compare_func; + return; + } + convert_to_string(user_compare_func_name); + if (_php3_hash_sort(target_hash, array_user_compare, 1) == FAILURE) { + user_compare_func_name = old_compare_func; + return; + } + user_compare_func_name = old_compare_func; + RETURN_TRUE; +} + +void php3_auser_sort(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array; + pval *old_compare_func; + HashTable *target_hash; + TLS_VARS; + + old_compare_func = user_compare_func_name; + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &array, &user_compare_func_name) == FAILURE) { + user_compare_func_name = old_compare_func; + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Wrong datatype in uasort() call"); + user_compare_func_name = old_compare_func; + return; + } + convert_to_string(user_compare_func_name); + if (_php3_hash_sort(target_hash, array_user_compare, 0) == FAILURE) { + user_compare_func_name = old_compare_func; + return; + } + user_compare_func_name = old_compare_func; + RETURN_TRUE; +} + + +static int array_user_key_compare(const void *a, const void *b) +{ + Bucket *f; + Bucket *s; + pval key1, key2; + pval *args[2]; + pval retval; + int status; + CLS_FETCH(); + + args[0] = &key1; + args[1] = &key2; + + f = *((Bucket **) a); + s = *((Bucket **) b); + + if (f->arKey) { + key1.value.str.val = estrndup(f->arKey, f->nKeyLength); + key1.value.str.len = f->nKeyLength; + key1.type = IS_STRING; + } else { + key1.value.lval = f->h; + key1.type = IS_LONG; + } + if (s->arKey) { + key2.value.str.val = estrndup(s->arKey, s->nKeyLength); + key2.value.str.len = s->nKeyLength; + key2.type = IS_STRING; + } else { + key2.value.lval = s->h; + key2.type = IS_LONG; + } + + status = call_user_function(CG(function_table), NULL, user_compare_func_name, &retval, 2, args); + + pval_destructor(&key1); + pval_destructor(&key2); + + if (status==SUCCESS) { + convert_to_long(&retval); + return retval.value.lval; + } else { + return 0; + } +} + + +void php3_user_key_sort(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array; + pval *old_compare_func; + HashTable *target_hash; + TLS_VARS; + + old_compare_func = user_compare_func_name; + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &array, &user_compare_func_name) == FAILURE) { + user_compare_func_name = old_compare_func; + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Wrong datatype in uksort() call"); + user_compare_func_name = old_compare_func; + return; + } + convert_to_string(user_compare_func_name); + if (_php3_hash_sort(target_hash, array_user_key_compare, 0) == FAILURE) { + user_compare_func_name = old_compare_func; + return; + } + user_compare_func_name = old_compare_func; + RETURN_TRUE; +} + + +void array_end(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array, **entry; + HashTable *target_hash; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Variable passed to end() is not an array or object"); + return; + } + if (!ParameterPassedByReference(ht,1)) { + php3_error(E_WARNING, "Array not passed by reference in call to end()"); + } + _php3_hash_internal_pointer_end(target_hash); + if (_php3_hash_get_current_data(target_hash, (void **) &entry) == FAILURE) { + RETURN_FALSE; + } + *return_value = **entry; + pval_copy_constructor(return_value); +} + + +void array_prev(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array, **entry; + HashTable *target_hash; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Variable passed to prev() is not an array or object"); + RETURN_FALSE; + } + _php3_hash_move_backwards(target_hash); + if (_php3_hash_get_current_data(target_hash, (void **) &entry) == FAILURE) { + RETURN_FALSE; + } + + *return_value = **entry; + pval_copy_constructor(return_value); +} + + +void array_next(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array, **entry; + HashTable *target_hash; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Variable passed to next() is not an array or object"); + RETURN_FALSE; + } + _php3_hash_move_forward(target_hash); + if (_php3_hash_get_current_data(target_hash, (void **) &entry) == FAILURE) { + RETURN_FALSE; + } + + *return_value = **entry; + pval_copy_constructor(return_value); +} + + +void array_each(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array,*entry,**entry_ptr, *tmp; + char *string_key; + ulong num_key; + pval **inserted_pointer; + HashTable *target_hash; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING,"Variable passed to each() is not an array or object"); + return; + } + if (_php3_hash_get_current_data(target_hash, (void **) &entry_ptr)==FAILURE) { + RETURN_FALSE; + } + array_init(return_value); + entry = *entry_ptr; + + /* add value elements */ + if (entry->is_ref) { + tmp = (pval *)emalloc(sizeof(pval)); + *tmp = *entry; + pval_copy_constructor(tmp); + tmp->is_ref=0; + tmp->refcount=0; + entry=tmp; + } + _php3_hash_index_update(return_value->value.ht, 1, &entry, sizeof(pval *), NULL); + entry->refcount++; + _php3_hash_update_ptr(return_value->value.ht, "value", sizeof("value"), entry, sizeof(pval *), NULL); + entry->refcount++; + + /* add the key elements */ + switch (_php3_hash_get_current_key(target_hash, &string_key, &num_key)) { + case HASH_KEY_IS_STRING: + add_get_index_string(return_value,0,string_key,(void **) &inserted_pointer,0); + break; + case HASH_KEY_IS_LONG: + add_get_index_long(return_value,0,num_key, (void **) &inserted_pointer); + break; + } + _php3_hash_update(return_value->value.ht, "key", sizeof("key"), inserted_pointer, sizeof(pval *), NULL); + (*inserted_pointer)->refcount++; + _php3_hash_move_forward(target_hash); +} + + +void array_reset(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array, **entry; + HashTable *target_hash; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Variable passed to reset() is not an array or object"); + return; + } + _php3_hash_internal_pointer_reset(target_hash); + if (_php3_hash_get_current_data(target_hash, (void **) &entry) == FAILURE) { + return; + } + + *return_value = **entry; + pval_copy_constructor(return_value); + return_value->refcount=1; + return_value->is_ref=0; +} + +void array_current(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array, **entry; + HashTable *target_hash; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Variable passed to current() is not an array or object"); + return; + } + if (_php3_hash_get_current_data(target_hash, (void **) &entry) == FAILURE) { + return; + } + *return_value = **entry; + pval_copy_constructor(return_value); +} + + +void array_current_key(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *array; + char *string_key; + ulong num_key; + HashTable *target_hash; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Variable passed to key() is not an array or object"); + return; + } + if (!ParameterPassedByReference(ht,1)) { + php3_error(E_WARNING, "Array not passed by reference in call to key()"); + } + switch (_php3_hash_get_current_key(target_hash, &string_key, &num_key)) { + case HASH_KEY_IS_STRING: + return_value->value.str.val = string_key; + return_value->value.str.len = strlen(string_key); + return_value->type = IS_STRING; + break; + case HASH_KEY_IS_LONG: + return_value->type = IS_LONG; + return_value->value.lval = num_key; + break; + case HASH_KEY_NON_EXISTANT: + return; + } +} + +#ifdef __cplusplus +void php3_flush(HashTable *) +#else +void php3_flush(INTERNAL_FUNCTION_PARAMETERS) +#endif +{ +#if APACHE + TLS_VARS; +# if MODULE_MAGIC_NUMBER > 19970110 + rflush(GLOBAL(php3_rqst)); +# else + bflush(GLOBAL(php3_rqst)->connection->client); +# endif +#endif +#if FHTTPD + /*FIXME -- what does it flush really? the whole response?*/ +#endif +#if CGI_BINARY + fflush(stdout); +#endif +#if USE_SAPI + TLS_VARS; + GLOBAL(sapi_rqst)->flush(GLOBAL(sapi_rqst)->scid); +#endif +} + + +void php3_sleep(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(num); + sleep(num->value.lval); +} + +void php3_usleep(INTERNAL_FUNCTION_PARAMETERS) +{ +#if HAVE_USLEEP + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(num); + usleep(num->value.lval); +#endif +} + +void php3_gettype(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + switch (arg->type) { + case IS_LONG: + RETVAL_STRING("integer",1); + break; + case IS_DOUBLE: + RETVAL_STRING("double",1); + break; + case IS_STRING: + RETVAL_STRING("string",1); + break; + case IS_ARRAY: + RETVAL_STRING("array",1); + break; + case IS_OBJECT: { + char *result; + int res_len; + + res_len = sizeof("object of type ")-1 + arg->value.obj.ce->name_length; + result = (char *) emalloc(res_len+1); + sprintf(result, "object of type %s", arg->value.obj.ce->name); + RETVAL_STRINGL(result, res_len, 0); + } + break; + default: + RETVAL_STRING("unknown type",1); + } +} + + +void php3_settype(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *var, *type; + char *new_type; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &var, &type) == + FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(type); + new_type = type->value.str.val; + + if (!strcasecmp(new_type, "integer")) { + convert_to_long(var); + } else if (!strcasecmp(new_type, "double")) { + convert_to_double(var); + } else if (!strcasecmp(new_type, "string")) { + convert_to_string(var); + } else if (!strcasecmp(new_type, "array")) { + convert_to_array(var); + } else if (!strcasecmp(new_type, "object")) { + convert_to_object(var); + } else { + php3_error(E_WARNING, "settype: invalid type"); + RETURN_FALSE; + } + RETVAL_TRUE; +} + + +void php3_min(INTERNAL_FUNCTION_PARAMETERS) +{ + int argc=ARG_COUNT(ht); + pval **result; + + if (argc<=0) { + php3_error(E_WARNING, "min: must be passed at least 1 value"); + var_uninit(return_value); + return; + } + if (argc == 1) { + pval *arr; + + if (getParameters(ht, 1, &arr) == FAILURE || + arr->type != IS_ARRAY) { + WRONG_PARAM_COUNT; + } + if (_php3_hash_minmax(arr->value.ht, array_data_compare, 0, (void **) &result)==SUCCESS) { + *return_value = **result; + pval_copy_constructor(return_value); + } else { + php3_error(E_WARNING, "min: array must contain at least 1 element"); + var_uninit(return_value); + } + } else { + if (_php3_hash_minmax(ht, array_data_compare, 0, (void **) &result)==SUCCESS) { + *return_value = **result; + pval_copy_constructor(return_value); + } + } +} + + +void php3_max(INTERNAL_FUNCTION_PARAMETERS) +{ + int argc=ARG_COUNT(ht); + pval **result; + + if (argc<=0) { + php3_error(E_WARNING, "max: must be passed at least 1 value"); + var_uninit(return_value); + return; + } + if (argc == 1) { + pval *arr; + + if (getParameters(ht, 1, &arr) == FAILURE || + arr->type != IS_ARRAY) { + WRONG_PARAM_COUNT; + } + if (_php3_hash_minmax(arr->value.ht, array_data_compare, 1, (void **) &result)==SUCCESS) { + *return_value = **result; + pval_copy_constructor(return_value); + } else { + php3_error(E_WARNING, "max: array must contain at least 1 element"); + var_uninit(return_value); + } + } else { + if (_php3_hash_minmax(ht, array_data_compare, 1, (void **) &result)==SUCCESS) { + *return_value = **result; + pval_copy_constructor(return_value); + } + } +} + +static pval *php3_array_walk_func_name; + +static int _php3_array_walk(const void *a) +{ + pval *args[1]; + pval retval; + CLS_FETCH(); + + args[0] = (pval *)a; + + call_user_function(CG(function_table), NULL, php3_array_walk_func_name, &retval, 1, args); + return 0; +} + +void php3_array_walk(INTERNAL_FUNCTION_PARAMETERS) { + pval *array, *old_walk_func_name; + HashTable *target_hash; + TLS_VARS; + + old_walk_func_name = php3_array_walk_func_name; + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &array, &php3_array_walk_func_name) == FAILURE) { + php3_array_walk_func_name = old_walk_func_name; + WRONG_PARAM_COUNT; + } + target_hash = HASH_OF(array); + if (!target_hash) { + php3_error(E_WARNING, "Wrong datatype in array_walk() call"); + php3_array_walk_func_name = old_walk_func_name; + return; + } + convert_to_string(php3_array_walk_func_name); + _php3_hash_apply(target_hash, (int (*)(void *))_php3_array_walk); + php3_array_walk_func_name = old_walk_func_name; + RETURN_TRUE; +} + +#if 0 +void php3_max(INTERNAL_FUNCTION_PARAMETERS) +{ + pval **argv; + int argc, i; + unsigned short max_type = IS_LONG; + TLS_VARS; + + argc = ARG_COUNT(ht); + /* if there is one parameter and this parameter is an array of + * 2 or more elements, use that array + */ + if (argc == 1) { + argv = (pval **)emalloc(sizeof(pval *) * argc); + if (getParametersArray(ht, argc, argv) == FAILURE || + argv[0]->type != IS_ARRAY) { + WRONG_PARAM_COUNT; + } + if (argv[0]->value.ht->nNumOfElements < 2) { + php3_error(E_WARNING, + "min: array must contain at least 2 elements"); + RETURN_FALSE; + } + /* replace the function parameters with the array */ + ht = argv[0]->value.ht; + argc = _php3_hash_num_elements(ht); + efree(argv); + } else if (argc < 2) { + WRONG_PARAM_COUNT; + } + argv = (pval **)emalloc(sizeof(pval *) * argc); + if (getParametersArray(ht, argc, argv) == FAILURE) { + efree(argv); + WRONG_PARAM_COUNT; + } + /* figure out what types to compare + * if the arguments contain a double, convert all of them to a double + * else convert all of them to long + */ + for (i = 0; i < argc; i++) { + if (argv[i]->type == IS_DOUBLE) { + max_type = IS_DOUBLE; + break; + } + } + if (max_type == IS_LONG) { + convert_to_long(argv[0]); + return_value->value.lval = argv[0]->value.lval; + for (i = 1; i < argc; i++) { + convert_to_long(argv[i]); + if (argv[i]->value.lval > return_value->value.lval) { + return_value->value.lval = argv[i]->value.lval; + } + } + } else { + convert_to_double(argv[0]); + return_value->value.dval = argv[0]->value.dval; + for (i = 1; i < argc; i++) { + convert_to_double(argv[i]); + if (argv[i]->value.dval > return_value->value.dval) { + return_value->value.dval = argv[i]->value.dval; + } + } + } + efree(argv); + return_value->type = max_type; +} +#endif + +void php3_get_current_user(INTERNAL_FUNCTION_PARAMETERS) +{ + TLS_VARS; + + RETURN_STRING(_php3_get_current_user(),1); +} + + +void php3_get_cfg_var(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *varname; + char *value; + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &varname)==FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(varname); + + if (cfg_get_string(varname->value.str.val,&value)==FAILURE) { + RETURN_FALSE; + } + RETURN_STRING(value,1); +} + +void php3_set_magic_quotes_runtime(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *new_setting; + PLS_FETCH(); + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &new_setting)==FAILURE) { + RETURN_FALSE; + } + convert_to_long(new_setting); + + PG(magic_quotes_runtime)=new_setting->value.lval; + RETURN_TRUE; +} + +void php3_get_magic_quotes_runtime(INTERNAL_FUNCTION_PARAMETERS) +{ + PLS_FETCH(); + + RETURN_LONG(PG(magic_quotes_runtime)); +} + +void php3_get_magic_quotes_gpc(INTERNAL_FUNCTION_PARAMETERS) +{ + PLS_FETCH(); + + RETURN_LONG(PG(magic_quotes_gpc)); +} + + +void php3_is_type(INTERNAL_FUNCTION_PARAMETERS,int type) +{ + pval *arg; + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &arg)==FAILURE) { + RETURN_FALSE; + } + if (arg->type == type) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} + + +void php3_is_long(INTERNAL_FUNCTION_PARAMETERS) { php3_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_LONG); } +void php3_is_double(INTERNAL_FUNCTION_PARAMETERS) { php3_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_DOUBLE); } +void php3_is_string(INTERNAL_FUNCTION_PARAMETERS) { php3_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_STRING); } +void php3_is_array(INTERNAL_FUNCTION_PARAMETERS) { php3_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_ARRAY); } +void php3_is_object(INTERNAL_FUNCTION_PARAMETERS) { php3_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_OBJECT); } + + +void php3_leak(INTERNAL_FUNCTION_PARAMETERS) +{ + int leakbytes=3; + pval *leak; + + if (ARG_COUNT(ht)>=1) { + if (getParameters(ht, 1, &leak)==SUCCESS) { + convert_to_long(leak); + leakbytes = leak->value.lval; + } + } + + emalloc(leakbytes); +} + +/* + 1st arg = error message + 2nd arg = error option + 3rd arg = optional parameters (email address or tcp address) + 4th arg = used for additional headers if email + + error options + 0 = send to php3_error_log (uses syslog or file depending on ini setting) + 1 = send via email to 3rd parameter 4th option = additional headers + 2 = send via tcp/ip to 3rd parameter (name or ip:port) + 3 = save to file in 3rd parameter +*/ + +void php3_error_log(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *string, *erropt = NULL, *option = NULL, *emailhead = NULL; + int opt_err = 0; + char *message, *opt=NULL, *headers=NULL; + TLS_VARS; + + switch(ARG_COUNT(ht)) { + case 1: + if (getParameters(ht,1,&string) == FAILURE) { + php3_error(E_WARNING,"Invalid argument 1 in error_log"); + RETURN_FALSE; + } + break; + case 2: + if (getParameters(ht,2,&string,&erropt) == FAILURE) { + php3_error(E_WARNING,"Invalid arguments in error_log"); + RETURN_FALSE; + } + convert_to_long(erropt); + opt_err=erropt->value.lval; + break; + case 3: + if (getParameters(ht,3,&string,&erropt,&option) == FAILURE){ + php3_error(E_WARNING,"Invalid arguments in error_log"); + RETURN_FALSE; + } + convert_to_long(erropt); + opt_err=erropt->value.lval; + convert_to_string(option); + opt=option->value.str.val; + break; + case 4: + if (getParameters(ht,4,&string,&erropt,&option,&emailhead) == FAILURE){ + php3_error(E_WARNING,"Invalid arguments in error_log"); + RETURN_FALSE; + } + break; + default: + WRONG_PARAM_COUNT; + } + + convert_to_string(string); + message=string->value.str.val; + if (erropt != NULL) { + convert_to_long(erropt); + opt_err=erropt->value.lval; + } + if (option != NULL) { + convert_to_string(option); + opt=option->value.str.val; + } + if (emailhead != NULL) { + convert_to_string(emailhead); + headers=emailhead->value.str.val; + } + + if (_php3_error_log(opt_err,message,opt,headers)==FAILURE) { + RETURN_FALSE; + } + + RETURN_TRUE; +} + +PHPAPI int _php3_error_log(int opt_err,char *message,char *opt,char *headers){ + FILE *logfile; + int issock=0, socketd=0;; + + switch(opt_err){ + case 1: /*send an email*/ + { +#if HAVE_SENDMAIL + if (!_php3_mail(opt,"PHP3 error_log message",message,headers)){ + return FAILURE; + } +#else + php3_error(E_WARNING,"Mail option not available!"); + return FAILURE; +#endif + } + break; + case 2: /*send to an address */ + php3_error(E_WARNING,"TCP/IP option not available!"); + return FAILURE; + break; + case 3: /*save to a file*/ + logfile=php3_fopen_wrapper(opt,"a", (IGNORE_URL|ENFORCE_SAFE_MODE), &issock, &socketd); + if(!logfile) { + php3_error(E_WARNING,"error_log: Unable to write to %s",opt); + return FAILURE; + } + fwrite(message,strlen(message),1,logfile); + fclose(logfile); + break; + default: + php3_log_err(message); + break; + } + return SUCCESS; +} + + +void php3_call_user_func(INTERNAL_FUNCTION_PARAMETERS) +{ + pval **params; + pval retval; + int arg_count=ARG_COUNT(ht); + CLS_FETCH(); + + if (arg_count<1) { + WRONG_PARAM_COUNT; + } + params = (pval **) emalloc(sizeof(pval)*arg_count); + + if (getParametersArray(ht, arg_count, params)==FAILURE) { + efree(params); + RETURN_FALSE; + } + convert_to_string(params[0]); + if (call_user_function(CG(function_table), NULL, params[0], &retval, arg_count-1, params+1)==SUCCESS) { + *return_value = retval; + } else { + php3_error(E_WARNING,"Unable to call %s() - function does not exist", params[0]->value.str.val); + } + efree(params); +} + + +void php3_call_user_method(INTERNAL_FUNCTION_PARAMETERS) +{ + pval **params; + pval retval; + int arg_count=ARG_COUNT(ht); + + if (arg_count<2) { + WRONG_PARAM_COUNT; + } + params = (pval **) emalloc(sizeof(pval)*arg_count); + + if (getParametersArray(ht, arg_count, params)==FAILURE) { + efree(params); + RETURN_FALSE; + } + if (params[1]->type != IS_OBJECT) { + php3_error(E_WARNING,"2nd argument is not an object\n"); + efree(params); + RETURN_FALSE; + } + convert_to_string(params[0]); + if (call_user_function(CG(function_table), params[1], params[0], &retval, arg_count-2, params+2)==SUCCESS) { + *return_value = retval; + } else { + php3_error(E_WARNING,"Unable to call %s() - function does not exist", params[0]->value.str.val); + } + efree(params); +} + + +void user_shutdown_function_dtor(pval *user_shutdown_function_name) +{ + pval retval; + CLS_FETCH(); + + if (call_user_function(CG(function_table), NULL, user_shutdown_function_name, &retval, 0, NULL)==SUCCESS) { + pval_destructor(&retval); + } + pval_destructor(user_shutdown_function_name); +} + + +void php3_call_shutdown_functions(void) +{ + if (user_shutdown_function_names) { + _php3_hash_destroy(user_shutdown_function_names); + efree(user_shutdown_function_names); + } +} + +/* {{{ proto void register_shutdown_function(string function_name) + Register a user-level function to be called on request termination */ +PHP_FUNCTION(register_shutdown_function) +{ + pval *arg, shutdown_function_name; + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &arg)==FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(arg); + if (!user_shutdown_function_names) { + user_shutdown_function_names = (HashTable *) emalloc(sizeof(HashTable)); + _php3_hash_init(user_shutdown_function_names, 0, NULL, (void (*)(void *))user_shutdown_function_dtor, 0); + } + + shutdown_function_name = *arg; + pval_copy_constructor(&shutdown_function_name); + + _php3_hash_next_index_insert(user_shutdown_function_names, &shutdown_function_name, sizeof(pval), NULL); +} +/* }}} */ + + +void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highlighter_ini) +{ + syntax_highlighter_ini->highlight_comment = INI_STR("highlight_comment"); + syntax_highlighter_ini->highlight_default = INI_STR("highlight_default"); + syntax_highlighter_ini->highlight_html = INI_STR("highlight_html"); + syntax_highlighter_ini->highlight_keyword = INI_STR("highlight_keyword"); + syntax_highlighter_ini->highlight_string = INI_STR("highlight_string"); +} + + +/* {{{ proto void highlight_file(string file_name) + Syntax highlight a source file */ +PHP_FUNCTION(highlight_file) +{ + pval *filename; + zend_syntax_highlighter_ini syntax_highlighter_ini; + + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &filename)==FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(filename); + + php_get_highlight_struct(&syntax_highlighter_ini); + + if (highlight_file(filename->value.str.val, &syntax_highlighter_ini)==FAILURE) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + + +/* {{{ proto void highlight_file(string file_name) + Syntax highlight a source file */ +PHP_FUNCTION(highlight_string) +{ + pval *expr; + zend_syntax_highlighter_ini syntax_highlighter_ini; + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &expr)==FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(expr); + + php_get_highlight_struct(&syntax_highlighter_ini); + + if (highlight_string(expr, &syntax_highlighter_ini)==FAILURE) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + + +pval test_class_get_property(zend_property_reference *property_reference) +{ + pval result; + zend_overloaded_element *overloaded_property; + zend_llist_element *element; + + + printf("Reading a property from a TestClass object:\n"); + + for (element=property_reference->elements_list.head; element; element=element->next) { + overloaded_property = (zend_overloaded_element *) element->data; + switch (overloaded_property->type) { + case IS_ARRAY: + printf("Array offset: "); + break; + case IS_OBJECT: + printf("Object property: "); + break; + } + switch (overloaded_property->element.type) { + case IS_LONG: + printf("%d (numeric)\n", overloaded_property->element.value.lval); + break; + case IS_STRING: + printf("'%s'\n", overloaded_property->element.value.str.val); + break; + } + pval_destructor(&overloaded_property->element); + } + + result.value.str.val = estrndup("testing", 7); + result.value.str.len = 7; + result.type = IS_STRING; + return result; +} + + +int test_class_set_property(zend_property_reference *property_reference, pval *value) +{ + zend_overloaded_element *overloaded_property; + zend_llist_element *element; + + printf("Writing to a property from a TestClass object:\n"); + printf("Writing '"); + zend_print_variable(value); + printf("'\n"); + + for (element=property_reference->elements_list.head; element; element=element->next) { + overloaded_property = (zend_overloaded_element *) element->data; + switch (overloaded_property->type) { + case IS_ARRAY: + printf("Array offset: "); + break; + case IS_OBJECT: + printf("Object property: "); + break; + } + switch (overloaded_property->element.type) { + case IS_LONG: + printf("%d (numeric)\n", overloaded_property->element.value.lval); + break; + case IS_STRING: + printf("'%s'\n", overloaded_property->element.value.str.val); + break; + } + pval_destructor(&overloaded_property->element); + } + + return 0; +} + + + +void test_class_call_function(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference) +{ + zend_overloaded_element *overloaded_property; + zend_llist_element *element; + + + printf("Reading a property from a TestClass object:\n"); + + for (element=property_reference->elements_list.head; element; element=element->next) { + overloaded_property = (zend_overloaded_element *) element->data; + switch (overloaded_property->type) { + case IS_ARRAY: + printf("Array offset: "); + break; + case IS_OBJECT: + printf("Object property: "); + break; + case IS_METHOD: + printf("Overloaded method: "); + } + switch (overloaded_property->element.type) { + case IS_LONG: + printf("%d (numeric)\n", overloaded_property->element.value.lval); + break; + case IS_STRING: + printf("'%s'\n", overloaded_property->element.value.str.val); + break; + } + pval_destructor(&overloaded_property->element); + } + + printf("%d arguments\n", zend_hash_num_elements(ht)); + return_value->value.str.val = estrndup("testing", 7); + return_value->value.str.len = 7; + return_value->type = IS_STRING; +} + + +void test_class_startup() +{ + zend_class_entry class_entry; + + class_entry.name = strdup("TestClass"); + class_entry.name_length = sizeof("TestClass")-1; + + class_entry.handle_property_get = test_class_get_property; + class_entry.handle_property_set = test_class_set_property; + class_entry.handle_function_call = test_class_call_function; + register_internal_class(&class_entry); +} + + +PHP_FUNCTION(ob_start) +{ + zend_start_ob_buffering(); +} + + +PHP_FUNCTION(ob_end_flush) +{ + zend_end_ob_buffering(1); +} + + +PHP_FUNCTION(ob_end_clean) +{ + zend_end_ob_buffering(0); +} + + +PHP_FUNCTION(ob_get_contents) +{ + if (zend_ob_get_buffer(return_value)==FAILURE) { + RETURN_FALSE; + } +} + + +PHP_FUNCTION(ini_get) +{ + pval *varname; + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &varname)==FAILURE) { + WRONG_PARAM_COUNT; + } + + return_value->value.str.val = php_ini_string(varname->value.str.val, varname->value.str.len+1, 0); + + if (!return_value->value.str.val) { + RETURN_FALSE; + } + + return_value->value.str.len = strlen(return_value->value.str.val); + return_value->type = IS_STRING; + pval_copy_constructor(return_value); +} + + +PHP_FUNCTION(ini_alter) +{ + pval *varname, *new_value; + char *old_value; + + if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &varname, &new_value)==FAILURE) { + WRONG_PARAM_COUNT; + } + + old_value = php_ini_string(varname->value.str.val, varname->value.str.len+1, 0); + + + convert_to_string(new_value); + + if (php_alter_ini_entry(varname->value.str.val, varname->value.str.len+1, new_value->value.str.val, new_value->value.str.len, PHP_INI_USER)==FAILURE) { + RETURN_FALSE; + } + if (old_value) { + RETURN_STRING(old_value, 1); + } else { + RETURN_FALSE; + } +} + + + +PHP_FUNCTION(ini_restore) +{ + pval *varname; + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &varname)==FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(varname); + + php_restore_ini_entry(varname->value.str.val, varname->value.str.len); +} + + +PHP_FUNCTION(print_r) +{ + pval *expr; + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &expr)==FAILURE) { + WRONG_PARAM_COUNT; + } + + zend_print_pval_r(expr, 0); + RETURN_TRUE; +} + + +/* This should go back to PHP */ +PHP_FUNCTION(define) +{ + pval *var, *val, *non_cs; + int case_sensitive; + zend_constant c; + + switch(ARG_COUNT(ht)) { + case 2: + if (getParameters(ht, 2, &var, &val)==FAILURE) { + RETURN_FALSE; + } + case_sensitive = CONST_CS; + break; + case 3: + if (getParameters(ht, 3, &var, &val, &non_cs)==FAILURE) { + RETURN_FALSE; + } + convert_to_long(non_cs); + if (non_cs->value.lval) { + case_sensitive = 0; + } else { + case_sensitive = CONST_CS; + } + break; + default: + WRONG_PARAM_COUNT; + break; + } + switch(val->type) { + case IS_LONG: + case IS_DOUBLE: + case IS_STRING: + break; + default: + php3_error(E_WARNING,"Constants may only evaluate to scalar values"); + RETURN_FALSE; + break; + } + convert_to_string(var); + + c.value = *val; + pval_copy_constructor(&c.value); + c.flags = case_sensitive | ~CONST_PERSISTENT; /* non persistent */ + c.name = php3_strndup(var->value.str.val, var->value.str.len); + c.name_len = var->value.str.len+1; + zend_register_constant(&c); + RETURN_TRUE; +} + + +PHP_FUNCTION(defined) +{ + pval *var; + pval c; + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &var)==FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(var); + if (zend_get_constant(var->value.str.val, var->value.str.len, &c)) { + pval_destructor(&c); + RETURN_LONG(1); + } else { + RETURN_LONG(0); + } +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h new file mode 100644 index 0000000000..4a1e0bcec9 --- /dev/null +++ b/ext/standard/basic_functions.h @@ -0,0 +1,130 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Andi Gutmans <andi@zend.com> | + | Zeev Suraski <zeev@zend.com> | + +----------------------------------------------------------------------+ + */ + + +/* $Id$ */ + +#ifndef _BASIC_FUNCTIONS_H +#define _BASIC_FUNCTIONS_H + +#include "zend_highlight.h" + +extern php3_module_entry basic_functions_module; +#define basic_functions_module_ptr &basic_functions_module + +extern int php3_minit_basic(INIT_FUNC_ARGS); +extern int php3_mshutdown_basic(SHUTDOWN_FUNC_ARGS); +extern int php3_rinit_basic(INIT_FUNC_ARGS); +extern int php3_rshutdown_basic(SHUTDOWN_FUNC_ARGS); +extern void int_value(INTERNAL_FUNCTION_PARAMETERS); +extern void double_value(INTERNAL_FUNCTION_PARAMETERS); +extern void string_value(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_toggle_short_open_tag(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_sleep(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_usleep(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_key_sort(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_asort(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_arsort(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_sort(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_rsort(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_user_sort(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_auser_sort(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_user_key_sort(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_array_walk(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_count(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_flush(INTERNAL_FUNCTION_PARAMETERS); +extern void array_end(INTERNAL_FUNCTION_PARAMETERS); +extern void array_prev(INTERNAL_FUNCTION_PARAMETERS); +extern void array_next(INTERNAL_FUNCTION_PARAMETERS); +extern void array_each(INTERNAL_FUNCTION_PARAMETERS); +extern void array_reset(INTERNAL_FUNCTION_PARAMETERS); +extern void array_current(INTERNAL_FUNCTION_PARAMETERS); +extern void array_current_key(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_gettype(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_settype(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_min(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_max(INTERNAL_FUNCTION_PARAMETERS); + +/* system functions */ +extern void php3_getenv(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_putenv(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_error_reporting(INTERNAL_FUNCTION_PARAMETERS); + +extern void php3_get_current_user(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_set_time_limit(INTERNAL_FUNCTION_PARAMETERS); + +extern void php3_get_cfg_var(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_set_magic_quotes_runtime(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_get_magic_quotes_runtime(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_get_magic_quotes_gpc(INTERNAL_FUNCTION_PARAMETERS); + +extern void php3_is_type(INTERNAL_FUNCTION_PARAMETERS, int type); +extern void php3_is_long(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_is_double(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_is_string(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_is_array(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_is_object(INTERNAL_FUNCTION_PARAMETERS); + +extern void php3_leak(INTERNAL_FUNCTION_PARAMETERS); + +extern void php3_error_log(INTERNAL_FUNCTION_PARAMETERS); + +extern void php3_call_user_func(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_call_user_method(INTERNAL_FUNCTION_PARAMETERS); + +PHP_FUNCTION(register_shutdown_function); +PHP_FUNCTION(highlight_file); +PHP_FUNCTION(highlight_string); +void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highlighter_ini); + +PHP_FUNCTION(ob_start); +PHP_FUNCTION(ob_end_flush); +PHP_FUNCTION(ob_end_clean); +PHP_FUNCTION(ob_get_contents); + +PHP_FUNCTION(ini_get); +PHP_FUNCTION(ini_alter); +PHP_FUNCTION(ini_restore); + +PHP_FUNCTION(print_r); + +PHP_FUNCTION(define); +PHP_FUNCTION(defined); + +#if HAVE_PUTENV +typedef struct { + char *putenv_string; + char *previous_value; + char *key; + int key_len; +} putenv_entry; +#endif + +#endif /* _BASIC_FUNCTIONS_H */ diff --git a/ext/standard/browscap.c b/ext/standard/browscap.c new file mode 100644 index 0000000000..4045a698a1 --- /dev/null +++ b/ext/standard/browscap.c @@ -0,0 +1,137 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Zeev Suraski <zeev@zend.com> | + +----------------------------------------------------------------------+ + */ + +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include "php3_browscap.h" +#include "php_ini.h" + +#include "zend_globals.h" + +#ifndef THREAD_SAFE +HashTable browser_hash; +static char *lookup_browser_name; +static pval *found_browser_entry; +#endif + +function_entry browscap_functions[] = { + {"get_browser", php3_get_browser, NULL}, + {NULL, NULL, NULL} +}; + +php3_module_entry browscap_module_entry = { + "browscap", browscap_functions, php3_minit_browscap, php3_mshutdown_browscap, NULL, NULL, NULL, STANDARD_MODULE_PROPERTIES +}; + + +static int browser_reg_compare(pval *browser) +{ + pval *browser_name; + regex_t r; + TLS_VARS; + + if (GLOBAL(found_browser_entry)) { /* already found */ + return 0; + } + _php3_hash_find(browser->value.ht,"browser_name_pattern",sizeof("browser_name_pattern"),(void **) &browser_name); + if (!strchr(browser_name->value.str.val,'*')) { + return 0; + } + if (regcomp(&r,browser_name->value.str.val,REG_NOSUB)!=0) { + return 0; + } + if (regexec(&r,GLOBAL(lookup_browser_name),0,NULL,0)==0) { + GLOBAL(found_browser_entry) = browser; + } + regfree(&r); + return 0; +} + +void php3_get_browser(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *agent_name,*agent,tmp; + ELS_FETCH(); + + if (!INI_STR("browscap")) { + RETURN_FALSE; + } + + switch(ARG_COUNT(ht)) { + case 0: + if (_php3_hash_find(&EG(symbol_table), "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT"), (void **) &agent_name)==FAILURE) { + agent_name = &tmp; + var_reset(agent_name); + } + break; + case 1: + if (getParameters(ht, 1, &agent_name)==FAILURE) { + RETURN_FALSE; + } + break; + default: + WRONG_PARAM_COUNT; + break; + } + + convert_to_string(agent_name); + + if (_php3_hash_find(&GLOBAL(browser_hash), agent_name->value.str.val, agent_name->value.str.len+1, (void **) &agent)==FAILURE) { + GLOBAL(lookup_browser_name) = agent_name->value.str.val; + GLOBAL(found_browser_entry) = NULL; + _php3_hash_apply(&GLOBAL(browser_hash),(int (*)(void *)) browser_reg_compare); + + if (GLOBAL(found_browser_entry)) { + agent = GLOBAL(found_browser_entry); + } else if (_php3_hash_find(&GLOBAL(browser_hash), "Default Browser", sizeof("Default Browser"), (void **) &agent)==FAILURE) { + RETURN_FALSE; + } + } + + *return_value = *agent; + return_value->type = IS_OBJECT; + pval_copy_constructor(return_value); + return_value->value.ht->pDestructor = PVAL_DESTRUCTOR; + + while (_php3_hash_find(agent->value.ht, "parent", sizeof("parent"), (void **) &agent_name)==SUCCESS) { + if (_php3_hash_find(&GLOBAL(browser_hash), agent_name->value.str.val, agent_name->value.str.len+1, (void **) &agent)==FAILURE) { + break; + } + _php3_hash_merge(return_value->value.ht,agent->value.ht,(void (*)(void *pData)) pval_copy_constructor, (void *) &tmp, sizeof(pval)); + } +} + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 new file mode 100644 index 0000000000..f44a1df39f --- /dev/null +++ b/ext/standard/config.m4 @@ -0,0 +1,3 @@ +dnl $Id$ -*- sh -*- + +PHP_EXTENSION(standard) diff --git a/ext/standard/cyr_convert.c b/ext/standard/cyr_convert.c new file mode 100644 index 0000000000..5f36a479be --- /dev/null +++ b/ext/standard/cyr_convert.c @@ -0,0 +1,301 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Kirill Maximov (kir@rus.net | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#include <stdlib.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <string.h> +#include <errno.h> + +#include "php.h" +#include "cyr_convert.h" + +#include <stdio.h> + + + + +/***************************************************************************** +* This is codetables for different Cyrillic charsets (relative to koi8-r). +* Each table contains data for 128-255 symbols from ASCII table. +* First 256 symbols are for conversion from koi8-r to corresponding charset, +* second 256 symbols are for reverse conversion, from charset to koi8-r. +* +* Here we have the following tables: +* _cyr_win1251 - for windows-1251 charset +* _cyr_iso88595 - for iso8859-5 charset +* _cyr_cp866 - for x-cp866 charset +* _cyr_mac - for x-mac-cyrillic charset +* +*****************************************************************************/ + +typedef unsigned char _cyr_charset_table[512]; + +const static _cyr_charset_table _cyr_win1251 = { +0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, +16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, +32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, +48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, +64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, +80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, +96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, +46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46, +46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46, +46,46,46,46,46,46,46,46,179,46,32,46,46,46,46,32, +46,46,46,46,46,46,46,46,163,46,32,46,46,46,46,32, +225,226,247,231,228,229,246,250,233,234,235,236,237,238,239,240, +242,243,244,245,230,232,227,254,251,253,255,249,248,252,224,241, +193,194,215,199,196,197,214,218,201,202,203,204,205,206,207,208, +210,211,212,213,198,200,195,222,219,221,223,217,216,220,192,209, +0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, +16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, +32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, +48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, +64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, +80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, +96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,184,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,168,32,32,32,32,32,32,32,32,32,32,32,32, +254,224,225,246,228,229,244,227,245,232,233,234,235,236,237,238, +239,255,240,241,242,243,230,226,252,251,231,248,253,249,247,250, +222,192,193,214,196,197,212,195,213,200,201,202,203,204,205,206, +207,223,208,209,210,211,198,194,220,219,199,216,221,217,215,218, +}, +_cyr_cp866 = { +0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, +16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, +32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, +48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, +64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, +80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, +96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, +225,226,247,231,228,229,246,250,233,234,235,236,237,238,239,240, +242,243,244,245,230,232,227,254,251,253,255,249,248,252,224,241, +193,194,215,199,196,197,214,218,201,202,203,204,205,206,207,208, +35,35,35,124,124,124,124,43,43,124,124,43,43,43,43,43, +43,45,45,124,45,43,124,124,43,43,45,45,124,45,43,45, +45,45,45,43,43,43,43,43,43,43,43,35,35,124,124,35, +210,211,212,213,198,200,195,222,219,221,223,217,216,220,192,209, +179,163,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, +16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, +32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, +48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, +64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, +80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, +96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,241,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,240,32,32,32,32,32,32,32,32,32,32,32,32, +238,160,161,230,164,165,228,163,229,168,169,170,171,172,173,174, +175,239,224,225,226,227,166,162,236,235,167,232,237,233,231,234, +158,128,129,150,132,133,148,131,149,136,137,138,139,140,141,142, +143,159,144,145,146,147,134,130,156,155,135,152,157,153,151,154, +}, +_cyr_iso88595 = { +0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, +16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, +32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, +48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, +64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, +80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, +96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,179,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +225,226,247,231,228,229,246,250,233,234,235,236,237,238,239,240, +242,243,244,245,230,232,227,254,251,253,255,249,248,252,224,241, +193,194,215,199,196,197,214,218,201,202,203,204,205,206,207,208, +210,211,212,213,198,200,195,222,219,221,223,217,216,220,192,209, +32,163,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, +16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, +32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, +48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, +64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, +80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, +96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,241,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,161,32,32,32,32,32,32,32,32,32,32,32,32, +238,208,209,230,212,213,228,211,229,216,217,218,219,220,221,222, +223,239,224,225,226,227,214,210,236,235,215,232,237,233,231,234, +206,176,177,198,180,181,196,179,197,184,185,186,187,188,189,190, +191,207,192,193,194,195,182,178,204,203,183,200,205,201,199,202, +}, +_cyr_mac = { +0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, +16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, +32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, +48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, +64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, +80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, +96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, +225,226,247,231,228,229,246,250,233,234,235,236,237,238,239,240, +242,243,244,245,230,232,227,254,251,253,255,249,248,252,224,241, +160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, +176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, +128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, +144,145,146,147,148,149,150,151,152,153,154,155,156,179,163,209, +193,194,215,199,196,197,214,218,201,202,203,204,205,206,207,208, +210,211,212,213,198,200,195,222,219,221,223,217,216,220,192,255, +0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, +16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, +32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, +48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, +64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, +80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, +96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, +112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, +192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, +208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, +160,161,162,222,164,165,166,167,168,169,170,171,172,173,174,175, +176,177,178,221,180,181,182,183,184,185,186,187,188,189,190,191, +254,224,225,246,228,229,244,227,245,232,233,234,235,236,237,238, +239,223,240,241,242,243,230,226,252,251,231,248,253,249,247,250, +158,128,129,150,132,133,148,131,149,136,137,138,139,140,141,142, +143,159,144,145,146,147,134,130,156,155,135,152,157,153,151,154, +}; + + +/***************************************************************************** +* This is the function that performs real in-place conversion of the string +* between charsets. +* Parameters: +* str - string to be converted +* from,to - one-symbol label of source and destination charset +* The following symbols are used as labels: +* k - koi8-r +* w - windows-1251 +* i - iso8859-5 +* a - x-cp866 +* d - x-cp866 +* m - x-mac-cyrillic +*****************************************************************************/ +static char * _php3_convert_cyr_string(unsigned char *str, char from, char to) +{ + const unsigned char *from_table, *to_table; + unsigned char tmp; + int i; + + from_table = NULL; + to_table = NULL; + + switch (toupper(from)) + { + case 'W': + from_table = _cyr_win1251; + break; + case 'A': + case 'D': + from_table = _cyr_cp866; + break; + case 'I': + from_table = _cyr_iso88595; + break; + case 'M': + from_table = _cyr_mac; + break; + case 'K': + break; + default: + php3_error(E_WARNING, "Unknown source charset: %c", from); + break; + } + + switch (toupper(to)) + { + case 'W': + to_table = _cyr_win1251; + break; + case 'A': + case 'D': + to_table = _cyr_cp866; + break; + case 'I': + to_table = _cyr_iso88595; + break; + case 'M': + to_table = _cyr_mac; + break; + case 'K': + break; + default: + php3_error(E_WARNING, "Unknown destination charset: %c", to); + break; + } + + + if (!str) + return (char *)str; + + for( i = 0; str[i]; i++) + { + tmp = (from_table == NULL)? str[i] : from_table[ str[i] ]; + str[i] = (to_table == NULL) ? tmp : to_table[tmp + 256]; + } + return (char *)str; +} + +/* {{{ proto string convert_cyr_string(string str, string from, string to) + Convert from one Cyrillic character set to another */ +void php3_convert_cyr_string(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str_arg, *fr_cs, *to_cs; + unsigned char *str; + + if (ARG_COUNT(ht) != 3 || getParameters(ht,3,&str_arg, &fr_cs, &to_cs)==FAILURE) + { + WRONG_PARAM_COUNT; + } + convert_to_string(str_arg); + convert_to_string(fr_cs); + convert_to_string(to_cs); + + str = (unsigned char*) str_arg->value.str.val; + + _php3_convert_cyr_string(str, fr_cs->value.str.val[0], to_cs->value.str.val[0]); + RETVAL_STRING((char *)str, 1) +} +/* }}} */ diff --git a/ext/standard/cyr_convert.h b/ext/standard/cyr_convert.h new file mode 100644 index 0000000000..c7ac46143e --- /dev/null +++ b/ext/standard/cyr_convert.h @@ -0,0 +1,40 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Kirill Maximov (kir@rus.net) | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifndef _CYR_CONVERT_H +#define _CYR_CONVERT_H + +extern void php3_convert_cyr_string(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _CYR_CONVERT_H */ + + + diff --git a/ext/standard/datetime.c b/ext/standard/datetime.c new file mode 100644 index 0000000000..3c82fe0918 --- /dev/null +++ b/ext/standard/datetime.c @@ -0,0 +1,510 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Andi Gutmans <andi@zend.com> | + | Zeev Suraski <zeev@zend.com> | + | Rasmus Lerdorf <rasmus@php.net> | + +----------------------------------------------------------------------+ + */ + + +/* $Id$ */ + + +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include "zend_operators.h" +#include "datetime.h" +#include "snprintf.h" +#include "php_globals.h" + +#include <time.h> +#include <stdio.h> + +char *mon_full_names[] = +{ + "January", "February", "March", "April", + "May", "June", "July", "August", + "September", "October", "November", "December" +}; +char *mon_short_names[] = +{ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; +char *day_full_names[] = +{ + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" +}; +char *day_short_names[] = +{ + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; + +#ifndef HAVE_TM_ZONE +#ifndef _TIMEZONE +extern time_t timezone; +#endif +#endif + +static int phpday_tab[2][12] = +{ + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} +}; + +void php3_time(INTERNAL_FUNCTION_PARAMETERS) +{ + return_value->value.lval = (long) time(NULL); + return_value->type = IS_LONG; +} + +void _php3_mktime(INTERNAL_FUNCTION_PARAMETERS, int gm) +{ + pval *arguments[6]; + struct tm ta, *tn; + time_t t; + int i, gmadjust=0,arg_count = ARG_COUNT(ht); + + if (arg_count > 6 || getParametersArray(ht, arg_count, arguments) == FAILURE) { + WRONG_PARAM_COUNT; + } + /* convert supplied arguments to longs */ + for (i = 0; i < arg_count; i++) { + convert_to_long(arguments[i]); + } + t=time(NULL); + if (gm) { + tn = gmtime(&t); +#if HAVE_TZSET + tzset(); +#if HAVE_TM_ZONE + gmadjust=(tn->tm_gmtoff)/3600; +#else + gmadjust=timezone/3600; +#endif +#endif + } else { + tn = localtime(&t); + } + memcpy(&ta,tn,sizeof(struct tm)); + ta.tm_isdst = -1; + + switch(arg_count) { + case 6: + ta.tm_year = arguments[5]->value.lval - ((arguments[5]->value.lval > 1000) ? 1900 : 0); + /* fall-through */ + case 5: + ta.tm_mday = arguments[4]->value.lval; + /* fall-through */ + case 4: + ta.tm_mon = arguments[3]->value.lval - 1; + /* fall-through */ + case 3: + ta.tm_sec = arguments[2]->value.lval; + /* fall-through */ + case 2: + ta.tm_min = arguments[1]->value.lval; + /* fall-through */ + case 1: + ta.tm_hour = arguments[0]->value.lval - gmadjust; + case 0: + break; + } + return_value->value.lval = mktime(&ta); + return_value->type = IS_LONG; +} + +void php3_mktime(INTERNAL_FUNCTION_PARAMETERS) +{ + _php3_mktime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} + +void php3_gmmktime(INTERNAL_FUNCTION_PARAMETERS) +{ + _php3_mktime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} + +static void +_php3_date(INTERNAL_FUNCTION_PARAMETERS, int gm) +{ + pval *format, *timestamp; + time_t the_time; + struct tm *ta; + int i, size = 0, length, h; + char tmp_buff[16]; + TLS_VARS; + + switch(ARG_COUNT(ht)) { + case 1: + if (getParameters(ht, 1, &format) == FAILURE) { + WRONG_PARAM_COUNT; + } + the_time = time(NULL); + break; + case 2: + if (getParameters(ht, 2, &format, ×tamp) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(timestamp); + the_time = timestamp->value.lval; + break; + default: + WRONG_PARAM_COUNT; + } + convert_to_string(format); + + if (gm) { + ta = gmtime(&the_time); + } else { + ta = localtime(&the_time); + } + + if (!ta) { /* that really shouldn't happen... */ + php3_error(E_WARNING, "unexpected error in date()"); + RETURN_FALSE; + } + for (i = 0; i < format->value.str.len; i++) { + switch (format->value.str.val[i]) { + case 'U': /* seconds since the epoch */ + size += 10; + break; + case 'F': /* month, textual, full */ + case 'l': /* day (of the week), textual */ + size += 9; + break; + case 'Y': /* year, numeric, 4 digits */ + size += 4; + break; + case 'M': /* month, textual, 3 letters */ + case 'D': /* day, textual, 3 letters */ + case 'z': /* day of the year */ + size += 3; + break; + case 'y': /* year, numeric, 2 digits */ + case 'm': /* month, numeric */ + case 'd': /* day of the month, numeric */ + case 'j': /* day of the month, numeric, no leading zeros */ + case 'H': /* hour, numeric, 24 hour format */ + case 'h': /* hour, numeric, 12 hour format */ + case 'i': /* minutes, numeric */ + case 's': /* seconds, numeric */ + case 'A': /* AM/PM */ + case 'a': /* am/pm */ + case 'S': /* standard english suffix for the day of the month (e.g. 3rd, 2nd, etc) */ + size += 2; + break; + case '\\': + if(i < format->value.str.len-1) { + i++; + } + case 'w': /* day of the week, numeric */ + default: + size++; + break; + } + } + + return_value->value.str.val = (char *) emalloc(size + 1); + return_value->value.str.val[0] = '\0'; + + for (i = 0; i < format->value.str.len; i++) { + switch (format->value.str.val[i]) { + case '\\': + if(i < format->value.str.len-1) { + char ch[2]; + ch[0]=format->value.str.val[i+1]; + ch[1]='\0'; + strcat(return_value->value.str.val, ch); + i++; + } + break; + case 'U': /* seconds since the epoch */ + sprintf(tmp_buff, "%ld", (long)the_time); /* SAFE */ + strcat(return_value->value.str.val, tmp_buff); + break; + case 'F': /* month, textual, full */ + strcat(return_value->value.str.val, mon_full_names[ta->tm_mon]); + break; + case 'l': /* day (of the week), textual, full */ + strcat(return_value->value.str.val, day_full_names[ta->tm_wday]); + break; + case 'Y': /* year, numeric, 4 digits */ + sprintf(tmp_buff, "%d", ta->tm_year + 1900); /* SAFE */ + strcat(return_value->value.str.val, tmp_buff); + break; + case 'M': /* month, textual, 3 letters */ + strcat(return_value->value.str.val, mon_short_names[ta->tm_mon]); + break; + case 'D': /* day (of the week), textual, 3 letters */ + strcat(return_value->value.str.val, day_short_names[ta->tm_wday]); + break; + case 'z': /* day (of the year) */ + sprintf(tmp_buff, "%d", ta->tm_yday); /* SAFE */ + strcat(return_value->value.str.val, tmp_buff); + break; + case 'y': /* year, numeric, 2 digits */ + sprintf(tmp_buff, "%02d", ((ta->tm_year)%100)); /* SAFE */ + strcat(return_value->value.str.val, tmp_buff); + break; + case 'm': /* month, numeric */ + sprintf(tmp_buff, "%02d", ta->tm_mon + 1); /* SAFE */ + strcat(return_value->value.str.val, tmp_buff); + break; + case 'd': /* day of the month, numeric */ + sprintf(tmp_buff, "%02d", ta->tm_mday); /* SAFE */ + strcat(return_value->value.str.val, tmp_buff); + break; + case 'j': + sprintf(tmp_buff, "%d", ta->tm_mday); /* SAFE */ + strcat(return_value->value.str.val, tmp_buff); + break; + case 'H': /* hour, numeric, 24 hour format */ + sprintf(tmp_buff, "%02d", ta->tm_hour); /* SAFE */ + strcat(return_value->value.str.val, tmp_buff); + break; + case 'h': /* hour, numeric, 12 hour format */ + h = ta->tm_hour % 12; if (h==0) h = 12; + sprintf(tmp_buff, "%02d", h); /* SAFE */ + strcat(return_value->value.str.val, tmp_buff); + break; + case 'i': /* minutes, numeric */ + sprintf(tmp_buff, "%02d", ta->tm_min); /* SAFE */ + strcat(return_value->value.str.val, tmp_buff); + break; + case 's': /* seconds, numeric */ + sprintf(tmp_buff, "%02d", ta->tm_sec); /* SAFE */ + strcat(return_value->value.str.val, tmp_buff); + break; + case 'A': /* AM/PM */ + strcat(return_value->value.str.val, (ta->tm_hour >= 12 ? "PM" : "AM")); + break; + case 'a': /* am/pm */ + strcat(return_value->value.str.val, (ta->tm_hour >= 12 ? "pm" : "am")); + break; + case 'S': /* standard english suffix, e.g. 2nd/3rd for the day of the month */ + if (ta->tm_mday >= 10 && ta->tm_mday <= 19) { + strcat(return_value->value.str.val, "th"); + } else { + switch (ta->tm_mday % 10) { + case 1: + strcat(return_value->value.str.val, "st"); + break; + case 2: + strcat(return_value->value.str.val, "nd"); + break; + case 3: + strcat(return_value->value.str.val, "rd"); + break; + default: + strcat(return_value->value.str.val, "th"); + break; + } + } + break; + case 'w': /* day of the week, numeric EXTENSION */ + sprintf(tmp_buff, "%01d", ta->tm_wday); /* SAFE */ + strcat(return_value->value.str.val, tmp_buff); + break; + default: + length = strlen(return_value->value.str.val); + return_value->value.str.val[length] = format->value.str.val[i]; + return_value->value.str.val[length + 1] = '\0'; + break; + } + } + return_value->value.str.len = strlen(return_value->value.str.val); + return_value->type = IS_STRING; +} + +void php3_date(INTERNAL_FUNCTION_PARAMETERS) +{ + _php3_date(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} + +void php3_gmdate(INTERNAL_FUNCTION_PARAMETERS) +{ + _php3_date(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} + +void php3_getdate(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *timestamp_arg; + struct tm *ta; + time_t timestamp; + + if (ARG_COUNT(ht) == 0) { + timestamp = time(NULL); + } else if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, ×tamp_arg) == FAILURE) { + WRONG_PARAM_COUNT; + } else { + convert_to_long(timestamp_arg); + timestamp = timestamp_arg->value.lval; + } + + ta = localtime(×tamp); + if (!ta) { + php3_error(E_WARNING, "Cannot perform date calculation"); + return; + } + if (array_init(return_value) == FAILURE) { + php3_error(E_ERROR, "Unable to initialize array"); + return; + } + add_assoc_long(return_value, "seconds", ta->tm_sec); + add_assoc_long(return_value, "minutes", ta->tm_min); + add_assoc_long(return_value, "hours", ta->tm_hour); + add_assoc_long(return_value, "mday", ta->tm_mday); + add_assoc_long(return_value, "wday", ta->tm_wday); + add_assoc_long(return_value, "mon", ta->tm_mon + 1); + add_assoc_long(return_value, "year", ta->tm_year + 1900); + add_assoc_long(return_value, "yday", ta->tm_yday); + add_assoc_string(return_value, "weekday", day_full_names[ta->tm_wday], 1); + add_assoc_string(return_value, "month", mon_full_names[ta->tm_mon], 1); + add_index_long(return_value, 0, timestamp); +} + +/* Return date string in standard format for http headers */ +char *php3_std_date(time_t t) +{ + struct tm *tm1; + char *str; + PLS_FETCH(); + + tm1 = gmtime(&t); + str = emalloc(81); + if (PG(y2k_compliance)) { + snprintf(str, 80, "%s, %02d-%s-%04d %02d:%02d:%02d GMT", + day_full_names[tm1->tm_wday], + tm1->tm_mday, + mon_short_names[tm1->tm_mon], + tm1->tm_year+1900, + tm1->tm_hour, tm1->tm_min, tm1->tm_sec); + } else { + snprintf(str, 80, "%s, %02d-%s-%02d %02d:%02d:%02d GMT", + day_full_names[tm1->tm_wday], + tm1->tm_mday, + mon_short_names[tm1->tm_mon], + ((tm1->tm_year)%100), + tm1->tm_hour, tm1->tm_min, tm1->tm_sec); + } + + str[79]=0; + return (str); +} + +/* + * CheckDate(month, day, year); + * returns True(1) if it is valid date + * + */ +#define isleap(year) (((year%4) == 0 && (year%100)!=0) || (year%400)==0) +void php3_checkdate(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *month, *day, *year; + int m, d, y; + TLS_VARS; + + if (ARG_COUNT(ht) != 3 || + getParameters(ht, 3, &month, &day, &year) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(day); + convert_to_long(month); + convert_to_long(year); + y = year->value.lval; + m = month->value.lval; + d = day->value.lval; + + if (y < 100) + y += 1900; + + if (y < 0 || y > 32767) { + RETURN_FALSE; + } + if (m < 1 || m > 12) { + RETURN_FALSE; + } + if (d < 1 || d > phpday_tab[isleap(y)][m - 1]) { + RETURN_FALSE; + } + RETURN_TRUE; /* True : This month,day,year arguments are valid */ +} + + +#if HAVE_STRFTIME + +void php3_strftime(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *format_arg, *timestamp_arg; + char *format,*buf; + time_t timestamp; + struct tm *ta; + size_t buf_len=64, real_len; + + switch (ARG_COUNT(ht)) { + case 1: + if (getParameters(ht, 1, &format_arg)==FAILURE) { + RETURN_FALSE; + } + time(×tamp); + break; + case 2: + if (getParameters(ht, 2, &format_arg, ×tamp_arg)==FAILURE) { + RETURN_FALSE; + } + convert_to_long(timestamp_arg); + timestamp = timestamp_arg->value.lval; + break; + default: + WRONG_PARAM_COUNT; + break; + } + + convert_to_string(format_arg); + if (format_arg->value.str.len==0) { + RETURN_FALSE; + } + format = format_arg->value.str.val; + ta = localtime(×tamp); + + buf = (char *) emalloc(buf_len); + while ((real_len=strftime(buf,buf_len,format,ta))==buf_len || real_len==0) { + buf_len *= 2; + buf = (char *) erealloc(buf, buf_len); + } + + return_value->value.str.val = (char *) erealloc(buf,real_len+1); + return_value->value.str.len = real_len; + return_value->type = IS_STRING; +} +#endif +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/datetime.h b/ext/standard/datetime.h new file mode 100644 index 0000000000..1cb6cf6723 --- /dev/null +++ b/ext/standard/datetime.h @@ -0,0 +1,51 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Andi Gutmans <andi@zend.com> | + | Zeev Suraski <zeev@zend.com> | + +----------------------------------------------------------------------+ + */ + + +/* $Id$ */ + +#ifndef _DATETIME_H +#define _DATETIME_H + +extern void php3_time(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_mktime(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_gmmktime(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_date(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_gmdate(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_getdate(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_checkdate(INTERNAL_FUNCTION_PARAMETERS); +#if HAVE_STRFTIME +extern void php3_strftime(INTERNAL_FUNCTION_PARAMETERS); +#endif + +extern char *php3_std_date(time_t t); +void _php3_mktime(INTERNAL_FUNCTION_PARAMETERS, int gm); + +#endif /* _DATETIME_H */ diff --git a/ext/standard/dir.c b/ext/standard/dir.c new file mode 100644 index 0000000000..1edd10d374 --- /dev/null +++ b/ext/standard/dir.c @@ -0,0 +1,287 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include "fopen-wrappers.h" + +#include "php3_dir.h" + +#if HAVE_DIRENT_H +#include <dirent.h> +#endif + +#if HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <errno.h> + +#if MSVC5 +#if !(APACHE) +#define NEEDRDH 1 +#endif +#include "win32/readdir.h" +#endif + +#ifndef THREAD_SAFE +static int dirp_id = 0; +static int le_dirp; +#endif + +function_entry php3_dir_functions[] = { + {"opendir", php3_opendir, NULL}, + {"closedir", php3_closedir, NULL}, + {"chdir", php3_chdir, NULL}, + {"rewinddir", php3_rewinddir, NULL}, + {"readdir", php3_readdir, NULL}, + {"dir", php3_getdir, NULL}, + {NULL, NULL, NULL} +}; + +php3_module_entry php3_dir_module_entry = { + "PHP_dir", php3_dir_functions, php3_minit_dir, NULL, NULL, NULL, NULL, STANDARD_MODULE_PROPERTIES +}; + + +int php3_minit_dir(INIT_FUNC_ARGS) +{ + TLS_VARS; + + GLOBAL(le_dirp) = register_list_destructors(closedir,NULL); + return SUCCESS; +} + +/* {{{ proto int opendir(string path) + Open a directory and return a dir_handle */ +void php3_opendir(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + DIR *dirp; + int ret; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + /* Check open_basedir */ + if (_php3_check_open_basedir(arg->value.str.val)) RETURN_FALSE; + + dirp = opendir(arg->value.str.val); + if (!dirp) { + php3_error(E_WARNING, "OpenDir: %s (errno %d)", strerror(errno),errno); + RETURN_FALSE; + } + ret = php3_list_insert(dirp, GLOBAL(le_dirp)); + GLOBAL(dirp_id) = ret; + RETURN_LONG(ret); +} +/* }}} */ + +/* {{{ proto void closedir([int dir_handle]) +Close directory connection identified by the dir_handle */ +void php3_closedir(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *id, *tmp; + int id_to_find; + DIR *dirp; + int dirp_type; + TLS_VARS; + + if (ARG_COUNT(ht) == 0) { + if (getThis(&id) == SUCCESS) { + if (_php3_hash_find(id->value.ht, "handle", sizeof("handle"), (void **)&tmp) == FAILURE) { + php3_error(E_WARNING, "unable to find my handle property"); + RETURN_FALSE; + } + id_to_find = tmp->value.lval; + } else { + id_to_find = GLOBAL(dirp_id); + } + } else if ((ARG_COUNT(ht) != 1) || getParameters(ht, 1, &id) == FAILURE) { + WRONG_PARAM_COUNT; + } else { + convert_to_long(id); + id_to_find = id->value.lval; + } + + dirp = (DIR *)php3_list_find(id_to_find, &dirp_type); + if (!dirp || dirp_type != GLOBAL(le_dirp)) { + php3_error(E_WARNING, "unable to find identifier (%d)", id_to_find); + RETURN_FALSE; + } + php3_list_delete(id_to_find); +} +/* }}} */ + +/* {{{ proto int chdir(string directory) +Change the current directory */ +void php3_chdir(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + int ret; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + ret = chdir(arg->value.str.val); + + if (ret < 0) { + php3_error(E_WARNING, "ChDir: %s (errno %d)", strerror(errno), errno); + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto void rewinddir([int dir_handle]) +Rewind dir_handle back to the start */ +void php3_rewinddir(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *id, *tmp; + int id_to_find; + DIR *dirp; + int dirp_type; + TLS_VARS; + + if (ARG_COUNT(ht) == 0) { + if (getThis(&id) == SUCCESS) { + if (_php3_hash_find(id->value.ht, "handle", sizeof("handle"), (void **)&tmp) == FAILURE) { + php3_error(E_WARNING, "unable to find my handle property"); + RETURN_FALSE; + } + id_to_find = tmp->value.lval; + } else { + id_to_find = GLOBAL(dirp_id); + } + } else if ((ARG_COUNT(ht) != 1) || getParameters(ht, 1, &id) == FAILURE) { + WRONG_PARAM_COUNT; + } else { + convert_to_long(id); + id_to_find = id->value.lval; + } + + dirp = (DIR *)php3_list_find(id_to_find, &dirp_type); + if (!dirp || dirp_type != GLOBAL(le_dirp)) { + php3_error(E_WARNING, "unable to find identifier (%d)", id_to_find); + RETURN_FALSE; + } + rewinddir(dirp); +} +/* }}} */ + +/* {{{ proto string readdir([int dir_handle]) +Read directory entry from dir_handle */ +void php3_readdir(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *id, *tmp; + int id_to_find; + DIR *dirp; + int dirp_type; + struct dirent *direntp; + TLS_VARS; + + if (ARG_COUNT(ht) == 0) { + if (getThis(&id) == SUCCESS) { + if (_php3_hash_find(id->value.ht, "handle", sizeof("handle"), (void **)&tmp) == FAILURE) { + php3_error(E_WARNING, "unable to find my handle property"); + RETURN_FALSE; + } + id_to_find = tmp->value.lval; + } else { + id_to_find = GLOBAL(dirp_id); + } + } else if ((ARG_COUNT(ht) != 1) || getParameters(ht, 1, &id) == FAILURE) { + WRONG_PARAM_COUNT; + } else { + convert_to_long(id); + id_to_find = id->value.lval; + } + + dirp = (DIR *)php3_list_find(id_to_find, &dirp_type); + if (!dirp || dirp_type != GLOBAL(le_dirp)) { + php3_error(E_WARNING, "unable to find identifier (%d)", id_to_find); + RETURN_FALSE; + } + direntp = readdir(dirp); + if (direntp) { + RETURN_STRINGL(direntp->d_name, strlen(direntp->d_name), 1); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto class dir(string directory) +Directory class with properties, handle and class and methods read, rewind and close */ +void php3_getdir(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg; + DIR *dirp; + int ret; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + /* Check open_basedir */ + if (_php3_check_open_basedir(arg->value.str.val)) RETURN_FALSE; + + dirp = opendir(arg->value.str.val); + if (!dirp) { + php3_error(E_WARNING, "OpenDir: %s (errno %d)", strerror(errno), errno); + RETURN_FALSE; + } + ret = php3_list_insert(dirp, GLOBAL(le_dirp)); + GLOBAL(dirp_id) = ret; + + /* construct an object with some methods */ + object_init(return_value); + add_property_long(return_value, "handle", ret); + add_property_stringl(return_value, "path", arg->value.str.val, arg->value.str.len, 1); + add_method(return_value, "read", php3_readdir); + add_method(return_value, "rewind", php3_rewinddir); + add_method(return_value, "close", php3_closedir); +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/dns.c b/ext/standard/dns.c new file mode 100644 index 0000000000..5a338856d0 --- /dev/null +++ b/ext/standard/dns.c @@ -0,0 +1,343 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: | + | | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#if HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#if WIN32|WINNT +#if HAVE_BINDLIB +#ifndef WINNT +#define WINNT 1 +#endif +/* located in www.php.net/extra/bindlib.zip */ +#include "arpa/inet.h" +#include "netdb.h" +#include "arpa/nameser.h" +#include "resolv.h" +#endif +#include <winsock.h> +#else +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#ifdef _OSD_POSIX +#undef STATUS +#undef T_UNSPEC +#endif +#include <arpa/nameser.h> +#include <resolv.h> +#endif + +#include "dns.h" + +char *_php3_gethostbyaddr(char *ip); +char *_php3_gethostbyname(char *name); + +/* {{{ proto string gethostbyaddr(string ip_address) + Get the Internet host name corresponding to a given IP address */ +void php3_gethostbyaddr(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + return_value->value.str.val = _php3_gethostbyaddr(arg->value.str.val); + return_value->value.str.len = strlen(return_value->value.str.val); + return_value->type = IS_STRING; +} +/* }}} */ + + +char *_php3_gethostbyaddr(char *ip) +{ + unsigned long addr; + struct hostent *hp; + + if ((int) (addr = inet_addr(ip)) == -1) { +#if DEBUG + php3_error(E_WARNING, "address not in a.b.c.d form"); +#endif + return estrdup(ip); + } + hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET); + if (!hp) { +#if DEBUG + php3_error(E_WARNING, "Unable to resolve %s\n", ip); +#endif + return estrdup(ip); + } + return estrdup(hp->h_name); +} + +/* {{{ proto string gethostbyname(string hostname) + Get the IP address corresponding to a given Internet host name */ +void php3_gethostbyname(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + return_value->value.str.val = _php3_gethostbyname(arg->value.str.val); + return_value->value.str.len = strlen(return_value->value.str.val); + return_value->type = IS_STRING; +} +/* }}} */ + +/* {{{ proto array gethostbynamel(string hostname) + Return a list of IP addresses that a given hostname resolves to. */ +void php3_gethostbynamel(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + struct hostent *hp; + struct in_addr in; + int i; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + if (array_init(return_value) == FAILURE) { + RETURN_FALSE; + } + + hp = gethostbyname(arg->value.str.val); + if (hp == NULL || hp->h_addr_list == NULL) { +#if DEBUG + php3_error(E_WARNING, "Unable to resolve %s\n", arg->value.str.val); +#endif + return; + } + + for (i = 0 ; hp->h_addr_list[i] != 0 ; i++) { + memcpy(&in.s_addr, hp->h_addr_list[i], sizeof(in.s_addr)); + add_next_index_string(return_value, inet_ntoa(in), 1); + } + + return; +} +/* }}} */ + +char *_php3_gethostbyname(char *name) +{ + struct hostent *hp; + struct in_addr in; + + hp = gethostbyname(name); + if (!hp || !hp->h_addr_list) { +#if DEBUG + php3_error(E_WARNING, "Unable to resolve %s\n", name); +#endif + return estrdup(name); + } + memcpy(&in.s_addr, *(hp->h_addr_list), sizeof(in.s_addr)); + return estrdup(inet_ntoa(in)); +} + +#if !(WIN32|WINNT)||HAVE_BINDLIB + +/* {{{ proto int checkdnsrr(string host [, string type]) + Check DNS records corresponding to a given Internet host name or IP address */ +void php3_checkdnsrr(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg1,*arg2; + int type,i; +#ifndef MAXPACKET +#define MAXPACKET 8192 /* max packet size used internally by BIND */ +#endif + u_char ans[MAXPACKET]; + TLS_VARS; + + switch (ARG_COUNT(ht)) { + case 1: + if (getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + type = T_MX; + convert_to_string(arg1); + break; + case 2: + if (getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg1); + convert_to_string(arg2); + if ( !strcasecmp("A",arg2->value.str.val) ) type = T_A; + else if ( !strcasecmp("NS",arg2->value.str.val) ) type = T_NS; + else if ( !strcasecmp("MX",arg2->value.str.val) ) type = T_MX; + else if ( !strcasecmp("PTR",arg2->value.str.val) ) type = T_PTR; + else if ( !strcasecmp("ANY",arg2->value.str.val) ) type = T_ANY; + else if ( !strcasecmp("SOA",arg2->value.str.val) ) type = T_SOA; + else if ( !strcasecmp("CNAME",arg2->value.str.val) ) type = T_CNAME; + else { + php3_error(E_WARNING,"Type '%s' not supported",arg2->value.str.val); + RETURN_FALSE; + } + break; + default: + WRONG_PARAM_COUNT; + } + i = res_search(arg1->value.str.val,C_IN,type,ans,sizeof(ans)); + if ( i < 0 ) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +#ifndef HFIXEDSZ +#define HFIXEDSZ 12 /* fixed data in header <arpa/nameser.h> */ +#endif /* HFIXEDSZ */ + +#ifndef QFIXEDSZ +#define QFIXEDSZ 4 /* fixed data in query <arpa/nameser.h> */ +#endif /* QFIXEDSZ */ + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 256 +#endif /* MAXHOSTNAMELEN */ + +/* {{{ proto int getmxrr(string hostname, array mxhosts [, array weight]) + Get MX records corresponding to a given Internet host name */ +void php3_getmxrr(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *host, *mx_list, *weight_list; + pval tmp1,tmp2; + int need_weight = 0; + int count,qdc; + u_short type,weight; + u_char ans[MAXPACKET]; + char buf[MAXHOSTNAMELEN]; + HEADER *hp; + u_char *cp,*end; + int i; + + switch(ARG_COUNT(ht)) { + case 2: + if (getParameters(ht, 2, &host, &mx_list) == FAILURE) { + WRONG_PARAM_COUNT; + } + if (!ParameterPassedByReference(ht, 2)) { + php3_error(E_WARNING, "Array to be filled with values must be passed by reference."); + RETURN_FALSE; + } + break; + case 3: + if (getParameters(ht, 3, &host, &mx_list, &weight_list) == FAILURE) { + WRONG_PARAM_COUNT; + } + if (!ParameterPassedByReference(ht, 2) || !ParameterPassedByReference(ht, 3)) { + php3_error(E_WARNING, "Array to be filled with values must be passed by reference."); + RETURN_FALSE; + } + need_weight = 1; + pval_destructor(weight_list _INLINE_TLS); /* start with clean array */ + if ( array_init(weight_list) == FAILURE ) { + RETURN_FALSE; + } + break; + default: + WRONG_PARAM_COUNT; + } + + convert_to_string( host ); + pval_destructor(mx_list _INLINE_TLS); /* start with clean array */ + if ( array_init(mx_list) == FAILURE ) { + RETURN_FALSE; + } + + /* Go! */ + i = res_search(host->value.str.val,C_IN,T_MX,(u_char *)&ans,sizeof(ans)); + if ( i < 0 ) { + RETURN_FALSE; + } + if ( i > sizeof(ans) ) i = sizeof(ans); + hp = (HEADER *)&ans; + cp = (u_char *)&ans + HFIXEDSZ; + end = (u_char *)&ans +i; + for ( qdc = ntohs((unsigned short)hp->qdcount); qdc--; cp += i + QFIXEDSZ) { + if ( (i = dn_skipname(cp,end)) < 0 ) { + RETURN_FALSE; + } + } + count = ntohs((unsigned short)hp->ancount); + while ( --count >= 0 && cp < end ) { + if ( (i = dn_skipname(cp,end)) < 0 ) { + RETURN_FALSE; + } + cp += i; + GETSHORT(type,cp); + cp += INT16SZ + INT32SZ; + GETSHORT(i,cp); + if ( type != T_MX ) { + cp += i; + continue; + } + GETSHORT(weight,cp); + if ( (i = dn_expand(ans,end,cp,buf,sizeof(buf)-1)) < 0 ) { + RETURN_FALSE; + } + cp += i; + tmp1.value.str.len = strlen(buf); + tmp1.value.str.val = estrndup(buf,tmp1.value.str.len); + tmp1.type = IS_STRING; + _php3_hash_next_index_insert(mx_list->value.ht, (void *)&tmp1, sizeof(pval), NULL); + if ( need_weight ) { + tmp2.value.lval = (long)weight; + tmp2.type = IS_LONG; + _php3_hash_next_index_insert(weight_list->value.ht, (void *)&tmp2, sizeof(pval), NULL); + } + } + RETURN_TRUE; +} +/* }}} */ + +#endif +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/dns.h b/ext/standard/dns.h new file mode 100644 index 0000000000..c9f3706848 --- /dev/null +++ b/ext/standard/dns.h @@ -0,0 +1,53 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: | + | | + +----------------------------------------------------------------------+ + */ + + +/* $Id$ */ + +#ifndef _DNS_H +#define _DNS_H + +extern void php3_gethostbyaddr(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_gethostbyname(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_gethostbynamel(INTERNAL_FUNCTION_PARAMETERS); +#if !(WIN32|WINNT)||(HAVE_BINDLIB) +extern void php3_checkdnsrr(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_getmxrr(INTERNAL_FUNCTION_PARAMETERS); +#endif + +#ifndef INT16SZ +#define INT16SZ 2 +#endif + +#ifndef INT32SZ +#define INT32SZ 4 +#endif + +#endif /* _DNS_H */ diff --git a/ext/standard/exec.c b/ext/standard/exec.c new file mode 100644 index 0000000000..cb953fc9bd --- /dev/null +++ b/ext/standard/exec.c @@ -0,0 +1,388 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Author: Rasmus Lerdorf | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ + +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include <stdio.h> +#include "php.h" +#include <ctype.h> +#include "php3_string.h" +#include "safe_mode.h" +#include "head.h" +#include "exec.h" +#include "php_globals.h" + +#if HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + +/* + * If type==0, only last line of output is returned (exec) + * If type==1, all lines will be printed and last lined returned (system) + * If type==2, all lines will be saved to given array (exec with &$array) + * If type==3, output will be printed binary, no lines will be saved or returned (passthru) + * + */ +static int _Exec(int type, char *cmd, pval *array, pval *return_value) +{ + FILE *fp; + char buf[EXEC_INPUT_BUF], *tmp=NULL; + int t, l, ret, output=1; + int overflow_limit, lcmd, ldir; + char *b, *c, *d=NULL; + PLS_FETCH(); + + if (PG(safe_mode)) { + lcmd = strlen(cmd); + ldir = strlen(PG(safe_mode_exec_dir)); + l = lcmd + ldir + 2; + overflow_limit = l; + c = strchr(cmd, ' '); + if (c) *c = '\0'; + if (strstr(cmd, "..")) { + php3_error(E_WARNING, "No '..' components allowed in path"); + return -1; + } + d = emalloc(l); + strcpy(d, PG(safe_mode_exec_dir)); + overflow_limit -= ldir; + b = strrchr(cmd, '/'); + if (b) { + strcat(d, b); + overflow_limit -= strlen(b); + } else { + strcat(d, "/"); + strcat(d, cmd); + overflow_limit-=(strlen(cmd)+1); + } + if (c) { + *c = ' '; + strncat(d, c, overflow_limit); + } + tmp = _php3_escapeshellcmd(d); + efree(d); + d = tmp; +#if WIN32|WINNT + fp = popen(d, "rb"); +#else + fp = popen(d, "r"); +#endif + if (!fp) { + php3_error(E_WARNING, "Unable to fork [%s]", d); + efree(d); + return -1; + } + } else { /* not safe_mode */ +#if WIN32|WINNT + fp = popen(cmd, "rb"); +#else + fp = popen(cmd, "r"); +#endif + if (!fp) { + php3_error(E_WARNING, "Unable to fork [%s]", cmd); + return -1; + } + } + buf[0] = '\0'; + if (type==2) { + if (array->type != IS_ARRAY) { + pval_destructor(array _INLINE_TLS); + array_init(array); + } + } + if (type != 3) { + while (fgets(buf, EXEC_INPUT_BUF - 1, fp)) { + if (type == 1) { + if (output) PUTS(buf); +#if APACHE +# if MODULE_MAGIC_NUMBER > 19970110 + if (output) rflush(GLOBAL(php3_rqst)); +# else + if (output) bflush(GLOBAL(php3_rqst)->connection->client); +# endif +#endif +#if CGI_BINARY + fflush(stdout); +#endif +#if FHTTPD + /* fhttpd doesn't flush */ +#endif +#if USE_SAPI + GLOBAL(sapi_rqst)->flush(GLOBAL(sapi_rqst)->scid); +#endif + } + else if (type == 2) { + pval tmp; + + /* strip trailing whitespaces */ + l = strlen(buf); + t = l; + while (l && isspace((int)buf[--l])); + if (l < t) buf[l + 1] = '\0'; + tmp.value.str.len = strlen(buf); + tmp.value.str.val = estrndup(buf,tmp.value.str.len); + tmp.type = IS_STRING; + _php3_hash_next_index_insert(array->value.ht,(void *) &tmp, sizeof(pval), NULL); + } + } + + /* strip trailing spaces */ + l = strlen(buf); + t = l; + while (l && isspace((int)buf[--l])); + if (l < t) buf[l + 1] = '\0'; + + } else { + int b, i; + + while ((b = fread(buf, 1, sizeof(buf), fp)) > 0) { + for (i = 0; i < b; i++) + if (output) PUTC(buf[i]); + } + } + + /* Return last line from the shell command */ + if (PG(magic_quotes_runtime) && type!=3) { + int len; + + tmp = _php3_addslashes(buf, 0, &len, 0); + RETVAL_STRINGL(tmp,len,0); + } else { + RETVAL_STRING(buf,1); + } + + ret = pclose(fp); +#if HAVE_SYS_WAIT_H + if (WIFEXITED(ret)) { + ret = WEXITSTATUS(ret); + } +#endif + + if (d) efree(d); + return ret; +} + +/* {{{ proto int exec(string command [, array output [, int return_value]]) + Execute an external program */ +void php3_exec(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg1, *arg2, *arg3; + int arg_count = ARG_COUNT(ht); + int ret; + + if (arg_count > 3 || getParameters(ht, arg_count, &arg1, &arg2, &arg3) == FAILURE) { + WRONG_PARAM_COUNT; + } + switch (arg_count) { + case 1: + ret = _Exec(0, arg1->value.str.val, NULL, return_value); + break; + case 2: + if (!ParameterPassedByReference(ht,2)) { + php3_error(E_WARNING,"Array argument to exec() not passed by reference"); + } + ret = _Exec(2, arg1->value.str.val, arg2, return_value); + break; + case 3: + if (!ParameterPassedByReference(ht,2)) { + php3_error(E_WARNING,"Array argument to exec() not passed by reference"); + } + if (!ParameterPassedByReference(ht,3)) { + php3_error(E_WARNING,"return_status argument to exec() not passed by reference"); + } + ret = _Exec(2, arg1->value.str.val, arg2, return_value); + arg3->type = IS_LONG; + arg3->value.lval=ret; + break; + } +} +/* }}} */ + +/* {{{ proto int system(string command [, int return_value]) + Execute an external program and display output */ +void php3_system(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg1, *arg2; + int arg_count = ARG_COUNT(ht); + int ret; + + if (arg_count > 2 || getParameters(ht, arg_count, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + switch (arg_count) { + case 1: + ret = _Exec(1, arg1->value.str.val, NULL, return_value); + break; + case 2: + if (!ParameterPassedByReference(ht,2)) { + php3_error(E_WARNING,"return_status argument to system() not passed by reference"); + } + ret = _Exec(1, arg1->value.str.val, NULL, return_value); + arg2->type = IS_LONG; + arg2->value.lval=ret; + break; + } +} +/* }}} */ + +/* {{{ proto int passthru(string command [, int return_value]) + Execute an external program and display raw output */ +void php3_passthru(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg1, *arg2; + int arg_count = ARG_COUNT(ht); + int ret; + + if (arg_count > 2 || getParameters(ht, arg_count, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + switch (arg_count) { + case 1: + ret = _Exec(3, arg1->value.str.val, NULL, return_value); + break; + case 2: + if (!ParameterPassedByReference(ht,2)) { + php3_error(E_WARNING,"return_status argument to system() not passed by reference"); + } + ret = _Exec(3, arg1->value.str.val, NULL, return_value); + arg2->type = IS_LONG; + arg2->value.lval=ret; + break; + } +} +/* }}} */ + +static int php3_ind(char *s, char c) +{ + register int x; + + for (x = 0; s[x]; x++) + if (s[x] == c) + return x; + + return -1; +} + +/* Escape all chars that could possibly be used to + break out of a shell command + + This function emalloc's a string and returns the pointer. + Remember to efree it when done with it. + + *NOT* safe for binary strings +*/ +char * _php3_escapeshellcmd(char *str) { + register int x, y, l; + char *cmd; + + l = strlen(str); + cmd = emalloc(2 * l + 1); + strcpy(cmd, str); + for (x = 0; cmd[x]; x++) { + if (php3_ind("&;`'\"|*?~<>^()[]{}$\\\x0A\xFF", cmd[x]) != -1) { + for (y = l + 1; y > x; y--) + cmd[y] = cmd[y - 1]; + l++; /* length has been increased */ + cmd[x] = '\\'; + x++; /* skip the character */ + } + } + return cmd; +} + +/* {{{ proto escapeshellcmd(string command) + escape shell metacharacters */ +void php3_escapeshellcmd(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg1; + char *cmd; + TLS_VARS; + + if (getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + cmd = _php3_escapeshellcmd(arg1->value.str.val); + + RETVAL_STRING(cmd,1); + efree(cmd); +} +/* }}} */ + + +PHP_FUNCTION(shell_exec) +{ + FILE *in; + int readbytes,total_readbytes=0,allocated_space; + pval *cmd; + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &cmd)==FAILURE) { + WRONG_PARAM_COUNT; + } + + if (PG(safe_mode)) { + php3_error(E_WARNING,"Cannot execute using backquotes in safe mode"); + RETURN_FALSE; + } + + convert_to_string(cmd); +#if WIN32|WINNT + if ((in=popen(cmd->value.str.val,"rt"))==NULL) { +#else + if ((in=popen(cmd->value.str.val,"r"))==NULL) { +#endif + php3_error(E_WARNING,"Unable to execute '%s'",cmd->value.str.val); + } + allocated_space = EXEC_INPUT_BUF; + return_value->value.str.val = (char *) emalloc(allocated_space); + while (1) { + readbytes = fread(return_value->value.str.val+total_readbytes,1,EXEC_INPUT_BUF,in); + if (readbytes<=0) { + break; + } + total_readbytes += readbytes; + allocated_space = total_readbytes+EXEC_INPUT_BUF; + return_value->value.str.val = (char *) erealloc(return_value->value.str.val,allocated_space); + } + fclose(in); + + return_value->value.str.val = erealloc(return_value->value.str.val,total_readbytes+1); + return_value->value.str.val[total_readbytes]=0; + return_value->value.str.len = total_readbytes; + return_value->type = IS_STRING; +} + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/exec.h b/ext/standard/exec.h new file mode 100644 index 0000000000..f8062ba828 --- /dev/null +++ b/ext/standard/exec.h @@ -0,0 +1,43 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + +----------------------------------------------------------------------+ + */ + + +/* $Id$ */ + +#ifndef _EXEC_H +#define _EXEC_H + +extern void php3_system(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_exec(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_escapeshellcmd(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_passthru(INTERNAL_FUNCTION_PARAMETERS); +PHP_FUNCTION(shell_exec); + +char *_php3_escapeshellcmd(char *); +#endif /* _EXEC_H */ diff --git a/ext/standard/file.c b/ext/standard/file.c new file mode 100644 index 0000000000..cedb4b5109 --- /dev/null +++ b/ext/standard/file.c @@ -0,0 +1,1435 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if MSVC5 +#include <windows.h> +#include <winsock.h> +#define O_RDONLY _O_RDONLY +#include "win32/param.h" +#include "win32/winutil.h" +#else +#include <sys/param.h> +#include <sys/socket.h> +/* #include <sys/uio.h> */ +#endif +#include "head.h" +#include "safe_mode.h" +#include "php3_string.h" +#include "file.h" +#if HAVE_PWD_H +#if MSVC5 +#include "win32/pwd.h" +#else +#include <pwd.h> +#endif +#endif +#if HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#include "snprintf.h" +#include "fsock.h" +#include "fopen-wrappers.h" +#include "php_globals.h" + +#if MISSING_FCLOSE_DECL +extern int fclose(); +#endif + +static void _php3_closesocket(int *); + +#ifndef THREAD_SAFE +static int fgetss_state = 0; +int le_fp,le_pp; +int wsa_fp; /*to handle reading and writing to windows sockets*/ +static int pclose_ret; +extern int le_uploads; +#endif + +#ifndef HAVE_TEMPNAM +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <unistd.h> + +#ifndef MAXPATHLEN +# ifdef PATH_MAX +# define MAXPATHLEN PATH_MAX +# else +# define MAXPATHLEN 255 +# endif +#endif + +char * +tempnam(const char *dir, const char *pfx) +{ + int save_errno; + char *f, *name; + static char path_tmp[] = "/tmp"; + + if (!(name = emalloc(MAXPATHLEN))) { + return(NULL); + } + + if (!pfx) { + pfx = "tmp."; + } + + if (f = getenv("TMPDIR")) { + (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, + *(f + strlen(f) - 1) == '/'? "": "/", pfx); + if (f = mktemp(name)) + return(f); + } + + if (f = (char *)dir) { + (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, + *(f + strlen(f) - 1) == '/'? "": "/", pfx); + if (f = mktemp(name)) + return(f); + } + + f = P_tmpdir; + (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); + if (f = mktemp(name)) + return(f); + + f = path_tmp; + (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx); + if (f = mktemp(name)) + return(f); + + save_errno = errno; + efree(name); + errno = save_errno; + return(NULL); +} +#endif + +function_entry php3_file_functions[] = { + {"pclose", php3_pclose, NULL}, + {"popen", php3_popen, NULL}, + {"readfile", php3_readfile, NULL}, + {"rewind", php3_rewind, NULL}, + {"rmdir", php3_rmdir, NULL}, + {"umask", php3_fileumask, NULL}, + {"fclose", php3_fclose, NULL}, + {"feof", php3_feof, NULL}, + {"fgetc", php3_fgetc, NULL}, + {"fgets", php3_fgets, NULL}, + {"fgetss", php3_fgetss, NULL}, + {"fread", php3_fread, NULL}, + {"fopen", php3_fopen, NULL}, + {"fpassthru", php3_fpassthru, NULL}, + {"fseek", php3_fseek, NULL}, + {"ftell", php3_ftell, NULL}, + {"fwrite", php3_fwrite, NULL}, + {"fputs", php3_fwrite, NULL}, + {"mkdir", php3_mkdir, NULL}, + {"rename", php3_rename, NULL}, + {"copy", php3_file_copy, NULL}, + {"tempnam", php3_tempnam, NULL}, + {"file", php3_file, NULL}, + {"get_meta_tags", php3_get_meta_tags, NULL}, + {"set_socket_blocking", php3_set_socket_blocking, NULL}, +#if (0 && HAVE_SYS_TIME_H && HAVE_SETSOCKOPT && defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO)) + {"set_socket_timeout", php3_set_socket_timeout, NULL}, +#endif + {NULL, NULL, NULL} +}; + +php3_module_entry php3_file_module_entry = { + "PHP_file", php3_file_functions, php3_minit_file, NULL, NULL, NULL, NULL, STANDARD_MODULE_PROPERTIES +}; + +/* {{{ proto array get_meta_tags(string filename [, int use_include_path]) + Extracts all meta tag content attributes from a file and returns an array */ +void php3_get_meta_tags(INTERNAL_FUNCTION_PARAMETERS) { + pval *filename, *arg2; + FILE *fp; + char buf[8192]; + int use_include_path = 0; + int issock=0, socketd=0; + int len, var_namelen; + char var_name[50],*val=NULL,*tmp,*end,*slashed; + PLS_FETCH(); + + /* check args */ + switch (ARG_COUNT(ht)) { + case 1: + if (getParameters(ht,1,&filename) == FAILURE) { + WRONG_PARAM_COUNT; + } + break; + case 2: + if (getParameters(ht,2,&filename,&arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg2); + use_include_path = arg2->value.lval; + break; + default: + WRONG_PARAM_COUNT; + } + convert_to_string(filename); + + fp = php3_fopen_wrapper(filename->value.str.val,"r", use_include_path|ENFORCE_SAFE_MODE, &issock, &socketd); + if (!fp && !socketd) { + if (issock != BAD_URL) { + php3_strip_url_passwd(filename->value.str.val); + php3_error(E_WARNING,"File(\"%s\") - %s",filename->value.str.val,strerror(errno)); + } + RETURN_FALSE; + } + + if (array_init(return_value)==FAILURE) { + if (issock) { +#if WIN32|WINNT + closesocket(socketd); +#else + close(socketd); +#endif + } else { + fclose(fp); + } + RETURN_FALSE; + } + /* Now loop through the file and do the magic quotes thing if needed */ + memset(buf,0,8191); + while((issock?SOCK_FGETS(buf,8191,socketd):(int)fgets(buf,8191,fp)) + && !php3i_stristr(buf,"</head>")) { + if(php3i_stristr(buf,"<meta")) { + + memset(var_name,0,50); + /* get the variable name from the name attribute of the meta tag */ + tmp=php3i_stristr(buf,"name=\""); + if(tmp) { + tmp+=6; + end=strstr(tmp,"\""); + if(end) { + unsigned char *c; + *end='\0'; + snprintf(var_name,50,"%s",tmp); + *end='"'; + + c = (unsigned char*)var_name; + while (*c) { + switch(*c) { + case '.': + case '\\': + case '+': + case '*': + case '?': + case '[': + case '^': + case ']': + case '$': + case '(': + case ')': + case ' ': + *c++ ='_'; + break; + default: + *c++ = tolower((unsigned char)*c); + } + } + var_namelen=strlen(var_name); + } + + /* get the variable value from the content attribute of the meta tag */ + tmp=php3i_stristr(buf,"content=\""); + if(tmp) { + tmp+=9; + end=strstr(tmp,"\""); + if(end) { + *end='\0'; + val=estrdup(tmp); + *end='"'; + } + } + } + if(*var_name && val) { + if (PG(magic_quotes_runtime)) { + slashed = _php3_addslashes(val,0,&len,0); + } else { + slashed = estrndup(val,strlen(val)); + } + add_assoc_string(return_value, var_name, slashed, 0); + efree(val); + } + } + } + if (issock) { +#if WIN32|WINNT + closesocket(socketd); +#else + close(socketd); +#endif + } else { + fclose(fp); + } +} +/* }}} */ + +/* {{{ proto array file(string filename) +Read entire file into an array */ +void php3_file(INTERNAL_FUNCTION_PARAMETERS) { + pval *filename, *arg2; + FILE *fp; + char *slashed, buf[8192]; + register int i=0; + int use_include_path = 0; + int issock=0, socketd=0; + PLS_FETCH(); + + /* check args */ + switch (ARG_COUNT(ht)) { + case 1: + if (getParameters(ht,1,&filename) == FAILURE) { + WRONG_PARAM_COUNT; + } + break; + case 2: + if (getParameters(ht,2,&filename,&arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg2); + use_include_path = arg2->value.lval; + break; + default: + WRONG_PARAM_COUNT; + } + convert_to_string(filename); + + fp = php3_fopen_wrapper(filename->value.str.val,"r", use_include_path|ENFORCE_SAFE_MODE, &issock, &socketd); + if (!fp && !socketd) { + if (issock != BAD_URL) { + php3_strip_url_passwd(filename->value.str.val); + php3_error(E_WARNING,"File(\"%s\") - %s",filename->value.str.val,strerror(errno)); + } + RETURN_FALSE; + } + + /* Initialize return array */ + if (array_init(return_value) == FAILURE) { + RETURN_FALSE; + } + + /* Now loop through the file and do the magic quotes thing if needed */ + memset(buf,0,8191); + while(issock?SOCK_FGETS(buf,8191,socketd):(int)fgets(buf,8191,fp)) { + if (PG(magic_quotes_runtime)) { + int len; + + slashed = _php3_addslashes(buf,0,&len,0); /* 0 = don't free source string */ + add_index_stringl(return_value, i++, slashed, len, 0); + } else { + add_index_string(return_value, i++, buf, 1); + } + } + if (issock) { +#if WIN32|WINNT + closesocket(socketd); +#else + close(socketd); +#endif + } else { + fclose(fp); + } +} +/* }}} */ + + +static void __pclose(FILE *pipe) +{ +TLS_VARS; + GLOBAL(pclose_ret) = pclose(pipe); +} + +static void _php3_closesocket(int *sock) { + int socketd=*sock; + if (socketd){ +#if WIN32|WINNT + closesocket(socketd); +#else + close(socketd); +#endif + efree(sock); + } +} + +static void _php3_unlink_uploaded_file(char *file) { + if(file) { + unlink(file); + } +} + +int php3_minit_file(INIT_FUNC_ARGS) +{ + TLS_VARS; + + GLOBAL(le_fp) = register_list_destructors(fclose,NULL); + GLOBAL(le_pp) = register_list_destructors(__pclose,NULL); + GLOBAL(wsa_fp) = register_list_destructors(_php3_closesocket,NULL); + GLOBAL(le_uploads) = register_list_destructors(_php3_unlink_uploaded_file,NULL); + return SUCCESS; +} + +/* {{{ proto string tempnam(string dir, string prefix) +Create a unique filename in a directory */ +void php3_tempnam(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1, *arg2; + char *d; + char *t; + char p[64]; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg1); + convert_to_string(arg2); + d = estrndup(arg1->value.str.val,arg1->value.str.len); + strncpy(p,arg2->value.str.val,sizeof(p)); + + t = tempnam(d,p); + efree(d); + RETURN_STRING(t,1); +} +/* }}} */ + +/* {{{ proto int fopen(string filename, string mode [, int use_include_path]) +Open a file or a URL and return a file pointer */ +void php3_fopen(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1, *arg2, *arg3; + FILE *fp; + char *p; + int *sock; + int id; + int use_include_path = 0; + int issock=0, socketd=0; + TLS_VARS; + + switch(ARG_COUNT(ht)) { + case 2: + if (getParameters(ht,2,&arg1,&arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + break; + case 3: + if (getParameters(ht,3,&arg1,&arg2,&arg3) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg3); + use_include_path = arg3->value.lval; + break; + default: + WRONG_PARAM_COUNT; + } + convert_to_string(arg1); + convert_to_string(arg2); + p = estrndup(arg2->value.str.val,arg2->value.str.len); + + /* + * We need a better way of returning error messages from + * php3_fopen__wrapper(). + */ + fp = php3_fopen_wrapper(arg1->value.str.val, p, use_include_path|ENFORCE_SAFE_MODE, &issock, &socketd); + if (!fp && !socketd) { + if (issock != BAD_URL) { + php3_strip_url_passwd(arg1->value.str.val); + php3_error(E_WARNING,"fopen(\"%s\",\"%s\") - %s", + arg1->value.str.val, p, strerror(errno)); + } + efree(p); + RETURN_FALSE; + } + GLOBAL(fgetss_state)=0; + if (issock) { + sock=emalloc(sizeof(int)); + *sock=socketd; + id = php3_list_insert(sock,GLOBAL(wsa_fp)); + } else { + id = php3_list_insert(fp,GLOBAL(le_fp)); + } + efree(p); + RETURN_LONG(id); +} +/* }}} */ + +/* {{{ proto int fclose(int fp) +Close an open file pointer */ +void php3_fclose(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + int id, type; + FILE *fp; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + id=arg1->value.lval; + fp = php3_list_find(id,&type); + if (!fp || (type!=GLOBAL(le_fp) && type!=GLOBAL(wsa_fp))) { + php3_error(E_WARNING,"Unable to find file identifier %d",id); + RETURN_FALSE; + } + php3_list_delete(id); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto int popen(string command, string mode) +Execute a command and open either a read or a write pipe to it */ +void php3_popen(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1, *arg2; + FILE *fp; + int id; + char *p; + char *b, buf[1024]; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg1); + convert_to_string(arg2); + p = estrndup(arg2->value.str.val,arg2->value.str.len); + if (PG(safe_mode)){ + b = strchr(arg1->value.str.val,' '); + if (!b) { + b = strrchr(arg1->value.str.val,'/'); + } else { + char *c; + c = arg1->value.str.val; + while((*b!='/')&&(b!=c)) b--; + if (b==c) b=NULL; + } + if (b) { + snprintf(buf,sizeof(buf),"%s%s",PG(safe_mode_exec_dir),b); + } else { + snprintf(buf,sizeof(buf),"%s/%s",PG(safe_mode_exec_dir),arg1->value.str.val); + } + fp = popen(buf,p); + if (!fp) { + php3_error(E_WARNING,"popen(\"%s\",\"%s\") - %s",buf,p,strerror(errno)); + RETURN_FALSE; + } + } else { + fp = popen(arg1->value.str.val,p); + if (!fp) { + php3_error(E_WARNING,"popen(\"%s\",\"%s\") - %s",arg1->value.str.val,p,strerror(errno)); + efree(p); + RETURN_FALSE; + } + } +/* #endif */ + id = php3_list_insert(fp,GLOBAL(le_pp)); + efree(p); + RETURN_LONG(id); +} +/* }}} */ + +/* {{{ proto int pclose(int fp) +Close a file pointer opened by popen() */ +void php3_pclose(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + int id,type; + FILE *fp; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + id = arg1->value.lval; + + fp = php3_list_find(id,&type); + if (!fp || type!=GLOBAL(le_pp)) { + php3_error(E_WARNING,"Unable to find pipe identifier %d",id); + RETURN_FALSE; + } + php3_list_delete(id); + RETURN_LONG(GLOBAL(pclose_ret)); +} +/* }}} */ + +/* {{{ proto int feof(int fp) +Test for end-of-file on a file pointer */ +void php3_feof(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + FILE *fp; + int id, type; + int issock=0; + int socketd=0, *sock; + unsigned int temp; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + id = arg1->value.lval; + fp = php3_list_find(id,&type); + if (type==GLOBAL(wsa_fp)){ + issock=1; + sock = php3_list_find(id,&type); + socketd=*sock; + } + if ((!fp || (type!=GLOBAL(le_fp) && type!=GLOBAL(le_pp))) && (!socketd || type!=GLOBAL(wsa_fp))) { + php3_error(E_WARNING,"Unable to find file identifier %d",id); + /* we're at the eof if the file doesn't exist */ + RETURN_TRUE; + } + if ((issock?!(recv(socketd,(char *)&temp,1,MSG_PEEK)):feof(fp))) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto int set_socket_blocking(int socket descriptor, int mode) +Set blocking/non-blocking mode on a socket */ +void php3_set_socket_blocking(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg1, *arg2; + int id, type, block; + int flags; + int socketd=0, *sock; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + convert_to_long(arg2); + id = arg1->value.lval; + block = arg2->value.lval; + + sock = php3_list_find(id,&type); + if (type!=GLOBAL(wsa_fp)) { + php3_error(E_WARNING,"%d is not a socket id",id); + RETURN_FALSE; + } + socketd=*sock; +#if WIN32|WINNT + /* with ioctlsocket, a non-zero sets nonblocking, a zero sets blocking */ + flags=block; + if (ioctlsocket(socketd,FIONBIO,&flags)==SOCKET_ERROR){ + php3_error(E_WARNING,"%s",WSAGetLastError()); + RETURN_FALSE; + } else { + RETURN_TRUE; + } +#else + flags = fcntl(socketd, F_GETFL); +# ifdef O_NONBLOCK + /* POSIX version */ + if (block) { + if ((flags & O_NONBLOCK)) { + flags ^= O_NONBLOCK; + } + } else { + if (!(flags & O_NONBLOCK)) { + flags |= O_NONBLOCK; + } + } +# else +# ifdef O_NDELAY + /* old non-POSIX version */ + if (block) { + flags |= O_NDELAY; + } else { + flags ^= O_NDELAY; + } +# endif +# endif + fcntl(socketd,F_SETFL,flags); + /* FIXME: Shouldnt we return true on this function? */ +#endif +} +/* }}} */ + + +#if (0 && HAVE_SYS_TIME_H && HAVE_SETSOCKOPT && defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO)) +/* this doesn't work, as it appears those properties are read-only :( */ +void php3_set_socket_timeout(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *socket,*timeout; + int type, *sock; + struct timeval t; + + if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &socket, &timeout)==FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(socket); + convert_to_long(timeout); + + sock = php3_list_find(socket->value.lval, &type); + if (type!=GLOBAL(wsa_fp)) { + php3_error(E_WARNING,"%d is not a socket id",socket->value.lval); + RETURN_FALSE; + } + t.tv_sec = timeout->value.lval; + t.tv_usec = 0; + setsockopt(*sock,SOL_SOCKET,SO_SNDTIMEO,(void *) &t,sizeof(struct timeval)); + setsockopt(*sock,SOL_SOCKET,SO_RCVTIMEO,(void *) &t,sizeof(struct timeval)); + RETURN_TRUE; +} +#endif + +/* {{{ proto string fgets(int fp, int length) +Get a line from file pointer */ +void php3_fgets(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg1, *arg2; + FILE *fp; + int id, len, type; + char *buf; + int issock=0; + int *sock, socketd=0; + PLS_FETCH(); + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + convert_to_long(arg2); + id = arg1->value.lval; + len = arg2->value.lval; + + fp = php3_list_find(id,&type); + if (type==GLOBAL(wsa_fp)){ + issock=1; + sock = php3_list_find(id,&type); + socketd=*sock; + } + if ((!fp || (type!=GLOBAL(le_fp) && type!=GLOBAL(le_pp))) && (!socketd || type!=GLOBAL(wsa_fp))) { + php3_error(E_WARNING,"Unable to find file identifier %d",id); + RETURN_FALSE; + } + buf = emalloc(sizeof(char) * (len + 1)); + /* needed because recv doesnt put a null at the end*/ + memset(buf,0,len+1); + if (!(issock?SOCK_FGETS(buf,len,socketd):(int)fgets(buf,len,fp))) { + efree(buf); + RETVAL_FALSE; + } else { + if (PG(magic_quotes_runtime)) { + return_value->value.str.val = _php3_addslashes(buf,0,&return_value->value.str.len,1); + } else { + return_value->value.str.val = buf; + return_value->value.str.len = strlen(return_value->value.str.val); + } + return_value->type = IS_STRING; + } + return; +} +/* }}} */ + +/* {{{ proto string fgetc(int fp) +Get a character from file pointer */ +void php3_fgetc(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + FILE *fp; + int id, type; + char *buf; + int issock=0; + int *sock, socketd=0; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + id = arg1->value.lval; + + fp = php3_list_find(id,&type); + if (type==GLOBAL(wsa_fp)){ + issock=1; + sock = php3_list_find(id,&type); + socketd = *sock; + } + if ((!fp || (type!=GLOBAL(le_fp) && type!=GLOBAL(le_pp))) && (!socketd || type!=GLOBAL(wsa_fp))) { + php3_error(E_WARNING,"Unable to find file identifier %d",id); + RETURN_FALSE; + } + buf = emalloc(sizeof(char) * 2); + if (!(issock?(SOCK_FGETC(buf,socketd)):(*buf=fgetc(fp)))) { + efree(buf); + RETVAL_FALSE; + } else { + buf[1]='\0'; + return_value->value.str.val = buf; + return_value->value.str.len = 1; + return_value->type = IS_STRING; + } + return; +} +/* }}} */ + +/* Strip any HTML tags while reading */ +/* {{{ proto string fgetss(int fp, int length) +Get a line from file pointer and strip HTML tags */ +void php3_fgetss(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *fd, *bytes; + FILE *fp; + int id, len, br, type; + char *buf, *p, *rbuf, *rp, c, lc; + int issock=0; + int *sock,socketd=0; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &fd, &bytes) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_long(fd); + convert_to_long(bytes); + + id = fd->value.lval; + len = bytes->value.lval; + + fp = php3_list_find(id,&type); + if (type==GLOBAL(wsa_fp)){ + issock=1; + sock = php3_list_find(id,&type); + socketd=*sock; + } + if ((!fp || (type!=GLOBAL(le_fp) && type!=GLOBAL(le_pp))) && (!socketd || type!=GLOBAL(wsa_fp))) { + php3_error(E_WARNING, "Unable to find file identifier %d", id); + RETURN_FALSE; + } + + buf = emalloc(sizeof(char) * (len + 1)); + /*needed because recv doesnt set null char at end*/ + memset(buf,0,len+1); + if (!(issock?SOCK_FGETS(buf,len,socketd):(int)fgets(buf, len, fp))) { + efree(buf); + RETURN_FALSE; + } + + rbuf = estrdup(buf); + c = *buf; + lc = '\0'; + p = buf; + rp = rbuf; + br = 0; + + while (c) { + switch (c) { + case '<': + if (GLOBAL(fgetss_state) == 0) { + lc = '<'; + GLOBAL(fgetss_state) = 1; + } + break; + + case '(': + if (GLOBAL(fgetss_state) == 2) { + if (lc != '\"') { + lc = '('; + br++; + } + } else if (GLOBAL(fgetss_state) == 0) { + *(rp++) = c; + } + break; + + case ')': + if (GLOBAL(fgetss_state) == 2) { + if (lc != '\"') { + lc = ')'; + br--; + } + } else if (GLOBAL(fgetss_state) == 0) { + *(rp++) = c; + } + break; + + case '>': + if (GLOBAL(fgetss_state) == 1) { + lc = '>'; + GLOBAL(fgetss_state) = 0; + } else if (GLOBAL(fgetss_state) == 2) { + if (!br && lc != '\"') { + GLOBAL(fgetss_state) = 0; + } + } + break; + + case '\"': + if (GLOBAL(fgetss_state) == 2) { + if (lc == '\"') { + lc = '\0'; + } else if (lc != '\\') { + lc = '\"'; + } + } else if (GLOBAL(fgetss_state) == 0) { + *(rp++) = c; + } + break; + + case '?': + if (GLOBAL(fgetss_state)==1) { + br=0; + GLOBAL(fgetss_state)=2; + break; + } + /* fall-through */ + + default: + if (GLOBAL(fgetss_state) == 0) { + *(rp++) = c; + } + } + c = *(++p); + } + *rp = '\0'; + efree(buf); + RETVAL_STRING(rbuf,1); + efree(rbuf); +} +/* }}} */ + +/* {{{ proto int fwrite(int fp, string str [, int length]) +Binary-safe file write */ +void php3_fwrite(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg1, *arg2, *arg3=NULL; + FILE *fp; + int ret,id,type; + int num_bytes; + int issock=0; + int *sock, socketd=0; + PLS_FETCH(); + + switch (ARG_COUNT(ht)) { + case 2: + if (getParameters(ht, 2, &arg1, &arg2)==FAILURE) { + RETURN_FALSE; + } + convert_to_string(arg2); + num_bytes = arg2->value.str.len; + break; + case 3: + if (getParameters(ht, 3, &arg1, &arg2, &arg3)==FAILURE) { + RETURN_FALSE; + } + convert_to_string(arg2); + convert_to_long(arg3); + num_bytes = MIN(arg3->value.lval, arg2->value.str.len); + break; + default: + WRONG_PARAM_COUNT; + /* NOTREACHED */ + break; + } + convert_to_long(arg1); + id = arg1->value.lval; + + fp = php3_list_find(id,&type); + if (type==GLOBAL(wsa_fp)){ + issock=1; + sock = php3_list_find(id,&type); + socketd=*sock; + } + if ((!fp || (type!=GLOBAL(le_fp) && type!=GLOBAL(le_pp))) && (!socketd || type!=GLOBAL(wsa_fp))) { + php3_error(E_WARNING,"Unable to find file identifier %d",id); + RETURN_FALSE; + } + + /* strip slashes only if the length wasn't specified explicitly */ + if (!arg3 && PG(magic_quotes_runtime)) { + _php3_stripslashes(arg2->value.str.val,&num_bytes); + } + + if (issock){ + ret = SOCK_WRITEL(arg2->value.str.val,num_bytes,socketd); + } else { + ret = fwrite(arg2->value.str.val,1,num_bytes,fp); + } + RETURN_LONG(ret); +} +/* }}} */ + +/* {{{ proto int rewind(int fp) +Rewind the position of a file pointer */ +void php3_rewind(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + int id,type; + FILE *fp; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + id = arg1->value.lval; + fp = php3_list_find(id,&type); + if (!fp || (type!=GLOBAL(le_fp) && type!=GLOBAL(le_pp))) { + php3_error(E_WARNING,"Unable to find file identifier %d",id); + RETURN_FALSE; + } + rewind(fp); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto int ftell(int fp) +Get file pointer's read/write position */ +void php3_ftell(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + int id, type; + long pos; + FILE *fp; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + id = arg1->value.lval; + fp = php3_list_find(id,&type); + if (!fp || (type!=GLOBAL(le_fp) && type!=GLOBAL(le_pp))) { + php3_error(E_WARNING,"Unable to find file identifier %d",id); + RETURN_FALSE; + } + pos = ftell(fp); + RETURN_LONG(pos); +} +/* }}} */ + +/* {{{ proto int fseek(int fp, int offset) +Seek on a file pointer */ +void php3_fseek(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1, *arg2; + int ret,id,type; + long pos; + FILE *fp; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + convert_to_long(arg2); + pos = arg2->value.lval; + id = arg1->value.lval; + fp = php3_list_find(id,&type); + if (!fp || (type!=GLOBAL(le_fp) && type!=GLOBAL(le_pp))) { + php3_error(E_WARNING,"Unable to find file identifier %d",id); + RETURN_FALSE; + } +/*fseek is flaky on windows, use setfilepointer, but we have to live with + it until we use win32 api for all the file functions in 3.1 */ +#if 0 + ret = SetFilePointer (fp, pos, NULL, FILE_BEGIN); + if (ret == 0xFFFFFFFF){ + php3_error(E_WARNING,"Unable to move file postition: %s",php3_win_err()); + RETURN_FALSE; + } +#else + ret = fseek(fp,pos,SEEK_SET); +#endif + RETURN_LONG(ret); +} +/* }}} */ + +/* {{{ proto int mkdir(string pathname, int mode) +Create a directory */ +void php3_mkdir(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1, *arg2; + int ret,mode; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg1); + convert_to_long(arg2); + mode = arg2->value.lval; + if (PG(safe_mode) &&(!_php3_checkuid(arg1->value.str.val,3))) { + RETURN_FALSE; + } + ret = mkdir(arg1->value.str.val,mode); + if (ret < 0) { + php3_error(E_WARNING,"MkDir failed (%s)", strerror(errno)); + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto int rmdir(string dirname) +Remove a directory */ +void php3_rmdir(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + int ret; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg1); + if (PG(safe_mode) &&(!_php3_checkuid(arg1->value.str.val,1))) { + RETURN_FALSE; + } + ret = rmdir(arg1->value.str.val); + if (ret < 0) { + php3_error(E_WARNING,"RmDir failed (%s)", strerror(errno)); + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto int readfile(string filename [, int use_include_path]) +Output a file or a URL */ +void php3_readfile(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1, *arg2; + char buf[8192]; + FILE *fp; + int b, size; + int use_include_path = 0; + + int issock=0, socketd=0; + TLS_VARS; + + /* check args */ + switch (ARG_COUNT(ht)) { + case 1: + if (getParameters(ht,1,&arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + break; + case 2: + if (getParameters(ht,2,&arg1,&arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg2); + use_include_path = arg2->value.lval; + break; + default: + WRONG_PARAM_COUNT; + } + convert_to_string(arg1); + + /* + * We need a better way of returning error messages from + * php3_fopen_wrapper(). + */ + fp = php3_fopen_wrapper(arg1->value.str.val,"r", use_include_path|ENFORCE_SAFE_MODE, &issock, &socketd); + if (!fp && !socketd){ + if (issock != BAD_URL) { + php3_strip_url_passwd(arg1->value.str.val); + php3_error(E_WARNING,"ReadFile(\"%s\") - %s",arg1->value.str.val,strerror(errno)); + } + RETURN_FALSE; + } + size= 0; + while(issock?(b=SOCK_FGETS(buf,sizeof(buf),socketd)):(b = fread(buf, 1, sizeof(buf), fp)) > 0) { + PHPWRITE(buf,b); + size += b ; + } + if (issock) { +#if WIN32|WINNT + closesocket(socketd); +#else + close(socketd); +#endif + } else { + fclose(fp); + } + RETURN_LONG(size); +} +/* }}} */ + +/* {{{ proto int umask([int mask]) +Return or change the umask */ +void php3_fileumask(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + int oldumask; + int arg_count = ARG_COUNT(ht); + TLS_VARS; + + oldumask = umask(077); + + if (arg_count == 0) { + umask(oldumask); + } + else { + if (arg_count > 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + umask(arg1->value.lval); + } + RETURN_LONG(oldumask); +} +/* }}} */ + +/* + * Read to EOF on a file descriptor and write the output to stdout. + */ +/* {{{ proto int fpassthru(int fp) +Output all remaining data from a file pointer */ +void php3_fpassthru(INTERNAL_FUNCTION_PARAMETERS) { + pval *arg1; + FILE *fp; + char buf[8192]; + int id, size, b, type; + int issock=0; + int socketd=0, *sock; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + id = arg1->value.lval; + fp = php3_list_find(id,&type); + if (type==GLOBAL(wsa_fp)){ + issock=1; + sock = php3_list_find(id,&type); + socketd=*sock; + } + if ((!fp || (type!=GLOBAL(le_fp) && type!=GLOBAL(le_pp))) && (!socketd || type!=GLOBAL(wsa_fp))) { + php3_error(E_WARNING,"Unable to find file identifier %d",id); + RETURN_FALSE; + } + size = 0; + if (php3_header()) { /* force headers if not already sent */ + while(issock?(b=SOCK_FGETS(buf,sizeof(buf),socketd)):(b = fread(buf, 1, sizeof(buf), fp)) > 0) { + PHPWRITE(buf,b); + size += b ; + } + } +/* + if (issock) { +#if WIN32|WINNT + closesocket(socketd); +#else + close(socketd); +#endif + } else { + fclose(fp); + } +*/ + php3_list_delete(id); + RETURN_LONG(size); +} +/* }}} */ + +/* {{{ proto int rename(string old_name, string new_name) +Rename a file */ +void php3_rename(INTERNAL_FUNCTION_PARAMETERS) { + pval *OLD, *NEW; + char *old, *new; + int ret; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &OLD, &NEW) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(OLD); + convert_to_string(NEW); + + old = OLD->value.str.val; + new = NEW->value.str.val; + + if (PG(safe_mode) &&(!_php3_checkuid(old,2))) { + RETURN_FALSE; + } + ret = rename(old, new); + + if (ret == -1) { + php3_error(E_WARNING, + "Rename failed (%s)", strerror(errno)); + RETURN_FALSE; + } + + RETVAL_TRUE; +} +/* }}} */ + +/* {{{ proto int copy(string source_file, string destination_file) +Copy a file */ +void php3_file_copy(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *source, *target; + char buffer[8192]; + int fd_s,fd_t,read_bytes; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &source, &target) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(source); + convert_to_string(target); + + if (PG(safe_mode) &&(!_php3_checkuid(source->value.str.val,2))) { + RETURN_FALSE; + } + +#if WIN32|WINNT + if ((fd_s=open(source->value.str.val,O_RDONLY|_O_BINARY))==-1) { +#else + if ((fd_s=open(source->value.str.val,O_RDONLY))==-1) { +#endif + php3_error(E_WARNING,"Unable to open '%s' for reading: %s",source->value.str.val,strerror(errno)); + RETURN_FALSE; + } +#if WIN32|WINNT + if ((fd_t=open(target->value.str.val,_O_WRONLY|_O_CREAT|_O_TRUNC|_O_BINARY,_S_IREAD|_S_IWRITE))==-1){ +#else + if ((fd_t=creat(target->value.str.val,0777))==-1) { +#endif + php3_error(E_WARNING,"Unable to create '%s': %s", target->value.str.val,strerror(errno)); + close(fd_s); + RETURN_FALSE; + } + + while ((read_bytes=read(fd_s,buffer,8192))!=-1 && read_bytes!=0) { + if (write(fd_t,buffer,read_bytes)==-1) { + php3_error(E_WARNING,"Unable to write to '%s': %s",target->value.str.val,strerror(errno)); + close(fd_s); + close(fd_t); + RETURN_FALSE; + } + } + + close(fd_s); + close(fd_t); + + RETVAL_TRUE; +} +/* }}} */ + +/* {{{ proto int fread(int fp, int length) +Binary-safe file read */ +void php3_fread(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg1, *arg2; + FILE *fp; + int id, len, type; + int issock=0; + int *sock, socketd=0; + PLS_FETCH(); + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg1); + convert_to_long(arg2); + id = arg1->value.lval; + len = arg2->value.lval; + + fp = php3_list_find(id,&type); + if (type==GLOBAL(wsa_fp)){ + issock=1; + sock = php3_list_find(id,&type); + socketd=*sock; + } + if ((!fp || (type!=GLOBAL(le_fp) && type!=GLOBAL(le_pp))) && (!socketd || type!=GLOBAL(wsa_fp))) { + php3_error(E_WARNING,"Unable to find file identifier %d",id); + RETURN_FALSE; + } + return_value->value.str.val = emalloc(sizeof(char) * (len + 1)); + /* needed because recv doesnt put a null at the end*/ + + if (!issock) { + return_value->value.str.len = fread(return_value->value.str.val, 1, len, fp); + return_value->value.str.val[return_value->value.str.len] = 0; + } else { + return_value->value.str.len = _php3_sock_fread(return_value->value.str.val, len, socketd); + } + if (PG(magic_quotes_runtime)) { + return_value->value.str.val = _php3_addslashes(return_value->value.str.val,return_value->value.str.len,&return_value->value.str.len,1); + } + return_value->type = IS_STRING; +} +/* }}} */ + +/* aparently needed for pdf to be compiled as a module under windows */ +PHPAPI int php3i_get_le_fp(void){ + TLS_VARS; + return GLOBAL(le_fp); +} + +/* + * Local variables: + * tab-width: 4 + * End: + */ diff --git a/ext/standard/file.h b/ext/standard/file.h new file mode 100644 index 0000000000..08f1440f13 --- /dev/null +++ b/ext/standard/file.h @@ -0,0 +1,65 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifndef _FILE_H +#define _FILE_H + +extern php3_module_entry php3_file_module_entry; +#define php3_file_module_ptr &php3_file_module_entry + +extern int php3_minit_file(INIT_FUNC_ARGS); +extern void php3_tempnam(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fopen(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fclose(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_popen(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_pclose(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_feof(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fread(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fgetc(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fgets(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fgetss(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fwrite(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_rewind(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_ftell(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fseek(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_mkdir(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_rmdir(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fpassthru(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_readfile(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fileumask(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_rename(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_file_copy(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_file(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_set_socket_blocking(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_set_socket_timeout(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_get_meta_tags(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _FILE_H */ diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c new file mode 100644 index 0000000000..9b4810f1cc --- /dev/null +++ b/ext/standard/filestat.c @@ -0,0 +1,509 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Author: Jim Winstead <jimw@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include "safe_mode.h" +#include "fopen-wrappers.h" +#include "php_globals.h" + +#include <stdlib.h> +#include <sys/stat.h> +#include <string.h> +#include <errno.h> +#include <ctype.h> +#include <time.h> + +#if HAVE_UNISTD_H +# include <unistd.h> +#endif + +#if HAVE_PWD_H +# if MSVC5 +# include "win32/pwd.h" +# else +# include <pwd.h> +# endif +#endif + +#if HAVE_GRP_H +# if MSVC5 +# include "win32/grp.h" +# else +# include <grp.h> +# endif +#endif + +#if HAVE_UTIME +# if MSVC5 +# include <sys/utime.h> +# else +# include <utime.h> +# endif +#endif + +#include "php3_filestat.h" + +#ifndef THREAD_SAFE +static char *CurrentStatFile=NULL; +# if MSVC5 +static unsigned int CurrentStatLength=0; +# else +static int CurrentStatLength=0; +# endif +static struct stat sb; +#if HAVE_SYMLINK +static struct stat lsb; +#endif +#endif + +#ifndef S_ISDIR +#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) +#endif +#ifndef S_ISREG +#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG) +#endif +#ifndef S_ISLNK +#define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK) +#endif + + +int php3_init_filestat(INIT_FUNC_ARGS) +{ + TLS_VARS; + + GLOBAL(CurrentStatFile)=NULL; + GLOBAL(CurrentStatLength)=0; + return SUCCESS; +} + + +int php3_shutdown_filestat(SHUTDOWN_FUNC_ARGS) +{ + TLS_VARS; + + if (GLOBAL(CurrentStatFile)) + efree (GLOBAL(CurrentStatFile)); + return SUCCESS; +} + +void php3_chgrp(INTERNAL_FUNCTION_PARAMETERS) +{ +#ifndef WINDOWS + pval *filename, *group; + gid_t gid; + struct group *gr=NULL; +#endif + int ret; + TLS_VARS; + ret = 0; +#ifndef WINDOWS + + if (ARG_COUNT(ht)!=2 || getParameters(ht,2,&filename,&group)==FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(filename); + if (group->type == IS_STRING) { + gr = getgrnam(group->value.str.val); + if (!gr) { + php3_error(E_WARNING, "unable to find gid for %s", + group->value.str.val); + RETURN_FALSE; + } + gid = gr->gr_gid; + } else { + convert_to_long(group); + gid = group->value.lval; + } + +/* #if PHP_SAFE_MODE */ + if (PG(safe_mode) &&(!_php3_checkuid(filename->value.str.val, 1))) { + RETURN_FALSE; + } +/* #endif */ + + /* Check the basedir */ + if (_php3_check_open_basedir(filename->value.str.val)) RETURN_FALSE; + + ret = chown(filename->value.str.val, -1, gid); + if (ret == -1) { + php3_error(E_WARNING, "chgrp failed: %s", strerror(errno)); + RETURN_FALSE; + } +#endif + RETURN_TRUE; +} + +void php3_chown(INTERNAL_FUNCTION_PARAMETERS) +{ +#ifndef WINDOWS + pval *filename, *user; + int ret; + uid_t uid; + struct passwd *pw = NULL; + TLS_VARS; + + if (ARG_COUNT(ht)!=2 || getParameters(ht,2,&filename,&user)==FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(filename); + if (user->type == IS_STRING) { + pw = getpwnam(user->value.str.val); + if (!pw) { + php3_error(E_WARNING, "unable to find uid for %s", + user->value.str.val); + RETURN_FALSE; + } + uid = pw->pw_uid; + } else { + convert_to_long(user); + uid = user->value.lval; + } + + if (PG(safe_mode) &&(!_php3_checkuid(filename->value.str.val, 1))) { + RETURN_FALSE; + } + + /* Check the basedir */ + if (_php3_check_open_basedir(filename->value.str.val)) RETURN_FALSE; + + ret = chown(filename->value.str.val, uid, -1); + if (ret == -1) { + php3_error(E_WARNING, "chown failed: %s", strerror(errno)); + RETURN_FALSE; + } +#else + TLS_VARS; +#endif + RETURN_TRUE; +} + +void php3_chmod(INTERNAL_FUNCTION_PARAMETERS) { + pval *filename, *mode; + int ret; + TLS_VARS; + + if (ARG_COUNT(ht)!=2 || getParameters(ht,2,&filename,&mode)==FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(filename); + convert_to_long(mode); + + if (PG(safe_mode) &&(!_php3_checkuid(filename->value.str.val, 1))) { + RETURN_FALSE; + } + + /* Check the basedir */ + if (_php3_check_open_basedir(filename->value.str.val)) RETURN_FALSE; + + ret = chmod(filename->value.str.val, mode->value.lval); + if (ret == -1) { + php3_error(E_WARNING, "chmod failed: %s", strerror(errno)); + RETURN_FALSE; + } + RETURN_TRUE; +} + +void php3_touch(INTERNAL_FUNCTION_PARAMETERS) { +#if HAVE_UTIME + pval *filename, *filetime; + int ret; + struct stat sb; + FILE *file; + struct utimbuf *newtime = NULL; + int ac = ARG_COUNT(ht); + TLS_VARS; + + if (ac == 1 && getParameters(ht,1,&filename) != FAILURE) { +#ifndef HAVE_UTIME_NULL + newtime = (struct utimbuf *)emalloc(sizeof(struct utimbuf)); + if (!newtime) { + php3_error(E_WARNING, "unable to emalloc memory for changing time"); + return; + } + newtime->actime = time(NULL); + newtime->modtime = newtime->actime; +#endif + } else if (ac == 2 && getParameters(ht,2,&filename,&filetime) != FAILURE) { + newtime = (struct utimbuf *)emalloc(sizeof(struct utimbuf)); + if (!newtime) { + php3_error(E_WARNING, "unable to emalloc memory for changing time"); + return; + } + convert_to_long(filetime); + newtime->actime = filetime->value.lval; + newtime->modtime = filetime->value.lval; + } else { + WRONG_PARAM_COUNT; + } + convert_to_string(filename); + + if (PG(safe_mode) &&(!_php3_checkuid(filename->value.str.val, 1))) { + if (newtime) efree(newtime); + RETURN_FALSE; + } + + /* Check the basedir */ + if (_php3_check_open_basedir(filename->value.str.val)) RETURN_FALSE; + + /* create the file if it doesn't exist already */ + ret = stat(filename->value.str.val, &sb); + if (ret == -1) { + file = fopen(filename->value.str.val, "w"); + if (file == NULL) { + php3_error(E_WARNING, "unable to create file %s because %s", filename->value.str.val, strerror(errno)); + if (newtime) efree(newtime); + RETURN_FALSE; + } + fclose(file); + } + + ret = utime(filename->value.str.val, newtime); + if (newtime) efree(newtime); + if (ret == -1) { + php3_error(E_WARNING, "utime failed: %s", strerror(errno)); + RETURN_FALSE; + } else { + RETURN_TRUE; + } +#endif +} + +void php3_clearstatcache(INTERNAL_FUNCTION_PARAMETERS) { + TLS_VARS; + + if (GLOBAL(CurrentStatFile)) { + efree(GLOBAL(CurrentStatFile)); + GLOBAL(CurrentStatFile) = NULL; + } +} + +static void _php3_stat(const char *filename, int type, pval *return_value) +{ + struct stat *stat_sb = &GLOBAL(sb); + TLS_VARS; + + if (!GLOBAL(CurrentStatFile) || strcmp(filename,GLOBAL(CurrentStatFile))) { + if (!GLOBAL(CurrentStatFile) + || strlen(filename) > GLOBAL(CurrentStatLength)) { + if (GLOBAL(CurrentStatFile)) efree(GLOBAL(CurrentStatFile)); + GLOBAL(CurrentStatLength) = strlen(filename); + GLOBAL(CurrentStatFile) = estrndup(filename,GLOBAL(CurrentStatLength)); + } else { + strcpy(GLOBAL(CurrentStatFile),filename); + } +#if HAVE_SYMLINK + GLOBAL(lsb).st_mode = 0; /* mark lstat buf invalid */ +#endif + if (stat(GLOBAL(CurrentStatFile),&GLOBAL(sb))==-1) { + if (type != 15 || errno != ENOENT) { /* fileexists() test must print no error */ + php3_error(E_NOTICE,"stat failed for %s (errno=%d - %s)",GLOBAL(CurrentStatFile),errno,strerror(errno)); + } + efree(GLOBAL(CurrentStatFile)); + GLOBAL(CurrentStatFile)=NULL; + RETURN_FALSE; + } + } + +#if HAVE_SYMLINK + if (8 == type /* filetype */ + || 14 == type /* is link */ + || 16 == type) { /* lstat */ + + /* do lstat if the buffer is empty */ + + if (!GLOBAL(lsb).st_mode) { + if (lstat(GLOBAL(CurrentStatFile),&GLOBAL(lsb)) == -1) { + php3_error(E_NOTICE,"lstat failed for %s (errno=%d - %s)",GLOBAL(CurrentStatFile),errno,strerror(errno)); + RETURN_FALSE; + } + } + } +#endif + + switch(type) { + case 0: /* fileperms */ + RETURN_LONG((long)GLOBAL(sb).st_mode); + case 1: /* fileinode */ + RETURN_LONG((long)GLOBAL(sb).st_ino); + case 2: /* filesize */ + RETURN_LONG((long)GLOBAL(sb).st_size); + case 3: /* fileowner */ + RETURN_LONG((long)GLOBAL(sb).st_uid); + case 4: /* filegroup */ + RETURN_LONG((long)GLOBAL(sb).st_gid); + case 5: /* fileatime */ + RETURN_LONG((long)GLOBAL(sb).st_atime); + case 6: /* filemtime */ + RETURN_LONG((long)GLOBAL(sb).st_mtime); + case 7: /* filectime */ + RETURN_LONG((long)GLOBAL(sb).st_ctime); + case 8: /* filetype */ +#if HAVE_SYMLINK + if (S_ISLNK(GLOBAL(lsb).st_mode)) { + RETURN_STRING("link",1); + } +#endif + switch(GLOBAL(sb).st_mode&S_IFMT) { + case S_IFIFO: RETURN_STRING("fifo",1); + case S_IFCHR: RETURN_STRING("char",1); + case S_IFDIR: RETURN_STRING("dir",1); + case S_IFBLK: RETURN_STRING("block",1); + case S_IFREG: RETURN_STRING("file",1); + } + php3_error(E_WARNING,"Unknown file type (%d)",GLOBAL(sb).st_mode&S_IFMT); + RETURN_STRING("unknown",1); + case 9: /*is writable*/ + RETURN_LONG((GLOBAL(sb).st_mode&S_IWRITE)!=0); + case 10: /*is readable*/ + RETURN_LONG((GLOBAL(sb).st_mode&S_IREAD)!=0); + case 11: /*is executable*/ + RETURN_LONG((GLOBAL(sb).st_mode&S_IEXEC)!=0 && !S_ISDIR(GLOBAL(sb).st_mode)); + case 12: /*is file*/ + RETURN_LONG(S_ISREG(GLOBAL(sb).st_mode)); + case 13: /*is dir*/ + RETURN_LONG(S_ISDIR(GLOBAL(sb).st_mode)); + case 14: /*is link*/ +#if HAVE_SYMLINK + RETURN_LONG(S_ISLNK(GLOBAL(lsb).st_mode)); +#else + RETURN_FALSE; +#endif + case 15: /*file exists*/ + RETURN_TRUE; /* the false case was done earlier */ + case 16: /* lstat */ +#if HAVE_SYMLINK + stat_sb = &GLOBAL(lsb); +#endif + /* FALLTHROUGH */ + case 17: /* stat */ + if (array_init(return_value) == FAILURE) { + RETURN_FALSE; + } + add_next_index_long(return_value, stat_sb->st_dev); + add_next_index_long(return_value, stat_sb->st_ino); + add_next_index_long(return_value, stat_sb->st_mode); + add_next_index_long(return_value, stat_sb->st_nlink); + add_next_index_long(return_value, stat_sb->st_uid); + add_next_index_long(return_value, stat_sb->st_gid); +#ifdef HAVE_ST_BLKSIZE + add_next_index_long(return_value, stat_sb->st_rdev); +#else + add_next_index_long(return_value, -1); +#endif + add_next_index_long(return_value, stat_sb->st_size); + add_next_index_long(return_value, stat_sb->st_atime); + add_next_index_long(return_value, stat_sb->st_mtime); + add_next_index_long(return_value, stat_sb->st_ctime); +#if HAVE_ST_BLKSIZE + add_next_index_long(return_value, stat_sb->st_blksize); +#else + add_next_index_long(return_value, -1); +#endif +#if HAVE_ST_BLOCKS + add_next_index_long(return_value, stat_sb->st_blocks); +#else + add_next_index_long(return_value, -1); +#endif + return; + } + php3_error(E_WARNING, "didn't understand stat call"); + RETURN_FALSE; +} + +/* another quickie macro to make defining similar functions easier */ +#define FileFunction(name, funcnum) \ +void name(INTERNAL_FUNCTION_PARAMETERS) { \ + pval *filename; \ + if (ARG_COUNT(ht)!=1 || getParameters(ht,1,&filename) == FAILURE) { \ + WRONG_PARAM_COUNT; \ + } \ + convert_to_string(filename); \ + _php3_stat(filename->value.str.val, funcnum, return_value); \ +} + +FileFunction(php3_fileperms,0) +FileFunction(php3_fileinode,1) +FileFunction(php3_filesize, 2) +FileFunction(php3_fileowner,3) +FileFunction(php3_filegroup,4) +FileFunction(php3_fileatime,5) +FileFunction(php3_filemtime,6) +FileFunction(php3_filectime,7) +FileFunction(php3_filetype, 8) +FileFunction(php3_iswritable, 9) +FileFunction(php3_isreadable,10) +FileFunction(php3_isexec,11) +FileFunction(php3_isfile,12) +FileFunction(php3_isdir,13) +FileFunction(php3_islink,14) +FileFunction(php3_fileexists,15) +FileFunction(php3_lstat,16) +FileFunction(php3_stat,17) + +function_entry php3_filestat_functions[] = { + {"fileatime", php3_fileatime, NULL}, + {"filectime", php3_filectime, NULL}, + {"filegroup", php3_filegroup, NULL}, + {"fileinode", php3_fileinode, NULL}, + {"filemtime", php3_filemtime, NULL}, + {"fileowner", php3_fileowner, NULL}, + {"fileperms", php3_fileperms, NULL}, + {"filesize", php3_filesize, NULL}, + {"filetype", php3_filetype, NULL}, + {"file_exists", php3_fileexists, NULL}, + {"is_writeable",php3_iswritable, NULL}, + {"is_readable", php3_isreadable, NULL}, + {"is_executable",php3_isexec, NULL}, + {"is_file", php3_isfile, NULL}, + {"is_dir", php3_isdir, NULL}, + {"is_link", php3_islink, NULL}, + {"stat", php3_stat, NULL}, + {"lstat", php3_lstat, NULL}, + {"chown", php3_chown, NULL}, + {"chgrp", php3_chgrp, NULL}, + {"chmod", php3_chmod, NULL}, + {"touch", php3_touch, NULL}, + {NULL, NULL, NULL} +}; + + +php3_module_entry php3_filestat_module_entry = { + "PHP_filestat", php3_filestat_functions, NULL, NULL, php3_init_filestat, php3_shutdown_filestat, NULL, STANDARD_MODULE_PROPERTIES +}; + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c new file mode 100644 index 0000000000..d6e3f3326f --- /dev/null +++ b/ext/standard/formatted_print.c @@ -0,0 +1,602 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Stig Sæther Bakken <ssb@guardian.no> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#include <math.h> /* modf() */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include "head.h" +#include "php3_string.h" +#include "zend_execute.h" +#include <stdio.h> + +#define ALIGN_LEFT 0 +#define ALIGN_RIGHT 1 +#define ADJ_WIDTH 1 +#define ADJ_PRECISION 2 +#define NUM_BUF_SIZE 500 +#define NDIG 80 +#define FLOAT_DIGITS 6 +#define FLOAT_PRECISION 6 +#define MAX_FLOAT_DIGITS 38 +#define MAX_FLOAT_PRECISION 40 + +#if 0 +/* trick to control varargs functions through cpp */ +# define PRINTF_DEBUG(arg) php3_printf arg +#else +# define PRINTF_DEBUG(arg) +#endif + +static char hexchars[] = "0123456789abcdef"; +static char HEXCHARS[] = "0123456789ABCDEF"; + + +/* + * cvt.c - IEEE floating point formatting routines for FreeBSD + * from GNU libc-4.6.27 + */ + +/* + * _php3_cvt converts to decimal + * the number of digits is specified by ndigit + * decpt is set to the position of the decimal point + * sign is set to 0 for positive, 1 for negative + */ +static char * +_php3_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag) +{ + register int r2; + double fi, fj; + register char *p, *p1; + /*THREADX*/ +#ifndef THREAD_SAFE + static char cvt_buf[NDIG]; +#endif + TLS_VARS; + + if (ndigits >= NDIG - 1) + ndigits = NDIG - 2; + r2 = 0; + *sign = 0; + p = &STATIC(cvt_buf)[0]; + if (arg < 0) { + *sign = 1; + arg = -arg; + } + arg = modf(arg, &fi); + p1 = &STATIC(cvt_buf)[NDIG]; + /* + * Do integer part + */ + if (fi != 0) { + p1 = &STATIC(cvt_buf)[NDIG]; + while (fi != 0) { + fj = modf(fi / 10, &fi); + *--p1 = (int) ((fj + .03) * 10) + '0'; + r2++; + } + while (p1 < &STATIC(cvt_buf)[NDIG]) + *p++ = *p1++; + } else if (arg > 0) { + while ((fj = arg * 10) < 1) { + arg = fj; + r2--; + } + } + p1 = &STATIC(cvt_buf)[ndigits]; + if (eflag == 0) + p1 += r2; + *decpt = r2; + if (p1 < &STATIC(cvt_buf)[0]) { + STATIC(cvt_buf)[0] = '\0'; + return (STATIC(cvt_buf)); + } + while (p <= p1 && p < &STATIC(cvt_buf)[NDIG]) { + arg *= 10; + arg = modf(arg, &fj); + *p++ = (int) fj + '0'; + } + if (p1 >= &STATIC(cvt_buf)[NDIG]) { + STATIC(cvt_buf)[NDIG - 1] = '\0'; + return (STATIC(cvt_buf)); + } + p = p1; + *p1 += 5; + while (*p1 > '9') { + *p1 = '0'; + if (p1 > STATIC(cvt_buf)) + ++ * --p1; + else { + *p1 = '1'; + (*decpt)++; + if (eflag == 0) { + if (p > STATIC(cvt_buf)) + *p = '0'; + p++; + } + } + } + *p = '\0'; + return (STATIC(cvt_buf)); +} + + +inline static void +_php3_sprintf_appendchar(char **buffer, int *pos, int *size, char add) +{ + if ((*pos + 1) >= *size) { + *size <<= 1; + PRINTF_DEBUG(("%s: ereallocing buffer to %d bytes\n", get_active_function_name(), *size)); + *buffer = erealloc(*buffer, *size); + } + PRINTF_DEBUG(("sprintf: appending '%c', pos=\n", add, *pos)); + (*buffer)[(*pos)++] = add; +} + + +inline static void +_php3_sprintf_appendstring(char **buffer, int *pos, int *size, char *add, + int min_width, int max_width, char padding, + int alignment, int len) +{ + register int npad = min_width - MIN(len,(max_width?max_width:len)); + + if (npad<0) { + npad=0; + } + + PRINTF_DEBUG(("sprintf: appendstring(%x, %d, %d, \"%s\", %d, '%c', %d)\n", + *buffer, *pos, *size, add, min_width, padding, alignment)); + if (max_width == 0) { + max_width = MAX(min_width,len); + } + if ((*pos + max_width) >= *size) { + while ((*pos + max_width) >= *size) { + *size <<= 1; + } + PRINTF_DEBUG(("sprintf ereallocing buffer to %d bytes\n", *size)); + *buffer = erealloc(*buffer, *size); + } + if (alignment == ALIGN_RIGHT) { + while (npad-- > 0) { + (*buffer)[(*pos)++] = padding; + } + } + PRINTF_DEBUG(("sprintf: appending \"%s\"\n", add)); + strncpy(&(*buffer)[*pos], add, max_width); + *pos += MIN(max_width,len); + if (alignment == ALIGN_LEFT) { + while (npad--) { + (*buffer)[(*pos)++] = padding; + } + } +} + + +inline static void +_php3_sprintf_appendint(char **buffer, int *pos, int *size, int number, + int width, char padding, int alignment) +{ + char numbuf[NUM_BUF_SIZE]; + register unsigned int magn, nmagn, i = NUM_BUF_SIZE - 1, neg = 0; + + PRINTF_DEBUG(("sprintf: appendint(%x, %x, %x, %d, %d, '%c', %d)\n", + *buffer, pos, size, number, width, padding, alignment)); + if (number < 0) { + neg = 1; + magn = ((unsigned int) -(number + 1)) + 1; + } else { + magn = (unsigned int) number; + } + + numbuf[i] = '\0'; + + do { + nmagn = magn / 10; + + numbuf[--i] = (magn - (nmagn * 10)) + '0'; + magn = nmagn; + } + while (magn > 0 && i > 0); + if (neg) { + numbuf[--i] = '-'; + } + PRINTF_DEBUG(("sprintf: appending %d as \"%s\", i=%d\n", + number, &numbuf[i], i)); + _php3_sprintf_appendstring(buffer, pos, size, &numbuf[i], width, 0, + padding, alignment, (NUM_BUF_SIZE - 1) - i); +} + + +inline static void +_php3_sprintf_appenddouble(char **buffer, int *pos, + int *size, double number, + int width, char padding, + int alignment, int precision, + int adjust, char fmt) +{ + char numbuf[NUM_BUF_SIZE]; + char *cvt; + register int i = 0, j = 0; + int sign, decpt; + + PRINTF_DEBUG(("sprintf: appenddouble(%x, %x, %x, %f, %d, '%c', %d, %c)\n", + *buffer, pos, size, number, width, padding, alignment, fmt)); + if ((adjust & ADJ_PRECISION) == 0) { + precision = FLOAT_PRECISION; + } else if (precision > MAX_FLOAT_PRECISION) { + precision = MAX_FLOAT_PRECISION; + } + cvt = _php3_cvt(number, precision, &decpt, &sign, (fmt == 'e')); + + if (sign) { + numbuf[i++] = '-'; + } + + if (fmt == 'f') { + if (decpt <= 0) { + numbuf[i++] = '0'; + if (precision > 0) { + int k = precision; + numbuf[i++] = '.'; + while ((decpt++ < 0) && k--) { + numbuf[i++] = '0'; + } + } + } else { + while (decpt-- > 0) + numbuf[i++] = cvt[j++]; + if (precision > 0) + numbuf[i++] = '.'; + } + } else { + numbuf[i++] = cvt[j++]; + if (precision > 0) + numbuf[i++] = '.'; + } + + while (cvt[j]) { + numbuf[i++] = cvt[j++]; + } + + numbuf[i] = '\0'; + + if (precision > 0) { + width += (precision + 1); + } + _php3_sprintf_appendstring(buffer, pos, size, numbuf, width, 0, padding, + alignment, i); +} + + +inline static void +_php3_sprintf_append2n(char **buffer, int *pos, int *size, int number, + int width, char padding, int alignment, int n, + char *chartable) +{ + char numbuf[NUM_BUF_SIZE]; + register unsigned int num, i = NUM_BUF_SIZE - 1, neg = 0; + register int andbits = (1 << n) - 1; + + PRINTF_DEBUG(("sprintf: append2n(%x, %x, %x, %d, %d, '%c', %d, %d, %x)\n", + *buffer, pos, size, number, width, padding, alignment, n, + chartable)); + PRINTF_DEBUG(("sprintf: append2n 2^%d andbits=%x\n", n, andbits)); + + if (number < 0) { + neg = 1; + num = ((unsigned int) -(number + 1)) + 1; + } else { + num = (unsigned int) number; + } + + numbuf[i] = '\0'; + + do { + numbuf[--i] = chartable[(num & andbits)]; + num >>= n; + } + while (num > 0); + + if (neg) { + numbuf[--i] = '-'; + } + _php3_sprintf_appendstring(buffer, pos, size, &numbuf[i], width, 0, + padding, alignment, (NUM_BUF_SIZE - 1) - i); +} + + +inline static int +_php3_sprintf_getnumber(char *buffer, int *pos) +{ + char *endptr; + register int num = strtol(&buffer[*pos], &endptr, 10); + register int i = 0; + + if (endptr != NULL) { + i = (endptr - &buffer[*pos]); + } + PRINTF_DEBUG(("sprintf_getnumber: number was %d bytes long\n", i)); + *pos += i; + return num; +} + + +/* + * New sprintf implementation for PHP. + * + * Modifiers: + * + * " " pad integers with spaces + * "-" left adjusted field + * n field size + * "."n precision (floats only) + * + * Type specifiers: + * + * "%" literal "%", modifiers are ignored. + * "b" integer argument is printed as binary + * "c" integer argument is printed as a single character + * "d" argument is an integer + * "f" the argument is a float + * "o" integer argument is printed as octal + * "s" argument is a string + * "x" integer argument is printed as lowercase hexadecimal + * "X" integer argument is printed as uppercase hexadecimal + * + */ +static char * +php3_formatted_print(int ht, int *len) +{ + pval **args; + int argc, size = 240, inpos = 0, outpos = 0; + int alignment, width, precision, currarg, adjusting; + char *format, *result, padding; + + argc = ARG_COUNT(ht); + + if (argc < 1) { + WRONG_PARAM_COUNT_WITH_RETVAL(NULL); + } + args = emalloc(argc * sizeof(pval *)); + + if (getParametersArray(ht, argc, args) == FAILURE) { + efree(args); + WRONG_PARAM_COUNT_WITH_RETVAL(NULL); + } + convert_to_string(args[0]); + format = args[0]->value.str.val; + result = emalloc(size); + + currarg = 1; + + while (format[inpos]) { + PRINTF_DEBUG(("sprintf: format[%d]='%c'\n", inpos, format[inpos])); + PRINTF_DEBUG(("sprintf: outpos=%d\n", outpos)); + if (format[inpos] != '%') { + _php3_sprintf_appendchar(&result, &outpos, &size, format[inpos++]); + } else if (format[inpos + 1] == '%') { + _php3_sprintf_appendchar(&result, &outpos, &size, '%'); + inpos += 2; + } else { + if (currarg >= argc && format[inpos + 1] != '%') { + efree(result); + efree(args); + php3_error(E_WARNING, "%s(): too few arguments",get_active_function_name()); + return NULL; + } + /* starting a new format specifier, reset variables */ + alignment = ALIGN_RIGHT; + adjusting = 0; + padding = ' '; + inpos++; /* skip the '%' */ + + PRINTF_DEBUG(("sprintf: first looking at '%c', inpos=%d\n", + format[inpos], inpos)); + if (isascii((int)format[inpos]) && !isalpha((int)format[inpos])) { + /* first look for modifiers */ + PRINTF_DEBUG(("sprintf: looking for modifiers\n" + "sprintf: now looking at '%c', inpos=%d\n", + format[inpos], inpos)); + for (;; inpos++) { + if (format[inpos] == ' ' || format[inpos] == '0') { + padding = format[inpos]; + } else if (format[inpos] == '-') { + alignment = ALIGN_LEFT; + /* space padding, the default */ + } else if (format[inpos] == '\'') { + padding = format[++inpos]; + } else { + PRINTF_DEBUG(("sprintf: end of modifiers\n")); + break; + } + } + PRINTF_DEBUG(("sprintf: padding='%c'\n", padding)); + PRINTF_DEBUG(("sprintf: alignment=%s\n", + (alignment == ALIGN_LEFT) ? "left" : "right")); + + + /* after modifiers comes width */ + if (isdigit((int)format[inpos])) { + PRINTF_DEBUG(("sprintf: getting width\n")); + width = _php3_sprintf_getnumber(format, &inpos); + adjusting |= ADJ_WIDTH; + } else { + width = 0; + } + PRINTF_DEBUG(("sprintf: width=%d\n", width)); + + /* after width comes precision */ + if (format[inpos] == '.') { + inpos++; + PRINTF_DEBUG(("sprintf: getting precision\n")); + if (isdigit((int)format[inpos])) { + precision = _php3_sprintf_getnumber(format, &inpos); + adjusting |= ADJ_PRECISION; + } else { + precision = 0; + } + } else { + precision = 0; + } + PRINTF_DEBUG(("sprintf: precision=%d\n", precision)); + } else { + width = precision = 0; + } + + if (format[inpos] == 'l') { + inpos++; + } + PRINTF_DEBUG(("sprintf: format character='%c'\n", format[inpos])); + /* now we expect to find a type specifier */ + switch (format[inpos]) { + case 's': + convert_to_string(args[currarg]); + _php3_sprintf_appendstring(&result, &outpos, &size, + args[currarg]->value.str.val, + width, precision, padding, + alignment, + args[currarg]->value.str.len); + break; + + case 'd': + convert_to_long(args[currarg]); + _php3_sprintf_appendint(&result, &outpos, &size, + args[currarg]->value.lval, + width, padding, alignment); + break; + + case 'e': + case 'f': + /* XXX not done */ + convert_to_double(args[currarg]); + _php3_sprintf_appenddouble(&result, &outpos, &size, + args[currarg]->value.dval, + width, padding, alignment, + precision, adjusting, + format[inpos]); + break; + + case 'c': + convert_to_long(args[currarg]); + _php3_sprintf_appendchar(&result, &outpos, &size, + (char) args[currarg]->value.lval); + break; + + case 'o': + convert_to_long(args[currarg]); + _php3_sprintf_append2n(&result, &outpos, &size, + args[currarg]->value.lval, + width, padding, alignment, 3, + hexchars); + break; + + case 'x': + convert_to_long(args[currarg]); + _php3_sprintf_append2n(&result, &outpos, &size, + args[currarg]->value.lval, + width, padding, alignment, 4, + hexchars); + break; + + case 'X': + convert_to_long(args[currarg]); + _php3_sprintf_append2n(&result, &outpos, &size, + args[currarg]->value.lval, + width, padding, alignment, 4, + HEXCHARS); + break; + + case 'b': + convert_to_long(args[currarg]); + _php3_sprintf_append2n(&result, &outpos, &size, + args[currarg]->value.lval, + width, padding, alignment, 1, + hexchars); + break; + + case '%': + _php3_sprintf_appendchar(&result, &outpos, &size, '%'); + + break; + default: + break; + } + currarg++; + inpos++; + } + } + + efree(args); + + /* possibly, we have to make sure we have room for the terminating null? */ + result[outpos]=0; + *len = outpos; + return result; +} + + +PHP_FUNCTION(user_sprintf) +{ + char *result; + int len; + TLS_VARS; + + if ((result=php3_formatted_print(ht,&len))==NULL) { + RETURN_FALSE; + } + RETVAL_STRINGL(result,len,1); + efree(result); +} + + +PHP_FUNCTION(user_printf) +{ + char *result; + int len; + TLS_VARS; + + if ((result=php3_formatted_print(ht,&len))==NULL) { + RETURN_FALSE; + } + PHPWRITE(result,len); + efree(result); +} + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c new file mode 100644 index 0000000000..e1f7f3f177 --- /dev/null +++ b/ext/standard/fsock.c @@ -0,0 +1,477 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-1999 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Paul Panotzki - Bunyip Information Systems | + | Jim Winstead (jimw@php.net) | + +----------------------------------------------------------------------+ +*/ +/* $Id$ */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include <stdlib.h> +#if HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <sys/types.h> +#if HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef WIN32 +#include <winsock.h> +#else +#include <netinet/in.h> +#include <netdb.h> +#include <arpa/inet.h> +#endif +#ifdef WIN32 +#undef AF_UNIX +#endif +#if defined(AF_UNIX) +#include <sys/un.h> +#endif + +#include <string.h> +#include <errno.h> + +#include "base64.h" +#include "file.h" +#include "post.h" +#include "url.h" +#include "fsock.h" + +#ifndef THREAD_SAFE +extern int le_fp; +#endif + +#define FREE_SOCK if(socketd >= 0) close(socketd); efree(sock); if (key) efree(key) + +#if WIN32|WINNT +#define EWOULDBLOCK WSAEWOULDBLOCK +#else +#include "build-defs.h" +#endif + +static unsigned char third_and_fourth_args_force_ref[] = { 4, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYREF_FORCE }; + +function_entry fsock_functions[] = { + PHP_FE(fsockopen, third_and_fourth_args_force_ref) + PHP_FE(pfsockopen, third_and_fourth_args_force_ref) + {NULL, NULL, NULL} +}; + +struct php3i_sockbuf { + int socket; + char *readbuf; + size_t readbuflen; + size_t readpos; + size_t writepos; + struct php3i_sockbuf *next; +}; + +static struct php3i_sockbuf *phpsockbuf; + +static int php3_minit_fsock(INIT_FUNC_ARGS); +static int php3_mshutdown_fsock(void); +static int php3_rshutdown_fsock(void); + +php3_module_entry fsock_module_entry = { + "Socket functions", fsock_functions, php3_minit_fsock, php3_mshutdown_fsock, NULL, php3_rshutdown_fsock, NULL, STANDARD_MODULE_PROPERTIES +}; + +#ifndef THREAD_SAFE +static HashTable ht_keys; +static HashTable ht_socks; +#endif + +/* {{{ lookup_hostname */ + +/* + * Converts a host name to an IP address. + */ +int lookup_hostname(const char *addr, struct in_addr *in) +{ + struct hostent *host_info; + + if(!inet_aton(addr, in)) { + host_info = gethostbyname(addr); + if (host_info == 0) { + /* Error: unknown host */ + return -1; + } + *in = *((struct in_addr *) host_info->h_addr); + } + return 0; +} +/* }}} */ +/* {{{ _php3_is_persistent_sock */ + +int _php3_is_persistent_sock(int sock) +{ + char *key; + + if (_php3_hash_find(&ht_socks, (char *) &sock, sizeof(sock), + (void **) &key) == SUCCESS) { + return 1; + } + return 0; +} +/* }}} */ +/* {{{ _php3_fsockopen() */ + +/* + This function takes an optional third argument which should be + passed by reference. The error code from the connect call is written + to this variable. +*/ +static void _php3_fsockopen(INTERNAL_FUNCTION_PARAMETERS, int persistent) { + pval *args[4]; + int *sock=emalloc(sizeof(int)); + int *sockp; + int id, arg_count=ARG_COUNT(ht); + int socketd = -1; + unsigned short portno; + char *key = NULL; + TLS_VARS; + + if (arg_count > 4 || arg_count < 2 || getParametersArray(ht,arg_count,args)==FAILURE) { + FREE_SOCK; + WRONG_PARAM_COUNT; + } + switch(arg_count) { + case 4: + if(!ParameterPassedByReference(ht,4)) { + php3_error(E_WARNING,"error string argument to fsockopen not passed by reference"); + } + pval_copy_constructor(args[3]); + args[3]->value.str.val = empty_string; + args[3]->value.str.len = 0; + args[3]->type = IS_STRING; + /* fall-through */ + case 3: + if(!ParameterPassedByReference(ht,3)) { + php3_error(E_WARNING,"error argument to fsockopen not passed by reference"); + } + args[2]->type = IS_LONG; + args[2]->value.lval = 0; + break; + } + convert_to_string(args[0]); + convert_to_long(args[1]); + portno = (unsigned short) args[1]->value.lval; + + key = emalloc(args[0]->value.str.len + 10); + sprintf(key, "%s:%d", args[0]->value.str.val, portno); + + if (persistent && _php3_hash_find(&ht_keys, key, strlen(key) + 1, + (void *) &sockp) == SUCCESS) { + efree(key); + *sock = *sockp; + RETURN_LONG(php3_list_insert(sock, GLOBAL(wsa_fp))); + } + + if (portno) { + struct sockaddr_in server; + + memset(&server, 0, sizeof(server)); + socketd = socket(AF_INET, SOCK_STREAM, 0); + if (socketd == SOCK_ERR) { + FREE_SOCK; + RETURN_FALSE; + } + + server.sin_family = AF_INET; + + if (lookup_hostname(args[0]->value.str.val, &server.sin_addr)) { + FREE_SOCK; + RETURN_FALSE; + } + + server.sin_port = htons(portno); + + if (connect(socketd, (struct sockaddr *)&server, sizeof(server)) == SOCK_CONN_ERR) { + FREE_SOCK; + if(arg_count>2) args[2]->value.lval = errno; + if(arg_count>3) { + args[3]->value.str.val = estrdup(strerror(errno)); + args[3]->value.str.len = strlen(args[3]->value.str.val); + } + RETURN_FALSE; + } +#if defined(AF_UNIX) + } else { + /* Unix domain socket. s->strval is socket name. */ + struct sockaddr_un unix_addr; + socketd = socket(AF_UNIX,SOCK_STREAM,0); + if (socketd == SOCK_ERR) { + FREE_SOCK; + RETURN_FALSE; + } + + memset(&unix_addr,(char)0,sizeof(unix_addr)); + unix_addr.sun_family = AF_UNIX; + strcpy(unix_addr.sun_path, args[0]->value.str.val); + + if (connect(socketd, (struct sockaddr *) &unix_addr, sizeof(unix_addr)) == SOCK_CONN_ERR) { + FREE_SOCK; + if(arg_count>2) args[2]->value.lval = errno; + if(arg_count>3) { + args[3]->value.str.val = estrdup(strerror(errno)); + args[3]->value.str.len = strlen(args[3]->value.str.val); + } + RETURN_FALSE; + } +#endif /* AF_UNIX */ + } + +#if 0 + if ((fp = fdopen (socketd, "r+")) == NULL){ + RETURN_LONG(-6); /* FIXME */ + } + +#ifdef HAVE_SETVBUF + if ((setvbuf(fp, NULL, _IONBF, 0)) != 0){ + RETURN_LONG(-7); /* FIXME */ + } +#endif +#endif + + *sock=socketd; + if (persistent) { + _php3_hash_update(&ht_keys, key, strlen(key) + 1, + sock, sizeof(*sock), NULL); + _php3_hash_update(&ht_socks, (char *) sock, sizeof(*sock), + key, strlen(key) + 1, NULL); + } + if(key) efree(key); + id = php3_list_insert(sock,GLOBAL(wsa_fp)); + RETURN_LONG(id); +} +/* }}} */ + +/* {{{ proto int fsockopen(string hostname, int port [, int errno [, string errstr]]) + Open Internet or Unix domain socket connection */ +PHP_FUNCTION(fsockopen) +{ + _php3_fsockopen(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ +/* {{{ proto int pfsockopen(string hostname, int port [, int errno [, string errstr]]) + Open persistent Internet or Unix domain socket connection */ +PHP_FUNCTION(pfsockopen) +{ + _php3_fsockopen(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* Known issues with the socket buffering code: + * - does not work reliably with persistent sockets yet + * (buffered data is not persistent) + * - php3_fopen_url_wrapper() is still doing single-byte lookahead/read + */ +/* {{{ _php3_sock_fgets() */ + +int _php3_sock_fgets(char *buf, int maxlen, int socket) +{ + struct php3i_sockbuf *sockbuf = NULL, *tmpsockbuf; + int bytesread, toread, len, buflen, count = 0; + char *nl; + + tmpsockbuf = phpsockbuf; + while (tmpsockbuf) { + if (tmpsockbuf->socket == socket) { + sockbuf = tmpsockbuf; + break; + } + tmpsockbuf = tmpsockbuf->next; + } + + if (sockbuf) { + toread = sockbuf->writepos - sockbuf->readpos; + if (toread > maxlen) { + toread = maxlen; + } + if ((nl = memchr(sockbuf->readbuf + sockbuf->readpos, '\n', toread)) != NULL) { + toread = (nl - (sockbuf->readbuf + sockbuf->readpos)) + 1; + } + memcpy(buf, sockbuf->readbuf + sockbuf->readpos, toread); + sockbuf->readpos += toread; + count += toread; + buf += toread; + if (sockbuf->readpos >= sockbuf->writepos) { + sockbuf->readpos = sockbuf->writepos = 0; + } + if (nl != NULL) { + /* if a newline was found, skip the recv() loop */ + goto sock_fgets_exit; + } + } + + nl = NULL; + buflen = 0; + while (count < maxlen && nl == NULL) { + toread = maxlen - count; + bytesread = recv(socket, buf, toread, 0); + if (bytesread <= 0) { + break; + } + if ((nl = memchr(buf, '\n', bytesread)) != NULL) { + len = (nl - buf) + 1; + count += len; + buf += len; + if (len < bytesread) { + buflen = bytesread - len; + break; + } + } else { + count += bytesread; + buf += bytesread; + } + } + + if (buflen > 0) { /* there was data after the "\n" ... */ + if (sockbuf == NULL) { + sockbuf = emalloc(sizeof(struct php3i_sockbuf)); + sockbuf->socket = socket; + sockbuf->readbuf = emalloc(maxlen); + sockbuf->readbuflen = maxlen; + sockbuf->readpos = sockbuf->writepos = 0; + sockbuf->next = phpsockbuf; + phpsockbuf = sockbuf; + } else { + int needlen = sockbuf->writepos + buflen; + if (needlen > sockbuf->readbuflen) { + sockbuf->readbuflen += maxlen; + sockbuf->readbuf = erealloc(sockbuf->readbuf, sockbuf->readbuflen); + } + } + memcpy(sockbuf->readbuf + sockbuf->writepos, buf, buflen); + sockbuf->writepos += buflen; + } + + sock_fgets_exit: + *buf = '\0'; + return count; +} + +/* }}} */ +/* {{{ _php3_sock_fread() */ + +int _php3_sock_fread(char *buf, int maxlen, int socket) +{ + struct php3i_sockbuf *sockbuf = phpsockbuf; + int bytesread, toread, count = 0; + + while (sockbuf) { + if (sockbuf->socket == socket) { + toread = sockbuf->writepos - sockbuf->readpos; + if (toread > maxlen) { + toread = maxlen; + } + memcpy(buf, sockbuf->readbuf + sockbuf->readpos, toread); + sockbuf->readpos += toread; + count += toread; + buf += toread; + break; + } + sockbuf = sockbuf->next; + } + + while (count < maxlen) { + toread = maxlen - count; + bytesread = recv(socket, buf, toread, 0); + if (bytesread <= 0) { + break; + } + count += bytesread; + buf += bytesread; + } + + *buf = '\0'; + return count; +} + +/* }}} */ +/* {{{ module start/shutdown functions */ + + /* {{{ _php3_sock_destroy */ +#ifndef THREAD_SAFE +static void _php3_sock_destroy(void *data) +{ + int *sock = (int *) data; + close(*sock); +} +#endif +/* }}} */ + /* {{{ php3_minit_fsock */ + +static int php3_minit_fsock(INIT_FUNC_ARGS) +{ +#ifndef THREAD_SAFE + _php3_hash_init(&ht_keys, 0, NULL, NULL, 1); + _php3_hash_init(&ht_socks, 0, NULL, _php3_sock_destroy, 1); +#endif + return SUCCESS; +} +/* }}} */ + /* {{{ php3_mshutdown_fsock */ + +static int php3_mshutdown_fsock(void) +{ +#ifndef THREAD_SAFE + _php3_hash_destroy(&ht_socks); + _php3_hash_destroy(&ht_keys); +#endif + return SUCCESS; +} +/* }}} */ + /* {{{ php3_rshutdown_fsock() */ + +static int php3_rshutdown_fsock(void) +{ + struct php3i_sockbuf *sockbuf = phpsockbuf, *this; + + while (sockbuf) { + this = sockbuf; + sockbuf = this->next; + efree(this->readbuf); + efree(this); + } + phpsockbuf = NULL; + return SUCCESS; +} + +/* }}} */ + +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/fsock.h b/ext/standard/fsock.h new file mode 100644 index 0000000000..9be93a34a6 --- /dev/null +++ b/ext/standard/fsock.h @@ -0,0 +1,47 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-1999 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Paul Panotzki - Bunyip Information Systems | + | Jim Winstead (jimw@php.net) | + +----------------------------------------------------------------------+ +*/ +/* $Id$ */ + +#ifndef _FSOCK_H +#define _FSOCK_H + +#include <netinet/in.h> + +extern php3_module_entry fsock_module_entry; +#define fsock_module_ptr &fsock_module_entry + +extern PHP_FUNCTION(fsockopen); +extern PHP_FUNCTION(pfsockopen); +extern int lookup_hostname(const char *addr, struct in_addr *in); +extern int _php3_sock_fgets(char *buf, int maxlen, int socket); +extern int _php3_sock_fread(char *buf, int maxlen, int socket); +extern int _php3_is_persistent_sock(int); + +#endif /* _FSOCK_H */ diff --git a/ext/standard/global.h b/ext/standard/global.h new file mode 100644 index 0000000000..cc528d4b6b --- /dev/null +++ b/ext/standard/global.h @@ -0,0 +1,58 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + +----------------------------------------------------------------------+ + */ +/* GLOBAL.H - RSAREF types and constants + */ + +/* PROTOTYPES should be set to one if and only if the compiler supports + function argument prototyping. + The following makes PROTOTYPES default to 0 if it has not already + been defined with C compiler flags. + */ +#ifndef PROTOTYPES +#define PROTOTYPES 1 /* php3 has prototypes everywhere */ +#endif + +/* _POINTER defines a generic pointer type */ +typedef unsigned char *_POINTER; + +/* UINT2 defines a two byte word */ +typedef unsigned short int UINT2; + +/* UINT4 defines a four byte word */ +typedef unsigned long int UINT4; + +/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. + If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it + returns an empty list. + */ +#if PROTOTYPES +#define PROTO_LIST(list) list +#else +#define PROTO_LIST(list) () +#endif diff --git a/ext/standard/html.c b/ext/standard/html.c new file mode 100644 index 0000000000..f15131523d --- /dev/null +++ b/ext/standard/html.c @@ -0,0 +1,134 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + | Jaakko Hyvätti <jaakko.hyvatti@iki.fi> | + +----------------------------------------------------------------------+ + */ + +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include "reg.h" +#include "html.h" + +/* This must be fixed to handle the input string according to LC_CTYPE. + Defaults to ISO-8859-1 for now. */ + +static char EntTable[][7] = +{ + "nbsp","iexcl","cent","pound","curren","yen","brvbar", + "sect","uml","copy","ordf","laquo","not","shy","reg", + "macr","deg","plusmn","sup2","sup3","acute","micro", + "para","middot","cedil","sup1","ordm","raquo","frac14", + "frac12","frac34","iquest","Agrave","Aacute","Acirc", + "Atilde","Auml","Aring","AElig","Ccedil","Egrave", + "Eacute","Ecirc","Euml","Igrave","Iacute","Icirc", + "Iuml","ETH","Ntilde","Ograve","Oacute","Ocirc","Otilde", + "Ouml","times","Oslash","Ugrave","Uacute","Ucirc","Uuml", + "Yacute","THORN","szlig","agrave","aacute","acirc", + "atilde","auml","aring","aelig","ccedil","egrave", + "eacute","ecirc","euml","igrave","iacute","icirc", + "iuml","eth","ntilde","ograve","oacute","ocirc","otilde", + "ouml","divide","oslash","ugrave","uacute","ucirc", + "uuml","yacute","thorn","yuml" +}; + +static void _php3_htmlentities(INTERNAL_FUNCTION_PARAMETERS, int all) +{ + pval *arg; + int i, len, maxlen; + unsigned char *old; + char *new; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(arg); + + maxlen = 2 * arg->value.str.len; + if (maxlen < 128) + maxlen = 128; + new = emalloc (maxlen); + len = 0; + + old = (unsigned char *)arg->value.str.val; + i = arg->value.str.len; + while (i--) { + if (len + 9 > maxlen) + new = erealloc (new, maxlen += 128); + if (38 == *old) { + memcpy (new + len, "&", 5); + len += 5; + } else if (34 == *old) { + memcpy (new + len, """, 6); + len += 6; + } else if (60 == *old) { + memcpy (new + len, "<", 4); + len += 4; + } else if (62 == *old) { + memcpy (new + len, ">", 4); + len += 4; + } else if (all && 160 <= *old) { + new [len++] = '&'; + strcpy (new + len, EntTable [*old - 160]); + len += strlen (EntTable [*old - 160]); + new [len++] = ';'; + } else { + new [len++] = *old; + } + old++; + } + new [len] = '\0'; + + RETVAL_STRINGL(new,len,1); + efree(new); +} + +/* {{{ proto string htmlspecialchars(string string) + Convert special characters to HTML entities */ +void php3_htmlspecialchars(INTERNAL_FUNCTION_PARAMETERS) +{ + _php3_htmlentities(INTERNAL_FUNCTION_PARAM_PASSTHRU,0); +} +/* }}} */ + +/* {{{ proto string htmlentities(string string) + Convert all applicable characters to HTML entities */ +void php3_htmlentities(INTERNAL_FUNCTION_PARAMETERS) +{ + _php3_htmlentities(INTERNAL_FUNCTION_PARAM_PASSTHRU,1); +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/html.h b/ext/standard/html.h new file mode 100644 index 0000000000..892dfb6bed --- /dev/null +++ b/ext/standard/html.h @@ -0,0 +1,38 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifndef _HTML_H +#define _HTML_H + +extern void php3_htmlspecialchars(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_htmlentities(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _HTML_H */ diff --git a/ext/standard/image.c b/ext/standard/image.c new file mode 100644 index 0000000000..a91607f3e7 --- /dev/null +++ b/ext/standard/image.c @@ -0,0 +1,386 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ +/* + * Based on Daniel Schmitt's imageinfo.c which carried the following + * Copyright notice. + */ + +/* + * imageinfo.c + * + * Simple routines to extract image width/height data from GIF/JPEG files. + * + * Copyright (c) 1997 Daniel Schmitt, opal online publishing, Bonn, Germany. + * + * Includes code snippets from rdjpgcom.c, + * Copyright (c) 1994-1995 Thomas G. Lane + * from release 6a of the Independent JPEG Group's software. + * + * Legal status: see GNU General Public License version 2 or later. + * + */ + +#include "php.h" +#include <stdio.h> +#if HAVE_FCNTL_H +#include <fcntl.h> +#endif +#include "fopen-wrappers.h" +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +#include "image.h" + +/* file type markers */ +const char php3_sig_gif[3] = +{'G', 'I', 'F'}; +const char php3_sig_jpg[3] = +{(char) 0xff, (char) 0xd8, (char) 0xff}; +const char php3_sig_png[8] = +{(char) 0x89, (char) 0x50, (char) 0x4e, + (char) 0x47, (char) 0x0d, (char) 0x0a, + (char) 0x1a, (char) 0x0a}; + +/* return info as a struct, to make expansion easier */ + +struct gfxinfo { + unsigned int width; + unsigned int height; +}; + +/* routine to handle GIF files. If only everything were that easy... ;} */ +static struct gfxinfo *php3_handle_gif (FILE *fp) +{ + struct gfxinfo *result = NULL; + unsigned char a[2]; + + result = (struct gfxinfo *) emalloc(sizeof(struct gfxinfo)); + fseek(fp, 6L, SEEK_SET); + fread(a,sizeof(a),1,fp); + result->width = (unsigned short)a[0] | (((unsigned short)a[1])<<8); + fread(a,sizeof(a),1,fp); + result->height = (unsigned short)a[0] | (((unsigned short)a[1])<<8); + return result; +} + +static unsigned long php3_read4(FILE *fp) +{ + unsigned char a[ 4 ]; + + /* just return 0 if we hit the end-of-file */ + if (fread(a,sizeof(a),1,fp) != 1) return 0; + + return (((unsigned long) a[ 0 ]) << 24) + (((unsigned long) a[ 1 ]) << 16) + (((unsigned long) a[ 2 ]) << 8) + ((unsigned long) a[ 3 ]); + +} + +/* routine to handle PNG files. - even easier */ +static struct gfxinfo *php3_handle_png(FILE *fp) +{ + struct gfxinfo *result = NULL; + unsigned long in_width, in_height; + + result = (struct gfxinfo *) emalloc(sizeof(struct gfxinfo)); + fseek(fp, 16L, SEEK_SET); + in_width = php3_read4(fp); + in_height = php3_read4(fp); + result->width = (unsigned int) in_width; + result->height = (unsigned int) in_height; + return result; +} + +/* routines to handle JPEG data */ + +/* some defines for the different JPEG block types */ +#define M_SOF0 0xC0 /* Start Of Frame N */ +#define M_SOF1 0xC1 /* N indicates which compression process */ +#define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */ +#define M_SOF3 0xC3 +#define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */ +#define M_SOF6 0xC6 +#define M_SOF7 0xC7 +#define M_SOF9 0xC9 +#define M_SOF10 0xCA +#define M_SOF11 0xCB +#define M_SOF13 0xCD +#define M_SOF14 0xCE +#define M_SOF15 0xCF +#define M_SOI 0xD8 +#define M_EOI 0xD9 /* End Of Image (end of datastream) */ +#define M_SOS 0xDA /* Start Of Scan (begins compressed data) */ +#define M_APP0 0xe0 +#define M_APP1 0xe1 +#define M_APP2 0xe2 +#define M_APP3 0xe3 +#define M_APP4 0xe4 +#define M_APP5 0xe5 +#define M_APP6 0xe6 +#define M_APP7 0xe7 +#define M_APP8 0xe8 +#define M_APP9 0xe9 +#define M_APP10 0xea +#define M_APP11 0xeb +#define M_APP12 0xec +#define M_APP13 0xed +#define M_APP14 0xee +#define M_APP15 0xef + +static unsigned short php3_read2(FILE *fp) +{ + unsigned char a[ 2 ]; + + /* just return 0 if we hit the end-of-file */ + if (fread(a,sizeof(a),1,fp) != 1) return 0; + + return (((unsigned short) a[ 0 ]) << 8) + ((unsigned short) a[ 1 ]); +} + +static unsigned int php3_next_marker(FILE *fp) + /* get next marker byte from file */ +{ + int c; + + /* skip unimportant stuff */ + + c = getc(fp); + + while (c != 0xff) { + if ((c = getc(fp)) == EOF) + return M_EOI; /* we hit EOF */ + } + + /* get marker byte, swallowing possible padding */ + do { + if ((c = getc(fp)) == EOF) + return M_EOI; /* we hit EOF */ + } while (c == 0xff); + + return (unsigned int) c; +} + +static void php3_skip_variable(FILE *fp) + /* skip over a variable-length block; assumes proper length marker */ +{ + unsigned short length; + + length = php3_read2(fp); + length -= 2; /* length includes itself */ + fseek(fp, (long) length, SEEK_CUR); /* skip the header */ +} + +static void php3_read_APP(FILE *fp,unsigned int marker,pval *info) +{ + unsigned short length; + unsigned char *buffer; + unsigned char markername[ 16 ]; + + length = php3_read2(fp); + length -= 2; /* length includes itself */ + + buffer = emalloc(length); + + if (fread(buffer,length,1,fp) != 1) { + return; + } + + sprintf(markername,"APP%d",marker - M_APP0); + + add_assoc_stringl(info,markername,buffer,length,1); + + efree(buffer); +} + +static struct gfxinfo *php3_handle_jpeg(FILE *fp,pval *info) + /* main loop to parse JPEG structure */ +{ + struct gfxinfo *result = NULL; + unsigned int marker; + unsigned short in_width, in_height; + + fseek(fp, 0L, SEEK_SET); /* position file pointer on SOF */ + + if (getc(fp) != 0xFF) /* JPEG header... */ + return NULL; + + if (getc(fp) != M_SOI) /* JPEG header... */ + return NULL; + + for (;;) { + marker = php3_next_marker(fp); + switch (marker) { + case M_SOF0: + case M_SOF1: + case M_SOF2: + case M_SOF3: + case M_SOF5: + case M_SOF6: + case M_SOF7: + case M_SOF9: + case M_SOF10: + case M_SOF11: + case M_SOF13: + case M_SOF14: + case M_SOF15: + if (result == NULL) { + /* handle SOFn block */ + fseek(fp, 3L, SEEK_CUR); /* skip length and precision bytes */ + in_height = php3_read2(fp); + in_width = php3_read2(fp); + /* fill a gfxinfo struct to return the data */ + result = (struct gfxinfo *) emalloc(sizeof(struct gfxinfo)); + + result->width = (unsigned int) in_width; + result->height = (unsigned int) in_height; + + if (! info) /* if we don't want an extanded info -> return */ + return result; + } else { + php3_skip_variable(fp); + } + break; + + case M_APP0: + case M_APP1: + case M_APP2: + case M_APP3: + case M_APP4: + case M_APP5: + case M_APP6: + case M_APP7: + case M_APP8: + case M_APP9: + case M_APP10: + case M_APP11: + case M_APP12: + case M_APP13: + case M_APP14: + case M_APP15: + if (info) { + php3_read_APP(fp,marker,info); /* read all the app markes... */ + } else { + php3_skip_variable(fp); + } + break; + + case M_SOS: + case M_EOI: + return result; /* we're about to hit image data, or are at EOF. stop processing. */ + break; + + default: + php3_skip_variable(fp); /* anything else isn't interesting */ + break; + } + } + + return NULL; +} + +/* main function */ +void php3_getimagesize(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg1,*info = 0; + FILE *fp; + int itype = 0; + char filetype[3]; + char pngtype[8]; + char temp[64]; + struct gfxinfo *result = NULL; + + switch(ARG_COUNT(ht)){ + case 1: + if (getParameters(ht, 1, &arg1) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg1); + break; + + case 2: + if (getParameters(ht, 2, &arg1, &info) == FAILURE) { + WRONG_PARAM_COUNT; + } + if (!ParameterPassedByReference(ht, 2)) { + php3_error(E_WARNING, "Array to be filled with values must be passed by reference."); + RETURN_FALSE; + } + + pval_destructor(info _INLINE_TLS); + if (array_init(info) == FAILURE) { + return; + } + + convert_to_string(arg1); + break; + + default: + WRONG_PARAM_COUNT; + break; + } + + /* Check open_basedir */ + if (_php3_check_open_basedir(arg1->value.str.val)) return; + + if ((fp = fopen(arg1->value.str.val,"rb")) == 0) { + php3_error(E_WARNING, "Unable to open %s", arg1->value.str.val); + return; + } + fread(filetype,sizeof(filetype),1,fp); + if (!memcmp(filetype, php3_sig_gif, 3)) { + result = php3_handle_gif (fp); + itype = 1; + } else if (!memcmp(filetype, php3_sig_jpg, 3)) { + result = php3_handle_jpeg(fp,info); + itype = 2; + } else if (!memcmp(filetype, php3_sig_png, 3)) { + fseek(fp, 0L, SEEK_SET); + fread(pngtype, sizeof(pngtype), 1, fp); + if (!memcmp(pngtype, php3_sig_png, 8)) { + result = php3_handle_png(fp); + itype = 3; + } else { + php3_error(E_WARNING, "PNG file corrupted by ASCII conversion"); + } + } + fclose(fp); + if (result) { + if (array_init(return_value) == FAILURE) { + php3_error(E_ERROR, "Unable to initialize array"); + if (result) efree(result); + return; + } + add_index_long(return_value, 0, result->width); + add_index_long(return_value, 1, result->height); + add_index_long(return_value, 2, itype); + sprintf(temp, "width=\"%d\" height=\"%d\"", result->width, result->height); /* safe */ + add_index_string(return_value, 3, temp, 1); + + efree(result); + } +} diff --git a/ext/standard/image.h b/ext/standard/image.h new file mode 100644 index 0000000000..f006ceba43 --- /dev/null +++ b/ext/standard/image.h @@ -0,0 +1,36 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ + +#ifndef _IMAGE_H +#define _IMAGE_H + +extern void php3_getimagesize(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _IMAGE_H */ diff --git a/ext/standard/info.c b/ext/standard/info.c new file mode 100644 index 0000000000..9d5ff9dfe0 --- /dev/null +++ b/ext/standard/info.c @@ -0,0 +1,438 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + | Zeev Suraski <zeev@zend.com> | + +----------------------------------------------------------------------+ + */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include "php_ini.h" +#include "php_globals.h" +#include "head.h" +#include "info.h" +#ifndef MSVC5 +#include "build-defs.h" +#endif +#include "zend_globals.h" /* needs ELS */ + + +#define PHP3_CONF_STR(directive,value1,value2) \ + PUTS("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">"); \ + PUTS(directive); \ + PUTS("</td><td bgcolor=\"" CONTENTS_COLOR "\"> "); \ + if (value1) PUTS(value1); \ + else PUTS("<i>none</i>"); \ + PUTS("</td><td bgcolor=\"" CONTENTS_COLOR "\"> "); \ + if (value2) PUTS(value2); \ + else PUTS("<i>none</i>"); \ + PUTS("</td></tr>\n"); + +#define PHP3_CONF_LONG(directive,value1,value2) \ + php3_printf("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">%s</td><td bgcolor=\"" CONTENTS_COLOR "\">%ld</td><td bgcolor=\"" CONTENTS_COLOR "\">%ld</td></tr>\n",directive,value1,value2); + +extern char **environ; + +#define SECTION(name) PUTS("<hr><h2>" name "</h2>\n") + +#define ENTRY_NAME_COLOR "#999999" +#define CONTENTS_COLOR "#DDDDDD" +#define HEADER_COLOR "#00DDDD" + +static int _display_module_info(php3_module_entry *module) +{ + PUTS("<tr><th align=left bgcolor=\"" ENTRY_NAME_COLOR "\">"); + PUTS(module->name); + PUTS("</th><td bgcolor=\"" CONTENTS_COLOR "\">"); + if (module->info_func) { + module->info_func(); + } else { + PUTS("No additional information."); + } + PUTS("</td></tr>\n"); + return 0; +} + + +void _php3_info(void) +{ + char **env,*tmp1,*tmp2; + char *php3_uname; +#if WIN32|WINNT + char php3_windows_uname[256]; + DWORD dwBuild=0; + DWORD dwVersion = GetVersion(); + DWORD dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); + DWORD dwWindowsMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion))); +#endif + ELS_FETCH(); + PLS_FETCH(); + + +#if WIN32|WINNT + // Get build numbers for Windows NT or Win95 + if (dwVersion < 0x80000000){ + dwBuild = (DWORD)(HIWORD(dwVersion)); + snprintf(php3_windows_uname,255,"%s %d.%d build %d","Windows NT",dwWindowsMajorVersion,dwWindowsMinorVersion,dwBuild); + } else { + snprintf(php3_windows_uname,255,"%s %d.%d","Windows 95/98",dwWindowsMajorVersion,dwWindowsMinorVersion); + } + php3_uname = php3_windows_uname; +#else + php3_uname=PHP_UNAME; +#endif + + + PUTS("<img src=\"?=PHPE9568F34-D428-11d2-A769-00AA001ACF42\" border=\"0\" width=\"100\" height=\"56\" align=\"right\">\n"); + php3_printf("<center><h1>PHP Version %s</h1></center>\n", PHP_VERSION); + PUTS("<p>by <a href=\"mailto:rasmus@lerdorf.on.ca\">Rasmus Lerdorf</a>,\n"); + PUTS("<a href=\"mailto:andi@zend.com\">Andi Gutmans</a>,\n"); + PUTS("<a href=\"mailto:zeev@zend.com\">Zeev Suraski</a>,\n"); + PUTS("<a href=\"mailto:ssb@guardian.no\">Stig Bakken</a>,\n"); + PUTS("<a href=\"mailto:shane@caraveo.com\">Shane Caraveo</a>,\n"); + PUTS("<a href=\"mailto:jimw@php.net\">Jim Winstead</a>, and countless others.</P>\n"); + + PUTS("<P><a href=\"http://www.zend.com/\">Zend</a>:</a> "); + PUTS("<a href=\"mailto:andi@zend.com\">Andi Gutmans</a> and \n"); + PUTS("<a href=\"mailto:zeev@zend.com\">Zeev Suraski</a></p>\n"); + + PUTS("<hr>"); + php3_printf("<center>System: %s<br>Build Date: %s</center>\n", php3_uname, __DATE__); + PUTS("<center>\n"); + + SECTION("Extensions"); + PUTS("<table border=5 width=\"600\">\n"); + PUTS("<tr><th bgcolor=\"" HEADER_COLOR "\">Extensions</th><th bgcolor=\"" HEADER_COLOR "\">Additional Information</th></tr>\n"); + +#ifndef MSVC5 + PUTS("<tr><th align=left bgcolor=\"" ENTRY_NAME_COLOR "\">PHP core</th>\n"); + PUTS("<td bgcolor=\"" CONTENTS_COLOR "\"><tt>CFLAGS=" PHP_CFLAGS "<br>\n"); + PUTS("HSREGEX=" PHP_HSREGEX "</td></tr>\n"); +#endif + + _php3_hash_apply(&GLOBAL(module_registry),(int (*)(void *))_display_module_info); + PUTS("</table>\n"); + + SECTION("Configuration"); + PUTS("php3.ini file path is set to: "); + PUTS(CONFIGURATION_FILE_PATH); + PUTS("<br>\n"); + PUTS("<table border=5 width=\"600\">\n"); + PUTS("<tr><th bgcolor=\"" HEADER_COLOR "\">Directive</th><th bgcolor=\"" HEADER_COLOR "\">Master Value</th><th bgcolor=\"" HEADER_COLOR "\">Local Value</th></tr>\n"); + PHP3_CONF_STR("arg_separator", INI_ORIG_STR("arg_separator"), PG(arg_separator)); + PHP3_CONF_LONG("asp_tags", INI_ORIG_INT("asp_tags"), PG(asp_tags)); + PHP3_CONF_STR("auto_prepend_file", INI_ORIG_STR("auto_prepend_file"), PG(auto_prepend_file)); + PHP3_CONF_STR("auto_append_file", INI_ORIG_STR("auto_append_file"), PG(auto_append_file)); + PHP3_CONF_STR("browscap", INI_ORIG_STR("browscap"), INI_STR("browscap")); + PHP3_CONF_LONG("define_syslog_variables", INI_ORIG_STR("define_syslog_variables"), INI_STR("define_syslog_variables")); + PHP3_CONF_LONG("display_errors", INI_ORIG_INT("display_errors"), PG(display_errors)); + PHP3_CONF_STR("doc_root", INI_ORIG_STR("doc_root"), PG(doc_root)); + PHP3_CONF_LONG("enable_dl", INI_ORIG_INT("enable_dl"), PG(enable_dl)); + PHP3_CONF_STR("error_log", INI_ORIG_STR("error_log"), PG(error_log)); + PHP3_CONF_STR("error_prepend_string", INI_ORIG_STR("error_prepend_string"), INI_STR("error_prepend_string")); + PHP3_CONF_STR("error_append_string", INI_ORIG_STR("error_append_string"), INI_STR("error_append_string")); + PHP3_CONF_LONG("error_reporting", INI_ORIG_INT("error_reporting"), EG(error_reporting)); + PHP3_CONF_STR("extension_dir", INI_ORIG_STR("extension_dir"), PG(extension_dir)); + PHP3_CONF_STR("gpc_order", INI_ORIG_STR("gpc_order"), PG(gpc_order)); + PHP3_CONF_STR("include_path", INI_ORIG_STR("include_path"), PG(include_path)); + PHP3_CONF_LONG("log_errors", INI_ORIG_INT("log_errors"), PG(log_errors)); + PHP3_CONF_LONG("max_execution_time", INI_ORIG_INT("max_execution_time"), PG(max_execution_time)); + PHP3_CONF_LONG("magic_quotes_gpc", INI_ORIG_INT("magic_quotes_gpc"), PG(magic_quotes_gpc)); + PHP3_CONF_LONG("magic_quotes_runtime", INI_ORIG_INT("magic_quotes_runtime"), PG(magic_quotes_runtime)); + PHP3_CONF_LONG("magic_quotes_sybase", INI_ORIG_INT("magic_quotes_sybase"), PG(magic_quotes_sybase)); + PHP3_CONF_LONG("memory limit", INI_ORIG_INT("memory_limit"), PG(memory_limit)); + PHP3_CONF_STR("open_basedir", INI_ORIG_STR("open_basedir"), PG(open_basedir)); + PHP3_CONF_LONG("precision", INI_ORIG_INT("precision"), EG(precision)); + PHP3_CONF_LONG("safe_mode", INI_ORIG_INT("safe_mode"), PG(safe_mode)); + PHP3_CONF_STR("safe_mode_exec_dir", INI_ORIG_STR("safe_mode_exec_dir"), PG(safe_mode_exec_dir)); + PHP3_CONF_STR("sendmail_from", INI_ORIG_STR("sendmail_from"), INI_STR("sendmail_from")); + PHP3_CONF_STR("sendmail_path", INI_ORIG_STR("sendmail_path"), INI_STR("sendmail_path")); + PHP3_CONF_LONG("short_open_tag", INI_ORIG_INT("short_open_tag"), PG(short_tags)); + PHP3_CONF_STR("SMTP", INI_ORIG_STR("SMTP"), INI_STR("SMTP")); + PHP3_CONF_LONG("sql_safe_mode", INI_ORIG_INT("sql.safe_mode"), PG(sql_safe_mode)); + PHP3_CONF_LONG("track_errors", INI_ORIG_INT("track_errors"), PG(track_errors)); + PHP3_CONF_LONG("track_vars", INI_ORIG_INT("track_vars"), PG(track_vars)); + PHP3_CONF_LONG("upload_max_filesize", INI_ORIG_INT("upload_max_filesize"), PG(upload_max_filesize)); + PHP3_CONF_STR("upload_tmp_dir", INI_ORIG_STR("upload_tmp_dir"), PG(upload_tmp_dir)); + PHP3_CONF_STR("user_dir", INI_ORIG_STR("user_dir"), PG(user_dir)); + PHP3_CONF_LONG("y2k_compliance", INI_ORIG_INT("y2k_compliance"), PG(y2k_compliance)); + /* apache only directives */ + PHP3_CONF_LONG("engine", INI_ORIG_INT("engine"), INI_INT("engine")); /* apache only */ + PHP3_CONF_LONG("xbithack", INI_ORIG_INT("xbithack"), INI_INT("xbithack")); /* apache only */ + PHP3_CONF_LONG("last_modified", INI_ORIG_INT("last_modified"), INI_INT("last_modified")); /* apache only */ + /* end of apache only directives */ + + /* And now for the highlight colours */ + php3_printf("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">highlight_comment</td><td bgcolor=\"" CONTENTS_COLOR "\"><font color=%s> %s</font></td><td bgcolor=\"" CONTENTS_COLOR "\"><font color=%s> %s</font></td></tr>\n",INI_ORIG_STR("highlight.comment"), INI_ORIG_STR("highlight.comment"), INI_STR("highlight.comment"), INI_STR("highlight.comment")); + php3_printf("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">highlight_default</td><td bgcolor=\"" CONTENTS_COLOR "\"><font color=%s> %s</font></td><td bgcolor=\"" CONTENTS_COLOR "\"><font color=%s> %s</font></td></tr>\n",INI_ORIG_STR("highlight.default"), INI_ORIG_STR("highlight.default"), INI_STR("highlight.default"), INI_STR("highlight.default")); + php3_printf("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">highlight_html</td><td bgcolor=\"" CONTENTS_COLOR "\"><font color=%s> %s</font></td><td bgcolor=\"" CONTENTS_COLOR "\"><font color=%s> %s</font></td></tr>\n",INI_ORIG_STR("highlight.html"), INI_ORIG_STR("highlight.html"), INI_STR("highlight.html"), INI_STR("highlight.html")); + php3_printf("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">highlight_string</td><td bgcolor=\"" CONTENTS_COLOR "\"><font color=%s> %s</font></td><td bgcolor=\"" CONTENTS_COLOR "\"><font color=%s> %s</font></td></tr>\n",INI_ORIG_STR("highlight.string"), INI_ORIG_STR("highlight.string"), INI_STR("highlight.string"), INI_STR("highlight.string")); + php3_printf("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">highlight_bg</td><td bgcolor=\"" CONTENTS_COLOR "\"><font color=%s> %s</font></td><td bgcolor=\"" CONTENTS_COLOR "\"><font color=%s> %s</font></td></tr>\n",INI_ORIG_STR("highlight.bg"), INI_ORIG_STR("highlight.bg"), INI_STR("highlight.bg"), INI_STR("highlight.bg")); + php3_printf("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">highlight_keyword</td><td bgcolor=\"" CONTENTS_COLOR "\"><font color=%s> %s</font></td><td bgcolor=\"" CONTENTS_COLOR "\"><font color=%s> %s</font></td></tr>\n",INI_ORIG_STR("highlight.keyword"), INI_ORIG_STR("highlight.keyword"), INI_STR("highlight.keyword"), INI_STR("highlight.keyword")); + PUTS("</table>"); + +#if USE_SAPI /* call a server module specific info function */ + GLOBAL(sapi_rqst)->info(GLOBAL(sapi_rqst)); +#endif + + SECTION("Environment"); + PUTS("<table border=5 width=\"600\">\n"); + PUTS("<tr><th bgcolor=\"" HEADER_COLOR "\">Variable</th><th bgcolor=\"" HEADER_COLOR "\">Value</th></tr>\n"); + for (env=environ; env!=NULL && *env !=NULL; env++) { + tmp1 = estrdup(*env); + if (!(tmp2=strchr(tmp1,'='))) { /* malformed entry? */ + efree(tmp1); + continue; + } + *tmp2 = 0; + tmp2++; + PUTS("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">"); + PUTS(tmp1); + PUTS("</td><td bgcolor=\"" CONTENTS_COLOR "\">"); + if (tmp2 && *tmp2) { + PUTS(tmp2); + } else { + PUTS(" "); + } + PUTS("</td></tr>\n"); + efree(tmp1); + } + PUTS("</table>\n"); + + { + pval **data, **tmp; + char *string_key; + ulong num_key; + + SECTION("PHP Variables"); + + PUTS("<table border=5 width=\"600\">\n"); + PUTS("<tr><th bgcolor=\"" HEADER_COLOR "\">Variable</th><th bgcolor=\"" HEADER_COLOR "\">Value</th></tr>\n"); + if (_php3_hash_find(&EG(symbol_table), "PHP_SELF", sizeof("PHP_SELF"), (void **) &data) != FAILURE) { + PUTS("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">"); + PUTS("PHP_SELF"); + PUTS("</td><td bgcolor=\"" CONTENTS_COLOR "\">"); + PUTS((*data)->value.str.val); + PUTS("</td></tr>\n"); + } + if (_php3_hash_find(&EG(symbol_table), "PHP_AUTH_TYPE", sizeof("PHP_AUTH_TYPE"), (void **) &data) != FAILURE) { + PUTS("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">"); + PUTS("PHP_AUTH_TYPE"); + PUTS("</td><td bgcolor=\"" CONTENTS_COLOR "\">"); + PUTS((*data)->value.str.val); + PUTS("</td></tr>\n"); + } + if (_php3_hash_find(&EG(symbol_table), "PHP_AUTH_USER", sizeof("PHP_AUTH_USER"), (void **) &data) != FAILURE) { + PUTS("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">"); + PUTS("PHP_AUTH_USER"); + PUTS("</td><td bgcolor=\"" CONTENTS_COLOR "\">"); + PUTS((*data)->value.str.val); + PUTS("</td></tr>\n"); + } + if (_php3_hash_find(&EG(symbol_table), "PHP_AUTH_PW", sizeof("PHP_AUTH_PW"), (void **) &data) != FAILURE) { + PUTS("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">"); + PUTS("PHP_AUTH_PW"); + PUTS("</td><td bgcolor=\"" CONTENTS_COLOR "\">"); + PUTS((*data)->value.str.val); + PUTS("</td></tr>\n"); + } + if (_php3_hash_find(&EG(symbol_table), "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), (void **) &data) != FAILURE) { + _php3_hash_internal_pointer_reset((*data)->value.ht); + while (_php3_hash_get_current_data((*data)->value.ht, (void **) &tmp) == SUCCESS) { + convert_to_string(*tmp); + PUTS("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">HTTP_GET_VARS[\""); + switch (_php3_hash_get_current_key((*data)->value.ht, &string_key, &num_key)) { + case HASH_KEY_IS_STRING: + PUTS(string_key); + break; + case HASH_KEY_IS_LONG: + php3_printf("%ld",num_key); + break; + } + PUTS("\"]</td><td bgcolor=\"" CONTENTS_COLOR "\">"); + PUTS((*tmp)->value.str.val); /* This could be "Array" - too ugly to expand that for now */ + PUTS("</td></tr>\n"); + _php3_hash_move_forward((*data)->value.ht); + } + } + if (_php3_hash_find(&EG(symbol_table), "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), (void **) &data) != FAILURE) { + _php3_hash_internal_pointer_reset((*data)->value.ht); + while (_php3_hash_get_current_data((*data)->value.ht, (void **) &tmp) == SUCCESS) { + convert_to_string(*tmp); + PUTS("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">HTTP_POST_VARS[\""); + switch (_php3_hash_get_current_key((*data)->value.ht, &string_key, &num_key)) { + case HASH_KEY_IS_STRING: + PUTS(string_key); + break; + case HASH_KEY_IS_LONG: + php3_printf("%ld",num_key); + break; + } + PUTS("\"]</td><td bgcolor=\"" CONTENTS_COLOR "\">"); + PUTS((*tmp)->value.str.val); + PUTS("</td></tr>\n"); + _php3_hash_move_forward((*data)->value.ht); + } + } + if (_php3_hash_find(&EG(symbol_table), "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), (void **) &data) != FAILURE) { + _php3_hash_internal_pointer_reset((*data)->value.ht); + while (_php3_hash_get_current_data((*data)->value.ht, (void **) &tmp) == SUCCESS) { + convert_to_string(*tmp); + PUTS("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">HTTP_COOKIE_VARS[\""); + switch (_php3_hash_get_current_key((*data)->value.ht, &string_key, &num_key)) { + case HASH_KEY_IS_STRING: + PUTS(string_key); + break; + case HASH_KEY_IS_LONG: + php3_printf("%ld",num_key); + break; + } + PUTS("\"]</td><td bgcolor=\"" CONTENTS_COLOR "\">"); + PUTS((*tmp)->value.str.val); + PUTS("</td></tr>\n"); + _php3_hash_move_forward((*data)->value.ht); + } + } + PUTS("</table>\n"); + } + +#if APACHE + { + register int i; + array_header *arr = table_elts(GLOBAL(php3_rqst)->subprocess_env); + table_entry *elts = (table_entry *)arr->elts; + + SECTION("Apache Environment"); + PUTS("<table border=5 width=\"600\">\n"); + PUTS("<tr><th bgcolor=\"" HEADER_COLOR "\">Variable</th><th bgcolor=\"" HEADER_COLOR "\">Value</th></tr>\n"); + for (i=0; i < arr->nelts; i++) { + PUTS("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">"); + PUTS(elts[i].key); + PUTS("</td><td bgcolor=\"" CONTENTS_COLOR "\">"); + PUTS(elts[i].val); + PUTS(" </td></tr>\n"); + } + PUTS("</table>\n"); + } +#endif + +#if APACHE + { + array_header *env_arr; + table_entry *env; + int i; + + SECTION("HTTP Headers Information"); + PUTS("<table border=5 width=\"600\">\n"); + PUTS(" <tr><th colspan=2 bgcolor=\"" HEADER_COLOR "\">HTTP Request Headers</th></tr>\n"); + PUTS("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">HTTP Request</td><td bgcolor=\"" CONTENTS_COLOR "\">"); + PUTS(GLOBAL(php3_rqst)->the_request); + PUTS(" </td></tr>\n"); + env_arr = table_elts(GLOBAL(php3_rqst)->headers_in); + env = (table_entry *)env_arr->elts; + for (i = 0; i < env_arr->nelts; ++i) { + if (env[i].key) { + PUTS("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">"); + PUTS(env[i].key); + PUTS("</td><td bgcolor=\"" CONTENTS_COLOR "\">"); + PUTS(env[i].val); + PUTS(" </td></tr>\n"); + } + } + PUTS(" <tr><th colspan=2 bgcolor=\"" HEADER_COLOR "\">HTTP Response Headers</th></tr>\n"); + env_arr = table_elts(GLOBAL(php3_rqst)->headers_out); + env = (table_entry *)env_arr->elts; + for(i = 0; i < env_arr->nelts; ++i) { + if (env[i].key) { + PUTS("<tr><td bgcolor=\"" ENTRY_NAME_COLOR "\">"); + PUTS(env[i].key); + PUTS("</td><td bgcolor=\"" CONTENTS_COLOR "\">"); + PUTS(env[i].val); + PUTS(" </td></tr>\n"); + } + } + PUTS("</table>\n\n"); + } +#endif + + PUTS("</center>"); + + PUTS("<hr>\n"); + PUTS("<table width=\"100%%\"><tr>\n"); + php3_printf("<td><h2>Zend</h2>This program makes use of the Zend scripting language engine:<br><pre>%s</pre></td>", get_zend_version()); + PUTS("<td width=\"100\"><a href=\"http://www.zend.com/\"><img src=\"?=PHPE9568F35-D428-11d2-A769-00AA001ACF42\" border=\"0\" width=\"100\" height=\"89\"></a></td>\n"); + PUTS("</tr></table>\n"); + + SECTION("PHP License"); + PUTS("<PRE>This program is free software; you can redistribute it and/or modify\n"); + PUTS("it under the terms of:\n"); + PUTS("\n"); + PUTS("A) the GNU General Public License as published by the Free Software\n"); + PUTS(" Foundation; either version 2 of the License, or (at your option)\n"); + PUTS(" any later version.\n"); + PUTS("\n"); + PUTS("B) the PHP License as published by the PHP Development Team and\n"); + PUTS(" included in the distribution in the file: LICENSE\n"); + PUTS("\n"); + PUTS("This program is distributed in the hope that it will be useful,\n"); + PUTS("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); + PUTS("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); + PUTS("GNU General Public License for more details.\n"); + PUTS("\n"); + PUTS("You should have received a copy of both licenses referred to here.\n"); + PUTS("If you did not, or have any questions about PHP licensing, please\n"); + PUTS("contact core@php.net.</PRE>\n"); + +} + +/* {{{ proto void phpinfo(void) + Output a page of useful information about PHP and the current request */ +void php3_info(INTERNAL_FUNCTION_PARAMETERS) +{ + TLS_VARS; + + _php3_info(); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto string phpversion(void) + Return the current PHP version */ +void php3_version(INTERNAL_FUNCTION_PARAMETERS) +{ + TLS_VARS; + + RETURN_STRING(PHP_VERSION,1); +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/info.h b/ext/standard/info.h new file mode 100644 index 0000000000..41e5483145 --- /dev/null +++ b/ext/standard/info.h @@ -0,0 +1,40 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + | Zeev Suraski <zeev@zend.com> | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ + +#ifndef _INFO_H +#define _INFO_H + +extern void php3_version(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_info(INTERNAL_FUNCTION_PARAMETERS); + +extern void _php3_info(void); + +#endif /* _INFO_H */ diff --git a/ext/standard/iptc.c b/ext/standard/iptc.c new file mode 100644 index 0000000000..c0711d66be --- /dev/null +++ b/ext/standard/iptc.c @@ -0,0 +1,132 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Thies C. Arntzen (thies@digicol.de) | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +/* + * Functions to parse & compse IPTC data. + * PhotoShop >= 3.0 can read and write textual data to JPEG files. + * ... more to come ..... + */ + +/* + * TODO: + * - add IPTC translation table + * - implement a call to embed iptc into a JPEG file + */ + +#include "php.h" +#include "php3_iptc.h" + +void php3_iptcparse(INTERNAL_FUNCTION_PARAMETERS) +{ + unsigned int length, inx, len, inheader, tagsfound; + unsigned char *buffer; + unsigned char recnum, dataset; + unsigned char key[ 16 ]; + pval values, *str, *element; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + + + inx = 0; + length = str->value.str.len; + buffer = str->value.str.val; + + inheader = 0; /* have we already found the IPTC-Header??? */ + tagsfound = 0; /* number of tags already found */ + + while (inx < length) { + if (buffer[ inx++ ] != 0x1c) { /* skip all junk */ + if (inheader) { + break; /* we ran against some data which does not conform to IPTC - stop parsing! */ + } else { + continue; + } + } else { + inheader = 1; + } + + if ((inx + 4) >= length) + break; + + dataset = buffer[ inx++ ]; + recnum = buffer[ inx++ ]; + + if (buffer[ inx ] & (unsigned char) 0x80) { + len = (((long) buffer[ inx + 2 ]) << 24) + (((long) buffer[ inx + 3 ]) << 16) + + (((long) buffer[ inx + 4 ]) << 8) + (((long) buffer[ inx + 5 ])); + inx += 6; + } else { + len = (((unsigned short) buffer[ inx ])<<8) | (unsigned short)buffer[ inx+1 ]; + inx += 2; + } + + sprintf(key,"%d#%03d",(unsigned int) dataset,(unsigned int) recnum); + + if ((inx + len) > length) + break; + + if (tagsfound == 0) { /* found the 1st tag - initialize the return array */ + if (array_init(return_value) == FAILURE) { + php3_error(E_ERROR, "Unable to initialize array"); + RETURN_FALSE; + } + } + + if (_php3_hash_find(return_value->value.ht,key,strlen(key) + 1,(void **) &element) == FAILURE) { + if (array_init(&values) == FAILURE) { + php3_error(E_ERROR, "Unable to initialize array"); + RETURN_FALSE; + } + + _php3_hash_update(return_value->value.ht, key, strlen(key)+1, (void *) &values, sizeof(pval), (void **) &element); + } + + add_next_index_stringl(element,buffer+inx,len,1); + + inx += len; + + tagsfound++; + } + + if (! tagsfound) { + RETURN_FALSE; + } +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/link.c b/ext/standard/link.c new file mode 100644 index 0000000000..e148858a3c --- /dev/null +++ b/ext/standard/link.c @@ -0,0 +1,214 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: | + | | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include "php3_filestat.h" +#include "php_globals.h" + +#include <stdlib.h> +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <sys/stat.h> +#include <string.h> +#if HAVE_PWD_H +#if MSVC5 +#include "win32/pwd.h" +#else +#include <pwd.h> +#endif +#endif +#if HAVE_GRP_H +#if MSVC5 +#include "win32/grp.h" +#else +#include <grp.h> +#endif +#endif +#include <errno.h> +#include <ctype.h> + +#include "safe_mode.h" +#include "php3_link.h" + +/* {{{ proto string readlink(string filename) + Return the target of a symbolic link */ +void php3_readlink(INTERNAL_FUNCTION_PARAMETERS) +{ +#if HAVE_SYMLINK + pval *filename; + char buff[256]; + int ret; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &filename) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(filename); + + ret = readlink(filename->value.str.val, buff, 255); + if (ret == -1) { + php3_error(E_WARNING, "readlink failed (%s)", strerror(errno)); + RETURN_FALSE; + } + /* Append NULL to the end of the string */ + buff[ret] = '\0'; + RETURN_STRING(buff,1); +#endif +} +/* }}} */ + +/* {{{ proto int linkinfo(string filename) + Returns the st_dev field of the UNIX C stat structure describing the link */ +void php3_linkinfo(INTERNAL_FUNCTION_PARAMETERS) +{ +#if HAVE_SYMLINK + pval *filename; + struct stat sb; + int ret; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &filename) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(filename); + + ret = lstat(filename->value.str.val, &sb); + if (ret == -1) { + php3_error(E_WARNING, "LinkInfo failed (%s)", strerror(errno)); + RETURN_LONG(-1L); + } + RETURN_LONG((long) sb.st_dev); +#endif +} +/* }}} */ + +/* {{{ proto int symlink(string target, string link) + Create a symbolic link */ +void php3_symlink(INTERNAL_FUNCTION_PARAMETERS) +{ +#if HAVE_SYMLINK + pval *topath, *frompath; + int ret; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &topath, &frompath) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(topath); + convert_to_string(frompath); + + if (PG(safe_mode) && !_php3_checkuid(topath->value.str.val, 2)) { + RETURN_FALSE; + } + + ret = symlink(topath->value.str.val, frompath->value.str.val); + if (ret == -1) { + php3_error(E_WARNING, "SymLink failed (%s)", strerror(errno)); + RETURN_FALSE; + } + RETURN_TRUE; +#endif +} +/* }}} */ + +/* {{{ proto int link(string target, string link) + Create a hard link */ +void php3_link(INTERNAL_FUNCTION_PARAMETERS) +{ +#if HAVE_LINK + pval *topath, *frompath; + int ret; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &topath, &frompath) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(topath); + convert_to_string(frompath); + + if (PG(safe_mode) && !_php3_checkuid(topath->value.str.val, 2)) { + RETURN_FALSE; + } + + ret = link(topath->value.str.val, frompath->value.str.val); + if (ret == -1) { + php3_error(E_WARNING, "Link failed (%s)", strerror(errno)); + RETURN_FALSE; + } + RETURN_TRUE; +#endif +} +/* }}} */ + +/* {{{ proto int unlink(string filename) + Delete a file */ +void php3_unlink(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *filename; + int ret; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &filename) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(filename); + + if (PG(safe_mode) && !_php3_checkuid(filename->value.str.val, 2)) { + RETURN_FALSE; + } + + ret = unlink(filename->value.str.val); + if (ret == -1) { + php3_error(E_WARNING, "Unlink failed (%s)", strerror(errno)); + RETURN_FALSE; + } + /* Clear stat cache */ + php3_clearstatcache(INTERNAL_FUNCTION_PARAM_PASSTHRU); + RETURN_TRUE; +} +/* }}} */ + +function_entry link_functions[] = { + {"readlink", php3_readlink, NULL}, + {"linkinfo", php3_linkinfo, NULL}, + {"symlink", php3_symlink, NULL}, + {"link", php3_link, NULL}, + {"unlink", php3_unlink, NULL}, + {NULL, NULL, NULL} +}; + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/mail.c b/ext/standard/mail.c new file mode 100644 index 0000000000..685e8d9cf9 --- /dev/null +++ b/ext/standard/mail.c @@ -0,0 +1,188 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: | + | | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#include <stdlib.h> +#include <ctype.h> +#include <stdio.h> +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#ifndef MSVC5 +#include "build-defs.h" +#endif +#include "php3_mail.h" +#include "php_ini.h" + +#if APACHE +# ifndef DEBUG +# undef palloc +# endif +#endif + +#if HAVE_SENDMAIL +#if MSVC5 +#include "win32/sendmail.h" +#endif + +function_entry mail_functions[] = { + {"mail", php3_mail, NULL}, + {NULL, NULL, NULL} +}; + +php3_module_entry mail_module_entry = { + "Sendmail", mail_functions, NULL, NULL, NULL, NULL, php3_info_mail, STANDARD_MODULE_PROPERTIES +}; + + +#if COMPILE_DL +DLEXPORT php3_module_entry *get_module(void) { return &odbc_module_entry; } +#endif + +/* {{{ proto int mail(string to, string subject, string message [, string additional_headers]) + Send an email message */ +void php3_mail(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *argv[4]; + char *to=NULL, *message=NULL, *headers=NULL, *subject=NULL; + int argc; + TLS_VARS; + + argc = ARG_COUNT(ht); + if (argc < 3 || argc > 4 || getParametersArray(ht, argc, argv) == FAILURE) { + WRONG_PARAM_COUNT; + } + /* To: */ + convert_to_string(argv[0]); + if (argv[0]->value.str.val) { + to = argv[0]->value.str.val; + } else { + php3_error(E_WARNING, "No to field in mail command"); + RETURN_FALSE; + } + + /* Subject: */ + convert_to_string(argv[1]); + if (argv[1]->value.str.val) { + subject = argv[1]->value.str.val; + } else { + php3_error(E_WARNING, "No subject field in mail command"); + RETURN_FALSE; + } + + /* message body */ + convert_to_string(argv[2]); + if (argv[2]->value.str.val) { + message = argv[2]->value.str.val; + } else { + /* this is not really an error, so it is allowed. */ + php3_error(E_WARNING, "No message string in mail command"); + message = NULL; + } + + if (argc == 4) { /* other headers */ + convert_to_string(argv[3]); + headers = argv[3]->value.str.val; + } + + if (_php3_mail(to, subject, message, headers)){ + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +int _php3_mail(char *to, char *subject, char *message, char *headers) +{ +#if MSVC5 + int tsm_err; +#else + FILE *sendmail; + int ret; + char *sendmail_path = INI_STR("sendmail_path"); +#endif + +#if MSVC5 + if (TSendMail(INI_STR("SMTP"), &tsm_err, headers, subject, to, message) != SUCCESS){ + php3_error(E_WARNING, GetSMErrorText(tsm_err)); + return 0; + } +#else + if (!sendmail_path) { + return 0; + } + sendmail = popen(sendmail_path, "w"); + + if (sendmail) { + fprintf(sendmail, "To: %s\n", to); + fprintf(sendmail, "Subject: %s\n", subject); + if (headers != NULL) { + fprintf(sendmail, "%s\n", headers); + } + fprintf(sendmail, "\n%s\n", message); + ret = pclose(sendmail); + if (ret == -1) { + return 0; + } else { + return 1; + } + } else { + php3_error(E_WARNING, "Could not execute mail delivery program"); + return 0; + } +#endif + return 1; +} + +void php3_info_mail(void) +{ +#if MSVC5 + PUTS("Internal Sendmail support for Windows 4"); +#else + php3_printf("Path to sendmail: <tt>%s</tt>", INI_STR("sendmail_path")); +#endif +} + +#else + +void php3_mail(INTERNAL_FUNCTION_PARAMETERS) {} +void php3_info_mail() {} + +#endif + + +/* + * Local variables: + * tab-width: 4 + * End: + */ diff --git a/ext/standard/math.c b/ext/standard/math.c new file mode 100644 index 0000000000..e13fb82119 --- /dev/null +++ b/ext/standard/math.c @@ -0,0 +1,708 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Jim Winstead (jimw@php.net) | + | Stig Sæther Bakken <ssb@guardian.no> | + +----------------------------------------------------------------------+ + */ + +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include "phpmath.h" +#include "snprintf.h" + +#include <math.h> + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +char *_php3_number_format(double, int, char ,char); + +/* {{{ proto int abs(int number) + Return the absolute value of the number */ +void php3_abs(INTERNAL_FUNCTION_PARAMETERS) { + pval *value; + TLS_VARS; + + if (ARG_COUNT(ht)!=1||getParameters(ht,1,&value)==FAILURE) { + WRONG_PARAM_COUNT; + } + + if (value->type == IS_STRING) { + convert_scalar_to_number(value); + } + + if (value->type == IS_DOUBLE) { + RETURN_DOUBLE(fabs(value->value.dval)); + } + else if (value->type == IS_LONG) { + RETURN_LONG(labs(value->value.lval)); + } + + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto int ceil(double number) + Returns the next highest integer value of the number */ +void php3_ceil(INTERNAL_FUNCTION_PARAMETERS) { + pval *value; + TLS_VARS; + + if (ARG_COUNT(ht)!=1||getParameters(ht,1,&value)==FAILURE) { + WRONG_PARAM_COUNT; + } + + if (value->type == IS_STRING) { + convert_scalar_to_number(value); + } + + if (value->type == IS_DOUBLE) { + RETURN_LONG((long)ceil(value->value.dval)); + } + else if (value->type == IS_LONG) { + RETURN_LONG(value->value.lval); + } + + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto int floor(double number) + Returns the next lowest integer value from the number */ +void php3_floor(INTERNAL_FUNCTION_PARAMETERS) { + pval *value; + TLS_VARS; + + if (ARG_COUNT(ht)!=1||getParameters(ht,1,&value)==FAILURE) { + WRONG_PARAM_COUNT; + } + + if (value->type == IS_STRING) { + convert_scalar_to_number(value); + } + + if (value->type == IS_DOUBLE) { + RETURN_LONG((long)floor(value->value.dval)); + } + else if (value->type == IS_LONG) { + RETURN_LONG(value->value.lval); + } + + RETURN_FALSE; +} +/* }}} */ + +#ifndef HAVE_RINT +/* emulate rint */ +inline double rint(double n) +{ + double i, f; + f = modf(n, &i); + if (f > .5) + i++; + else if (f < -.5) + i--; + return i; +} +#endif + +/* {{{ proto int round(double number) + Returns the rounded value of the number */ +void php3_round(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *value; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &value) == FAILURE) { + WRONG_PARAM_COUNT; + } + if (value->type == IS_STRING) { + convert_scalar_to_number(value); + } + if (value->type == IS_DOUBLE) { + RETURN_DOUBLE(rint(value->value.dval)); + } + if (value->type == IS_LONG) { + RETURN_DOUBLE((double)value->value.lval); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto double sin(double number) + Returns the sine of the number in radians */ +void php3_sin(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(num); + return_value->value.dval = sin(num->value.dval); + return_value->type = IS_DOUBLE; +} +/* }}} */ + +/* {{{ proto double cos(double number) + Returns the cosine of the number in radians */ +void php3_cos(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(num); + return_value->value.dval = cos(num->value.dval); + return_value->type = IS_DOUBLE; +} +/* }}} */ + +/* {{{ proto double tan(double number) + Returns the tangent of the number in radians */ +void php3_tan(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(num); + return_value->value.dval = tan(num->value.dval); + return_value->type = IS_DOUBLE; +} +/* }}} */ + +/* {{{ proto double asin(double number) + Returns the arc sine of the number in radians */ +void php3_asin(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(num); + return_value->value.dval = asin(num->value.dval); + return_value->type = IS_DOUBLE; +} +/* }}} */ + +/* {{{ proto double acos(double number) + Return the arc cosine of the number in radians */ +void php3_acos(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(num); + return_value->value.dval = acos(num->value.dval); + return_value->type = IS_DOUBLE; +} +/* }}} */ + +/* {{{ proto double atan(double number) + Returns the arc tangent of the number in radians */ +void php3_atan(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(num); + return_value->value.dval = atan(num->value.dval); + return_value->type = IS_DOUBLE; +} +/* }}} */ + +/* {{{ proto double atan2(double y, double x) + Returns the arc tangent of y/x, with the resulting quadrant determined by the signs of y and x */ +void php3_atan2(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num1, *num2; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &num1, &num2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(num1); + convert_to_double(num2); + return_value->value.dval = atan2(num1->value.dval,num2->value.dval); + return_value->type = IS_DOUBLE; +} +/* }}} */ + +/* {{{ proto double pi(void) + Returns an approximation of pi */ +void php3_pi(INTERNAL_FUNCTION_PARAMETERS) +{ + return_value->value.dval = M_PI; + return_value->type = IS_DOUBLE; +} +/* }}} */ + +/* {{{ proto double pow(double base, double exponent) + Returns base raised to the power of expopent */ +void php3_pow(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num1, *num2; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht,2,&num1,&num2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(num1); + convert_to_double(num2); + RETURN_DOUBLE(pow(num1->value.dval, num2->value.dval)); +} +/* }}} */ + +/* {{{ proto double exp(double number) + Returns e raised to the power of the number */ +void php3_exp(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(num); + return_value->value.dval = exp(num->value.dval); + return_value->type = IS_DOUBLE; +} +/* }}} */ + +/* {{{ proto double log(double number) + Returns the natural logarithm of the number */ +void php3_log(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(num); + return_value->value.dval = log(num->value.dval); + return_value->type = IS_DOUBLE; +} +/* }}} */ + +/* {{{ proto double log10(double number) + Returns the base-10 logarithm of the number */ +void php3_log10(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(num); + return_value->value.dval = log10(num->value.dval); + return_value->type = IS_DOUBLE; +} +/* }}} */ + +/* {{{ proto double sqrt(double number) + Returns the square root of the number */ +void php3_sqrt(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(num); + return_value->value.dval = sqrt(num->value.dval); + return_value->type = IS_DOUBLE; +} +/* }}} */ + +/* {{{ proto double deg2rad(double number) + Converts the number in degrees to the radian equivalent */ +void php3_deg2rad(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *deg; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, °) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(deg); + RETVAL_DOUBLE((deg->value.dval / 180.0) * M_PI); +} +/* }}} */ + +/* {{{ proto double rad2deg(double number) + Converts the radian number to the equivalent number in degrees */ +void php3_rad2deg(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *rad; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &rad) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_double(rad); + RETVAL_DOUBLE((rad->value.dval / M_PI) * 180); +} +/* }}} */ + + +/* + * Convert a string representation of a base(2-36) number to a long. + */ +static long +_php3_basetolong(pval *arg, int base) { + long mult = 1, num = 0, digit; + int i; + char c, *s; + + if (arg->type != IS_STRING || base < 2 || base > 36) { + return 0; + } + + s = arg->value.str.val; + + for (i = arg->value.str.len - 1; i >= 0; i--, mult *= base) { + c = toupper(s[i]); + if (c >= '0' && c <= '9') { + digit = (c - '0'); + } else if (c >= 'A' && c <= 'Z') { + digit = (c - 'A' + 10); + } else { + continue; + } + if (digit >= base) { + continue; + } + num += mult * digit; + } + + return num; +} + + +/* + * Convert a long to a string containing a base(2-36) representation of + * the number. + */ +static char * +_php3_longtobase(pval *arg, int base) +{ + static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + char *result, *ptr, *ret; + int len, digit; + long value; + + if (arg->type != IS_LONG || base < 2 || base > 36) { + return empty_string; + } + + value = arg->value.lval; + + /* allocates space for the longest possible result with the lowest base */ + len = (sizeof(arg->value.lval) * 8) + 1; + result = emalloc((sizeof(arg->value.lval) * 8) + 1); + + ptr = result + len - 1; + *ptr-- = '\0'; + + do { + digit = value % base; + *ptr = digits[digit]; + value /= base; + } + while (ptr-- > result && value); + ptr++; + ret = estrdup(ptr); + efree(result); + + return ret; +} + +/* {{{ proto int bindec(string binary_number) + Returns the decimal equivalent of the binary number */ +void php3_bindec(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + long ret; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(arg); + ret = _php3_basetolong(arg, 2); + + RETVAL_LONG(ret); +} +/* }}} */ + +/* {{{ proto int hexdec(string hexadimal_number) + Returns the decimal equivalent of the hexadecimal number */ +void php3_hexdec(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + long ret; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(arg); + + ret = _php3_basetolong(arg, 16); + RETVAL_LONG(ret); +} +/* }}} */ + +/* {{{ proto int octdec(string octal_number) + Returns the decimal equivalent of an octal string */ +void php3_octdec(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + long ret; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(arg); + + ret = _php3_basetolong(arg, 8); + RETVAL_LONG(ret); +} +/* }}} */ + +/* {{{ proto string decbin(int decimal_number) + Returns a string containing a binary representation of the number */ +void php3_decbin(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + char *result; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_long(arg); + + result = _php3_longtobase(arg, 2); + return_value->type = IS_STRING; + return_value->value.str.len = strlen(result); + return_value->value.str.val = result; +} +/* }}} */ + +/* {{{ proto string decoct(int decimal_number) + Returns a string containing an octal representation of the given number */ +void php3_decoct(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + char *result; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_long(arg); + + result = _php3_longtobase(arg, 8); + return_value->type = IS_STRING; + return_value->value.str.len = strlen(result); + return_value->value.str.val = result; +} +/* }}} */ + +/* {{{ proto string dechex(int decimal_number) + Returns a string containing a hexadecimal representation of the given number */ +void php3_dechex(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + char *result; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_long(arg); + + result = _php3_longtobase(arg, 16); + return_value->type = IS_STRING; + return_value->value.str.len = strlen(result); + return_value->value.str.val = result; +} +/* }}} */ + + +/* {{{ proto string base_convert(string number, int frombase, int tobase) + Converts a number in a string from any base <= 36 to any base <= 36. +*/ +void php3_base_convert(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *number, *frombase, *tobase, temp; + char *result; + + if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &number, &frombase, &tobase) + == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(number); + convert_to_long(frombase); + convert_to_long(tobase); + if (frombase->value.lval < 2 || frombase->value.lval > 36) { + php3_error(E_WARNING, "base_convert: invalid `from base' (%d)", + frombase->value.lval); + RETURN_FALSE; + } + if (tobase->value.lval < 2 || tobase->value.lval > 36) { + php3_error(E_WARNING, "base_convert: invalid `to base' (%d)", + tobase->value.lval); + RETURN_FALSE; + } + temp.type = IS_LONG; + temp.value.lval = _php3_basetolong(number, frombase->value.lval); + result = _php3_longtobase(&temp, tobase->value.lval); + RETVAL_STRING(result, 0); +} /* }}} */ + + +char *_php3_number_format(double d,int dec,char dec_point,char thousand_sep) +{ + char *tmpbuf,*resbuf; + char *s,*t; /* source, target */ + int tmplen,reslen=0; + int count=0; + int is_negative=0; + + if (d<0) { + is_negative=1; + d = -d; + } + dec = MAX(0,dec); + tmpbuf = (char *) emalloc(32+dec); + + tmplen=_php3_sprintf(tmpbuf,"%.*f",dec,d); + + for (t=tmpbuf; *t; t++) { + if (*t=='.') { + *t = dec_point; + } + } + if (dec) { + reslen = dec+1 + (tmplen-dec-1) + (tmplen-1-dec-1)/3; + } else { + reslen = tmplen+(tmplen-1)/3; + } + if (is_negative) { + reslen++; + } + resbuf = (char *) emalloc(reslen+1); + + s = tmpbuf+tmplen-1; + t = resbuf+reslen; + *t-- = 0; + + if (dec) { + while (*s!=dec_point) { + *t-- = *s--; + } + *t-- = *s--; /* copy that dot */ + } + + while(s>=tmpbuf) { + *t-- = *s--; + if ((++count%3)==0 && s>=tmpbuf) { + *t-- = thousand_sep; + } + } + if (is_negative) { + *t-- = '-'; + } + efree(tmpbuf); + return resbuf; +} + +/* {{{ proto string number_format(double number, [,int num_decimal_places [, string dec_seperator, string thousands_seperator)]]) + Formats a number with grouped thousands */ +void php3_number_format(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num,*dec,*t_s,*d_p; + char thousand_sep=',', dec_point='.'; + + switch(ARG_COUNT(ht)) { + case 1: + if (getParameters(ht, 1, &num)==FAILURE) { + RETURN_FALSE; + } + convert_to_double(num); + RETURN_STRING(_php3_number_format(num->value.dval,0,dec_point,thousand_sep),0); + break; + case 2: + if (getParameters(ht, 2, &num, &dec)==FAILURE) { + RETURN_FALSE; + } + convert_to_double(num); + convert_to_long(dec); + RETURN_STRING(_php3_number_format(num->value.dval,dec->value.lval,dec_point,thousand_sep),0); + break; + case 4: + if (getParameters(ht, 4, &num, &dec, &d_p, &t_s)==FAILURE) { + RETURN_FALSE; + } + convert_to_double(num); + convert_to_long(dec); + convert_to_string(d_p); + convert_to_string(t_s); + if (d_p->value.str.len==1) { + dec_point=d_p->value.str.val[0]; + } + if (t_s->value.str.len==1) { + thousand_sep=t_s->value.str.val[0]; + } + RETURN_STRING(_php3_number_format(num->value.dval,dec->value.lval,dec_point,thousand_sep),0); + break; + default: + WRONG_PARAM_COUNT; + break; + } +} +/* }}} */ +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/md5.c b/ext/standard/md5.c new file mode 100644 index 0000000000..23e2d54c4b --- /dev/null +++ b/ext/standard/md5.c @@ -0,0 +1,407 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Lachlan Roche | + +----------------------------------------------------------------------+ + */ + +/* + * md5.c - Copyright 1997 Lachlan Roche + */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif + +#include <stdio.h> +#include "php.h" + +#include "md5.h" + +/* {{{ proto string md5(string str) + Calculate the md5 hash of a string */ +void php3_md5(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + char md5str[33]; + PHP3_MD5_CTX context; + unsigned char digest[16]; + int i; + char *r; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + md5str[0] = '\0'; + PHP3_MD5Init(&context); + PHP3_MD5Update(&context, arg->value.str.val, arg->value.str.len); + PHP3_MD5Final(digest, &context); + for (i = 0, r = md5str; i < 16; i++, r += 2) { + sprintf(r, "%02x", digest[i]); + } + *r = '\0'; + RETVAL_STRING(md5str,1); +} +/* }}} */ + +/* + * The remaining code is the reference MD5 code (md5c.c) from rfc1321 + */ +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +/* Constants for MD5Transform routine. + */ + + +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static void MD5Transform PROTO_LIST((UINT4[4], const unsigned char[64])); +static void Encode PROTO_LIST + ((unsigned char *, UINT4 *, unsigned int)); +static void Decode PROTO_LIST + ((UINT4 *, const unsigned char *, unsigned int)); +static void MD5_memcpy PROTO_LIST((_POINTER, _POINTER, unsigned int)); +static void MD5_memset PROTO_LIST((_POINTER, int, unsigned int)); + +static unsigned char PADDING[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. + Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +/* MD5 initialization. Begins an MD5 operation, writing a new context. + */ +void PHP3_MD5Init(PHP3_MD5_CTX * context) +{ + context->count[0] = context->count[1] = 0; + /* Load magic initialization constants. + */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest + operation, processing another message block, and updating the + context. + */ +void PHP3_MD5Update(PHP3_MD5_CTX * context, const unsigned char *input, + unsigned int inputLen) +{ + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int) ((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((UINT4) inputLen << 3)) + < ((UINT4) inputLen << 3)) + context->count[1]++; + context->count[1] += ((UINT4) inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible. + */ + if (inputLen >= partLen) { + MD5_memcpy + ((_POINTER) & context->buffer[index], (_POINTER) input, partLen); + MD5Transform(context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform(context->state, &input[i]); + + index = 0; + } else + i = 0; + + /* Buffer remaining input */ + MD5_memcpy + ((_POINTER) & context->buffer[index], (_POINTER) & input[i], + inputLen - i); +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + the message digest and zeroizing the context. + */ +void PHP3_MD5Final(unsigned char digest[16], PHP3_MD5_CTX * context) +{ + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode(bits, context->count, 8); + + /* Pad out to 56 mod 64. + */ + index = (unsigned int) ((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + PHP3_MD5Update(context, PADDING, padLen); + + /* Append length (before padding) */ + PHP3_MD5Update(context, bits, 8); + + /* Store state in digest */ + Encode(digest, context->state, 16); + + /* Zeroize sensitive information. + */ + MD5_memset((_POINTER) context, 0, sizeof(*context)); +} + +/* MD5 basic transformation. Transforms state based on block. + */ +static void MD5Transform(state, block) +UINT4 state[4]; +const unsigned char block[64]; +{ + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode(x, block, 64); + + /* Round 1 */ + FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */ + FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */ + FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */ + FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */ + FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */ + FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */ + FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */ + FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */ + FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */ + FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */ + FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */ + GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */ + GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */ + GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */ + GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */ + GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */ + GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */ + GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */ + GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */ + GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */ + GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */ + HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */ + HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */ + HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */ + HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */ + HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */ + HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */ + HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */ + HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */ + HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */ + II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */ + II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */ + II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */ + II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */ + II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */ + II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */ + II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */ + II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */ + II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. */ + MD5_memset((_POINTER) x, 0, sizeof(x)); +} + +/* Encodes input (UINT4) into output (unsigned char). Assumes len is + a multiple of 4. + */ +static void Encode(output, input, len) +unsigned char *output; +UINT4 *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char) (input[i] & 0xff); + output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff); + output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff); + output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (unsigned char) into output (UINT4). Assumes len is + a multiple of 4. + */ +static void Decode(output, input, len) +UINT4 *output; +const unsigned char *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4) input[j]) | (((UINT4) input[j + 1]) << 8) | + (((UINT4) input[j + 2]) << 16) | (((UINT4) input[j + 3]) << 24); +} + +/* Note: Replace "for loop" with standard memcpy if possible. + */ + +static void MD5_memcpy(output, input, len) +_POINTER output; +_POINTER input; +unsigned int len; +{ + unsigned int i; + + for (i = 0; i < len; i++) + output[i] = input[i]; +} + +/* Note: Replace "for loop" with standard memset if possible. + */ +static void MD5_memset(output, value, len) +_POINTER output; +int value; +unsigned int len; +{ + unsigned int i; + + for (i = 0; i < len; i++) + ((char *) output)[i] = (char) value; +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/md5.h b/ext/standard/md5.h new file mode 100644 index 0000000000..1c71321c2e --- /dev/null +++ b/ext/standard/md5.h @@ -0,0 +1,71 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + +----------------------------------------------------------------------+ + */ +#ifndef _md5_h +#define _md5_h +/* MD5.H - header file for MD5C.C + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +#include "global.h" + +/* MD5 context. */ +typedef struct { + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} PHP3_MD5_CTX; + +void PHP3_MD5Init PROTO_LIST((PHP3_MD5_CTX *)); +void PHP3_MD5Update PROTO_LIST((PHP3_MD5_CTX *, const unsigned char *, unsigned int)); +void PHP3_MD5Final PROTO_LIST((unsigned char[16], PHP3_MD5_CTX *)); + +extern void php3_md5(INTERNAL_FUNCTION_PARAMETERS); + +#endif diff --git a/ext/standard/microtime.c b/ext/standard/microtime.c new file mode 100644 index 0000000000..3ccf2a28a9 --- /dev/null +++ b/ext/standard/microtime.c @@ -0,0 +1,88 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Paul Panotzki - Bunyip Information Systems | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#include <stdlib.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <string.h> +#include <errno.h> + +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include "microtime.h" +#include "snprintf.h" + +#include <stdio.h> +#if HAVE_GETTIMEOFDAY +#if MSVC5 +#include "win32/time.h" +#else +#include <sys/time.h> +#endif +#endif + +#define NUL '\0' +#define MICRO_IN_SEC 1000000.00 + +/* {{{ proto string microtime(void) + Returns a string containing the current time in seconds and microseconds */ +#ifdef __cplusplus +void php3_microtime(HashTable *) +#else +void php3_microtime(INTERNAL_FUNCTION_PARAMETERS) +#endif +{ +#if HAVE_GETTIMEOFDAY + struct timeval tp; + long sec = 0L; + double msec = 0.0; + char ret[100]; + TLS_VARS; + + if (gettimeofday((struct timeval *) &tp, (NUL)) == 0) { + msec = (double) (tp.tv_usec / MICRO_IN_SEC); + sec = tp.tv_sec; + } + snprintf(ret, 100, "%.8f %ld", msec, sec); + RETVAL_STRING(ret,1); +#endif +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/microtime.h b/ext/standard/microtime.h new file mode 100644 index 0000000000..b827272779 --- /dev/null +++ b/ext/standard/microtime.h @@ -0,0 +1,37 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Paul Panotzki - Bunyip Information Systems | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifndef _MICROTIME_H +#define _MICROTIME_H + +extern void php3_microtime(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _MICROTIME_H */ diff --git a/ext/standard/pack.c b/ext/standard/pack.c new file mode 100644 index 0000000000..629595df90 --- /dev/null +++ b/ext/standard/pack.c @@ -0,0 +1,890 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Chris Schneider <cschneid@relog.ch> | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if MSVC5 +#include <windows.h> +#include <winsock.h> +#define O_RDONLY _O_RDONLY +#include "win32/param.h" +#else +#include <sys/param.h> +#endif +#include "head.h" +#include "safe_mode.h" +#include "php3_string.h" +#include "pack.h" +#if HAVE_PWD_H +#if MSVC5 +#include "win32/pwd.h" +#else +#include <pwd.h> +#endif +#endif +#include "snprintf.h" +#include "fsock.h" +#if HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif + +function_entry pack_functions[] = { + {"pack", php3_pack, NULL}, + {"unpack", php3_unpack, NULL}, + {NULL, NULL, NULL} +}; + +php3_module_entry pack_module_entry = { + "PHP_pack", pack_functions, php3_minit_pack, NULL, NULL, NULL, NULL, STANDARD_MODULE_PROPERTIES +}; + +/* Whether machine is little endian */ +char machine_little_endian; + +/* Mapping of byte from char (8bit) to long for machine endian */ +static int byte_map[1]; + +/* Mappings of bytes from int (machine dependant) to int for machine endian */ +static int int_map[sizeof(int)]; + +/* Mappings of bytes from shorts (16bit) for all endian environments */ +static int machine_endian_short_map[2]; +static int big_endian_short_map[2]; +static int little_endian_short_map[2]; + +/* Mappings of bytes from longs (32bit) for all endian environments */ +static int machine_endian_long_map[4]; +static int big_endian_long_map[4]; +static int little_endian_long_map[4]; + + +static void _php3_pack(pval *val, int size, int *map, char *output) +{ + int i; + char *v; + + convert_to_long(val); + v = (char *)&val->value.lval; + + for (i = 0; i < size; i++) { + *(output++) = v[map[i]]; + } +} + + +/* pack() idea stolen from Perl (implemented formats behave the same as there) + * Implemented formats are A,a,h,H,c,C,s,S,i,I,l,L,n,N,f,d,x,X,@. + */ +/* {{{ proto string pack(string format, mixed arg1, mixed arg2, ...) + Takes 1 or more arguments and packs them into a binary string according to the format argument */ +PHP_FUNCTION(pack) +{ + pval **argv; + int argc, i; + int currentarg; + char *format; + int formatlen; + char *formatcodes; + int *formatargs; + int formatcount = 0; + int outputpos = 0, outputsize = 0; + char *output; + TLS_VARS; + + argc = ARG_COUNT(ht); + + if (argc < 1) { + WRONG_PARAM_COUNT; + } + + argv = emalloc(argc * sizeof(pval *)); + + if (getParametersArray(ht, argc, argv) == FAILURE) { + efree(argv); + WRONG_PARAM_COUNT; + } + + convert_to_string(argv[0]); + format = argv[0]->value.str.val; + formatlen = argv[0]->value.str.len; + + /* We have a maximum of <formatlen> format codes to deal with */ + formatcodes = emalloc(formatlen * sizeof(*formatcodes)); + formatargs = emalloc(formatlen * sizeof(*formatargs)); + currentarg = 1; + + /* Preprocess format into formatcodes and formatargs */ + for (i = 0; i < formatlen; formatcount++) { + char code = format[i++]; + int arg = 1; + + /* Handle format arguments if any */ + if (i < formatlen) { + char c = format[i]; + + if (c == '*') { + arg = -1; + i++; + } + else if ((c >= '0') && (c <= '9')) { + arg = atoi(&format[i]); + + while (format[i] >= '0' && format[i] <= '9' && i < formatlen) { + i++; + } + } + } + + /* Handle special arg '*' for all codes and check argv overflows */ + switch ((int)code) { + /* Never uses any args */ + case 'x': case 'X': case '@': { + if (arg < 0) { + php3_error(E_WARNING, "pack type %c: '*' ignored", code); + arg = 1; + } + break; + } + + /* Always uses one arg */ + case 'a': case 'A': case 'h': case 'H': { + if (currentarg >= argc) { + efree(argv); + efree(formatcodes); + efree(formatargs); + php3_error(E_ERROR, "pack type %c: not enough arguments", code); + RETURN_FALSE; + } + + if (arg < 0) { + arg = argv[currentarg]->value.str.len; + } + + currentarg++; + break; + } + + /* Use as many args as specified */ + case 'c': case 'C': case 's': case 'S': case 'i': case 'I': + case 'l': case 'L': case 'n': case 'N': case 'v': case 'V': + case 'f': case 'd': { + if (arg < 0) { + arg = argc - currentarg; + } + + currentarg += arg; + + if (currentarg > argc) { + efree(argv); + efree(formatcodes); + efree(formatargs); + php3_error(E_ERROR, "pack type %c: too few arguments", code); + RETURN_FALSE; + } + break; + } + + default: { + php3_error(E_ERROR, "pack type %c: unknown format code", code); + RETURN_FALSE; + } + } + + formatcodes[formatcount] = code; + formatargs[formatcount] = arg; + } + + if (currentarg < argc) { + php3_error(E_WARNING, "pack %d arguments unused", (argc - currentarg)); + } + + /* Calculate output length and upper bound while processing*/ + for (i = 0; i < formatcount; i++) { + int code = (int)formatcodes[i]; + int arg = formatargs[i]; + + switch ((int)code) { + case 'h': case 'H': { + outputpos += (arg + 1) / 2; /* 4 bit per arg */ + break; + } + + case 'a': case 'A': + case 'c': case 'C': + case 'x': { + outputpos += arg; /* 8 bit per arg */ + break; + } + + case 's': case 'S': case 'n': case 'v': { + outputpos += arg * 2; /* 16 bit per arg */ + break; + } + + case 'i': case 'I': { + outputpos += arg * sizeof(int); + break; + } + + case 'l': case 'L': case 'N': case 'V': { + outputpos += arg * 4; /* 32 bit per arg */ + break; + } + + case 'f': { + outputpos += arg * sizeof(float); + break; + } + + case 'd': { + outputpos += arg * sizeof(double); + break; + } + + case 'X': { + outputpos -= arg; + + if (outputpos < 0) { + php3_error(E_WARNING, "pack type %c: outside of string", code); + outputpos = 0; + } + break; + } + + case '@': { + outputpos = arg; + break; + } + } + + if (outputsize < outputpos) { + outputsize = outputpos; + } + } + + output = emalloc(outputsize + 1); + outputpos = 0; + currentarg = 1; + + /* Do actual packing */ + for (i = 0; i < formatcount; i++) { + int code = (int)formatcodes[i]; + int arg = formatargs[i]; + pval *val; + + switch ((int)code) { + case 'a': case 'A': { + memset(&output[outputpos], (code == 'a') ? '\0' : ' ', arg); + val = argv[currentarg++]; + convert_to_string(val); + memcpy(&output[outputpos], val->value.str.val, + (val->value.str.len < arg) ? val->value.str.len : arg); + outputpos += arg; + break; + } + + case 'h': case 'H': { + int nibbleshift = (code == 'h') ? 0 : 4; + int first = 1; + char *v; + + val = argv[currentarg++]; + convert_to_string(val); + v = val->value.str.val; + outputpos--; + + while (arg-- > 0) { + char n = *(v++); + + if ((n >= '0') && (n <= '9')) { + n -= '0'; + } else if ((n >= 'A') && (n <= 'F')) { + n -= ('A' - 10); + } else if ((n >= 'a') && (n <= 'f')) { + n -= ('a' - 10); + } else { + php3_error(E_WARNING, "pack type %c: illegal hex digit %c", code, n); + n = 0; + } + + if (first--) { + output[++outputpos] = 0; + } else { + first = 1; + } + + output[outputpos] |= (n << nibbleshift); + nibbleshift = (nibbleshift + 4) & 7; + } + + outputpos++; + break; + } + + case 'c': case 'C': { + while (arg-- > 0) { + _php3_pack(argv[currentarg++], 1, byte_map, &output[outputpos]); + outputpos++; + } + break; + } + + case 's': case 'S': case 'n': case 'v': { + int *map = machine_endian_short_map; + + if (code == 'n') { + map = big_endian_short_map; + } else if (code == 'v') { + map = little_endian_short_map; + } + + while (arg-- > 0) { + _php3_pack(argv[currentarg++], 2, map, &output[outputpos]); + outputpos += 2; + } + break; + } + + case 'i': case 'I': { + while (arg-- > 0) { + _php3_pack(argv[currentarg++], sizeof(int), int_map, &output[outputpos]); + outputpos += sizeof(int); + } + break; + } + + case 'l': case 'L': case 'N': case 'V': { + int *map = machine_endian_long_map; + + if (code == 'N') { + map = big_endian_long_map; + } else if (code == 'V') { + map = little_endian_long_map; + } + + while (arg-- > 0) { + _php3_pack(argv[currentarg++], 4, map, &output[outputpos]); + outputpos += 4; + } + break; + } + + case 'f': { + float v; + + while (arg-- > 0) { + val = argv[currentarg++]; + convert_to_double(val); + v = (float)val->value.dval; + memcpy(&output[outputpos], &v, sizeof(v)); + outputpos += sizeof(v); + } + break; + } + + case 'd': { + double v; + + while (arg-- > 0) { + val = argv[currentarg++]; + convert_to_double(val); + v = (double)val->value.dval; + memcpy(&output[outputpos], &v, sizeof(v)); + outputpos += sizeof(v); + } + break; + } + + case 'x': { + memset(&output[outputpos], '\0', arg); + outputpos += arg; + break; + } + + case 'X': { + outputpos -= arg; + + if (outputpos < 0) { + outputpos = 0; + } + break; + } + + case '@': { + if (arg > outputpos) { + memset(&output[outputpos], '\0', arg - outputpos); + } + outputpos = arg; + break; + } + } + } + + efree(argv); + efree(formatcodes); + efree(formatargs); + output[outputpos] = '\0'; + RETVAL_STRINGL(output, outputpos, 1); + efree(output); +} +/* }}} */ + + +static long _php3_unpack(char *data, int size, int issigned, int *map) +{ + long result; + char *cresult = (char *)&result; + int i; + + result = issigned ? -1 : 0; + + for (i = 0; i < size; i++) { + cresult[map[i]] = *(data++); + } + + return result; +} + + +/* unpack() is based on Perl's unpack(), but is modified a bit from there. + * Rather than depending on error-prone ordered lists or syntactically + * unpleasant pass-by-reference, we return an object with named paramters + * (like *_fetch_object()). Syntax is "f[repeat]name/...", where "f" is the + * formatter char (like pack()), "[repeatt]" is the optional repeater argument, + * and "name" is the name of the variable to use. + * Example: "c2chars/nints" will return an object with fields + * chars1, chars2, and ints. + * Numeric pack types will return numbers, a and A will return strings, + * f and d will return doubles. + * Implemented formats are A,a,h,H,c,C,s,S,i,I,l,L,n,N,f,d,x,X,@. + */ +/* {{{ proto array unpack(string format, string input) + Unpack binary string into named array elements according to format argument */ +PHP_FUNCTION(unpack) +{ + pval *formatarg; + pval *inputarg; + char *format; + char *input; + int formatlen; + int inputpos, inputlen; + int i; + TLS_VARS; + + if ((ARG_COUNT(ht) != 2) || getParameters(ht, 2, &formatarg, &inputarg) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(formatarg); + convert_to_string(inputarg); + + format = formatarg->value.str.val; + formatlen = formatarg->value.str.len; + input = inputarg->value.str.val; + inputlen = inputarg->value.str.len; + inputpos = 0; + + if (array_init(return_value) == FAILURE) + return; + + while (formatlen-- > 0) { + char type = *(format++); + char c; + int arg = 1; + char *name; + int namelen; + int size=0; + + /* Handle format arguments if any */ + if (formatlen > 0) { + c = *format; + + if ((c >= '0') && (c <= '9')) { + arg = atoi(format); + + while ((formatlen > 0) && (*format >= '0') && (*format <= '9')) { + format++; + formatlen--; + } + } else if (c == '*') { + arg = -1; + format++; + formatlen--; + } + } + + /* Get of new value in array */ + name = format; + + while ((formatlen > 0) && (*format != '/')) { + formatlen--; + format++; + } + + namelen = format - name; + + if (namelen > 200) + namelen = 200; + + switch ((int)type) { + /* Never use any input */ + case 'X': { + size = -1; + break; + } + + case '@': { + size = 0; + break; + } + + case 'a': case 'A': case 'h': case 'H': { + size = arg; + arg = 1; + break; + } + + /* Use 1 byte of input */ + case 'c': case 'C': case 'x': { + size = 1; + break; + } + + /* Use 2 bytes of input */ + case 's': case 'S': case 'n': case 'v': { + size = 2; + break; + } + + /* Use sizeof(int) bytes of input */ + case 'i': case 'I': { + size = sizeof(int); + break; + } + + /* Use 4 bytes of input */ + case 'l': case 'L': case 'N': case 'V': { + size = 4; + break; + } + + /* Use sizeof(float) bytes of input */ + case 'f': { + size = sizeof(float); + break; + } + + /* Use sizeof(double) bytes of input */ + case 'd': { + size = sizeof(double); + break; + } + } + + /* Do actual unpacking */ + for (i = 0; (i != arg); i++ ) { + /* Space for name + number, safe as namelen is ensured <= 200 */ + char n[256]; + + if (arg != 1) { + /* Need to add element number to name */ + sprintf(n, "%.*s%d", namelen, name, i + 1); + } else { + /* Truncate name to next format code or end of string */ + sprintf(n, "%.*s", namelen, name); + } + + if ((inputpos + size) <= inputlen) { + switch ((int)type) { + case 'a': case 'A': { + char pad = (type == 'a') ? '\0' : ' '; + int len = inputlen - inputpos; /* Remaining string */ + + /* If size was given take minimum of len and size */ + if ((size >= 0) && (len > size)) { + len = size; + } + + size = len; + + /* Remove padding chars from unpacked data */ + while (--len >= 0) { + if (input[inputpos + len] != pad) + break; + } + + add_assoc_stringl(return_value, n, &input[inputpos], len + 1, 1); + break; + } + + case 'h': case 'H': { + int len = (inputlen - inputpos) * 2; /* Remaining */ + int nibbleshift = (type == 'h') ? 0 : 4; + int first = 1; + char *buf; + int ipos, opos; + + /* If size was given take minimum of len and size */ + if ((size >= 0) && (len > size)) { + len = size; + } + + size = (len + 1) / 2; + buf = emalloc(len + 1); + + for (ipos = opos = 0; opos < len; opos++) { + char c = (input[inputpos + ipos] >> nibbleshift) & 0xf; + + if (c < 10) { + c += '0'; + } else { + c += 'a' - 10; + } + + buf[opos] = c; + nibbleshift = (nibbleshift + 4) & 7; + + if (first-- == 0) { + ipos++; + first = 1; + } + } + + buf[len] = '\0'; + add_assoc_stringl(return_value, n, buf, len, 1); + efree(buf); + break; + } + + case 'c': case 'C': { + int issigned = (type == 'c') ? (input[inputpos] & 0x80) : 0; + long v = _php3_unpack(&input[inputpos], 1, issigned, byte_map); + add_assoc_long(return_value, n, v); + break; + } + + case 's': case 'S': case 'n': case 'v': { + long v; + int issigned = 0; + int *map = machine_endian_short_map; + + if (type == 's') { + issigned = input[inputpos + (machine_little_endian ? 1 : 0)] & 0x80; + } else if (type == 'n') { + map = big_endian_short_map; + } else if (type == 'v') { + map = little_endian_short_map; + } + + v = _php3_unpack(&input[inputpos], 2, issigned, map); + add_assoc_long(return_value, n, v); + break; + } + + case 'i': case 'I': { + long v; + int issigned = 0; + + if (type == 'i') { + issigned = input[inputpos + (machine_little_endian ? (sizeof(int) - 1) : 0)] & 0x80; + } + + v = _php3_unpack(&input[inputpos], sizeof(int), issigned, int_map); + add_assoc_long(return_value, n, v); + break; + } + + case 'l': case 'L': case 'N': case 'V': { + int issigned = 0; + int *map = machine_endian_long_map; + long v; + + if (type == 'l') { + issigned = input[inputpos + (machine_little_endian ? 3 : 0)] & 0x80; + } else if (type == 'N') { + map = big_endian_long_map; + } else if (type == 'V') { + map = little_endian_long_map; + } + + v = _php3_unpack(&input[inputpos], 4, issigned, map); + add_assoc_long(return_value, n, v); + break; + } + + case 'f': { + float v; + + memcpy(&v, &input[inputpos], sizeof(float)); + add_assoc_double(return_value, n, (double)v); + break; + } + + case 'd': { + double v; + + memcpy(&v, &input[inputpos], sizeof(float)); + add_assoc_double(return_value, n, v); + break; + } + + case 'x': { + /* Do nothing with input, just skip it */ + break; + } + + case 'X': { + if (inputpos < size) { + inputpos = -size; + i = arg - 1; /* Break out of for loop */ + + if (arg >= 0) { + php3_error(E_WARNING, "pack type %c: outside of string", type); + } + } + break; + } + + case '@': { + if (arg <= inputlen) { + inputpos = arg; + } else { + php3_error(E_WARNING, "pack type %c: outside of string", type); + } + + i = arg - 1; /* Done, break out of for loop */ + break; + } + } + + inputpos += size; + } else if (arg < 0) { + /* Reached end of input for '*' repeater */ + break; + } else { + php3_error(E_ERROR, "pack type %c: not enough input, need %d, have %d", type, size, inputlen - inputpos); + RETURN_FALSE; + } + } + + formatlen--; /* Skip '/' separator, does no harm if inputlen == 0 */ + format++; + } +} +/* }}} */ + + +int php3_minit_pack(INIT_FUNC_ARGS) +{ + int machine_endian_check = 1; + int i; + TLS_VARS; + + machine_little_endian = ((char *)&machine_endian_check)[0]; + + if (machine_little_endian) { + /* Where to get lo to hi bytes from */ + byte_map[0] = 0; + + for (i = 0; i < sizeof(int); i++) { + int_map[i] = i; + } + + machine_endian_short_map[0] = 0; + machine_endian_short_map[1] = 1; + big_endian_short_map[0] = 1; + big_endian_short_map[1] = 0; + little_endian_short_map[0] = 0; + little_endian_short_map[1] = 1; + + machine_endian_long_map[0] = 0; + machine_endian_long_map[1] = 1; + machine_endian_long_map[2] = 2; + machine_endian_long_map[3] = 3; + big_endian_long_map[0] = 3; + big_endian_long_map[1] = 2; + big_endian_long_map[2] = 1; + big_endian_long_map[3] = 0; + little_endian_long_map[0] = 0; + little_endian_long_map[1] = 1; + little_endian_long_map[2] = 2; + little_endian_long_map[3] = 3; + } + else { + pval val; + int size = sizeof(val.value.lval); + val.value.lval=0; /*silence a warning*/ + + /* Where to get hi to lo bytes from */ + byte_map[0] = size - 1; + + for (i = 0; i < sizeof(int); i++) { + int_map[i] = size - (sizeof(int) - i); + } + + machine_endian_short_map[0] = size - 2; + machine_endian_short_map[1] = size - 1; + big_endian_short_map[0] = size - 2; + big_endian_short_map[1] = size - 1; + little_endian_short_map[0] = size - 1; + little_endian_short_map[1] = size - 2; + + machine_endian_long_map[0] = size - 4; + machine_endian_long_map[1] = size - 3; + machine_endian_long_map[2] = size - 2; + machine_endian_long_map[3] = size - 1; + big_endian_long_map[0] = size - 4; + big_endian_long_map[1] = size - 3; + big_endian_long_map[2] = size - 2; + big_endian_long_map[3] = size - 1; + little_endian_long_map[0] = size - 1; + little_endian_long_map[1] = size - 2; + little_endian_long_map[2] = size - 3; + little_endian_long_map[3] = size - 4; + } + + return SUCCESS; +} + + + +/* + * Local variables: + * tab-width: 4 + * End: + */ diff --git a/ext/standard/pack.h b/ext/standard/pack.h new file mode 100644 index 0000000000..36a55091a3 --- /dev/null +++ b/ext/standard/pack.h @@ -0,0 +1,42 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifndef _PACK_H +#define _PACK_H + +extern php3_module_entry pack_module_entry; +#define pack_module_ptr &pack_module_entry + +extern int php3_minit_pack(INIT_FUNC_ARGS); +extern void php3_pack(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_unpack(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _PACK_H */ diff --git a/ext/standard/pageinfo.c b/ext/standard/pageinfo.c new file mode 100644 index 0000000000..2c072c7b35 --- /dev/null +++ b/ext/standard/pageinfo.c @@ -0,0 +1,159 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Jim Winstead <jimw@php.net> | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include "pageinfo.h" + +#include <stdio.h> +#include <stdlib.h> +#if HAVE_PWD_H +#if MSVC5 +#include "win32/pwd.h" +#else +#include <pwd.h> +#endif +#endif +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <sys/stat.h> +#if MSVC5 +#include <process.h> +#endif + +#ifndef THREAD_SAFE +static long page_uid = -1; +static long page_inode = -1; +static long page_mtime = -1; +#endif + +static void _php3_statpage(void) +{ +#if !APACHE + char *path; + struct stat sb; +#endif + TLS_VARS; + +#if APACHE + /* Apache has already gone through the trouble of doing + the stat(), so the only real overhead is copying three + values. We can afford it, and it means we don't have to + worry about resetting the static variables after every + hit. */ + GLOBAL(page_uid) = GLOBAL(php3_rqst)->finfo.st_uid; + GLOBAL(page_inode) = GLOBAL(php3_rqst)->finfo.st_ino; + GLOBAL(page_mtime) = GLOBAL(php3_rqst)->finfo.st_mtime; +#else + if (GLOBAL(page_uid) == -1) { + path = GLOBAL(request_info).filename; + if (path != NULL) { + if (stat(path, &sb) == -1) { + php3_error(E_WARNING, "Unable to find file: '%s'", path); + return; + } + GLOBAL(page_uid) = sb.st_uid; + GLOBAL(page_inode) = sb.st_ino; + GLOBAL(page_mtime) = sb.st_mtime; + } + } +#endif +} + +long _php3_getuid(void) +{ + TLS_VARS; + _php3_statpage(); + return (GLOBAL(page_uid)); +} + +/* {{{ proto int getmyuid(void) + Get PHP script owner's UID */ +void php3_getmyuid(INTERNAL_FUNCTION_PARAMETERS) +{ + long uid; + TLS_VARS; + + uid = _php3_getuid(); + if (uid < 0) { + RETURN_FALSE; + } else { + RETURN_LONG(uid); + } +} +/* }}} */ + +/* {{{ proto int getmypid(void) + Get current process ID */ +void php3_getmypid(INTERNAL_FUNCTION_PARAMETERS) +{ + int pid; + TLS_VARS; + + pid = getpid(); + if (pid < 0) { + RETURN_FALSE; + } else { + RETURN_LONG((long) pid); + } +} +/* }}} */ + +/* {{{ proto int getmyinode(void) + Get the inode of the current script being parsed */ +void php3_getmyinode(INTERNAL_FUNCTION_PARAMETERS) +{ + TLS_VARS; + + _php3_statpage(); + if (GLOBAL(page_inode) < 0) { + RETURN_FALSE; + } else { + RETURN_LONG(GLOBAL(page_inode)); + } +} +/* }}} */ + +/* {{{ proto int getlastmod(void) + Get time of last page modification */ +void php3_getlastmod(INTERNAL_FUNCTION_PARAMETERS) +{ + TLS_VARS; + + _php3_statpage(); + if (GLOBAL(page_mtime) < 0) { + RETURN_FALSE; + } else { + RETURN_LONG(GLOBAL(page_mtime)); + } +} +/* }}} */ diff --git a/ext/standard/pageinfo.h b/ext/standard/pageinfo.h new file mode 100644 index 0000000000..963fe1c1c7 --- /dev/null +++ b/ext/standard/pageinfo.h @@ -0,0 +1,11 @@ +#ifndef _PROCESS_H +#define _PROCESS_H + +extern void php3_getmyuid(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_getmypid(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_getmyinode(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_getlastmod(INTERNAL_FUNCTION_PARAMETERS); + +extern long _php3_getuid(void); + +#endif diff --git a/ext/standard/php3_browscap.h b/ext/standard/php3_browscap.h new file mode 100644 index 0000000000..0b5e8cafd4 --- /dev/null +++ b/ext/standard/php3_browscap.h @@ -0,0 +1,43 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Zeev Suraski <zeev@zend.com> | + +----------------------------------------------------------------------+ + */ + + +#ifndef _PHP3_BROWSCAP_H +#define _PHP3_BROWSCAP_H + +extern php3_module_entry browscap_module_entry; +#define browscap_module_ptr &browscap_module_entry + +extern int php3_minit_browscap(INIT_FUNC_ARGS); +extern int php3_mshutdown_browscap(SHUTDOWN_FUNC_ARGS); + +extern void php3_get_browser(INTERNAL_FUNCTION_PARAMETERS); + + +#endif /* _PHP3_BROWSCAP_H */ diff --git a/ext/standard/php3_dir.h b/ext/standard/php3_dir.h new file mode 100644 index 0000000000..ee0e719dd7 --- /dev/null +++ b/ext/standard/php3_dir.h @@ -0,0 +1,48 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: | + | | + +----------------------------------------------------------------------+ + */ + + +/* $Id$ */ + +#ifndef _PHP3_DIR_H +#define _PHP3_DIR_H +extern php3_module_entry php3_dir_module_entry; +#define php3_dir_module_ptr &php3_dir_module_entry + +/* directory functions */ +extern int php3_minit_dir(INIT_FUNC_ARGS); +extern void php3_opendir(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_closedir(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_chdir(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_rewinddir(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_readdir(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_getdir(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _PHP3_DIR_H */ diff --git a/ext/standard/php3_filestat.h b/ext/standard/php3_filestat.h new file mode 100644 index 0000000000..6c82124b36 --- /dev/null +++ b/ext/standard/php3_filestat.h @@ -0,0 +1,64 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Author: Jim Winstead <jimw@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifndef _FILESTAT_H +#define _FILESTAT_H + +extern int php3_init_filestat(INIT_FUNC_ARGS); +extern int php3_shutdown_filestat(SHUTDOWN_FUNC_ARGS); +extern void php3_clearstatcache(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fileatime(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_filectime(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_filegroup(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fileinode(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_filemtime(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fileowner(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fileperms(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_filesize(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_filetype(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_iswritable(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_isreadable(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_isexec(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_isfile(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_isdir(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_islink(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fileexists(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_stat(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_lstat(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_chown(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_chgrp(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_chmod(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_touch(INTERNAL_FUNCTION_PARAMETERS); + +extern php3_module_entry php3_filestat_module_entry; +#define php3_filestat_module_ptr &php3_filestat_module_entry + +#endif /* _FILESTAT_H */ diff --git a/ext/standard/php3_iptc.h b/ext/standard/php3_iptc.h new file mode 100644 index 0000000000..4166fbd4ff --- /dev/null +++ b/ext/standard/php3_iptc.h @@ -0,0 +1,38 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Thies C. Arntzen <thies@digicol.de> | + +----------------------------------------------------------------------+ + */ + + +/* $Id$ */ + +#ifndef _PHPIPTC_H +#define _PHPIPTC_H + +extern void php3_iptcparse(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _PHPIPTC_H */ diff --git a/ext/standard/php3_link.h b/ext/standard/php3_link.h new file mode 100644 index 0000000000..80718a893b --- /dev/null +++ b/ext/standard/php3_link.h @@ -0,0 +1,41 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: | + | | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ +#ifndef _PHP3_LINK_H +#define _PHP3_LINK_H + +extern void php3_link(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_unlink(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_readlink(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_linkinfo(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_symlink(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _PHP3_LINK_H */ diff --git a/ext/standard/php3_mail.h b/ext/standard/php3_mail.h new file mode 100644 index 0000000000..3fb763ecb0 --- /dev/null +++ b/ext/standard/php3_mail.h @@ -0,0 +1,46 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + +----------------------------------------------------------------------+ + */ + + +/* $Id$ */ + +#ifndef _MAIL_H +#define _MAIL_H +#if HAVE_SENDMAIL +extern php3_module_entry mail_module_entry; +#define mail_module_ptr &mail_module_entry + +extern void php3_mail(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_info_mail(void); +extern int _php3_mail(char *to, char *subject, char *message, char *headers); + +#else +#define mail_module_ptr NULL +#endif +#endif /* _MAIL_H */ diff --git a/ext/standard/php3_standard.h b/ext/standard/php3_standard.h new file mode 100644 index 0000000000..828b3c4de6 --- /dev/null +++ b/ext/standard/php3_standard.h @@ -0,0 +1,71 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: | + | | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#include "basic_functions.h" +#include "phpmath.h" +#include "php3_string.h" +#include "base64.h" +#include "php3_dir.h" +#include "dns.h" +#include "reg.h" +#include "php3_mail.h" +#include "md5.h" +#include "html.h" +#include "exec.h" +#include "file.h" +#include "php3_syslog.h" +#include "php3_filestat.h" +#include "php3_browscap.h" +#include "pack.h" +#include "datetime.h" +#include "microtime.h" +#include "url.h" +#include "pageinfo.h" +#include "cyr_convert.h" +#include "php3_link.h" +#include "fsock.h" +#include "image.h" +#include "php3_iptc.h" +#include "info.h" +#include "uniqid.h" +#include "php3_var.h" +#include "quot_print.h" +#include "type.h" + +#define standard_module_ptr basic_functions_module_ptr + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/php3_string.h b/ext/standard/php3_string.h new file mode 100644 index 0000000000..eea721f5dd --- /dev/null +++ b/ext/standard/php3_string.h @@ -0,0 +1,99 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + | Stig Sæther Bakken <ssb@guardian.no> | + +----------------------------------------------------------------------+ + */ + + +/* $Id$ */ + +#ifndef _PHPSTRING_H +#define _PHPSTRING_H + +#ifndef THREAD_SAFE +extern char *strtok_string; +#endif + +extern void php3_strlen(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_strcmp(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_strspn(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_strcspn(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_strcasecmp(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_str_replace(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_chop(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_trim(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_ltrim(INTERNAL_FUNCTION_PARAMETERS); +extern void soundex(INTERNAL_FUNCTION_PARAMETERS); + +extern void php3_explode(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_implode(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_strtok(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_strtoupper(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_strtolower(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_basename(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_dirname(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_strstr(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_strpos(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_strrpos(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_strrchr(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_substr(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_quotemeta(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_ucfirst(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_ucwords(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_strtr(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_strrev(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_hebrev(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_hebrev_with_conversion(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_user_sprintf(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_user_printf(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_addslashes(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_stripslashes(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_chr(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_ord(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_newline_to_br(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_setlocale(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_stristr(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_chunk_split(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_parsestr(INTERNAL_FUNCTION_PARAMETERS); + +#if HAVE_CRYPT +extern php3_module_entry crypt_module_entry; +#define crypt_module_ptr &crypt_module_entry +extern void php3_crypt(INTERNAL_FUNCTION_PARAMETERS); +#else +#define crypt_module_ptr NULL +#endif + +extern PHPAPI char *_php3_strtoupper(char *s); +extern PHPAPI char *_php3_strtolower(char *s); +extern char *_StrTr(char *string, char *str_from, char *str_to); +extern PHPAPI char *_php3_addslashes(char *string, int length, int *new_length, int freeit); +extern PHPAPI void _php3_stripslashes(char *string, int *len); +extern PHPAPI void _php3_dirname(char *str, int len); +extern PHPAPI char *php3i_stristr(unsigned char *s, unsigned char *t); + +#endif /* _PHPSTRING_H */ diff --git a/ext/standard/php3_syslog.h b/ext/standard/php3_syslog.h new file mode 100644 index 0000000000..028a5aa018 --- /dev/null +++ b/ext/standard/php3_syslog.h @@ -0,0 +1,44 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: | + | | + +----------------------------------------------------------------------+ + */ +#if HAVE_SYSLOG_H +extern php3_module_entry syslog_module_entry; +#define syslog_module_ptr &syslog_module_entry + +extern int php3_minit_syslog(INIT_FUNC_ARGS); +extern int php3_rinit_syslog(INIT_FUNC_ARGS); +extern int php3_rshutdown_syslog(SHUTDOWN_FUNC_ARGS); +extern void php3_openlog(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_syslog(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_closelog(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_define_syslog_variables(INTERNAL_FUNCTION_PARAMETERS); + +#else +#define syslog_module_ptr NULL +#endif diff --git a/ext/standard/php3_var.h b/ext/standard/php3_var.h new file mode 100644 index 0000000000..238a0a3cb3 --- /dev/null +++ b/ext/standard/php3_var.h @@ -0,0 +1,42 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Jani Lehtimäki <jkl@njet.net> | + +----------------------------------------------------------------------+ + */ + + +#ifndef _PHPVAR_H +#define _PHPVAR_H + +PHP_FUNCTION(var_dump); +PHP_FUNCTION(serialize); +PHP_FUNCTION(unserialize); + +void php3api_var_dump(pval *struc, int level); +void php3api_var_serialize(pval *buf, pval *struc); +int php3api_var_unserialize(pval *rval, char **p, char *max); + +#endif /* _PHPVAR_H */ diff --git a/ext/standard/phpdir.h b/ext/standard/phpdir.h new file mode 100644 index 0000000000..5813f79c36 --- /dev/null +++ b/ext/standard/phpdir.h @@ -0,0 +1,44 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + +----------------------------------------------------------------------+ + */ + + +/* $Id$ */ + +#ifndef _PHPDIR_H +#define _PHPDIR_H + +/* directory functions */ +extern void php3_opendir(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_closedir(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_chdir(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_rewinddir(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_readdir(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_getdir(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _PHPDIR_H */ diff --git a/ext/standard/phpmath.h b/ext/standard/phpmath.h new file mode 100644 index 0000000000..ed3759018b --- /dev/null +++ b/ext/standard/phpmath.h @@ -0,0 +1,70 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Jim Winstead (jimw@php.net) | + | Stig Sæther Bakken <ssb@guardian.no> | + +----------------------------------------------------------------------+ + */ + + +/* $Id$ */ + +#ifndef _PHPMATH_H +#define _PHPMATH_H +extern void php3_sin(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_cos(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_tan(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_asin(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_acos(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_atan(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_atan2(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_pi(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_exp(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_log(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_log10(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_pow(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_sqrt(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_srand(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_rand(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_getrandmax(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_mt_srand(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_mt_rand(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_mt_getrandmax(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_abs(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_ceil(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_floor(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_round(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_decbin(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_dechex(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_decoct(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_bindec(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_hexdec(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_octdec(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_base_convert(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_number_format(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_deg2rad(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_rad2deg(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _PHPMATH_H */ diff --git a/ext/standard/quot_print.c b/ext/standard/quot_print.c new file mode 100644 index 0000000000..55937d3b86 --- /dev/null +++ b/ext/standard/quot_print.c @@ -0,0 +1,109 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Kirill Maximov (kir@rus.net | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#include <stdlib.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <string.h> +#include <errno.h> + +#include "php.h" +#include "quot_print.h" + +#include <stdio.h> + +/* +* Converting HEX char to INT value +*/ +static char _php3_hex2int(int c) +{ + if ( isdigit(c) ) + { + return c - '0'; + } + else if ( c >= 'A' && c <= 'F' ) + { + return c - 'A' + 10; + } + else + { + return -1; + } +} + +/* +* +* Decoding Quoted-printable string. +* +*/ +/* {{{ proto string quoted_printable_decode(string str) + Convert a quoted-printable string to an 8 bit string */ +void php3_quoted_printable_decode(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg1; + char *str; + int i = 0, j = 0; + + if (ARG_COUNT(ht) != 1 || getParameters(ht,1,&arg1)==FAILURE) + { + WRONG_PARAM_COUNT; + } + convert_to_string(arg1); + + str = arg1->value.str.val; + while ( str[i] ) + { + if ( (str[i] == '=') && str[i+1] && str[i+2] && + ( isdigit((int)str[i+1]) || (str[i+1]<='F' && str[i+1]>='A')) + && + ( isdigit((int)str[i+2]) || (str[i+2]<='F' && str[i+2]>='A')) + ) + { + str[j++] = (_php3_hex2int((int)str[i+1]) << 4 ) + + _php3_hex2int((int)str[i+2]); + i += 3; + } + else if ( str[i] == 13 ) + { + i++; + } + else + { + str[j++] = str[i++]; + } + } + str[j] = '\0'; + + RETVAL_STRINGL(str, j, 1) +} +/* }}} */ diff --git a/ext/standard/quot_print.h b/ext/standard/quot_print.h new file mode 100644 index 0000000000..abd959545f --- /dev/null +++ b/ext/standard/quot_print.h @@ -0,0 +1,37 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Kirill Maximov (kir@rus.net) | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifndef _QUOT_PRINT_H +#define _QUOT_PRINT_H + +extern void php3_quoted_printable_decode(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _QUOT_PRINT_H */ diff --git a/ext/standard/rand.c b/ext/standard/rand.c new file mode 100644 index 0000000000..e117833296 --- /dev/null +++ b/ext/standard/rand.c @@ -0,0 +1,343 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + | Zeev Suraski <zeev@zend.com | + | Pedro Melo <melo@ip.pt> | + | | + | Based on code from: Shawn Cokus <Cokus@math.washington.edu> | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ + +#include <stdlib.h> + +#include "php.h" +#include "phpmath.h" + +#ifndef RAND_MAX +#define RAND_MAX (1<<15) + +#endif + +/* + This is the ``Mersenne Twister'' random number generator MT19937, which + generates pseudorandom integers uniformly distributed in 0..(2^32 - 1) + starting from any odd seed in 0..(2^32 - 1). This version is a recode + by Shawn Cokus (Cokus@math.washington.edu) on March 8, 1998 of a version by + Takuji Nishimura (who had suggestions from Topher Cooper and Marc Rieffel in + July-August 1997). + + Effectiveness of the recoding (on Goedel2.math.washington.edu, a DEC Alpha + running OSF/1) using GCC -O3 as a compiler: before recoding: 51.6 sec. to + generate 300 million random numbers; after recoding: 24.0 sec. for the same + (i.e., 46.5% of original time), so speed is now about 12.5 million random + number generations per second on this machine. + + According to the URL <http://www.math.keio.ac.jp/~matumoto/emt.html> + (and paraphrasing a bit in places), the Mersenne Twister is ``designed + with consideration of the flaws of various existing generators,'' has + a period of 2^19937 - 1, gives a sequence that is 623-dimensionally + equidistributed, and ``has passed many stringent tests, including the + die-hard test of G. Marsaglia and the load test of P. Hellekalek and + S. Wegenkittl.'' It is efficient in memory usage (typically using 2506 + to 5012 bytes of static data, depending on data type sizes, and the code + is quite short as well). It generates random numbers in batches of 624 + at a time, so the caching and pipelining of modern systems is exploited. + It is also divide- and mod-free. + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation (either version 2 of the License or, at your + option, any later version). This library is distributed in the hope that + it will be useful, but WITHOUT ANY WARRANTY, without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + the GNU Library General Public License for more details. You should have + received a copy of the GNU Library General Public License along with this + library; if not, write to the Free Software Foundation, Inc., 59 Temple + Place, Suite 330, Boston, MA 02111-1307, USA. + + The code as Shawn received it included the following notice: + + Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. When + you use this, send an e-mail to <matumoto@math.keio.ac.jp> with + an appropriate reference to your work. + + It would be nice to CC: <Cokus@math.washington.edu> when you write. + + + + uint32 must be an unsigned integer type capable of holding at least 32 + bits; exactly 32 should be fastest, but 64 is better on an Alpha with + GCC at -O3 optimization so try your options and see what's best for you + + Melo: we should put some ifdefs here to catch those alphas... +*/ + +typedef unsigned int uint32; + +#define N (624) /* length of state vector */ +#define M (397) /* a period parameter */ +#define K (0x9908B0DFU) /* a magic constant */ +#define hiBit(u) ((u) & 0x80000000U) /* mask all but highest bit of u */ +#define loBit(u) ((u) & 0x00000001U) /* mask all but lowest bit of u */ +#define loBits(u) ((u) & 0x7FFFFFFFU) /* mask the highest bit of u */ +#define mixBits(u, v) (hiBit(u)|loBits(v)) /* move hi bit of u to hi bit of v */ + +static uint32 state[N+1]; /* state vector + 1 extra to not violate ANSI C */ +static uint32 *next; /* next random value is computed from here */ +static int left = -1; /* can *next++ this many times before reloading */ + + +static void seedMT(uint32 seed) +{ + /* + We initialize state[0..(N-1)] via the generator + + x_new = (69069 * x_old) mod 2^32 + + from Line 15 of Table 1, p. 106, Sec. 3.3.4 of Knuth's + _The Art of Computer Programming_, Volume 2, 3rd ed. + + Notes (SJC): I do not know what the initial state requirements + of the Mersenne Twister are, but it seems this seeding generator + could be better. It achieves the maximum period for its modulus + (2^30) iff x_initial is odd (p. 20-21, Sec. 3.2.1.2, Knuth); if + x_initial can be even, you have sequences like 0, 0, 0, ...; + 2^31, 2^31, 2^31, ...; 2^30, 2^30, 2^30, ...; 2^29, 2^29 + 2^31, + 2^29, 2^29 + 2^31, ..., etc. so I force seed to be odd below. + + Even if x_initial is odd, if x_initial is 1 mod 4 then + + the lowest bit of x is always 1, + the next-to-lowest bit of x is always 0, + the 2nd-from-lowest bit of x alternates ... 0 1 0 1 0 1 0 1 ... , + the 3rd-from-lowest bit of x 4-cycles ... 0 1 1 0 0 1 1 0 ... , + the 4th-from-lowest bit of x has the 8-cycle ... 0 0 0 1 1 1 1 0 ... , + ... + + and if x_initial is 3 mod 4 then + + the lowest bit of x is always 1, + the next-to-lowest bit of x is always 1, + the 2nd-from-lowest bit of x alternates ... 0 1 0 1 0 1 0 1 ... , + the 3rd-from-lowest bit of x 4-cycles ... 0 0 1 1 0 0 1 1 ... , + the 4th-from-lowest bit of x has the 8-cycle ... 0 0 1 1 1 1 0 0 ... , + ... + + The generator's potency (min. s>=0 with (69069-1)^s = 0 mod 2^32) is + 16, which seems to be alright by p. 25, Sec. 3.2.1.3 of Knuth. It + also does well in the dimension 2..5 spectral tests, but it could be + better in dimension 6 (Line 15, Table 1, p. 106, Sec. 3.3.4, Knuth). + + Note that the random number user does not see the values generated + here directly since reloadMT() will always munge them first, so maybe + none of all of this matters. In fact, the seed values made here could + even be extra-special desirable if the Mersenne Twister theory says + so-- that's why the only change I made is to restrict to odd seeds. + */ + + register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = state; + register int j; + + for(left=0, *s++=x, j=N; --j; + *s++ = (x*=69069U) & 0xFFFFFFFFU); +} + + +static uint32 reloadMT(void) +{ + register uint32 *p0=state, *p2=state+2, *pM=state+M, s0, s1; + register int j; + + if(left < -1) + seedMT(4357U); + + left=N-1, next=state+1; + + for(s0=state[0], s1=state[1], j=N-M+1; --j; s0=s1, s1=*p2++) + *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); + + for(pM=state, j=M; --j; s0=s1, s1=*p2++) + *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); + + s1=state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); + s1 ^= (s1 >> 11); + s1 ^= (s1 << 7) & 0x9D2C5680U; + s1 ^= (s1 << 15) & 0xEFC60000U; + return(s1 ^ (s1 >> 18)); +} + + +static inline uint32 randomMT(void) +{ + uint32 y; + + if(--left < 0) + return(reloadMT()); + + y = *next++; + y ^= (y >> 11); + y ^= (y << 7) & 0x9D2C5680U; + y ^= (y << 15) & 0xEFC60000U; + return(y ^ (y >> 18)); +} + + +#if HAVE_LRAND48 +#define PHP_RAND_MAX 2147483647 +#else +#define PHP_RAND_MAX RAND_MAX +#endif + +void php3_srand(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg); +#ifdef HAVE_SRAND48 + srand48((unsigned int) arg->value.lval); +#else +#ifdef HAVE_SRANDOM + srandom((unsigned int) arg->value.lval); +#else + srand((unsigned int) arg->value.lval); +#endif +#endif +} + +void php3_mt_srand(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(arg); + seedMT(arg->value.lval); +} + +void php3_rand(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *p_min=NULL, *p_max=NULL; + + switch (ARG_COUNT(ht)) { + case 0: + break; + case 2: + if (getParameters(ht, 2, &p_min, &p_max)==FAILURE) { + RETURN_FALSE; + } + convert_to_long(p_min); + convert_to_long(p_max); + if (p_max->value.lval-p_min->value.lval <= 0) { + php3_error(E_WARNING,"rand(): Invalid range: %ld..%ld", p_min->value.lval, p_max->value.lval); + } + break; + default: + WRONG_PARAM_COUNT; + break; + } + + return_value->type = IS_LONG; +#ifdef HAVE_LRAND48 + return_value->value.lval = lrand48(); +#else +#ifdef HAVE_RANDOM + return_value->value.lval = random(); +#else + return_value->value.lval = rand(); +#endif +#endif + + if (p_min && p_max) { /* implement range */ + return_value->value.lval = p_min->value.lval + + (int)((double)p_max->value.lval * return_value->value.lval/(PHP_RAND_MAX+(double)p_min->value.lval)); + } +} + +void php3_mt_rand(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *p_min=NULL, *p_max=NULL; + + switch (ARG_COUNT(ht)) { + case 0: + break; + case 2: + if (getParameters(ht, 2, &p_min, &p_max)==FAILURE) { + RETURN_FALSE; + } + convert_to_long(p_min); + convert_to_long(p_max); + if (p_max->value.lval-p_min->value.lval <= 0) { + php3_error(E_WARNING,"mtrand(): Invalid range: %ld..%ld", p_min->value.lval, p_max->value.lval); + } + break; + default: + WRONG_PARAM_COUNT; + break; + } + + return_value->type = IS_LONG; + /* + * Melo: hmms.. randomMT() returns 32 random bits... + * Yet, the previous php3_rand only returns 31 at most. + * So I put a right shift to loose the lsb. It *seems* + * better than clearing the msb. + * Update: + * I talked with Cokus via email and it won't ruin the algorithm + */ + return_value->value.lval = (long)(randomMT() >> 1); + + if (p_min && p_max) { /* implement range */ + return_value->value.lval = p_min->value.lval + + (int)((double)p_max->value.lval * return_value->value.lval/(PHP_RAND_MAX+(double)p_min->value.lval)); + } +} + +void php3_getrandmax(INTERNAL_FUNCTION_PARAMETERS) +{ + return_value->type = IS_LONG; + return_value->value.lval = PHP_RAND_MAX; +} + +void php3_mt_getrandmax(INTERNAL_FUNCTION_PARAMETERS) +{ + return_value->type = IS_LONG; + /* + * Melo: it could be 2^^32 but we only use 2^^31 to maintain + * compatibility with the previous php3_rand + */ + return_value->value.lval = 2147483647; /* 2^^31 */ +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/reg.c b/ext/standard/reg.c new file mode 100644 index 0000000000..42d36493d6 --- /dev/null +++ b/ext/standard/reg.c @@ -0,0 +1,569 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + | Jim Winstead <jimw@php.net> | + | Jaakko Hyvätti <jaakko@hyvatti.iki.fi> | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include <stdio.h> +#include "php.h" +#include "php3_string.h" +#include "reg.h" + +unsigned char third_argument_force_ref[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE }; + +function_entry reg_functions[] = { + {"ereg", php3_ereg, third_argument_force_ref }, + {"ereg_replace", php3_eregreplace, NULL }, + {"eregi", php3_eregi, third_argument_force_ref }, + {"eregi_replace", php3_eregireplace, NULL }, + {"split", php3_split, NULL}, + {"join", php3_implode, NULL}, + {"sql_regcase", php3_sql_regcase, NULL}, + {NULL, NULL, NULL} +}; + +php3_module_entry regexp_module_entry = { + "Regular Expressions", reg_functions, NULL, NULL, NULL, NULL, NULL, STANDARD_MODULE_PROPERTIES +}; + +/* This is the maximum number of (..) constructs we'll generate from a + call to ereg() or eregi() with the optional third argument. */ +#define NS 10 + +/* + * _php3_reg_eprint - convert error number to name + */ +static void _php3_reg_eprint(int err, regex_t *re) { + char *buf = NULL, *message = NULL; + size_t len; + size_t buf_len; + +#ifdef REG_ITOA + /* get the length of the message */ + buf_len = regerror(REG_ITOA | err, re, NULL, 0); + if (buf_len) { + buf = (char *)emalloc(buf_len * sizeof(char)); + if (!buf) return; /* fail silently */ + /* finally, get the error message */ + regerror(REG_ITOA | err, re, buf, buf_len); + } +#else + buf_len = 0; +#endif + len = regerror(err, re, NULL, 0); + if (len) { + message = (char *)emalloc((buf_len + len + 2) * sizeof(char)); + if (!message) { + return; /* fail silently */ + } + if (buf_len) { + snprintf(message, buf_len, "%s: ", buf); + buf_len += 1; /* so pointer math below works */ + } + /* drop the message into place */ + regerror(err, re, message + buf_len, len); + + php3_error(E_WARNING, "%s", message); + } + + STR_FREE(buf); + STR_FREE(message); +} + +static void _php3_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase) +{ + pval *regex, /* Regular expression */ + *findin, /* String to apply expression to */ + *array = NULL; /* Optional register array */ + regex_t re; + regmatch_t subs[NS]; + int err, i, match_len, string_len; + int copts = 0; + off_t start, end; + char *buf = NULL; + char *string = NULL; + TLS_VARS; + + if (icase) + copts |= REG_ICASE; + + switch(ARG_COUNT(ht)) { + case 2: + if (getParameters(ht, 2, ®ex, &findin) == FAILURE) { + WRONG_PARAM_COUNT; + } + /* don't bother doing substring matching if we're not going + to make use of the information */ + copts |= REG_NOSUB; + break; + case 3: + if (getParameters(ht, 3, ®ex, &findin, &array) == FAILURE) { + WRONG_PARAM_COUNT; + } + if (!ParameterPassedByReference(ht, 3)) { + php3_error(E_WARNING, "Array to be filled with values must be passed by reference."); + RETURN_FALSE; + } + break; + default: + WRONG_PARAM_COUNT; + } + + + /* compile the regular expression from the supplied regex */ + if (regex->type == IS_STRING) { + err = regcomp(&re, regex->value.str.val, REG_EXTENDED | copts); + } else { + /* we convert numbers to integers and treat them as a string */ + if (regex->type == IS_DOUBLE) + convert_to_long(regex); /* get rid of decimal places */ + convert_to_string(regex); + /* don't bother doing an extended regex with just a number */ + err = regcomp(&re, regex->value.str.val, copts); + } + + if (err) { + _php3_reg_eprint(err, &re); + RETURN_FALSE; + } + + /* make a copy of the string we're looking in */ + convert_to_string(findin); + string = estrndup(findin->value.str.val, findin->value.str.len); + + /* actually execute the regular expression */ + err = regexec(&re, string, (size_t) NS, subs, 0); + if (err && err != REG_NOMATCH) { + _php3_reg_eprint(err, &re); + regfree(&re); + RETURN_FALSE; + } + match_len = 1; + + if (array && err != REG_NOMATCH) { + match_len = (int) (subs[0].rm_eo - subs[0].rm_so); + string_len = strlen(string) + 1; + + buf = emalloc(string_len); + if (!buf) { + php3_error(E_WARNING, "Unable to allocate memory in _php3_ereg"); + RETURN_FALSE; + } + + pval_destructor(array _INLINE_TLS); /* start with clean array */ + array_init(array); + + for (i = 0; i < NS; i++) { + start = subs[i].rm_so; + end = subs[i].rm_eo; + if (start != -1 && end > 0 && start < string_len && end < string_len && start < end) { + add_index_stringl(array, i, string+start, end-start, 1); + } + } + efree(buf); + } + + efree(string); + if (err == REG_NOMATCH) { + RETVAL_FALSE; + } else { + if (match_len == 0) + match_len = 1; + RETVAL_LONG(match_len); + } + regfree(&re); +} + +/* {{{ proto int ereg(string pattern, string string [, array registers]) + Regular expression match */ +void php3_ereg(INTERNAL_FUNCTION_PARAMETERS) +{ + _php3_ereg(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ proto int eregi(string pattern, string string [, array registers]) + Case-insensitive regular expression match */ +void php3_eregi(INTERNAL_FUNCTION_PARAMETERS) +{ + _php3_ereg(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* this is the meat and potatoes of regex replacement! */ +char *_php3_regreplace(const char *pattern, const char *replace, const char *string, int icase, int extended) +{ + regex_t re; + regmatch_t subs[NS]; + + char *buf, /* buf is where we build the replaced string */ + *nbuf, /* nbuf is used when we grow the buffer */ + *walkbuf; /* used to walk buf when replacing backrefs */ + const char *walk; /* used to walk replacement string for backrefs */ + int buf_len; + int pos, tmp, string_len, new_l; + int err, copts = 0; + + string_len = strlen(string); + if (!string_len) + return (char *)string; + + if (icase) + copts = REG_ICASE; + if (extended) + copts |= REG_EXTENDED; + err = regcomp(&re, pattern, copts); + if (err) { + _php3_reg_eprint(err, &re); + return ((char *) -1); + } + + /* start with a buffer that is twice the size of the stringo + we're doing replacements in */ + buf_len = 2 * string_len + 1; + buf = emalloc(buf_len * sizeof(char)); + if (!buf) { + php3_error(E_WARNING, "Unable to allocate memory in _php3_regreplace"); + regfree(&re); + return ((char *) -1); + } + + err = pos = 0; + buf[0] = '\0'; + + while (!err) { + err = regexec(&re, &string[pos], (size_t) NS, subs, (pos ? REG_NOTBOL : 0)); + + if (err && err != REG_NOMATCH) { + _php3_reg_eprint(err, &re); + regfree(&re); + return ((char *) -1); + } + if (!err) { + /* backref replacement is done in two passes: + 1) find out how long the string will be, and allocate buf + 2) copy the part before match, replacement and backrefs to buf + + Jaakko Hyvätti <Jaakko.Hyvatti@iki.fi> + */ + + new_l = strlen(buf) + subs[0].rm_so; /* part before the match */ + walk = replace; + while (*walk) + if ('\\' == *walk + && '0' <= walk[1] && '9' >= walk[1] + && subs[walk[1] - '0'].rm_so > -1 + && subs[walk[1] - '0'].rm_eo > -1) { + new_l += subs[walk[1] - '0'].rm_eo + - subs[walk[1] - '0'].rm_so; + walk += 2; + } else { + new_l++; + walk++; + } + + if (new_l + 1 > buf_len) { + buf_len = 1 + buf_len + 2 * new_l; + nbuf = emalloc(buf_len); + strcpy(nbuf, buf); + efree(buf); + buf = nbuf; + } + tmp = strlen(buf); + /* copy the part of the string before the match */ + strncat(buf, &string[pos], subs[0].rm_so); + + /* copy replacement and backrefs */ + walkbuf = &buf[tmp + subs[0].rm_so]; + walk = replace; + while (*walk) + if ('\\' == *walk + && '0' <= walk[1] && '9' >= walk[1] + && subs[walk[1] - '0'].rm_so > -1 + && subs[walk[1] - '0'].rm_eo > -1) { + tmp = subs[walk[1] - '0'].rm_eo + - subs[walk[1] - '0'].rm_so; + memcpy (walkbuf, + &string[pos + subs[walk[1] - '0'].rm_so], + tmp); + walkbuf += tmp; + walk += 2; + } else + *walkbuf++ = *walk++; + *walkbuf = '\0'; + + /* and get ready to keep looking for replacements */ + if (subs[0].rm_so == subs[0].rm_eo) { + if (subs[0].rm_so + pos >= string_len) + break; + new_l = strlen (buf) + 1; + if (new_l + 1 > buf_len) { + buf_len = 1 + buf_len + 2 * new_l; + nbuf = emalloc(buf_len * sizeof(char)); + strcpy(nbuf, buf); + efree(buf); + buf = nbuf; + } + pos += subs[0].rm_eo + 1; + buf [new_l-1] = string [pos-1]; + buf [new_l] = '\0'; + } else { + pos += subs[0].rm_eo; + } + } else { /* REG_NOMATCH */ + new_l = strlen(buf) + strlen(&string[pos]); + if (new_l + 1 > buf_len) { + buf_len = new_l + 1; /* now we know exactly how long it is */ + nbuf = emalloc(buf_len * sizeof(char)); + strcpy(nbuf, buf); + efree(buf); + buf = nbuf; + } + /* stick that last bit of string on our output */ + strcat(buf, &string[pos]); + } + } + + /* don't want to leak memory .. */ + regfree(&re); + + /* whew. */ + return (buf); +} + +static void _php3_eregreplace(INTERNAL_FUNCTION_PARAMETERS, int icase) +{ + pval *arg_pattern, + *arg_replace, + *arg_string; + char *pattern; + char *string; + char *replace; + char *ret; + TLS_VARS; + + if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg_pattern, &arg_replace, &arg_string) == FAILURE) { + WRONG_PARAM_COUNT; + } + + if (arg_pattern->type == IS_STRING) { + if (arg_pattern->value.str.val && arg_pattern->value.str.len) + pattern = estrndup(arg_pattern->value.str.val,arg_pattern->value.str.len); + else + pattern = empty_string; + } else { + convert_to_long(arg_pattern); + pattern = emalloc(2); + pattern[0] = (char) arg_pattern->value.lval; + pattern[1] = '\0'; + } + + if (arg_replace->type == IS_STRING) { + if (arg_replace->value.str.val && arg_replace->value.str.len) + replace = estrndup(arg_replace->value.str.val, arg_replace->value.str.len); + else + replace = empty_string; + } else { + convert_to_long(arg_replace); + replace = emalloc(2); + replace[0] = (char) arg_replace->value.lval; + replace[1] = '\0'; + } + + convert_to_string(arg_string); + if (arg_string->value.str.val && arg_string->value.str.len) + string = estrndup(arg_string->value.str.val, arg_string->value.str.len); + else + string = empty_string; + + /* do the actual work */ + ret = _php3_regreplace(pattern, replace, string, icase, 1); + if (ret == (char *) -1) { + RETVAL_FALSE; + } else { + RETVAL_STRING(ret,1); + STR_FREE(ret); + } + STR_FREE(string); + STR_FREE(replace); + STR_FREE(pattern); +} + +/* {{{ proto string ereg_replace(string pattern, string string [, array registers]) + Replace regular expression */ +void php3_eregreplace(INTERNAL_FUNCTION_PARAMETERS) +{ + _php3_eregreplace(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ proto string eregi_replace(string pattern, string string [, array registers]) + Case insensitive replace regular expression */ +void php3_eregireplace(INTERNAL_FUNCTION_PARAMETERS) +{ + _php3_eregreplace(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* ("root", "passwd", "uid", "gid", "other:stuff:like:/bin/sh") + = split(":", $passwd_file, 5); */ +/* {{{ proto array split(string pattern, string string [, int limit]) + split string into array by regular expression */ +void php3_split(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *spliton, *str, *arg_count = NULL; + regex_t re; + regmatch_t subs[1]; + char *strp, *endp; + int err, size, count; + TLS_VARS; + + switch (ARG_COUNT(ht)) { + case 2: + if (getParameters(ht, 2, &spliton, &str) == FAILURE) + WRONG_PARAM_COUNT; + count = -1; + break; + case 3: + if (getParameters(ht, 3, &spliton, &str, &arg_count) == FAILURE) + WRONG_PARAM_COUNT; + convert_to_long(arg_count); + count = arg_count->value.lval; + break; + default: + WRONG_PARAM_COUNT; + } + + convert_to_string(spliton); + convert_to_string(str); + + strp = str->value.str.val; + endp = str->value.str.val + strlen(str->value.str.val); + + err = regcomp(&re, spliton->value.str.val, REG_EXTENDED); + if (err) { + php3_error(E_WARNING, "unexpected regex error (%d)", err); + RETURN_FALSE; + } + + if (array_init(return_value) == FAILURE) { + regfree(&re); + RETURN_FALSE; + } + + /* churn through str, generating array entries as we go */ + while ((count == -1 || count > 1) && !(err = regexec(&re, strp, 1, subs, 0))) { + if (subs[0].rm_so == 0 && subs[0].rm_eo) { + /* match is at start of string, return empty string */ + add_next_index_stringl(return_value, empty_string, 0, 1); + /* skip ahead the length of the regex match */ + strp+=subs[0].rm_eo; + } else if (subs[0].rm_so==0 && subs[0].rm_eo==0) { + /* No more matches */ + regfree(&re); + php3_error(E_WARNING, "bad regular expression for split()"); + _php3_hash_destroy(return_value->value.ht); + efree(return_value->value.ht); + RETURN_FALSE; + } else { + /* On a real match */ + + /* make a copy of the substring */ + size = subs[0].rm_so; + + /* add it to the array */ + add_next_index_stringl(return_value, strp, size, 1); + + /* point at our new starting point */ + strp = strp + subs[0].rm_eo; + } + + /* if we're only looking for a certain number of points, + stop looking once we hit it */ + if (count != -1) count--; + } + + /* see if we encountered an error */ + if (err && err != REG_NOMATCH) { + php3_error(E_WARNING, "unexpected regex error (%d)", err); + regfree(&re); + _php3_hash_destroy(return_value->value.ht); + efree(return_value->value.ht); + RETURN_FALSE; + } + + /* otherwise we just have one last element to add to the array */ + size = endp - strp; + + add_next_index_stringl(return_value, strp, size, 1); + + regfree(&re); + + return; +} +/* }}} */ + +/* {{{ proto string sql_regcase(string string) + Make regular expression for case insensitive match */ +PHPAPI void php3_sql_regcase(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *string; + char *tmp; + register int i; + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &string)==FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(string); + + tmp = (char *) emalloc(string->value.str.len*4+1); + + for (i=0; i<string->value.str.len; i++) { + tmp[i*4] = '['; + tmp[i*4+1]=toupper((unsigned char)string->value.str.val[i]); + tmp[i*4+2]=tolower((unsigned char)string->value.str.val[i]); + tmp[i*4+3]=']'; + } + tmp[string->value.str.len*4]=0; + + return_value->value.str.val = tmp; + return_value->value.str.len = string->value.str.len*4; + return_value->type = IS_STRING; +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/reg.h b/ext/standard/reg.h new file mode 100644 index 0000000000..bb33aa768f --- /dev/null +++ b/ext/standard/reg.h @@ -0,0 +1,48 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + +----------------------------------------------------------------------+ + */ + + +/* $Id$ */ + +#ifndef _REG_H +#define _REG_H + +extern php3_module_entry regexp_module_entry; +#define regexp_module_ptr ®exp_module_entry + +extern char *_php3_regreplace(const char *pattern, const char *replace, const char *string, int icase, int extended); + +extern void php3_ereg(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_eregi(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_eregireplace(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_eregreplace(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_split(INTERNAL_FUNCTION_PARAMETERS); +extern PHPAPI void php3_sql_regcase(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _REG_H */ diff --git a/ext/standard/soundex.c b/ext/standard/soundex.c new file mode 100644 index 0000000000..24eef3fcc9 --- /dev/null +++ b/ext/standard/soundex.c @@ -0,0 +1,136 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Author: Bjørn Borud - Guardian Networks AS <borud@guardian.no> | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ + +#include "php.h" +#include <stdlib.h> +#include <errno.h> +#include <ctype.h> +#include "php3_string.h" + +/* Simple soundex algorithm as described by Knuth in TAOCP, vol 3 */ +/* {{{ proto string soundex(string str) + Calculate the soundex key of a string */ +void soundex(INTERNAL_FUNCTION_PARAMETERS) +{ + char l, u; + char *somestring; + int i, j, n; + pval *arg; + + /* pad with '0' and terminate with 0 ;-) */ + char soundex[5] = + {'0', '0', '0', '0', 0}; + + static char soundex_table[26] = + {0, /* A */ + '1', /* B */ + '2', /* C */ + '3', /* D */ + 0, /* E */ + '1', /* F */ + '2', /* G */ + 0, /* H */ + 0, /* I */ + '2', /* J */ + '2', /* K */ + '4', /* L */ + '5', /* M */ + '5', /* N */ + 0, /* O */ + '1', /* P */ + '2', /* Q */ + '6', /* R */ + '2', /* S */ + '3', /* T */ + 0, /* U */ + '1', /* V */ + 0, /* W */ + '2', /* X */ + 0, /* Y */ + '2'}; /* Z */ + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + if (arg->value.str.len==0) { + RETURN_FALSE; + } + + somestring = arg->value.str.val; + + n = arg->value.str.len; + + /* convert chars to upper case and strip non-letter chars */ + j = 0; + for (i = 0; i < n; i++) { + u = toupper(somestring[i]); + if ((u > 64) && (u < 91)) { + somestring[j] = u; + j++; + } + } + + /* null-terminate string */ + somestring[j] = 0; + + n = strlen(somestring); + + /* prefix soundex string with first valid char */ + soundex[0] = somestring[0]; + + /* remember first char */ + l = soundex_table[((somestring[0]) - 65)]; + + j = 1; + + /* build soundex string */ + for (i = 1; i < n && j < 4; i++) { + u = soundex_table[((somestring[i]) - 65)]; + + if (u != l) { + if (u != 0) { + soundex[(int) j++] = u; + } + l = u; + } + } + + return_value->value.str.val = estrndup(soundex, 4); + return_value->value.str.len = strlen(soundex); + return_value->type = IS_STRING; +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/string.c b/ext/standard/string.c new file mode 100644 index 0000000000..8700bb3f4a --- /dev/null +++ b/ext/standard/string.c @@ -0,0 +1,1590 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + | Stig Sæther Bakken <ssb@guardian.no> | + | Zeev Suraski <bourbon@nevision.net.il> | + +----------------------------------------------------------------------+ + */ + + +/* $Id$ */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include <stdio.h> +#include "php.h" +#include "reg.h" +#include "post.h" +#include "php3_string.h" +#if HAVE_SETLOCALE +#include <locale.h> +#endif +#include "zend_execute.h" +#include "php_globals.h" + + +/* {{{ proto int strlen(string str) + Get string length */ +void php3_strlen(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + RETVAL_LONG(str->value.str.len); +} +/* }}} */ + +/* {{{ proto int strcmp(string str1, string str2) + Binary safe string comparison */ +void php3_strcmp(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *s1,*s2; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &s1, &s2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(s1); + convert_to_string(s2); + RETURN_LONG(php3_binary_strcmp(s1,s2)); +} +/* }}} */ + +/* {{{ proto int strcasecmp(string str1, string str2) + Binary safe case-insensitive string comparison */ +void php3_strcasecmp(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *s1,*s2; + + if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &s1, &s2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(s1); + convert_to_string(s2); + RETURN_LONG(strcasecmp(s1->value.str.val,s2->value.str.val)); +} +/* }}} */ + +/* {{{ proto int strspn(string str, string mask) + Find length of initial segment consisting entirely of characters found in mask */ +void php3_strspn(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *s1,*s2; + + if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &s1, &s2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(s1); + convert_to_string(s2); + RETURN_LONG(strspn(s1->value.str.val,s2->value.str.val)); +} +/* }}} */ + +/* {{{ proto int strcspn(string str, string mask) + Find length of initial segment consisting entirely of characters not found in mask */ +void php3_strcspn(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *s1,*s2; + + if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &s1, &s2) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(s1); + convert_to_string(s2); + RETURN_LONG(strcspn(s1->value.str.val,s2->value.str.val)); +} +/* }}} */ + +/* {{{ proto string chop(string str) + Remove trailing whitespace */ +void php3_chop(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str; + register int i; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + + if (str->type == IS_STRING) { + int len = str->value.str.len; + char *c = str->value.str.val; + for (i = len - 1; i >= 0; i--) { + if (c[i] == ' ' || c[i] == '\n' || c[i] == '\r' || + c[i] == '\t' || c[i] == '\v') { + len--; + } else { + break; + } + } + RETVAL_STRINGL(c, len, 1); + return; + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto string trim(string str) + Strip whitespace from the beginning and end of a string */ +void php3_trim(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str; + register int i; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + + if (str->type == IS_STRING) { + int len = str->value.str.len; + int trimmed = 0; + char *c = str->value.str.val; + for (i = 0; i < len; i++) { + if (c[i] == ' ' || c[i] == '\n' || c[i] == '\r' || + c[i] == '\t' || c[i] == '\v') { + trimmed++; + } else { + break; + } + } + len-=trimmed; + c+=trimmed; + for (i = len - 1; i >= 0; i--) { + if (c[i] == ' ' || c[i] == '\n' || c[i] == '\r' || + c[i] == '\t' || c[i] == '\v') { + len--; + } else { + break; + } + } + RETVAL_STRINGL(c, len, 1); + return; + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto string ltrim(string str) + Strip whitespace from the beginning of a string */ +void php3_ltrim(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str; + register int i; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + + if (str->type == IS_STRING) { + int len = str->value.str.len; + int trimmed = 0; + char *c = str->value.str.val; + for (i = 0; i < len; i++) { + if (c[i] == ' ' || c[i] == '\n' || c[i] == '\r' || + c[i] == '\t' || c[i] == '\v') { + trimmed++; + } else { + break; + } + } + RETVAL_STRINGL(c+trimmed, len-trimmed, 1); + return; + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto array(string separator, string str) + Split a string on string separator and return array of components */ +void php3_explode(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str, *delim; + char *work_str, *p1, *p2; + int i = 0; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &delim, &str) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + convert_to_string(delim); + + if (strlen(delim->value.str.val)==0) { + /* the delimiter must be a valid C string that's at least 1 character long */ + php3_error(E_WARNING,"Empty delimiter"); + RETURN_FALSE; + } + if (array_init(return_value) == FAILURE) { + return; + } + work_str = p1 = estrndup(str->value.str.val,str->value.str.len); + p2 = strstr(p1, delim->value.str.val); + if (p2 == NULL) { + add_index_string(return_value, i++, p1, 1); + } else do { + p2[0] = 0; + add_index_string(return_value, i++, p1, 1); + p1 = p2 + delim->value.str.len; + } while ((p2 = strstr(p1, delim->value.str.val)) && p2 != work_str); + if (p1 != work_str) { + add_index_string(return_value, i++, p1, 1); + } + efree(work_str); +} +/* }}} */ + +/* {{{ proto string implode(array src, string glue) + Join array elements placing glue string between items and return one string */ +void php3_implode(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg1, *arg2, *delim, *tmp, *arr; + int len = 0, count = 0; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) { + WRONG_PARAM_COUNT; + } + + if (arg1->type == IS_ARRAY && arg2->type == IS_STRING) { + arr = arg1; + delim = arg2; + } else if (arg2->type == IS_ARRAY) { + convert_to_string(arg1); + arr = arg2; + delim = arg1; + } else { + php3_error(E_WARNING, "Bad arguments to %s()", + get_active_function_name()); + return; + } + + /* convert everything to strings, and calculate length */ + _php3_hash_internal_pointer_reset(arr->value.ht); + while (_php3_hash_get_current_data(arr->value.ht, (void **) &tmp) == SUCCESS) { + convert_to_string(tmp); + if (tmp->type == IS_STRING) { + len += tmp->value.str.len; + if (count>0) { + len += delim->value.str.len; + } + count++; + } + _php3_hash_move_forward(arr->value.ht); + } + + /* do it */ + return_value->value.str.val = (char *) emalloc(len + 1); + return_value->value.str.val[0] = '\0'; + return_value->value.str.val[len] = '\0'; + _php3_hash_internal_pointer_reset(arr->value.ht); + while (_php3_hash_get_current_data(arr->value.ht, (void **) &tmp) == SUCCESS) { + if (tmp->type == IS_STRING) { + count--; + strcat(return_value->value.str.val, tmp->value.str.val); + if (count > 0) { + strcat(return_value->value.str.val, delim->value.str.val); + } + } + _php3_hash_move_forward(arr->value.ht); + } + return_value->type = IS_STRING; + return_value->value.str.len = len; +} +/* }}} */ + +#ifndef THREAD_SAFE +char *strtok_string; +#endif + +/* {{{ proto string strtok([string str,] string token) + Tokenize a string */ +void php3_strtok(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str, *tok; +#ifndef THREAD_SAFE + static char *strtok_pos1 = NULL; + static char *strtok_pos2 = NULL; +#endif + char *token = NULL, *tokp=NULL; + char *first = NULL; + int argc; + TLS_VARS; + + argc = ARG_COUNT(ht); + + if ((argc == 1 && getParameters(ht, 1, &tok) == FAILURE) || + (argc == 2 && getParameters(ht, 2, &str, &tok) == FAILURE) || + argc < 1 || argc > 2) { + WRONG_PARAM_COUNT; + } + convert_to_string(tok); + tokp = token = tok->value.str.val; + + if (argc == 2) { + convert_to_string(str); + + STR_FREE(GLOBAL(strtok_string)); + GLOBAL(strtok_string) = estrndup(str->value.str.val,str->value.str.len); + STATIC(strtok_pos1) = GLOBAL(strtok_string); + STATIC(strtok_pos2) = NULL; + } + if (STATIC(strtok_pos1) && *STATIC(strtok_pos1)) { + for ( /* NOP */ ; token && *token; token++) { + STATIC(strtok_pos2) = strchr(STATIC(strtok_pos1), (int) *token); + if (!first || (STATIC(strtok_pos2) && STATIC(strtok_pos2) < first)) { + first = STATIC(strtok_pos2); + } + } /* NB: token is unusable now */ + + STATIC(strtok_pos2) = first; + if (STATIC(strtok_pos2)) { + *STATIC(strtok_pos2) = '\0'; + } + RETVAL_STRING(STATIC(strtok_pos1),1); +#if 0 + /* skip 'token' white space for next call to strtok */ + while (STATIC(strtok_pos2) && + strchr(tokp, *(STATIC(strtok_pos2)+1))) { + STATIC(strtok_pos2)++; + } +#endif + if (STATIC(strtok_pos2)) + STATIC(strtok_pos1) = STATIC(strtok_pos2) + 1; + else + STATIC(strtok_pos1) = NULL; + } else { + RETVAL_FALSE; + } +} +/* }}} */ + +PHPAPI char *_php3_strtoupper(char *s) +{ + char *c; + int ch; + + c = s; + while (*c) { + ch = toupper((unsigned char)*c); + *c++ = ch; + } + return (s); +} + +/* {{{ proto string strtoupper(string str) + Make a string uppercase */ +void php3_strtoupper(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + char *ret; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg)) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + ret = _php3_strtoupper(arg->value.str.val); + RETVAL_STRING(ret,1); +} +/* }}} */ + + +PHPAPI char *_php3_strtolower(char *s) +{ + register int ch; + char *c; + + c = s; + while (*c) { + ch = tolower((unsigned char)*c); + *c++ = ch; + } + return (s); +} + +/* {{{ proto string strtolower(string str) + Make a string lowercase */ +void php3_strtolower(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str; + char *ret; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str)) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + + ret = _php3_strtolower(str->value.str.val); + RETVAL_STRING(ret,1); +} +/* }}} */ + +/* {{{ proto string basename(string path) + Return the filename component of the path */ +void php3_basename(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str; + char *ret, *c; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str)) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + ret = estrdup(str->value.str.val); + c = ret + str->value.str.len -1; + while (*c == '/' +#ifdef MSVC5 + || *c == '\\' +#endif + ) + c--; + *(c + 1) = '\0'; + if ((c = strrchr(ret, '/')) +#ifdef MSVC5 + || (c = strrchr(ret, '\\')) +#endif + ) { + RETVAL_STRING(c + 1,1); + } else { + RETVAL_STRING(str->value.str.val,1); + } + efree(ret); +} +/* }}} */ + +PHPAPI void _php3_dirname(char *str, int len) { + register char *c; + + c = str + len - 1; + while (*c == '/' +#ifdef MSVC5 + || *c == '\\' +#endif + ) + c--; /* strip trailing slashes */ + *(c + 1) = '\0'; + if ((c = strrchr(str, '/')) +#ifdef MSVC5 + || (c = strrchr(str, '\\')) +#endif + ) + *c='\0'; +} + +/* {{{ proto string dirname(string path) + Return the directory name component of the path */ +void php3_dirname(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str; + char *ret; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str)) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + ret = estrdup(str->value.str.val); + _php3_dirname(ret,str->value.str.len); + RETVAL_STRING(ret,1); + efree(ret); +} +/* }}} */ + + +/* case-insensitve strstr */ +PHPAPI char *php3i_stristr(unsigned char *s, unsigned char *t) +{ + int i, j, k, l; + + for (i = 0; s[i]; i++) { + for (j = 0, l = k = i; s[k] && t[j] && + tolower(s[k]) == tolower(t[j]); j++, k++) + ; + if (t[j] == '\0') + return s + l; + } + return NULL; +} + +/* {{{ proto string strstr(string haystack, string needle) + Find first occurrence of a string within another, case insensitive */ +void php3_stristr(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *haystack, *needle; + char *found = NULL; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &haystack, &needle) == + FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(haystack); + convert_to_string(needle); + + if (strlen(needle->value.str.val)==0) { + php3_error(E_WARNING,"Empty delimiter"); + RETURN_FALSE; + } + found = php3i_stristr(haystack->value.str.val, needle->value.str.val); + + if (found) { + RETVAL_STRING(found,1); + } else { + RETVAL_FALSE; + } +} +/* }}} */ + +/* {{{ proto string strstr(string haystack, string needle) + Find first occurrence of a string within another */ +void php3_strstr(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *haystack, *needle; + char *found = NULL; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &haystack, &needle) == + FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(haystack); + + if (needle->type == IS_STRING) { + if (strlen(needle->value.str.val)==0) { + php3_error(E_WARNING,"Empty delimiter"); + RETURN_FALSE; + } + found = strstr(haystack->value.str.val, needle->value.str.val); + } else { + convert_to_long(needle); + found = strchr(haystack->value.str.val, (char) needle->value.lval); + } + + + if (found) { + RETVAL_STRING(found,1); + } else { + RETVAL_FALSE; + } +} +/* }}} */ + +/* {{{ proto int strpos(string haystack, string needle) + Find position of first occurrence of a string within another */ +void php3_strpos(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *haystack, *needle, *OFFSET; + int offset = 0; + char *found = NULL; + TLS_VARS; + + switch(ARG_COUNT(ht)) { + case 2: + if (getParameters(ht, 2, &haystack, &needle) == FAILURE) { + WRONG_PARAM_COUNT; + } + break; + case 3: + if (getParameters(ht, 3, &haystack, &needle, &OFFSET) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(OFFSET); + offset = OFFSET->value.lval; + break; + default: + WRONG_PARAM_COUNT; + } + convert_to_string(haystack); + if (offset > haystack->value.str.len) { + php3_error(E_WARNING,"offset not contained in string"); + RETURN_FALSE; + } + + if (needle->type == IS_STRING) { + if (needle->value.str.len==0) { + php3_error(E_WARNING,"Empty delimiter"); + RETURN_FALSE; + } + found = strstr(haystack->value.str.val+offset, needle->value.str.val); + } else { + convert_to_long(needle); + found = strchr(haystack->value.str.val+offset, (char) needle->value.lval); + } + + if (found) { + RETVAL_LONG(found - haystack->value.str.val); + } else { + RETVAL_FALSE; + } +} +/* }}} */ + +/* {{{ proto int strrpos(string haystack, string needle) + Find the last occurrence of a character in a string within another */ +void php3_strrpos(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *haystack, *needle; + char *found = NULL; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &haystack, &needle) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(haystack); + + if (needle->type == IS_STRING) { + found = strrchr(haystack->value.str.val, *needle->value.str.val); + } else { + convert_to_long(needle); + found = strrchr(haystack->value.str.val, (char) needle->value.lval); + } + + if (found) { + RETVAL_LONG(haystack->value.str.len - strlen(found)); + } else { + RETVAL_FALSE; + } +} +/* }}} */ + +/* {{{ proto string strrchr(string haystack, string needle) + Find the last occurrence of a character in a string within another */ +void php3_strrchr(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *haystack, *needle; + char *found = NULL; + TLS_VARS; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &haystack, &needle) == + FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(haystack); + + if (needle->type == IS_STRING) { + found = strrchr(haystack->value.str.val, *needle->value.str.val); + } else { + + convert_to_long(needle); + found = strrchr(haystack->value.str.val, needle->value.lval); + } + + + if (found) { + RETVAL_STRING(found,1); + } else { + RETVAL_FALSE; + } +} +/* }}} */ + +static char * +_php3_chunk_split(char *src, int srclen, char *end, int endlen, int chunklen) +{ + char *dest; + char *p, *q; + int chunks; /* complete chunks! */ + int restlen; + + chunks = srclen / chunklen; + restlen = srclen - chunks * chunklen; /* srclen % chunklen */ + + dest = emalloc((srclen + (chunks + 1) * endlen + 1) * sizeof(char)); + + for(p = src, q = dest; p < (src + srclen - chunklen + 1); ) { + memcpy(q, p, chunklen); + q += chunklen; + memcpy(q, end, endlen); + q += endlen; + p += chunklen; + } + + if(restlen) { + memcpy(q, p, restlen); + q += restlen; + memcpy(q, end, endlen); + q += endlen; + } + + *q = '\0'; + + return(dest); +} + +/* {{{ proto string chunk_split(string str [, int chunklen [, string ending]]) + Return split line */ +void php3_chunk_split(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *p_str, *p_chunklen, *p_ending; + int argc; + char *result; + char *end = "\r\n"; + int endlen = 2; + int chunklen = 76; + TLS_VARS; + + argc = ARG_COUNT(ht); + + if(!((argc == 1 && getParameters(ht, 1, &p_str) != FAILURE) || + (argc == 2 && getParameters(ht, 2, &p_str, &p_chunklen) != FAILURE) || + (argc == 3 && getParameters(ht, 3, &p_str, &p_chunklen, + &p_ending) != FAILURE))) { + WRONG_PARAM_COUNT; + } + + switch(argc) { + case 3: + convert_to_string(p_ending); + end = p_ending->value.str.val; + endlen = p_ending->value.str.len; + case 2: + convert_to_long(p_chunklen); + chunklen = p_chunklen->value.lval; + case 1: + convert_to_string(p_str); + } + + if(chunklen == 0) { + php3_error(E_WARNING, "chunk length is 0"); + RETURN_FALSE; + } + + result = _php3_chunk_split(p_str->value.str.val, p_str->value.str.len, + end, endlen, chunklen); + + if(result) { + RETVAL_STRING(result, 0); + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto string substr(string str, int start [, int length]) + Return part of a string */ +void php3_substr(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *string, *from, *len; + int argc, l; + int f; + TLS_VARS; + + argc = ARG_COUNT(ht); + + if ((argc == 2 && getParameters(ht, 2, &string, &from) == FAILURE) || + (argc == 3 && getParameters(ht, 3, &string, &from, &len) == FAILURE) || + argc < 2 || argc > 3) { + WRONG_PARAM_COUNT; + } + convert_to_string(string); + convert_to_long(from); + f = from->value.lval; + + if (argc == 2) { + l = string->value.str.len; + } else { + convert_to_long(len); + l = len->value.lval; + } + + /* if "from" position is negative, count start position from the end + * of the string + */ + if (f < 0) { + f = string->value.str.len + f; + if (f < 0) { + f = 0; + } + } + + /* if "length" position is negative, set it to the length + * needed to stop that many chars from the end of the string + */ + if (l < 0) { + l = (string->value.str.len - f) + l; + if (l < 0) { + l = 0; + } + } + + if (f >= (int)string->value.str.len) { + RETURN_FALSE; + } + + if ((f + l) < (int)string->value.str.len) { + string->value.str.val[f + l] = '\0'; + } + RETVAL_STRING(string->value.str.val + f,1); +} +/* }}} */ + +/* {{{ proto string quotemeta(string str) + Quote meta characters */ +void php3_quotemeta(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + char *str, *old; + char *p, *q; + char c; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + old = arg->value.str.val; + + if (!*old) { + RETURN_FALSE; + } + + str = emalloc(2 * arg->value.str.len + 1); + + for(p = old, q = str; (c = *p); p++) { + switch(c) { + case '.': + case '\\': + case '+': + case '*': + case '?': + case '[': + case '^': + case ']': + case '$': + case '(': + case ')': + *q++ = '\\'; + /* break is missing _intentionally_ */ + default: + *q++ = c; + } + } + *q = 0; + RETVAL_STRING(erealloc(str, q - str + 1), 0); +} +/* }}} */ + +/* {{{ proto int ord(string character) + Return ASCII value of character */ +void php3_ord(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + RETVAL_LONG((unsigned char)str->value.str.val[0]); +} +/* }}} */ + +/* {{{ proto string chr(int ascii) + Convert ASCII code to a character */ +void php3_chr(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *num; + char temp[2]; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(num); + temp[0] = (char) num->value.lval; + temp[1] = '\0'; + RETVAL_STRINGL(temp, 1,1); +} +/* }}} */ + +/* {{{ proto string(string str) + Make a string's first character uppercase */ +void php3_ucfirst(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + if (!*arg->value.str.val) { + RETURN_FALSE; + } + *arg->value.str.val = toupper((unsigned char)*arg->value.str.val); + RETVAL_STRING(arg->value.str.val,1); +} +/* }}} */ + +/* {{{ proto string ucwords(string str) + Uppercase the first character of every word in a string */ +void php3_ucwords(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + char *r; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + if (!*arg->value.str.val) { + RETURN_FALSE; + } + *arg->value.str.val = toupper((unsigned char)*arg->value.str.val); + r=arg->value.str.val; + while((r=strstr(r," "))){ + if(*(r+1)){ + r++; + *r=toupper((unsigned char)*r); + } + } + RETVAL_STRING(arg->value.str.val,1); +} +/* }}} */ + +/* {{{ proto string strtr(string str, string from, string to) + Translate characters in str using given translation tables */ +void php3_strtr(INTERNAL_FUNCTION_PARAMETERS) +{ /* strtr(STRING,FROM,TO) */ + pval *str, *from, *to; + unsigned char xlat[256]; + unsigned char *str_from, *str_to, *string; + int i, len1, len2; + TLS_VARS; + + if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &str, &from, &to) == + FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + convert_to_string(from); + convert_to_string(to); + + string = (unsigned char*) str->value.str.val; + str_from = (unsigned char*) from->value.str.val; + str_to = (unsigned char*) to->value.str.val; + + len1 = from->value.str.len; + len2 = to->value.str.len; + + if (len1 > len2) { + str_from[len2] = '\0'; + len1 = len2; + } + for (i = 0; i < 256; xlat[i] = i, i++); + + for (i = 0; i < len1; i++) { + xlat[(unsigned char) str_from[i]] = str_to[i]; + } + + for (i = 0; i < str->value.str.len; i++) { + string[i] = xlat[(unsigned char) string[i]]; + } + + RETVAL_STRING((char *)string,1); +} +/* }}} */ + + +/* {{{ proto string strrev(string str) + Reverse a string */ +void php3_strrev(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str; + int i,len; + char c; + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &str)==FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(str); + + len = str->value.str.len; + + for (i=0; i<len-1-i; i++) { + c=str->value.str.val[i]; + str->value.str.val[i] = str->value.str.val[len-1-i]; + str->value.str.val[len-1-i]=c; + } + + *return_value = *str; + pval_copy_constructor(return_value); +} +/* }}} */ + + +/* be careful, this edits the string in-place */ +PHPAPI void _php3_stripslashes(char *string, int *len) +{ + char *s, *t; + int l; + char escape_char='\\'; + PLS_FETCH(); + + if (PG(magic_quotes_sybase)) { + escape_char='\''; + } + + if (len != NULL) { + l = *len; + } else { + l = strlen(string); + } + s = string; + t = string; + while (l > 0) { + if (*t == escape_char) { + t++; /* skip the slash */ + if (len != NULL) + (*len)--; + l--; + if (l > 0) { + if(*t=='0') { + *s++='\0'; + t++; + } else { + *s++ = *t++; /* preserve the next character */ + } + l--; + } + } else { + if (s != t) + *s++ = *t++; + else { + s++; + t++; + } + l--; + } + } + if (s != t) { + *s = '\0'; + } +} + +/* {{{ proto string addslashes(string str) + Escape single quote, double quotes and backslash characters in a string with backslashes */ +void php3_addslashes(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + return_value->value.str.val = _php3_addslashes(str->value.str.val,str->value.str.len,&return_value->value.str.len,0); + return_value->type = IS_STRING; +} +/* }}} */ + +/* {{{ proto string stripslashes(string str) + Strip backslashes from a string */ +void php3_stripslashes(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(str); + + /* let RETVAL do the estrdup() */ + RETVAL_STRING(str->value.str.val,1); + _php3_stripslashes(return_value->value.str.val,&return_value->value.str.len); +} +/* }}} */ + +#ifndef HAVE_STRERROR +#if !APACHE +char *strerror(int errnum) +{ + extern int sys_nerr; + extern char *sys_errlist[]; +#ifndef THREAD_SAFE + static char str_ebuf[40]; +#endif + + if ((unsigned int)errnum < sys_nerr) return(sys_errlist[errnum]); + (void)sprintf(STATIC(str_ebuf), "Unknown error: %d", errnum); + return(STATIC(str_ebuf)); +} +#endif +#endif + + +PHPAPI char *_php3_addslashes(char *str, int length, int *new_length, int should_free) +{ + /* maximum string length, worst case situation */ + char *new_str = (char *) emalloc((length?length:strlen(str))*2+1); + char *source,*target; + char *end; + char c; + PLS_FETCH(); + + for (source=str,end=source+length,target=new_str; (c = *source) || source<end; source++) { + switch(c) { + case '\0': + *target++ = '\\'; + *target++ = '0'; + break; + case '\'': + if (PG(magic_quotes_sybase)) { + *target++ = '\''; + *target++ = '\''; + break; + } + /* break is missing *intentionally* */ + case '\"': + case '\\': + if (!PG(magic_quotes_sybase)) { + *target++ = '\\'; + } + /* break is missing *intentionally* */ + default: + *target++ = c; + break; + } + } + *target = 0; + if(new_length) *new_length = target - new_str; + if (should_free) { + STR_FREE(str); + } + return new_str; +} + + +#define _HEB_BLOCK_TYPE_ENG 1 +#define _HEB_BLOCK_TYPE_HEB 2 +#define isheb(c) (((((unsigned char) c)>=224) && (((unsigned char) c)<=250)) ? 1 : 0) +#define _isblank(c) (((((unsigned char) c)==' ' || ((unsigned char) c)=='\t')) ? 1 : 0) +#define _isnewline(c) (((((unsigned char) c)=='\n' || ((unsigned char) c)=='\r')) ? 1 : 0) + +static void _php3_char_to_str(char *str,uint len,char from,char *to,int to_len,pval *result) +{ + int char_count=0; + char *source,*target,*tmp,*source_end=str+len, *tmp_end=NULL; + + for (source=str; source<source_end; source++) { + if (*source==from) { + char_count++; + } + } + + result->type = IS_STRING; + + if (char_count==0) { + result->value.str.val = estrndup(str,len); + result->value.str.len = len; + return; + } + + result->value.str.len = len+char_count*(to_len-1); + result->value.str.val = target = (char *) emalloc(result->value.str.len+1); + + for (source=str; source<source_end; source++) { + if (*source==from) { + for (tmp=to,tmp_end=tmp+to_len; tmp<tmp_end; tmp++) { + *target = *tmp; + target++; + } + } else { + *target = *source; + target++; + } + } + *target = 0; +} + +/* + * this is a binary safe equivalent to strnstr + * note that we don't check for the end in str_to_str but here + */ + +static inline char * +_php3_memnstr(char *haystack, char *needle, int needle_len, char *end) +{ + char *p = haystack; + char *s = NULL; + + for(; p < end - needle_len + 1&& + (s = memchr(p, *needle, end - haystack)); p = s + 1) { + if(memcmp(s, needle, needle_len) == 0) + return s; + } + return NULL; +} + +/* + * because of efficiency we use malloc/realloc/free here + * erealloc _will_ move your data around - it took me some time + * to find out ... Sascha Schumann <sas@schell.de> 981220 + */ + +static char *_php3_str_to_str(char *haystack, int length, + char *needle, int needle_len, char *str, int str_len, int *_new_length) +{ + char *p, *q; + char *r, *s; + char *end = haystack + length; + char *new; + + new = malloc(length); + /* we jump through haystack searching for the needle. hurray! */ + for(p = haystack, q = new; + (r = _php3_memnstr(p, needle, needle_len, end));) { + /* this ain't optimal. you could call it `efficient memory usage' */ + realloc(new, (q - new) + (r - p) + (str_len) + 1); + memcpy(q, p, r - p); + q += r - p; + memcpy(q, str, str_len); + q += str_len; + p = r + needle_len; + } + /* if there is a rest, copy it */ + if((end - p)) { + s = (q) + (end - p); + new = realloc(new, s - new + 1); + memcpy(q, p, end - p); + q = s; + } + *q = '\0'; + if(_new_length) *_new_length = q - new; + return new; +} + +/* {{{ proto string str_replace(string needle, string str, string haystack) + Replace all occurrences of needle in haystack with str */ +void php3_str_replace(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *haystack, *needle, *str; + char *new; + + if(ARG_COUNT(ht) != 3 || + getParameters(ht, 3, &needle, &str, &haystack) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(haystack); + convert_to_string(needle); + convert_to_string(str); + + if(needle->value.str.len == 1) { + _php3_char_to_str(haystack->value.str.val,haystack->value.str.len,needle->value.str.val[0],str->value.str.val, str->value.str.len ,return_value); + return; + } + + new = _php3_str_to_str(haystack->value.str.val, haystack->value.str.len, + needle->value.str.val, needle->value.str.len, + str->value.str.val, str->value.str.len, + &return_value->value.str.len); + return_value->value.str.val = emalloc(return_value->value.str.len + 1); + memcpy(return_value->value.str.val, new, return_value->value.str.len + 1); + free(new); + return_value->type = IS_STRING; +} +/* }}} */ + +/* Converts Logical Hebrew text (Hebrew Windows style) to Visual text + * Cheers/complaints/flames - Zeev Suraski <zeev@php.net> + */ +static void _php3_hebrev(INTERNAL_FUNCTION_PARAMETERS,int convert_newlines) +{ + pval *str,*max_chars_per_line; + char *heb_str,*tmp,*target,*opposite_target,*broken_str; + int block_start, block_end, block_type, block_length, i; + int block_ended; + long max_chars=0; + int begin,end,char_count,orig_begin; + + + switch(ARG_COUNT(ht)) { + case 1: + if (getParameters(ht, 1, &str)==FAILURE) { + RETURN_FALSE; + } + break; + case 2: + if (getParameters(ht, 2, &str, &max_chars_per_line)==FAILURE) { + RETURN_FALSE; + } + convert_to_long(max_chars_per_line); + max_chars = max_chars_per_line->value.lval; + break; + default: + WRONG_PARAM_COUNT; + break; + } + + convert_to_string(str); + + if (str->value.str.len==0) { + RETURN_FALSE; + } + + tmp = str->value.str.val; + block_start=block_end=0; + block_ended=0; + + heb_str = (char *) emalloc(str->value.str.len+1); + target = heb_str+str->value.str.len; + opposite_target = heb_str; + *target = 0; + target--; + + block_length=0; + + if (isheb(*tmp)) { + block_type = _HEB_BLOCK_TYPE_HEB; + } else { + block_type = _HEB_BLOCK_TYPE_ENG; + } + + do { + if (block_type==_HEB_BLOCK_TYPE_HEB) { + while((isheb((int)*(tmp+1)) || _isblank((int)*(tmp+1)) || ispunct((int)*(tmp+1)) || (int)*(tmp+1)=='\n' ) && block_end<str->value.str.len-1) { + tmp++; + block_end++; + block_length++; + } + for (i=block_start; i<=block_end; i++) { + *target = str->value.str.val[i]; + switch (*target) { + case '(': + *target = ')'; + break; + case ')': + *target = '('; + break; + default: + break; + } + target--; + } + block_type = _HEB_BLOCK_TYPE_ENG; + } else { + while(!isheb(*(tmp+1)) && (int)*(tmp+1)!='\n' && block_end<str->value.str.len-1) { + tmp++; + block_end++; + block_length++; + } + while ((_isblank((int)*tmp) || ispunct((int)*tmp)) && *tmp!='/' && *tmp!='-' && block_end>block_start) { + tmp--; + block_end--; + } + for (i=block_end; i>=block_start; i--) { + *target = str->value.str.val[i]; + target--; + } + block_type = _HEB_BLOCK_TYPE_HEB; + } + block_start=block_end+1; + } while(block_end<str->value.str.len-1); + + + broken_str = (char *) emalloc(str->value.str.len+1); + begin=end=str->value.str.len-1; + target = broken_str; + + while (1) { + char_count=0; + while ((!max_chars || char_count<max_chars) && begin>0) { + char_count++; + begin--; + if (begin<=0 || _isnewline(heb_str[begin])) { + while(begin>0 && _isnewline(heb_str[begin-1])) { + begin--; + char_count++; + } + break; + } + } + if (char_count==max_chars) { /* try to avoid breaking words */ + int new_char_count=char_count, new_begin=begin; + + while (new_char_count>0) { + if (_isblank(heb_str[new_begin]) || _isnewline(heb_str[new_begin])) { + break; + } + new_begin++; + new_char_count--; + } + if (new_char_count>0) { + char_count=new_char_count; + begin=new_begin; + } + } + orig_begin=begin; + + if (_isblank(heb_str[begin])) { + heb_str[begin]='\n'; + } + while (begin<=end && _isnewline(heb_str[begin])) { /* skip leading newlines */ + begin++; + } + for (i=begin; i<=end; i++) { /* copy content */ + *target = heb_str[i]; + target++; + } + for (i=orig_begin; i<=end && _isnewline(heb_str[i]); i++) { + *target = heb_str[i]; + target++; + } + begin=orig_begin; + + if (begin<=0) { + *target = 0; + break; + } + begin--; + end=begin; + } + efree(heb_str); + + if (convert_newlines) { + _php3_char_to_str(broken_str,str->value.str.len,'\n',"<br>\n",5,return_value); + efree(broken_str); + } else { + return_value->value.str.val = broken_str; + return_value->value.str.len = str->value.str.len; + return_value->type = IS_STRING; + } +} + + +/* {{{ proto string hebrev(string str [, int max_chars_per_line]) + Convert logical Hebrew text to visual text */ +void php3_hebrev(INTERNAL_FUNCTION_PARAMETERS) +{ + _php3_hebrev(INTERNAL_FUNCTION_PARAM_PASSTHRU,0); +} +/* }}} */ + +/* {{{ proto string hebrev(string str [, int max_chars_per_line]) + Convert logical Hebrew text to visual text with newline conversion */ +void php3_hebrev_with_conversion(INTERNAL_FUNCTION_PARAMETERS) +{ + _php3_hebrev(INTERNAL_FUNCTION_PARAM_PASSTHRU,1); +} +/* }}} */ + +/* {{{ proto string nl2br(string str) + Converts newlines to HTML line breaks */ +void php3_newline_to_br(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *str; + + if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &str)==FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string(str); + + _php3_char_to_str(str->value.str.val,str->value.str.len,'\n',"<br>\n",5,return_value); +} +/* }}} */ + +/* {{{ proto string setlocale(string category, string locale) + Set locale information */ +void php3_setlocale(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *category, *locale; + int cat; + char *loc, *retval; + + if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &category, &locale)==FAILURE) + WRONG_PARAM_COUNT; +#if HAVE_SETLOCALE + convert_to_string(category); + convert_to_string(locale); + if (!strcasecmp ("LC_ALL", category->value.str.val)) + cat = LC_ALL; + else if (!strcasecmp ("LC_COLLATE", category->value.str.val)) + cat = LC_COLLATE; + else if (!strcasecmp ("LC_CTYPE", category->value.str.val)) + cat = LC_CTYPE; + else if (!strcasecmp ("LC_MONETARY", category->value.str.val)) + cat = LC_MONETARY; + else if (!strcasecmp ("LC_NUMERIC", category->value.str.val)) + cat = LC_NUMERIC; + else if (!strcasecmp ("LC_TIME", category->value.str.val)) + cat = LC_TIME; + else { + php3_error(E_WARNING,"Invalid locale category name %s, must be one of LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC or LC_TIME", category->value.str.val); + RETURN_FALSE; + } + if (!strcmp ("0", locale->value.str.val)) + loc = NULL; + else + loc = locale->value.str.val; + retval = setlocale (cat, loc); + if (retval) { + RETVAL_STRING(retval,1); + return; + } +#endif + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto void parsestr(string encoded_string) + Parses GET/POST/COOKIE data and sets global variables. */ +void php3_parsestr(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + char *res = NULL; + + if (getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + if (arg->value.str.val && *arg->value.str.val) { + res = estrndup(arg->value.str.val,arg->value.str.len); + } + php3_treat_data(PARSE_STRING, res); +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/syslog.c b/ext/standard/syslog.c new file mode 100644 index 0000000000..4581ed58dc --- /dev/null +++ b/ext/standard/syslog.c @@ -0,0 +1,296 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Stig Sæther Bakken <ssb@guardian.no> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" +#include "php_ini.h" +#include "zend_globals.h" + +#include <stdlib.h> +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +#if MSVC5 +#include "win32/syslog.h" +#else +#include <syslog.h> +#endif + +#include <string.h> +#include <errno.h> + +#include <stdio.h> +#include "php3_syslog.h" + +static int syslog_started; +static char *syslog_device; +static void start_syslog(void); + +int php3_minit_syslog(INIT_FUNC_ARGS) +{ + TLS_VARS; + + /* error levels */ + REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ + REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ + REGISTER_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */ + REGISTER_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT); + /* facility: type of program logging the message */ + REGISTER_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */ + REGISTER_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */ + REGISTER_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */ + REGISTER_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT); +#ifdef LOG_NEWS + /* No LOG_NEWS on HP-UX */ + REGISTER_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */ +#endif +#ifdef LOG_UUCP + /* No LOG_UUCP on HP-UX */ + REGISTER_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT); +#endif +#ifdef LOG_CRON + /* apparently some systems don't have this one */ + REGISTER_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT); +#endif +#ifdef LOG_AUTHPRIV + /* AIX doesn't have LOG_AUTHPRIV */ + REGISTER_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT); +#endif +#ifndef MSVC5 + REGISTER_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT); +#endif + /* options */ + REGISTER_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT); +#ifdef LOG_PERROR + /* AIX doesn't have LOG_PERROR */ + REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ +#endif + + return SUCCESS; +} + + +int php3_rinit_syslog(INIT_FUNC_ARGS) +{ + if (INI_INT("define_syslog_variables")) { + start_syslog(); + } else { + syslog_started=0; + } + syslog_device=NULL; + return SUCCESS; +} + + +int php3_rshutdown_syslog(SHUTDOWN_FUNC_ARGS) +{ + if (syslog_device) { + efree(syslog_device); + } + return SUCCESS; +} + + +static void start_syslog(void) +{ + ELS_FETCH(); + + /* error levels */ + SET_VAR_LONG("LOG_EMERG", LOG_EMERG); /* system unusable */ + SET_VAR_LONG("LOG_ALERT", LOG_ALERT); /* immediate action required */ + SET_VAR_LONG("LOG_CRIT", LOG_CRIT); /* critical conditions */ + SET_VAR_LONG("LOG_ERR", LOG_ERR); + SET_VAR_LONG("LOG_WARNING", LOG_WARNING); + SET_VAR_LONG("LOG_NOTICE", LOG_NOTICE); + SET_VAR_LONG("LOG_INFO", LOG_INFO); + SET_VAR_LONG("LOG_DEBUG", LOG_DEBUG); + /* facility: type of program logging the message */ + SET_VAR_LONG("LOG_KERN", LOG_KERN); + SET_VAR_LONG("LOG_USER", LOG_USER); /* generic user level */ + SET_VAR_LONG("LOG_MAIL", LOG_MAIL); /* log to email */ + SET_VAR_LONG("LOG_DAEMON", LOG_DAEMON); /* other system daemons */ + SET_VAR_LONG("LOG_AUTH", LOG_AUTH); + SET_VAR_LONG("LOG_SYSLOG", LOG_SYSLOG); + SET_VAR_LONG("LOG_LPR", LOG_LPR); +#ifdef LOG_NEWS + /* No LOG_NEWS on HP-UX */ + SET_VAR_LONG("LOG_NEWS", LOG_NEWS); /* usenet new */ +#endif +#ifdef LOG_UUCP + /* No LOG_UUCP on HP-UX */ + SET_VAR_LONG("LOG_UUCP", LOG_UUCP); +#endif +#ifdef LOG_CRON + /* apparently some systems don't have this one */ + SET_VAR_LONG("LOG_CRON", LOG_CRON); +#endif +#ifdef LOG_AUTHPRIV + /* AIX doesn't have LOG_AUTHPRIV */ + SET_VAR_LONG("LOG_AUTHPRIV", LOG_AUTHPRIV); +#endif +#ifndef MSVC5 + SET_VAR_LONG("LOG_LOCAL0", LOG_LOCAL0); + SET_VAR_LONG("LOG_LOCAL1", LOG_LOCAL1); + SET_VAR_LONG("LOG_LOCAL2", LOG_LOCAL2); + SET_VAR_LONG("LOG_LOCAL3", LOG_LOCAL3); + SET_VAR_LONG("LOG_LOCAL4", LOG_LOCAL4); + SET_VAR_LONG("LOG_LOCAL5", LOG_LOCAL5); + SET_VAR_LONG("LOG_LOCAL6", LOG_LOCAL6); + SET_VAR_LONG("LOG_LOCAL7", LOG_LOCAL7); +#endif + /* options */ + SET_VAR_LONG("LOG_PID", LOG_PID); + SET_VAR_LONG("LOG_CONS", LOG_CONS); + SET_VAR_LONG("LOG_ODELAY", LOG_ODELAY); + SET_VAR_LONG("LOG_NDELAY", LOG_NDELAY); + SET_VAR_LONG("LOG_NOWAIT", LOG_NOWAIT); +#ifdef LOG_PERROR + /* AIX doesn't have LOG_PERROR */ + SET_VAR_LONG("LOG_PERROR", LOG_PERROR); /*log to stderr*/ +#endif + + syslog_started=1; +} + +/* {{{ proto void define_syslog_variables(void) + Initializes all syslog-related variables */ +void php3_define_syslog_variables(INTERNAL_FUNCTION_PARAMETERS) +{ + if (!syslog_started) { + start_syslog(); + } +} + +/* {{{ proto int openlog(string ident, int option, int facility) + Open connection to system logger */ +/* + ** OpenLog("nettopp", $LOG_PID, $LOG_LOCAL1); + ** Syslog($LOG_EMERG, "help me!") + ** CloseLog(); + */ +void php3_openlog(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *ident, *option, *facility; + if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &ident, &option, &facility) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(ident); + convert_to_long(option); + convert_to_long(facility); + if (syslog_device) { + efree(syslog_device); + } + syslog_device = estrndup(ident->value.str.val,ident->value.str.len); + openlog(syslog_device, option->value.lval, facility->value.lval); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto int closelog(void) + Close connection to system logger */ +void php3_closelog(INTERNAL_FUNCTION_PARAMETERS) +{ + closelog(); + if (syslog_device) { + efree(syslog_device); + syslog_device=NULL; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto int syslog(int priority, string message) + Generate a system log message */ +void php3_syslog(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *priority, *message; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &priority, &message) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long(priority); + convert_to_string(message); + + /* + * CAVEAT: if the message contains patterns such as "%s", + * this will cause problems. + */ + + syslog(priority->value.lval, message->value.str.val); + RETURN_TRUE; +} +/* }}} */ + + +function_entry syslog_functions[] = { + {"openlog", php3_openlog, NULL}, + {"syslog", php3_syslog, NULL}, + {"closelog", php3_closelog, NULL}, + {"define_syslog_variables", php3_define_syslog_variables, NULL}, + {NULL, NULL, NULL} +}; + + +php3_module_entry syslog_module_entry = { + "Syslog", syslog_functions, php3_minit_syslog, NULL, php3_rinit_syslog, php3_rshutdown_syslog, NULL, STANDARD_MODULE_PROPERTIES +}; + + +#if COMPILE_DL +DLEXPORT php3_module_entry *get_module(void) { return &syslog_module_entry; } +#endif + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/type.c b/ext/standard/type.c new file mode 100644 index 0000000000..f263ee8185 --- /dev/null +++ b/ext/standard/type.c @@ -0,0 +1,108 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf | + | | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ +#include "php.h" +#include "type.h" + +/* + * Determines if 'str' is an integer (long), real number or a string + * + * Note that leading zeroes automatically force a STRING type + */ +int php3_check_type(char *str) +{ + char *s; + int type = IS_LONG; + + s = str; + if (*s == '0' && *(s + 1) && *(s + 1) != '.') + return (IS_STRING); + if (*s == '+' || *s == '-' || (*s >= '0' && *s <= '9') || *s == '.') { + if (*s == '.') + type = IS_DOUBLE; + s++; + while (*s) { + if (*s >= '0' && *s <= '9') { + s++; + continue; + } else if (*s == '.' && type == IS_LONG) { + type = IS_DOUBLE; + s++; + continue; + } else + return (IS_STRING); + } + } else + return (IS_STRING); + + return (type); +} /* php3_check_type */ + +/* + * 0 - simple variable + * 1 - non-index array + * 2 - index array + */ +int php3_check_ident_type(char *str) +{ + char *s; + + if (!(s = (char *) strchr(str, '['))) + return (GPC_REGULAR); + s++; + while (*s == ' ' || *s == '\t' || *s == '\n') { + s++; + } + if (*s == ']') { + return (GPC_NON_INDEXED_ARRAY); + } + return (GPC_INDEXED_ARRAY); +} + +char *php3_get_ident_index(char *str) +{ + char *temp; + char *s, *t; + char o; + + temp = emalloc(strlen(str)); + temp[0] = '\0'; + s = (char *) strchr(str, '['); + if (s) { + t = (char *) strrchr(str, ']'); + if (t) { + o = *t; + *t = '\0'; + strcpy(temp, s + 1); + *t = o; + } + } + return (temp); +} diff --git a/ext/standard/type.h b/ext/standard/type.h new file mode 100644 index 0000000000..62f98bea7a --- /dev/null +++ b/ext/standard/type.h @@ -0,0 +1,41 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + +----------------------------------------------------------------------+ + */ +#ifndef _TYPE_H +#define _TYPE_H + +extern int php3_check_type(char *str); +extern int php3_check_ident_type(char *str); +extern char *php3_get_ident_index(char *str); + +#define GPC_REGULAR 0x1 +#define GPC_INDEXED_ARRAY 0x2 +#define GPC_NON_INDEXED_ARRAY 0x4 +#define GPC_ARRAY (GPC_INDEXED_ARRAY | GPC_NON_INDEXED_ARRAY) + +#endif diff --git a/ext/standard/uniqid.c b/ext/standard/uniqid.c new file mode 100644 index 0000000000..89988b3eca --- /dev/null +++ b/ext/standard/uniqid.c @@ -0,0 +1,103 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Author: Stig Sæther Bakken <ssb@guardian.no> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" + +#include <stdlib.h> +#if HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <string.h> +#include <errno.h> + +#include <stdio.h> +#if MSVC5 +#include "win32/time.h" +#else +#include <sys/time.h> +#endif + +#include "uniqid.h" + +/* {{{ proto string uniqid(string prefix) + Generate a unique id */ +void php3_uniqid(INTERNAL_FUNCTION_PARAMETERS) +{ +#ifdef HAVE_GETTIMEOFDAY + pval *prefix; + + char uniqid[128]; + int sec, usec; + struct timeval tv; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht,1,&prefix)==FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(prefix); + + /* Do some bounds checking since we are using a char array. */ + if (strlen(prefix->value.str.val) > 114) { + php3_error(E_WARNING, "The prefix to uniqid should not be more than 114 characters."); + return; + } + /* dont need this on windows so lets not do it*/ +#if HAVE_USLEEP && !(WIN32|WINNT) + usleep(1); +#endif + gettimeofday((struct timeval *) &tv, (struct timezone *) NULL); + sec = (int) tv.tv_sec; + usec = (int) (tv.tv_usec % 1000000); + + /* The max value usec can have is 0xF423F, so we use only five hex + * digits for usecs: + */ + sprintf(uniqid, "%s%08x%05x", prefix->value.str.val, sec, usec); + + RETURN_STRING(uniqid,1); +#endif +} +/* }}} */ + +function_entry uniqid_functions[] = { + {"uniqid", php3_uniqid, NULL}, + {NULL, NULL, NULL} +}; + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/uniqid.h b/ext/standard/uniqid.h new file mode 100644 index 0000000000..b241c35514 --- /dev/null +++ b/ext/standard/uniqid.h @@ -0,0 +1,37 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Author: Stig Sæther Bakken <ssb@guardian.no> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifndef _UNIQID_H +#define _UNIQID_H + +extern void php3_uniqid(INTERNAL_FUNCTION_PARAMETERS); + +#endif /* _UNIQID_H */ diff --git a/ext/standard/url.c b/ext/standard/url.c new file mode 100644 index 0000000000..df6e6171f6 --- /dev/null +++ b/ext/standard/url.c @@ -0,0 +1,439 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Author: Jim Winstead (jimw@php.net) | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ + +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <sys/types.h> + +/* php.h includes the correct regex.h */ +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include "php.h" + +#include "url.h" +#ifdef _OSD_POSIX +#ifndef APACHE +#error On this EBCDIC platform, PHP3 is only supported as an Apache module. +#else /*APACHE*/ +#ifndef CHARSET_EBCDIC +#define CHARSET_EBCDIC /* this machine uses EBCDIC, not ASCII! */ +#endif +#include "ebcdic.h" +#endif /*APACHE*/ +#endif /*_OSD_POSIX*/ + + +void free_url(url * theurl) +{ + if (theurl->scheme) + efree(theurl->scheme); + if (theurl->user) + efree(theurl->user); + if (theurl->pass) + efree(theurl->pass); + if (theurl->host) + efree(theurl->host); + if (theurl->path) + efree(theurl->path); + if (theurl->query) + efree(theurl->query); + if (theurl->fragment) + efree(theurl->fragment); + efree(theurl); +} + +url *url_parse(char *string) +{ + regex_t re; + regmatch_t subs[10]; + int err; + int length = strlen(string); + char *result; + + url *ret = (url *) emalloc(sizeof(url)); + if (!ret) { + /*php3_error(E_WARNING,"Unable to allocate memory\n");*/ + return NULL; + } + memset(ret, 0, sizeof(url)); + + /* from Appendix B of draft-fielding-url-syntax-09, + http://www.ics.uci.edu/~fielding/url/url.txt */ + err = regcomp(&re, "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?", REG_EXTENDED); + if (err) { + /*php3_error(E_WARNING,"Unable to compile regex: %d\n", err);*/ + efree(ret); + return NULL; + } + err = regexec(&re, string, 10, subs, 0); + if (err) { + /*php3_error(E_WARNING,"Error with regex\n");*/ + efree(ret); + return NULL; + } + /* no processing necessary on the scheme */ + if (subs[2].rm_so != -1 && subs[2].rm_so < length) { + ret->scheme = estrndup(string + subs[2].rm_so, subs[2].rm_eo - subs[2].rm_so); + } + + /* the path to the resource */ + if (subs[5].rm_so != -1 && subs[5].rm_so < length) { + ret->path = estrndup(string + subs[5].rm_so, subs[5].rm_eo - subs[5].rm_so); + } + + /* the query part */ + if (subs[7].rm_so != -1 && subs[7].rm_so < length) { + ret->query = estrndup(string + subs[7].rm_so, subs[7].rm_eo - subs[7].rm_so); + } + + /* the fragment */ + if (subs[9].rm_so != -1 && subs[9].rm_so < length) { + ret->fragment = estrndup(string + subs[9].rm_so, subs[9].rm_eo - subs[9].rm_so); + } + + /* extract the username, pass, and port from the hostname */ + if (subs[4].rm_so != -1 && subs[4].rm_so < length) { + /* extract username:pass@host:port from regex results */ + result = estrndup(string + subs[4].rm_so, subs[4].rm_eo - subs[4].rm_so); + length = strlen(result); + + regfree(&re); /* free the old regex */ + + if ((err=regcomp(&re, "^(([^@:]+)(:([^@:]+))?@)?([^:@]+)(:([^:@]+))?", REG_EXTENDED)) + || (err=regexec(&re, result, 10, subs, 0))) { + STR_FREE(ret->scheme); + STR_FREE(ret->path); + STR_FREE(ret->query); + STR_FREE(ret->fragment); + efree(ret); + efree(result); + /*php3_error(E_WARNING,"Unable to compile regex: %d\n", err);*/ + return NULL; + } + /* now deal with all of the results */ + if (subs[2].rm_so != -1 && subs[2].rm_so < length) { + ret->user = estrndup(result + subs[2].rm_so, subs[2].rm_eo - subs[2].rm_so); + } + if (subs[4].rm_so != -1 && subs[4].rm_so < length) { + ret->pass = estrndup(result + subs[4].rm_so, subs[4].rm_eo - subs[4].rm_so); + } + if (subs[5].rm_so != -1 && subs[5].rm_so < length) { + ret->host = estrndup(result + subs[5].rm_so, subs[5].rm_eo - subs[5].rm_so); + } + if (subs[7].rm_so != -1 && subs[7].rm_so < length) { + ret->port = (unsigned short) strtol(result + subs[7].rm_so, NULL, 10); + } + efree(result); + } + regfree(&re); + return ret; +} + +/* {{{ proto array parse_url(string url) + Parse a URL and return its components */ +void php3_parse_url(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *string; + url *resource; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &string) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(string); + + resource = url_parse(string->value.str.val); + + if (resource == NULL) { + php3_error(E_WARNING, "unable to parse url (%s)", string->value.str.val); + RETURN_FALSE; + } + /* allocate an array for return */ + if (array_init(return_value) == FAILURE) { + free_url(resource); + RETURN_FALSE; + } + /* add the various elements to the array */ + if (resource->scheme != NULL) + add_assoc_string(return_value, "scheme", resource->scheme, 1); + if (resource->host != NULL) + add_assoc_string(return_value, "host", resource->host, 1); + if (resource->port != 0) + add_assoc_long(return_value, "port", resource->port); + if (resource->user != NULL) + add_assoc_string(return_value, "user", resource->user, 1); + if (resource->pass != NULL) + add_assoc_string(return_value, "pass", resource->pass, 1); + if (resource->path != NULL) + add_assoc_string(return_value, "path", resource->path, 1); + if (resource->query != NULL) + add_assoc_string(return_value, "query", resource->query, 1); + if (resource->fragment != NULL) + add_assoc_string(return_value, "fragment", resource->fragment, 1); + free_url(resource); +} +/* }}} */ + +static int php3_htoi(char *s) +{ + int value; + int c; + + c = s[0]; + if (isupper(c)) + c = tolower(c); + value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16; + + c = s[1]; + if (isupper(c)) + c = tolower(c); + value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10; + + return (value); +} + +/* rfc1738: + + ...The characters ";", + "/", "?", ":", "@", "=" and "&" are the characters which may be + reserved for special meaning within a scheme... + + ...Thus, only alphanumerics, the special characters "$-_.+!*'(),", and + reserved characters used for their reserved purposes may be used + unencoded within a URL... + + For added safety, we only leave -_. unencoded. + */ + +static unsigned char hexchars[] = "0123456789ABCDEF"; + +char *_php3_urlencode(char *s, int len) +{ + register int x, y; + unsigned char *str; + + str = (unsigned char *) emalloc(3 * strlen(s) + 1); + for (x = 0, y = 0; len--; x++, y++) { + str[y] = (unsigned char) s[x]; + if (str[y] == ' ') { + str[y] = '+'; +#ifndef CHARSET_EBCDIC + } else if ((str[y] < '0' && str[y] != '-' && str[y] != '.') || + (str[y] < 'A' && str[y] > '9') || + (str[y] > 'Z' && str[y] < 'a' && str[y] != '_') || + (str[y] > 'z')) { + str[y++] = '%'; + str[y++] = hexchars[(unsigned char) s[x] >> 4]; + str[y] = hexchars[(unsigned char) s[x] & 15]; + } +#else /*CHARSET_EBCDIC*/ + } else if (!isalnum(str[y]) && strchr("_-.", str[y]) != NULL) { + str[y++] = '%'; + str[y++] = hexchars[os_toascii[(unsigned char) s[x]] >> 4]; + str[y] = hexchars[os_toascii[(unsigned char) s[x]] & 0x0F]; + } +#endif /*CHARSET_EBCDIC*/ + } + str[y] = '\0'; + return ((char *) str); +} + +/* {{{ proto string urlencode(string str) + URL-encodes string */ +void php3_urlencode(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + char *str; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + if (!arg->value.str.len) { + RETURN_FALSE; + } + str = _php3_urlencode(arg->value.str.val, arg->value.str.len); + RETVAL_STRING(str, 1); + efree(str); +} +/* }}} */ + +/* {{{ proto string urldecode(string str) + Decodes URL-encoded string */ +void php3_urldecode(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + int len; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + if (!arg->value.str.len) { + RETURN_FALSE; + } + len = _php3_urldecode(arg->value.str.val, arg->value.str.len); + + RETVAL_STRINGL(arg->value.str.val, len, 1); +} +/* }}} */ + +int _php3_urldecode(char *str, int len) +{ + char *dest = str; + char *data = str; + + while (len--) { + if (*data == '+') + *dest = ' '; + else if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) && isxdigit((int) *(data + 2))) { +#ifndef CHARSET_EBCDIC + *dest = (char) php3_htoi(data + 1); +#else + *dest = os_toebcdic[(char) php3_htoi(data + 1)]; +#endif + data += 2; + len -= 2; + } else + *dest = *data; + data++; + dest++; + } + *dest = '\0'; + return dest - str; +} + +char *_php3_rawurlencode(char *s, int len) +{ + register int x, y; + unsigned char *str; + + str = (unsigned char *) emalloc(3 * len + 1); + for (x = 0, y = 0; len--; x++, y++) { + str[y] = (unsigned char) s[x]; +#ifndef CHARSET_EBCDIC + if ((str[y] < '0' && str[y] != '-' && str[y] != '.') || + (str[y] < 'A' && str[y] > '9') || + (str[y] > 'Z' && str[y] < 'a' && str[y] != '_') || + (str[y] > 'z')) { + str[y++] = '%'; + str[y++] = hexchars[(unsigned char) s[x] >> 4]; + str[y] = hexchars[(unsigned char) s[x] & 15]; +#else /*CHARSET_EBCDIC*/ + if (!isalnum(str[y]) && strchr("_-.", str[y]) != NULL) { + str[y++] = '%'; + str[y++] = hexchars[os_toascii[(unsigned char) s[x]] >> 4]; + str[y] = hexchars[os_toascii[(unsigned char) s[x]] & 15]; +#endif /*CHARSET_EBCDIC*/ + } + } + str[y] = '\0'; + return ((char *) str); +} + +/* {{{ proto string rawurlencode(string str) + URL-encodes string */ +void php3_rawurlencode(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + char *str; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + if (!arg->value.str.len) { + RETURN_FALSE; + } + str = _php3_rawurlencode(arg->value.str.val, arg->value.str.len); + RETVAL_STRING(str, 1); + efree(str); +} +/* }}} */ + +/* {{{ proto string rawurldecode(string str) + Decodes URL-encodes string */ +void php3_rawurldecode(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *arg; + int len; + TLS_VARS; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string(arg); + + if (!arg->value.str.len) { + RETURN_FALSE; + } + len = _php3_rawurldecode(arg->value.str.val, arg->value.str.len); + + RETVAL_STRINGL(arg->value.str.val, len, 1); +} +/* }}} */ + +int _php3_rawurldecode(char *str, int len) +{ + char *dest = str; + char *data = str; + + while (len--) { + if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) && isxdigit((int) *(data + 2))) { +#ifndef CHARSET_EBCDIC + *dest = (char) php3_htoi(data + 1); +#else + *dest = os_toebcdic[(char) php3_htoi(data + 1)]; +#endif + data += 2; + len -= 2; + } else + *dest = *data; + data++; + dest++; + } + *dest = '\0'; + return dest - str; +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/url.h b/ext/standard/url.h new file mode 100644 index 0000000000..22d6e4a984 --- /dev/null +++ b/ext/standard/url.h @@ -0,0 +1,60 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Jim Winstead (jimw@php.net) | + +----------------------------------------------------------------------+ + */ +/* $Id$ */ + +typedef struct url { + char *scheme; + char *user; + char *pass; + char *host; + unsigned short port; + char *path; + char *query; + char *fragment; +} url; + +extern void free_url(url *); +extern url *url_parse(char *); +extern int _php3_urldecode(char *, int); /* return value: length of decoded string */ +extern char *_php3_urlencode(char *, int); +extern int _php3_rawurldecode(char *, int); /* return value: length of decoded string */ +extern char *_php3_rawurlencode(char *, int); + +extern void php3_parse_url(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_urlencode(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_urldecode(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_rawurlencode(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_rawurldecode(INTERNAL_FUNCTION_PARAMETERS); + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/standard/var.c b/ext/standard/var.c new file mode 100644 index 0000000000..feb277c4c3 --- /dev/null +++ b/ext/standard/var.c @@ -0,0 +1,391 @@ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: Jani Lehtimäki <jkl@njet.net> | + +----------------------------------------------------------------------+ + */ + +#ifdef THREAD_SAFE +#include "tls.h" +#endif +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include "php.h" +#include "fopen-wrappers.h" +#include "reg.h" +#include "post.h" +#include "php3_string.h" +#if HAVE_SETLOCALE +#include <locale.h> +#endif + +#include "php3_var.h" + +void php3api_var_dump(pval *struc, int level) +{ + ulong index; + char *key; + int i, c = 0; + pval *data; + char buf[512]; + + switch (struc->type) { + case IS_LONG: + i = sprintf(buf, "%*cint(%ld)\n", level, ' ', struc->value.lval); + PHPWRITE(&buf[1], i - 1); + break; + + case IS_DOUBLE: + i = sprintf(buf, "%*cfloat(%g)\n", level, ' ', struc->value.dval); + PHPWRITE(&buf[1], i - 1); + break; + + case IS_STRING: + i = sprintf(buf, "%*cstring(%d) \"", level, ' ', struc->value.str.len); + PHPWRITE(&buf[1], i - 1); + PHPWRITE(struc->value.str.val, struc->value.str.len); + strcpy(buf, "\"\n"); + PHPWRITE(buf, strlen(buf)); + break; + + case IS_ARRAY: + i = sprintf(buf, "%*carray(%d) {\n", level, ' ', _php3_hash_num_elements(struc->value.ht)); + PHPWRITE(&buf[1], i - 1); + goto head_done; + + case IS_OBJECT: + i = sprintf(buf, "%*cobject(%d) {\n", level, ' ', _php3_hash_num_elements(struc->value.ht)); + PHPWRITE(&buf[1], i - 1); + head_done: + + _php3_hash_internal_pointer_reset(struc->value.ht); + for (;; _php3_hash_move_forward(struc->value.ht)) { + if ((i = _php3_hash_get_current_key(struc->value.ht, &key, &index)) == HASH_KEY_NON_EXISTANT) + break; + if (c > 0) { + strcpy(buf, "\n"); + PHPWRITE(buf, strlen(buf)); + } + c++; + if (_php3_hash_get_current_data(struc->value.ht, (void **) (&data)) != SUCCESS || !data || (data == struc)) + continue; + switch (i) { + case HASH_KEY_IS_LONG:{ + pval d; + + d.type = IS_LONG; + d.value.lval = index; + php3api_var_dump(&d, level + 2); + } + break; + + case HASH_KEY_IS_STRING:{ + pval d; + + d.type = IS_STRING; + d.value.str.val = key; + d.value.str.len = strlen(key); + php3api_var_dump(&d, level + 2); + efree(key); + } + break; + } + php3api_var_dump(data, level + 2); + } + i = sprintf(buf, "%*c}\n", level, ' '); + PHPWRITE(&buf[1], i - 1); + break; + + default: + i = sprintf(buf, "%*ci:0\n", level, ' '); + PHPWRITE(&buf[1], i - 1); + } +} + + +PHP_FUNCTION(var_dump) +{ + pval *struc; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &struc) == FAILURE) { + WRONG_PARAM_COUNT; + } + php3api_var_dump(struc, 1); +} + + + +#define STR_CAT(P,S,I) {\ + pval *__p = (P);\ + ulong __i = __p->value.str.len;\ + __p->value.str.len += (I);\ + if (__p->value.str.val) {\ + __p->value.str.val = (char *)erealloc(__p->value.str.val, __p->value.str.len + 1);\ + } else {\ + __p->value.str.val = emalloc(__p->value.str.len + 1);\ + *__p->value.str.val = 0;\ + }\ + strcat(__p->value.str.val + __i, (S));\ +} + + +void php3api_var_serialize(pval *buf, pval *struc) +{ + char s[256]; + ulong slen; + int i, ch; + + switch (struc->type) { + case IS_LONG: + slen = sprintf(s, "i:%ld;", struc->value.lval); + STR_CAT(buf, s, slen); + return; + + case IS_DOUBLE: + slen = sprintf(s, "d:%g;", struc->value.dval); + STR_CAT(buf, s, slen); + return; + + case IS_STRING:{ + char *p; + + i = buf->value.str.len; + slen = sprintf(s, "s:%d:\"", struc->value.str.len); + STR_CAT(buf, s, slen + struc->value.str.len + 2); + p = buf->value.str.val + i + slen; + if (struc->value.str.len > 0) { + memcpy(p, struc->value.str.val, struc->value.str.len); + p += struc->value.str.len; + } + *p++ = '\"'; + *p++ = ';'; + *p = 0; + } + return; + + case IS_ARRAY: + ch = 'a'; + goto got_array; + + case IS_OBJECT: + ch = 'o'; + + got_array: + i = _php3_hash_num_elements(struc->value.ht); + slen = sprintf(s, "%c:%d:{", ch, i); + STR_CAT(buf, s, slen); + if (i > 0) { + char *key; + pval *data; + pval d; + ulong index; + + _php3_hash_internal_pointer_reset(struc->value.ht); + for (;; _php3_hash_move_forward(struc->value.ht)) { + if ((i = _php3_hash_get_current_key(struc->value.ht, &key, &index)) == HASH_KEY_NON_EXISTANT) { + break; + } + if (_php3_hash_get_current_data(struc->value.ht, (void **) (&data)) != SUCCESS || !data || (data == struc)) { + continue; + } + switch (i) { + case HASH_KEY_IS_LONG: + d.type = IS_LONG; + d.value.lval = index; + php3api_var_serialize(buf, &d); + break; + case HASH_KEY_IS_STRING: + d.type = IS_STRING; + d.value.str.val = key; + d.value.str.len = strlen(key); + php3api_var_serialize(buf, &d); + efree(key); + break; + } + php3api_var_serialize(buf, data); + } + } + STR_CAT(buf, "}", 1); + return; + + default: + STR_CAT(buf, "i:0;", 4); + return; + } +} + + +int php3api_var_unserialize(pval *rval, char **p, char *max) +{ + char *q; + char *str; + int i; + + switch (**p) { + case 'i': + if (*((*p) + 1) != ':') { + return 0; + } + q = *p; + while (**p && **p != ';') { + (*p)++; + } + if (**p != ';') { + return 0; + } + (*p)++; + rval->type = IS_LONG; + rval->value.lval = atol(q + 2); + return 1; + + case 'd': + if (*((*p) + 1) != ':') { + return 0; + } + q = *p; + while (**p && **p != ';') { + (*p)++; + } + if (**p != ';') { + return 0; + } + (*p)++; + rval->type = IS_DOUBLE; + rval->value.dval = atof(q + 2); + return 1; + + case 's': + if (*((*p) + 1) != ':') { + return 0; + } + (*p) += 2; + q = *p; + while (**p && **p != ':') { + (*p)++; + } + if (**p != ':') { + return 0; + } + i = atoi(q); + if (i < 0 || (*p + 3 + i) > max || *((*p) + 1) != '\"' || + *((*p) + 2 + i) != '\"' || *((*p) + 3 + i) != ';') { + return 0; + } + (*p) += 2; + str = emalloc(i + 1); + if (i > 0) { + memcpy(str, *p, i); + } + str[i] = 0; + (*p) += i + 2; + rval->type = IS_STRING; + rval->value.str.val = str; + rval->value.str.len = i; + return 1; + + case 'a': + rval->type = IS_ARRAY; + goto got_array; + + case 'o': + rval->type = IS_OBJECT; + + got_array: + (*p) += 2; + i = atoi(*p); + rval->value.ht = (HashTable *) emalloc(sizeof(HashTable)); + _php3_hash_init(rval->value.ht, i + 1, NULL, PVAL_DESTRUCTOR, 0); + while (**p && **p != ':') { + (*p)++; + } + if (**p != ':' || *((*p) + 1) != '{') { + return 0; + } + for ((*p) += 2; **p && **p != '}' && i > 0; i--) { + pval key; + pval data; + + if (!php3api_var_unserialize(&key, p, max)) { + return 0; + } + if (!php3api_var_unserialize(&data, p, max)) { + return 0; + } + switch (key.type) { + case IS_LONG: + _php3_hash_index_update(rval->value.ht, key.value.lval, &data, sizeof(data), NULL); + break; + case IS_STRING: + _php3_hash_add(rval->value.ht, key.value.str.val, key.value.str.len + 1, &data, sizeof(data), NULL); + break; + } + pval_destructor(&key); + } + return *((*p)++) == '}'; + + default: + return 0; + } +} + + +PHP_FUNCTION(serialize) +{ + pval *struc; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &struc) == FAILURE) { + WRONG_PARAM_COUNT; + } + return_value->type = IS_STRING; + return_value->value.str.val = NULL; + return_value->value.str.len = 0; + php3api_var_serialize(return_value, struc); +} + + +PHP_FUNCTION(unserialize) +{ + pval *buf; + + if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &buf) == FAILURE) { + WRONG_PARAM_COUNT; + } + if (buf->type == IS_STRING) { + char *p = buf->value.str.val; + if (!php3api_var_unserialize(return_value, &p, p + buf->value.str.len)) { + RETURN_FALSE; + } + } else { + RETURN_FALSE; + } +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ |