From a2df3c334593ed37e36d097c72ecd4a991682bd5 Mon Sep 17 00:00:00 2001 From: "Jordan K. Hubbard" Date: Sat, 22 Jun 1996 21:43:56 +0000 Subject: [PATCH] Fix a bug in the way binary/ascii settings were being done. New ftpAscii() call sets connection to ascii as counterpart to ftpBinary(). --- lib/libftpio/ftpio.c | 111 ++++++++++++++++++++++++++++--------------- lib/libftpio/ftpio.h | 9 ++-- 2 files changed, 78 insertions(+), 42 deletions(-) diff --git a/lib/libftpio/ftpio.c b/lib/libftpio/ftpio.c index bfc3a667946e..032eaa79338c 100644 --- a/lib/libftpio/ftpio.c +++ b/lib/libftpio/ftpio.c @@ -14,7 +14,7 @@ * Turned inside out. Now returns xfers as new file ids, not as a special * `state' of FTP_t * - * $Id: ftpio.c,v 1.5 1996/06/17 22:10:15 jkh Exp $ + * $Id: ftpio.c,v 1.6 1996/06/17 23:16:04 jkh Exp $ * */ @@ -48,6 +48,7 @@ /* Internal routines - deal only with internal FTP_t type */ static FTP_t ftp_new(void); +static void check_passive(FILE *fp); static int ftp_read_method(void *n, char *buf, int nbytes); static int ftp_write_method(void *n, const char *buf, int nbytes); static int ftp_close_method(void *n); @@ -65,6 +66,7 @@ static int get_url_info(char *url_in, char *host_ret, int *port_ret, char *name_ int FtpTimedOut; /* FTP status codes */ +#define FTP_ASCII_HAPPY 200 #define FTP_BINARY_HAPPY 200 #define FTP_PORT_HAPPY 200 #define FTP_QUIT_HAPPY 221 @@ -107,24 +109,35 @@ check_code(FTP_t ftp, int var, int preferred) } } } - -/* Returns a standard FILE pointer type representing an open control connection */ -FILE * -ftpLogin(char *host, char *user, char *passwd, int port) + +int +ftpAscii(FILE *fp) { - FTP_t n; - FILE *fp; + FTP_t ftp = fcookie(fp); + int i; - if (networkInit() != SUCCESS) - return NULL; + if (!ftp->is_binary) + return SUCCESS; + i = cmd(ftp, "TYPE A"); + if (i < 0 || check_code(ftp, i, FTP_ASCII_HAPPY)) + return i; + ftp->is_binary = FALSE; + return SUCCESS; +} - n = ftp_new(); - fp = NULL; - if (n && ftp_login_session(n, host, user, passwd, port) == SUCCESS) { - fp = funopen(n, ftp_read_method, ftp_write_method, NULL, ftp_close_method); /* BSD 4.4 function! */ - fp->_file = n->fd_ctrl; - } - return fp; +int +ftpBinary(FILE *fp) +{ + FTP_t ftp = fcookie(fp); + int i; + + if (ftp->is_binary) + return SUCCESS; + i = cmd(ftp, "TYPE I"); + if (i < 0 || check_code(ftp, i, FTP_BINARY_HAPPY)) + return i; + ftp->is_binary = TRUE; + return SUCCESS; } int @@ -153,6 +166,7 @@ ftpGetSize(FILE *fp, char *name) char p[BUFSIZ], *cp; FTP_t ftp = fcookie(fp); + check_passive(fp); sprintf(p, "SIZE %s\r\n", name); i = writes(ftp->fd_ctrl, p); if (i) @@ -172,6 +186,7 @@ ftpGetModtime(FILE *fp, char *name) FTP_t ftp = fcookie(fp); int i; + check_passive(fp); sprintf(p, "MDTM %s\r\n", name); i = writes(ftp->fd_ctrl, p); if (i) @@ -199,37 +214,59 @@ ftpGet(FILE *fp, char *file, int *seekto) FILE *fp2; FTP_t ftp = fcookie(fp); + check_passive(fp); + if (ftpBinary(fp) != SUCCESS) + return NULL; + if (ftp_file_op(ftp, "RETR", file, &fp2, "r", seekto) == SUCCESS) return fp2; return NULL; } +/* Returns a standard FILE pointer type representing an open control connection */ +FILE * +ftpLogin(char *host, char *user, char *passwd, int port) +{ + FTP_t n; + FILE *fp; + + if (networkInit() != SUCCESS) + return NULL; + + n = ftp_new(); + fp = NULL; + if (n && ftp_login_session(n, host, user, passwd, port) == SUCCESS) { + fp = funopen(n, ftp_read_method, ftp_write_method, NULL, ftp_close_method); /* BSD 4.4 function! */ + fp->_file = n->fd_ctrl; + } + return fp; +} + FILE * ftpPut(FILE *fp, char *file) { FILE *fp2; FTP_t ftp = fcookie(fp); + check_passive(fp); if (ftp_file_op(ftp, "STOR", file, &fp2, "w", NULL) == SUCCESS) return fp2; return NULL; } -int -ftpBinary(FILE *fp, int st) -{ - FTP_t ftp = fcookie(fp); - - ftp->binary = st; - return SUCCESS; -} - +/* Unlike binary mode, passive mode is a toggle! :-( */ int ftpPassive(FILE *fp, int st) { FTP_t ftp = fcookie(fp); + int i; - ftp->passive = st; + if (ftp->is_passive == st) + return SUCCESS; + i = cmd(ftp, "PASSIVE"); + if (i < 0) + return i; + ftp->is_passive = !ftp->is_passive; return SUCCESS; } @@ -321,10 +358,9 @@ ftp_new(void) memset(ftp, 0, sizeof *ftp); ftp->fd_ctrl = -1; ftp->con_state = init; + ftp->is_binary = FALSE; + ftp->is_passive = FALSE; ftp->errno = 0; - ftp->binary = TRUE; - if (getenv("FTP_PASSIVE_MODE")) - ftp->passive = 1; return ftp; } @@ -360,6 +396,13 @@ ftp_close_method(void *n) return i; } +static void +check_passive(FILE *fp) +{ + if (getenv("FTP_PASSIVE_MODE")) + ftpPassive(fp, TRUE); +} + static void ftp_timeout() { @@ -575,18 +618,10 @@ ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode, int * if (ftp->con_state != isopen) return botch("ftp_file_op", "open"); - if (ftp->binary) { - i = cmd(ftp, "TYPE I"); - if (check_code(ftp, i, FTP_BINARY_HAPPY)) { - ftp_close(ftp); - return i; - } - } - if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) return FAILURE; - if (ftp->passive) { + if (ftp->is_passive) { if (writes(ftp->fd_ctrl, "PASV\r\n")) { ftp_close(ftp); return FAILURE; diff --git a/lib/libftpio/ftpio.h b/lib/libftpio/ftpio.h index 40e2429b4880..9ba2f1fc66d4 100644 --- a/lib/libftpio/ftpio.h +++ b/lib/libftpio/ftpio.h @@ -20,19 +20,19 @@ * Turned inside out. Now returns xfers as new file ids, not as a special * `state' of FTP_t * - * $Id: ftpio.h,v 1.1.1.1 1996/06/17 12:26:06 jkh Exp $ + * $Id: ftpio.h,v 1.2 1996/06/17 15:28:08 jkh Exp $ */ /* Internal housekeeping data structure for FTP sessions */ typedef struct { enum { init, isopen } con_state; int fd_ctrl; - int binary; - int passive; int addrtype; char *host; char *file; int errno; + int is_binary; + int is_passive; } *FTP_t; /* Exported routines - deal only with FILE* type */ @@ -42,7 +42,8 @@ extern int ftpErrno(FILE *fp); extern size_t ftpGetSize(FILE *fp, char *file); extern FILE *ftpGet(FILE *fp, char *file, int *seekto); extern FILE *ftpPut(FILE *fp, char *file); -extern int ftpBinary(FILE *fp, int status); +extern int ftpAscii(FILE *fp); +extern int ftpBinary(FILE *fp); extern int ftpPassive(FILE *fp, int status); extern FILE *ftpGetURL(char *url, char *user, char *passwd); extern FILE *ftpPutURL(char *url, char *user, char *passwd);