cvs: /php3/functions php_ftp.c php_ftp.h /php3 Makefile.in internal_functions.c /php3/functions ftp.c ftp.h /php3/regex engine.ih regcomp.ih
regerror.ih

From: Date: Mon, 20 Sep 1999 15:39:07 +0000
Subject: cvs: /php3/functions php_ftp.c php_ftp.h /php3 Makefile.in internal_functions.c /php3/functions ftp.c ftp.h /php3/regex engine.ih regcomp.ih
regerror.ih
Groups: php.dev 
Request: Send a blank email to php-dev+get-11099@lists.php.net to get a copy of this message
askalski Mon Sep 20 11:39:07 1999 EDT Added files: /php3/functions php_ftp.c php_ftp.h Modified files: /php3 Makefile.in internal_functions.c /php3/functions ftp.c ftp.h /php3/regex engine.ih regcomp.ih regerror.ih Log: replaced ftplib with own routines because of license incompatibility Index: php3/Makefile.in diff -u php3/Makefile.in:1.351 php3/Makefile.in:1.352 --- php3/Makefile.in:1.351 Thu Sep 16 13:20:14 1999 +++ php3/Makefile.in Mon Sep 20 11:39:05 1999 @@ -24,7 +24,7 @@ # +----------------------------------------------------------------------+ # -# $Id: Makefile.in,v 1.351 1999/09/16 17:20:14 musone Exp $ +# $Id: Makefile.in,v 1.352 1999/09/20 15:39:05 askalski Exp $ # prefix = @prefix@ @@ -78,7 +78,7 @@ functions/dl.c functions/dns.c functions/exec.c functions/file.c \ functions/filepro.c functions/filestat.c \ functions/formatted_print.c functions/fsock.c functions/gd.c \ - functions/head.c functions/html.c functions/image.c functions/imap.c functions/php3_mcal.c functions/ftp.c functions/ftplib.c functions/imsp.c \ + functions/head.c functions/html.c functions/image.c functions/imap.c functions/php3_mcal.c functions/php_ftp.c functions/ftp.c functions/imsp.c \ functions/link.c functions/mail.c functions/math.c functions/iptc.c \ functions/md5.c functions/microtime.c functions/mime.c \ functions/msql.c functions/mysql.c \ @@ -292,7 +292,7 @@ functions/oracle.h functions/base64.h functions/php3_dir.h \ functions/dns.h functions/php3_pgsql.h functions/php3_velocis.h \ functions/php3_sybase.h functions/php3_sybase-ct.h functions/reg.h \ - functions/php3_mail.h functions/imap.h functions/php3_mcal.h functions/ftp.h functions/ftplib.h functions/imsp.h functions/php3_aspell.h \ + functions/php3_mail.h functions/imap.h functions/php3_mcal.h functions/php_ftp.h functions/ftp.h functions/imsp.h functions/php3_aspell.h \ functions/md5.h functions/php3_global.h functions/php3_gd.h \ functions/html.h functions/dl.h functions/head.h functions/post.h \ functions/exec.h functions/php3_solid.h functions/adabasd.h \ @@ -481,11 +481,11 @@ php3_hash.h alloc.h safe_mode.h fopen-wrappers.h \ mod_php3.h stack.h operators.h token_cache.h variables.h constants.h \ internal_functions.h modules.h -functions/ftplib.o: functions/ftplib.c functions/ftplib.h config.h php.h php_version.h request_info.h \ +functions/ftp.o: functions/ftp.c functions/ftp.h config.h php.h php_version.h request_info.h \ php3_hash.h alloc.h safe_mode.h fopen-wrappers.h \ mod_php3.h stack.h operators.h token_cache.h variables.h constants.h \ internal_functions.h modules.h -functions/ftp.o: functions/ftp.c functions/ftp.h config.h php.h php_version.h request_info.h \ +functions/php_ftp.o: functions/php_ftp.c functions/php_ftp.h functions/ftp.h config.h php.h php_version.h request_info.h \ php3_hash.h alloc.h safe_mode.h fopen-wrappers.h \ mod_php3.h stack.h operators.h token_cache.h variables.h constants.h \ internal_functions.h modules.h Index: php3/internal_functions.c diff -u php3/internal_functions.c:1.359 php3/internal_functions.c:1.360 --- php3/internal_functions.c:1.359 Thu Sep 16 13:20:14 1999 +++ php3/internal_functions.c Mon Sep 20 11:39:06 1999 @@ -29,7 +29,7 @@ */ -/* $Id: internal_functions.c,v 1.359 1999/09/16 17:20:14 musone Exp $ */ +/* $Id: internal_functions.c,v 1.360 1999/09/20 15:39:06 askalski Exp $ */ #ifdef THREAD_SAFE #include "tls.h" @@ -69,7 +69,7 @@ #include "functions/imap.h" #include "functions/imsp.h" #include "functions/php3_mcal.h" -#include "functions/ftp.h" +#include "functions/php_ftp.h" #include "functions/php3_aspell.h" #include "functions/md5.h" #include "functions/php3_gd.h" Index: php3/functions/ftp.c diff -u php3/functions/ftp.c:1.4 php3/functions/ftp.c:1.5 --- php3/functions/ftp.c:1.4 Mon Sep 20 06:36:33 1999 +++ php3/functions/ftp.c Mon Sep 20 11:39:06 1999 @@ -30,420 +30,698 @@ #include "php.h" -#ifndef ZEND_VERSION -#include "internal_functions.h" -#endif - -#ifdef ZEND_VERSION -#include "php_globals.h" -#endif - -#ifndef ZEND_VERSION -#include "php3_list.h" -#endif - #if HAVE_FTP -#include "ftplib.h" +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> #include "ftp.h" + + +/* 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 port for ftp transfer */ +static databuf_t* ftp_port(ftpbuf_t *ftp); -static int le_netbuf; +/* accepts the data connection, returns updated data buffer */ +static databuf_t* data_accept(databuf_t *data); + +/* closes the data connection, returns NULL */ +static databuf_t* data_close(databuf_t *data); + +/* generic file lister */ +static char** ftp_genlist(ftpbuf_t *ftp, + const char *cmd, const char *path); + + +ftpbuf_t* +ftp_open(const char *host, short port) +{ + int fd = -1; + ftpbuf_t *ftp; + struct sockaddr_in addr; + struct hostent *he; + int size; -function_entry php3_ftp_functions[] = { - PHP_FE(ftp_connect, NULL) - PHP_FE(ftp_login, NULL) - PHP_FE(ftp_chdir, NULL) - PHP_FE(ftp_nlist, NULL) - PHP_FE(ftp_get, NULL) - PHP_FE(ftp_put, NULL) - PHP_FE(ftp_quit, NULL) - {NULL, NULL, NULL} -}; - -#ifdef ZEND_VERSION -php3_module_entry php3_ftp_module_entry = { - "FTP Functions", - php3_ftp_functions, - PHP_MINIT(ftp), - NULL, - NULL, - NULL, - NULL, - STANDARD_MODULE_PROPERTIES -}; - -#else -php3_module_entry php3_ftp_module_entry = { - "FTP Functions", - php3_ftp_functions, - PHP_MINIT_FUNCTION, - NULL, - NULL, - NULL, - NULL, - STANDARD_MODULE_PROPERTIES -}; - -#endif - -static void ftp_destructor_netbuf(netbuf *net) -{ - if (net) { - FtpQuit(net); - } -} - -#ifdef ZEND_VERSION -PHP_MINIT_FUNCTION(ftp) -#else -int PHP_MINIT_FUNCTION(INIT_FUNC_ARGS) -#endif -{ - le_netbuf = register_list_destructors(ftp_destructor_netbuf, NULL); - REGISTER_MAIN_LONG_CONSTANT("FTP_ASCII", FTPLIB_ASCII, - CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("FTP_BINARY", FTPLIB_BINARY, - CONST_PERSISTENT | CONST_CS); - return SUCCESS; -} - -PHP_FUNCTION(ftp_connect) -{ - pval *arg1; - int id; - netbuf *net; - - /* arg1 - hostname - */ - if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { - WRONG_PARAM_COUNT; + /* set up the address */ + if ((he = gethostbyname(host)) == NULL) { + herror("gethostbyname"); + return NULL; } - convert_to_string(arg1); + memset(&addr, 0, sizeof(addr)); + memcpy(&addr.sin_addr, he->h_addr, he->h_length); + addr.sin_port = port ? port : htons(21); - /* connect */ - if (!FtpConnect(arg1->value.str.val, &net)) { - php_error(E_WARNING, "FtpConnect: %s", FtpLastResponse(net)); - RETURN_FALSE; + + /* alloc the ftp structure */ + ftp = calloc(1, sizeof(*ftp)); + if (ftp == NULL) { + perror("calloc"); + return NULL; } - id = php3_list_insert(net, le_netbuf); - RETURN_LONG(id); -} + /* connect */ + if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { + perror("socket"); + goto bail; + } -PHP_FUNCTION(ftp_login) -{ - pval *arg1, *arg2, *arg3; - int id, type; - netbuf *net; + if (connect(fd, (struct sockaddr*) &addr, sizeof(addr)) == -1) { + perror("connect"); + goto bail; + } - /* arg1 - netbuf - * arg2 - username - * arg3 - password - */ - if ( ARG_COUNT(ht) != 3 || - getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) - { - WRONG_PARAM_COUNT; + size = sizeof(addr); + if (getsockname(fd, (struct sockaddr*) &addr, &size) == -1) { + perror("getsockname"); + goto bail; } - convert_to_long(arg1); - convert_to_string(arg2); - convert_to_string(arg3); + ftp->localaddr = addr.sin_addr; - id = arg1->value.lval; - net = php3_list_find(id, &type); - if (!net || type != le_netbuf) { - php_error(E_WARNING, "Unable to find netbuf %d", id); - RETURN_FALSE; + if ((ftp->fp = fdopen(fd, "r+")) == NULL) { + perror("fdopen"); + goto bail; } - /* log in */ - if (!FtpLogin(arg2->value.str.val, arg3->value.str.val, net)) { - php_error(E_WARNING, "FtpLogin: %s", FtpLastResponse(net)); - RETURN_FALSE; + if (!ftp_getresp(ftp) || ftp->resp != 220) { + goto bail; } + + return ftp; + +bail: + if (ftp->fp) + fclose(ftp->fp); + else if (fd != -1) + close(fd); + free(ftp); + return NULL; +} + - RETURN_TRUE; +ftpbuf_t* +ftp_close(ftpbuf_t *ftp) +{ + if (ftp == NULL) + return NULL; + if (ftp->fp) + fclose(ftp->fp); + ftp_gc(ftp); + free(ftp); + return NULL; } -PHP_FUNCTION(ftp_chdir) + +void +ftp_gc(ftpbuf_t *ftp) { - pval *arg1, *arg2; - int id, type; - netbuf *net; + if (ftp == NULL) + return; - /* arg1 - netbuf - * arg2 - directory - */ - if ( ARG_COUNT(ht) != 2 || - getParameters(ht, 2, &arg1, &arg2) == FAILURE) - { - WRONG_PARAM_COUNT; - } + free(ftp->pwd); + ftp->pwd = NULL; + free(ftp->syst); + ftp->syst = NULL; +} - convert_to_long(arg1); - convert_to_string(arg2); - id = arg1->value.lval; - net = php3_list_find(id, &type); - if (!net || type != le_netbuf) { - php_error(E_WARNING, "Unable to find netbuf %d", id); - RETURN_FALSE; - } +int +ftp_quit(ftpbuf_t *ftp) +{ + if (ftp == NULL) + return 0; - /* change directories */ - if (!FtpChdir(arg2->value.str.val, net)) { - php_error(E_WARNING, "FtpChdir: %s", FtpLastResponse(net)); - RETURN_FALSE; - } + fprintf(ftp->fp, "QUIT\r\n"); + if (!ftp_getresp(ftp) || ftp->resp != 221) + return 0; + + free(ftp->pwd); + ftp->pwd = NULL; - RETURN_TRUE; + return 1; } -PHP_FUNCTION(ftp_nlist) + +int +ftp_login(ftpbuf_t *ftp, const char *user, const char *pass) { - pval *arg1, *arg2; - int id, type; - netbuf *net; - FILE *outfp; - char *entry = NULL; - char *ptr; - long size; - char ch; + if (ftp == NULL) + return 0; + fprintf(ftp->fp, "USER %s\r\n", user); + if (!ftp_getresp(ftp)) + return 0; + if (ftp->resp == 230) + return 1; + if (ftp->resp != 331) + return 0; + fprintf(ftp->fp, "PASS %s\r\n", pass); + if (!ftp_getresp(ftp)) + return 0; + return (ftp->resp == 230); +} - /* arg1 - netbuf - * arg2 - directory - */ - if ( ARG_COUNT(ht) != 2 || - getParameters(ht, 2, &arg1, &arg2) == FAILURE) - { - WRONG_PARAM_COUNT; - } - convert_to_long(arg1); - convert_to_string(arg2); +int +ftp_reinit(ftpbuf_t *ftp) +{ + if (ftp == NULL) + return 0; - id = arg1->value.lval; - net = php3_list_find(id, &type); - if (!net || type != le_netbuf) { - php_error(E_WARNING, "Unable to find netbuf %d", id); - RETURN_FALSE; - } + ftp_gc(ftp); - /* set up a temporary output file */ - if ((outfp = tmpfile()) == NULL) { - php_error(E_WARNING, "error opening tmpfile"); - RETURN_FALSE; - } + fprintf(ftp->fp, "REIN\r\n"); + if (!ftp_getresp(ftp) || ftp->resp != 220) + return 0; - /* list to the temporary file */ - if (!FtpNlst(outfp, arg2->value.str.val, net) || ferror(outfp)) { - fclose(outfp); - RETURN_FALSE; - } + return 1; +} + + +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; + + fprintf(ftp->fp, "SYST\r\n"); + if (!ftp_getresp(ftp) || ftp->resp != 215) + return NULL; + + syst = ftp->inbuf; + if ((end = strchr(syst, ' '))) + *end = 0; + ftp->syst = strdup(syst); + if (end) + *end = ' '; + + return ftp->syst; +} + + +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; + + fprintf(ftp->fp, "PWD\r\n"); + if (!ftp_getresp(ftp) || ftp->resp != 257) + return NULL; + + /* copy out the pwd from response */ + if ((pwd = strchr(ftp->inbuf, '"')) == NULL) + return NULL; + end = strrchr(++pwd, '"'); + *end = 0; + ftp->pwd = strdup(pwd); + *end = '"'; + + return ftp->pwd; +} + + +int +ftp_chdir(ftpbuf_t *ftp, const char *dir) +{ + if (ftp == NULL) + return 0; + + free(ftp->pwd); + ftp->pwd = NULL; + + fprintf(ftp->fp, "CWD %s\r\n", dir); + if (!ftp_getresp(ftp) || ftp->resp != 250) + return 0; + + return 1; +} + + +int +ftp_cdup(ftpbuf_t *ftp) +{ + if (ftp == NULL) + return 0; + + free(ftp->pwd); + ftp->pwd = NULL; + + fprintf(ftp->fp, "CDUP\r\n"); + if (!ftp_getresp(ftp) || ftp->resp != 250) + return 0; + + return 1; +} + + +char* +ftp_mkdir(ftpbuf_t *ftp, const char *dir) +{ + char *mkd, *end; + + if (ftp == NULL) + return NULL; + + fprintf(ftp->fp, "MKD %s\r\n", dir); + if (!ftp_getresp(ftp) || ftp->resp != 257) + return NULL; + + /* copy out the dir from response */ + if ((mkd = strchr(ftp->inbuf, '"')) == NULL) + return NULL; + end = strrchr(++mkd, '"'); + *end = 0; + mkd = strdup(mkd); + *end = '"'; + + return mkd; +} + + +int +ftp_rmdir(ftpbuf_t *ftp, const char *dir) +{ + if (ftp == NULL) + return 0; - array_init(return_value); - rewind(outfp); + fprintf(ftp->fp, "RMD %s\r\n", dir); + if (!ftp_getresp(ftp) || ftp->resp != 250) + return 0; - /* Pluck out each file name and save to the return array. */ + return 1; +} + + +char** +ftp_nlist(ftpbuf_t *ftp, const char *path) +{ + return ftp_genlist(ftp, "NLST", path); +} + + +char** +ftp_list(ftpbuf_t *ftp, const char *path) +{ + return ftp_genlist(ftp, "LIST", path); +} + + +int +ftp_getresp(ftpbuf_t *ftp) +{ + char tag[4]; + int ch; + char *buf; + char *ptr; + + if (ftp == NULL) + return 0; + buf = ftp->inbuf; + ftp->resp = 0; + do { - /* scan for end of line */ - size = 1; - while ((ch = getc(outfp)) != '\n') { - if (ch == EOF) { - size = -1; - break; - } - size++; - } + if (!fread(tag, 4, 1, ftp->fp)) + return 0; - if (size > 0) { - /* seek back to the start of file name and copy - * to a buffer. add the buffer to the array. - */ - fseek(outfp, -size, SEEK_CUR); - entry = emalloc(size); - ptr = entry; - while (--size) - *ptr++ = getc(outfp); + if (tag[3] == '-') { + while ((ch = getc(ftp->fp)) != '\n') + if (ch == EOF) { + return 0; + } + } + else if (tag[3] == ' ') { + ptr = fgets(buf, FTP_BUFSIZE, ftp->fp); + if (!ptr || !(ptr = strchr(buf, '\n'))) + return 0; + if (ptr > buf && ptr[-1] == '\r') + ptr--; *ptr = 0; - - add_next_index_string(return_value, entry, 0); } + else { + return 0; + } + } while (tag[3] == '-'); + + + /* translate the tag */ + if (!isdigit(tag[0]) || !isdigit(tag[1]) || !isdigit(tag[2])) + return 0; - /* eat the \n */ - (void) getc(outfp); - } while (size != -1); - fclose(outfp); + ftp->resp = 100 * (tag[0] - '0') + + 10 * (tag[1] - '0') + + (tag[2] - '0'); + return 1; } -PHP_FUNCTION(ftp_get) -{ - pval *arg1, *arg2, *arg3, *arg4; - int id, type; - netbuf *net; - FILE *outfp, *tmpfp; - char *entry = NULL; - char *ptr; - long size; - char ch; +int +ftp_type(ftpbuf_t *ftp, ftptype_t type) +{ + char typechar; - /* arg1 - netbuf - * arg2 - destination (local) file - * arg3 - source (remote) file - * arg4 - transfer mode - */ - if ( ARG_COUNT(ht) != 4 || - getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE) - { - WRONG_PARAM_COUNT; - } - - convert_to_long(arg1); - convert_to_string(arg2); - convert_to_string(arg3); - convert_to_long(arg4); - - id = arg1->value.lval; - net = php3_list_find(id, &type); - if (!net || type != le_netbuf) { - php_error(E_WARNING, "Unable to find netbuf %d", id); - RETURN_FALSE; - } - - if ( arg4->value.lval != FTPLIB_ASCII && - arg4->value.lval != FTPLIB_BINARY) - { - php_error(E_WARNING, "arg4 must be FTP_ASCII or FTP_BINARY"); - RETURN_FALSE; - } + if (ftp == NULL) + return 0; + if (type == ftp->type) + return 1; - /* get to temporary file, so if there is an error, no existing - * file gets clobbered - */ - if ((tmpfp = tmpfile()) == NULL) { - php_error(E_WARNING, "error opening tmpfile"); - RETURN_FALSE; - } - - if ( !FtpGet(tmpfp, arg3->value.str.val, arg4->value.lval, net) || - ferror(tmpfp)) - { - fclose(tmpfp); - php_error(E_WARNING, "FtpGet: %s", FtpLastResponse(net)); - RETURN_FALSE; - } + if (type == FTPTYPE_ASCII) + typechar = 'A'; + else if (type == FTPTYPE_IMAGE) + typechar = 'I'; + else + return 0; - rewind(tmpfp); + fprintf(ftp->fp, "TYPE %c\r\n", typechar); + if (!ftp_getresp(ftp) || ftp->resp != 200) + return 0; - if ((outfp = fopen(arg2->value.str.val, "w")) == NULL) { - fclose(tmpfp); - php_error(E_WARNING, "error opening %s", arg2->value.str.val); - RETURN_FALSE; - } + ftp->type = type; - while ((ch = getc(tmpfp)) != EOF) - putc(ch, outfp); - - if (ferror(tmpfp) || ferror(outfp)) { - fclose(tmpfp); - fclose(outfp); - php_error(E_WARNING, "error writing %s", arg2->value.str.val); - RETURN_FALSE; + return 1; +} + + +int +ftp_get(ftpbuf_t *ftp, FILE *outfp, const char *path, ftptype_t type) +{ + databuf_t *data = NULL; + int ch, lastch; + + if (ftp == NULL) + return 0; + + if (!ftp_type(ftp, type)) + goto bail; + + if ((data = ftp_port(ftp)) == NULL) + goto bail; + + fprintf(ftp->fp, "RETR %s\r\n", path); + if (!ftp_getresp(ftp) || ftp->resp != 150) + goto bail; + + if ((data = data_accept(data)) == NULL) + goto bail; + + lastch = 0; + while ((ch = getc(data->fp)) != EOF) { + if (type == FTPTYPE_ASCII) { + if (lastch == '\r' && ch != '\n') + putc('\r', outfp); + if (ch != '\r') + putc(ch, outfp); + lastch = ch; + } + else { + putc(ch, outfp); + } } + if (type == FTPTYPE_ASCII && lastch == '\r') + putc('\r', outfp); - fclose(tmpfp); - fclose(outfp); + if (ferror(data->fp) || ferror(outfp)) + goto bail; - RETURN_TRUE; + data = data_close(data); + + if (!ftp_getresp(ftp) || ftp->resp != 226) + goto bail; + + return 1; +bail: + data_close(data); + return 0; } + -PHP_FUNCTION(ftp_put) +int +ftp_put(ftpbuf_t *ftp, const char *path, FILE *infp, ftptype_t type) { - pval *arg1, *arg2, *arg3, *arg4; - int id, type; - netbuf *net; - FILE *infp; - char *entry = NULL; - char *ptr; - long size; - char ch; + databuf_t *data = NULL; + int ch; + if (ftp == NULL) + return 0; - /* arg1 - netbuf - * arg2 - destination (remote) file - * arg3 - source (local) file - * arg4 - transfer mode - */ - if ( ARG_COUNT(ht) != 4 || - getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE) - { - WRONG_PARAM_COUNT; - } + if (!ftp_type(ftp, type)) + goto bail; - convert_to_long(arg1); - convert_to_string(arg2); - convert_to_string(arg3); - convert_to_long(arg4); + if ((data = ftp_port(ftp)) == NULL) + goto bail; - id = arg1->value.lval; - net = php3_list_find(id, &type); - if (!net || type != le_netbuf) { - php_error(E_WARNING, "Unable to find netbuf %d", id); - RETURN_FALSE; - } + fprintf(ftp->fp, "STOR %s\r\n", path); + if (!ftp_getresp(ftp) || ftp->resp != 150) + goto bail; + + if ((data = data_accept(data)) == NULL) + goto bail; - if ( arg4->value.lval != FTPLIB_ASCII && - arg4->value.lval != FTPLIB_BINARY) - { - php_error(E_WARNING, "arg4 must be FTP_ASCII or FTP_BINARY"); - RETURN_FALSE; + while ((ch = getc(infp)) != EOF) { + if (type == FTPTYPE_ASCII && ch == '\n') + putc('\r', data->fp); + putc(ch, data->fp); } + + if (ferror(data->fp) || ferror(infp)) + goto bail; + + data = data_close(data); + + if (!ftp_getresp(ftp) || ftp->resp != 226) + goto bail; + + return 1; +bail: + data_close(data); + return 0; +} + + +databuf_t* +ftp_port(ftpbuf_t *ftp) +{ + int fd = -1; + databuf_t *data; + struct sockaddr_in addr; + int size; + union { + unsigned long l[1]; + unsigned short s[2]; + unsigned char c[4]; + } ipbox; + + /* alloc the data structure */ + data = calloc(1, sizeof(*data)); + if (data == NULL) { + perror("calloc"); + return NULL; + } + data->listener = -1; + data->type = ftp->type; + + /* bind/listen */ + if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { + perror("socket"); + goto bail; + } + + /* bind to a local address */ + memset(&addr, 0, sizeof(addr)); + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = 0; + + if (bind(fd, (struct sockaddr*) &addr, sizeof(addr)) == -1) { + perror("bind"); + goto bail; + } + + size = sizeof(addr); + if (getsockname(fd, (struct sockaddr*) &addr, &size) == -1) { + perror("getsockname"); + goto bail; + } + + if (listen(fd, 5) == -1) { + perror("listen"); + goto bail; + } + + data->listener = fd; + + /* send the PORT */ + ipbox.l[0] = ftp->localaddr.s_addr; + fprintf(ftp->fp, "PORT %u,%u,%u,%u,", + ipbox.c[0], ipbox.c[1], ipbox.c[2], ipbox.c[3]); + ipbox.s[0] = addr.sin_port; + fprintf(ftp->fp, "%u,%u\r\n", + ipbox.c[0], ipbox.c[1]); + + if (!ftp_getresp(ftp) || ftp->resp != 200) + goto bail; + + return data; + +bail: + if (fd != -1) + close(fd); + free(data); + return NULL; +} + + +databuf_t* +data_accept(databuf_t *data) +{ + struct sockaddr_in addr; + int size; + int fd; - if ((infp = fopen(arg3->value.str.val, "r")) == NULL) { - php_error(E_WARNING, "error opening %s", arg3->value.str.val); - RETURN_FALSE; + size = sizeof(addr); + fd = accept(data->listener, (struct sockaddr*) &addr, &size); + close(data->listener); + data->listener = -1; + + if (fd == -1) { + free(data); + return NULL; } - if ( !FtpPut(infp, arg2->value.str.val, arg4->value.lval, net) || - ferror(infp)) - { - fclose(infp); - php_error(E_WARNING, "FtpPut: %s", FtpLastResponse(net)); - RETURN_FALSE; + + if ((data->fp = fdopen(fd, "r+")) == NULL) { + close(fd); + free(data); + return NULL; } - fclose(infp); - RETURN_TRUE; + return data; } + -PHP_FUNCTION(ftp_quit) +databuf_t* +data_close(databuf_t *data) { - pval *arg1; - int id, type; - netbuf *net; + if (data == NULL) + return NULL; + if (data->listener != -1) + close(data->listener); + if (data->fp) + fclose(data->fp); + free(data); + return NULL; +} + - /* arg1 - netbuf - */ - if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) { - WRONG_PARAM_COUNT; +char** +ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path) +{ + FILE *tmpfp = NULL; + databuf_t *data = NULL; + int ch, lastch; + int size; + int lines; + char **ret = NULL; + char **entry; + char *text; + + + if ((tmpfp = tmpfile()) == NULL) + return NULL; + + if (!ftp_type(ftp, FTPTYPE_ASCII)) + goto bail; + + if ((data = ftp_port(ftp)) == NULL) + goto bail; + + if (path) + fprintf(ftp->fp, "%s %s\r\n", cmd, path); + else + fprintf(ftp->fp, "%s\r\n", cmd); + if (!ftp_getresp(ftp) || ftp->resp != 150) + goto bail; + + /* pull data buffer into tmpfile */ + if ((data = data_accept(data)) == NULL) + goto bail; + + size = 0; + lines = 0; + lastch = 0; + while ((ch = getc(data->fp)) != EOF) { + if (ch == '\n' && lastch == '\r') + lines++; + else + size++; + putc(ch, tmpfp); + lastch = ch; } + data = data_close(data); + + if (ferror(tmpfp)) + goto bail; + + rewind(tmpfp); - convert_to_long(arg1); - id = arg1->value.lval; - net = php3_list_find(id, &type); - if (!net || type != le_netbuf) { - php_error(E_WARNING, "Unable to find netbuf %d", id); - RETURN_FALSE; + ret = malloc((lines + 1) * sizeof(char**) + size * sizeof(char*)); + if (ret == NULL) { + perror("malloc"); + goto bail; } - php3_list_delete(id); + entry = ret; + text = (char*) (ret + lines + 1); + *entry = text; + lastch = 0; + while ((ch = getc(tmpfp)) != EOF) { + if (ch == '\n' && lastch == '\r') { + *(text - 1) = 0; + *++entry = text; + } + else { + *text++ = ch; + } + lastch = ch; + } + *entry = NULL; - RETURN_TRUE; + if (ferror(tmpfp)) + goto bail; + + fclose(tmpfp); + + if (!ftp_getresp(ftp) || ftp->resp != 226) { + free(ret); + return NULL; + } + + return ret; +bail: + data_close(data); + fclose(tmpfp); + free(ret); + return NULL; } #endif /* HAVE_FTP */ Index: php3/functions/ftp.h diff -u php3/functions/ftp.h:1.2 php3/functions/ftp.h:1.3 --- php3/functions/ftp.h:1.2 Thu Sep 16 13:20:14 1999 +++ php3/functions/ftp.h Mon Sep 20 11:39:06 1999 @@ -1,39 +1,131 @@ -/* $Id: ftp.h,v 1.2 1999/09/16 17:20:14 musone Exp $ */ - -#ifndef _INCLUDED_FTP_H -#define _INCLUDED_FTP_H - -#if COMPILE_DL -#undef HAVE_FTP -#define HAVE_FTP 1 -#endif - -#if HAVE_FTP - -extern php3_module_entry php3_ftp_module_entry; -#define php3_ftp_module_ptr &php3_ftp_module_entry - -#ifdef ZEND_VERSION -extern PHP_MINIT_FUNCTION(ftp); -PHP_MINFO_FUNCTION(ftp); -#else -extern int PHP_MINIT_FUNCTION(INIT_FUNC_ARGS); -extern void PHP_MINFO_FUNCTION(void); -#endif - - -PHP_FUNCTION(ftp_connect); -PHP_FUNCTION(ftp_login); -PHP_FUNCTION(ftp_chdir); -PHP_FUNCTION(ftp_nlist); -PHP_FUNCTION(ftp_get); -PHP_FUNCTION(ftp_put); -PHP_FUNCTION(ftp_quit); - -#define phpext_ftp_ptr php3_ftp_module_ptr - -#else -#define php3_ftp_module_ptr NULL -#endif /* HAVE_FTP */ +/* + +----------------------------------------------------------------------+ + | PHP HTML Embedded Scripting Language Version 3.0 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-1999 PHP Development Team (See Credits file) | + +----------------------------------------------------------------------+ + | This program is free software; you can redistribute it and/or modify | + | it under the terms of one of the following licenses: | + | | + | A) the GNU General Public License as published by the Free Software | + | Foundation; either version 2 of the License, or (at your option) | + | any later version. | + | | + | B) the PHP License as published by the PHP Development Team and | + | included in the distribution in the file: LICENSE | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of both licenses referred to here. | + | If you did not, or have any questions about PHP licensing, please | + | contact core@php.net. | + +----------------------------------------------------------------------+ + | Authors: | + | Andrew Skalski <askalski@chek.com> | + +----------------------------------------------------------------------+ + */ + +#ifndef _FTP_H +#define _FTP_H + +#include <stdio.h> +#include <netinet/in.h> + + +#define FTP_BUFSIZE 4096 + +typedef enum ftptype { + FTPTYPE_ASCII, + FTPTYPE_IMAGE, +} ftptype_t; + +typedef struct ftpbuf +{ + FILE *fp; /* control connection */ + struct in_addr localaddr; /* local inet address */ + int resp; /* last response code */ + char inbuf[FTP_BUFSIZE]; /* last response text */ + char *pwd; /* cached pwd */ + char *syst; /* cached system type */ + ftptype_t type; /* current transfer type */ +} ftpbuf_t; + +typedef struct databuf +{ + int listener; /* listener socket */ + FILE *fp; /* data connection */ + ftptype_t type; /* transfer type */ +} databuf_t; + + +/* open a FTP connection, returns ftpbuf (NULL on error) + * port is the ftp port in network byte order, or 0 for the default + */ +ftpbuf_t* ftp_open(const char *host, short port); + +/* quits from the ftp session (it still needs to be closed) + * return true on success, false on error + */ +int ftp_quit(ftpbuf_t *ftp); + +/* frees up any cached data held in the ftp buffer */ +void ftp_gc(ftpbuf_t *ftp); + +/* close the FTP connection and return NULL */ +ftpbuf_t* ftp_close(ftpbuf_t *ftp); + +/* logs into the FTP server, returns true on success, false on error */ +int ftp_login(ftpbuf_t *ftp, const char *user, const char *pass); + +/* reinitializes the connection, returns true on success, false on error */ +int ftp_reinit(ftpbuf_t *ftp); + +/* returns the remote system type (NULL on error) */ +const char* ftp_syst(ftpbuf_t *ftp); + +/* returns the present working directory (NULL on error) */ +const char* ftp_pwd(ftpbuf_t *ftp); + +/* changes directories, return true on success, false on error */ +int ftp_chdir(ftpbuf_t *ftp, const char *dir); + +/* changes to parent directory, return true on success, false on error */ +int ftp_cdup(ftpbuf_t *ftp); + +/* creates a directory, return the directory name on success, NULL on error. + * the return value must be freed + */ +char* ftp_mkdir(ftpbuf_t *ftp, const char *dir); + +/* removes a directory, return true on success, false on error */ +int ftp_rmdir(ftpbuf_t *ftp, const char *dir); + +/* returns a NULL-terminated array of filenames in the given path + * or NULL on error. the return array must be freed (but don't + * free the array elements) + */ +char** ftp_nlist(ftpbuf_t *ftp, const char *path); + +/* returns a NULL-terminated array of lines returned by the ftp + * LIST command for the given path or NULL on error. the return + * array must be freed (but don't + * free the array elements) + */ +char** ftp_list(ftpbuf_t *ftp, const char *path); + +/* retrieves a file and saves its contents to outfp + * returns true on success, false on error + */ +int ftp_get(ftpbuf_t *ftp, FILE *outfp, const char *path, + ftptype_t type); + +/* stores the data from infp as a file on the remote server + * returns true on success, false on error + */ +int ftp_put(ftpbuf_t *ftp, const char *path, FILE *infp, + ftptype_t type); #endif Index: php3/regex/engine.ih diff -u php3/regex/engine.ih:1.8 php3/regex/engine.ih:1.9 --- php3/regex/engine.ih:1.8 Wed Jun 30 20:03:53 1999 +++ php3/regex/engine.ih Mon Sep 20 11:39:06 1999 @@ -1,9 +1,9 @@ -/* ========= begin header generated by ../../regex/mkh ========= */ +/* ========= begin header generated by ./mkh ========= */ #ifdef __cplusplus extern "C" { #endif -/* === ../../regex/engine.c === */ +/* === engine.c === */ static int matcher(register struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags); static char *dissect(register struct match *m, char *start, char *stop, sopno startst, sopno stopst); static char *backref(register struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev); @@ -32,4 +32,4 @@ #ifdef __cplusplus } #endif -/* ========= end header generated by ../../regex/mkh ========= */ +/* ========= end header generated by ./mkh ========= */ Index: php3/regex/regcomp.ih diff -u php3/regex/regcomp.ih:1.9 php3/regex/regcomp.ih:1.10 --- php3/regex/regcomp.ih:1.9 Wed Jun 30 20:03:53 1999 +++ php3/regex/regcomp.ih Mon Sep 20 11:39:06 1999 @@ -1,9 +1,9 @@ -/* ========= begin header generated by ../../regex/mkh ========= */ +/* ========= begin header generated by ./mkh ========= */ #ifdef __cplusplus extern "C" { #endif -/* === ../../regex/regcomp.c === */ +/* === regcomp.c === */ static void p_ere(register struct parse *p, int stop); static void p_ere_exp(register struct parse *p); static void p_str(register struct parse *p); @@ -45,4 +45,4 @@ #ifdef __cplusplus } #endif -/* ========= end header generated by ../../regex/mkh ========= */ +/* ========= end header generated by ./mkh ========= */ Index: php3/regex/regerror.ih diff -u php3/regex/regerror.ih:1.8 php3/regex/regerror.ih:1.9 --- php3/regex/regerror.ih:1.8 Wed Jun 30 20:03:53 1999 +++ php3/regex/regerror.ih Mon Sep 20 11:39:06 1999 @@ -1,12 +1,12 @@ -/* ========= begin header generated by ../../regex/mkh ========= */ +/* ========= begin header generated by ./mkh ========= */ #ifdef __cplusplus extern "C" { #endif -/* === ../../regex/regerror.c === */ +/* === regerror.c === */ static char *regatoi(const regex_t *preg, char *localbuf); #ifdef __cplusplus } #endif -/* ========= end header generated by ../../regex/mkh ========= */ +/* ========= end header generated by ./mkh ========= */

« previous php.dev (#11099) next »