OverTheWire.org
Hacker Community
Contribute to OverTheWire ?
Click here!
News (2012-01-07):
Best wishes for 2012 ! We released the HES2010 wargame ! Read more...
Discuss this level on the forum

Level 4

level4 is an installation of Apache and PHP with an introduced heap vulnerability.

The introduced vulnerability is as follows:

Code listing (level4.function.c)
 1 PHP_FUNCTION(dovuln)
 2 {
 3         zval **p_str, **p_len;
 4         char *str, *smashme;
 5         int argc = ZEND_NUM_ARGS(), len = 42, strlen;
 6         
 7         if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &p_str, &p_len) == FAILURE) {
 8              WRONG_PARAM_COUNT;
 9         }
10 
11         convert_to_string_ex(p_str);
12         convert_to_long_ex(p_len);
13         len = Z_LVAL_PP(p_len);
14         str = Z_STRVAL_PP(p_str);
15         strlen = Z_STRLEN_PP(p_str);
16         smashme = emalloc(len);
17         memcpy(smashme, str, strlen); //xxx
18 }

Thanks to orix for the introduced code snippet

The document root is in /levels/level4/htdocs, you'll need to put your php code there and call it via the webserver on port 55555.

Note: that if you're executing a shell, it can't be /bin/sh or /bin/bash, oh, and the apache process can't access the /etc/pass directory :P

Binary information
Stack smashing protection (SSP):Enabled
Postition Independent Executable (PIE):Enabled
Address space layout randomisation (ASLR):Enabled
Non-executable pages:None / disabled

Location:127.0.0.1:55555
Code listing (level4.basic_functions.c)
   1 
   2 PHP_FUNCTION(dovuln)
   3 {
   4 	zval **p_str, **p_len;
   5 	char *str, *smashme;
   6 	int argc = ZEND_NUM_ARGS(), len = 42, strlen;
   7 	
   8 	if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &p_str, &p_len) == FAILURE) {     		WRONG_PARAM_COUNT;
   9 	}
  10 	
  11 	convert_to_string_ex(p_str);
  12         convert_to_long_ex(p_len);
  13         len = Z_LVAL_PP(p_len);
  14         str = Z_STRVAL_PP(p_str);
  15         strlen = Z_STRLEN_PP(p_str);
  16         smashme = emalloc(len);
  17         memcpy(smashme, str, strlen); //xxx
  18 }    
  19 
  20 #undef sprintf
  21 
  22 zend_function_entry basic_functions[] = {
  23 	PHP_FE(constant,														NULL)
  24 	PHP_FE(bin2hex,															NULL)
  25 	PHP_FE(sleep,															NULL)
  26 	PHP_FE(usleep,															NULL)
  27 #if HAVE_NANOSLEEP
  28 	PHP_FE(time_nanosleep,														NULL)
  29 	PHP_FE(time_sleep_until,														NULL)
  30 #endif
  31 
  32 #if HAVE_STRPTIME
  33 	PHP_FE(strptime,														NULL)
  34 #endif
  35 
  36 	PHP_FE(flush,															NULL)
  37 	PHP_FE(wordwrap,														NULL)
  38 	PHP_FE(htmlspecialchars,												NULL)
  39 	PHP_FE(htmlentities,													NULL)
  40 	PHP_FE(html_entity_decode,												NULL)
  41 	PHP_FE(htmlspecialchars_decode,												NULL)
  42 	PHP_FE(get_html_translation_table,										NULL)
  43 	PHP_FE(sha1,															NULL)
  44 	PHP_FE(sha1_file,														NULL)
  45 	PHP_NAMED_FE(md5,php_if_md5,											NULL)
  46 	PHP_NAMED_FE(md5_file,php_if_md5_file,									NULL)
  47 	PHP_NAMED_FE(crc32,php_if_crc32,										NULL)
  48 
  49 	PHP_FE(iptcparse,														NULL)															
  50 	PHP_FE(iptcembed,														NULL)
  51 	PHP_FE(getimagesize,			second_arg_force_ref)
  52 	PHP_FE(image_type_to_mime_type,											NULL)
  53 
  54 	PHP_FE(phpinfo,															NULL)
  55 	PHP_FE(phpversion,														NULL)
  56 	PHP_FE(phpcredits,														NULL)
  57 	PHP_FE(php_logo_guid,													NULL)
  58 	PHP_FE(php_real_logo_guid,												NULL)
  59 	PHP_FE(php_egg_logo_guid,												NULL)
  60 	PHP_FE(zend_logo_guid,													NULL)
  61 	PHP_FE(php_sapi_name,													NULL)
  62 	PHP_FE(php_uname,														NULL)
  63 	PHP_FE(php_ini_scanned_files,											NULL)
  64 
  65 	PHP_FE(strnatcmp,														NULL)
  66 	PHP_FE(strnatcasecmp,													NULL)
  67 	PHP_FE(substr_count,													NULL)
  68 	PHP_FE(strspn,															NULL)
  69 	PHP_FE(strcspn,															NULL)
  70 	PHP_FE(strtok,															NULL)
  71 	PHP_FE(strtoupper,														NULL)
  72 	PHP_FE(strtolower,														NULL)
  73 	PHP_FE(strpos,															NULL)
  74 	PHP_FE(stripos,															NULL)
  75 	PHP_FE(strrpos,															NULL)
  76 	PHP_FE(strripos,														NULL)
  77 	PHP_FE(strrev,															NULL)
  78 	PHP_FE(hebrev,															NULL)
  79 	PHP_FE(hebrevc,															NULL)
  80 	PHP_FE(nl2br,															NULL)
  81 	PHP_FE(basename,														NULL)
  82 	PHP_FE(dirname,															NULL)
  83 	PHP_FE(pathinfo,														NULL)
  84 	PHP_FE(stripslashes,													NULL)
  85 	PHP_FE(stripcslashes,													NULL)
  86 	PHP_FE(strstr,															NULL)
  87 	PHP_FE(stristr,															NULL)
  88 	PHP_FE(strrchr,															NULL)
  89 	PHP_FE(str_shuffle,															NULL)
  90 	PHP_FE(str_word_count,														NULL)
  91 	PHP_FE(str_split,														NULL)
  92 	PHP_FE(strpbrk,															NULL)
  93 	PHP_FE(substr_compare,														NULL)
  94 
  95 #ifdef HAVE_STRCOLL
  96 	PHP_FE(strcoll,															NULL)
  97 #endif
  98 
  99 #ifdef HAVE_STRFMON
 100 	PHP_FE(money_format,                                                    NULL)
 101 #endif
 102 
 103 	PHP_FE(substr,															NULL)
 104 	PHP_FE(substr_replace,													NULL)
 105 	PHP_FE(quotemeta,														NULL)
 106 	PHP_FE(ucfirst,															NULL)
 107 	PHP_FE(ucwords,															NULL)
 108 	PHP_FE(strtr,															NULL)
 109 	PHP_FE(addslashes,														NULL)
 110 	PHP_FE(addcslashes,														NULL)
 111 	PHP_FE(rtrim,															NULL)
 112 	PHP_FE(str_replace,				fourth_arg_force_ref)
 113 	PHP_FE(str_ireplace,			fourth_arg_force_ref)
 114 	PHP_FE(str_repeat,														NULL)
 115 	PHP_FE(count_chars,														NULL)
 116 	PHP_FE(chunk_split,														NULL)
 117 	PHP_FE(trim,															NULL)
 118 	PHP_FE(ltrim,															NULL)
 119 	PHP_FE(strip_tags,														NULL)
 120 	PHP_FE(similar_text,			third_arg_force_ref)
 121 	PHP_FE(explode,															NULL)
 122 	PHP_FE(implode,															NULL)
 123 	PHP_FE(setlocale,														NULL)
 124 	PHP_FE(localeconv,														NULL)
 125 
 126 #if HAVE_NL_LANGINFO
 127 	PHP_FE(nl_langinfo,														NULL)
 128 #endif
 129 
 130 	PHP_FE(soundex,															NULL)
 131 	PHP_FE(levenshtein,														NULL)
 132 	PHP_FE(chr,																NULL)
 133 	PHP_FE(ord,																NULL)
 134 	PHP_FE(parse_str,				second_arg_force_ref)
 135 	PHP_FE(str_pad,															NULL)
 136 	PHP_FALIAS(chop,				rtrim,									NULL)
 137 	PHP_FALIAS(strchr,				strstr,									NULL)
 138 	PHP_NAMED_FE(sprintf,			PHP_FN(user_sprintf),					NULL)
 139 	PHP_NAMED_FE(printf,			PHP_FN(user_printf),					NULL)
 140 	PHP_FE(vprintf,															NULL)
 141 	PHP_FE(vsprintf,														NULL)
 142 	PHP_FE(fprintf,															NULL)
 143 	PHP_FE(vfprintf,														NULL)
 144 	PHP_FE(sscanf,					third_and_rest_force_ref)
 145 	PHP_FE(fscanf,					third_and_rest_force_ref)
 146 	PHP_FE(parse_url,														NULL)
 147 	PHP_FE(urlencode,														NULL)
 148 	PHP_FE(urldecode,														NULL)
 149 	PHP_FE(rawurlencode,													NULL)
 150 	PHP_FE(rawurldecode,													NULL)
 151 	PHP_FE(http_build_query,												NULL)
 152 
 153 #ifdef HAVE_SYMLINK
 154 	PHP_FE(readlink,														NULL)
 155 	PHP_FE(linkinfo,														NULL)
 156 	PHP_FE(symlink,															NULL)
 157 	PHP_FE(link,															NULL)
 158 #endif
 159 
 160 	PHP_FE(unlink,															NULL)
 161 	PHP_FE(exec,					second_and_third_args_force_ref)
 162 	PHP_FE(system,					second_arg_force_ref)
 163 	PHP_FE(escapeshellcmd,													NULL)
 164 	PHP_FE(escapeshellarg,													NULL)
 165 	PHP_FE(passthru,				second_arg_force_ref)
 166 	PHP_FE(shell_exec,														NULL)
 167 #ifdef PHP_CAN_SUPPORT_PROC_OPEN
 168 	PHP_FE(proc_open,				third_arg_force_ref)
 169 	PHP_FE(proc_close,														NULL)
 170 	PHP_FE(proc_terminate,													NULL)
 171 	PHP_FE(proc_get_status,													NULL)
 172 #endif
 173 
 174 #ifdef HAVE_NICE
 175 	PHP_FE(proc_nice,														NULL)	
 176 #endif
 177 
 178 	PHP_FE(rand,															NULL)
 179 	PHP_FE(srand,															NULL)
 180 	PHP_FE(getrandmax,														NULL)
 181 	PHP_FE(mt_rand,															NULL)
 182 	PHP_FE(mt_srand,														NULL)
 183 	PHP_FE(mt_getrandmax,													NULL)
 184 
 185 #if HAVE_GETSERVBYNAME
 186 	PHP_FE(getservbyname,													NULL)
 187 #endif
 188 
 189 #if HAVE_GETSERVBYPORT
 190 	PHP_FE(getservbyport,													NULL)
 191 #endif
 192 
 193 #if HAVE_GETPROTOBYNAME
 194 	PHP_FE(getprotobyname,													NULL)
 195 #endif
 196 
 197 #if HAVE_GETPROTOBYNUMBER
 198 	PHP_FE(getprotobynumber,												NULL)
 199 #endif
 200 
 201 	PHP_FE(getmyuid,														NULL)
 202 	PHP_FE(getmygid,														NULL)
 203 	PHP_FE(getmypid,														NULL)
 204 	PHP_FE(getmyinode,														NULL)
 205 	PHP_FE(getlastmod,														NULL)
 206 
 207 	PHP_FE(base64_decode,													NULL)
 208 	PHP_FE(base64_encode,													NULL)
 209 
 210 	PHP_FE(convert_uuencode,														NULL)
 211 	PHP_FE(convert_uudecode,														NULL)
 212 
 213 	PHP_FE(abs,																NULL)
 214 	PHP_FE(ceil,															NULL)
 215 	PHP_FE(floor,															NULL)
 216 	PHP_FE(round,															NULL)
 217 	PHP_FE(sin,																NULL)
 218 	PHP_FE(cos,																NULL)
 219 	PHP_FE(tan,																NULL)
 220 	PHP_FE(asin,															NULL)
 221 	PHP_FE(acos,															NULL)
 222 	PHP_FE(atan,															NULL)
 223 	PHP_FE(atan2,															NULL)
 224 	PHP_FE(sinh,															NULL)
 225 	PHP_FE(cosh,															NULL)
 226 	PHP_FE(tanh,															NULL)
 227 
 228 #ifdef HAVE_ASINH 
 229 	PHP_FE(asinh,															NULL)
 230 #endif
 231 #ifdef HAVE_ACOSH
 232 	PHP_FE(acosh,															NULL)
 233 #endif
 234 #ifdef HAVE_ATANH
 235 	PHP_FE(atanh,															NULL)
 236 #endif
 237 #if !defined(PHP_WIN32) && !defined(NETWARE)
 238 	PHP_FE(expm1,															NULL)
 239 	PHP_FE(log1p,															NULL)
 240 #endif
 241 
 242 	PHP_FE(pi,																NULL)
 243 	PHP_FE(is_finite,														NULL)
 244 	PHP_FE(is_nan,															NULL)
 245 	PHP_FE(is_infinite,														NULL)
 246 	PHP_FE(pow,																NULL)
 247 	PHP_FE(exp,																NULL)
 248 	PHP_FE(log,																NULL)
 249 	PHP_FE(log10,															NULL)
 250 	PHP_FE(sqrt,															NULL)
 251 	PHP_FE(hypot,															NULL)
 252 	PHP_FE(deg2rad,															NULL)
 253 	PHP_FE(rad2deg,															NULL)
 254 	PHP_FE(bindec,															NULL)
 255 	PHP_FE(hexdec,															NULL)
 256 	PHP_FE(octdec,															NULL)
 257 	PHP_FE(decbin,															NULL)
 258 	PHP_FE(decoct,															NULL)
 259 	PHP_FE(dechex,															NULL)
 260 	PHP_FE(base_convert,													NULL)
 261 	PHP_FE(number_format,													NULL)
 262 	PHP_FE(fmod,															NULL)
 263 #ifdef HAVE_INET_NTOP
 264 	PHP_NAMED_FE(inet_ntop,		php_inet_ntop,											NULL)
 265 #endif
 266 #ifdef HAVE_INET_PTON
 267 	PHP_NAMED_FE(inet_pton,		php_inet_pton,											NULL)
 268 #endif
 269 	PHP_FE(ip2long,															NULL)
 270 	PHP_FE(long2ip,															NULL)
 271 
 272 	PHP_FE(getenv,															NULL)
 273 #ifdef HAVE_PUTENV
 274 	PHP_FE(putenv,															NULL)
 275 #endif
 276 
 277 #ifdef HAVE_GETOPT
 278 	PHP_FE(getopt,															NULL)
 279 #endif
 280 
 281 #ifdef HAVE_GETTIMEOFDAY
 282 	PHP_FE(microtime,														NULL)
 283 	PHP_FE(gettimeofday,													NULL)
 284 #endif
 285 
 286 #ifdef HAVE_GETRUSAGE
 287 	PHP_FE(getrusage,														NULL)
 288 #endif
 289 
 290 #ifdef HAVE_GETTIMEOFDAY
 291 	PHP_FE(uniqid,															NULL)
 292 #endif
 293 
 294 	PHP_FE(quoted_printable_decode,											NULL)
 295 	PHP_FE(convert_cyr_string,												NULL)
 296 	PHP_FE(get_current_user,												NULL)
 297 	PHP_FE(set_time_limit,													NULL)
 298 	PHP_FE(get_cfg_var,														NULL)
 299 	PHP_FALIAS(magic_quotes_runtime, set_magic_quotes_runtime,				NULL)
 300 	PHP_FE(set_magic_quotes_runtime,										NULL)
 301 	PHP_FE(get_magic_quotes_gpc,											NULL)
 302 	PHP_FE(get_magic_quotes_runtime,										NULL)
 303 
 304 	PHP_FE(import_request_variables,										NULL)
 305 	PHP_FE(error_log,														NULL)
 306 	PHP_FE(call_user_func,													NULL)
 307 	PHP_FE(call_user_func_array,											NULL)
 308 	PHP_FE(call_user_method,		second_arg_force_ref)
 309 	PHP_FE(call_user_method_array,	second_arg_force_ref)
 310 	PHP_FE(serialize,														NULL)
 311 	PHP_FE(unserialize,														NULL)
 312 
 313 	PHP_FE(var_dump,														NULL)
 314 	PHP_FE(var_export,														NULL)
 315 	PHP_FE(debug_zval_dump,														NULL)
 316 	PHP_FE(print_r,															NULL)
 317 #if MEMORY_LIMIT 
 318 	PHP_FE(memory_get_usage,												NULL)
 319 #endif
 320 
 321 	PHP_FE(register_shutdown_function,										NULL)
 322 	PHP_FE(register_tick_function,											NULL)
 323 	PHP_FE(unregister_tick_function,										NULL)
 324 
 325 	PHP_FE(highlight_file,													NULL)
 326 	PHP_FALIAS(show_source, 		highlight_file,							NULL)
 327 	PHP_FE(highlight_string,												NULL)
 328 	PHP_FE(php_strip_whitespace,												NULL)
 329 
 330 	PHP_FE(ini_get,															NULL)
 331 	PHP_FE(ini_get_all,														NULL)
 332 	PHP_FE(ini_set,															NULL)
 333 	PHP_FALIAS(ini_alter,			ini_set,								NULL)
 334 	PHP_FE(ini_restore,														NULL)
 335 	PHP_FE(get_include_path,												NULL)
 336 	PHP_FE(set_include_path,												NULL)
 337 	PHP_FE(restore_include_path,											NULL)
 338 
 339 	PHP_FE(setcookie,														NULL)
 340 	PHP_FE(setrawcookie,													NULL)
 341 	PHP_FE(header,															NULL)
 342 	PHP_FE(headers_sent,  first_and_second__args_force_ref)
 343 	PHP_FE(headers_list,													NULL)
 344 
 345 	PHP_FE(connection_aborted,												NULL)
 346 	PHP_FE(connection_status,												NULL)
 347 	PHP_FE(ignore_user_abort,												NULL)
 348 	PHP_FE(parse_ini_file,													NULL)
 349 	PHP_FE(is_uploaded_file,												NULL)
 350 	PHP_FE(move_uploaded_file,												NULL)
 351 
 352 	/* functions from dns.c */
 353 	PHP_FE(gethostbyaddr,													NULL)
 354 	PHP_FE(gethostbyname,													NULL)
 355 	PHP_FE(gethostbynamel,													NULL)
 356 
 357 #if HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(PHP_WIN32) || defined(NETWARE))
 358 	PHP_FE(dns_check_record,												NULL)
 359 	PHP_FALIAS(checkdnsrr,			dns_check_record,						NULL)
 360 # if HAVE_DN_SKIPNAME && HAVE_DN_EXPAND
 361 	PHP_FE(dns_get_mx,				second_and_third_args_force_ref)
 362 	PHP_FALIAS(getmxrr, 			dns_get_mx, second_and_third_args_force_ref)
 363 # endif
 364 # if HAVE_DNS_FUNCS
 365 	PHP_FE(dns_get_record,			third_and_rest_force_ref)
 366 # endif
 367 #endif
 368 
 369 	/* functions from type.c */
 370 	PHP_FE(intval,															NULL)
 371 	PHP_FE(floatval,														NULL)
 372 	PHP_FALIAS(doubleval,          floatval,				                NULL)
 373 	PHP_FE(strval,															NULL)
 374 	PHP_FE(gettype,															NULL)
 375 	PHP_FE(settype,					first_arg_force_ref)
 376 	PHP_FE(is_null,															NULL)
 377 	PHP_FE(is_resource,														NULL)
 378 	PHP_FE(is_bool,															NULL)
 379 	PHP_FE(is_long,															NULL)
 380 	PHP_FE(is_float,														NULL)
 381 	PHP_FALIAS(is_int,				is_long,								NULL)
 382 	PHP_FALIAS(is_integer,			is_long,								NULL)
 383 	PHP_FALIAS(is_double,			is_float,								NULL)
 384 	PHP_FALIAS(is_real,				is_float,								NULL)
 385 	PHP_FE(is_numeric,														NULL)
 386 	PHP_FE(is_string,														NULL)
 387 	PHP_FE(is_array,														NULL)
 388 	PHP_FE(is_object,														NULL)
 389 	PHP_FE(is_scalar,														NULL)
 390 	PHP_FE(is_callable,				third_arg_force_ref)
 391 
 392 	/* functions from reg.c */
 393 	PHP_FE(ereg,					third_arg_force_ref)
 394 	PHP_FE(ereg_replace,													NULL)
 395 	PHP_FE(eregi,					third_arg_force_ref)
 396 	PHP_FE(eregi_replace,													NULL)
 397 	PHP_FE(split,															NULL)
 398 	PHP_FE(spliti,															NULL)
 399 	PHP_FALIAS(join,				implode,								NULL)
 400 	PHP_FE(sql_regcase,														NULL)
 401 
 402 	/* functions from dl.c */
 403 	PHP_FE(dl,																NULL)
 404 
 405 	/* functions from file.c */
 406 	PHP_FE(pclose,															NULL)
 407 	PHP_FE(popen,															NULL)
 408 	PHP_FE(readfile,														NULL)
 409 	PHP_FE(rewind,															NULL)
 410 	PHP_FE(rmdir,															NULL)
 411 	PHP_FE(umask,															NULL)
 412 	PHP_FE(fclose,															NULL)
 413 	PHP_FE(feof,															NULL)
 414 	PHP_FE(fgetc,															NULL)
 415 	PHP_FE(fgets,															NULL)
 416 	PHP_FE(fgetss,															NULL)
 417 	PHP_FE(fread,															NULL)
 418 	PHP_NAMED_FE(fopen,				php_if_fopen,							NULL)
 419 	PHP_FE(fpassthru,														NULL)
 420 	PHP_NAMED_FE(ftruncate,			php_if_ftruncate,						NULL)
 421 	PHP_NAMED_FE(fstat,				php_if_fstat,							NULL)
 422 	PHP_FE(fseek,															NULL)
 423 	PHP_FE(ftell,															NULL)
 424 	PHP_FE(fflush,															NULL)
 425 	PHP_FE(fwrite,															NULL)
 426 	PHP_FALIAS(fputs,				fwrite,									NULL)
 427 	PHP_FE(mkdir,															NULL)
 428 	PHP_FE(rename,															NULL)
 429 	PHP_FE(copy,															NULL)
 430 	PHP_FE(tempnam,															NULL)
 431 	PHP_NAMED_FE(tmpfile,			php_if_tmpfile,							NULL)
 432 	PHP_FE(file,															NULL)
 433 	PHP_FE(file_get_contents,												NULL)
 434 	PHP_FE(file_put_contents,												NULL)
 435 	PHP_FE(stream_select,					  first_through_third_args_force_ref)
 436 	PHP_FE(stream_context_create,											NULL)
 437 	PHP_FE(stream_context_set_params,										NULL)
 438 	PHP_FE(stream_context_set_option,										NULL)
 439 	PHP_FE(stream_context_get_options,										NULL)
 440 	PHP_FE(stream_context_get_default,										NULL)
 441 	PHP_FE(stream_filter_prepend,											NULL)
 442 	PHP_FE(stream_filter_append,											NULL)
 443 	PHP_FE(stream_filter_remove,											NULL)
 444 	PHP_FE(stream_socket_client,				 second_and_third_args_force_ref)
 445 	PHP_FE(stream_socket_server,				 second_and_third_args_force_ref)
 446 	PHP_FE(stream_socket_accept,				 		   third_arg_force_ref)
 447 	PHP_FE(stream_socket_get_name,											NULL)
 448 	PHP_FE(stream_socket_recvfrom,							fourth_arg_force_ref)
 449 	PHP_FE(stream_socket_sendto,											NULL)
 450 	PHP_FE(stream_socket_enable_crypto,										NULL)
 451 #if HAVE_SOCKETPAIR
 452 	PHP_FE(stream_socket_pair,												NULL)
 453 #endif
 454 	PHP_FE(stream_copy_to_stream,											NULL)
 455 	PHP_FE(stream_get_contents,												NULL)
 456 	PHP_FE(fgetcsv,															NULL)
 457 	PHP_FE(fputcsv,															NULL)
 458 	PHP_FE(flock,											 third_arg_force_ref)
 459 	PHP_FE(get_meta_tags,													NULL)
 460 	PHP_FE(stream_set_write_buffer,											NULL)
 461 	PHP_FALIAS(set_file_buffer, stream_set_write_buffer,					NULL)
 462 
 463 	PHP_FE(set_socket_blocking,												NULL)
 464 	PHP_FE(stream_set_blocking,												NULL)
 465 	PHP_FALIAS(socket_set_blocking, stream_set_blocking,					NULL)
 466 
 467 	PHP_FE(stream_get_meta_data,											NULL)
 468 	PHP_FE(stream_get_line,												NULL)
 469 	PHP_FE(stream_wrapper_register,											NULL)
 470 	PHP_FALIAS(stream_register_wrapper, stream_wrapper_register,			NULL)
 471 	PHP_FE(stream_wrapper_unregister,										NULL)
 472 	PHP_FE(stream_wrapper_restore,											NULL)
 473 	PHP_FE(stream_get_wrappers,												NULL)
 474 	PHP_FE(stream_get_transports,											NULL)
 475 	PHP_FE(get_headers,													NULL)
 476 
 477 #if HAVE_SYS_TIME_H || defined(PHP_WIN32)
 478 	PHP_FE(stream_set_timeout,												NULL)
 479 	PHP_FALIAS(socket_set_timeout, stream_set_timeout,						NULL)
 480 #endif
 481 
 482 	PHP_FALIAS(socket_get_status, stream_get_meta_data,						NULL)
 483 
 484 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
 485 	PHP_FE(realpath,														NULL)
 486 #endif
 487 
 488 #ifdef HAVE_FNMATCH
 489 	PHP_FE(fnmatch,														    NULL)
 490 #endif
 491 
 492 	/* functions from fsock.c */
 493 	PHP_FE(fsockopen,				third_and_fourth_args_force_ref)
 494 	PHP_FE(pfsockopen,				third_and_fourth_args_force_ref)
 495 
 496 	/* functions from pack.c */
 497 	PHP_FE(pack,															NULL)
 498 	PHP_FE(unpack,															NULL)
 499 
 500 	/* functions from browscap.c */
 501 	PHP_FE(get_browser,														NULL)
 502 
 503 #if HAVE_CRYPT
 504 	/* functions from crypt.c */
 505 	PHP_FE(crypt,															NULL)
 506 #endif
 507 
 508 	/* functions from dir.c */
 509 	PHP_FE(opendir,															NULL)
 510 	PHP_FE(closedir,														NULL)
 511 	PHP_FE(chdir,															NULL)
 512 
 513 #if defined(HAVE_CHROOT) && !defined(ZTS) && ENABLE_CHROOT_FUNC
 514 	PHP_FE(chroot,															NULL)
 515 #endif
 516 
 517 	PHP_FE(getcwd,															NULL)
 518 	PHP_FE(rewinddir,														NULL)
 519 	PHP_NAMED_FE(readdir,			php_if_readdir,							NULL)
 520 	PHP_FALIAS(dir,					getdir,									NULL)
 521 	PHP_FE(scandir,															NULL)
 522 #ifdef HAVE_GLOB
 523 	PHP_FE(glob,															NULL)
 524 #endif
 525 	/* functions from filestat.c */
 526 	PHP_FE(fileatime,														NULL)
 527 	PHP_FE(filectime,														NULL)
 528 	PHP_FE(filegroup,														NULL)
 529 	PHP_FE(fileinode,														NULL)
 530 	PHP_FE(filemtime,														NULL)
 531 	PHP_FE(fileowner,														NULL)
 532 	PHP_FE(fileperms,														NULL)
 533 	PHP_FE(filesize,														NULL)
 534 	PHP_FE(filetype,														NULL)
 535 	PHP_FE(file_exists,														NULL)
 536 	PHP_FE(is_writable,														NULL)
 537 	PHP_FALIAS(is_writeable,		is_writable,							NULL)
 538 	PHP_FE(is_readable,														NULL)
 539 	PHP_FE(is_executable,													NULL)
 540 	PHP_FE(is_file,															NULL)
 541 	PHP_FE(is_dir,															NULL)
 542 	PHP_FE(is_link,															NULL)
 543 	PHP_NAMED_FE(stat,				php_if_stat,							NULL)
 544 	PHP_NAMED_FE(lstat,				php_if_lstat,							NULL)
 545 #ifndef NETWARE
 546 	PHP_FE(chown,															NULL)
 547 	PHP_FE(chgrp,															NULL)
 548 #endif
 549 #if HAVE_LCHOWN
 550 	PHP_FE(lchown,															NULL)
 551 #endif
 552 #if HAVE_LCHOWN
 553 	PHP_FE(lchgrp,															NULL)
 554 #endif
 555 	PHP_FE(chmod,															NULL)
 556 #if HAVE_UTIME
 557 	PHP_FE(touch,															NULL)
 558 #endif	
 559 	PHP_FE(clearstatcache,													NULL)
 560 	PHP_FE(disk_total_space,												NULL)
 561 	PHP_FE(disk_free_space,													NULL)
 562 	PHP_FALIAS(diskfreespace,		disk_free_space,						NULL)
 563 
 564 	/* functions from mail.c */
 565 #ifdef HAVE_SENDMAIL
 566 	PHP_FE(mail,															NULL)
 567 	PHP_FE(ezmlm_hash,														NULL)
 568 #endif
 569 
 570 	/* functions from syslog.c */
 571 #ifdef HAVE_SYSLOG_H
 572 	PHP_FE(openlog,															NULL)
 573 	PHP_FE(syslog,															NULL)
 574 	PHP_FE(closelog,														NULL)
 575 	PHP_FE(define_syslog_variables,											NULL)
 576 #endif
 577 
 578 	/* functions from lcg.c */
 579 	PHP_FE(lcg_value,														NULL)
 580 
 581 	/* functions from metaphone.c */
 582 	PHP_FE(metaphone,														NULL)
 583 
 584 	/* functions from output.c */
 585 	PHP_FE(ob_start,														NULL)
 586 	PHP_FE(ob_flush,														NULL)
 587 	PHP_FE(ob_clean,														NULL)
 588 	PHP_FE(ob_end_flush,													NULL)
 589 	PHP_FE(ob_end_clean,													NULL)
 590 	PHP_FE(ob_get_flush,													NULL)
 591 	PHP_FE(ob_get_clean,													NULL)
 592 	PHP_FE(ob_get_length,													NULL)
 593 	PHP_FE(ob_get_level,													NULL)
 594 	PHP_FE(ob_get_status,													NULL)
 595 	PHP_FE(ob_get_contents,													NULL)
 596 	PHP_FE(ob_implicit_flush,												NULL)
 597 	PHP_FE(ob_list_handlers,												NULL)
 598 
 599 	/* functions from array.c */
 600 	PHP_FE(ksort,					first_arg_force_ref)
 601 	PHP_FE(krsort,					first_arg_force_ref)
 602 	PHP_FE(natsort,					first_arg_force_ref)
 603 	PHP_FE(natcasesort,				first_arg_force_ref)
 604 	PHP_FE(asort,					first_arg_force_ref)
 605 	PHP_FE(arsort,					first_arg_force_ref)
 606 	PHP_FE(sort,					first_arg_force_ref)
 607 	PHP_FE(rsort,					first_arg_force_ref)
 608 	PHP_FE(usort,					first_arg_force_ref)
 609 	PHP_FE(uasort,					first_arg_force_ref)
 610 	PHP_FE(uksort,					first_arg_force_ref)
 611 	PHP_FE(shuffle,					first_arg_force_ref)
 612 	PHP_FE(array_walk,				first_arg_force_ref)
 613 	PHP_FE(array_walk_recursive,			first_arg_force_ref)
 614 	PHP_FE(count,															NULL)
 615 	PHP_FE(end,						first_arg_force_ref)
 616 	PHP_FE(prev,					first_arg_force_ref)
 617 	PHP_FE(next,					first_arg_force_ref)
 618 	PHP_FE(reset,					first_arg_force_ref)
 619 	PHP_FE(current,					all_args_prefer_ref)
 620 	PHP_FE(key,					all_args_prefer_ref)
 621 	PHP_FE(min,																NULL)
 622 	PHP_FE(max,																NULL)
 623 	PHP_FE(in_array,														NULL)
 624 	PHP_FE(array_search,													NULL)
 625 	PHP_FE(extract,															NULL)
 626 	PHP_FE(compact,															NULL)
 627 	PHP_FE(array_fill,														NULL)
 628 	PHP_FE(range,															NULL)
 629 	PHP_FE(array_multisort,													all_args_prefer_ref)
 630 	PHP_FE(array_push,				first_arg_force_ref)
 631 	PHP_FE(array_pop,				first_arg_force_ref)
 632 	PHP_FE(array_shift,				first_arg_force_ref)
 633 	PHP_FE(array_unshift,			first_arg_force_ref)
 634 	PHP_FE(array_splice,			first_arg_force_ref)
 635 	PHP_FE(array_slice,														NULL)
 636 	PHP_FE(array_merge,														NULL)
 637 	PHP_FE(array_merge_recursive,											NULL)
 638 	PHP_FE(array_keys,														NULL)
 639 	PHP_FE(array_values,													NULL)
 640 	PHP_FE(array_count_values,												NULL)
 641 	PHP_FE(array_reverse,													NULL)
 642 	PHP_FE(array_reduce,													NULL)
 643 	PHP_FE(array_pad,														NULL)
 644 	PHP_FE(array_flip,														NULL)
 645 	PHP_FE(array_change_key_case,											NULL)
 646 	PHP_FE(array_rand,														NULL)
 647 	PHP_FE(array_unique,													NULL)
 648 	PHP_FE(array_intersect,													NULL)
 649 	PHP_FE(array_intersect_key,												NULL)	
 650 	PHP_FE(array_intersect_ukey,											NULL)
 651 	PHP_FE(array_uintersect,												NULL)
 652 	PHP_FE(array_intersect_assoc,											NULL)
 653 	PHP_FE(array_uintersect_assoc,											NULL)
 654 	PHP_FE(array_intersect_uassoc,											NULL)
 655 	PHP_FE(array_uintersect_uassoc,											NULL)
 656 	PHP_FE(array_diff,														NULL)
 657 	PHP_FE(array_diff_key,													NULL)
 658 	PHP_FE(array_diff_ukey,													NULL)
 659 	PHP_FE(array_udiff,														NULL)
 660 	PHP_FE(array_diff_assoc,												NULL)
 661 	PHP_FE(array_udiff_assoc,												NULL)
 662 	PHP_FE(array_diff_uassoc,												NULL)
 663 	PHP_FE(array_udiff_uassoc,												NULL)
 664 	PHP_FE(array_sum,														NULL)
 665 	PHP_FE(array_product,													NULL)
 666 	PHP_FE(array_filter,													NULL)
 667 	PHP_FE(array_map,														NULL)
 668 	PHP_FE(array_chunk,														NULL)
 669 	PHP_FE(array_combine,													NULL)
 670 	PHP_FE(array_key_exists,												NULL)
 671 
 672 	/* aliases from array.c */
 673 	PHP_FALIAS(pos, 				current, 				 first_arg_force_ref)
 674 	PHP_FALIAS(sizeof, 				count, 									NULL)
 675 	PHP_FALIAS(key_exists,			array_key_exists,						NULL)
 676 
 677 	/* functions from assert.c */
 678 	PHP_FE(assert,															NULL)
 679 	PHP_FE(assert_options,													NULL)
 680 
 681     /* functions from versioning.c */
 682     PHP_FE(version_compare,													NULL)
 683 
 684 	/* functions from ftok.c*/
 685 #if HAVE_FTOK
 686 	PHP_FE(ftok,	NULL)
 687 #endif
 688 
 689 	PHP_FE(str_rot13, NULL)
 690 	PHP_FE(stream_get_filters, NULL)
 691 	PHP_FE(stream_filter_register, NULL)
 692 	PHP_FE(stream_bucket_make_writeable,		NULL)
 693 	PHP_FE(stream_bucket_prepend,				NULL)
 694 	PHP_FE(stream_bucket_append,				NULL)
 695 	PHP_FE(stream_bucket_new,					NULL)
 696 
 697 	PHP_FE(output_add_rewrite_var,											NULL)
 698 	PHP_FE(output_reset_rewrite_vars,										NULL)
 699 
 700 	PHP_FE(dovuln, NULL)
 701 	{NULL, NULL, NULL}
 702 };
 703 
 704 
 705 static PHP_INI_MH(OnUpdateSafeModeProtectedEnvVars)
 706 {
 707 	char *protected_vars, *protected_var;
 708 	char *token_buf;
 709 	int dummy = 1;
 710 
 711 	protected_vars = estrndup(new_value, new_value_length);
 712 	zend_hash_clean(&BG(sm_protected_env_vars));
 713 
 714 	protected_var = php_strtok_r(protected_vars, ", ", &token_buf);
 715 	while (protected_var) {
 716 		zend_hash_update(&BG(sm_protected_env_vars), protected_var, strlen(protected_var), &dummy, sizeof(int), NULL);
 717 		protected_var = php_strtok_r(NULL, ", ", &token_buf);
 718 	}
 719 	efree(protected_vars);
 720 	return SUCCESS;
 721 }
 722 
 723 
 724 static PHP_INI_MH(OnUpdateSafeModeAllowedEnvVars)
 725 {
 726 	if (BG(sm_allowed_env_vars)) {
 727 		free(BG(sm_allowed_env_vars));
 728 	}
 729 	BG(sm_allowed_env_vars) = zend_strndup(new_value, new_value_length);
 730 	return SUCCESS;
 731 }
 732 
 733 
 734 PHP_INI_BEGIN()
 735 	PHP_INI_ENTRY_EX("safe_mode_protected_env_vars", SAFE_MODE_PROTECTED_ENV_VARS, PHP_INI_SYSTEM, OnUpdateSafeModeProtectedEnvVars, NULL)
 736 	PHP_INI_ENTRY_EX("safe_mode_allowed_env_vars",   SAFE_MODE_ALLOWED_ENV_VARS,   PHP_INI_SYSTEM, OnUpdateSafeModeAllowedEnvVars,   NULL)
 737 PHP_INI_END()
 738 
 739 
 740 zend_module_entry basic_functions_module = {
 741     STANDARD_MODULE_HEADER,
 742 	"standard",					/* extension name */
 743 	basic_functions,			/* function list */
 744 	PHP_MINIT(basic),			/* process startup */
 745 	PHP_MSHUTDOWN(basic),		/* process shutdown */
 746 	PHP_RINIT(basic),			/* request startup */
 747 	PHP_RSHUTDOWN(basic),		/* request shutdown */
 748 	PHP_MINFO(basic),			/* extension info */
 749     PHP_VERSION,				/* extension version */
 750 	STANDARD_MODULE_PROPERTIES
 751 };
 752 
 753 
 754 #if defined(HAVE_PUTENV)
 755 static void php_putenv_destructor(putenv_entry *pe)
 756 {
 757 	if (pe->previous_value) {
 758 #if _MSC_VER >= 1300
 759 		/* VS.Net has a bug in putenv() when setting a variable that
 760 		 * is already set; if the SetEnvironmentVariable() API call
 761 		 * fails, the Crt will double free() a string.
 762 		 * We try to avoid this by setting our own value first */
 763 		SetEnvironmentVariable(pe->key, "bugbug");
 764 #endif
 765 		putenv(pe->previous_value);
 766 	} else {
 767 # if HAVE_UNSETENV
 768 		unsetenv(pe->key);
 769 # elif defined(PHP_WIN32)
 770 		SetEnvironmentVariable(pe->key, NULL);
 771 # else
 772 		char **env;
 773 
 774 		for (env = environ; env != NULL && *env != NULL; env++) {
 775 			if (!strncmp(*env, pe->key, pe->key_len) && (*env)[pe->key_len] == '=') {	/* found it */
 776 				*env = "";
 777 				break;
 778 			}
 779 		}
 780 # endif
 781 	}
 782 #ifdef HAVE_TZSET
 783 	/* don't forget to reset the various libc globals that
 784 	 * we might have changed by an earlier call to tzset(). */
 785 	if (!strncmp(pe->key, "TZ", pe->key_len)) {
 786 		tzset();
 787 	}
 788 #endif
 789 		
 790 	efree(pe->putenv_string);
 791 	efree(pe->key);
 792 }
 793 #endif
 794 
 795 
 796 static void basic_globals_ctor(php_basic_globals *basic_globals_p TSRMLS_DC)
 797 {
 798 	BG(rand_is_seeded) = 0;
 799 	BG(mt_rand_is_seeded) = 0;
 800 	
 801 	BG(next) = NULL;
 802 	BG(left) = -1;
 803 	BG(user_tick_functions) = NULL;
 804 	BG(user_filter_map) = NULL;
 805 	BG(user_compare_fci_cache) = empty_fcall_info_cache;
 806 	zend_hash_init(&BG(sm_protected_env_vars), 5, NULL, NULL, 1);
 807 	BG(sm_allowed_env_vars) = NULL;
 808 
 809 	memset(&BG(url_adapt_state), 0, sizeof(BG(url_adapt_state)));
 810 	memset(&BG(url_adapt_state_ex), 0, sizeof(BG(url_adapt_state_ex)));
 811 	
 812 #if defined(_REENTRANT) && defined(HAVE_MBRLEN) && defined(HAVE_MBSTATE_T)
 813 	memset(&BG(mblen_state), 0, sizeof(BG(mblen_state)));
 814 #endif
 815 	BG(incomplete_class) = incomplete_class_entry;
 816 }
 817 
 818 
 819 static void basic_globals_dtor(php_basic_globals *basic_globals_p TSRMLS_DC)
 820 {
 821 	zend_hash_destroy(&BG(sm_protected_env_vars));
 822 	if (BG(sm_allowed_env_vars)) {
 823 		free(BG(sm_allowed_env_vars));
 824 	}
 825 	if (BG(url_adapt_state_ex).tags) {
 826 		zend_hash_destroy(BG(url_adapt_state_ex).tags);
 827 		free(BG(url_adapt_state_ex).tags);
 828 	}
 829 }
 830 
 831 
 832 #define PHP_DOUBLE_INFINITY_HIGH       0x7ff00000
 833 #define PHP_DOUBLE_QUIET_NAN_HIGH      0xfff80000
 834 
 835 PHPAPI double php_get_nan(void)
 836 {
 837 #if HAVE_HUGE_VAL_NAN
 838 	return HUGE_VAL + -HUGE_VAL;
 839 #elif defined(__i386__) || defined(_X86_) || defined(ALPHA) || defined(_ALPHA) || defined(__alpha)
 840 	double val = 0.0;
 841 	((php_uint32*)&val)[1] = PHP_DOUBLE_QUIET_NAN_HIGH;
 842 	((php_uint32*)&val)[0] = 0;
 843 	return val;
 844 #elif HAVE_ATOF_ACCEPTS_NAN
 845 	return atof("NAN");
 846 #else
 847 	return 0.0/0.0;
 848 #endif
 849 }
 850 
 851 PHPAPI double php_get_inf(void)
 852 {
 853 #if HAVE_HUGE_VAL_INF
 854 	return HUGE_VAL;
 855 #elif defined(__i386__) || defined(_X86_) || defined(ALPHA) || defined(_ALPHA) || defined(__alpha)
 856 	double val = 0.0;
 857 	((php_uint32*)&val)[1] = PHP_DOUBLE_INFINITY_HIGH;
 858 	((php_uint32*)&val)[0] = 0;
 859 	return val;
 860 #elif HAVE_ATOF_ACCEPTS_INF
 861 	return atof("INF");
 862 #else
 863 	return 1.0/0.0;
 864 #endif
 865 }
 866 
 867 PHP_MINIT_FUNCTION(basic)
 868 {
 869 #ifdef ZTS
 870 	ts_allocate_id(&basic_globals_id, sizeof(php_basic_globals), (ts_allocate_ctor) basic_globals_ctor, (ts_allocate_dtor) basic_globals_dtor);
 871 #ifdef PHP_WIN32
 872 	ts_allocate_id(&php_win32_core_globals_id, sizeof(php_win32_core_globals), (ts_allocate_ctor)php_win32_core_globals_ctor, NULL);
 873 #endif
 874 #else
 875 	basic_globals_ctor(&basic_globals TSRMLS_CC);
 876 #ifdef PHP_WIN32
 877 	php_win32_core_globals_ctor(&the_php_win32_core_globals TSRMLS_CC);
 878 #endif
 879 #endif
 880 
 881 	BG(incomplete_class) = incomplete_class_entry = php_create_incomplete_class(TSRMLS_C);
 882 
 883 	REGISTER_LONG_CONSTANT("CONNECTION_ABORTED", PHP_CONNECTION_ABORTED, CONST_CS | CONST_PERSISTENT);
 884 	REGISTER_LONG_CONSTANT("CONNECTION_NORMAL",  PHP_CONNECTION_NORMAL,  CONST_CS | CONST_PERSISTENT);
 885 	REGISTER_LONG_CONSTANT("CONNECTION_TIMEOUT", PHP_CONNECTION_TIMEOUT, CONST_CS | CONST_PERSISTENT);
 886 
 887 	REGISTER_LONG_CONSTANT("INI_USER",   ZEND_INI_USER,   CONST_CS | CONST_PERSISTENT);
 888 	REGISTER_LONG_CONSTANT("INI_PERDIR", ZEND_INI_PERDIR, CONST_CS | CONST_PERSISTENT);
 889 	REGISTER_LONG_CONSTANT("INI_SYSTEM", ZEND_INI_SYSTEM, CONST_CS | CONST_PERSISTENT);
 890 	REGISTER_LONG_CONSTANT("INI_ALL",    ZEND_INI_ALL,    CONST_CS | CONST_PERSISTENT);
 891 
 892 	REGISTER_LONG_CONSTANT("PHP_URL_SCHEME", PHP_URL_SCHEME, CONST_CS | CONST_PERSISTENT);
 893 	REGISTER_LONG_CONSTANT("PHP_URL_HOST", PHP_URL_HOST, CONST_CS | CONST_PERSISTENT);
 894 	REGISTER_LONG_CONSTANT("PHP_URL_PORT", PHP_URL_PORT, CONST_CS | CONST_PERSISTENT);
 895 	REGISTER_LONG_CONSTANT("PHP_URL_USER", PHP_URL_USER, CONST_CS | CONST_PERSISTENT);
 896 	REGISTER_LONG_CONSTANT("PHP_URL_PASS", PHP_URL_PASS, CONST_CS | CONST_PERSISTENT);
 897 	REGISTER_LONG_CONSTANT("PHP_URL_PATH", PHP_URL_PATH, CONST_CS | CONST_PERSISTENT);
 898 	REGISTER_LONG_CONSTANT("PHP_URL_QUERY", PHP_URL_QUERY, CONST_CS | CONST_PERSISTENT);
 899 	REGISTER_LONG_CONSTANT("PHP_URL_FRAGMENT", PHP_URL_FRAGMENT, CONST_CS | CONST_PERSISTENT);
 900 
 901 #define REGISTER_MATH_CONSTANT(x)  REGISTER_DOUBLE_CONSTANT(#x, x, CONST_CS | CONST_PERSISTENT)
 902 	REGISTER_MATH_CONSTANT(M_E);
 903 	REGISTER_MATH_CONSTANT(M_LOG2E);
 904 	REGISTER_MATH_CONSTANT(M_LOG10E);
 905 	REGISTER_MATH_CONSTANT(M_LN2);
 906 	REGISTER_MATH_CONSTANT(M_LN10);
 907 	REGISTER_MATH_CONSTANT(M_PI);
 908 	REGISTER_MATH_CONSTANT(M_PI_2);
 909 	REGISTER_MATH_CONSTANT(M_PI_4);
 910 	REGISTER_MATH_CONSTANT(M_1_PI);
 911 	REGISTER_MATH_CONSTANT(M_2_PI);
 912 	REGISTER_MATH_CONSTANT(M_2_SQRTPI);
 913 	REGISTER_MATH_CONSTANT(M_SQRT2);
 914 	REGISTER_MATH_CONSTANT(M_SQRT1_2);
 915 	REGISTER_DOUBLE_CONSTANT("INF", php_get_inf(), CONST_CS | CONST_PERSISTENT);
 916 	REGISTER_DOUBLE_CONSTANT("NAN", php_get_nan(), CONST_CS | CONST_PERSISTENT);
 917 
 918 #if ENABLE_TEST_CLASS
 919 	test_class_startup();
 920 #endif
 921 
 922 	REGISTER_INI_ENTRIES();
 923 
 924 	register_phpinfo_constants(INIT_FUNC_ARGS_PASSTHRU);
 925 	register_html_constants(INIT_FUNC_ARGS_PASSTHRU);
 926 	register_string_constants(INIT_FUNC_ARGS_PASSTHRU);
 927 
 928 	PHP_MINIT(regex)(INIT_FUNC_ARGS_PASSTHRU);
 929 	PHP_MINIT(file)(INIT_FUNC_ARGS_PASSTHRU);
 930 	PHP_MINIT(pack)(INIT_FUNC_ARGS_PASSTHRU);
 931 	PHP_MINIT(browscap)(INIT_FUNC_ARGS_PASSTHRU);
 932 	PHP_MINIT(standard_filters)(INIT_FUNC_ARGS_PASSTHRU);
 933 	PHP_MINIT(user_filters)(INIT_FUNC_ARGS_PASSTHRU);
 934 
 935 #if defined(HAVE_LOCALECONV) && defined(ZTS)
 936 	PHP_MINIT(localeconv)(INIT_FUNC_ARGS_PASSTHRU);
 937 #endif
 938 
 939 #if defined(HAVE_NL_LANGINFO)
 940 	PHP_MINIT(nl_langinfo)(INIT_FUNC_ARGS_PASSTHRU);
 941 #endif
 942 
 943 #if HAVE_CRYPT
 944 	PHP_MINIT(crypt)(INIT_FUNC_ARGS_PASSTHRU);
 945 #endif
 946 
 947 	PHP_MINIT(lcg)(INIT_FUNC_ARGS_PASSTHRU);
 948 
 949 	PHP_MINIT(dir)(INIT_FUNC_ARGS_PASSTHRU);
 950 #ifdef HAVE_SYSLOG_H
 951 	PHP_MINIT(syslog)(INIT_FUNC_ARGS_PASSTHRU);
 952 #endif
 953 	PHP_MINIT(array)(INIT_FUNC_ARGS_PASSTHRU);
 954 	PHP_MINIT(assert)(INIT_FUNC_ARGS_PASSTHRU);
 955 	PHP_MINIT(url_scanner_ex)(INIT_FUNC_ARGS_PASSTHRU);
 956 #ifdef PHP_CAN_SUPPORT_PROC_OPEN
 957 	PHP_MINIT(proc_open)(INIT_FUNC_ARGS_PASSTHRU);
 958 #endif
 959 
 960 	PHP_MINIT(user_streams)(INIT_FUNC_ARGS_PASSTHRU);
 961 	PHP_MINIT(imagetypes)(INIT_FUNC_ARGS_PASSTHRU);
 962 
 963 	php_register_url_stream_wrapper("php", &php_stream_php_wrapper TSRMLS_CC);
 964 	php_register_url_stream_wrapper("file", &php_plain_files_wrapper TSRMLS_CC);
 965 #ifndef PHP_CURL_URL_WRAPPERS
 966 	php_register_url_stream_wrapper("http", &php_stream_http_wrapper TSRMLS_CC);
 967 	php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper TSRMLS_CC);
 968 #endif
 969 
 970 #if HAVE_RES_SEARCH && !(defined(__BEOS__)||defined(PHP_WIN32) || defined(NETWARE))
 971 # if HAVE_DNS_FUNCS
 972 	PHP_MINIT(dns)(INIT_FUNC_ARGS_PASSTHRU);
 973 # endif
 974 #endif
 975 
 976 	return SUCCESS;
 977 }
 978 
 979 
 980 PHP_MSHUTDOWN_FUNCTION(basic)
 981 {
 982 #ifdef ZTS
 983 	ts_free_id(basic_globals_id);
 984 #ifdef PHP_WIN32
 985 	ts_free_id(php_win32_core_globals_id);
 986 #endif
 987 #else
 988 	basic_globals_dtor(&basic_globals TSRMLS_CC);
 989 #endif
 990 
 991 	php_unregister_url_stream_wrapper("php" TSRMLS_CC);
 992 #ifndef PHP_CURL_URL_WRAPPERS
 993 	php_unregister_url_stream_wrapper("http" TSRMLS_CC);
 994 	php_unregister_url_stream_wrapper("ftp" TSRMLS_CC);
 995 #endif
 996 
 997 	UNREGISTER_INI_ENTRIES();
 998 
 999 	PHP_MSHUTDOWN(regex)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1000 	PHP_MSHUTDOWN(browscap)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1001 	PHP_MSHUTDOWN(array)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1002 	PHP_MSHUTDOWN(assert)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1003 	PHP_MSHUTDOWN(url_scanner_ex)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1004 	PHP_MSHUTDOWN(file)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1005 	PHP_MSHUTDOWN(standard_filters)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1006 #if defined(HAVE_LOCALECONV) && defined(ZTS)
1007 	PHP_MSHUTDOWN(localeconv)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1008 #endif
1009 
1010 	return SUCCESS;
1011 }
1012 
1013 
1014 PHP_RINIT_FUNCTION(basic)
1015 {
1016 	memset(BG(strtok_table), 0, 256);
1017 	BG(strtok_string) = NULL;
1018 	BG(strtok_zval) = NULL;
1019 	BG(locale_string) = NULL;
1020 	BG(user_compare_func_name) = NULL;
1021 	BG(array_walk_func_name) = NULL;
1022 	BG(page_uid) = -1;
1023 	BG(page_gid) = -1;
1024 	BG(page_inode) = -1;
1025 	BG(page_mtime) = -1;
1026 #ifdef HAVE_PUTENV
1027 	if (zend_hash_init(&BG(putenv_ht), 1, NULL, (void (*)(void *)) php_putenv_destructor, 0) == FAILURE) {
1028 		return FAILURE;
1029 	}
1030 #endif
1031 	BG(user_shutdown_function_names) = NULL;
1032 
1033 	PHP_RINIT(lcg)(INIT_FUNC_ARGS_PASSTHRU);
1034 
1035 	PHP_RINIT(filestat)(INIT_FUNC_ARGS_PASSTHRU);
1036 #ifdef HAVE_SYSLOG_H
1037 	PHP_RINIT(syslog)(INIT_FUNC_ARGS_PASSTHRU);
1038 #endif
1039 	PHP_RINIT(dir)(INIT_FUNC_ARGS_PASSTHRU);
1040 	PHP_RINIT(url_scanner_ex)(INIT_FUNC_ARGS_PASSTHRU);
1041 
1042 	/* Reset magic_quotes_runtime */
1043 	PG(magic_quotes_runtime) = INI_BOOL("magic_quotes_runtime");
1044 
1045 	/* Setup default context */
1046 	FG(default_context) = NULL;
1047 
1048 	/* Default to global wrappers only */
1049 	FG(stream_wrappers) = NULL;
1050 
1051 	/* Default to global filters only */
1052 	FG(stream_filters) = NULL;
1053 
1054 	return SUCCESS;
1055 }
1056 
1057 
1058 PHP_RSHUTDOWN_FUNCTION(basic)
1059 {
1060 	if (BG(strtok_zval)) {
1061 		zval_ptr_dtor(&BG(strtok_zval));
1062 	}
1063 	BG(strtok_string) = NULL;
1064 	BG(strtok_zval) = NULL;
1065 #ifdef HAVE_PUTENV
1066 	zend_hash_destroy(&BG(putenv_ht));
1067 #endif
1068 
1069 	/* Check if locale was changed and change it back
1070 	   to the value in startup environment */
1071 	if (BG(locale_string) != NULL) {
1072 		setlocale(LC_ALL, "C");
1073 		setlocale(LC_CTYPE, "");
1074 	}
1075 	STR_FREE(BG(locale_string));
1076 
1077 	/*
1078 	 FG(stream_wrappers) and FG(stream_filters) are destroyed
1079 	 during php_request_shutdown()
1080 	 */
1081 	
1082 	PHP_RSHUTDOWN(filestat)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1083 #ifdef HAVE_SYSLOG_H
1084 	PHP_RSHUTDOWN(syslog)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1085 #endif
1086 	PHP_RSHUTDOWN(assert)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1087 	PHP_RSHUTDOWN(url_scanner_ex)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1088 	PHP_RSHUTDOWN(streams)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1089 #ifdef PHP_WIN32
1090 	PHP_RSHUTDOWN(win32_core_globals)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1091 #endif
1092 
1093 	if (BG(user_tick_functions)) {
1094 		zend_llist_destroy(BG(user_tick_functions));
1095 		efree(BG(user_tick_functions));
1096 		BG(user_tick_functions) = NULL;
1097 	}
1098 
1099 	PHP_RSHUTDOWN(user_filters)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1100 	
1101 	return SUCCESS;
1102 }
1103 
1104 
1105 PHP_MINFO_FUNCTION(basic)
1106 {
1107 	php_info_print_table_start();
1108 	PHP_MINFO(regex)(ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU);
1109 	PHP_MINFO(dl)(ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU);
1110 	PHP_MINFO(mail)(ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU);
1111 	php_info_print_table_end();
1112 	PHP_MINFO(assert)(ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU);
1113 }
1114 
1115 
1116 /* {{{ proto mixed constant(string const_name)
1117    Given the name of a constant this function will return the constants associated value */
1118 PHP_FUNCTION(constant)
1119 {
1120 	zval **const_name;
1121 
1122 	if (ZEND_NUM_ARGS() != 1 ||
1123 		zend_get_parameters_ex(1, &const_name) == FAILURE) {
1124 		WRONG_PARAM_COUNT;
1125 	}
1126 	convert_to_string_ex(const_name);
1127 
1128 	if (!zend_get_constant(Z_STRVAL_PP(const_name), Z_STRLEN_PP(const_name), return_value TSRMLS_CC)) {
1129 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't find constant %s", Z_STRVAL_PP(const_name));
1130 		RETURN_NULL();
1131 	}
1132 }
1133 /* }}} */
1134 
1135 #ifdef HAVE_INET_NTOP
1136 /* {{{ proto string inet_ntop(string in_addr)
1137    Converts a packed inet address to a human readable IP address string */
1138 PHP_NAMED_FUNCTION(php_inet_ntop)
1139 {
1140 	char *address;
1141 	int address_len, af = AF_INET;
1142 	char buffer[40];
1143 
1144 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &address, &address_len) == FAILURE) {
1145 		RETURN_FALSE;
1146 	}
1147 
1148 #ifdef HAVE_IPV6
1149 	if (address_len == 16) {
1150 		af = AF_INET6;
1151 	} else
1152 #endif
1153 	if (address_len != 4) {
1154 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid in_addr value");
1155 		RETURN_FALSE;
1156 	}
1157 
1158 	if (!inet_ntop(af, address, buffer, sizeof(buffer))) {
1159 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "An unknown error occured");
1160 		RETURN_FALSE;
1161 	}
1162 
1163 	RETURN_STRING(buffer, 1);
1164 }
1165 /* }}} */
1166 #endif /* HAVE_INET_NTOP */
1167 
1168 #ifdef HAVE_INET_PTON
1169 /* {{{ proto string inet_pton(string ip_address)
1170    Converts a human readable IP address to a packed binary string */
1171 PHP_NAMED_FUNCTION(php_inet_pton)
1172 {
1173 	int ret, af = AF_INET;
1174 	char *address;
1175 	int address_len;
1176 	char buffer[17];
1177 
1178 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &address, &address_len) == FAILURE) {
1179 		RETURN_FALSE;
1180 	}
1181 
1182 	memset(buffer, 0, sizeof(buffer));
1183 
1184 #ifdef HAVE_IPV6
1185 	if (strchr(address, ':')) {
1186 		af = AF_INET6;
1187 	} else 
1188 #endif
1189 	if (!strchr(address, '.')) {
1190 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unrecognized address %s", address);
1191 		RETURN_FALSE;
1192 	}
1193 
1194 	ret = inet_pton(af, address, buffer);
1195 
1196 	if (ret <= 0) {
1197 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unrecognized address %s", address);
1198 		RETURN_FALSE;
1199 	}
1200 
1201 	RETURN_STRINGL(buffer, af == AF_INET ? 4 : 16, 1);
1202 }
1203 /* }}} */
1204 #endif /* HAVE_INET_PTON */
1205 
1206 
1207 
1208 /* {{{ proto int ip2long(string ip_address)
1209    Converts a string containing an (IPv4) Internet Protocol dotted address into a proper address */
1210 PHP_FUNCTION(ip2long)
1211 {
1212 	zval **str;
1213 	unsigned long int ip;
1214 
1215 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) {
1216 		WRONG_PARAM_COUNT;
1217 	}
1218 
1219 	convert_to_string_ex(str);
1220 
1221 	if (Z_STRLEN_PP(str) == 0 || (ip = inet_addr(Z_STRVAL_PP(str))) == INADDR_NONE) {
1222 		/* the only special case when we should return -1 ourselves,
1223 		 * because inet_addr() considers it wrong.
1224 		 */
1225 		if (!memcmp(Z_STRVAL_PP(str), "255.255.255.255", Z_STRLEN_PP(str))) {
1226 			RETURN_LONG(-1);
1227 		}
1228 		
1229 		RETURN_FALSE;
1230 	}
1231 
1232 	RETURN_LONG(ntohl(ip));
1233 }
1234 /* }}} */
1235 
1236 /* {{{ proto string long2ip(int proper_address)
1237    Converts an (IPv4) Internet network address into a string in Internet standard dotted format */
1238 PHP_FUNCTION(long2ip)
1239 {
1240 	zval **num;
1241 	unsigned long n;
1242 	struct in_addr myaddr;
1243 
1244 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
1245 		WRONG_PARAM_COUNT;
1246 	}
1247 	convert_to_string_ex(num);
1248 	
1249 	n = strtoul(Z_STRVAL_PP(num), NULL, 0);
1250 
1251 	myaddr.s_addr = htonl(n);
1252 	RETURN_STRING(inet_ntoa(myaddr), 1);
1253 }
1254 /* }}} */
1255 
1256 
1257 /********************
1258  * System Functions *
1259  ********************/
1260 
1261 /* {{{ proto string getenv(string varname)
1262    Get the value of an environment variable */
1263 PHP_FUNCTION(getenv)
1264 {
1265 	char *ptr, *str;
1266 	int str_len;
1267 
1268 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
1269 		RETURN_FALSE;
1270 	}
1271 	ptr = sapi_getenv(str, str_len TSRMLS_CC);
1272 	if (! ptr) {
1273 		ptr = getenv(str);
1274 	}
1275 	if (ptr) {
1276 		RETURN_STRING(ptr, 1);
1277 	}
1278 	RETURN_FALSE;
1279 }
1280 /* }}} */
1281 
1282 #ifdef HAVE_PUTENV
1283 /* {{{ proto bool putenv(string setting)
1284    Set the value of an environment variable */
1285 PHP_FUNCTION(putenv)
1286 {
1287 	zval **str;
1288 
1289 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) {
1290 		WRONG_PARAM_COUNT;
1291 	}
1292 	convert_to_string_ex(str);
1293 
1294 	if (Z_STRVAL_PP(str) && *(Z_STRVAL_PP(str))) {
1295 		char *p, **env;
1296 		putenv_entry pe;
1297 
1298 		pe.putenv_string = estrndup(Z_STRVAL_PP(str), Z_STRLEN_PP(str));
1299 		pe.key = estrndup(Z_STRVAL_PP(str), Z_STRLEN_PP(str));
1300 		if ((p = strchr(pe.key, '='))) {	/* nullify the '=' if there is one */
1301 			*p = '\0';
1302 		}
1303 		pe.key_len = strlen(pe.key);
1304 
1305 		if (PG(safe_mode)) {
1306 			/* Check the protected list */
1307 			if (zend_hash_exists(&BG(sm_protected_env_vars), pe.key, pe.key_len)) {
1308 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Safe Mode warning: Cannot override protected environment variable '%s'", pe.key);
1309 				efree(pe.putenv_string);
1310 				efree(pe.key);
1311 				RETURN_FALSE;
1312 			}
1313 
1314 			/* Check the allowed list */
1315 			if (BG(sm_allowed_env_vars) && *BG(sm_allowed_env_vars)) {
1316 				char *allowed_env_vars = estrdup(BG(sm_allowed_env_vars));
1317 				char *allowed_prefix = strtok(allowed_env_vars, ", ");
1318 				zend_bool allowed = 0;
1319 
1320 				while (allowed_prefix) {
1321 					if (!strncmp(allowed_prefix, pe.key, strlen(allowed_prefix))) {
1322 						allowed = 1;
1323 						break;
1324 					}
1325 					allowed_prefix = strtok(NULL, ", ");
1326 				}
1327 				efree(allowed_env_vars);
1328 				if (!allowed) {
1329 					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Safe Mode warning: Cannot set environment variable '%s' - it's not in the allowed list", pe.key);
1330 					efree(pe.putenv_string);
1331 					efree(pe.key);
1332 					RETURN_FALSE;
1333 				}
1334 			}
1335 		}
1336 
1337 		zend_hash_del(&BG(putenv_ht), pe.key, pe.key_len+1);
1338 
1339 		/* find previous value */
1340 		pe.previous_value = NULL;
1341 		for (env = environ; env != NULL && *env != NULL; env++) {
1342 			if (!strncmp(*env, pe.key, pe.key_len) && (*env)[pe.key_len] == '=') {	/* found it */
1343 				pe.previous_value = *env;
1344 				break;
1345 			}
1346 		}
1347 
1348 #if _MSC_VER >= 1300
1349 		/* VS.Net has a bug in putenv() when setting a variable that
1350 		 * is already set; if the SetEnvironmentVariable() API call
1351 		 * fails, the Crt will double free() a string.
1352 		 * We try to avoid this by setting our own value first */
1353 		SetEnvironmentVariable(pe.key, "bugbug");
1354 #endif
1355 		
1356 		if (putenv(pe.putenv_string) == 0) {	/* success */
1357 			zend_hash_add(&BG(putenv_ht), pe.key, pe.key_len+1, (void **) &pe, sizeof(putenv_entry), NULL);
1358 #ifdef HAVE_TZSET
1359 			if (!strncmp(pe.key, "TZ", pe.key_len)) {
1360 				tzset();
1361 			}
1362 #endif
1363 			RETURN_TRUE;
1364 		} else {
1365 			efree(pe.putenv_string);
1366 			efree(pe.key);
1367 			RETURN_FALSE;
1368 		}
1369 	}
1370 
1371 	php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter syntax.");
1372 	RETURN_FALSE;
1373 }
1374 /* }}} */
1375 #endif
1376 
1377 #ifdef HAVE_GETOPT
1378 /* {{{ free_argv
1379    Free the memory allocated to an argv array. */
1380 static void free_argv(char **argv, int argc)
1381 {
1382 	int i;
1383 
1384 	if (argv) {
1385 		for (i = 0; i < argc; i++) {
1386 			if (argv[i]) {
1387 				efree(argv[i]);
1388 			}
1389 		}
1390 		efree(argv);
1391 	}
1392 }
1393 /* }}} */
1394 
1395 #ifdef HARTMUT_0
1396 /* {{{ free_longopts
1397    Free the memory allocated to an longopt array. */
1398 static void free_longopts(struct option *longopts)
1399 {
1400 	struct option *p;
1401 
1402 	if(longopts) {
1403 		for(p=longopts; p->name; p++) {
1404 			efree((char *)(p->name));
1405 		}
1406 		
1407 		efree(longopts);
1408 	}
1409 }
1410 /* }}} */
1411 #endif
1412 
1413 /* {{{ proto array getopt(string options [, array longopts])
1414    Get options from the command line argument list */
1415 PHP_FUNCTION(getopt)
1416 {
1417 	char *options = NULL, **argv = NULL;
1418 	char opt[2] = { '\0' };
1419 	char *optname;
1420 	int argc = 0, options_len = 0, o;
1421 	zval *val, **args = NULL, *p_longopts = NULL;
1422 	int optname_len = 0;
1423 #ifdef HARTMUT_0
1424 	struct option *longopts = NULL;
1425 	int longindex = 0;
1426 #endif
1427 
1428 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a",
1429 							  &options, &options_len, &p_longopts) == FAILURE) {
1430 		RETURN_FALSE;
1431 	}
1432 
1433 	/*
1434 	 * Get argv from the global symbol table.  We calculate argc ourselves
1435 	 * in order to be on the safe side, even though it is also available
1436 	 * from the symbol table.
1437 	 */
1438 	if (zend_hash_find(HASH_OF(PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv"), (void **) &args) != FAILURE ||
1439 		zend_hash_find(&EG(symbol_table), "argv", sizeof("argv"), (void **) &args) != FAILURE) {
1440 		int pos = 0;
1441 		zval **arg;
1442 
1443 		argc = zend_hash_num_elements(Z_ARRVAL_PP(args));
1444 
1445 		/* 
1446 		 * Attempt to allocate enough memory to hold all of the arguments
1447 		 * and a trailing NULL 
1448 		 */
1449 		argv = (char **) safe_emalloc(sizeof(char *), (argc + 1), 0);
1450 
1451 		/* Reset the array indexes. */
1452 		zend_hash_internal_pointer_reset(Z_ARRVAL_PP(args));
1453 
1454 		/* Iterate over the hash to construct the argv array. */
1455 		while (zend_hash_get_current_data(Z_ARRVAL_PP(args),
1456 										  (void **)&arg) == SUCCESS) {
1457 			argv[pos++] = estrdup(Z_STRVAL_PP(arg));
1458 			zend_hash_move_forward(Z_ARRVAL_PP(args));
1459 		}
1460 
1461 		/* 
1462 		 * The C Standard requires argv[argc] to be NULL - this might
1463 		 * keep some getopt implementations happy. 
1464 		 */
1465 		argv[argc] = NULL;
1466 	} else {
1467 		/* Return false if we can't find argv. */
1468 		RETURN_FALSE;
1469 	}
1470 
1471 	if(p_longopts) {
1472 #ifdef HARTMUT_0
1473 		int len, c = zend_hash_num_elements(Z_ARRVAL_P(p_longopts));
1474 		struct option *p;
1475 		zval **arg;
1476 		char *name;
1477 
1478 		longopts = (struct option *)ecalloc(c+1, sizeof(struct option));
1479 
1480 		if(!longopts) RETURN_FALSE;
1481 
1482 		/* Reset the array indexes. */
1483 		zend_hash_internal_pointer_reset(Z_ARRVAL_P(p_longopts));
1484 		p = longopts;
1485 
1486 		/* Iterate over the hash to construct the argv array. */
1487 		while (zend_hash_get_current_data(Z_ARRVAL_P(p_longopts),
1488 										  (void **)&arg) == SUCCESS) {
1489 
1490 			p->has_arg = 0;
1491 			name = estrdup(Z_STRVAL_PP(arg));
1492 			len = strlen(name);
1493 			if((len > 0) && (name[len-1] == ':')) {
1494 				p->has_arg++;
1495 				name[len-1] = '\0';
1496 				if((len > 1) && (name[len-2] == ':')) {
1497 					p->has_arg++;
1498 					name[len-2] = '\0';
1499 				}
1500 			}
1501 				
1502 			p->name = name; 
1503 			p->flag = NULL;
1504 			p->val = 0;
1505 
1506 			zend_hash_move_forward(Z_ARRVAL_P(p_longopts));
1507 			p++;
1508 		}
1509 #else
1510 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "No support for long options in this build");
1511 #endif	
1512 	}
1513 
1514 	/* Initialize the return value as an array. */
1515 	array_init(return_value);
1516 
1517 	/* Disable getopt()'s error messages. */
1518 	opterr = 0;
1519 
1520 	/* Force reinitialization of getopt() (via optind reset) on every call. */
1521 	optind = 0;
1522 
1523 	/* Invoke getopt(3) on the argument array. */
1524 #ifdef HARTMUT_0
1525 	while ((o = getopt_long(argc, argv, options, longopts, &longindex)) != -1) {
1526 #else
1527 	while ((o = getopt(argc, argv, options)) != -1) {
1528 #endif
1529 		/* Skip unknown arguments. */
1530 		if (o == '?') {
1531 			continue;
1532 		}
1533 
1534 		/* Prepare the option character and the argument string. */
1535 		if(o == 0) {
1536 #ifdef HARTMUT_0
1537 			optname = (char *)longopts[longindex].name;
1538 #else                      
1539 			/* o == 0 shall never happen so this only fixes a compiler warning */
1540 			optname = NULL;
1541 #endif
1542 		} else {		
1543 			if(o == 1) o = '-';
1544 			opt[0] = o;
1545 			optname = opt;
1546 		}
1547 
1548 		MAKE_STD_ZVAL(val);
1549 		if (optarg != NULL) {
1550 			ZVAL_STRING(val, optarg, 1);
1551 		} else {
1552 			ZVAL_FALSE(val);
1553 		}
1554 
1555 		/* Add this option / argument pair to the result hash. */
1556 		optname_len = strlen(optname);
1557 		if (!(optname_len > 1 && optname[0] == '0') && is_numeric_string(optname, optname_len, NULL, NULL, 0) == IS_LONG) {
1558 			/* numeric string */
1559 			int optname_int = atoi(optname);
1560 			if(zend_hash_index_find(HASH_OF(return_value), optname_int, (void **)&args) != FAILURE) {
1561 				if(Z_TYPE_PP(args) != IS_ARRAY) {
1562 					convert_to_array_ex(args);
1563 				} 
1564 				zend_hash_next_index_insert(HASH_OF(*args),  (void *)&val, sizeof(zval *), NULL);
1565 			} else {
1566 				zend_hash_index_update(HASH_OF(return_value), optname_int, &val, sizeof(zval *), NULL);
1567 			}
1568 		} else {
1569 			/* other strings */
1570 			if(zend_hash_find(HASH_OF(return_value), optname, strlen(optname)+1, (void **)&args) != FAILURE) {
1571 				if(Z_TYPE_PP(args) != IS_ARRAY) {
1572 					convert_to_array_ex(args);
1573 				} 
1574 				zend_hash_next_index_insert(HASH_OF(*args),  (void *)&val, sizeof(zval *), NULL);
1575 			} else {
1576 				zend_hash_add(HASH_OF(return_value), optname, strlen(optname)+1, (void *)&val, sizeof(zval *), NULL);
1577 			}
1578 		}
1579 	}
1580 
1581 	free_argv(argv, argc);
1582 #ifdef HARTMUT_0
1583 	free_longopts(longopts);
1584 #endif
1585 }
1586 /* }}} */
1587 #endif
1588 
1589 /* {{{ proto void flush(void)
1590    Flush the output buffer */
1591 PHP_FUNCTION(flush)
1592 {
1593 	sapi_flush(TSRMLS_C);
1594 }
1595 /* }}} */
1596 
1597 /* {{{ proto void sleep(int seconds)
1598    Delay for a given number of seconds */
1599 PHP_FUNCTION(sleep)
1600 {
1601 	zval **num;
1602 
1603 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
1604 		WRONG_PARAM_COUNT;
1605 	}
1606 
1607 	convert_to_long_ex(num);
1608 #ifdef PHP_SLEEP_NON_VOID
1609 	RETURN_LONG(php_sleep(Z_LVAL_PP(num)));
1610 #else
1611 	php_sleep(Z_LVAL_PP(num));
1612 #endif
1613 
1614 }
1615 /* }}} */
1616 
1617 /* {{{ proto void usleep(int micro_seconds)
1618    Delay for a given number of micro seconds */
1619 PHP_FUNCTION(usleep)
1620 {
1621 #if HAVE_USLEEP
1622 	zval **num;
1623 
1624 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) {
1625 		WRONG_PARAM_COUNT;
1626 	}
1627 	convert_to_long_ex(num);
1628 	usleep(Z_LVAL_PP(num));
1629 #endif
1630 }
1631 /* }}} */
1632 
1633 #if HAVE_NANOSLEEP
1634 /* {{{ proto mixed time_nanosleep(long seconds, long nanoseconds)
1635    Delay for a number of seconds and nano seconds */
1636 PHP_FUNCTION(time_nanosleep)
1637 {
1638 	long tv_sec, tv_nsec;
1639 	struct timespec php_req, php_rem;
1640 	
1641 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &tv_sec, &tv_nsec)) {
1642 		WRONG_PARAM_COUNT;
1643 	}
1644 
1645 	php_req.tv_sec = (time_t) tv_sec;
1646 	php_req.tv_nsec = tv_nsec;
1647 	if (!nanosleep(&php_req, &php_rem)) {
1648 		RETURN_TRUE;
1649 	} else if (errno == EINTR) {
1650 		array_init(return_value);
1651 		add_assoc_long_ex(return_value, "seconds", sizeof("seconds"), php_rem.tv_sec);
1652 		add_assoc_long_ex(return_value, "nanoseconds", sizeof("nanoseconds"), php_rem.tv_nsec);
1653 		return;
1654 	} else if (errno == EINVAL) {
1655 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "nanoseconds was not in the range 0 to 999 999 999 or seconds was negative");
1656 	}
1657 
1658 	RETURN_FALSE;
1659 }
1660 /* }}} */
1661 
1662 /* {{{ proto mixed time_sleep_until(float timestamp)
1663    Make the script sleep until the specified time */
1664 PHP_FUNCTION(time_sleep_until)
1665 {
1666 	double d_ts, c_ts;
1667 	struct timeval tm;
1668 	struct timespec php_req, php_rem;
1669 	
1670 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &d_ts)) {
1671 		WRONG_PARAM_COUNT;
1672 	}
1673 
1674 	if (gettimeofday((struct timeval *) &tm, NULL) != 0) {
1675 		RETURN_FALSE;
1676 	}
1677 
1678 	c_ts = (double)(d_ts - tm.tv_sec - tm.tv_usec / 1000000.00);
1679 	if (c_ts < 0) {
1680 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sleep until to time is less then current time.");
1681 		RETURN_FALSE;
1682 	}
1683 
1684 	php_req.tv_sec = (time_t) c_ts;
1685 	if (php_req.tv_sec > c_ts) { /* rounding up occurred */
1686 		php_req.tv_sec--;
1687 	}
1688 	/* 1sec = 1000000000 nanoseconds */
1689 	php_req.tv_nsec = (long) ((c_ts - php_req.tv_sec) * 1000000000.00);
1690 
1691 	while (nanosleep(&php_req, &php_rem)) {
1692 		if (errno == EINTR) {
1693 			php_req.tv_sec = php_rem.tv_sec;
1694 			php_req.tv_nsec = php_rem.tv_nsec;
1695 		} else {
1696 			RETURN_FALSE;
1697 		}
1698 	}
1699 
1700 	RETURN_TRUE;
1701 }
1702 /* }}} */
1703 #endif
1704 
1705 /* {{{ proto string get_current_user(void)
1706    Get the name of the owner of the current PHP script */
1707 PHP_FUNCTION(get_current_user)
1708 {
1709 	if (ZEND_NUM_ARGS() != 0) {
1710 		WRONG_PARAM_COUNT;
1711 	}
1712 
1713 	RETURN_STRING(php_get_current_user(), 1);
1714 }
1715 /* }}} */
1716 
1717 /* {{{ proto string get_cfg_var(string option_name)
1718    Get the value of a PHP configuration option */
1719 PHP_FUNCTION(get_cfg_var)
1720 {
1721 	zval **varname;
1722 	char *value;
1723 
1724 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &varname) == FAILURE) {
1725 		WRONG_PARAM_COUNT;
1726 	}
1727 
1728 	convert_to_string_ex(varname);
1729 
1730 	if (cfg_get_string(Z_STRVAL_PP(varname), &value) == FAILURE) {
1731 		RETURN_FALSE;
1732 	}
1733 	RETURN_STRING(value, 1);
1734 }
1735 /* }}} */
1736 
1737 /* {{{ proto bool set_magic_quotes_runtime(int new_setting)
1738    Set the current active configuration setting of magic_quotes_runtime and return previous */
1739 PHP_FUNCTION(set_magic_quotes_runtime)
1740 {
1741 	zval **new_setting;
1742 
1743 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &new_setting) == FAILURE) {
1744 		RETURN_FALSE;
1745 	}
1746 	convert_to_boolean_ex(new_setting);
1747 
1748 	PG(magic_quotes_runtime) = (zend_bool) Z_LVAL_PP(new_setting);
1749 	RETURN_TRUE;
1750 }
1751 /* }}} */
1752 
1753 /* {{{ proto int get_magic_quotes_runtime(void)
1754    Get the current active configuration setting of magic_quotes_runtime */
1755 PHP_FUNCTION(get_magic_quotes_runtime)
1756 {
1757 	RETURN_LONG(PG(magic_quotes_runtime));
1758 }
1759 
1760 /* }}} */
1761 
1762 /* {{{ proto int get_magic_quotes_gpc(void)
1763    Get the current active configuration setting of magic_quotes_gpc */
1764 PHP_FUNCTION(get_magic_quotes_gpc)
1765 {
1766 	RETURN_LONG(PG(magic_quotes_gpc));
1767 }
1768 /* }}} */
1769 
1770 /*
1771 	1st arg = error message
1772 	2nd arg = error option
1773 	3rd arg = optional parameters (email address or tcp address)
1774 	4th arg = used for additional headers if email
1775 
1776 error options:
1777     0 = send to php_error_log (uses syslog or file depending on ini setting)
1778 	1 = send via email to 3rd parameter 4th option = additional headers
1779 	2 = send via tcp/ip to 3rd parameter (name or ip:port)
1780 	3 = save to file in 3rd parameter
1781 */
1782 
1783 /* {{{ proto bool error_log(string message [, int message_type [, string destination [, string extra_headers]]])
1784    Send an error message somewhere */
1785 PHP_FUNCTION(error_log)
1786 {
1787 	zval **string, **erropt = NULL, **option = NULL, **emailhead = NULL;
1788 	int opt_err = 0;
1789 	char *message, *opt = NULL, *headers = NULL;
1790 
1791 	switch (ZEND_NUM_ARGS()) {
1792 		case 1:
1793 			if (zend_get_parameters_ex(1, &string) == FAILURE) {
1794 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument 1 invalid");
1795 				RETURN_FALSE;
1796 			}
1797 			break;
1798 
1799 		case 2:
1800 			if (zend_get_parameters_ex(2, &string, &erropt) == FAILURE) {
1801 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments");
1802 				RETURN_FALSE;
1803 			}
1804 			convert_to_long_ex(erropt);
1805 			opt_err = Z_LVAL_PP(erropt);
1806 			break;
1807 	
1808 		case 3:
1809 			if (zend_get_parameters_ex(3, &string, &erropt, &option) == FAILURE) {
1810 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments");
1811 				RETURN_FALSE;
1812 			}
1813 			convert_to_long_ex(erropt);
1814 			opt_err = Z_LVAL_PP(erropt);
1815 			convert_to_string_ex(option);
1816 			opt = Z_STRVAL_PP(option);
1817 			break;
1818 		
1819 		case 4:
1820 			if (zend_get_parameters_ex (4, &string, &erropt, &option, &emailhead) == FAILURE) {
1821 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments");
1822 				RETURN_FALSE;
1823 			}
1824 			break;
1825 	
1826 		default:
1827 			WRONG_PARAM_COUNT;
1828 	}
1829 
1830 	convert_to_string_ex(string);
1831 	message = Z_STRVAL_PP(string);
1832 
1833 	if (erropt != NULL) {
1834 		convert_to_long_ex(erropt);
1835 		opt_err = Z_LVAL_PP(erropt);
1836 	}
1837 
1838 	if (option != NULL) {
1839 		convert_to_string_ex(option);
1840 		opt = Z_STRVAL_PP(option);
1841 	}
1842 
1843 	if (emailhead != NULL) {
1844 		convert_to_string_ex(emailhead);
1845 		headers = Z_STRVAL_PP(emailhead);
1846 	}
1847 
1848 	if (_php_error_log(opt_err, message, opt, headers TSRMLS_CC) == FAILURE) {
1849 		RETURN_FALSE;
1850 	}
1851 	
1852 	RETURN_TRUE;
1853 }
1854 /* }}} */
1855 
1856 
1857 PHPAPI int _php_error_log(int opt_err, char *message, char *opt, char *headers TSRMLS_DC)
1858 {
1859 	php_stream *stream = NULL;
1860 
1861 	switch (opt_err) {
1862 
1863 		case 1:		/*send an email */
1864 			{
1865 #if HAVE_SENDMAIL
1866 				if (!php_mail(opt, "PHP error_log message", message, headers, NULL TSRMLS_CC)) {
1867 					return FAILURE;
1868 				}
1869 #else
1870 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Mail option not available!");
1871 				return FAILURE;
1872 #endif
1873 			}
1874 			break;
1875 
1876 		case 2:		/*send to an address */
1877 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "TCP/IP option not available!");
1878 			return FAILURE;
1879 			break;
1880 
1881 		case 3:		/*save to a file */
1882 			stream = php_stream_open_wrapper(opt, "a", IGNORE_URL | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
1883 			if (!stream)
1884 				return FAILURE;
1885 			php_stream_write(stream, message, strlen(message));
1886 			php_stream_close(stream);
1887 			break;
1888 
1889 		default:
1890 			php_log_err(message TSRMLS_CC);
1891 			break;
1892 	}
1893 	return SUCCESS;
1894 }
1895 
1896 /* {{{ proto mixed call_user_func(string function_name [, mixed parmeter] [, mixed ...])
1897    Call a user function which is the first parameter */
1898 PHP_FUNCTION(call_user_func)
1899 {
1900 	zval ***params;
1901 	zval *retval_ptr;
1902 	char *name;
1903 	int argc = ZEND_NUM_ARGS();
1904 
1905 	if (argc < 1) {
1906 		WRONG_PARAM_COUNT;
1907 	}
1908 
1909 	params = safe_emalloc(sizeof(zval **), argc, 0);
1910 
1911 	if (zend_get_parameters_array_ex(1, params) == FAILURE) {
1912 		efree(params);
1913 		RETURN_FALSE;
1914 	}
1915 
1916 	if (Z_TYPE_PP(params[0]) != IS_STRING && Z_TYPE_PP(params[0]) != IS_ARRAY) {
1917 		SEPARATE_ZVAL(params[0]);
1918 		convert_to_string_ex(params[0]);
1919 	}
1920 
1921 	if (!zend_is_callable(*params[0], 0, &name)) {
1922 		php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "First argument is expected to be a valid callback");
1923 		efree(name);
1924 		efree(params);
1925 		RETURN_NULL();
1926 	}
1927 
1928 	if (zend_get_parameters_array_ex(argc, params) == FAILURE) {
1929 		efree(params);
1930 		RETURN_FALSE;
1931 	}
1932 
1933 	if (call_user_function_ex(EG(function_table), NULL, *params[0], &retval_ptr, argc-1, params+1, 0, NULL TSRMLS_CC) == SUCCESS) {
1934 		if (retval_ptr) {
1935 			COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
1936 		}
1937 	} else {
1938 		if (argc > 1) {
1939 			SEPARATE_ZVAL(params[1]);
1940 			convert_to_string_ex(params[1]);
1941 			if (argc > 2) {
1942 				SEPARATE_ZVAL(params[2]);
1943 				convert_to_string_ex(params[2]);
1944 				php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "Unable to call %s(%s,%s)", name, Z_STRVAL_PP(params[1]), Z_STRVAL_PP(params[2]));
1945 			} else {
1946 				php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "Unable to call %s(%s)", name, Z_STRVAL_PP(params[1]));
1947 			}
1948 		} else {
1949 			php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "Unable to call %s()", name);
1950 		}
1951 	}
1952 
1953 	efree(name);
1954 	efree(params);
1955 }
1956 /* }}} */
1957 
1958 /* {{{ proto mixed call_user_func_array(string function_name, array parameters)
1959    Call a user function which is the first parameter with the arguments contained in array */
1960 PHP_FUNCTION(call_user_func_array)
1961 {
1962 	zval ***func_params, **func, **params;
1963 	zval *retval_ptr;
1964 	HashTable *func_params_ht;
1965 	char *name;
1966 	int count;
1967 	int current = 0;
1968 
1969 	if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &func, &params) == FAILURE) {
1970 		WRONG_PARAM_COUNT;
1971 	}
1972 
1973 	SEPARATE_ZVAL(params);
1974 	convert_to_array_ex(params);
1975 
1976 	if (Z_TYPE_PP(func) != IS_STRING && Z_TYPE_PP(func) != IS_ARRAY) {
1977 		SEPARATE_ZVAL(func);
1978 		convert_to_string_ex(func);
1979 	}
1980 
1981 	if (!zend_is_callable(*func, 0, &name)) {
1982 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument is expected to be a valid callback, '%s' was given", name);
1983 		efree(name);
1984 		RETURN_NULL();
1985 	}
1986 
1987 	func_params_ht = Z_ARRVAL_PP(params);
1988 
1989 	count = zend_hash_num_elements(func_params_ht);
1990 	if (count) {
1991 		func_params = safe_emalloc(sizeof(zval **), count, 0);
1992 
1993 		for (zend_hash_internal_pointer_reset(func_params_ht);
1994 				zend_hash_get_current_data(func_params_ht, (void **) &func_params[current]) == SUCCESS;
1995 				zend_hash_move_forward(func_params_ht)
1996 			) {
1997 			current++;
1998 		}
1999 	} else {
2000 		func_params = NULL;
2001 	}
2002 
2003 	if (call_user_function_ex(EG(function_table), NULL, *func, &retval_ptr, count, func_params, 0, NULL TSRMLS_CC) == SUCCESS) {
2004 		if (retval_ptr) {
2005 			COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
2006 		}
2007 	} else {
2008 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s()", name);
2009 	}
2010 
2011 	efree(name);
2012 	if (func_params) {
2013 		efree(func_params);
2014 	}
2015 }
2016 /* }}} */
2017 
2018 #define _CUM_DEPREC "This function is deprecated, use the call_user_func variety with the array(&$obj, \"method\") syntax instead"
2019 
2020 /* {{{ proto mixed call_user_method(string method_name, mixed object [, mixed parameter] [, mixed ...])
2021    Call a user method on a specific object or class */
2022 PHP_FUNCTION(call_user_method)
2023 {
2024 	zval ***params;
2025 	zval *retval_ptr;
2026 	int arg_count = ZEND_NUM_ARGS();
2027 
2028 	php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s", _CUM_DEPREC);
2029 
2030 	if (arg_count < 2) {
2031 		WRONG_PARAM_COUNT;
2032 	}
2033 	params = (zval ***) safe_emalloc(sizeof(zval **), arg_count, 0);
2034 
2035 	if (zend_get_parameters_array_ex(arg_count, params) == FAILURE) {
2036 		efree(params);
2037 		RETURN_FALSE;
2038 	}
2039 	if (Z_TYPE_PP(params[1]) != IS_OBJECT && Z_TYPE_PP(params[1]) != IS_STRING) {
2040 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argument is not an object or class name");
2041 		efree(params);
2042 		RETURN_FALSE;
2043 	}
2044 
2045 	SEPARATE_ZVAL(params[0]);
2046 	convert_to_string(*params[0]);
2047 
2048 	if (call_user_function_ex(EG(function_table), params[1], *params[0], &retval_ptr, arg_count-2, params+2, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) {
2049 		COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
2050 	} else {
2051 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s()", Z_STRVAL_PP(params[0]));
2052 	}
2053 	efree(params);
2054 }
2055 /* }}} */
2056 
2057 /* {{{ proto mixed call_user_method_array(string method_name, mixed object, array params)
2058    Call a user method on a specific object or class using a parameter array */
2059 PHP_FUNCTION(call_user_method_array)
2060 {
2061 	zval **method_name,	**obj, **params, ***method_args = NULL, *retval_ptr;
2062 	HashTable *params_ar;
2063 	int num_elems, element = 0;
2064 
2065 	php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s", _CUM_DEPREC);
2066 
2067 	if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &method_name, &obj, &params) == FAILURE) {
2068 		WRONG_PARAM_COUNT;
2069 	}
2070 
2071 	if (Z_TYPE_PP(obj) != IS_OBJECT && Z_TYPE_PP(obj) != IS_STRING) {
2072 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argument is not an object or class name");
2073 		RETURN_FALSE;
2074 	}
2075 
2076 	SEPARATE_ZVAL(method_name);
2077 	SEPARATE_ZVAL(params);
2078 	convert_to_string_ex(method_name);
2079 	convert_to_array_ex(params);
2080 
2081 	params_ar = HASH_OF(*params);
2082 	num_elems = zend_hash_num_elements(params_ar);
2083 	method_args = (zval ***) safe_emalloc(sizeof(zval **), num_elems, 0);
2084 
2085 	for (zend_hash_internal_pointer_reset(params_ar);
2086 		 zend_hash_get_current_data(params_ar, (void **) &(method_args[element])) == SUCCESS;
2087 		 zend_hash_move_forward(params_ar)
2088 		) {
2089 		element++;
2090 	}
2091 	
2092 	if (call_user_function_ex(EG(function_table), obj, *method_name, &retval_ptr, num_elems, method_args, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) {
2093 		COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
2094 	} else {
2095 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s()", Z_STRVAL_PP(method_name));
2096 	}
2097 
2098 	efree(method_args);
2099 }
2100 /* }}} */
2101 
2102 
2103 void user_shutdown_function_dtor(php_shutdown_function_entry *shutdown_function_entry)
2104 {
2105 	int i;
2106 
2107 	for (i = 0; i < shutdown_function_entry->arg_count; i++) {
2108 		zval_ptr_dtor(&shutdown_function_entry->arguments[i]);
2109 	}
2110 	efree(shutdown_function_entry->arguments);
2111 }
2112 
2113 void user_tick_function_dtor(user_tick_function_entry *tick_function_entry)
2114 {
2115 	int i;
2116 
2117 	for (i = 0; i < tick_function_entry->arg_count; i++) {
2118 		zval_ptr_dtor(&tick_function_entry->arguments[i]);
2119 	}
2120 	efree(tick_function_entry->arguments);
2121 }
2122 
2123 static int user_shutdown_function_call(php_shutdown_function_entry *shutdown_function_entry TSRMLS_DC)
2124 {
2125 	zval retval;
2126 	char *function_name = NULL;
2127 
2128 	if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
2129 		php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
2130 	} else if (call_user_function(EG(function_table), NULL,
2131 								shutdown_function_entry->arguments[0],
2132 								&retval, 
2133 								shutdown_function_entry->arg_count - 1,
2134 								shutdown_function_entry->arguments + 1 
2135 								TSRMLS_CC ) == SUCCESS)
2136 	{
2137 		zval_dtor(&retval);
2138 	} 
2139 	if (function_name) {
2140 		efree(function_name);
2141 	}
2142 	return 0;
2143 }
2144 
2145 static void user_tick_function_call(user_tick_function_entry *tick_fe TSRMLS_DC)
2146 {
2147 	zval retval;
2148 	zval *function = tick_fe->arguments[0];
2149 	
2150 	/* Prevent reentrant calls to the same user ticks function */
2151 	if (! tick_fe->calling) {
2152 		tick_fe->calling = 1;
2153 
2154 		if (call_user_function(	EG(function_table), NULL, 
2155 								function, 
2156 								&retval,
2157 								tick_fe->arg_count - 1,
2158 								tick_fe->arguments+1
2159 								TSRMLS_CC) == SUCCESS) {
2160 			zval_dtor(&retval);
2161 
2162 		} else {
2163 			zval **obj, **method;
2164 
2165 			if (Z_TYPE_P(function) == IS_STRING) {
2166 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s() - function does not exist", Z_STRVAL_P(function));
2167 			} else if (	Z_TYPE_P(function) == IS_ARRAY 
2168 						&& zend_hash_index_find(Z_ARRVAL_P(function), 0, (void **) &obj) == SUCCESS
2169 						&& zend_hash_index_find(Z_ARRVAL_P(function), 1, (void **) &method) == SUCCESS
2170 						&& Z_TYPE_PP(obj) == IS_OBJECT
2171 						&& Z_TYPE_PP(method) == IS_STRING ) {
2172 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s::%s() - function does not exist", Z_OBJCE_PP(obj)->name, Z_STRVAL_PP(method));
2173 			} else {
2174 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call tick function");
2175 			}
2176 		}
2177 	
2178 		tick_fe->calling = 0;
2179 	}
2180 }
2181 
2182 static void run_user_tick_functions(int tick_count)
2183 {
2184 	TSRMLS_FETCH();
2185 
2186 	zend_llist_apply(BG(user_tick_functions), (llist_apply_func_t) user_tick_function_call TSRMLS_CC);
2187 }
2188 
2189 static int user_tick_function_compare(user_tick_function_entry * tick_fe1, user_tick_function_entry * tick_fe2)
2190 {
2191 	zval *func1 = tick_fe1->arguments[0];
2192 	zval *func2 = tick_fe2->arguments[0];
2193 	TSRMLS_FETCH();
2194 
2195 	if (Z_TYPE_P(func1) == IS_STRING && Z_TYPE_P(func2) == IS_STRING) {
2196 		return (zend_binary_zval_strcmp(func1, func2) == 0);
2197 	} else if (Z_TYPE_P(func1) == IS_ARRAY && Z_TYPE_P(func2) == IS_ARRAY) {
2198 		zval result;
2199 		zend_compare_arrays(&result, func1, func2 TSRMLS_CC);
2200 		return (Z_LVAL(result) == 0);
2201 	} else {
2202 		return 0;
2203 	}
2204 }
2205 
2206 void php_call_shutdown_functions(TSRMLS_D)
2207 {
2208 	if (BG(user_shutdown_function_names))
2209 		zend_try {
2210 			zend_hash_apply(BG(user_shutdown_function_names), (apply_func_t) user_shutdown_function_call TSRMLS_CC);
2211 			memcpy(&EG(bailout), &orig_bailout, sizeof(jmp_buf));
2212 			php_free_shutdown_functions(TSRMLS_C);
2213 		}
2214 		zend_end_try();
2215 }
2216 
2217 void php_free_shutdown_functions(TSRMLS_D)
2218 {
2219 	if (BG(user_shutdown_function_names))
2220 		zend_try {
2221 			zend_hash_destroy(BG(user_shutdown_function_names));
2222 			FREE_HASHTABLE(BG(user_shutdown_function_names));
2223 			BG(user_shutdown_function_names) = NULL;
2224 		}
2225 		zend_end_try();
2226 }
2227 
2228 /* {{{ proto void register_shutdown_function(string function_name)
2229    Register a user-level function to be called on request termination */
2230 PHP_FUNCTION(register_shutdown_function)
2231 {
2232 	php_shutdown_function_entry shutdown_function_entry;
2233 	char *function_name = NULL;
2234 	int i;
2235 
2236 	shutdown_function_entry.arg_count = ZEND_NUM_ARGS();
2237 
2238 	if (shutdown_function_entry.arg_count < 1) {
2239 		WRONG_PARAM_COUNT;
2240 	}
2241 
2242 	shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0);
2243 
2244 	if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
2245 		RETURN_FALSE;
2246 	}
2247 	
2248 	/* Prevent entering of anything but valid callback (syntax check only!) */
2249 	if (!zend_is_callable(shutdown_function_entry.arguments[0], 0, &function_name)) {
2250 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid shutdown callback '%s' passed", function_name);
2251 		efree(shutdown_function_entry.arguments);
2252 		RETVAL_FALSE;
2253 	} else {
2254 		if (!BG(user_shutdown_function_names)) {
2255 			ALLOC_HASHTABLE(BG(user_shutdown_function_names));
2256 			zend_hash_init(BG(user_shutdown_function_names), 0, NULL, (void (*)(void *)) user_shutdown_function_dtor, 0);
2257 		}
2258 
2259 		for (i = 0; i < shutdown_function_entry.arg_count; i++) {
2260 			shutdown_function_entry.arguments[i]->refcount++;
2261 		}
2262 		zend_hash_next_index_insert(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL);
2263 	}
2264 	if (function_name) {
2265 		efree(function_name);
2266 	}
2267 }
2268 /* }}} */
2269 
2270 
2271 ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highlighter_ini)
2272 {
2273 	syntax_highlighter_ini->highlight_comment = INI_STR("highlight.comment");
2274 	syntax_highlighter_ini->highlight_default = INI_STR("highlight.default");
2275 	syntax_highlighter_ini->highlight_html    = INI_STR("highlight.html");
2276 	syntax_highlighter_ini->highlight_keyword = INI_STR("highlight.keyword");
2277 	syntax_highlighter_ini->highlight_string  = INI_STR("highlight.string");
2278 }
2279 
2280 /* {{{ proto bool highlight_file(string file_name [, bool return] )
2281    Syntax highlight a source file */
2282 PHP_FUNCTION(highlight_file)
2283 {
2284 	zval *filename;
2285 	zend_syntax_highlighter_ini syntax_highlighter_ini;
2286 	zend_bool i = 0;
2287 
2288 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &filename, &i) == FAILURE) {
2289 		RETURN_FALSE;
2290 	}
2291 	convert_to_string(filename);
2292 
2293 	if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_P(filename), NULL, CHECKUID_ALLOW_ONLY_FILE))) {
2294 		RETURN_FALSE;
2295 	}
2296 
2297 	if (php_check_open_basedir(Z_STRVAL_P(filename) TSRMLS_CC)) {
2298 		RETURN_FALSE;
2299 	}
2300 
2301 	if (i) {
2302 		php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC);
2303 	}
2304 
2305 	php_get_highlight_struct(&syntax_highlighter_ini);
2306 
2307 	if (highlight_file(Z_STRVAL_P(filename), &syntax_highlighter_ini TSRMLS_CC) == FAILURE) {
2308 		RETURN_FALSE;
2309 	}
2310 
2311 	if (i) {
2312 		php_ob_get_buffer (return_value TSRMLS_CC);
2313 		php_end_ob_buffer (0, 0 TSRMLS_CC);
2314 	} else {
2315 		RETURN_TRUE;
2316 	}
2317 }
2318 /* }}} */
2319 
2320 /* {{{ proto string php_strip_whitespace(string file_name)
2321    Return source with stripped comments and whitespace */
2322 PHP_FUNCTION(php_strip_whitespace)
2323 {
2324 	char *filename;
2325 	int filename_len;
2326 	zend_lex_state original_lex_state;
2327 	zend_file_handle file_handle = {0};
2328 
2329 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
2330 		RETURN_FALSE;
2331 	}
2332 
2333 	php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC);
2334 
2335 	file_handle.type = ZEND_HANDLE_FILENAME;
2336 	file_handle.filename = filename;
2337 	file_handle.free_filename = 0;
2338 	file_handle.opened_path = NULL;
2339 	zend_save_lexical_state(&original_lex_state TSRMLS_CC);
2340 	if (open_file_for_scanning(&file_handle TSRMLS_CC)==FAILURE) {
2341 		RETURN_EMPTY_STRING();
2342 	}
2343 
2344 	zend_strip(TSRMLS_C);
2345 	
2346 	zend_destroy_file_handle(&file_handle TSRMLS_CC);
2347 	zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
2348 
2349 	php_ob_get_buffer(return_value TSRMLS_CC);
2350 	php_end_ob_buffer(0, 0 TSRMLS_CC);
2351 
2352 	return;
2353 }
2354 /* }}} */
2355 
2356 /* {{{ proto bool highlight_string(string string [, bool return] )
2357    Syntax highlight a string or optionally return it */
2358 PHP_FUNCTION(highlight_string)
2359 {
2360 	zval *expr;
2361 	zend_syntax_highlighter_ini syntax_highlighter_ini;
2362 	char *hicompiled_string_description;
2363 	zend_bool  i = 0;
2364 	int old_error_reporting = EG(error_reporting);
2365 
2366 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &expr, &i) == FAILURE) {
2367 		RETURN_FALSE;
2368 	}
2369 	convert_to_string(expr);
2370 
2371 	if (i) {
2372 		php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC);
2373 	}
2374 
2375 	EG(error_reporting) = E_ERROR;
2376 
2377 	php_get_highlight_struct(&syntax_highlighter_ini);
2378 
2379 	hicompiled_string_description = zend_make_compiled_string_description("highlighted code" TSRMLS_CC);
2380 
2381 	if (highlight_string(expr, &syntax_highlighter_ini, hicompiled_string_description TSRMLS_CC) == FAILURE) {
2382 		efree(hicompiled_string_description);
2383 		RETURN_FALSE;
2384 	}
2385 	efree(hicompiled_string_description);
2386 
2387 	EG(error_reporting) = old_error_reporting;
2388 
2389 	if (i) {
2390 		php_ob_get_buffer (return_value TSRMLS_CC);
2391 		php_end_ob_buffer (0, 0 TSRMLS_CC);
2392 	} else {
2393 		RETURN_TRUE;
2394 	}
2395 }
2396 /* }}} */
2397 
2398 /* {{{ proto string ini_get(string varname)
2399    Get a configuration option */
2400 PHP_FUNCTION(ini_get)
2401 {
2402 	zval **varname;
2403 	char *str;
2404 
2405 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &varname) == FAILURE) {
2406 		WRONG_PARAM_COUNT;
2407 	}
2408 
2409 	convert_to_string_ex(varname);
2410 
2411 	str = zend_ini_string(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, 0);
2412 
2413 	if (!str) {
2414 		RETURN_FALSE;
2415 	}
2416 
2417 	RETURN_STRING(str, 1);
2418 }
2419 /* }}} */
2420 
2421 
2422 static int php_ini_get_option(zend_ini_entry *ini_entry, int num_args, va_list args, zend_hash_key *hash_key)
2423 {
2424 	zval *ini_array = va_arg(args, zval *);
2425 	int module_number = va_arg(args, int);
2426 	zval *option;
2427 
2428 	if (module_number != 0 && ini_entry->module_number != module_number) {
2429 		return 0;
2430 	}
2431 
2432 	if (hash_key->nKeyLength == 0 || hash_key->arKey[0] != 0) {
2433 
2434 		MAKE_STD_ZVAL(option);
2435 		array_init(option);
2436 
2437 		if (ini_entry->orig_value) {
2438 			add_assoc_stringl(option, "global_value", ini_entry->orig_value, ini_entry->orig_value_length, 1);
2439 		} else if (ini_entry->value) {
2440 			add_assoc_stringl(option, "global_value", ini_entry->value, ini_entry->value_length, 1);
2441 		} else {
2442 			add_assoc_null(option, "global_value");
2443 		}
2444 
2445 		if (ini_entry->value) {
2446 			add_assoc_stringl(option, "local_value", ini_entry->value, ini_entry->value_length, 1);
2447 		} else {
2448 			add_assoc_null(option, "local_value");
2449 		}
2450 
2451 		add_assoc_long(option, "access", ini_entry->modifiable);
2452 
2453 		add_assoc_zval_ex(ini_array, ini_entry->name, ini_entry->name_length, option);
2454 	}
2455 	return 0;
2456 }
2457 
2458 /* {{{ proto array ini_get_all([string extension])
2459    Get all configuration options */
2460 PHP_FUNCTION(ini_get_all)
2461 {
2462 	char *extname = NULL;
2463 	int extname_len = 0, extnumber = 0;
2464 	zend_module_entry *module;
2465 	
2466 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &extname, &extname_len) == FAILURE) {
2467 		RETURN_FALSE;
2468 	}
2469 
2470 	zend_ini_sort_entries(TSRMLS_C);
2471 
2472 	if (extname) {
2473 		if (zend_hash_find(&module_registry, extname, extname_len+1, (void **) &module) == FAILURE) {
2474 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find extension '%s'", extname);
2475 			RETURN_FALSE;
2476 		}
2477 		extnumber = module->module_number;
2478 	}
2479 
2480 	array_init(return_value);
2481 	zend_hash_apply_with_arguments(EG(ini_directives), (apply_func_args_t) php_ini_get_option, 2, return_value, extnumber TSRMLS_CC);
2482 }
2483 /* }}} */
2484 
2485 static int php_ini_check_path(char *option_name, int option_len, char *new_option_name, int new_option_len)
2486 {
2487 	if ( option_len != (new_option_len-1) ) {
2488 		return 0;
2489 	}
2490 	
2491 	return !strncmp(option_name, new_option_name, option_len);
2492 }
2493 
2494 /* {{{ proto string ini_set(string varname, string newvalue)
2495    Set a configuration option, returns false on error and the old value of the configuration option on success */
2496 PHP_FUNCTION(ini_set)
2497 {
2498 	zval **varname, **new_value;
2499 	char *old_value;
2500 
2501 	if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &varname, &new_value) == FAILURE) {
2502 		WRONG_PARAM_COUNT;
2503 	}
2504 
2505 	convert_to_string_ex(varname);
2506 	convert_to_string_ex(new_value);
2507 
2508 	old_value = zend_ini_string(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, 0);
2509 
2510 	/* copy to return here, because alter might free it! */
2511 	if (old_value) {
2512 		RETVAL_STRING(old_value, 1);
2513 	} else {
2514 		RETVAL_FALSE;
2515 	}
2516 
2517 #define _CHECK_PATH(var, ini) php_ini_check_path(Z_STRVAL_PP(var), Z_STRLEN_PP(var), ini, sizeof(ini))
2518 	
2519 	/* safe_mode & basedir check */
2520 	if (PG(safe_mode) || PG(open_basedir)) {
2521 		if (_CHECK_PATH(varname, "error_log") ||
2522 			_CHECK_PATH(varname, "java.class.path") ||
2523 			_CHECK_PATH(varname, "java.home") ||
2524 			_CHECK_PATH(varname, "java.library.path") ||
2525 			_CHECK_PATH(varname, "session.save_path") ||
2526 			_CHECK_PATH(varname, "vpopmail.directory")) {
2527 			if (PG(safe_mode) &&(!php_checkuid(Z_STRVAL_PP(new_value), NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2528 				zval_dtor(return_value);
2529 				RETURN_FALSE;
2530 			}
2531 
2532 			if (php_check_open_basedir(Z_STRVAL_PP(new_value) TSRMLS_CC)) {
2533 				zval_dtor(return_value);
2534 				RETURN_FALSE;
2535 			}
2536 		}
2537 	}	
2538 		
2539 	/* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */
2540 	if (PG(safe_mode)) {
2541 		if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) ||
2542 			!strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) ||
2543 			!strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) {
2544 			zval_dtor(return_value);
2545 			RETURN_FALSE;
2546 		}	
2547 	}	
2548 		
2549 	if (zend_alter_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, Z_STRVAL_PP(new_value), Z_STRLEN_PP(new_value),
2550 								PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == FAILURE) {
2551 		zval_dtor(return_value);
2552 		RETURN_FALSE;
2553 	}
2554 }
2555 /* }}} */
2556 
2557 /* {{{ proto void ini_restore(string varname)
2558    Restore the value of a configuration option specified by varname */
2559 PHP_FUNCTION(ini_restore)
2560 {
2561 	zval **varname;
2562 
2563 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &varname) == FAILURE) {
2564 		WRONG_PARAM_COUNT;
2565 	}
2566 
2567 	convert_to_string_ex(varname);
2568 
2569 	zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME);
2570 }
2571 /* }}} */
2572 
2573 /* {{{ proto string set_include_path(string new_include_path)
2574    Sets the include_path configuration option */
2575 
2576 PHP_FUNCTION(set_include_path)
2577 {
2578 	zval **new_value;
2579 	char *old_value;
2580 
2581 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &new_value) == FAILURE) {
2582 		WRONG_PARAM_COUNT;
2583 	}
2584 	convert_to_string_ex(new_value);
2585 	old_value = zend_ini_string("include_path", sizeof("include_path"), 0);
2586 	/* copy to return here, because alter might free it! */
2587 	if (old_value) {
2588 		RETVAL_STRING(old_value, 1);
2589 	} else {
2590 		RETVAL_FALSE;
2591 	}
2592 	if (zend_alter_ini_entry("include_path", sizeof("include_path"),
2593                              Z_STRVAL_PP(new_value), Z_STRLEN_PP(new_value),
2594                              PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == FAILURE) {
2595 		zval_dtor(return_value);
2596 		RETURN_FALSE;
2597 	}
2598 }
2599 
2600 /* }}} */
2601 
2602 /* {{{ proto string get_include_path()
2603    Get the current include_path configuration option */
2604 
2605 PHP_FUNCTION(get_include_path)
2606 {
2607     char *str;
2608 	if (ZEND_NUM_ARGS() != 0) {
2609 		WRONG_PARAM_COUNT;
2610 	}
2611 	str = zend_ini_string("include_path", sizeof("include_path"), 0);
2612 	if (str == NULL) {
2613 		RETURN_FALSE;
2614 	}
2615 	RETURN_STRING(str, 1);
2616 }
2617 
2618 /* }}} */
2619 
2620 /* {{{ proto void restore_include_path()
2621    Restore the value of the include_path configuration option */
2622 
2623 PHP_FUNCTION(restore_include_path)
2624 {
2625 	if (ZEND_NUM_ARGS() != 0) {
2626 		WRONG_PARAM_COUNT;
2627 	}
2628 
2629 	zend_restore_ini_entry("include_path", sizeof("include_path"),
2630                            PHP_INI_STAGE_RUNTIME);
2631 }
2632 
2633 /* }}} */
2634 
2635 /* {{{ proto mixed print_r(mixed var [, bool return])
2636    Prints out or returns information about the specified variable */
2637 PHP_FUNCTION(print_r)
2638 {
2639 	zval *var;
2640 	zend_bool i = 0;
2641 
2642 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &i) == FAILURE) {
2643 		RETURN_FALSE;
2644 	}
2645 	
2646 	if (i) {
2647 		php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC);
2648 	}
2649 
2650 	zend_print_zval_r(var, 0 TSRMLS_CC);
2651 
2652 	if (i) {
2653 		php_ob_get_buffer (return_value TSRMLS_CC);
2654 		php_end_ob_buffer (0, 0 TSRMLS_CC);
2655 	} else {
2656 		RETURN_TRUE;
2657 	}
2658 }
2659 /* }}} */
2660 
2661 /* This should go back to PHP */
2662 
2663 /* {{{ proto int connection_aborted(void)
2664    Returns true if client disconnected */
2665 PHP_FUNCTION(connection_aborted)
2666 {
2667 	RETURN_LONG(PG(connection_status) & PHP_CONNECTION_ABORTED);
2668 }
2669 /* }}} */
2670 
2671 /* {{{ proto int connection_status(void)
2672    Returns the connection status bitfield */
2673 PHP_FUNCTION(connection_status)
2674 {
2675 	RETURN_LONG(PG(connection_status));
2676 }
2677 /* }}} */
2678 
2679 /* {{{ proto int ignore_user_abort(bool value)
2680    Set whether we want to ignore a user abort event or not */
2681 PHP_FUNCTION(ignore_user_abort)
2682 {
2683 	zval **arg;
2684 	int old_setting;
2685 
2686 	old_setting = PG(ignore_user_abort);
2687 	switch (ZEND_NUM_ARGS()) {
2688 
2689 		case 0:
2690 			break;
2691 	
2692 		case 1:
2693 			if (zend_get_parameters_ex(1, &arg) == FAILURE) {
2694 				RETURN_FALSE;
2695 			}
2696 			convert_to_string_ex(arg);
2697 			zend_alter_ini_entry("ignore_user_abort", sizeof("ignore_user_abort"), Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
2698 			break;
2699 	
2700 		default:	
2701 			WRONG_PARAM_COUNT;
2702 			break;
2703 	}
2704 	RETURN_LONG(old_setting);
2705 }
2706 /* }}} */
2707 
2708 #if HAVE_GETSERVBYNAME
2709 /* {{{ proto int getservbyname(string service, string protocol)
2710    Returns port associated with service. Protocol must be "tcp" or "udp" */
2711 PHP_FUNCTION(getservbyname)
2712 {
2713 	zval **name, **proto;
2714 	struct servent *serv;
2715 
2716 	if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &name, &proto) == FAILURE) {
2717 		WRONG_PARAM_COUNT;
2718 	}
2719 	convert_to_string_ex(name);
2720 	convert_to_string_ex(proto);
2721 
2722 	serv = getservbyname(Z_STRVAL_PP(name), Z_STRVAL_PP(proto));
2723 
2724 	if (serv == NULL) {
2725 		RETURN_FALSE;
2726 	}
2727 	
2728 	RETURN_LONG(ntohs(serv->s_port));
2729 }
2730 /* }}} */
2731 #endif
2732 
2733 #if HAVE_GETSERVBYPORT
2734 /* {{{ proto string getservbyport(int port, string protocol)
2735    Returns service name associated with port. Protocol must be "tcp" or "udp" */
2736 PHP_FUNCTION(getservbyport)
2737 {
2738 	zval **port, **proto;
2739 	struct servent *serv;
2740 
2741 	if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &port, &proto) == FAILURE) {
2742 		WRONG_PARAM_COUNT;
2743 	}
2744 	convert_to_long_ex(port);
2745 	convert_to_string_ex(proto);
2746 
2747 	serv = getservbyport(htons((unsigned short) Z_LVAL_PP(port)), Z_STRVAL_PP(proto));
2748 
2749 	if (serv == NULL) {
2750 		RETURN_FALSE;
2751 	}
2752 	
2753 	RETURN_STRING(serv->s_name, 1);
2754 }
2755 /* }}} */
2756 #endif
2757 
2758 #if HAVE_GETPROTOBYNAME
2759 /* {{{ proto int getprotobyname(string name)
2760    Returns protocol number associated with name as per /etc/protocols */
2761 PHP_FUNCTION(getprotobyname)
2762 {
2763 	zval **name;
2764 	struct protoent *ent;
2765 
2766 	if (ZEND_NUM_ARGS() != 1
2767 		|| zend_get_parameters_ex(1, &name) == FAILURE) {
2768 		WRONG_PARAM_COUNT;
2769 	}
2770 
2771 	convert_to_string_ex(name);
2772 
2773 	ent = getprotobyname(Z_STRVAL_PP(name));
2774 
2775 	if (ent == NULL) {
2776 		Z_LVAL_P(return_value) = -1;
2777 		Z_TYPE_P(return_value) = IS_LONG;
2778 		RETURN_FALSE;
2779 	}
2780 
2781 	RETURN_LONG(ent->p_proto);
2782 }
2783 /* }}} */
2784 #endif
2785 
2786 #if HAVE_GETPROTOBYNUMBER
2787 /* {{{ proto string getprotobynumber(int proto)
2788    Returns protocol name associated with protocol number proto */
2789 PHP_FUNCTION(getprotobynumber)
2790 {
2791 	zval **proto;
2792 	struct protoent *ent;
2793 
2794 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &proto) == FAILURE) {
2795 		WRONG_PARAM_COUNT;
2796 	}
2797 
2798 	convert_to_long_ex(proto);
2799 
2800 	ent = getprotobynumber(Z_LVAL_PP(proto));
2801 
2802 	if (ent == NULL) {
2803 		RETURN_FALSE;
2804 	}
2805 
2806 	RETURN_STRING(ent->p_name, 1);
2807 }
2808 /* }}} */
2809 #endif
2810 
2811 /* {{{ proto bool register_tick_function(string function_name [, mixed arg [, mixed ... ]])
2812    Registers a tick callback function */
2813 PHP_FUNCTION(register_tick_function)
2814 {
2815 	user_tick_function_entry tick_fe;
2816 	int i;
2817 
2818 	tick_fe.calling = 0;
2819 	tick_fe.arg_count = ZEND_NUM_ARGS();
2820 
2821 	if (tick_fe.arg_count < 1) {
2822 		WRONG_PARAM_COUNT;
2823 	}
2824 
2825 	tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
2826 
2827 	if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
2828 		RETURN_FALSE;
2829 	}
2830 
2831 	if (Z_TYPE_P(tick_fe.arguments[0]) != IS_ARRAY)
2832 		convert_to_string_ex(&tick_fe.arguments[0]);
2833 
2834 	if (!BG(user_tick_functions)) {
2835 		BG(user_tick_functions) = (zend_llist *) emalloc(sizeof(zend_llist));
2836 		zend_llist_init(BG(user_tick_functions),
2837 						sizeof(user_tick_function_entry),
2838 						(llist_dtor_func_t) user_tick_function_dtor, 0);
2839 		php_add_tick_function(run_user_tick_functions);
2840 	}
2841 
2842 	for (i = 0; i < tick_fe.arg_count; i++) {
2843 		tick_fe.arguments[i]->refcount++;
2844 	}
2845 
2846 	zend_llist_add_element(BG(user_tick_functions), &tick_fe);
2847 
2848 	RETURN_TRUE;
2849 }
2850 /* }}} */
2851 
2852 /* {{{ proto void unregister_tick_function(string function_name)
2853    Unregisters a tick callback function */
2854 PHP_FUNCTION(unregister_tick_function)
2855 {
2856 	zval **function;
2857 	user_tick_function_entry tick_fe;
2858 
2859 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &function)) {
2860 		WRONG_PARAM_COUNT;
2861 	}
2862 
2863 	if (!BG(user_tick_functions)) {
2864 		return;
2865 	}
2866 	
2867 	if (Z_TYPE_PP(function) != IS_ARRAY) {
2868 		convert_to_string_ex(function);
2869 	}
2870 	
2871 	tick_fe.arguments = (zval **) emalloc(sizeof(zval *));
2872 	tick_fe.arguments[0] = *function;
2873 	tick_fe.arg_count = 1;
2874 	zend_llist_del_element(BG(user_tick_functions), &tick_fe, (int (*)(void *, void *)) user_tick_function_compare);
2875 	efree(tick_fe.arguments);
2876 }
2877 /* }}} */
2878 
2879 /* {{{ proto bool is_uploaded_file(string path)
2880    Check if file was created by rfc1867 upload  */
2881 PHP_FUNCTION(is_uploaded_file)
2882 {
2883 	zval **path;
2884 
2885 	if (!SG(rfc1867_uploaded_files)) {
2886 		RETURN_FALSE;
2887 	}
2888 
2889 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &path) != SUCCESS) {
2890 		ZEND_WRONG_PARAM_COUNT();
2891 	}
2892 
2893 	convert_to_string_ex(path);
2894 
2895 	if (zend_hash_exists(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path), Z_STRLEN_PP(path)+1)) {
2896 		RETURN_TRUE;
2897 	} else {
2898 		RETURN_FALSE;
2899 	}
2900 }
2901 /* }}} */
2902 
2903 /* {{{ proto bool move_uploaded_file(string path, string new_path)
2904    Move a file if and only if it was created by an upload */
2905 PHP_FUNCTION(move_uploaded_file)
2906 {
2907 	zval **path, **new_path;
2908 	zend_bool successful = 0;
2909 
2910 	if (!SG(rfc1867_uploaded_files)) {
2911 		RETURN_FALSE;
2912 	}
2913 
2914 	if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &path, &new_path) != SUCCESS) {
2915 		ZEND_WRONG_PARAM_COUNT();
2916 	}
2917 	convert_to_string_ex(path);
2918 	convert_to_string_ex(new_path);
2919 
2920 	if (!zend_hash_exists(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path), Z_STRLEN_PP(path)+1)) {
2921 		RETURN_FALSE;
2922 	}
2923 
2924 	if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_PP(new_path), NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2925 		RETURN_FALSE;
2926 	}
2927 
2928 	if (php_check_open_basedir(Z_STRVAL_PP(new_path) TSRMLS_CC)) {
2929 		RETURN_FALSE;
2930 	}
2931 
2932 	VCWD_UNLINK(Z_STRVAL_PP(new_path));
2933 	if (rename(Z_STRVAL_PP(path), Z_STRVAL_PP(new_path)) == 0) {
2934 		successful = 1;
2935 	} else
2936 		if (php_copy_file(Z_STRVAL_PP(path), Z_STRVAL_PP(new_path) TSRMLS_CC) == SUCCESS) {
2937 		VCWD_UNLINK(Z_STRVAL_PP(path));
2938 		successful = 1;
2939 	}
2940 
2941 	if (successful) {
2942 		zend_hash_del(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path), Z_STRLEN_PP(path)+1);
2943 	} else {
2944 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to move '%s' to '%s'", Z_STRVAL_PP(path), Z_STRVAL_PP(new_path));
2945 	}
2946 	RETURN_BOOL(successful);
2947 }
2948 /* }}} */
2949 
2950 
2951 static void php_simple_ini_parser_cb(zval *arg1, zval *arg2, int callback_type, zval *arr)
2952 {
2953 	zval *element;
2954 
2955 	switch (callback_type) {
2956 	
2957 		case ZEND_INI_PARSER_ENTRY:
2958 			if (!arg2) {
2959 				/* bare string - nothing to do */
2960 				break;
2961 			}
2962 			ALLOC_ZVAL(element);
2963 			*element = *arg2;
2964 			zval_copy_ctor(element);
2965 			INIT_PZVAL(element);
2966 			if (is_numeric_string(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), NULL, NULL, 0) != IS_LONG) { 
2967 				zend_hash_update(Z_ARRVAL_P(arr), Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)+1, &element, sizeof(zval *), NULL);
2968 			} else {
2969 				ulong key = (ulong) zend_atoi(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1));
2970 				zend_hash_index_update(Z_ARRVAL_P(arr), key, &element, sizeof(zval *), NULL);
2971 			}
2972 			break;
2973 
2974 		case ZEND_INI_PARSER_POP_ENTRY:
2975 		{
2976 			zval *hash, **find_hash;
2977 
2978 			if (!arg2) {
2979 				/* bare string - nothing to do */
2980 				break;
2981 			}
2982 
2983 			if (is_numeric_string(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), NULL, NULL, 0) != IS_LONG) {
2984 				if (zend_hash_find(Z_ARRVAL_P(arr), Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)+1, (void **) &find_hash) == FAILURE) {
2985 					ALLOC_ZVAL(hash);
2986 					INIT_PZVAL(hash);
2987 					array_init(hash);
2988 
2989 					zend_hash_update(Z_ARRVAL_P(arr), Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)+1, &hash, sizeof(zval *), NULL);
2990 				} else {
2991 					hash = *find_hash;
2992 				}
2993 			} else {
2994 				ulong key = (ulong) zend_atoi(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1));
2995 				if (zend_hash_index_find(Z_ARRVAL_P(arr), key, (void **) &find_hash) == FAILURE) {
2996 						ALLOC_ZVAL(hash);
2997 						INIT_PZVAL(hash);
2998 					        array_init(hash);
2999 
3000 					        zend_hash_index_update(Z_ARRVAL_P(arr), key, &hash, sizeof(zval *), NULL);
3001 				} else {
3002 					hash = *find_hash;
3003 				}
3004 			}
3005 
3006 			ALLOC_ZVAL(element);
3007 			*element = *arg2;
3008 			zval_copy_ctor(element);
3009 			INIT_PZVAL(element);
3010 			add_next_index_zval(hash, element);			
3011 		}
3012 		break;
3013 
3014 		case ZEND_INI_PARSER_SECTION:
3015 			break;
3016 	}
3017 }
3018 
3019 static void php_ini_parser_cb_with_sections(zval *arg1, zval *arg2, int callback_type, zval *arr)
3020 {
3021 	TSRMLS_FETCH();
3022 
3023 	if (callback_type == ZEND_INI_PARSER_SECTION) {
3024 		MAKE_STD_ZVAL(BG(active_ini_file_section));
3025 		array_init(BG(active_ini_file_section));
3026 		if (is_numeric_string(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), NULL, NULL, 0) != IS_LONG) {
3027 			zend_hash_update(Z_ARRVAL_P(arr), Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)+1, &BG(active_ini_file_section), sizeof(zval *), NULL);
3028 		} else {
3029 			ulong key = (ulong) zend_atoi(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1));
3030 			zend_hash_index_update(Z_ARRVAL_P(arr), key, &BG(active_ini_file_section), sizeof(zval *), NULL);
3031 		}
3032 	} else if (arg2) {
3033 		zval *active_arr;
3034 
3035 		if (BG(active_ini_file_section)) {
3036 			active_arr = BG(active_ini_file_section);
3037 		} else {
3038 			active_arr = arr;
3039 		}
3040 
3041 		php_simple_ini_parser_cb(arg1, arg2, callback_type, active_arr);
3042 	}
3043 }
3044 
3045 
3046 /* {{{ proto array parse_ini_file(string filename [, bool process_sections])
3047    Parse configuration file */
3048 PHP_FUNCTION(parse_ini_file)
3049 {
3050 	zval **filename, **process_sections;
3051 	zend_file_handle fh;
3052 	zend_ini_parser_cb_t ini_parser_cb;
3053 
3054 	switch (ZEND_NUM_ARGS()) {
3055 
3056 		case 1:
3057 			if (zend_get_parameters_ex(1, &filename) == FAILURE) {
3058 				RETURN_FALSE;
3059 			}
3060 			ini_parser_cb = (zend_ini_parser_cb_t) php_simple_ini_parser_cb;
3061 			break;
3062 
3063 		case 2:
3064 			if (zend_get_parameters_ex(2, &filename, &process_sections) == FAILURE) {
3065 				RETURN_FALSE;
3066 			}
3067 	
3068 			convert_to_boolean_ex(process_sections);
3069 		
3070 			if (Z_BVAL_PP(process_sections)) {
3071 				BG(active_ini_file_section) = NULL;
3072 				ini_parser_cb = (zend_ini_parser_cb_t) php_ini_parser_cb_with_sections;
3073 			} else {
3074 				ini_parser_cb = (zend_ini_parser_cb_t) php_simple_ini_parser_cb;
3075 			}
3076 			break;
3077 	
3078 		default:
3079 			ZEND_WRONG_PARAM_COUNT();
3080 			break;
3081 	}
3082 
3083 	convert_to_string_ex(filename);
3084 
3085 	memset(&fh, 0, sizeof(fh));
3086 	fh.filename = Z_STRVAL_PP(filename);
3087 	Z_TYPE(fh) = ZEND_HANDLE_FILENAME;
3088 	
3089 	array_init(return_value);
3090 	zend_parse_ini_file(&fh, 0, ini_parser_cb, return_value);
3091 }
3092 /* }}} */
3093 
3094 static int copy_request_variable(void *pDest, int num_args, va_list args, zend_hash_key *hash_key)
3095 {
3096 	char *prefix, *new_key;
3097 	uint prefix_len, new_key_len;
3098 	zval **var = (zval **) pDest;
3099 	TSRMLS_FETCH();
3100 
3101 	if (num_args != 2) {
3102 		return 0;
3103 	}
3104 
3105 	prefix = va_arg(args, char *);
3106 	prefix_len = va_arg(args, uint);
3107 
3108 	if (!prefix_len) {
3109 		if (!hash_key->nKeyLength) {
3110 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Numeric key detected - possible security hazard.");
3111 			return 0;
3112 		} else if (!strcmp(hash_key->arKey, "GLOBALS")) {
3113 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted GLOBALS variable overwrite.");
3114 			return 0; 
3115 		}
3116 	}
3117 
3118 	if (hash_key->nKeyLength) {
3119 		new_key_len = prefix_len + hash_key->nKeyLength;
3120 		new_key = (char *) emalloc(new_key_len);
3121 
3122 		memcpy(new_key, prefix, prefix_len);
3123 		memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength);
3124 	} else {
3125 		new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h);
3126 	}
3127 
3128 	zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC);
3129 	ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
3130 
3131 	efree(new_key);
3132 	return 0;
3133 }
3134 
3135 /* {{{ proto bool import_request_variables(string types [, string prefix])
3136    Import GET/POST/Cookie variables into the global scope */
3137 PHP_FUNCTION(import_request_variables)
3138 {
3139 	zval **z_types, **z_prefix;
3140 	char *types, *prefix;
3141 	uint prefix_len;
3142 	char *p;
3143 
3144 	switch (ZEND_NUM_ARGS()) {
3145 
3146 		case 1:
3147 			if (zend_get_parameters_ex(1, &z_types) == FAILURE) {
3148 				RETURN_FALSE;
3149 			}
3150 			prefix = "";
3151 			prefix_len = 0;
3152 			break;
3153 
3154 		case 2:
3155 			if (zend_get_parameters_ex(2, &z_types, &z_prefix) == FAILURE) {
3156 				RETURN_FALSE;
3157 			}
3158 			convert_to_string_ex(z_prefix);
3159 			prefix = Z_STRVAL_PP(z_prefix);
3160 			prefix_len = Z_STRLEN_PP(z_prefix);
3161 			break;
3162 	
3163 		default:
3164 			ZEND_WRONG_PARAM_COUNT();
3165 	}
3166 
3167 	if (prefix_len == 0) {
3168 		php_error_docref(NULL TSRMLS_CC, E_NOTICE, "No prefix specified - possible security hazard");
3169 	}
3170 
3171 	convert_to_string_ex(z_types);
3172 	types = Z_STRVAL_PP(z_types);
3173 
3174 	for (p = types; p && *p; p++) {
3175 		switch (*p) {
3176 	
3177 			case 'g':
3178 			case 'G':
3179 				zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_GET]), (apply_func_args_t) copy_request_variable, 2, prefix, prefix_len);
3180 				break;
3181 	
3182 			case 'p':
3183 			case 'P':
3184 				zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_POST]), (apply_func_args_t) copy_request_variable, 2, prefix, prefix_len);
3185 				zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_FILES]), (apply_func_args_t) copy_request_variable, 2, prefix, prefix_len);
3186 				break;
3187 
3188 			case 'c':
3189 			case 'C':
3190 				zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]), (apply_func_args_t) copy_request_variable, 2, prefix, prefix_len);
3191 				break;
3192 		}
3193 	}
3194 }
3195 /* }}} */
3196 
3197 
3198 
3199 /*
3200  * Local variables:
3201  * tab-width: 4
3202  * c-basic-offset: 4
3203  * End:
3204  * vim600: fdm=marker
3205  * vim: noet sw=4 ts=4
3206  */