⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftp.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*   +----------------------------------------------------------------------+   | PHP Version 4                                                        |   +----------------------------------------------------------------------+   | Copyright (c) 1997-2007 The PHP Group                                |   +----------------------------------------------------------------------+   | This source file is subject to version 3.01 of the PHP license,      |   | that is bundled with this package in the file LICENSE, and is        |   | available through the world-wide-web at the following url:           |   | http://www.php.net/license/3_01.txt                                  |   | If you did not receive a copy of the PHP license and are unable to   |   | obtain it through the world-wide-web, please send a note to          |   | license@php.net so we can mail you a copy immediately.               |   +----------------------------------------------------------------------+   | Authors: Andrew Skalski <askalski@chek.com>                          |   |          Stefan Esser <sesser@php.net> (resume functions)            |   +----------------------------------------------------------------------+ *//* $Id: ftp.c,v 1.68.2.22.2.6 2007/03/24 16:26:50 iliaa Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#if HAVE_FTP#include <stdio.h>#include <ctype.h>#include <stdlib.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <fcntl.h>#include <string.h>#include <time.h>#ifdef PHP_WIN32#include <winsock.h>#elif defined(NETWARE)#ifdef USE_WINSOCK    /* Modified to use Winsock (NOVSOCK2.H), atleast for now */#include <novsock2.h>#else#ifdef NEW_LIBC#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#else#include <sys/socket.h>#endif#endif#else#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#endif#include <errno.h>#if HAVE_SYS_TIME_H#include <sys/time.h>#endif#ifdef HAVE_SYS_SELECT_H#include <sys/select.h>#endif#include "ftp.h"#include "ext/standard/fsock.h"/* sends an ftp command, returns true on success, false on error. * it sends the string "cmd args\r\n" if args is non-null, or * "cmd\r\n" if args is null */static int		ftp_putcmd(	ftpbuf_t *ftp,					const char *cmd,					const char *args);/* wrapper around send/recv to handle timeouts */static int		my_send(ftpbuf_t *ftp, int s, void *buf, size_t len);static int		my_recv(ftpbuf_t *ftp, int s, void *buf, size_t len);static int		my_accept(ftpbuf_t *ftp, int s, struct sockaddr *addr, socklen_t *addrlen);/* reads a line the socket , returns true on success, false on error */static int		ftp_readline(ftpbuf_t *ftp);/* reads an ftp response, returns true on success, false on error */static int		ftp_getresp(ftpbuf_t *ftp);/* sets the ftp transfer type */static int		ftp_type(ftpbuf_t *ftp, ftptype_t type);/* opens up a data stream */static databuf_t*	ftp_getdata(ftpbuf_t *ftp TSRMLS_DC);/* accepts the data connection, returns updated data buffer */static databuf_t*	data_accept(databuf_t *data, ftpbuf_t *ftp);/* closes the data connection, returns NULL */static databuf_t*	data_close(ftpbuf_t *ftp, databuf_t *data);/* generic file lister */static char**		ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC);/* IP and port conversion box */union ipbox {	struct in_addr	ia[2];	unsigned short	s[4];	unsigned char	c[8];};/* {{{ ftp_open */ftpbuf_t*ftp_open(const char *host, short port, long timeout_sec TSRMLS_DC){	ftpbuf_t		*ftp;	socklen_t		 size;	struct timeval tv;	/* alloc the ftp structure */	ftp = ecalloc(1, sizeof(*ftp));	tv.tv_sec = timeout_sec;	tv.tv_usec = 0;	ftp->fd = php_hostconnect(host, (unsigned short) (port ? port : 21), SOCK_STREAM, &tv TSRMLS_CC);	if (ftp->fd == -1) {		goto bail;	}	/* Default Settings */	ftp->timeout_sec = timeout_sec;	ftp->nb = 0;	size = sizeof(ftp->localaddr);	memset(&ftp->localaddr, 0, size);	if (getsockname(ftp->fd, (struct sockaddr*) &ftp->localaddr, &size) == -1) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "getsockname failed: %s (%d)\n", strerror(errno), errno);		goto bail;	}	if (!ftp_getresp(ftp) || ftp->resp != 220) {		goto bail;	}	return ftp;bail:	if (ftp->fd != -1)		closesocket(ftp->fd);	efree(ftp);	return NULL;}/* }}} *//* {{{ ftp_close */ftpbuf_t*ftp_close(ftpbuf_t *ftp){	if (ftp == NULL)		return NULL;	if (ftp->data) 		data_close(ftp, ftp->data);	if (ftp->fd != -1) {#ifdef HAVE_OPENSSL_EXT		if (ftp->ssl_active) {			SSL_shutdown(ftp->ssl_handle);		}#endif				closesocket(ftp->fd);	}		ftp_gc(ftp);	efree(ftp);	return NULL;}/* }}} *//* {{{ ftp_gc */voidftp_gc(ftpbuf_t *ftp){	if (ftp == NULL)		return;	if (ftp->pwd) {		efree(ftp->pwd);		ftp->pwd = NULL;	}	if (ftp->syst) {		efree(ftp->syst);		ftp->syst = NULL;	}}/* }}} *//* {{{ ftp_quit */intftp_quit(ftpbuf_t *ftp){	if (ftp == NULL)		return 0;	if (!ftp_putcmd(ftp, "QUIT", NULL))		return 0;	if (!ftp_getresp(ftp) || ftp->resp != 221)		return 0;	if (ftp->pwd) {		efree(ftp->pwd);		ftp->pwd = NULL;	}	return 1;}/* }}} *//* {{{ ftp_login */intftp_login(ftpbuf_t *ftp, const char *user, const char *pass TSRMLS_DC){#ifdef HAVE_OPENSSL_EXT	SSL_CTX	*ctx = NULL;#endif	if (ftp == NULL)		return 0;#ifdef HAVE_OPENSSL_EXT	if (ftp->use_ssl && !ftp->ssl_active) {		if (!ftp_putcmd(ftp, "AUTH", "TLS"))			return 0;		if (!ftp_getresp(ftp))			return 0;					if (ftp->resp != 234) {			if (!ftp_putcmd(ftp, "AUTH", "SSL"))				return 0;			if (!ftp_getresp(ftp))				return 0;							if (ftp->resp != 334) {				ftp->use_ssl = 0;			} else {				ftp->old_ssl = 1;				ftp->use_ssl_for_data = 1;			}		}				/* now enable ssl if we still need to */		if (ftp->use_ssl) {			ctx = SSL_CTX_new(SSLv23_client_method());			if (ctx == NULL) {				php_error_docref(NULL TSRMLS_CC, E_WARNING, "ftp_login: failed to create the SSL context");				return 0;			}			SSL_CTX_set_options(ctx, SSL_OP_ALL);			ftp->ssl_handle = SSL_new(ctx);			if (ftp->ssl_handle == NULL) {				php_error_docref(NULL TSRMLS_CC, E_WARNING, "ftp_login: failed to create the SSL handle");				SSL_CTX_free(ctx);				return 0;			}						SSL_set_fd(ftp->ssl_handle, ftp->fd);						if (SSL_connect(ftp->ssl_handle) <= 0) {				php_error_docref(NULL TSRMLS_CC, E_WARNING, "ftp_login: SSL/TLS handshake failed");				SSL_shutdown(ftp->ssl_handle);				return 0;			}						ftp->ssl_active = 1;						if (!ftp->old_ssl) {								/* set protection buffersize to zero */				if (!ftp_putcmd(ftp, "PBSZ", "0"))					return 0;				if (!ftp_getresp(ftp))					return 0;									/* enable data conn encryption */				if (!ftp_putcmd(ftp, "PROT", "P"))					return 0;				if (!ftp_getresp(ftp))					return 0;								ftp->use_ssl_for_data = (ftp->resp >= 200 && ftp->resp <=299);									}		}			}#endif	if (!ftp_putcmd(ftp, "USER", user))		return 0;	if (!ftp_getresp(ftp))		return 0;	if (ftp->resp == 230)		return 1;	if (ftp->resp != 331)		return 0;	if (!ftp_putcmd(ftp, "PASS", pass))		return 0;	if (!ftp_getresp(ftp))		return 0;	return (ftp->resp == 230);}/* }}} *//* {{{ ftp_reinit */intftp_reinit(ftpbuf_t *ftp){	if (ftp == NULL)		return 0;	ftp_gc(ftp);	ftp->nb = 0;	if (!ftp_putcmd(ftp, "REIN", NULL))		return 0;	if (!ftp_getresp(ftp) || ftp->resp != 220)		return 0;	return 1;}/* }}} *//* {{{ ftp_syst */const char*ftp_syst(ftpbuf_t *ftp){	char		*syst, *end;	if (ftp == NULL)		return NULL;	/* default to cached value */	if (ftp->syst)		return ftp->syst;	if (!ftp_putcmd(ftp, "SYST", NULL))		return NULL;	if (!ftp_getresp(ftp) || ftp->resp != 215)		return NULL;	syst = ftp->inbuf;	while (*syst == ' ') { 		syst++; 	}	if ((end = strchr(syst, ' ')))		*end = 0;	ftp->syst = estrdup(syst);	if (end)		*end = ' ';	return ftp->syst;}/* }}} *//* {{{ ftp_pwd */const char*ftp_pwd(ftpbuf_t *ftp){	char		*pwd, *end;	if (ftp == NULL)		return NULL;	/* default to cached value */	if (ftp->pwd)		return ftp->pwd;	if (!ftp_putcmd(ftp, "PWD", NULL))		return NULL;	if (!ftp_getresp(ftp) || ftp->resp != 257)		return NULL;	/* copy out the pwd from response */	if ((pwd = strchr(ftp->inbuf, '"')) == NULL)		return NULL;	if ((end = strrchr(++pwd, '"')) == NULL) 		return NULL;	ftp->pwd = estrndup(pwd, end - pwd);	return ftp->pwd;}/* }}} *//* {{{ ftp_exec */intftp_exec(ftpbuf_t *ftp, const char *cmd){	if (ftp == NULL)		return 0;	if (!ftp_putcmd(ftp, "SITE EXEC", cmd))		return 0;	if (!ftp_getresp(ftp) || ftp->resp != 200)		return 0;	return 1;}/* }}} *//* {{{ ftp_chdir */intftp_chdir(ftpbuf_t *ftp, const char *dir){	if (ftp == NULL)		return 0;	if (ftp->pwd) {		efree(ftp->pwd);		ftp->pwd = NULL;	}	if (!ftp_putcmd(ftp, "CWD", dir))		return 0;	if (!ftp_getresp(ftp) || ftp->resp != 250)		return 0;	return 1;}/* }}} *//* {{{ ftp_cdup */intftp_cdup(ftpbuf_t *ftp){	if (ftp == NULL)		return 0;	if (ftp->pwd) {		efree(ftp->pwd);		ftp->pwd = NULL;	}	if (!ftp_putcmd(ftp, "CDUP", NULL))		return 0;	if (!ftp_getresp(ftp) || ftp->resp != 250)		return 0;	return 1;}/* }}} *//* {{{ ftp_mkdir */char*ftp_mkdir(ftpbuf_t *ftp, const char *dir){	char		*mkd, *end;	if (ftp == NULL)		return NULL;	if (!ftp_putcmd(ftp, "MKD", dir))		return NULL;	if (!ftp_getresp(ftp) || ftp->resp != 257)		return NULL;	/* copy out the dir from response */	if ((mkd = strchr(ftp->inbuf, '"')) == NULL) {		mkd = estrdup(dir);		return mkd;	}	if ((end = strrchr(++mkd, '"')) == NULL) {		return NULL;	}	*end = 0;	mkd = estrdup(mkd);	*end = '"';	return mkd;}/* }}} *//* {{{ ftp_rmdir */intftp_rmdir(ftpbuf_t *ftp, const char *dir){	if (ftp == NULL)		return 0;	if (!ftp_putcmd(ftp, "RMD", dir))		return 0;	if (!ftp_getresp(ftp) || ftp->resp != 250)		return 0;	return 1;}/* }}} *//* {{{ ftp_nlist */char**ftp_nlist(ftpbuf_t *ftp, const char *path TSRMLS_DC){	return ftp_genlist(ftp, "NLST", path TSRMLS_CC);}/* }}} *//* {{{ ftp_list */char**ftp_list(ftpbuf_t *ftp, const char *path, int recursive TSRMLS_DC){	return ftp_genlist(ftp, ((recursive) ? "LIST -R" : "LIST"), path TSRMLS_CC);}/* }}} *//* {{{ ftp_type */intftp_type(ftpbuf_t *ftp, ftptype_t type){	char		typechar[2] = "?";	if (ftp == NULL)		return 0;	if (type == ftp->type)		return 1;	if (type == FTPTYPE_ASCII)		typechar[0] = 'A';	else if (type == FTPTYPE_IMAGE)		typechar[0] = 'I';	else		return 0;	if (!ftp_putcmd(ftp, "TYPE", typechar))		return 0;	if (!ftp_getresp(ftp) || ftp->resp != 200)		return 0;	ftp->type = type;	return 1;}/* }}} *//* {{{ ftp_pasv */intftp_pasv(ftpbuf_t *ftp, int pasv){	char			*ptr;	union ipbox		ipbox;	unsigned long		b[6];	socklen_t			n;	struct sockaddr *sa;	struct sockaddr_in *sin;	if (ftp == NULL)		return 0;	if (pasv && ftp->pasv == 2)		return 1;	ftp->pasv = 0;	if (!pasv)		return 1;	n = sizeof(ftp->pasvaddr);	memset(&ftp->pasvaddr, 0, n);	sa = (struct sockaddr *) &ftp->pasvaddr;#ifdef HAVE_IPV6	if (getpeername(ftp->fd, sa, &n) < 0)		return 0;	if (sa->sa_family == AF_INET6) {		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;		char *endptr, delimiter;		/* try EPSV first */		if (!ftp_putcmd(ftp, "EPSV", NULL))			return 0;		if (!ftp_getresp(ftp))			return 0;		if (ftp->resp == 229) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -