basic_functions.c 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | https://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Authors: Andi Gutmans <andi@php.net> |
  14. | Zeev Suraski <zeev@php.net> |
  15. +----------------------------------------------------------------------+
  16. */
  17. #include "php.h"
  18. #include "php_streams.h"
  19. #include "php_main.h"
  20. #include "php_globals.h"
  21. #include "php_variables.h"
  22. #include "php_ini.h"
  23. #include "php_standard.h"
  24. #include "php_math.h"
  25. #include "php_http.h"
  26. #include "php_incomplete_class.h"
  27. #include "php_getopt.h"
  28. #include "ext/standard/info.h"
  29. #include "ext/session/php_session.h"
  30. #include "zend_exceptions.h"
  31. #include "zend_operators.h"
  32. #include "ext/standard/php_dns.h"
  33. #include "ext/standard/php_uuencode.h"
  34. #include "ext/standard/php_mt_rand.h"
  35. #include "ext/standard/crc32_x86.h"
  36. #ifdef PHP_WIN32
  37. #include "win32/php_win32_globals.h"
  38. #include "win32/time.h"
  39. #include "win32/ioutil.h"
  40. #endif
  41. typedef struct yy_buffer_state *YY_BUFFER_STATE;
  42. #include "zend.h"
  43. #include "zend_ini_scanner.h"
  44. #include "zend_language_scanner.h"
  45. #include <zend_language_parser.h>
  46. #include "zend_portability.h"
  47. #include <stdarg.h>
  48. #include <stdlib.h>
  49. #include <math.h>
  50. #include <time.h>
  51. #include <stdio.h>
  52. #ifndef PHP_WIN32
  53. #include <sys/types.h>
  54. #include <sys/stat.h>
  55. #endif
  56. #ifndef PHP_WIN32
  57. # include <netdb.h>
  58. #else
  59. #include "win32/inet.h"
  60. #endif
  61. #if HAVE_ARPA_INET_H
  62. # include <arpa/inet.h>
  63. #endif
  64. #if HAVE_UNISTD_H
  65. # include <unistd.h>
  66. #endif
  67. #include <string.h>
  68. #include <locale.h>
  69. #if HAVE_SYS_MMAN_H
  70. # include <sys/mman.h>
  71. #endif
  72. #if HAVE_SYS_LOADAVG_H
  73. # include <sys/loadavg.h>
  74. #endif
  75. #ifdef PHP_WIN32
  76. # include "win32/unistd.h"
  77. #endif
  78. #ifndef INADDR_NONE
  79. #define INADDR_NONE ((zend_ulong) -1)
  80. #endif
  81. #include "zend_globals.h"
  82. #include "php_globals.h"
  83. #include "SAPI.h"
  84. #include "php_ticks.h"
  85. #ifdef ZTS
  86. PHPAPI int basic_globals_id;
  87. #else
  88. PHPAPI php_basic_globals basic_globals;
  89. #endif
  90. #include "php_fopen_wrappers.h"
  91. #include "streamsfuncs.h"
  92. #include "basic_functions_arginfo.h"
  93. typedef struct _user_tick_function_entry {
  94. zend_fcall_info fci;
  95. zend_fcall_info_cache fci_cache;
  96. bool calling;
  97. } user_tick_function_entry;
  98. #if HAVE_PUTENV
  99. typedef struct {
  100. char *putenv_string;
  101. char *previous_value;
  102. zend_string *key;
  103. } putenv_entry;
  104. #endif
  105. /* some prototypes for local functions */
  106. static void user_shutdown_function_dtor(zval *zv);
  107. static void user_tick_function_dtor(user_tick_function_entry *tick_function_entry);
  108. static const zend_module_dep standard_deps[] = { /* {{{ */
  109. ZEND_MOD_OPTIONAL("session")
  110. ZEND_MOD_END
  111. };
  112. /* }}} */
  113. zend_module_entry basic_functions_module = { /* {{{ */
  114. STANDARD_MODULE_HEADER_EX,
  115. NULL,
  116. standard_deps,
  117. "standard", /* extension name */
  118. ext_functions, /* function list */
  119. PHP_MINIT(basic), /* process startup */
  120. PHP_MSHUTDOWN(basic), /* process shutdown */
  121. PHP_RINIT(basic), /* request startup */
  122. PHP_RSHUTDOWN(basic), /* request shutdown */
  123. PHP_MINFO(basic), /* extension info */
  124. PHP_STANDARD_VERSION, /* extension version */
  125. STANDARD_MODULE_PROPERTIES
  126. };
  127. /* }}} */
  128. #if defined(HAVE_PUTENV)
  129. static void php_putenv_destructor(zval *zv) /* {{{ */
  130. {
  131. putenv_entry *pe = Z_PTR_P(zv);
  132. if (pe->previous_value) {
  133. # if defined(PHP_WIN32)
  134. /* MSVCRT has a bug in putenv() when setting a variable that
  135. * is already set; if the SetEnvironmentVariable() API call
  136. * fails, the Crt will double free() a string.
  137. * We try to avoid this by setting our own value first */
  138. SetEnvironmentVariable(ZSTR_VAL(pe->key), "bugbug");
  139. # endif
  140. putenv(pe->previous_value);
  141. # if defined(PHP_WIN32)
  142. efree(pe->previous_value);
  143. # endif
  144. } else {
  145. # if HAVE_UNSETENV
  146. unsetenv(ZSTR_VAL(pe->key));
  147. # elif defined(PHP_WIN32)
  148. SetEnvironmentVariable(ZSTR_VAL(pe->key), NULL);
  149. # ifndef ZTS
  150. _putenv_s(ZSTR_VAL(pe->key), "");
  151. # endif
  152. # else
  153. char **env;
  154. for (env = environ; env != NULL && *env != NULL; env++) {
  155. if (!strncmp(*env, ZSTR_VAL(pe->key), ZSTR_LEN(pe->key))
  156. && (*env)[ZSTR_LEN(pe->key)] == '=') { /* found it */
  157. *env = "";
  158. break;
  159. }
  160. }
  161. # endif
  162. }
  163. #ifdef HAVE_TZSET
  164. /* don't forget to reset the various libc globals that
  165. * we might have changed by an earlier call to tzset(). */
  166. if (zend_string_equals_literal_ci(pe->key, "TZ")) {
  167. tzset();
  168. }
  169. #endif
  170. free(pe->putenv_string);
  171. zend_string_release(pe->key);
  172. efree(pe);
  173. }
  174. /* }}} */
  175. #endif
  176. static void basic_globals_ctor(php_basic_globals *basic_globals_p) /* {{{ */
  177. {
  178. BG(mt_rand_is_seeded) = 0;
  179. BG(mt_rand_mode) = MT_RAND_MT19937;
  180. BG(umask) = -1;
  181. BG(next) = NULL;
  182. BG(left) = -1;
  183. BG(user_tick_functions) = NULL;
  184. BG(user_filter_map) = NULL;
  185. BG(serialize_lock) = 0;
  186. memset(&BG(serialize), 0, sizeof(BG(serialize)));
  187. memset(&BG(unserialize), 0, sizeof(BG(unserialize)));
  188. memset(&BG(url_adapt_session_ex), 0, sizeof(BG(url_adapt_session_ex)));
  189. memset(&BG(url_adapt_output_ex), 0, sizeof(BG(url_adapt_output_ex)));
  190. BG(url_adapt_session_ex).type = 1;
  191. BG(url_adapt_output_ex).type = 0;
  192. zend_hash_init(&BG(url_adapt_session_hosts_ht), 0, NULL, NULL, 1);
  193. zend_hash_init(&BG(url_adapt_output_hosts_ht), 0, NULL, NULL, 1);
  194. #if defined(_REENTRANT)
  195. memset(&BG(mblen_state), 0, sizeof(BG(mblen_state)));
  196. #endif
  197. BG(page_uid) = -1;
  198. BG(page_gid) = -1;
  199. }
  200. /* }}} */
  201. static void basic_globals_dtor(php_basic_globals *basic_globals_p) /* {{{ */
  202. {
  203. if (basic_globals_p->url_adapt_session_ex.tags) {
  204. zend_hash_destroy(basic_globals_p->url_adapt_session_ex.tags);
  205. free(basic_globals_p->url_adapt_session_ex.tags);
  206. }
  207. if (basic_globals_p->url_adapt_output_ex.tags) {
  208. zend_hash_destroy(basic_globals_p->url_adapt_output_ex.tags);
  209. free(basic_globals_p->url_adapt_output_ex.tags);
  210. }
  211. zend_hash_destroy(&basic_globals_p->url_adapt_session_hosts_ht);
  212. zend_hash_destroy(&basic_globals_p->url_adapt_output_hosts_ht);
  213. }
  214. /* }}} */
  215. PHPAPI double php_get_nan(void) /* {{{ */
  216. {
  217. return ZEND_NAN;
  218. }
  219. /* }}} */
  220. PHPAPI double php_get_inf(void) /* {{{ */
  221. {
  222. return ZEND_INFINITY;
  223. }
  224. /* }}} */
  225. #define BASIC_MINIT_SUBMODULE(module) \
  226. if (PHP_MINIT(module)(INIT_FUNC_ARGS_PASSTHRU) != SUCCESS) {\
  227. return FAILURE; \
  228. }
  229. #define BASIC_RINIT_SUBMODULE(module) \
  230. PHP_RINIT(module)(INIT_FUNC_ARGS_PASSTHRU);
  231. #define BASIC_MINFO_SUBMODULE(module) \
  232. PHP_MINFO(module)(ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU);
  233. #define BASIC_RSHUTDOWN_SUBMODULE(module) \
  234. PHP_RSHUTDOWN(module)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
  235. #define BASIC_MSHUTDOWN_SUBMODULE(module) \
  236. PHP_MSHUTDOWN(module)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
  237. PHP_MINIT_FUNCTION(basic) /* {{{ */
  238. {
  239. #ifdef ZTS
  240. ts_allocate_id(&basic_globals_id, sizeof(php_basic_globals), (ts_allocate_ctor) basic_globals_ctor, (ts_allocate_dtor) basic_globals_dtor);
  241. #ifdef PHP_WIN32
  242. ts_allocate_id(&php_win32_core_globals_id, sizeof(php_win32_core_globals), (ts_allocate_ctor)php_win32_core_globals_ctor, (ts_allocate_dtor)php_win32_core_globals_dtor );
  243. #endif
  244. #else
  245. basic_globals_ctor(&basic_globals);
  246. #ifdef PHP_WIN32
  247. php_win32_core_globals_ctor(&the_php_win32_core_globals);
  248. #endif
  249. #endif
  250. php_ce_incomplete_class = register_class___PHP_Incomplete_Class();
  251. php_register_incomplete_class_handlers();
  252. assertion_error_ce = register_class_AssertionError(zend_ce_error);
  253. REGISTER_LONG_CONSTANT("CONNECTION_ABORTED", PHP_CONNECTION_ABORTED, CONST_CS | CONST_PERSISTENT);
  254. REGISTER_LONG_CONSTANT("CONNECTION_NORMAL", PHP_CONNECTION_NORMAL, CONST_CS | CONST_PERSISTENT);
  255. REGISTER_LONG_CONSTANT("CONNECTION_TIMEOUT", PHP_CONNECTION_TIMEOUT, CONST_CS | CONST_PERSISTENT);
  256. REGISTER_LONG_CONSTANT("INI_USER", ZEND_INI_USER, CONST_CS | CONST_PERSISTENT);
  257. REGISTER_LONG_CONSTANT("INI_PERDIR", ZEND_INI_PERDIR, CONST_CS | CONST_PERSISTENT);
  258. REGISTER_LONG_CONSTANT("INI_SYSTEM", ZEND_INI_SYSTEM, CONST_CS | CONST_PERSISTENT);
  259. REGISTER_LONG_CONSTANT("INI_ALL", ZEND_INI_ALL, CONST_CS | CONST_PERSISTENT);
  260. REGISTER_LONG_CONSTANT("INI_SCANNER_NORMAL", ZEND_INI_SCANNER_NORMAL, CONST_CS | CONST_PERSISTENT);
  261. REGISTER_LONG_CONSTANT("INI_SCANNER_RAW", ZEND_INI_SCANNER_RAW, CONST_CS | CONST_PERSISTENT);
  262. REGISTER_LONG_CONSTANT("INI_SCANNER_TYPED", ZEND_INI_SCANNER_TYPED, CONST_CS | CONST_PERSISTENT);
  263. REGISTER_LONG_CONSTANT("PHP_URL_SCHEME", PHP_URL_SCHEME, CONST_CS | CONST_PERSISTENT);
  264. REGISTER_LONG_CONSTANT("PHP_URL_HOST", PHP_URL_HOST, CONST_CS | CONST_PERSISTENT);
  265. REGISTER_LONG_CONSTANT("PHP_URL_PORT", PHP_URL_PORT, CONST_CS | CONST_PERSISTENT);
  266. REGISTER_LONG_CONSTANT("PHP_URL_USER", PHP_URL_USER, CONST_CS | CONST_PERSISTENT);
  267. REGISTER_LONG_CONSTANT("PHP_URL_PASS", PHP_URL_PASS, CONST_CS | CONST_PERSISTENT);
  268. REGISTER_LONG_CONSTANT("PHP_URL_PATH", PHP_URL_PATH, CONST_CS | CONST_PERSISTENT);
  269. REGISTER_LONG_CONSTANT("PHP_URL_QUERY", PHP_URL_QUERY, CONST_CS | CONST_PERSISTENT);
  270. REGISTER_LONG_CONSTANT("PHP_URL_FRAGMENT", PHP_URL_FRAGMENT, CONST_CS | CONST_PERSISTENT);
  271. REGISTER_LONG_CONSTANT("PHP_QUERY_RFC1738", PHP_QUERY_RFC1738, CONST_CS | CONST_PERSISTENT);
  272. REGISTER_LONG_CONSTANT("PHP_QUERY_RFC3986", PHP_QUERY_RFC3986, CONST_CS | CONST_PERSISTENT);
  273. #define REGISTER_MATH_CONSTANT(x) REGISTER_DOUBLE_CONSTANT(#x, x, CONST_CS | CONST_PERSISTENT)
  274. REGISTER_MATH_CONSTANT(M_E);
  275. REGISTER_MATH_CONSTANT(M_LOG2E);
  276. REGISTER_MATH_CONSTANT(M_LOG10E);
  277. REGISTER_MATH_CONSTANT(M_LN2);
  278. REGISTER_MATH_CONSTANT(M_LN10);
  279. REGISTER_MATH_CONSTANT(M_PI);
  280. REGISTER_MATH_CONSTANT(M_PI_2);
  281. REGISTER_MATH_CONSTANT(M_PI_4);
  282. REGISTER_MATH_CONSTANT(M_1_PI);
  283. REGISTER_MATH_CONSTANT(M_2_PI);
  284. REGISTER_MATH_CONSTANT(M_SQRTPI);
  285. REGISTER_MATH_CONSTANT(M_2_SQRTPI);
  286. REGISTER_MATH_CONSTANT(M_LNPI);
  287. REGISTER_MATH_CONSTANT(M_EULER);
  288. REGISTER_MATH_CONSTANT(M_SQRT2);
  289. REGISTER_MATH_CONSTANT(M_SQRT1_2);
  290. REGISTER_MATH_CONSTANT(M_SQRT3);
  291. REGISTER_DOUBLE_CONSTANT("INF", ZEND_INFINITY, CONST_CS | CONST_PERSISTENT);
  292. REGISTER_DOUBLE_CONSTANT("NAN", ZEND_NAN, CONST_CS | CONST_PERSISTENT);
  293. REGISTER_LONG_CONSTANT("PHP_ROUND_HALF_UP", PHP_ROUND_HALF_UP, CONST_CS | CONST_PERSISTENT);
  294. REGISTER_LONG_CONSTANT("PHP_ROUND_HALF_DOWN", PHP_ROUND_HALF_DOWN, CONST_CS | CONST_PERSISTENT);
  295. REGISTER_LONG_CONSTANT("PHP_ROUND_HALF_EVEN", PHP_ROUND_HALF_EVEN, CONST_CS | CONST_PERSISTENT);
  296. REGISTER_LONG_CONSTANT("PHP_ROUND_HALF_ODD", PHP_ROUND_HALF_ODD, CONST_CS | CONST_PERSISTENT);
  297. #if ENABLE_TEST_CLASS
  298. test_class_startup();
  299. #endif
  300. register_phpinfo_constants(INIT_FUNC_ARGS_PASSTHRU);
  301. register_html_constants(INIT_FUNC_ARGS_PASSTHRU);
  302. register_string_constants(INIT_FUNC_ARGS_PASSTHRU);
  303. BASIC_MINIT_SUBMODULE(var)
  304. BASIC_MINIT_SUBMODULE(file)
  305. BASIC_MINIT_SUBMODULE(pack)
  306. BASIC_MINIT_SUBMODULE(browscap)
  307. BASIC_MINIT_SUBMODULE(standard_filters)
  308. BASIC_MINIT_SUBMODULE(user_filters)
  309. BASIC_MINIT_SUBMODULE(password)
  310. BASIC_MINIT_SUBMODULE(mt_rand)
  311. #if defined(ZTS)
  312. BASIC_MINIT_SUBMODULE(localeconv)
  313. #endif
  314. #if defined(HAVE_NL_LANGINFO)
  315. BASIC_MINIT_SUBMODULE(nl_langinfo)
  316. #endif
  317. #if ZEND_INTRIN_SSE4_2_FUNC_PTR
  318. BASIC_MINIT_SUBMODULE(string_intrin)
  319. #endif
  320. #if ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PTR
  321. BASIC_MINIT_SUBMODULE(crc32_x86_intrin)
  322. #endif
  323. #if ZEND_INTRIN_AVX2_FUNC_PTR || ZEND_INTRIN_SSSE3_FUNC_PTR
  324. BASIC_MINIT_SUBMODULE(base64_intrin)
  325. #endif
  326. BASIC_MINIT_SUBMODULE(crypt)
  327. BASIC_MINIT_SUBMODULE(lcg)
  328. BASIC_MINIT_SUBMODULE(dir)
  329. #ifdef HAVE_SYSLOG_H
  330. BASIC_MINIT_SUBMODULE(syslog)
  331. #endif
  332. BASIC_MINIT_SUBMODULE(array)
  333. BASIC_MINIT_SUBMODULE(assert)
  334. BASIC_MINIT_SUBMODULE(url_scanner_ex)
  335. #ifdef PHP_CAN_SUPPORT_PROC_OPEN
  336. BASIC_MINIT_SUBMODULE(proc_open)
  337. #endif
  338. BASIC_MINIT_SUBMODULE(exec)
  339. BASIC_MINIT_SUBMODULE(user_streams)
  340. BASIC_MINIT_SUBMODULE(imagetypes)
  341. php_register_url_stream_wrapper("php", &php_stream_php_wrapper);
  342. php_register_url_stream_wrapper("file", &php_plain_files_wrapper);
  343. #ifdef HAVE_GLOB
  344. php_register_url_stream_wrapper("glob", &php_glob_stream_wrapper);
  345. #endif
  346. php_register_url_stream_wrapper("data", &php_stream_rfc2397_wrapper);
  347. php_register_url_stream_wrapper("http", &php_stream_http_wrapper);
  348. php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper);
  349. #if defined(PHP_WIN32) || HAVE_DNS_SEARCH_FUNC
  350. # if defined(PHP_WIN32) || HAVE_FULL_DNS_FUNCS
  351. BASIC_MINIT_SUBMODULE(dns)
  352. # endif
  353. #endif
  354. BASIC_MINIT_SUBMODULE(random)
  355. BASIC_MINIT_SUBMODULE(hrtime)
  356. return SUCCESS;
  357. }
  358. /* }}} */
  359. PHP_MSHUTDOWN_FUNCTION(basic) /* {{{ */
  360. {
  361. #ifdef HAVE_SYSLOG_H
  362. PHP_MSHUTDOWN(syslog)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
  363. #endif
  364. #ifdef ZTS
  365. ts_free_id(basic_globals_id);
  366. #ifdef PHP_WIN32
  367. ts_free_id(php_win32_core_globals_id);
  368. #endif
  369. #else
  370. basic_globals_dtor(&basic_globals);
  371. #ifdef PHP_WIN32
  372. php_win32_core_globals_dtor(&the_php_win32_core_globals);
  373. #endif
  374. #endif
  375. php_unregister_url_stream_wrapper("php");
  376. php_unregister_url_stream_wrapper("http");
  377. php_unregister_url_stream_wrapper("ftp");
  378. BASIC_MSHUTDOWN_SUBMODULE(browscap)
  379. BASIC_MSHUTDOWN_SUBMODULE(array)
  380. BASIC_MSHUTDOWN_SUBMODULE(assert)
  381. BASIC_MSHUTDOWN_SUBMODULE(url_scanner_ex)
  382. BASIC_MSHUTDOWN_SUBMODULE(file)
  383. BASIC_MSHUTDOWN_SUBMODULE(standard_filters)
  384. #if defined(ZTS)
  385. BASIC_MSHUTDOWN_SUBMODULE(localeconv)
  386. #endif
  387. BASIC_MSHUTDOWN_SUBMODULE(crypt)
  388. BASIC_MSHUTDOWN_SUBMODULE(random)
  389. BASIC_MSHUTDOWN_SUBMODULE(password)
  390. return SUCCESS;
  391. }
  392. /* }}} */
  393. PHP_RINIT_FUNCTION(basic) /* {{{ */
  394. {
  395. memset(BG(strtok_table), 0, 256);
  396. BG(serialize_lock) = 0;
  397. memset(&BG(serialize), 0, sizeof(BG(serialize)));
  398. memset(&BG(unserialize), 0, sizeof(BG(unserialize)));
  399. BG(strtok_string) = NULL;
  400. BG(strtok_last) = NULL;
  401. BG(ctype_string) = NULL;
  402. BG(locale_changed) = 0;
  403. BG(user_compare_fci) = empty_fcall_info;
  404. BG(user_compare_fci_cache) = empty_fcall_info_cache;
  405. BG(page_uid) = -1;
  406. BG(page_gid) = -1;
  407. BG(page_inode) = -1;
  408. BG(page_mtime) = -1;
  409. #ifdef HAVE_PUTENV
  410. zend_hash_init(&BG(putenv_ht), 1, NULL, php_putenv_destructor, 0);
  411. #endif
  412. BG(user_shutdown_function_names) = NULL;
  413. PHP_RINIT(filestat)(INIT_FUNC_ARGS_PASSTHRU);
  414. #ifdef HAVE_SYSLOG_H
  415. BASIC_RINIT_SUBMODULE(syslog)
  416. #endif
  417. BASIC_RINIT_SUBMODULE(dir)
  418. BASIC_RINIT_SUBMODULE(url_scanner_ex)
  419. /* Setup default context */
  420. FG(default_context) = NULL;
  421. /* Default to global wrappers only */
  422. FG(stream_wrappers) = NULL;
  423. /* Default to global filters only */
  424. FG(stream_filters) = NULL;
  425. return SUCCESS;
  426. }
  427. /* }}} */
  428. PHP_RSHUTDOWN_FUNCTION(basic) /* {{{ */
  429. {
  430. if (BG(strtok_string)) {
  431. zend_string_release(BG(strtok_string));
  432. BG(strtok_string) = NULL;
  433. }
  434. #ifdef HAVE_PUTENV
  435. tsrm_env_lock();
  436. zend_hash_destroy(&BG(putenv_ht));
  437. tsrm_env_unlock();
  438. #endif
  439. BG(mt_rand_is_seeded) = 0;
  440. if (BG(umask) != -1) {
  441. umask(BG(umask));
  442. }
  443. /* Check if locale was changed and change it back
  444. * to the value in startup environment */
  445. if (BG(locale_changed)) {
  446. setlocale(LC_ALL, "C");
  447. zend_reset_lc_ctype_locale();
  448. zend_update_current_locale();
  449. if (BG(ctype_string)) {
  450. zend_string_release_ex(BG(ctype_string), 0);
  451. BG(ctype_string) = NULL;
  452. }
  453. }
  454. /* FG(stream_wrappers) and FG(stream_filters) are destroyed
  455. * during php_request_shutdown() */
  456. PHP_RSHUTDOWN(filestat)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
  457. #ifdef HAVE_SYSLOG_H
  458. #ifdef PHP_WIN32
  459. BASIC_RSHUTDOWN_SUBMODULE(syslog)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
  460. #endif
  461. #endif
  462. BASIC_RSHUTDOWN_SUBMODULE(assert)
  463. BASIC_RSHUTDOWN_SUBMODULE(url_scanner_ex)
  464. BASIC_RSHUTDOWN_SUBMODULE(streams)
  465. #ifdef PHP_WIN32
  466. BASIC_RSHUTDOWN_SUBMODULE(win32_core_globals)
  467. #endif
  468. if (BG(user_tick_functions)) {
  469. zend_llist_destroy(BG(user_tick_functions));
  470. efree(BG(user_tick_functions));
  471. BG(user_tick_functions) = NULL;
  472. }
  473. BASIC_RSHUTDOWN_SUBMODULE(user_filters)
  474. BASIC_RSHUTDOWN_SUBMODULE(browscap)
  475. BG(page_uid) = -1;
  476. BG(page_gid) = -1;
  477. return SUCCESS;
  478. }
  479. /* }}} */
  480. PHP_MINFO_FUNCTION(basic) /* {{{ */
  481. {
  482. php_info_print_table_start();
  483. BASIC_MINFO_SUBMODULE(dl)
  484. BASIC_MINFO_SUBMODULE(mail)
  485. php_info_print_table_end();
  486. BASIC_MINFO_SUBMODULE(assert)
  487. }
  488. /* }}} */
  489. /* {{{ Given the name of a constant this function will return the constant's associated value */
  490. PHP_FUNCTION(constant)
  491. {
  492. zend_string *const_name;
  493. zval *c;
  494. zend_class_entry *scope;
  495. ZEND_PARSE_PARAMETERS_START(1, 1)
  496. Z_PARAM_STR(const_name)
  497. ZEND_PARSE_PARAMETERS_END();
  498. scope = zend_get_executed_scope();
  499. c = zend_get_constant_ex(const_name, scope, 0);
  500. if (!c) {
  501. RETURN_THROWS();
  502. }
  503. ZVAL_COPY_OR_DUP(return_value, c);
  504. if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) {
  505. if (UNEXPECTED(zval_update_constant_ex(return_value, scope) != SUCCESS)) {
  506. RETURN_THROWS();
  507. }
  508. }
  509. }
  510. /* }}} */
  511. #ifdef HAVE_INET_NTOP
  512. /* {{{ Converts a packed inet address to a human readable IP address string */
  513. PHP_FUNCTION(inet_ntop)
  514. {
  515. char *address;
  516. size_t address_len;
  517. int af = AF_INET;
  518. char buffer[40];
  519. ZEND_PARSE_PARAMETERS_START(1, 1)
  520. Z_PARAM_STRING(address, address_len)
  521. ZEND_PARSE_PARAMETERS_END();
  522. #ifdef HAVE_IPV6
  523. if (address_len == 16) {
  524. af = AF_INET6;
  525. } else
  526. #endif
  527. if (address_len != 4) {
  528. RETURN_FALSE;
  529. }
  530. if (!inet_ntop(af, address, buffer, sizeof(buffer))) {
  531. RETURN_FALSE;
  532. }
  533. RETURN_STRING(buffer);
  534. }
  535. /* }}} */
  536. #endif /* HAVE_INET_NTOP */
  537. #ifdef HAVE_INET_PTON
  538. /* {{{ Converts a human readable IP address to a packed binary string */
  539. PHP_FUNCTION(inet_pton)
  540. {
  541. int ret, af = AF_INET;
  542. char *address;
  543. size_t address_len;
  544. char buffer[17];
  545. ZEND_PARSE_PARAMETERS_START(1, 1)
  546. Z_PARAM_STRING(address, address_len)
  547. ZEND_PARSE_PARAMETERS_END();
  548. memset(buffer, 0, sizeof(buffer));
  549. #ifdef HAVE_IPV6
  550. if (strchr(address, ':')) {
  551. af = AF_INET6;
  552. } else
  553. #endif
  554. if (!strchr(address, '.')) {
  555. RETURN_FALSE;
  556. }
  557. ret = inet_pton(af, address, buffer);
  558. if (ret <= 0) {
  559. RETURN_FALSE;
  560. }
  561. RETURN_STRINGL(buffer, af == AF_INET ? 4 : 16);
  562. }
  563. /* }}} */
  564. #endif /* HAVE_INET_PTON */
  565. /* {{{ Converts a string containing an (IPv4) Internet Protocol dotted address into a proper address */
  566. PHP_FUNCTION(ip2long)
  567. {
  568. char *addr;
  569. size_t addr_len;
  570. #ifdef HAVE_INET_PTON
  571. struct in_addr ip;
  572. #else
  573. zend_ulong ip;
  574. #endif
  575. ZEND_PARSE_PARAMETERS_START(1, 1)
  576. Z_PARAM_STRING(addr, addr_len)
  577. ZEND_PARSE_PARAMETERS_END();
  578. #ifdef HAVE_INET_PTON
  579. if (addr_len == 0 || inet_pton(AF_INET, addr, &ip) != 1) {
  580. RETURN_FALSE;
  581. }
  582. RETURN_LONG(ntohl(ip.s_addr));
  583. #else
  584. if (addr_len == 0 || (ip = inet_addr(addr)) == INADDR_NONE) {
  585. /* The only special case when we should return -1 ourselves,
  586. * because inet_addr() considers it wrong. We return 0xFFFFFFFF and
  587. * not -1 or ~0 because of 32/64bit issues. */
  588. if (addr_len == sizeof("255.255.255.255") - 1 &&
  589. !memcmp(addr, "255.255.255.255", sizeof("255.255.255.255") - 1)
  590. ) {
  591. RETURN_LONG(0xFFFFFFFF);
  592. }
  593. RETURN_FALSE;
  594. }
  595. RETURN_LONG(ntohl(ip));
  596. #endif
  597. }
  598. /* }}} */
  599. /* {{{ Converts an (IPv4) Internet network address into a string in Internet standard dotted format */
  600. PHP_FUNCTION(long2ip)
  601. {
  602. zend_ulong ip;
  603. zend_long sip;
  604. struct in_addr myaddr;
  605. #ifdef HAVE_INET_PTON
  606. char str[40];
  607. #endif
  608. ZEND_PARSE_PARAMETERS_START(1, 1)
  609. Z_PARAM_LONG(sip)
  610. ZEND_PARSE_PARAMETERS_END();
  611. /* autoboxes on 32bit platforms, but that's expected */
  612. ip = (zend_ulong)sip;
  613. myaddr.s_addr = htonl(ip);
  614. #ifdef HAVE_INET_PTON
  615. if (inet_ntop(AF_INET, &myaddr, str, sizeof(str))) {
  616. RETURN_STRING(str);
  617. } else {
  618. RETURN_FALSE;
  619. }
  620. #else
  621. RETURN_STRING(inet_ntoa(myaddr));
  622. #endif
  623. }
  624. /* }}} */
  625. /********************
  626. * System Functions *
  627. ********************/
  628. PHPAPI zend_string *php_getenv(const char *str, size_t str_len) {
  629. #ifdef PHP_WIN32
  630. {
  631. wchar_t *keyw = php_win32_cp_conv_any_to_w(str, str_len, PHP_WIN32_CP_IGNORE_LEN_P);
  632. if (!keyw) {
  633. return NULL;
  634. }
  635. SetLastError(0);
  636. /* If the given buffer is not large enough to hold the data, the return value is
  637. * the buffer size, in characters, required to hold the string and its terminating
  638. * null character. We use this return value to alloc the final buffer. */
  639. wchar_t dummybuf;
  640. DWORD size = GetEnvironmentVariableW(keyw, &dummybuf, 0);
  641. if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
  642. /* The environment variable doesn't exist. */
  643. free(keyw);
  644. return NULL;
  645. }
  646. if (size == 0) {
  647. /* env exists, but it is empty */
  648. free(keyw);
  649. return ZSTR_EMPTY_ALLOC();
  650. }
  651. wchar_t *valw = emalloc((size + 1) * sizeof(wchar_t));
  652. size = GetEnvironmentVariableW(keyw, valw, size);
  653. if (size == 0) {
  654. /* has been removed between the two calls */
  655. free(keyw);
  656. efree(valw);
  657. return ZSTR_EMPTY_ALLOC();
  658. } else {
  659. char *ptr = php_win32_cp_w_to_any(valw);
  660. zend_string *result = zend_string_init(ptr, strlen(ptr), 0);
  661. free(ptr);
  662. free(keyw);
  663. efree(valw);
  664. return result;
  665. }
  666. }
  667. #else
  668. tsrm_env_lock();
  669. /* system method returns a const */
  670. char *ptr = getenv(str);
  671. zend_string *result = NULL;
  672. if (ptr) {
  673. result = zend_string_init(ptr, strlen(ptr), 0);
  674. }
  675. tsrm_env_unlock();
  676. return result;
  677. #endif
  678. }
  679. /* {{{ Get the value of an environment variable or every available environment variable
  680. if no varname is present */
  681. PHP_FUNCTION(getenv)
  682. {
  683. char *str = NULL;
  684. size_t str_len;
  685. bool local_only = 0;
  686. ZEND_PARSE_PARAMETERS_START(0, 2)
  687. Z_PARAM_OPTIONAL
  688. Z_PARAM_STRING_OR_NULL(str, str_len)
  689. Z_PARAM_BOOL(local_only)
  690. ZEND_PARSE_PARAMETERS_END();
  691. if (!str) {
  692. array_init(return_value);
  693. php_import_environment_variables(return_value);
  694. return;
  695. }
  696. if (!local_only) {
  697. /* SAPI method returns an emalloc()'d string */
  698. char *ptr = sapi_getenv(str, str_len);
  699. if (ptr) {
  700. // TODO: avoid reallocation ???
  701. RETVAL_STRING(ptr);
  702. efree(ptr);
  703. return;
  704. }
  705. }
  706. zend_string *res = php_getenv(str, str_len);
  707. if (res) {
  708. RETURN_STR(res);
  709. }
  710. RETURN_FALSE;
  711. }
  712. /* }}} */
  713. #ifdef HAVE_PUTENV
  714. /* {{{ Set the value of an environment variable */
  715. PHP_FUNCTION(putenv)
  716. {
  717. char *setting;
  718. size_t setting_len;
  719. char *p, **env;
  720. putenv_entry pe;
  721. #ifdef PHP_WIN32
  722. const char *value = NULL;
  723. int error_code;
  724. #endif
  725. ZEND_PARSE_PARAMETERS_START(1, 1)
  726. Z_PARAM_STRING(setting, setting_len)
  727. ZEND_PARSE_PARAMETERS_END();
  728. if (setting_len == 0 || setting[0] == '=') {
  729. zend_argument_value_error(1, "must have a valid syntax");
  730. RETURN_THROWS();
  731. }
  732. pe.putenv_string = zend_strndup(setting, setting_len);
  733. if ((p = strchr(setting, '='))) {
  734. pe.key = zend_string_init(setting, p - setting, 0);
  735. #ifdef PHP_WIN32
  736. value = p + 1;
  737. #endif
  738. } else {
  739. pe.key = zend_string_init(setting, setting_len, 0);
  740. }
  741. tsrm_env_lock();
  742. zend_hash_del(&BG(putenv_ht), pe.key);
  743. /* find previous value */
  744. pe.previous_value = NULL;
  745. for (env = environ; env != NULL && *env != NULL; env++) {
  746. if (!strncmp(*env, ZSTR_VAL(pe.key), ZSTR_LEN(pe.key))
  747. && (*env)[ZSTR_LEN(pe.key)] == '=') { /* found it */
  748. #if defined(PHP_WIN32)
  749. /* must copy previous value because MSVCRT's putenv can free the string without notice */
  750. pe.previous_value = estrdup(*env);
  751. #else
  752. pe.previous_value = *env;
  753. #endif
  754. break;
  755. }
  756. }
  757. #if HAVE_UNSETENV
  758. if (!p) { /* no '=' means we want to unset it */
  759. unsetenv(pe.putenv_string);
  760. }
  761. if (!p || putenv(pe.putenv_string) == 0) { /* success */
  762. #else
  763. # ifndef PHP_WIN32
  764. if (putenv(pe.putenv_string) == 0) { /* success */
  765. # else
  766. wchar_t *keyw, *valw = NULL;
  767. keyw = php_win32_cp_any_to_w(ZSTR_VAL(pe.key));
  768. if (value) {
  769. valw = php_win32_cp_any_to_w(value);
  770. }
  771. /* valw may be NULL, but the failed conversion still needs to be checked. */
  772. if (!keyw || !valw && value) {
  773. tsrm_env_unlock();
  774. free(pe.putenv_string);
  775. zend_string_release(pe.key);
  776. free(keyw);
  777. free(valw);
  778. RETURN_FALSE;
  779. }
  780. error_code = SetEnvironmentVariableW(keyw, valw);
  781. if (error_code != 0
  782. # ifndef ZTS
  783. /* We need both SetEnvironmentVariable and _putenv here as some
  784. dependency lib could use either way to read the environment.
  785. Obviously the CRT version will be useful more often. But
  786. generally, doing both brings us on the safe track at least
  787. in NTS build. */
  788. && _wputenv_s(keyw, valw ? valw : L"") == 0
  789. # endif
  790. ) { /* success */
  791. # endif
  792. #endif
  793. zend_hash_add_mem(&BG(putenv_ht), pe.key, &pe, sizeof(putenv_entry));
  794. #ifdef HAVE_TZSET
  795. if (zend_string_equals_literal_ci(pe.key, "TZ")) {
  796. tzset();
  797. }
  798. #endif
  799. tsrm_env_unlock();
  800. #if defined(PHP_WIN32)
  801. free(keyw);
  802. free(valw);
  803. #endif
  804. RETURN_TRUE;
  805. } else {
  806. free(pe.putenv_string);
  807. zend_string_release(pe.key);
  808. #if defined(PHP_WIN32)
  809. free(keyw);
  810. free(valw);
  811. #endif
  812. RETURN_FALSE;
  813. }
  814. }
  815. /* }}} */
  816. #endif
  817. /* {{{ free_argv()
  818. Free the memory allocated to an argv array. */
  819. static void free_argv(char **argv, int argc)
  820. {
  821. int i;
  822. if (argv) {
  823. for (i = 0; i < argc; i++) {
  824. if (argv[i]) {
  825. efree(argv[i]);
  826. }
  827. }
  828. efree(argv);
  829. }
  830. }
  831. /* }}} */
  832. /* {{{ free_longopts()
  833. Free the memory allocated to an longopt array. */
  834. static void free_longopts(opt_struct *longopts)
  835. {
  836. opt_struct *p;
  837. if (longopts) {
  838. for (p = longopts; p && p->opt_char != '-'; p++) {
  839. if (p->opt_name != NULL) {
  840. efree((char *)(p->opt_name));
  841. }
  842. }
  843. }
  844. }
  845. /* }}} */
  846. /* {{{ parse_opts()
  847. Convert the typical getopt input characters to the php_getopt struct array */
  848. static int parse_opts(char * opts, opt_struct ** result)
  849. {
  850. opt_struct * paras = NULL;
  851. unsigned int i, count = 0;
  852. unsigned int opts_len = (unsigned int)strlen(opts);
  853. for (i = 0; i < opts_len; i++) {
  854. if ((opts[i] >= 48 && opts[i] <= 57) ||
  855. (opts[i] >= 65 && opts[i] <= 90) ||
  856. (opts[i] >= 97 && opts[i] <= 122)
  857. ) {
  858. count++;
  859. }
  860. }
  861. paras = safe_emalloc(sizeof(opt_struct), count, 0);
  862. memset(paras, 0, sizeof(opt_struct) * count);
  863. *result = paras;
  864. while ( (*opts >= 48 && *opts <= 57) || /* 0 - 9 */
  865. (*opts >= 65 && *opts <= 90) || /* A - Z */
  866. (*opts >= 97 && *opts <= 122) /* a - z */
  867. ) {
  868. paras->opt_char = *opts;
  869. paras->need_param = *(++opts) == ':';
  870. paras->opt_name = NULL;
  871. if (paras->need_param == 1) {
  872. opts++;
  873. if (*opts == ':') {
  874. paras->need_param++;
  875. opts++;
  876. }
  877. }
  878. paras++;
  879. }
  880. return count;
  881. }
  882. /* }}} */
  883. /* {{{ Get options from the command line argument list */
  884. PHP_FUNCTION(getopt)
  885. {
  886. char *options = NULL, **argv = NULL;
  887. char opt[2] = { '\0' };
  888. char *optname;
  889. int argc = 0, o;
  890. size_t options_len = 0, len;
  891. char *php_optarg = NULL;
  892. int php_optind = 1;
  893. zval val, *args = NULL, *p_longopts = NULL;
  894. zval *zoptind = NULL;
  895. size_t optname_len = 0;
  896. opt_struct *opts, *orig_opts;
  897. ZEND_PARSE_PARAMETERS_START(1, 3)
  898. Z_PARAM_STRING(options, options_len)
  899. Z_PARAM_OPTIONAL
  900. Z_PARAM_ARRAY(p_longopts)
  901. Z_PARAM_ZVAL(zoptind)
  902. ZEND_PARSE_PARAMETERS_END();
  903. /* Init zoptind to 1 */
  904. if (zoptind) {
  905. ZEND_TRY_ASSIGN_REF_LONG(zoptind, 1);
  906. }
  907. /* Get argv from the global symbol table. We calculate argc ourselves
  908. * in order to be on the safe side, even though it is also available
  909. * from the symbol table. */
  910. if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_SERVER))) &&
  911. ((args = zend_hash_find_ex_ind(Z_ARRVAL_P(&PG(http_globals)[TRACK_VARS_SERVER]), ZSTR_KNOWN(ZEND_STR_ARGV), 1)) != NULL ||
  912. (args = zend_hash_find_ex_ind(&EG(symbol_table), ZSTR_KNOWN(ZEND_STR_ARGV), 1)) != NULL)
  913. ) {
  914. int pos = 0;
  915. zval *entry;
  916. if (Z_TYPE_P(args) != IS_ARRAY) {
  917. RETURN_FALSE;
  918. }
  919. argc = zend_hash_num_elements(Z_ARRVAL_P(args));
  920. /* Attempt to allocate enough memory to hold all of the arguments
  921. * and a trailing NULL */
  922. argv = (char **) safe_emalloc(sizeof(char *), (argc + 1), 0);
  923. /* Iterate over the hash to construct the argv array. */
  924. ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), entry) {
  925. zend_string *tmp_arg_str;
  926. zend_string *arg_str = zval_get_tmp_string(entry, &tmp_arg_str);
  927. argv[pos++] = estrdup(ZSTR_VAL(arg_str));
  928. zend_tmp_string_release(tmp_arg_str);
  929. } ZEND_HASH_FOREACH_END();
  930. /* The C Standard requires argv[argc] to be NULL - this might
  931. * keep some getopt implementations happy. */
  932. argv[argc] = NULL;
  933. } else {
  934. /* Return false if we can't find argv. */
  935. RETURN_FALSE;
  936. }
  937. len = parse_opts(options, &opts);
  938. if (p_longopts) {
  939. int count;
  940. zval *entry;
  941. count = zend_hash_num_elements(Z_ARRVAL_P(p_longopts));
  942. /* the first <len> slots are filled by the one short ops
  943. * we now extend our array and jump to the new added structs */
  944. opts = (opt_struct *) erealloc(opts, sizeof(opt_struct) * (len + count + 1));
  945. orig_opts = opts;
  946. opts += len;
  947. memset(opts, 0, count * sizeof(opt_struct));
  948. /* Iterate over the hash to construct the argv array. */
  949. ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(p_longopts), entry) {
  950. zend_string *tmp_arg_str;
  951. zend_string *arg_str = zval_get_tmp_string(entry, &tmp_arg_str);
  952. opts->need_param = 0;
  953. opts->opt_name = estrdup(ZSTR_VAL(arg_str));
  954. len = strlen(opts->opt_name);
  955. if ((len > 0) && (opts->opt_name[len - 1] == ':')) {
  956. opts->need_param++;
  957. opts->opt_name[len - 1] = '\0';
  958. if ((len > 1) && (opts->opt_name[len - 2] == ':')) {
  959. opts->need_param++;
  960. opts->opt_name[len - 2] = '\0';
  961. }
  962. }
  963. opts->opt_char = 0;
  964. opts++;
  965. zend_tmp_string_release(tmp_arg_str);
  966. } ZEND_HASH_FOREACH_END();
  967. } else {
  968. opts = (opt_struct*) erealloc(opts, sizeof(opt_struct) * (len + 1));
  969. orig_opts = opts;
  970. opts += len;
  971. }
  972. /* php_getopt want to identify the last param */
  973. opts->opt_char = '-';
  974. opts->need_param = 0;
  975. opts->opt_name = NULL;
  976. /* Initialize the return value as an array. */
  977. array_init(return_value);
  978. /* after our pointer arithmetic jump back to the first element */
  979. opts = orig_opts;
  980. while ((o = php_getopt(argc, argv, opts, &php_optarg, &php_optind, 0, 1)) != -1) {
  981. /* Skip unknown arguments. */
  982. if (o == PHP_GETOPT_INVALID_ARG) {
  983. continue;
  984. }
  985. /* Prepare the option character and the argument string. */
  986. if (o == 0) {
  987. optname = opts[php_optidx].opt_name;
  988. } else {
  989. if (o == 1) {
  990. o = '-';
  991. }
  992. opt[0] = o;
  993. optname = opt;
  994. }
  995. if (php_optarg != NULL) {
  996. /* keep the arg as binary, since the encoding is not known */
  997. ZVAL_STRING(&val, php_optarg);
  998. } else {
  999. ZVAL_FALSE(&val);
  1000. }
  1001. /* Add this option / argument pair to the result hash. */
  1002. optname_len = strlen(optname);
  1003. if (!(optname_len > 1 && optname[0] == '0') && is_numeric_string(optname, optname_len, NULL, NULL, 0) == IS_LONG) {
  1004. /* numeric string */
  1005. int optname_int = atoi(optname);
  1006. if ((args = zend_hash_index_find(Z_ARRVAL_P(return_value), optname_int)) != NULL) {
  1007. if (Z_TYPE_P(args) != IS_ARRAY) {
  1008. convert_to_array(args);
  1009. }
  1010. zend_hash_next_index_insert(Z_ARRVAL_P(args), &val);
  1011. } else {
  1012. zend_hash_index_update(Z_ARRVAL_P(return_value), optname_int, &val);
  1013. }
  1014. } else {
  1015. /* other strings */
  1016. if ((args = zend_hash_str_find(Z_ARRVAL_P(return_value), optname, strlen(optname))) != NULL) {
  1017. if (Z_TYPE_P(args) != IS_ARRAY) {
  1018. convert_to_array(args);
  1019. }
  1020. zend_hash_next_index_insert(Z_ARRVAL_P(args), &val);
  1021. } else {
  1022. zend_hash_str_add(Z_ARRVAL_P(return_value), optname, strlen(optname), &val);
  1023. }
  1024. }
  1025. php_optarg = NULL;
  1026. }
  1027. /* Set zoptind to php_optind */
  1028. if (zoptind) {
  1029. ZEND_TRY_ASSIGN_REF_LONG(zoptind, php_optind);
  1030. }
  1031. free_longopts(orig_opts);
  1032. efree(orig_opts);
  1033. free_argv(argv, argc);
  1034. }
  1035. /* }}} */
  1036. /* {{{ Flush the output buffer */
  1037. PHP_FUNCTION(flush)
  1038. {
  1039. ZEND_PARSE_PARAMETERS_NONE();
  1040. sapi_flush();
  1041. }
  1042. /* }}} */
  1043. /* {{{ Delay for a given number of seconds */
  1044. PHP_FUNCTION(sleep)
  1045. {
  1046. zend_long num;
  1047. ZEND_PARSE_PARAMETERS_START(1, 1)
  1048. Z_PARAM_LONG(num)
  1049. ZEND_PARSE_PARAMETERS_END();
  1050. if (num < 0) {
  1051. zend_argument_value_error(1, "must be greater than or equal to 0");
  1052. RETURN_THROWS();
  1053. }
  1054. RETURN_LONG(php_sleep((unsigned int)num));
  1055. }
  1056. /* }}} */
  1057. /* {{{ Delay for a given number of micro seconds */
  1058. PHP_FUNCTION(usleep)
  1059. {
  1060. zend_long num;
  1061. ZEND_PARSE_PARAMETERS_START(1, 1)
  1062. Z_PARAM_LONG(num)
  1063. ZEND_PARSE_PARAMETERS_END();
  1064. if (num < 0) {
  1065. zend_argument_value_error(1, "must be greater than or equal to 0");
  1066. RETURN_THROWS();
  1067. }
  1068. #if HAVE_USLEEP
  1069. usleep((unsigned int)num);
  1070. #endif
  1071. }
  1072. /* }}} */
  1073. #if HAVE_NANOSLEEP
  1074. /* {{{ Delay for a number of seconds and nano seconds */
  1075. PHP_FUNCTION(time_nanosleep)
  1076. {
  1077. zend_long tv_sec, tv_nsec;
  1078. struct timespec php_req, php_rem;
  1079. ZEND_PARSE_PARAMETERS_START(2, 2)
  1080. Z_PARAM_LONG(tv_sec)
  1081. Z_PARAM_LONG(tv_nsec)
  1082. ZEND_PARSE_PARAMETERS_END();
  1083. if (tv_sec < 0) {
  1084. zend_argument_value_error(1, "must be greater than or equal to 0");
  1085. RETURN_THROWS();
  1086. }
  1087. if (tv_nsec < 0) {
  1088. zend_argument_value_error(2, "must be greater than or equal to 0");
  1089. RETURN_THROWS();
  1090. }
  1091. php_req.tv_sec = (time_t) tv_sec;
  1092. php_req.tv_nsec = (long)tv_nsec;
  1093. if (!nanosleep(&php_req, &php_rem)) {
  1094. RETURN_TRUE;
  1095. } else if (errno == EINTR) {
  1096. array_init(return_value);
  1097. add_assoc_long_ex(return_value, "seconds", sizeof("seconds")-1, php_rem.tv_sec);
  1098. add_assoc_long_ex(return_value, "nanoseconds", sizeof("nanoseconds")-1, php_rem.tv_nsec);
  1099. return;
  1100. } else if (errno == EINVAL) {
  1101. zend_value_error("Nanoseconds was not in the range 0 to 999 999 999 or seconds was negative");
  1102. RETURN_THROWS();
  1103. }
  1104. RETURN_FALSE;
  1105. }
  1106. /* }}} */
  1107. /* {{{ Make the script sleep until the specified time */
  1108. PHP_FUNCTION(time_sleep_until)
  1109. {
  1110. double target_secs;
  1111. struct timeval tm;
  1112. struct timespec php_req, php_rem;
  1113. uint64_t current_ns, target_ns, diff_ns;
  1114. const uint64_t ns_per_sec = 1000000000;
  1115. ZEND_PARSE_PARAMETERS_START(1, 1)
  1116. Z_PARAM_DOUBLE(target_secs)
  1117. ZEND_PARSE_PARAMETERS_END();
  1118. if (gettimeofday((struct timeval *) &tm, NULL) != 0) {
  1119. RETURN_FALSE;
  1120. }
  1121. target_ns = (uint64_t) (target_secs * ns_per_sec);
  1122. current_ns = ((uint64_t) tm.tv_sec) * ns_per_sec + ((uint64_t) tm.tv_usec) * 1000;
  1123. if (target_ns < current_ns) {
  1124. php_error_docref(NULL, E_WARNING, "Argument #1 ($timestamp) must be greater than or equal to the current time");
  1125. RETURN_FALSE;
  1126. }
  1127. diff_ns = target_ns - current_ns;
  1128. php_req.tv_sec = (time_t) (diff_ns / ns_per_sec);
  1129. php_req.tv_nsec = (long) (diff_ns % ns_per_sec);
  1130. while (nanosleep(&php_req, &php_rem)) {
  1131. if (errno == EINTR) {
  1132. php_req.tv_sec = php_rem.tv_sec;
  1133. php_req.tv_nsec = php_rem.tv_nsec;
  1134. } else {
  1135. RETURN_FALSE;
  1136. }
  1137. }
  1138. RETURN_TRUE;
  1139. }
  1140. /* }}} */
  1141. #endif
  1142. /* {{{ Get the name of the owner of the current PHP script */
  1143. PHP_FUNCTION(get_current_user)
  1144. {
  1145. ZEND_PARSE_PARAMETERS_NONE();
  1146. RETURN_STRING(php_get_current_user());
  1147. }
  1148. /* }}} */
  1149. #define ZVAL_SET_INI_STR(zv, val) do { \
  1150. if (ZSTR_IS_INTERNED(val)) { \
  1151. ZVAL_INTERNED_STR(zv, val); \
  1152. } else if (ZSTR_LEN(val) == 0) { \
  1153. ZVAL_EMPTY_STRING(zv); \
  1154. } else if (ZSTR_LEN(val) == 1) { \
  1155. ZVAL_CHAR(zv, ZSTR_VAL(val)[0]); \
  1156. } else if (!(GC_FLAGS(val) & GC_PERSISTENT)) { \
  1157. ZVAL_NEW_STR(zv, zend_string_copy(val)); \
  1158. } else { \
  1159. ZVAL_NEW_STR(zv, zend_string_init(ZSTR_VAL(val), ZSTR_LEN(val), 0)); \
  1160. } \
  1161. } while (0)
  1162. static void add_config_entries(HashTable *hash, zval *return_value);
  1163. /* {{{ add_config_entry */
  1164. static void add_config_entry(zend_ulong h, zend_string *key, zval *entry, zval *retval)
  1165. {
  1166. if (Z_TYPE_P(entry) == IS_STRING) {
  1167. zval str_zv;
  1168. ZVAL_SET_INI_STR(&str_zv, Z_STR_P(entry));
  1169. if (key) {
  1170. add_assoc_zval_ex(retval, ZSTR_VAL(key), ZSTR_LEN(key), &str_zv);
  1171. } else {
  1172. add_index_zval(retval, h, &str_zv);
  1173. }
  1174. } else if (Z_TYPE_P(entry) == IS_ARRAY) {
  1175. zval tmp;
  1176. array_init(&tmp);
  1177. add_config_entries(Z_ARRVAL_P(entry), &tmp);
  1178. zend_hash_update(Z_ARRVAL_P(retval), key, &tmp);
  1179. }
  1180. }
  1181. /* }}} */
  1182. /* {{{ add_config_entries */
  1183. static void add_config_entries(HashTable *hash, zval *return_value) /* {{{ */
  1184. {
  1185. zend_ulong h;
  1186. zend_string *key;
  1187. zval *zv;
  1188. ZEND_HASH_FOREACH_KEY_VAL(hash, h, key, zv)
  1189. add_config_entry(h, key, zv, return_value);
  1190. ZEND_HASH_FOREACH_END();
  1191. }
  1192. /* }}} */
  1193. /* {{{ Get the value of a PHP configuration option */
  1194. PHP_FUNCTION(get_cfg_var)
  1195. {
  1196. zend_string *varname;
  1197. ZEND_PARSE_PARAMETERS_START(1, 1)
  1198. Z_PARAM_STR(varname)
  1199. ZEND_PARSE_PARAMETERS_END();
  1200. zval *retval = cfg_get_entry_ex(varname);
  1201. if (retval) {
  1202. if (Z_TYPE_P(retval) == IS_ARRAY) {
  1203. array_init(return_value);
  1204. add_config_entries(Z_ARRVAL_P(retval), return_value);
  1205. return;
  1206. } else {
  1207. ZVAL_SET_INI_STR(return_value, Z_STR_P(retval));
  1208. }
  1209. } else {
  1210. RETURN_FALSE;
  1211. }
  1212. }
  1213. /* }}} */
  1214. /*
  1215. 1st arg = error message
  1216. 2nd arg = error option
  1217. 3rd arg = optional parameters (email address or tcp address)
  1218. 4th arg = used for additional headers if email
  1219. error options:
  1220. 0 = send to php_error_log (uses syslog or file depending on ini setting)
  1221. 1 = send via email to 3rd parameter 4th option = additional headers
  1222. 2 = send via tcp/ip to 3rd parameter (name or ip:port)
  1223. 3 = save to file in 3rd parameter
  1224. 4 = send to SAPI logger directly
  1225. */
  1226. /* {{{ Send an error message somewhere */
  1227. PHP_FUNCTION(error_log)
  1228. {
  1229. char *message, *opt = NULL, *headers = NULL;
  1230. size_t message_len, opt_len = 0, headers_len = 0;
  1231. zend_long erropt = 0;
  1232. ZEND_PARSE_PARAMETERS_START(1, 4)
  1233. Z_PARAM_STRING(message, message_len)
  1234. Z_PARAM_OPTIONAL
  1235. Z_PARAM_LONG(erropt)
  1236. Z_PARAM_PATH_OR_NULL(opt, opt_len)
  1237. Z_PARAM_STRING_OR_NULL(headers, headers_len)
  1238. ZEND_PARSE_PARAMETERS_END();
  1239. if (_php_error_log_ex((int) erropt, message, message_len, opt, headers) == FAILURE) {
  1240. RETURN_FALSE;
  1241. }
  1242. RETURN_TRUE;
  1243. }
  1244. /* }}} */
  1245. /* For BC (not binary-safe!) */
  1246. PHPAPI int _php_error_log(int opt_err, const char *message, const char *opt, const char *headers) /* {{{ */
  1247. {
  1248. return _php_error_log_ex(opt_err, message, (opt_err == 3) ? strlen(message) : 0, opt, headers);
  1249. }
  1250. /* }}} */
  1251. PHPAPI int _php_error_log_ex(int opt_err, const char *message, size_t message_len, const char *opt, const char *headers) /* {{{ */
  1252. {
  1253. php_stream *stream = NULL;
  1254. size_t nbytes;
  1255. switch (opt_err)
  1256. {
  1257. case 1: /*send an email */
  1258. if (!php_mail(opt, "PHP error_log message", message, headers, NULL)) {
  1259. return FAILURE;
  1260. }
  1261. break;
  1262. case 2: /*send to an address */
  1263. zend_value_error("TCP/IP option is not available for error logging");
  1264. return FAILURE;
  1265. case 3: /*save to a file */
  1266. stream = php_stream_open_wrapper(opt, "a", REPORT_ERRORS, NULL);
  1267. if (!stream) {
  1268. return FAILURE;
  1269. }
  1270. nbytes = php_stream_write(stream, message, message_len);
  1271. php_stream_close(stream);
  1272. if (nbytes != message_len) {
  1273. return FAILURE;
  1274. }
  1275. break;
  1276. case 4: /* send to SAPI */
  1277. if (sapi_module.log_message) {
  1278. sapi_module.log_message(message, -1);
  1279. } else {
  1280. return FAILURE;
  1281. }
  1282. break;
  1283. default:
  1284. php_log_err_with_severity(message, LOG_NOTICE);
  1285. break;
  1286. }
  1287. return SUCCESS;
  1288. }
  1289. /* }}} */
  1290. /* {{{ Get the last occurred error as associative array. Returns NULL if there hasn't been an error yet. */
  1291. PHP_FUNCTION(error_get_last)
  1292. {
  1293. ZEND_PARSE_PARAMETERS_NONE();
  1294. if (PG(last_error_message)) {
  1295. zval tmp;
  1296. array_init(return_value);
  1297. ZVAL_LONG(&tmp, PG(last_error_type));
  1298. zend_hash_update(Z_ARR_P(return_value), ZSTR_KNOWN(ZEND_STR_TYPE), &tmp);
  1299. ZVAL_STR_COPY(&tmp, PG(last_error_message));
  1300. zend_hash_update(Z_ARR_P(return_value), ZSTR_KNOWN(ZEND_STR_MESSAGE), &tmp);
  1301. ZVAL_STR_COPY(&tmp, PG(last_error_file));
  1302. zend_hash_update(Z_ARR_P(return_value), ZSTR_KNOWN(ZEND_STR_FILE), &tmp);
  1303. ZVAL_LONG(&tmp, PG(last_error_lineno));
  1304. zend_hash_update(Z_ARR_P(return_value), ZSTR_KNOWN(ZEND_STR_LINE), &tmp);
  1305. }
  1306. }
  1307. /* }}} */
  1308. /* {{{ Clear the last occurred error. */
  1309. PHP_FUNCTION(error_clear_last)
  1310. {
  1311. ZEND_PARSE_PARAMETERS_NONE();
  1312. if (PG(last_error_message)) {
  1313. PG(last_error_type) = 0;
  1314. PG(last_error_lineno) = 0;
  1315. zend_string_release(PG(last_error_message));
  1316. PG(last_error_message) = NULL;
  1317. if (PG(last_error_file)) {
  1318. zend_string_release(PG(last_error_file));
  1319. PG(last_error_file) = NULL;
  1320. }
  1321. }
  1322. }
  1323. /* }}} */
  1324. /* {{{ Call a user function which is the first parameter
  1325. Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
  1326. PHP_FUNCTION(call_user_func)
  1327. {
  1328. zval retval;
  1329. zend_fcall_info fci;
  1330. zend_fcall_info_cache fci_cache;
  1331. ZEND_PARSE_PARAMETERS_START(1, -1)
  1332. Z_PARAM_FUNC(fci, fci_cache)
  1333. Z_PARAM_VARIADIC_WITH_NAMED(fci.params, fci.param_count, fci.named_params)
  1334. ZEND_PARSE_PARAMETERS_END();
  1335. fci.retval = &retval;
  1336. if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
  1337. if (Z_ISREF(retval)) {
  1338. zend_unwrap_reference(&retval);
  1339. }
  1340. ZVAL_COPY_VALUE(return_value, &retval);
  1341. }
  1342. }
  1343. /* }}} */
  1344. /* {{{ Call a user function which is the first parameter with the arguments contained in array
  1345. Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
  1346. PHP_FUNCTION(call_user_func_array)
  1347. {
  1348. zval retval;
  1349. HashTable *params;
  1350. zend_fcall_info fci;
  1351. zend_fcall_info_cache fci_cache;
  1352. ZEND_PARSE_PARAMETERS_START(2, 2)
  1353. Z_PARAM_FUNC(fci, fci_cache)
  1354. Z_PARAM_ARRAY_HT(params)
  1355. ZEND_PARSE_PARAMETERS_END();
  1356. fci.named_params = params;
  1357. fci.retval = &retval;
  1358. if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
  1359. if (Z_ISREF(retval)) {
  1360. zend_unwrap_reference(&retval);
  1361. }
  1362. ZVAL_COPY_VALUE(return_value, &retval);
  1363. }
  1364. }
  1365. /* }}} */
  1366. /* {{{ Call a user function which is the first parameter */
  1367. PHP_FUNCTION(forward_static_call)
  1368. {
  1369. zval retval;
  1370. zend_fcall_info fci;
  1371. zend_fcall_info_cache fci_cache;
  1372. zend_class_entry *called_scope;
  1373. ZEND_PARSE_PARAMETERS_START(1, -1)
  1374. Z_PARAM_FUNC(fci, fci_cache)
  1375. Z_PARAM_VARIADIC('*', fci.params, fci.param_count)
  1376. ZEND_PARSE_PARAMETERS_END();
  1377. if (!EX(prev_execute_data)->func->common.scope) {
  1378. zend_throw_error(NULL, "Cannot call forward_static_call() when no class scope is active");
  1379. RETURN_THROWS();
  1380. }
  1381. fci.retval = &retval;
  1382. called_scope = zend_get_called_scope(execute_data);
  1383. if (called_scope && fci_cache.calling_scope &&
  1384. instanceof_function(called_scope, fci_cache.calling_scope)) {
  1385. fci_cache.called_scope = called_scope;
  1386. }
  1387. if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
  1388. if (Z_ISREF(retval)) {
  1389. zend_unwrap_reference(&retval);
  1390. }
  1391. ZVAL_COPY_VALUE(return_value, &retval);
  1392. }
  1393. }
  1394. /* }}} */
  1395. /* {{{ Call a static method which is the first parameter with the arguments contained in array */
  1396. PHP_FUNCTION(forward_static_call_array)
  1397. {
  1398. zval *params, retval;
  1399. zend_fcall_info fci;
  1400. zend_fcall_info_cache fci_cache;
  1401. zend_class_entry *called_scope;
  1402. ZEND_PARSE_PARAMETERS_START(2, 2)
  1403. Z_PARAM_FUNC(fci, fci_cache)
  1404. Z_PARAM_ARRAY(params)
  1405. ZEND_PARSE_PARAMETERS_END();
  1406. zend_fcall_info_args(&fci, params);
  1407. fci.retval = &retval;
  1408. called_scope = zend_get_called_scope(execute_data);
  1409. if (called_scope && fci_cache.calling_scope &&
  1410. instanceof_function(called_scope, fci_cache.calling_scope)) {
  1411. fci_cache.called_scope = called_scope;
  1412. }
  1413. if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
  1414. if (Z_ISREF(retval)) {
  1415. zend_unwrap_reference(&retval);
  1416. }
  1417. ZVAL_COPY_VALUE(return_value, &retval);
  1418. }
  1419. zend_fcall_info_args_clear(&fci, 1);
  1420. }
  1421. /* }}} */
  1422. static void fci_addref(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache)
  1423. {
  1424. Z_TRY_ADDREF(fci->function_name);
  1425. if (fci_cache->object) {
  1426. GC_ADDREF(fci_cache->object);
  1427. }
  1428. }
  1429. static void fci_release(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache)
  1430. {
  1431. zval_ptr_dtor(&fci->function_name);
  1432. if (fci_cache->object) {
  1433. zend_object_release(fci_cache->object);
  1434. }
  1435. }
  1436. void user_shutdown_function_dtor(zval *zv) /* {{{ */
  1437. {
  1438. php_shutdown_function_entry *shutdown_function_entry = Z_PTR_P(zv);
  1439. zend_fcall_info_args_clear(&shutdown_function_entry->fci, true);
  1440. fci_release(&shutdown_function_entry->fci, &shutdown_function_entry->fci_cache);
  1441. efree(shutdown_function_entry);
  1442. }
  1443. /* }}} */
  1444. void user_tick_function_dtor(user_tick_function_entry *tick_function_entry) /* {{{ */
  1445. {
  1446. zend_fcall_info_args_clear(&tick_function_entry->fci, true);
  1447. fci_release(&tick_function_entry->fci, &tick_function_entry->fci_cache);
  1448. }
  1449. /* }}} */
  1450. static int user_shutdown_function_call(zval *zv) /* {{{ */
  1451. {
  1452. php_shutdown_function_entry *shutdown_function_entry = Z_PTR_P(zv);
  1453. zval retval;
  1454. zend_result call_status;
  1455. /* set retval zval for FCI struct */
  1456. shutdown_function_entry->fci.retval = &retval;
  1457. call_status = zend_call_function(&shutdown_function_entry->fci, &shutdown_function_entry->fci_cache);
  1458. ZEND_ASSERT(call_status == SUCCESS);
  1459. zval_ptr_dtor(&retval);
  1460. return 0;
  1461. }
  1462. /* }}} */
  1463. static void user_tick_function_call(user_tick_function_entry *tick_fe) /* {{{ */
  1464. {
  1465. /* Prevent re-entrant calls to the same user ticks function */
  1466. if (!tick_fe->calling) {
  1467. zval tmp;
  1468. /* set tmp zval */
  1469. tick_fe->fci.retval = &tmp;
  1470. tick_fe->calling = true;
  1471. zend_call_function(&tick_fe->fci, &tick_fe->fci_cache);
  1472. /* Destroy return value */
  1473. zval_ptr_dtor(&tmp);
  1474. tick_fe->calling = false;
  1475. }
  1476. }
  1477. /* }}} */
  1478. static void run_user_tick_functions(int tick_count, void *arg) /* {{{ */
  1479. {
  1480. zend_llist_apply(BG(user_tick_functions), (llist_apply_func_t) user_tick_function_call);
  1481. }
  1482. /* }}} */
  1483. static int user_tick_function_compare(user_tick_function_entry * tick_fe1, user_tick_function_entry * tick_fe2) /* {{{ */
  1484. {
  1485. zval *func1 = &tick_fe1->fci.function_name;
  1486. zval *func2 = &tick_fe2->fci.function_name;
  1487. int ret;
  1488. if (Z_TYPE_P(func1) == IS_STRING && Z_TYPE_P(func2) == IS_STRING) {
  1489. ret = zend_binary_zval_strcmp(func1, func2) == 0;
  1490. } else if (Z_TYPE_P(func1) == IS_ARRAY && Z_TYPE_P(func2) == IS_ARRAY) {
  1491. ret = zend_compare_arrays(func1, func2) == 0;
  1492. } else if (Z_TYPE_P(func1) == IS_OBJECT && Z_TYPE_P(func2) == IS_OBJECT) {
  1493. ret = zend_compare_objects(func1, func2) == 0;
  1494. } else {
  1495. ret = 0;
  1496. }
  1497. if (ret && tick_fe1->calling) {
  1498. zend_throw_error(NULL, "Registered tick function cannot be unregistered while it is being executed");
  1499. return 0;
  1500. }
  1501. return ret;
  1502. }
  1503. /* }}} */
  1504. PHPAPI void php_call_shutdown_functions(void) /* {{{ */
  1505. {
  1506. if (BG(user_shutdown_function_names)) {
  1507. zend_try {
  1508. zend_hash_apply(BG(user_shutdown_function_names), user_shutdown_function_call);
  1509. } zend_end_try();
  1510. }
  1511. }
  1512. /* }}} */
  1513. PHPAPI void php_free_shutdown_functions(void) /* {{{ */
  1514. {
  1515. if (BG(user_shutdown_function_names))
  1516. zend_try {
  1517. zend_hash_destroy(BG(user_shutdown_function_names));
  1518. FREE_HASHTABLE(BG(user_shutdown_function_names));
  1519. BG(user_shutdown_function_names) = NULL;
  1520. } zend_catch {
  1521. /* maybe shutdown method call exit, we just ignore it */
  1522. FREE_HASHTABLE(BG(user_shutdown_function_names));
  1523. BG(user_shutdown_function_names) = NULL;
  1524. } zend_end_try();
  1525. }
  1526. /* }}} */
  1527. /* {{{ Register a user-level function to be called on request termination */
  1528. PHP_FUNCTION(register_shutdown_function)
  1529. {
  1530. php_shutdown_function_entry entry;
  1531. zval *params = NULL;
  1532. uint32_t param_count = 0;
  1533. bool status;
  1534. if (zend_parse_parameters(ZEND_NUM_ARGS(), "f*", &entry.fci, &entry.fci_cache, &params, &param_count) == FAILURE) {
  1535. RETURN_THROWS();
  1536. }
  1537. fci_addref(&entry.fci, &entry.fci_cache);
  1538. zend_fcall_info_argp(&entry.fci, param_count, params);
  1539. status = append_user_shutdown_function(&entry);
  1540. ZEND_ASSERT(status);
  1541. }
  1542. /* }}} */
  1543. PHPAPI bool register_user_shutdown_function(const char *function_name, size_t function_len, php_shutdown_function_entry *shutdown_function_entry) /* {{{ */
  1544. {
  1545. if (!BG(user_shutdown_function_names)) {
  1546. ALLOC_HASHTABLE(BG(user_shutdown_function_names));
  1547. zend_hash_init(BG(user_shutdown_function_names), 0, NULL, user_shutdown_function_dtor, 0);
  1548. }
  1549. zend_hash_str_update_mem(BG(user_shutdown_function_names), function_name, function_len, shutdown_function_entry, sizeof(php_shutdown_function_entry));
  1550. return 1;
  1551. }
  1552. /* }}} */
  1553. PHPAPI bool remove_user_shutdown_function(const char *function_name, size_t function_len) /* {{{ */
  1554. {
  1555. if (BG(user_shutdown_function_names)) {
  1556. return zend_hash_str_del(BG(user_shutdown_function_names), function_name, function_len) != FAILURE;
  1557. }
  1558. return 0;
  1559. }
  1560. /* }}} */
  1561. PHPAPI bool append_user_shutdown_function(php_shutdown_function_entry *shutdown_function_entry) /* {{{ */
  1562. {
  1563. if (!BG(user_shutdown_function_names)) {
  1564. ALLOC_HASHTABLE(BG(user_shutdown_function_names));
  1565. zend_hash_init(BG(user_shutdown_function_names), 0, NULL, user_shutdown_function_dtor, 0);
  1566. }
  1567. return zend_hash_next_index_insert_mem(BG(user_shutdown_function_names), shutdown_function_entry, sizeof(php_shutdown_function_entry)) != NULL;
  1568. }
  1569. /* }}} */
  1570. ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highlighter_ini) /* {{{ */
  1571. {
  1572. syntax_highlighter_ini->highlight_comment = INI_STR("highlight.comment");
  1573. syntax_highlighter_ini->highlight_default = INI_STR("highlight.default");
  1574. syntax_highlighter_ini->highlight_html = INI_STR("highlight.html");
  1575. syntax_highlighter_ini->highlight_keyword = INI_STR("highlight.keyword");
  1576. syntax_highlighter_ini->highlight_string = INI_STR("highlight.string");
  1577. }
  1578. /* }}} */
  1579. /* {{{ Syntax highlight a source file */
  1580. PHP_FUNCTION(highlight_file)
  1581. {
  1582. char *filename;
  1583. size_t filename_len;
  1584. int ret;
  1585. zend_syntax_highlighter_ini syntax_highlighter_ini;
  1586. bool i = 0;
  1587. ZEND_PARSE_PARAMETERS_START(1, 2)
  1588. Z_PARAM_PATH(filename, filename_len)
  1589. Z_PARAM_OPTIONAL
  1590. Z_PARAM_BOOL(i)
  1591. ZEND_PARSE_PARAMETERS_END();
  1592. if (php_check_open_basedir(filename)) {
  1593. RETURN_FALSE;
  1594. }
  1595. if (i) {
  1596. php_output_start_default();
  1597. }
  1598. php_get_highlight_struct(&syntax_highlighter_ini);
  1599. ret = highlight_file(filename, &syntax_highlighter_ini);
  1600. if (ret == FAILURE) {
  1601. if (i) {
  1602. php_output_end();
  1603. }
  1604. RETURN_FALSE;
  1605. }
  1606. if (i) {
  1607. php_output_get_contents(return_value);
  1608. php_output_discard();
  1609. ZEND_ASSERT(Z_TYPE_P(return_value) == IS_STRING);
  1610. } else {
  1611. RETURN_TRUE;
  1612. }
  1613. }
  1614. /* }}} */
  1615. /* {{{ Return source with stripped comments and whitespace */
  1616. PHP_FUNCTION(php_strip_whitespace)
  1617. {
  1618. zend_string *filename;
  1619. zend_lex_state original_lex_state;
  1620. zend_file_handle file_handle;
  1621. ZEND_PARSE_PARAMETERS_START(1, 1)
  1622. Z_PARAM_PATH_STR(filename)
  1623. ZEND_PARSE_PARAMETERS_END();
  1624. php_output_start_default();
  1625. zend_stream_init_filename_ex(&file_handle, filename);
  1626. zend_save_lexical_state(&original_lex_state);
  1627. if (open_file_for_scanning(&file_handle) == FAILURE) {
  1628. zend_restore_lexical_state(&original_lex_state);
  1629. php_output_end();
  1630. zend_destroy_file_handle(&file_handle);
  1631. RETURN_EMPTY_STRING();
  1632. }
  1633. zend_strip();
  1634. zend_restore_lexical_state(&original_lex_state);
  1635. php_output_get_contents(return_value);
  1636. php_output_discard();
  1637. zend_destroy_file_handle(&file_handle);
  1638. }
  1639. /* }}} */
  1640. /* {{{ Syntax highlight a string or optionally return it */
  1641. PHP_FUNCTION(highlight_string)
  1642. {
  1643. zend_string *str;
  1644. zend_syntax_highlighter_ini syntax_highlighter_ini;
  1645. char *hicompiled_string_description;
  1646. bool i = 0;
  1647. int old_error_reporting = EG(error_reporting);
  1648. ZEND_PARSE_PARAMETERS_START(1, 2)
  1649. Z_PARAM_STR(str)
  1650. Z_PARAM_OPTIONAL
  1651. Z_PARAM_BOOL(i)
  1652. ZEND_PARSE_PARAMETERS_END();
  1653. if (i) {
  1654. php_output_start_default();
  1655. }
  1656. EG(error_reporting) = E_ERROR;
  1657. php_get_highlight_struct(&syntax_highlighter_ini);
  1658. hicompiled_string_description = zend_make_compiled_string_description("highlighted code");
  1659. highlight_string(str, &syntax_highlighter_ini, hicompiled_string_description);
  1660. efree(hicompiled_string_description);
  1661. EG(error_reporting) = old_error_reporting;
  1662. if (i) {
  1663. php_output_get_contents(return_value);
  1664. php_output_discard();
  1665. ZEND_ASSERT(Z_TYPE_P(return_value) == IS_STRING);
  1666. } else {
  1667. // TODO Make this function void?
  1668. RETURN_TRUE;
  1669. }
  1670. }
  1671. /* }}} */
  1672. /* {{{ Get a configuration option */
  1673. PHP_FUNCTION(ini_get)
  1674. {
  1675. zend_string *varname, *val;
  1676. ZEND_PARSE_PARAMETERS_START(1, 1)
  1677. Z_PARAM_STR(varname)
  1678. ZEND_PARSE_PARAMETERS_END();
  1679. val = zend_ini_get_value(varname);
  1680. if (!val) {
  1681. RETURN_FALSE;
  1682. }
  1683. ZVAL_SET_INI_STR(return_value, val);
  1684. }
  1685. /* }}} */
  1686. /* {{{ Get all configuration options */
  1687. PHP_FUNCTION(ini_get_all)
  1688. {
  1689. char *extname = NULL;
  1690. size_t extname_len = 0, module_number = 0;
  1691. zend_module_entry *module;
  1692. bool details = 1;
  1693. zend_string *key;
  1694. zend_ini_entry *ini_entry;
  1695. ZEND_PARSE_PARAMETERS_START(0, 2)
  1696. Z_PARAM_OPTIONAL
  1697. Z_PARAM_STRING_OR_NULL(extname, extname_len)
  1698. Z_PARAM_BOOL(details)
  1699. ZEND_PARSE_PARAMETERS_END();
  1700. zend_ini_sort_entries();
  1701. if (extname) {
  1702. if ((module = zend_hash_str_find_ptr(&module_registry, extname, extname_len)) == NULL) {
  1703. php_error_docref(NULL, E_WARNING, "Extension \"%s\" cannot be found", extname);
  1704. RETURN_FALSE;
  1705. }
  1706. module_number = module->module_number;
  1707. }
  1708. array_init(return_value);
  1709. ZEND_HASH_FOREACH_STR_KEY_PTR(EG(ini_directives), key, ini_entry) {
  1710. zval option;
  1711. if (module_number != 0 && ini_entry->module_number != module_number) {
  1712. continue;
  1713. }
  1714. if (key == NULL || ZSTR_VAL(key)[0] != 0) {
  1715. if (details) {
  1716. array_init(&option);
  1717. if (ini_entry->orig_value) {
  1718. add_assoc_str(&option, "global_value", zend_string_copy(ini_entry->orig_value));
  1719. } else if (ini_entry->value) {
  1720. add_assoc_str(&option, "global_value", zend_string_copy(ini_entry->value));
  1721. } else {
  1722. add_assoc_null(&option, "global_value");
  1723. }
  1724. if (ini_entry->value) {
  1725. add_assoc_str(&option, "local_value", zend_string_copy(ini_entry->value));
  1726. } else {
  1727. add_assoc_null(&option, "local_value");
  1728. }
  1729. add_assoc_long(&option, "access", ini_entry->modifiable);
  1730. zend_symtable_update(Z_ARRVAL_P(return_value), ini_entry->name, &option);
  1731. } else {
  1732. if (ini_entry->value) {
  1733. zval zv;
  1734. ZVAL_STR_COPY(&zv, ini_entry->value);
  1735. zend_symtable_update(Z_ARRVAL_P(return_value), ini_entry->name, &zv);
  1736. } else {
  1737. zend_symtable_update(Z_ARRVAL_P(return_value), ini_entry->name, &EG(uninitialized_zval));
  1738. }
  1739. }
  1740. }
  1741. } ZEND_HASH_FOREACH_END();
  1742. }
  1743. /* }}} */
  1744. static int php_ini_check_path(char *option_name, size_t option_len, char *new_option_name, size_t new_option_len) /* {{{ */
  1745. {
  1746. if (option_len + 1 != new_option_len) {
  1747. return 0;
  1748. }
  1749. return !strncmp(option_name, new_option_name, option_len);
  1750. }
  1751. /* }}} */
  1752. /* {{{ Set a configuration option, returns false on error and the old value of the configuration option on success */
  1753. PHP_FUNCTION(ini_set)
  1754. {
  1755. zend_string *varname;
  1756. zval *new_value;
  1757. zend_string *val;
  1758. ZEND_PARSE_PARAMETERS_START(2, 2)
  1759. Z_PARAM_STR(varname)
  1760. Z_PARAM_ZVAL(new_value)
  1761. ZEND_PARSE_PARAMETERS_END();
  1762. if (Z_TYPE_P(new_value) > IS_STRING) {
  1763. zend_argument_type_error(2, "must be of type string|int|float|bool|null");
  1764. RETURN_THROWS();
  1765. }
  1766. val = zend_ini_get_value(varname);
  1767. if (val) {
  1768. ZVAL_SET_INI_STR(return_value, val);
  1769. } else {
  1770. RETVAL_FALSE;
  1771. }
  1772. zend_string *new_value_tmp_str;
  1773. zend_string *new_value_str = zval_get_tmp_string(new_value, &new_value_tmp_str);
  1774. #define _CHECK_PATH(var, var_len, ini) php_ini_check_path(var, var_len, ini, sizeof(ini))
  1775. /* open basedir check */
  1776. if (PG(open_basedir)) {
  1777. if (_CHECK_PATH(ZSTR_VAL(varname), ZSTR_LEN(varname), "error_log") ||
  1778. _CHECK_PATH(ZSTR_VAL(varname), ZSTR_LEN(varname), "java.class.path") ||
  1779. _CHECK_PATH(ZSTR_VAL(varname), ZSTR_LEN(varname), "java.home") ||
  1780. _CHECK_PATH(ZSTR_VAL(varname), ZSTR_LEN(varname), "mail.log") ||
  1781. _CHECK_PATH(ZSTR_VAL(varname), ZSTR_LEN(varname), "java.library.path") ||
  1782. _CHECK_PATH(ZSTR_VAL(varname), ZSTR_LEN(varname), "vpopmail.directory")) {
  1783. if (php_check_open_basedir(ZSTR_VAL(new_value_str))) {
  1784. zval_ptr_dtor_str(return_value);
  1785. zend_tmp_string_release(new_value_tmp_str);
  1786. RETURN_FALSE;
  1787. }
  1788. }
  1789. }
  1790. #undef _CHECK_PATH
  1791. if (zend_alter_ini_entry_ex(varname, new_value_str, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0) == FAILURE) {
  1792. zval_ptr_dtor_str(return_value);
  1793. RETVAL_FALSE;
  1794. }
  1795. zend_tmp_string_release(new_value_tmp_str);
  1796. }
  1797. /* }}} */
  1798. /* {{{ Restore the value of a configuration option specified by varname */
  1799. PHP_FUNCTION(ini_restore)
  1800. {
  1801. zend_string *varname;
  1802. ZEND_PARSE_PARAMETERS_START(1, 1)
  1803. Z_PARAM_STR(varname)
  1804. ZEND_PARSE_PARAMETERS_END();
  1805. zend_restore_ini_entry(varname, PHP_INI_STAGE_RUNTIME);
  1806. }
  1807. /* }}} */
  1808. /* {{{ Sets the include_path configuration option */
  1809. PHP_FUNCTION(set_include_path)
  1810. {
  1811. zend_string *new_value;
  1812. char *old_value;
  1813. zend_string *key;
  1814. ZEND_PARSE_PARAMETERS_START(1, 1)
  1815. Z_PARAM_PATH_STR(new_value)
  1816. ZEND_PARSE_PARAMETERS_END();
  1817. old_value = zend_ini_string("include_path", sizeof("include_path") - 1, 0);
  1818. /* copy to return here, because alter might free it! */
  1819. if (old_value) {
  1820. RETVAL_STRING(old_value);
  1821. } else {
  1822. RETVAL_FALSE;
  1823. }
  1824. key = zend_string_init("include_path", sizeof("include_path") - 1, 0);
  1825. if (zend_alter_ini_entry_ex(key, new_value, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0) == FAILURE) {
  1826. zend_string_release_ex(key, 0);
  1827. zval_ptr_dtor_str(return_value);
  1828. RETURN_FALSE;
  1829. }
  1830. zend_string_release_ex(key, 0);
  1831. }
  1832. /* }}} */
  1833. /* {{{ Get the current include_path configuration option */
  1834. PHP_FUNCTION(get_include_path)
  1835. {
  1836. char *str;
  1837. ZEND_PARSE_PARAMETERS_NONE();
  1838. str = zend_ini_string("include_path", sizeof("include_path") - 1, 0);
  1839. if (str == NULL) {
  1840. RETURN_FALSE;
  1841. }
  1842. RETURN_STRING(str);
  1843. }
  1844. /* }}} */
  1845. /* {{{ Prints out or returns information about the specified variable */
  1846. PHP_FUNCTION(print_r)
  1847. {
  1848. zval *var;
  1849. bool do_return = 0;
  1850. ZEND_PARSE_PARAMETERS_START(1, 2)
  1851. Z_PARAM_ZVAL(var)
  1852. Z_PARAM_OPTIONAL
  1853. Z_PARAM_BOOL(do_return)
  1854. ZEND_PARSE_PARAMETERS_END();
  1855. if (do_return) {
  1856. RETURN_STR(zend_print_zval_r_to_str(var, 0));
  1857. } else {
  1858. zend_print_zval_r(var, 0);
  1859. RETURN_TRUE;
  1860. }
  1861. }
  1862. /* }}} */
  1863. /* {{{ Returns true if client disconnected */
  1864. PHP_FUNCTION(connection_aborted)
  1865. {
  1866. ZEND_PARSE_PARAMETERS_NONE();
  1867. RETURN_LONG(PG(connection_status) & PHP_CONNECTION_ABORTED);
  1868. }
  1869. /* }}} */
  1870. /* {{{ Returns the connection status bitfield */
  1871. PHP_FUNCTION(connection_status)
  1872. {
  1873. ZEND_PARSE_PARAMETERS_NONE();
  1874. RETURN_LONG(PG(connection_status));
  1875. }
  1876. /* }}} */
  1877. /* {{{ Set whether we want to ignore a user abort event or not */
  1878. PHP_FUNCTION(ignore_user_abort)
  1879. {
  1880. bool arg = 0;
  1881. bool arg_is_null = 1;
  1882. int old_setting;
  1883. ZEND_PARSE_PARAMETERS_START(0, 1)
  1884. Z_PARAM_OPTIONAL
  1885. Z_PARAM_BOOL_OR_NULL(arg, arg_is_null)
  1886. ZEND_PARSE_PARAMETERS_END();
  1887. old_setting = (unsigned short)PG(ignore_user_abort);
  1888. if (!arg_is_null) {
  1889. zend_string *key = zend_string_init("ignore_user_abort", sizeof("ignore_user_abort") - 1, 0);
  1890. zend_alter_ini_entry_chars(key, arg ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
  1891. zend_string_release_ex(key, 0);
  1892. }
  1893. RETURN_LONG(old_setting);
  1894. }
  1895. /* }}} */
  1896. #if HAVE_GETSERVBYNAME
  1897. /* {{{ Returns port associated with service. Protocol must be "tcp" or "udp" */
  1898. PHP_FUNCTION(getservbyname)
  1899. {
  1900. zend_string *name;
  1901. char *proto;
  1902. size_t proto_len;
  1903. struct servent *serv;
  1904. ZEND_PARSE_PARAMETERS_START(2, 2)
  1905. Z_PARAM_STR(name)
  1906. Z_PARAM_STRING(proto, proto_len)
  1907. ZEND_PARSE_PARAMETERS_END();
  1908. /* empty string behaves like NULL on windows implementation of
  1909. getservbyname. Let be portable instead. */
  1910. #ifdef PHP_WIN32
  1911. if (proto_len == 0) {
  1912. RETURN_FALSE;
  1913. }
  1914. #endif
  1915. serv = getservbyname(ZSTR_VAL(name), proto);
  1916. #if defined(_AIX)
  1917. /*
  1918. On AIX, imap is only known as imap2 in /etc/services, while on Linux imap is an alias for imap2.
  1919. If a request for imap gives no result, we try again with imap2.
  1920. */
  1921. if (serv == NULL && zend_string_equals_literal(name, "imap")) {
  1922. serv = getservbyname("imap2", proto);
  1923. }
  1924. #endif
  1925. if (serv == NULL) {
  1926. RETURN_FALSE;
  1927. }
  1928. RETURN_LONG(ntohs(serv->s_port));
  1929. }
  1930. /* }}} */
  1931. #endif
  1932. #if HAVE_GETSERVBYPORT
  1933. /* {{{ Returns service name associated with port. Protocol must be "tcp" or "udp" */
  1934. PHP_FUNCTION(getservbyport)
  1935. {
  1936. char *proto;
  1937. size_t proto_len;
  1938. zend_long port;
  1939. struct servent *serv;
  1940. ZEND_PARSE_PARAMETERS_START(2, 2)
  1941. Z_PARAM_LONG(port)
  1942. Z_PARAM_STRING(proto, proto_len)
  1943. ZEND_PARSE_PARAMETERS_END();
  1944. serv = getservbyport(htons((unsigned short) port), proto);
  1945. if (serv == NULL) {
  1946. RETURN_FALSE;
  1947. }
  1948. RETURN_STRING(serv->s_name);
  1949. }
  1950. /* }}} */
  1951. #endif
  1952. #if HAVE_GETPROTOBYNAME
  1953. /* {{{ Returns protocol number associated with name as per /etc/protocols */
  1954. PHP_FUNCTION(getprotobyname)
  1955. {
  1956. char *name;
  1957. size_t name_len;
  1958. struct protoent *ent;
  1959. ZEND_PARSE_PARAMETERS_START(1, 1)
  1960. Z_PARAM_STRING(name, name_len)
  1961. ZEND_PARSE_PARAMETERS_END();
  1962. ent = getprotobyname(name);
  1963. if (ent == NULL) {
  1964. RETURN_FALSE;
  1965. }
  1966. RETURN_LONG(ent->p_proto);
  1967. }
  1968. /* }}} */
  1969. #endif
  1970. #if HAVE_GETPROTOBYNUMBER
  1971. /* {{{ Returns protocol name associated with protocol number proto */
  1972. PHP_FUNCTION(getprotobynumber)
  1973. {
  1974. zend_long proto;
  1975. struct protoent *ent;
  1976. ZEND_PARSE_PARAMETERS_START(1, 1)
  1977. Z_PARAM_LONG(proto)
  1978. ZEND_PARSE_PARAMETERS_END();
  1979. ent = getprotobynumber((int)proto);
  1980. if (ent == NULL) {
  1981. RETURN_FALSE;
  1982. }
  1983. RETURN_STRING(ent->p_name);
  1984. }
  1985. /* }}} */
  1986. #endif
  1987. /* {{{ Registers a tick callback function */
  1988. PHP_FUNCTION(register_tick_function)
  1989. {
  1990. user_tick_function_entry tick_fe;
  1991. zval *params = NULL;
  1992. uint32_t param_count = 0;
  1993. if (zend_parse_parameters(ZEND_NUM_ARGS(), "f*", &tick_fe.fci, &tick_fe.fci_cache, &params, &param_count) == FAILURE) {
  1994. RETURN_THROWS();
  1995. }
  1996. tick_fe.calling = false;
  1997. fci_addref(&tick_fe.fci, &tick_fe.fci_cache);
  1998. zend_fcall_info_argp(&tick_fe.fci, param_count, params);
  1999. if (!BG(user_tick_functions)) {
  2000. BG(user_tick_functions) = (zend_llist *) emalloc(sizeof(zend_llist));
  2001. zend_llist_init(BG(user_tick_functions),
  2002. sizeof(user_tick_function_entry),
  2003. (llist_dtor_func_t) user_tick_function_dtor, 0);
  2004. php_add_tick_function(run_user_tick_functions, NULL);
  2005. }
  2006. zend_llist_add_element(BG(user_tick_functions), &tick_fe);
  2007. RETURN_TRUE;
  2008. }
  2009. /* }}} */
  2010. /* {{{ Unregisters a tick callback function */
  2011. PHP_FUNCTION(unregister_tick_function)
  2012. {
  2013. user_tick_function_entry tick_fe;
  2014. ZEND_PARSE_PARAMETERS_START(1, 1)
  2015. Z_PARAM_FUNC(tick_fe.fci, tick_fe.fci_cache)
  2016. ZEND_PARSE_PARAMETERS_END();
  2017. if (!BG(user_tick_functions)) {
  2018. return;
  2019. }
  2020. zend_llist_del_element(BG(user_tick_functions), &tick_fe, (int (*)(void *, void *)) user_tick_function_compare);
  2021. }
  2022. /* }}} */
  2023. /* {{{ Check if file was created by rfc1867 upload */
  2024. PHP_FUNCTION(is_uploaded_file)
  2025. {
  2026. char *path;
  2027. size_t path_len;
  2028. ZEND_PARSE_PARAMETERS_START(1, 1)
  2029. Z_PARAM_PATH(path, path_len)
  2030. ZEND_PARSE_PARAMETERS_END();
  2031. if (!SG(rfc1867_uploaded_files)) {
  2032. RETURN_FALSE;
  2033. }
  2034. if (zend_hash_str_exists(SG(rfc1867_uploaded_files), path, path_len)) {
  2035. RETURN_TRUE;
  2036. } else {
  2037. RETURN_FALSE;
  2038. }
  2039. }
  2040. /* }}} */
  2041. /* {{{ Move a file if and only if it was created by an upload */
  2042. PHP_FUNCTION(move_uploaded_file)
  2043. {
  2044. char *path, *new_path;
  2045. size_t path_len, new_path_len;
  2046. bool successful = 0;
  2047. #ifndef PHP_WIN32
  2048. int oldmask; int ret;
  2049. #endif
  2050. ZEND_PARSE_PARAMETERS_START(2, 2)
  2051. Z_PARAM_STRING(path, path_len)
  2052. Z_PARAM_PATH(new_path, new_path_len)
  2053. ZEND_PARSE_PARAMETERS_END();
  2054. if (!SG(rfc1867_uploaded_files)) {
  2055. RETURN_FALSE;
  2056. }
  2057. if (!zend_hash_str_exists(SG(rfc1867_uploaded_files), path, path_len)) {
  2058. RETURN_FALSE;
  2059. }
  2060. if (php_check_open_basedir(new_path)) {
  2061. RETURN_FALSE;
  2062. }
  2063. if (VCWD_RENAME(path, new_path) == 0) {
  2064. successful = 1;
  2065. #ifndef PHP_WIN32
  2066. oldmask = umask(077);
  2067. umask(oldmask);
  2068. ret = VCWD_CHMOD(new_path, 0666 & ~oldmask);
  2069. if (ret == -1) {
  2070. php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
  2071. }
  2072. #endif
  2073. } else if (php_copy_file_ex(path, new_path, STREAM_DISABLE_OPEN_BASEDIR) == SUCCESS) {
  2074. VCWD_UNLINK(path);
  2075. successful = 1;
  2076. }
  2077. if (successful) {
  2078. zend_hash_str_del(SG(rfc1867_uploaded_files), path, path_len);
  2079. } else {
  2080. php_error_docref(NULL, E_WARNING, "Unable to move \"%s\" to \"%s\"", path, new_path);
  2081. }
  2082. RETURN_BOOL(successful);
  2083. }
  2084. /* }}} */
  2085. /* {{{ php_simple_ini_parser_cb */
  2086. static void php_simple_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_type, zval *arr)
  2087. {
  2088. switch (callback_type) {
  2089. case ZEND_INI_PARSER_ENTRY:
  2090. if (!arg2) {
  2091. /* bare string - nothing to do */
  2092. break;
  2093. }
  2094. Z_TRY_ADDREF_P(arg2);
  2095. zend_symtable_update(Z_ARRVAL_P(arr), Z_STR_P(arg1), arg2);
  2096. break;
  2097. case ZEND_INI_PARSER_POP_ENTRY:
  2098. {
  2099. zval hash, *find_hash;
  2100. if (!arg2) {
  2101. /* bare string - nothing to do */
  2102. break;
  2103. }
  2104. if (!(Z_STRLEN_P(arg1) > 1 && Z_STRVAL_P(arg1)[0] == '0') && is_numeric_string(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), NULL, NULL, 0) == IS_LONG) {
  2105. zend_ulong key = (zend_ulong) zend_atol(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1));
  2106. if ((find_hash = zend_hash_index_find(Z_ARRVAL_P(arr), key)) == NULL) {
  2107. array_init(&hash);
  2108. find_hash = zend_hash_index_add_new(Z_ARRVAL_P(arr), key, &hash);
  2109. }
  2110. } else {
  2111. if ((find_hash = zend_hash_find(Z_ARRVAL_P(arr), Z_STR_P(arg1))) == NULL) {
  2112. array_init(&hash);
  2113. find_hash = zend_hash_add_new(Z_ARRVAL_P(arr), Z_STR_P(arg1), &hash);
  2114. }
  2115. }
  2116. if (Z_TYPE_P(find_hash) != IS_ARRAY) {
  2117. zval_ptr_dtor_nogc(find_hash);
  2118. array_init(find_hash);
  2119. }
  2120. if (!arg3 || (Z_TYPE_P(arg3) == IS_STRING && Z_STRLEN_P(arg3) == 0)) {
  2121. Z_TRY_ADDREF_P(arg2);
  2122. add_next_index_zval(find_hash, arg2);
  2123. } else {
  2124. array_set_zval_key(Z_ARRVAL_P(find_hash), arg3, arg2);
  2125. }
  2126. }
  2127. break;
  2128. case ZEND_INI_PARSER_SECTION:
  2129. break;
  2130. }
  2131. }
  2132. /* }}} */
  2133. /* {{{ php_ini_parser_cb_with_sections */
  2134. static void php_ini_parser_cb_with_sections(zval *arg1, zval *arg2, zval *arg3, int callback_type, zval *arr)
  2135. {
  2136. if (callback_type == ZEND_INI_PARSER_SECTION) {
  2137. array_init(&BG(active_ini_file_section));
  2138. zend_symtable_update(Z_ARRVAL_P(arr), Z_STR_P(arg1), &BG(active_ini_file_section));
  2139. } else if (arg2) {
  2140. zval *active_arr;
  2141. if (Z_TYPE(BG(active_ini_file_section)) != IS_UNDEF) {
  2142. active_arr = &BG(active_ini_file_section);
  2143. } else {
  2144. active_arr = arr;
  2145. }
  2146. php_simple_ini_parser_cb(arg1, arg2, arg3, callback_type, active_arr);
  2147. }
  2148. }
  2149. /* }}} */
  2150. /* {{{ Parse configuration file */
  2151. PHP_FUNCTION(parse_ini_file)
  2152. {
  2153. zend_string *filename = NULL;
  2154. bool process_sections = 0;
  2155. zend_long scanner_mode = ZEND_INI_SCANNER_NORMAL;
  2156. zend_file_handle fh;
  2157. zend_ini_parser_cb_t ini_parser_cb;
  2158. ZEND_PARSE_PARAMETERS_START(1, 3)
  2159. Z_PARAM_PATH_STR(filename)
  2160. Z_PARAM_OPTIONAL
  2161. Z_PARAM_BOOL(process_sections)
  2162. Z_PARAM_LONG(scanner_mode)
  2163. ZEND_PARSE_PARAMETERS_END();
  2164. if (ZSTR_LEN(filename) == 0) {
  2165. zend_argument_value_error(1, "cannot be empty");
  2166. RETURN_THROWS();
  2167. }
  2168. /* Set callback function */
  2169. if (process_sections) {
  2170. ZVAL_UNDEF(&BG(active_ini_file_section));
  2171. ini_parser_cb = (zend_ini_parser_cb_t) php_ini_parser_cb_with_sections;
  2172. } else {
  2173. ini_parser_cb = (zend_ini_parser_cb_t) php_simple_ini_parser_cb;
  2174. }
  2175. /* Setup filehandle */
  2176. zend_stream_init_filename_ex(&fh, filename);
  2177. array_init(return_value);
  2178. if (zend_parse_ini_file(&fh, 0, (int)scanner_mode, ini_parser_cb, return_value) == FAILURE) {
  2179. zend_array_destroy(Z_ARR_P(return_value));
  2180. RETVAL_FALSE;
  2181. }
  2182. zend_destroy_file_handle(&fh);
  2183. }
  2184. /* }}} */
  2185. /* {{{ Parse configuration string */
  2186. PHP_FUNCTION(parse_ini_string)
  2187. {
  2188. char *string = NULL, *str = NULL;
  2189. size_t str_len = 0;
  2190. bool process_sections = 0;
  2191. zend_long scanner_mode = ZEND_INI_SCANNER_NORMAL;
  2192. zend_ini_parser_cb_t ini_parser_cb;
  2193. ZEND_PARSE_PARAMETERS_START(1, 3)
  2194. Z_PARAM_STRING(str, str_len)
  2195. Z_PARAM_OPTIONAL
  2196. Z_PARAM_BOOL(process_sections)
  2197. Z_PARAM_LONG(scanner_mode)
  2198. ZEND_PARSE_PARAMETERS_END();
  2199. if (INT_MAX - str_len < ZEND_MMAP_AHEAD) {
  2200. RETVAL_FALSE;
  2201. }
  2202. /* Set callback function */
  2203. if (process_sections) {
  2204. ZVAL_UNDEF(&BG(active_ini_file_section));
  2205. ini_parser_cb = (zend_ini_parser_cb_t) php_ini_parser_cb_with_sections;
  2206. } else {
  2207. ini_parser_cb = (zend_ini_parser_cb_t) php_simple_ini_parser_cb;
  2208. }
  2209. /* Setup string */
  2210. string = (char *) emalloc(str_len + ZEND_MMAP_AHEAD);
  2211. memcpy(string, str, str_len);
  2212. memset(string + str_len, 0, ZEND_MMAP_AHEAD);
  2213. array_init(return_value);
  2214. if (zend_parse_ini_string(string, 0, (int)scanner_mode, ini_parser_cb, return_value) == FAILURE) {
  2215. zend_array_destroy(Z_ARR_P(return_value));
  2216. RETVAL_FALSE;
  2217. }
  2218. efree(string);
  2219. }
  2220. /* }}} */
  2221. #if ZEND_DEBUG
  2222. /* This function returns an array of ALL valid ini options with values and
  2223. * is not the same as ini_get_all() which returns only registered ini options. Only useful for devs to debug php.ini scanner/parser! */
  2224. PHP_FUNCTION(config_get_hash) /* {{{ */
  2225. {
  2226. ZEND_PARSE_PARAMETERS_NONE();
  2227. HashTable *hash = php_ini_get_configuration_hash();
  2228. array_init(return_value);
  2229. add_config_entries(hash, return_value);
  2230. }
  2231. /* }}} */
  2232. #endif
  2233. #ifdef HAVE_GETLOADAVG
  2234. /* {{{ */
  2235. PHP_FUNCTION(sys_getloadavg)
  2236. {
  2237. double load[3];
  2238. ZEND_PARSE_PARAMETERS_NONE();
  2239. if (getloadavg(load, 3) == -1) {
  2240. RETURN_FALSE;
  2241. } else {
  2242. array_init(return_value);
  2243. add_index_double(return_value, 0, load[0]);
  2244. add_index_double(return_value, 1, load[1]);
  2245. add_index_double(return_value, 2, load[2]);
  2246. }
  2247. }
  2248. /* }}} */
  2249. #endif