php_ftp.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 7 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2018 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Andrew Skalski <askalski@chek.com> |
  16. | Stefan Esser <sesser@php.net> (resume functions) |
  17. +----------------------------------------------------------------------+
  18. */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include "php.h"
  23. #ifdef HAVE_FTP_SSL
  24. # include <openssl/ssl.h>
  25. #endif
  26. #if HAVE_FTP
  27. #include "ext/standard/info.h"
  28. #include "ext/standard/file.h"
  29. #include "php_ftp.h"
  30. #include "ftp.h"
  31. static int le_ftpbuf;
  32. #define le_ftpbuf_name "FTP Buffer"
  33. /* {{{ arginfo */
  34. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_connect, 0, 0, 1)
  35. ZEND_ARG_INFO(0, host)
  36. ZEND_ARG_INFO(0, port)
  37. ZEND_ARG_INFO(0, timeout)
  38. ZEND_END_ARG_INFO()
  39. #ifdef HAVE_FTP_SSL
  40. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_ssl_connect, 0, 0, 1)
  41. ZEND_ARG_INFO(0, host)
  42. ZEND_ARG_INFO(0, port)
  43. ZEND_ARG_INFO(0, timeout)
  44. ZEND_END_ARG_INFO()
  45. #endif
  46. ZEND_BEGIN_ARG_INFO(arginfo_ftp_login, 0)
  47. ZEND_ARG_INFO(0, ftp)
  48. ZEND_ARG_INFO(0, username)
  49. ZEND_ARG_INFO(0, password)
  50. ZEND_END_ARG_INFO()
  51. ZEND_BEGIN_ARG_INFO(arginfo_ftp_pwd, 0)
  52. ZEND_ARG_INFO(0, ftp)
  53. ZEND_END_ARG_INFO()
  54. ZEND_BEGIN_ARG_INFO(arginfo_ftp_cdup, 0)
  55. ZEND_ARG_INFO(0, ftp)
  56. ZEND_END_ARG_INFO()
  57. ZEND_BEGIN_ARG_INFO(arginfo_ftp_chdir, 0)
  58. ZEND_ARG_INFO(0, ftp)
  59. ZEND_ARG_INFO(0, directory)
  60. ZEND_END_ARG_INFO()
  61. ZEND_BEGIN_ARG_INFO(arginfo_ftp_exec, 0)
  62. ZEND_ARG_INFO(0, ftp)
  63. ZEND_ARG_INFO(0, command)
  64. ZEND_END_ARG_INFO()
  65. ZEND_BEGIN_ARG_INFO(arginfo_ftp_raw, 0)
  66. ZEND_ARG_INFO(0, ftp)
  67. ZEND_ARG_INFO(0, command)
  68. ZEND_END_ARG_INFO()
  69. ZEND_BEGIN_ARG_INFO(arginfo_ftp_mkdir, 0)
  70. ZEND_ARG_INFO(0, ftp)
  71. ZEND_ARG_INFO(0, directory)
  72. ZEND_END_ARG_INFO()
  73. ZEND_BEGIN_ARG_INFO(arginfo_ftp_rmdir, 0)
  74. ZEND_ARG_INFO(0, ftp)
  75. ZEND_ARG_INFO(0, directory)
  76. ZEND_END_ARG_INFO()
  77. ZEND_BEGIN_ARG_INFO(arginfo_ftp_chmod, 0)
  78. ZEND_ARG_INFO(0, ftp)
  79. ZEND_ARG_INFO(0, mode)
  80. ZEND_ARG_INFO(0, filename)
  81. ZEND_END_ARG_INFO()
  82. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_alloc, 0, 0, 2)
  83. ZEND_ARG_INFO(0, ftp)
  84. ZEND_ARG_INFO(0, size)
  85. ZEND_ARG_INFO(1, response)
  86. ZEND_END_ARG_INFO()
  87. ZEND_BEGIN_ARG_INFO(arginfo_ftp_nlist, 0)
  88. ZEND_ARG_INFO(0, ftp)
  89. ZEND_ARG_INFO(0, directory)
  90. ZEND_END_ARG_INFO()
  91. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_rawlist, 0, 0, 2)
  92. ZEND_ARG_INFO(0, ftp)
  93. ZEND_ARG_INFO(0, directory)
  94. ZEND_ARG_INFO(0, recursive)
  95. ZEND_END_ARG_INFO()
  96. ZEND_BEGIN_ARG_INFO(arginfo_ftp_mlsd, 0)
  97. ZEND_ARG_INFO(0, ftp)
  98. ZEND_ARG_INFO(0, directory)
  99. ZEND_END_ARG_INFO()
  100. ZEND_BEGIN_ARG_INFO(arginfo_ftp_systype, 0)
  101. ZEND_ARG_INFO(0, ftp)
  102. ZEND_END_ARG_INFO()
  103. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_fget, 0, 0, 3)
  104. ZEND_ARG_INFO(0, ftp)
  105. ZEND_ARG_INFO(0, fp)
  106. ZEND_ARG_INFO(0, remote_file)
  107. ZEND_ARG_INFO(0, mode)
  108. ZEND_ARG_INFO(0, resumepos)
  109. ZEND_END_ARG_INFO()
  110. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_fget, 0, 0, 3)
  111. ZEND_ARG_INFO(0, ftp)
  112. ZEND_ARG_INFO(0, fp)
  113. ZEND_ARG_INFO(0, remote_file)
  114. ZEND_ARG_INFO(0, mode)
  115. ZEND_ARG_INFO(0, resumepos)
  116. ZEND_END_ARG_INFO()
  117. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_pasv, 0, 0, 2)
  118. ZEND_ARG_INFO(0, ftp)
  119. ZEND_ARG_INFO(0, pasv)
  120. ZEND_END_ARG_INFO()
  121. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_get, 0, 0, 3)
  122. ZEND_ARG_INFO(0, ftp)
  123. ZEND_ARG_INFO(0, local_file)
  124. ZEND_ARG_INFO(0, remote_file)
  125. ZEND_ARG_INFO(0, mode)
  126. ZEND_ARG_INFO(0, resume_pos)
  127. ZEND_END_ARG_INFO()
  128. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_get, 0, 0, 3)
  129. ZEND_ARG_INFO(0, ftp)
  130. ZEND_ARG_INFO(0, local_file)
  131. ZEND_ARG_INFO(0, remote_file)
  132. ZEND_ARG_INFO(0, mode)
  133. ZEND_ARG_INFO(0, resume_pos)
  134. ZEND_END_ARG_INFO()
  135. ZEND_BEGIN_ARG_INFO(arginfo_ftp_nb_continue, 0)
  136. ZEND_ARG_INFO(0, ftp)
  137. ZEND_END_ARG_INFO()
  138. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_fput, 0, 0, 3)
  139. ZEND_ARG_INFO(0, ftp)
  140. ZEND_ARG_INFO(0, remote_file)
  141. ZEND_ARG_INFO(0, fp)
  142. ZEND_ARG_INFO(0, mode)
  143. ZEND_ARG_INFO(0, startpos)
  144. ZEND_END_ARG_INFO()
  145. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_fput, 0, 0, 3)
  146. ZEND_ARG_INFO(0, ftp)
  147. ZEND_ARG_INFO(0, remote_file)
  148. ZEND_ARG_INFO(0, fp)
  149. ZEND_ARG_INFO(0, mode)
  150. ZEND_ARG_INFO(0, startpos)
  151. ZEND_END_ARG_INFO()
  152. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_put, 0, 0, 3)
  153. ZEND_ARG_INFO(0, ftp)
  154. ZEND_ARG_INFO(0, remote_file)
  155. ZEND_ARG_INFO(0, local_file)
  156. ZEND_ARG_INFO(0, mode)
  157. ZEND_ARG_INFO(0, startpos)
  158. ZEND_END_ARG_INFO()
  159. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_append, 0, 0, 3)
  160. ZEND_ARG_INFO(0, ftp)
  161. ZEND_ARG_INFO(0, remote_file)
  162. ZEND_ARG_INFO(0, local_file)
  163. ZEND_ARG_INFO(0, mode)
  164. ZEND_END_ARG_INFO()
  165. ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_put, 0, 0, 3)
  166. ZEND_ARG_INFO(0, ftp)
  167. ZEND_ARG_INFO(0, remote_file)
  168. ZEND_ARG_INFO(0, local_file)
  169. ZEND_ARG_INFO(0, mode)
  170. ZEND_ARG_INFO(0, startpos)
  171. ZEND_END_ARG_INFO()
  172. ZEND_BEGIN_ARG_INFO(arginfo_ftp_size, 0)
  173. ZEND_ARG_INFO(0, ftp)
  174. ZEND_ARG_INFO(0, filename)
  175. ZEND_END_ARG_INFO()
  176. ZEND_BEGIN_ARG_INFO(arginfo_ftp_mdtm, 0)
  177. ZEND_ARG_INFO(0, ftp)
  178. ZEND_ARG_INFO(0, filename)
  179. ZEND_END_ARG_INFO()
  180. ZEND_BEGIN_ARG_INFO(arginfo_ftp_rename, 0)
  181. ZEND_ARG_INFO(0, ftp)
  182. ZEND_ARG_INFO(0, src)
  183. ZEND_ARG_INFO(0, dest)
  184. ZEND_END_ARG_INFO()
  185. ZEND_BEGIN_ARG_INFO(arginfo_ftp_delete, 0)
  186. ZEND_ARG_INFO(0, ftp)
  187. ZEND_ARG_INFO(0, file)
  188. ZEND_END_ARG_INFO()
  189. ZEND_BEGIN_ARG_INFO(arginfo_ftp_site, 0)
  190. ZEND_ARG_INFO(0, ftp)
  191. ZEND_ARG_INFO(0, cmd)
  192. ZEND_END_ARG_INFO()
  193. ZEND_BEGIN_ARG_INFO(arginfo_ftp_close, 0)
  194. ZEND_ARG_INFO(0, ftp)
  195. ZEND_END_ARG_INFO()
  196. ZEND_BEGIN_ARG_INFO(arginfo_ftp_set_option, 0)
  197. ZEND_ARG_INFO(0, ftp)
  198. ZEND_ARG_INFO(0, option)
  199. ZEND_ARG_INFO(0, value)
  200. ZEND_END_ARG_INFO()
  201. ZEND_BEGIN_ARG_INFO(arginfo_ftp_get_option, 0)
  202. ZEND_ARG_INFO(0, ftp)
  203. ZEND_ARG_INFO(0, option)
  204. ZEND_END_ARG_INFO()
  205. /* }}} */
  206. static const zend_function_entry php_ftp_functions[] = {
  207. PHP_FE(ftp_connect, arginfo_ftp_connect)
  208. #ifdef HAVE_FTP_SSL
  209. PHP_FE(ftp_ssl_connect, arginfo_ftp_ssl_connect)
  210. #endif
  211. PHP_FE(ftp_login, arginfo_ftp_login)
  212. PHP_FE(ftp_pwd, arginfo_ftp_pwd)
  213. PHP_FE(ftp_cdup, arginfo_ftp_cdup)
  214. PHP_FE(ftp_chdir, arginfo_ftp_chdir)
  215. PHP_FE(ftp_exec, arginfo_ftp_exec)
  216. PHP_FE(ftp_raw, arginfo_ftp_raw)
  217. PHP_FE(ftp_mkdir, arginfo_ftp_mkdir)
  218. PHP_FE(ftp_rmdir, arginfo_ftp_rmdir)
  219. PHP_FE(ftp_chmod, arginfo_ftp_chmod)
  220. PHP_FE(ftp_alloc, arginfo_ftp_alloc)
  221. PHP_FE(ftp_nlist, arginfo_ftp_nlist)
  222. PHP_FE(ftp_rawlist, arginfo_ftp_rawlist)
  223. PHP_FE(ftp_mlsd, arginfo_ftp_mlsd)
  224. PHP_FE(ftp_systype, arginfo_ftp_systype)
  225. PHP_FE(ftp_pasv, arginfo_ftp_pasv)
  226. PHP_FE(ftp_get, arginfo_ftp_get)
  227. PHP_FE(ftp_fget, arginfo_ftp_fget)
  228. PHP_FE(ftp_put, arginfo_ftp_put)
  229. PHP_FE(ftp_append, arginfo_ftp_append)
  230. PHP_FE(ftp_fput, arginfo_ftp_fput)
  231. PHP_FE(ftp_size, arginfo_ftp_size)
  232. PHP_FE(ftp_mdtm, arginfo_ftp_mdtm)
  233. PHP_FE(ftp_rename, arginfo_ftp_rename)
  234. PHP_FE(ftp_delete, arginfo_ftp_delete)
  235. PHP_FE(ftp_site, arginfo_ftp_site)
  236. PHP_FE(ftp_close, arginfo_ftp_close)
  237. PHP_FE(ftp_set_option, arginfo_ftp_set_option)
  238. PHP_FE(ftp_get_option, arginfo_ftp_get_option)
  239. PHP_FE(ftp_nb_fget, arginfo_ftp_nb_fget)
  240. PHP_FE(ftp_nb_get, arginfo_ftp_nb_get)
  241. PHP_FE(ftp_nb_continue, arginfo_ftp_nb_continue)
  242. PHP_FE(ftp_nb_put, arginfo_ftp_nb_put)
  243. PHP_FE(ftp_nb_fput, arginfo_ftp_nb_fput)
  244. PHP_FALIAS(ftp_quit, ftp_close, arginfo_ftp_close)
  245. PHP_FE_END
  246. };
  247. zend_module_entry php_ftp_module_entry = {
  248. STANDARD_MODULE_HEADER_EX,
  249. NULL,
  250. NULL,
  251. "ftp",
  252. php_ftp_functions,
  253. PHP_MINIT(ftp),
  254. NULL,
  255. NULL,
  256. NULL,
  257. PHP_MINFO(ftp),
  258. PHP_FTP_VERSION,
  259. STANDARD_MODULE_PROPERTIES
  260. };
  261. #if COMPILE_DL_FTP
  262. ZEND_GET_MODULE(php_ftp)
  263. #endif
  264. static void ftp_destructor_ftpbuf(zend_resource *rsrc)
  265. {
  266. ftpbuf_t *ftp = (ftpbuf_t *)rsrc->ptr;
  267. ftp_close(ftp);
  268. }
  269. PHP_MINIT_FUNCTION(ftp)
  270. {
  271. #ifdef HAVE_FTP_SSL
  272. SSL_library_init();
  273. OpenSSL_add_all_ciphers();
  274. OpenSSL_add_all_digests();
  275. OpenSSL_add_all_algorithms();
  276. SSL_load_error_strings();
  277. #endif
  278. le_ftpbuf = zend_register_list_destructors_ex(ftp_destructor_ftpbuf, NULL, le_ftpbuf_name, module_number);
  279. REGISTER_LONG_CONSTANT("FTP_ASCII", FTPTYPE_ASCII, CONST_PERSISTENT | CONST_CS);
  280. REGISTER_LONG_CONSTANT("FTP_TEXT", FTPTYPE_ASCII, CONST_PERSISTENT | CONST_CS);
  281. REGISTER_LONG_CONSTANT("FTP_BINARY", FTPTYPE_IMAGE, CONST_PERSISTENT | CONST_CS);
  282. REGISTER_LONG_CONSTANT("FTP_IMAGE", FTPTYPE_IMAGE, CONST_PERSISTENT | CONST_CS);
  283. REGISTER_LONG_CONSTANT("FTP_AUTORESUME", PHP_FTP_AUTORESUME, CONST_PERSISTENT | CONST_CS);
  284. REGISTER_LONG_CONSTANT("FTP_TIMEOUT_SEC", PHP_FTP_OPT_TIMEOUT_SEC, CONST_PERSISTENT | CONST_CS);
  285. REGISTER_LONG_CONSTANT("FTP_AUTOSEEK", PHP_FTP_OPT_AUTOSEEK, CONST_PERSISTENT | CONST_CS);
  286. REGISTER_LONG_CONSTANT("FTP_USEPASVADDRESS", PHP_FTP_OPT_USEPASVADDRESS, CONST_PERSISTENT | CONST_CS);
  287. REGISTER_LONG_CONSTANT("FTP_FAILED", PHP_FTP_FAILED, CONST_PERSISTENT | CONST_CS);
  288. REGISTER_LONG_CONSTANT("FTP_FINISHED", PHP_FTP_FINISHED, CONST_PERSISTENT | CONST_CS);
  289. REGISTER_LONG_CONSTANT("FTP_MOREDATA", PHP_FTP_MOREDATA, CONST_PERSISTENT | CONST_CS);
  290. return SUCCESS;
  291. }
  292. PHP_MINFO_FUNCTION(ftp)
  293. {
  294. php_info_print_table_start();
  295. php_info_print_table_row(2, "FTP support", "enabled");
  296. #ifdef HAVE_FTP_SSL
  297. php_info_print_table_row(2, "FTPS support", "enabled");
  298. #else
  299. php_info_print_table_row(2, "FTPS support", "disabled");
  300. #endif
  301. php_info_print_table_end();
  302. }
  303. #define XTYPE(xtype, mode) { \
  304. if (mode != FTPTYPE_ASCII && mode != FTPTYPE_IMAGE) { \
  305. php_error_docref(NULL, E_WARNING, "Mode must be FTP_ASCII or FTP_BINARY"); \
  306. RETURN_FALSE; \
  307. } \
  308. xtype = mode; \
  309. }
  310. /* {{{ proto resource ftp_connect(string host [, int port [, int timeout]])
  311. Opens a FTP stream */
  312. PHP_FUNCTION(ftp_connect)
  313. {
  314. ftpbuf_t *ftp;
  315. char *host;
  316. size_t host_len;
  317. zend_long port = 0;
  318. zend_long timeout_sec = FTP_DEFAULT_TIMEOUT;
  319. if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|ll", &host, &host_len, &port, &timeout_sec) == FAILURE) {
  320. return;
  321. }
  322. if (timeout_sec <= 0) {
  323. php_error_docref(NULL, E_WARNING, "Timeout has to be greater than 0");
  324. RETURN_FALSE;
  325. }
  326. /* connect */
  327. if (!(ftp = ftp_open(host, (short)port, timeout_sec))) {
  328. RETURN_FALSE;
  329. }
  330. /* autoseek for resuming */
  331. ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
  332. ftp->usepasvaddress = FTP_DEFAULT_USEPASVADDRESS;
  333. #ifdef HAVE_FTP_SSL
  334. /* disable ssl */
  335. ftp->use_ssl = 0;
  336. #endif
  337. RETURN_RES(zend_register_resource(ftp, le_ftpbuf));
  338. }
  339. /* }}} */
  340. #ifdef HAVE_FTP_SSL
  341. /* {{{ proto resource ftp_ssl_connect(string host [, int port [, int timeout]])
  342. Opens a FTP-SSL stream */
  343. PHP_FUNCTION(ftp_ssl_connect)
  344. {
  345. ftpbuf_t *ftp;
  346. char *host;
  347. size_t host_len;
  348. zend_long port = 0;
  349. zend_long timeout_sec = FTP_DEFAULT_TIMEOUT;
  350. if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|ll", &host, &host_len, &port, &timeout_sec) == FAILURE) {
  351. return;
  352. }
  353. if (timeout_sec <= 0) {
  354. php_error_docref(NULL, E_WARNING, "Timeout has to be greater than 0");
  355. RETURN_FALSE;
  356. }
  357. /* connect */
  358. if (!(ftp = ftp_open(host, (short)port, timeout_sec))) {
  359. RETURN_FALSE;
  360. }
  361. /* autoseek for resuming */
  362. ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
  363. ftp->usepasvaddress = FTP_DEFAULT_USEPASVADDRESS;
  364. /* enable ssl */
  365. ftp->use_ssl = 1;
  366. RETURN_RES(zend_register_resource(ftp, le_ftpbuf));
  367. }
  368. /* }}} */
  369. #endif
  370. /* {{{ proto bool ftp_login(resource stream, string username, string password)
  371. Logs into the FTP server */
  372. PHP_FUNCTION(ftp_login)
  373. {
  374. zval *z_ftp;
  375. ftpbuf_t *ftp;
  376. char *user, *pass;
  377. size_t user_len, pass_len;
  378. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss", &z_ftp, &user, &user_len, &pass, &pass_len) == FAILURE) {
  379. return;
  380. }
  381. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  382. RETURN_FALSE;
  383. }
  384. /* log in */
  385. if (!ftp_login(ftp, user, user_len, pass, pass_len)) {
  386. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  387. RETURN_FALSE;
  388. }
  389. RETURN_TRUE;
  390. }
  391. /* }}} */
  392. /* {{{ proto string ftp_pwd(resource stream)
  393. Returns the present working directory */
  394. PHP_FUNCTION(ftp_pwd)
  395. {
  396. zval *z_ftp;
  397. ftpbuf_t *ftp;
  398. const char *pwd;
  399. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_ftp) == FAILURE) {
  400. return;
  401. }
  402. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  403. RETURN_FALSE;
  404. }
  405. if (!(pwd = ftp_pwd(ftp))) {
  406. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  407. RETURN_FALSE;
  408. }
  409. RETURN_STRING((char*) pwd);
  410. }
  411. /* }}} */
  412. /* {{{ proto bool ftp_cdup(resource stream)
  413. Changes to the parent directory */
  414. PHP_FUNCTION(ftp_cdup)
  415. {
  416. zval *z_ftp;
  417. ftpbuf_t *ftp;
  418. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_ftp) == FAILURE) {
  419. return;
  420. }
  421. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  422. RETURN_FALSE;
  423. }
  424. if (!ftp_cdup(ftp)) {
  425. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  426. RETURN_FALSE;
  427. }
  428. RETURN_TRUE;
  429. }
  430. /* }}} */
  431. /* {{{ proto bool ftp_chdir(resource stream, string directory)
  432. Changes directories */
  433. PHP_FUNCTION(ftp_chdir)
  434. {
  435. zval *z_ftp;
  436. ftpbuf_t *ftp;
  437. char *dir;
  438. size_t dir_len;
  439. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
  440. return;
  441. }
  442. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  443. RETURN_FALSE;
  444. }
  445. /* change directories */
  446. if (!ftp_chdir(ftp, dir, dir_len)) {
  447. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  448. RETURN_FALSE;
  449. }
  450. RETURN_TRUE;
  451. }
  452. /* }}} */
  453. /* {{{ proto bool ftp_exec(resource stream, string command)
  454. Requests execution of a program on the FTP server */
  455. PHP_FUNCTION(ftp_exec)
  456. {
  457. zval *z_ftp;
  458. ftpbuf_t *ftp;
  459. char *cmd;
  460. size_t cmd_len;
  461. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
  462. return;
  463. }
  464. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  465. RETURN_FALSE;
  466. }
  467. /* execute serverside command */
  468. if (!ftp_exec(ftp, cmd, cmd_len)) {
  469. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  470. RETURN_FALSE;
  471. }
  472. RETURN_TRUE;
  473. }
  474. /* }}} */
  475. /* {{{ proto array ftp_raw(resource stream, string command)
  476. Sends a literal command to the FTP server */
  477. PHP_FUNCTION(ftp_raw)
  478. {
  479. zval *z_ftp;
  480. ftpbuf_t *ftp;
  481. char *cmd;
  482. size_t cmd_len;
  483. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
  484. return;
  485. }
  486. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  487. RETURN_FALSE;
  488. }
  489. /* execute arbitrary ftp command */
  490. ftp_raw(ftp, cmd, cmd_len, return_value);
  491. }
  492. /* }}} */
  493. /* {{{ proto string ftp_mkdir(resource stream, string directory)
  494. Creates a directory and returns the absolute path for the new directory or false on error */
  495. PHP_FUNCTION(ftp_mkdir)
  496. {
  497. zval *z_ftp;
  498. ftpbuf_t *ftp;
  499. char *dir;
  500. zend_string *tmp;
  501. size_t dir_len;
  502. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
  503. return;
  504. }
  505. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  506. RETURN_FALSE;
  507. }
  508. /* create directory */
  509. if (NULL == (tmp = ftp_mkdir(ftp, dir, dir_len))) {
  510. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  511. RETURN_FALSE;
  512. }
  513. RETURN_STR(tmp);
  514. }
  515. /* }}} */
  516. /* {{{ proto bool ftp_rmdir(resource stream, string directory)
  517. Removes a directory */
  518. PHP_FUNCTION(ftp_rmdir)
  519. {
  520. zval *z_ftp;
  521. ftpbuf_t *ftp;
  522. char *dir;
  523. size_t dir_len;
  524. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
  525. return;
  526. }
  527. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  528. RETURN_FALSE;
  529. }
  530. /* remove directorie */
  531. if (!ftp_rmdir(ftp, dir, dir_len)) {
  532. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  533. RETURN_FALSE;
  534. }
  535. RETURN_TRUE;
  536. }
  537. /* }}} */
  538. /* {{{ proto int ftp_chmod(resource stream, int mode, string filename)
  539. Sets permissions on a file */
  540. PHP_FUNCTION(ftp_chmod)
  541. {
  542. zval *z_ftp;
  543. ftpbuf_t *ftp;
  544. char *filename;
  545. size_t filename_len;
  546. zend_long mode;
  547. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlp", &z_ftp, &mode, &filename, &filename_len) == FAILURE) {
  548. RETURN_FALSE;
  549. }
  550. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  551. RETURN_FALSE;
  552. }
  553. if (!ftp_chmod(ftp, mode, filename, filename_len)) {
  554. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  555. RETURN_FALSE;
  556. }
  557. RETURN_LONG(mode);
  558. }
  559. /* }}} */
  560. /* {{{ proto bool ftp_alloc(resource stream, int size[, &response])
  561. Attempt to allocate space on the remote FTP server */
  562. PHP_FUNCTION(ftp_alloc)
  563. {
  564. zval *z_ftp, *zresponse = NULL;
  565. ftpbuf_t *ftp;
  566. zend_long size, ret;
  567. zend_string *response = NULL;
  568. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl|z/", &z_ftp, &size, &zresponse) == FAILURE) {
  569. RETURN_FALSE;
  570. }
  571. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  572. RETURN_FALSE;
  573. }
  574. ret = ftp_alloc(ftp, size, zresponse ? &response : NULL);
  575. if (response) {
  576. zval_ptr_dtor(zresponse);
  577. ZVAL_STR(zresponse, response);
  578. }
  579. if (!ret) {
  580. RETURN_FALSE;
  581. }
  582. RETURN_TRUE;
  583. }
  584. /* }}} */
  585. /* {{{ proto array ftp_nlist(resource stream, string directory)
  586. Returns an array of filenames in the given directory */
  587. PHP_FUNCTION(ftp_nlist)
  588. {
  589. zval *z_ftp;
  590. ftpbuf_t *ftp;
  591. char **nlist, **ptr, *dir;
  592. size_t dir_len;
  593. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rp", &z_ftp, &dir, &dir_len) == FAILURE) {
  594. return;
  595. }
  596. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  597. RETURN_FALSE;
  598. }
  599. /* get list of files */
  600. if (NULL == (nlist = ftp_nlist(ftp, dir, dir_len))) {
  601. RETURN_FALSE;
  602. }
  603. array_init(return_value);
  604. for (ptr = nlist; *ptr; ptr++) {
  605. add_next_index_string(return_value, *ptr);
  606. }
  607. efree(nlist);
  608. }
  609. /* }}} */
  610. /* {{{ proto array ftp_rawlist(resource stream, string directory [, bool recursive])
  611. Returns a detailed listing of a directory as an array of output lines */
  612. PHP_FUNCTION(ftp_rawlist)
  613. {
  614. zval *z_ftp;
  615. ftpbuf_t *ftp;
  616. char **llist, **ptr, *dir;
  617. size_t dir_len;
  618. zend_bool recursive = 0;
  619. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|b", &z_ftp, &dir, &dir_len, &recursive) == FAILURE) {
  620. return;
  621. }
  622. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  623. RETURN_FALSE;
  624. }
  625. /* get raw directory listing */
  626. if (NULL == (llist = ftp_list(ftp, dir, dir_len, recursive))) {
  627. RETURN_FALSE;
  628. }
  629. array_init(return_value);
  630. for (ptr = llist; *ptr; ptr++) {
  631. add_next_index_string(return_value, *ptr);
  632. }
  633. efree(llist);
  634. }
  635. /* }}} */
  636. /* {{{ proto array ftp_mlsd(resource stream, string directory)
  637. Returns a detailed listing of a directory as an array of parsed output lines */
  638. PHP_FUNCTION(ftp_mlsd)
  639. {
  640. zval *z_ftp;
  641. ftpbuf_t *ftp;
  642. char **llist, **ptr, *dir;
  643. size_t dir_len;
  644. zval entry;
  645. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &dir, &dir_len) == FAILURE) {
  646. return;
  647. }
  648. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  649. RETURN_FALSE;
  650. }
  651. /* get raw directory listing */
  652. if (NULL == (llist = ftp_mlsd(ftp, dir, dir_len))) {
  653. RETURN_FALSE;
  654. }
  655. array_init(return_value);
  656. for (ptr = llist; *ptr; ptr++) {
  657. array_init(&entry);
  658. if (ftp_mlsd_parse_line(Z_ARRVAL_P(&entry), *ptr) == SUCCESS) {
  659. zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &entry);
  660. } else {
  661. zval_ptr_dtor(&entry);
  662. }
  663. }
  664. efree(llist);
  665. }
  666. /* }}} */
  667. /* {{{ proto string ftp_systype(resource stream)
  668. Returns the system type identifier */
  669. PHP_FUNCTION(ftp_systype)
  670. {
  671. zval *z_ftp;
  672. ftpbuf_t *ftp;
  673. const char *syst;
  674. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_ftp) == FAILURE) {
  675. return;
  676. }
  677. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  678. RETURN_FALSE;
  679. }
  680. if (NULL == (syst = ftp_syst(ftp))) {
  681. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  682. RETURN_FALSE;
  683. }
  684. RETURN_STRING((char*) syst);
  685. }
  686. /* }}} */
  687. /* {{{ proto bool ftp_fget(resource stream, resource fp, string remote_file, [, int mode [, int resumepos]])
  688. Retrieves a file from the FTP server and writes it to an open file */
  689. PHP_FUNCTION(ftp_fget)
  690. {
  691. zval *z_ftp, *z_file;
  692. ftpbuf_t *ftp;
  693. ftptype_t xtype;
  694. php_stream *stream;
  695. char *file;
  696. size_t file_len;
  697. zend_long mode=FTPTYPE_IMAGE, resumepos=0;
  698. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrs|ll", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
  699. return;
  700. }
  701. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  702. RETURN_FALSE;
  703. }
  704. php_stream_from_res(stream, Z_RES_P(z_file));
  705. XTYPE(xtype, mode);
  706. /* ignore autoresume if autoseek is switched off */
  707. if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
  708. resumepos = 0;
  709. }
  710. if (ftp->autoseek && resumepos) {
  711. /* if autoresume is wanted seek to end */
  712. if (resumepos == PHP_FTP_AUTORESUME) {
  713. php_stream_seek(stream, 0, SEEK_END);
  714. resumepos = php_stream_tell(stream);
  715. } else {
  716. php_stream_seek(stream, resumepos, SEEK_SET);
  717. }
  718. }
  719. if (!ftp_get(ftp, stream, file, file_len, xtype, resumepos)) {
  720. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  721. RETURN_FALSE;
  722. }
  723. RETURN_TRUE;
  724. }
  725. /* }}} */
  726. /* {{{ proto int ftp_nb_fget(resource stream, resource fp, string remote_file [, int mode [, int resumepos]])
  727. Retrieves a file from the FTP server asynchronly and writes it to an open file */
  728. PHP_FUNCTION(ftp_nb_fget)
  729. {
  730. zval *z_ftp, *z_file;
  731. ftpbuf_t *ftp;
  732. ftptype_t xtype;
  733. php_stream *stream;
  734. char *file;
  735. size_t file_len;
  736. zend_long mode=FTPTYPE_IMAGE, resumepos=0, ret;
  737. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrs|ll", &z_ftp, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) {
  738. return;
  739. }
  740. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  741. RETURN_FALSE;
  742. }
  743. php_stream_from_res(stream, Z_RES_P(z_file));
  744. XTYPE(xtype, mode);
  745. /* ignore autoresume if autoseek is switched off */
  746. if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
  747. resumepos = 0;
  748. }
  749. if (ftp->autoseek && resumepos) {
  750. /* if autoresume is wanted seek to end */
  751. if (resumepos == PHP_FTP_AUTORESUME) {
  752. php_stream_seek(stream, 0, SEEK_END);
  753. resumepos = php_stream_tell(stream);
  754. } else {
  755. php_stream_seek(stream, resumepos, SEEK_SET);
  756. }
  757. }
  758. /* configuration */
  759. ftp->direction = 0; /* recv */
  760. ftp->closestream = 0; /* do not close */
  761. if ((ret = ftp_nb_get(ftp, stream, file, file_len, xtype, resumepos)) == PHP_FTP_FAILED) {
  762. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  763. RETURN_LONG(ret);
  764. }
  765. RETURN_LONG(ret);
  766. }
  767. /* }}} */
  768. /* {{{ proto bool ftp_pasv(resource stream, bool pasv)
  769. Turns passive mode on or off */
  770. PHP_FUNCTION(ftp_pasv)
  771. {
  772. zval *z_ftp;
  773. ftpbuf_t *ftp;
  774. zend_bool pasv;
  775. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rb", &z_ftp, &pasv) == FAILURE) {
  776. return;
  777. }
  778. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  779. RETURN_FALSE;
  780. }
  781. if (!ftp_pasv(ftp, pasv ? 1 : 0)) {
  782. RETURN_FALSE;
  783. }
  784. RETURN_TRUE;
  785. }
  786. /* }}} */
  787. /* {{{ proto bool ftp_get(resource stream, string local_file, string remote_file [, int mode [, int resume_pos]])
  788. Retrieves a file from the FTP server and writes it to a local file */
  789. PHP_FUNCTION(ftp_get)
  790. {
  791. zval *z_ftp;
  792. ftpbuf_t *ftp;
  793. ftptype_t xtype;
  794. php_stream *outstream;
  795. char *local, *remote;
  796. size_t local_len, remote_len;
  797. zend_long mode=FTPTYPE_IMAGE, resumepos=0;
  798. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rpp|ll", &z_ftp, &local, &local_len, &remote, &remote_len, &mode, &resumepos) == FAILURE) {
  799. return;
  800. }
  801. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  802. RETURN_FALSE;
  803. }
  804. XTYPE(xtype, mode);
  805. /* ignore autoresume if autoseek is switched off */
  806. if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
  807. resumepos = 0;
  808. }
  809. #ifdef PHP_WIN32
  810. mode = FTPTYPE_IMAGE;
  811. #endif
  812. if (ftp->autoseek && resumepos) {
  813. outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt+" : "rb+", REPORT_ERRORS, NULL);
  814. if (outstream == NULL) {
  815. outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
  816. }
  817. if (outstream != NULL) {
  818. /* if autoresume is wanted seek to end */
  819. if (resumepos == PHP_FTP_AUTORESUME) {
  820. php_stream_seek(outstream, 0, SEEK_END);
  821. resumepos = php_stream_tell(outstream);
  822. } else {
  823. php_stream_seek(outstream, resumepos, SEEK_SET);
  824. }
  825. }
  826. } else {
  827. outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
  828. }
  829. if (outstream == NULL) {
  830. php_error_docref(NULL, E_WARNING, "Error opening %s", local);
  831. RETURN_FALSE;
  832. }
  833. if (!ftp_get(ftp, outstream, remote, remote_len, xtype, resumepos)) {
  834. php_stream_close(outstream);
  835. VCWD_UNLINK(local);
  836. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  837. RETURN_FALSE;
  838. }
  839. php_stream_close(outstream);
  840. RETURN_TRUE;
  841. }
  842. /* }}} */
  843. /* {{{ proto int ftp_nb_get(resource stream, string local_file, string remote_file, [, int mode [, int resume_pos]])
  844. Retrieves a file from the FTP server nbhronly and writes it to a local file */
  845. PHP_FUNCTION(ftp_nb_get)
  846. {
  847. zval *z_ftp;
  848. ftpbuf_t *ftp;
  849. ftptype_t xtype;
  850. php_stream *outstream;
  851. char *local, *remote;
  852. size_t local_len, remote_len;
  853. int ret;
  854. zend_long mode=FTPTYPE_IMAGE, resumepos=0;
  855. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss|ll", &z_ftp, &local, &local_len, &remote, &remote_len, &mode, &resumepos) == FAILURE) {
  856. return;
  857. }
  858. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  859. RETURN_FALSE;
  860. }
  861. XTYPE(xtype, mode);
  862. /* ignore autoresume if autoseek is switched off */
  863. if (!ftp->autoseek && resumepos == PHP_FTP_AUTORESUME) {
  864. resumepos = 0;
  865. }
  866. #ifdef PHP_WIN32
  867. mode = FTPTYPE_IMAGE;
  868. #endif
  869. if (ftp->autoseek && resumepos) {
  870. outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt+" : "rb+", REPORT_ERRORS, NULL);
  871. if (outstream == NULL) {
  872. outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
  873. }
  874. if (outstream != NULL) {
  875. /* if autoresume is wanted seek to end */
  876. if (resumepos == PHP_FTP_AUTORESUME) {
  877. php_stream_seek(outstream, 0, SEEK_END);
  878. resumepos = php_stream_tell(outstream);
  879. } else {
  880. php_stream_seek(outstream, resumepos, SEEK_SET);
  881. }
  882. }
  883. } else {
  884. outstream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "wt" : "wb", REPORT_ERRORS, NULL);
  885. }
  886. if (outstream == NULL) {
  887. php_error_docref(NULL, E_WARNING, "Error opening %s", local);
  888. RETURN_FALSE;
  889. }
  890. /* configuration */
  891. ftp->direction = 0; /* recv */
  892. ftp->closestream = 1; /* do close */
  893. if ((ret = ftp_nb_get(ftp, outstream, remote, remote_len, xtype, resumepos)) == PHP_FTP_FAILED) {
  894. php_stream_close(outstream);
  895. ftp->stream = NULL;
  896. VCWD_UNLINK(local);
  897. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  898. RETURN_LONG(PHP_FTP_FAILED);
  899. }
  900. if (ret == PHP_FTP_FINISHED){
  901. php_stream_close(outstream);
  902. ftp->stream = NULL;
  903. }
  904. RETURN_LONG(ret);
  905. }
  906. /* }}} */
  907. /* {{{ proto int ftp_nb_continue(resource stream)
  908. Continues retrieving/sending a file nbronously */
  909. PHP_FUNCTION(ftp_nb_continue)
  910. {
  911. zval *z_ftp;
  912. ftpbuf_t *ftp;
  913. zend_long ret;
  914. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_ftp) == FAILURE) {
  915. return;
  916. }
  917. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  918. RETURN_FALSE;
  919. }
  920. if (!ftp->nb) {
  921. php_error_docref(NULL, E_WARNING, "no nbronous transfer to continue.");
  922. RETURN_LONG(PHP_FTP_FAILED);
  923. }
  924. if (ftp->direction) {
  925. ret=ftp_nb_continue_write(ftp);
  926. } else {
  927. ret=ftp_nb_continue_read(ftp);
  928. }
  929. if (ret != PHP_FTP_MOREDATA && ftp->closestream) {
  930. php_stream_close(ftp->stream);
  931. ftp->stream = NULL;
  932. }
  933. if (ret == PHP_FTP_FAILED) {
  934. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  935. }
  936. RETURN_LONG(ret);
  937. }
  938. /* }}} */
  939. /* {{{ proto bool ftp_fput(resource stream, string remote_file, resource fp [, int mode [, int startpos]])
  940. Stores a file from an open file to the FTP server */
  941. PHP_FUNCTION(ftp_fput)
  942. {
  943. zval *z_ftp, *z_file;
  944. ftpbuf_t *ftp;
  945. ftptype_t xtype;
  946. size_t remote_len;
  947. zend_long mode=FTPTYPE_IMAGE, startpos=0;
  948. php_stream *stream;
  949. char *remote;
  950. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsr|ll", &z_ftp, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) {
  951. return;
  952. }
  953. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  954. RETURN_FALSE;
  955. }
  956. php_stream_from_zval(stream, z_file);
  957. XTYPE(xtype, mode);
  958. /* ignore autoresume if autoseek is switched off */
  959. if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
  960. startpos = 0;
  961. }
  962. if (ftp->autoseek && startpos) {
  963. /* if autoresume is wanted ask for remote size */
  964. if (startpos == PHP_FTP_AUTORESUME) {
  965. startpos = ftp_size(ftp, remote, remote_len);
  966. if (startpos < 0) {
  967. startpos = 0;
  968. }
  969. }
  970. if (startpos) {
  971. php_stream_seek(stream, startpos, SEEK_SET);
  972. }
  973. }
  974. if (!ftp_put(ftp, remote, remote_len, stream, xtype, startpos)) {
  975. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  976. RETURN_FALSE;
  977. }
  978. RETURN_TRUE;
  979. }
  980. /* }}} */
  981. /* {{{ proto int ftp_nb_fput(resource stream, string remote_file, resource fp [, int mode [, int startpos]])
  982. Stores a file from an open file to the FTP server nbronly */
  983. PHP_FUNCTION(ftp_nb_fput)
  984. {
  985. zval *z_ftp, *z_file;
  986. ftpbuf_t *ftp;
  987. ftptype_t xtype;
  988. size_t remote_len;
  989. int ret;
  990. zend_long mode=FTPTYPE_IMAGE, startpos=0;
  991. php_stream *stream;
  992. char *remote;
  993. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsr|ll", &z_ftp, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) {
  994. return;
  995. }
  996. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  997. RETURN_FALSE;
  998. }
  999. php_stream_from_res(stream, Z_RES_P(z_file));
  1000. XTYPE(xtype, mode);
  1001. /* ignore autoresume if autoseek is switched off */
  1002. if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
  1003. startpos = 0;
  1004. }
  1005. if (ftp->autoseek && startpos) {
  1006. /* if autoresume is wanted ask for remote size */
  1007. if (startpos == PHP_FTP_AUTORESUME) {
  1008. startpos = ftp_size(ftp, remote, remote_len);
  1009. if (startpos < 0) {
  1010. startpos = 0;
  1011. }
  1012. }
  1013. if (startpos) {
  1014. php_stream_seek(stream, startpos, SEEK_SET);
  1015. }
  1016. }
  1017. /* configuration */
  1018. ftp->direction = 1; /* send */
  1019. ftp->closestream = 0; /* do not close */
  1020. if (((ret = ftp_nb_put(ftp, remote, remote_len, stream, xtype, startpos)) == PHP_FTP_FAILED)) {
  1021. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  1022. RETURN_LONG(ret);
  1023. }
  1024. RETURN_LONG(ret);
  1025. }
  1026. /* }}} */
  1027. /* {{{ proto bool ftp_put(resource stream, string remote_file, string local_file [, int mode [, int startpos]])
  1028. Stores a file on the FTP server */
  1029. PHP_FUNCTION(ftp_put)
  1030. {
  1031. zval *z_ftp;
  1032. ftpbuf_t *ftp;
  1033. ftptype_t xtype;
  1034. char *remote, *local;
  1035. size_t remote_len, local_len;
  1036. zend_long mode=FTPTYPE_IMAGE, startpos=0;
  1037. php_stream *instream;
  1038. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rpp|ll", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
  1039. return;
  1040. }
  1041. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  1042. RETURN_FALSE;
  1043. }
  1044. XTYPE(xtype, mode);
  1045. if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) {
  1046. RETURN_FALSE;
  1047. }
  1048. /* ignore autoresume if autoseek is switched off */
  1049. if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
  1050. startpos = 0;
  1051. }
  1052. if (ftp->autoseek && startpos) {
  1053. /* if autoresume is wanted ask for remote size */
  1054. if (startpos == PHP_FTP_AUTORESUME) {
  1055. startpos = ftp_size(ftp, remote, remote_len);
  1056. if (startpos < 0) {
  1057. startpos = 0;
  1058. }
  1059. }
  1060. if (startpos) {
  1061. php_stream_seek(instream, startpos, SEEK_SET);
  1062. }
  1063. }
  1064. if (!ftp_put(ftp, remote, remote_len, instream, xtype, startpos)) {
  1065. php_stream_close(instream);
  1066. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  1067. RETURN_FALSE;
  1068. }
  1069. php_stream_close(instream);
  1070. RETURN_TRUE;
  1071. }
  1072. /* }}} */
  1073. /* {{{ proto bool ftp_append(resource stream, string remote_file, string local_file [, int mode])
  1074. Append content of a file a another file on the FTP server */
  1075. PHP_FUNCTION(ftp_append)
  1076. {
  1077. zval *z_ftp;
  1078. ftpbuf_t *ftp;
  1079. ftptype_t xtype;
  1080. char *remote, *local;
  1081. size_t remote_len, local_len;
  1082. zend_long mode=FTPTYPE_IMAGE;
  1083. php_stream *instream;
  1084. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rpp|l", &z_ftp, &remote, &remote_len, &local, &local_len, &mode) == FAILURE) {
  1085. return;
  1086. }
  1087. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  1088. RETURN_FALSE;
  1089. }
  1090. XTYPE(xtype, mode);
  1091. if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) {
  1092. RETURN_FALSE;
  1093. }
  1094. if (!ftp_append(ftp, remote, remote_len, instream, xtype)) {
  1095. php_stream_close(instream);
  1096. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  1097. RETURN_FALSE;
  1098. }
  1099. php_stream_close(instream);
  1100. RETURN_TRUE;
  1101. }
  1102. /* }}} */
  1103. /* {{{ proto int ftp_nb_put(resource stream, string remote_file, string local_file [, int mode [, int startpos]])
  1104. Stores a file on the FTP server */
  1105. PHP_FUNCTION(ftp_nb_put)
  1106. {
  1107. zval *z_ftp;
  1108. ftpbuf_t *ftp;
  1109. ftptype_t xtype;
  1110. char *remote, *local;
  1111. size_t remote_len, local_len;
  1112. zend_long mode=FTPTYPE_IMAGE, startpos=0, ret;
  1113. php_stream *instream;
  1114. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rpp|ll", &z_ftp, &remote, &remote_len, &local, &local_len, &mode, &startpos) == FAILURE) {
  1115. return;
  1116. }
  1117. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  1118. RETURN_FALSE;
  1119. }
  1120. XTYPE(xtype, mode);
  1121. if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) {
  1122. RETURN_FALSE;
  1123. }
  1124. /* ignore autoresume if autoseek is switched off */
  1125. if (!ftp->autoseek && startpos == PHP_FTP_AUTORESUME) {
  1126. startpos = 0;
  1127. }
  1128. if (ftp->autoseek && startpos) {
  1129. /* if autoresume is wanted ask for remote size */
  1130. if (startpos == PHP_FTP_AUTORESUME) {
  1131. startpos = ftp_size(ftp, remote, remote_len);
  1132. if (startpos < 0) {
  1133. startpos = 0;
  1134. }
  1135. }
  1136. if (startpos) {
  1137. php_stream_seek(instream, startpos, SEEK_SET);
  1138. }
  1139. }
  1140. /* configuration */
  1141. ftp->direction = 1; /* send */
  1142. ftp->closestream = 1; /* do close */
  1143. ret = ftp_nb_put(ftp, remote, remote_len, instream, xtype, startpos);
  1144. if (ret != PHP_FTP_MOREDATA) {
  1145. php_stream_close(instream);
  1146. ftp->stream = NULL;
  1147. }
  1148. if (ret == PHP_FTP_FAILED) {
  1149. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  1150. }
  1151. RETURN_LONG(ret);
  1152. }
  1153. /* }}} */
  1154. /* {{{ proto int ftp_size(resource stream, string filename)
  1155. Returns the size of the file, or -1 on error */
  1156. PHP_FUNCTION(ftp_size)
  1157. {
  1158. zval *z_ftp;
  1159. ftpbuf_t *ftp;
  1160. char *file;
  1161. size_t file_len;
  1162. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rp", &z_ftp, &file, &file_len) == FAILURE) {
  1163. return;
  1164. }
  1165. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  1166. RETURN_FALSE;
  1167. }
  1168. /* get file size */
  1169. RETURN_LONG(ftp_size(ftp, file, file_len));
  1170. }
  1171. /* }}} */
  1172. /* {{{ proto int ftp_mdtm(resource stream, string filename)
  1173. Returns the last modification time of the file, or -1 on error */
  1174. PHP_FUNCTION(ftp_mdtm)
  1175. {
  1176. zval *z_ftp;
  1177. ftpbuf_t *ftp;
  1178. char *file;
  1179. size_t file_len;
  1180. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rp", &z_ftp, &file, &file_len) == FAILURE) {
  1181. return;
  1182. }
  1183. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  1184. RETURN_FALSE;
  1185. }
  1186. /* get file mod time */
  1187. RETURN_LONG(ftp_mdtm(ftp, file, file_len));
  1188. }
  1189. /* }}} */
  1190. /* {{{ proto bool ftp_rename(resource stream, string src, string dest)
  1191. Renames the given file to a new path */
  1192. PHP_FUNCTION(ftp_rename)
  1193. {
  1194. zval *z_ftp;
  1195. ftpbuf_t *ftp;
  1196. char *src, *dest;
  1197. size_t src_len, dest_len;
  1198. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss", &z_ftp, &src, &src_len, &dest, &dest_len) == FAILURE) {
  1199. return;
  1200. }
  1201. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  1202. RETURN_FALSE;
  1203. }
  1204. /* rename the file */
  1205. if (!ftp_rename(ftp, src, src_len, dest, dest_len)) {
  1206. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  1207. RETURN_FALSE;
  1208. }
  1209. RETURN_TRUE;
  1210. }
  1211. /* }}} */
  1212. /* {{{ proto bool ftp_delete(resource stream, string file)
  1213. Deletes a file */
  1214. PHP_FUNCTION(ftp_delete)
  1215. {
  1216. zval *z_ftp;
  1217. ftpbuf_t *ftp;
  1218. char *file;
  1219. size_t file_len;
  1220. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &file, &file_len) == FAILURE) {
  1221. return;
  1222. }
  1223. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  1224. RETURN_FALSE;
  1225. }
  1226. /* delete the file */
  1227. if (!ftp_delete(ftp, file, file_len)) {
  1228. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  1229. RETURN_FALSE;
  1230. }
  1231. RETURN_TRUE;
  1232. }
  1233. /* }}} */
  1234. /* {{{ proto bool ftp_site(resource stream, string cmd)
  1235. Sends a SITE command to the server */
  1236. PHP_FUNCTION(ftp_site)
  1237. {
  1238. zval *z_ftp;
  1239. ftpbuf_t *ftp;
  1240. char *cmd;
  1241. size_t cmd_len;
  1242. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &z_ftp, &cmd, &cmd_len) == FAILURE) {
  1243. return;
  1244. }
  1245. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  1246. RETURN_FALSE;
  1247. }
  1248. /* send the site command */
  1249. if (!ftp_site(ftp, cmd, cmd_len)) {
  1250. php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
  1251. RETURN_FALSE;
  1252. }
  1253. RETURN_TRUE;
  1254. }
  1255. /* }}} */
  1256. /* {{{ proto bool ftp_close(resource stream)
  1257. Closes the FTP stream */
  1258. PHP_FUNCTION(ftp_close)
  1259. {
  1260. zval *z_ftp;
  1261. ftpbuf_t *ftp;
  1262. if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_ftp) == FAILURE) {
  1263. return;
  1264. }
  1265. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  1266. RETURN_FALSE;
  1267. }
  1268. ftp_quit(ftp);
  1269. RETURN_BOOL(zend_list_close(Z_RES_P(z_ftp)) == SUCCESS);
  1270. }
  1271. /* }}} */
  1272. /* {{{ proto bool ftp_set_option(resource stream, int option, mixed value)
  1273. Sets an FTP option */
  1274. PHP_FUNCTION(ftp_set_option)
  1275. {
  1276. zval *z_ftp, *z_value;
  1277. zend_long option;
  1278. ftpbuf_t *ftp;
  1279. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlz", &z_ftp, &option, &z_value) == FAILURE) {
  1280. return;
  1281. }
  1282. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  1283. RETURN_FALSE;
  1284. }
  1285. switch (option) {
  1286. case PHP_FTP_OPT_TIMEOUT_SEC:
  1287. if (Z_TYPE_P(z_value) != IS_LONG) {
  1288. php_error_docref(NULL, E_WARNING, "Option TIMEOUT_SEC expects value of type int, %s given",
  1289. zend_zval_type_name(z_value));
  1290. RETURN_FALSE;
  1291. }
  1292. if (Z_LVAL_P(z_value) <= 0) {
  1293. php_error_docref(NULL, E_WARNING, "Timeout has to be greater than 0");
  1294. RETURN_FALSE;
  1295. }
  1296. ftp->timeout_sec = Z_LVAL_P(z_value);
  1297. RETURN_TRUE;
  1298. break;
  1299. case PHP_FTP_OPT_AUTOSEEK:
  1300. if (Z_TYPE_P(z_value) != IS_TRUE && Z_TYPE_P(z_value) != IS_FALSE) {
  1301. php_error_docref(NULL, E_WARNING, "Option AUTOSEEK expects value of type bool, %s given",
  1302. zend_zval_type_name(z_value));
  1303. RETURN_FALSE;
  1304. }
  1305. ftp->autoseek = Z_TYPE_P(z_value) == IS_TRUE ? 1 : 0;
  1306. RETURN_TRUE;
  1307. break;
  1308. case PHP_FTP_OPT_USEPASVADDRESS:
  1309. if (Z_TYPE_P(z_value) != IS_TRUE && Z_TYPE_P(z_value) != IS_FALSE) {
  1310. php_error_docref(NULL, E_WARNING, "Option USEPASVADDRESS expects value of type bool, %s given",
  1311. zend_zval_type_name(z_value));
  1312. RETURN_FALSE;
  1313. }
  1314. ftp->usepasvaddress = Z_TYPE_P(z_value) == IS_TRUE ? 1 : 0;
  1315. RETURN_TRUE;
  1316. break;
  1317. default:
  1318. php_error_docref(NULL, E_WARNING, "Unknown option '" ZEND_LONG_FMT "'", option);
  1319. RETURN_FALSE;
  1320. break;
  1321. }
  1322. }
  1323. /* }}} */
  1324. /* {{{ proto mixed ftp_get_option(resource stream, int option)
  1325. Gets an FTP option */
  1326. PHP_FUNCTION(ftp_get_option)
  1327. {
  1328. zval *z_ftp;
  1329. zend_long option;
  1330. ftpbuf_t *ftp;
  1331. if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &z_ftp, &option) == FAILURE) {
  1332. return;
  1333. }
  1334. if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) {
  1335. RETURN_FALSE;
  1336. }
  1337. switch (option) {
  1338. case PHP_FTP_OPT_TIMEOUT_SEC:
  1339. RETURN_LONG(ftp->timeout_sec);
  1340. break;
  1341. case PHP_FTP_OPT_AUTOSEEK:
  1342. RETURN_BOOL(ftp->autoseek);
  1343. break;
  1344. case PHP_FTP_OPT_USEPASVADDRESS:
  1345. RETURN_BOOL(ftp->usepasvaddress);
  1346. break;
  1347. default:
  1348. php_error_docref(NULL, E_WARNING, "Unknown option '" ZEND_LONG_FMT "'", option);
  1349. RETURN_FALSE;
  1350. break;
  1351. }
  1352. }
  1353. /* }}} */
  1354. #endif /* HAVE_FTP */
  1355. /*
  1356. * Local variables:
  1357. * tab-width: 4
  1358. * c-basic-offset: 4
  1359. * indent-tabs-mode: t
  1360. * End:
  1361. */