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

📄 ftp.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	int		n;	tv.tv_sec = 0;	tv.tv_usec = 1;	FD_ZERO(&write_set);	FD_SET(s, &write_set);	n = select(s + 1, NULL, &write_set, NULL, &tv);	if (n < 1) {#ifndef PHP_WIN32		if (n == 0)			errno = ETIMEDOUT;#endif		return 0;	}	return 1;}/* }}} *//* {{{ my_accept */intmy_accept(ftpbuf_t *ftp, int s, struct sockaddr *addr, socklen_t *addrlen){	fd_set		accept_set;	struct timeval	tv;	int		n;	tv.tv_sec = ftp->timeout_sec;	tv.tv_usec = 0;	FD_ZERO(&accept_set);	FD_SET(s, &accept_set);	n = select(s + 1, &accept_set, NULL, NULL, &tv);	if (n < 1) {#if !defined(PHP_WIN32) && !(defined(NETWARE) && defined(USE_WINSOCK))		if (n == 0)			errno = ETIMEDOUT;#endif		return -1;	}	return accept(s, addr, addrlen);}/* }}} *//* {{{ ftp_getdata */databuf_t*ftp_getdata(ftpbuf_t *ftp TSRMLS_DC){	int			fd = -1;	databuf_t		*data;	php_sockaddr_storage addr;	struct sockaddr *sa;	socklen_t		size;	union ipbox		ipbox;	char			arg[sizeof("255, 255, 255, 255, 255, 255")];	struct timeval	tv;	/* ask for a passive connection if we need one */	if (ftp->pasv && !ftp_pasv(ftp, 1))		return NULL;	/* alloc the data structure */	data = ecalloc(1, sizeof(*data));	data->listener = -1;	data->fd = -1;	data->type = ftp->type;	sa = (struct sockaddr *) &ftp->localaddr;	/* bind/listen */	if ((fd = socket(sa->sa_family, SOCK_STREAM, 0)) == -1) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "socket() failed: %s (%d)\n", strerror(errno), errno);		goto bail;	}	/* passive connection handler */	if (ftp->pasv) {		/* clear the ready status */		ftp->pasv = 1;		/* connect */		/* Win 95/98 seems not to like size > sizeof(sockaddr_in) */		size = php_sockaddr_size(&ftp->pasvaddr);		tv.tv_sec = ftp->timeout_sec;		tv.tv_usec = 0;		if (php_connect_nonb(fd, (struct sockaddr*) &ftp->pasvaddr, size, &tv) == -1) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_connect_nonb() failed: %s (%d)\n", strerror(errno), errno);			goto bail;		}		data->fd = fd;		ftp->data = data;		return data;	}	/* active (normal) connection */	/* bind to a local address */	php_any_addr(sa->sa_family, &addr, 0);	size = php_sockaddr_size(&addr);	if (bind(fd, (struct sockaddr*) &addr, size) == -1) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "bind() failed: %s (%d)\n", strerror(errno), errno);		goto bail;	}	if (getsockname(fd, (struct sockaddr*) &addr, &size) == -1) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "getsockname() failed: %s (%d)\n", strerror(errno), errno);		goto bail;	}	if (listen(fd, 5) == -1) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "listen() failed: %s (%d)\n", strerror(errno), errno);		goto bail;	}	data->listener = fd;#ifdef HAVE_IPV6	if (sa->sa_family == AF_INET6) {		/* need to use EPRT */		char eprtarg[INET6_ADDRSTRLEN + sizeof("|x||xxxxx|")];		char out[INET6_ADDRSTRLEN];		inet_ntop(AF_INET6, &((struct sockaddr_in6*) sa)->sin6_addr, out, sizeof(out));		sprintf(eprtarg, "|2|%s|%hu|", out, ntohs(((struct sockaddr_in6 *) &addr)->sin6_port));		if (!ftp_putcmd(ftp, "EPRT", eprtarg))			goto bail;		if (!ftp_getresp(ftp) || ftp->resp != 200)			goto bail;		ftp->data = data;		return data;	}#endif	/* send the PORT */	ipbox.ia[0] = ((struct sockaddr_in*) sa)->sin_addr;	ipbox.s[2] = ((struct sockaddr_in*) &addr)->sin_port;	sprintf(arg, "%u,%u,%u,%u,%u,%u",		ipbox.c[0], ipbox.c[1], ipbox.c[2], ipbox.c[3],		ipbox.c[4], ipbox.c[5]);	if (!ftp_putcmd(ftp, "PORT", arg))		goto bail;	if (!ftp_getresp(ftp) || ftp->resp != 200)		goto bail;	ftp->data = data;	return data;bail:	if (fd != -1)		closesocket(fd);	efree(data);	return NULL;}/* }}} *//* {{{ data_accept */databuf_t*data_accept(databuf_t *data, ftpbuf_t *ftp){	php_sockaddr_storage addr;	socklen_t			size;#ifdef HAVE_OPENSSL_EXT	SSL_CTX		*ctx;	TSRMLS_FETCH();	#endif	if (data->fd != -1)		goto data_accepted;	size = sizeof(addr);	data->fd = my_accept(ftp, data->listener, (struct sockaddr*) &addr, &size);	closesocket(data->listener);	data->listener = -1;	if (data->fd == -1) {		efree(data);		return NULL;	}data_accepted:#ifdef HAVE_OPENSSL_EXT		/* now enable ssl if we need to */	if (ftp->use_ssl && ftp->use_ssl_for_data) {		ctx = SSL_CTX_new(SSLv23_client_method());		if (ctx == NULL) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_accept: failed to create the SSL context");			return 0;		}		SSL_CTX_set_options(ctx, SSL_OP_ALL);		data->ssl_handle = SSL_new(ctx);		if (data->ssl_handle == NULL) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_accept: failed to create the SSL handle");			SSL_CTX_free(ctx);			return 0;		}							SSL_set_fd(data->ssl_handle, data->fd);		if (ftp->old_ssl) {			SSL_copy_session_id(data->ssl_handle, ftp->ssl_handle);		}					if (SSL_connect(data->ssl_handle) <= 0) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_accept: SSL/TLS handshake failed");			SSL_shutdown(data->ssl_handle);			return 0;		}					data->ssl_active = 1;	}	#endif	return data;}/* }}} *//* {{{ data_close */databuf_t*data_close(ftpbuf_t *ftp, databuf_t *data){	if (data == NULL)		return NULL;	if (data->listener != -1) {#ifdef HAVE_OPENSSL_EXT		if (data->ssl_active) {			SSL_shutdown(data->ssl_handle);			data->ssl_active = 0;		}#endif						closesocket(data->listener);	}		if (data->fd != -1) {#ifdef HAVE_OPENSSL_EXT		if (data->ssl_active) {			SSL_shutdown(data->ssl_handle);			data->ssl_active = 0;		}#endif						closesocket(data->fd);	}		if (ftp) {		ftp->data = NULL;	}	efree(data);	return NULL;}/* }}} *//* {{{ ftp_genlist */char**ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC){	php_stream	*tmpstream = NULL;	databuf_t	*data = NULL;	char		*ptr;	int		ch, lastch;	int		size, rcvd;	int		lines;	char		**ret = NULL;	char		**entry;	char		*text;	if ((tmpstream = php_stream_fopen_tmpfile()) == NULL) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create temporary file.  Check permissions in temporary files directory.");		return NULL;	}	if (!ftp_type(ftp, FTPTYPE_ASCII))		goto bail;	if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL)		goto bail;	ftp->data = data;		if (!ftp_putcmd(ftp, cmd, path))		goto bail;	if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125 && ftp->resp != 226))		goto bail;	/* some servers don't open a ftp-data connection if the directory is empty */	if (ftp->resp == 226) {		ftp->data = data_close(ftp, data);		php_stream_close(tmpstream);		return ecalloc(1, sizeof(char**));	}	/* pull data buffer into tmpfile */	if ((data = data_accept(data, ftp)) == NULL)		goto bail;	size = 0;	lines = 0;	lastch = 0;	while ((rcvd = my_recv(ftp, data->fd, data->buf, FTP_BUFSIZE))) {		if (rcvd == -1)			goto bail;		php_stream_write(tmpstream, data->buf, rcvd);		size += rcvd;		for (ptr = data->buf; rcvd; rcvd--, ptr++) {			if (*ptr == '\n' && lastch == '\r')				lines++;			else				size++;			lastch = *ptr;		}	}	ftp->data = data = data_close(ftp, data);	php_stream_rewind(tmpstream);	ret = emalloc((lines + 1) * sizeof(char**) + size * sizeof(char*));	entry = ret;	text = (char*) (ret + lines + 1);	*entry = text;	lastch = 0;	while ((ch = php_stream_getc(tmpstream)) != EOF) {		if (ch == '\n' && lastch == '\r') {			*(text - 1) = 0;			*++entry = text;		}		else {			*text++ = ch;		}		lastch = ch;	}	*entry = NULL;	php_stream_close(tmpstream);	if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) {		efree(ret);		return NULL;	}	return ret;bail:	ftp->data = data_close(ftp, data);	php_stream_close(tmpstream);	if (ret)		efree(ret);	return NULL;}/* }}} *//* {{{ ftp_nb_get */intftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos TSRMLS_DC){	databuf_t		*data = NULL;	char			arg[11];	if (ftp == NULL)		goto bail;	if (!ftp_type(ftp, type)) {		goto bail;	}	if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL) {		goto bail;	}	if (resumepos>0) {		sprintf(arg, "%u", resumepos);		if (!ftp_putcmd(ftp, "REST", arg)) {			goto bail;		}		if (!ftp_getresp(ftp) || (ftp->resp != 350)) {			goto bail;		}	}	if (!ftp_putcmd(ftp, "RETR", path)) {		goto bail;	}	if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) {		goto bail;	}	if ((data = data_accept(data, ftp)) == NULL) {		goto bail;	}	ftp->data = data;	ftp->stream = outstream;	ftp->lastch = 0;	ftp->nb = 1;	return (ftp_nb_continue_read(ftp));bail:	ftp->data = data_close(ftp, data);	return PHP_FTP_FAILED;}/* }}} *//* {{{ ftp_nb_continue_read */intftp_nb_continue_read(ftpbuf_t *ftp){	databuf_t	*data = NULL;	char		*ptr;	int			lastch;	size_t		rcvd;	ftptype_t	type;	TSRMLS_FETCH();	data = ftp->data;	/* check if there is already more data */	if (!data_available(ftp, data->fd)) {		return PHP_FTP_MOREDATA;	}	type = ftp->type;	lastch = ftp->lastch;	if ((rcvd = my_recv(ftp, data->fd, data->buf, FTP_BUFSIZE))) {		if (rcvd == -1) {			goto bail;		}		if (type == FTPTYPE_ASCII) {			for (ptr = data->buf; rcvd; rcvd--, ptr++) {				if (lastch == '\r' && *ptr != '\n')					php_stream_putc(ftp->stream, '\r');				if (*ptr != '\r')					php_stream_putc(ftp->stream, *ptr);				lastch = *ptr;			}		}		else {			if (rcvd != php_stream_write(ftp->stream, data->buf, rcvd))				goto bail;		}		ftp->lastch = lastch;		return PHP_FTP_MOREDATA;	}	if (type == FTPTYPE_ASCII && lastch == '\r')		php_stream_putc(ftp->stream, '\r');	ftp->data = data = data_close(ftp, data);	if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) {		goto bail;	}	ftp->nb = 0;	return PHP_FTP_FINISHED;bail:	ftp->nb = 0;	ftp->data = data_close(ftp, data);	return PHP_FTP_FAILED;}/* }}} *//* {{{ ftp_nb_put */intftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos TSRMLS_DC){	databuf_t		*data = NULL;	char			arg[11];	if (ftp == NULL)		return 0;	if (!ftp_type(ftp, type))		goto bail;	if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL)		goto bail;	if (startpos>0) {		if (startpos > 2147483647) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files with a size greater then 2147483647 bytes.\n");			goto bail;		}		sprintf(arg, "%u", startpos);		if (!ftp_putcmd(ftp, "REST", arg)) {			goto bail;		}		if (!ftp_getresp(ftp) || (ftp->resp != 350)) {			goto bail;		}	}	if (!ftp_putcmd(ftp, "STOR", path))		goto bail;	if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125))		goto bail;	if ((data = data_accept(data, ftp)) == NULL)		goto bail;	ftp->data = data;	ftp->stream = instream;	ftp->lastch = 0;	ftp->nb = 1;	return (ftp_nb_continue_write(ftp));bail:	ftp->data = data_close(ftp, data);	return PHP_FTP_FAILED;}/* }}} *//* {{{ ftp_nb_continue_write */intftp_nb_continue_write(ftpbuf_t *ftp){	int			size;	char			*ptr;	int 			ch;	TSRMLS_FETCH();	/* check if we can write more data */	if (!data_writeable(ftp, ftp->data->fd)) {		return PHP_FTP_MOREDATA;	}	size = 0;	ptr = ftp->data->buf;	while (!php_stream_eof(ftp->stream) && (ch = php_stream_getc(ftp->stream))!=EOF) {		if (ch == '\n' && ftp->type == FTPTYPE_ASCII) {			*ptr++ = '\r';			size++;		}		*ptr++ = ch;		size++;		/* flush if necessary */		if (FTP_BUFSIZE - size < 2) {			if (my_send(ftp, ftp->data->fd, ftp->data->buf, size) != size)				goto bail;			return PHP_FTP_MOREDATA;		}	}	if (size && my_send(ftp, ftp->data->fd, ftp->data->buf, size) != size)		goto bail;	ftp->data = data_close(ftp, ftp->data);	if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250))		goto bail;	ftp->nb = 0;	return PHP_FTP_FINISHED;bail:	ftp->data = data_close(ftp, ftp->data);	ftp->nb = 0;	return PHP_FTP_FAILED;}/* }}} */#endif /* HAVE_FTP *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */

⌨️ 快捷键说明

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