Rethink and reimpliment the way RESTARTS are handled. The method I inheirited

from jmz was a hopeless kludge (sorry Jean-Marc :) and handled the problem
in the wrong way.  ftpRestart() has now gone away and ftpGet() has grown a
new parameter.
This commit is contained in:
Jordan K. Hubbard 1996-06-17 15:28:08 +00:00
parent 5d1999ec59
commit 92f6d79189
3 changed files with 33 additions and 53 deletions

View file

@ -36,7 +36,6 @@
.Nm ftpPut ,
.Nm ftpBinary ,
.Nm ftpPassive ,
.Nm ftpRestart ,
.Nm ftpGetURL ,
.Nm ftpPutURL ,
.Nd FTPIO User library
@ -53,15 +52,13 @@
.Ft size_t
.Fn ftpGetSize "FILE *fp, char *file"
.Ft FILE *
.Fn ftpGet "FILE *fp, char *file"
.Fn ftpGet "FILE *fp, char *file, int *seekto"
.Ft FILE *
.Fn ftpPut "FILE *fp, char *file"
.Ft int
.Fn ftpBinary "FILE *fp, int status"
.Ft int
.Fn ftpPassive "FILE *fp, int status"
.Ft int
.Fn ftpRestart "FILE *fp, int where"
.Ft FILE *
.Fn ftpGetURL "char *url, char *user, char *passwd"
.Ft FILE *
@ -79,10 +76,8 @@ and
fields (if passed as 0,
.Fa ftp_port
defaults to the standard ftp port of 21). If it is successful, a
standard
.Fa stream
descriptor is returned which should be passed to subsequent FTP
operations. On failure, NULL is returned and
standard stream descriptor is returned which should be passed to
subsequent FTP operations. On failure, NULL is returned and
.Fn ftpErrno
will return the error code returned by the foreign server.
.Pp
@ -101,9 +96,17 @@ attempts to retreive the file named by the
argument (which is assumed to be relative to the FTP server's current directory,
see
.Fn ftpChdir )
and returns a new
.Fa stream
pointer for the file or NULL on failure.
and returns a new stream pointer for the file or NULL on failure. If
.Fa seekto
is non-NULL, the contents of the integer it points to will be used
as a restart point for the file, that is to say that the stream
returned will point
.Fa *seekto
bytes into the file gotten (this is handy for restarting failed
transfers efficiently). If the seek operation succeeds, the value
of
.Fa *seekto
will be zero'd.
.Pp
.Fn ftpGetModtime
returns the last modification time of the file named by the
@ -137,15 +140,6 @@ sets passive mode (for firewalls) for the current server connection named by
to boolean value
.Fa status .
.Pp
.Fn ftpRestart
requests that if the remote server supports restart operations, the offset
in bytes specified in
.Fa where
should be used in the next file get operation to resume transferring from
that location. This is handy for restarting long get operations which have
aborted in the middle without re-transferring wasted bytes. Returns the
old seek value, if any.
.Pp
.Fn ftpGetURL
attempts to retreive the file named by the supplied
.Fa URL
@ -168,11 +162,10 @@ and can be considered equivalent to the combined
.Fn ftpChdir
and
.Fn ftpPut
operations except that no server
.Fa stream
is ever returned - the connection to the server closes when
the file has been completely written. Use the lower-level routines
if multiple puts are required as it will be far more efficient.
operations except that no server stream is ever returned - the connection
to the server closes when the file has been completely written. Use the
lower-level routines if multiple puts are required as it will be far more
efficient.
.Sh BUGS
I'm sure you can get this thing's internal state machine confused if
you really work at it, but so far it's proven itself pretty robust in

View file

@ -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.1.1.1 1996/06/17 12:26:06 jkh Exp $
* $Id: ftpio.c,v 1.2 1996/06/17 12:42:33 jkh Exp $
*
*/
@ -57,7 +57,7 @@ static int get_a_number(FTP_t ftp, char **q);
static int botch(char *func, char *botch_state);
static int cmd(FTP_t ftp, const char *fmt, ...);
static int ftp_login_session(FTP_t ftp, char *host, char *user, char *passwd, int port);
static int ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode);
static int ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode, int *seekto);
static int ftp_close(FTP_t ftp);
static int get_url_info(char *url_in, char *host_ret, int *port_ret, char *name_ret);
@ -149,16 +149,6 @@ ftpErrno(FILE *fp)
return ftp->errno;
}
int
ftpRestart(FILE *fp, int where)
{
FTP_t ftp = fcookie(fp);
int old = ftp->seek;
ftp->seek = where;
return old;
}
size_t
ftpGetSize(FILE *fp, char *name)
{
@ -207,12 +197,12 @@ ftpGetModtime(FILE *fp, char *name)
}
FILE *
ftpGet(FILE *fp, char *file)
ftpGet(FILE *fp, char *file, int *seekto)
{
FILE *fp2;
FTP_t ftp = fcookie(fp);
if (ftp_file_op(ftp, "RETR", file, &fp2, "r") == SUCCESS)
if (ftp_file_op(ftp, "RETR", file, &fp2, "r", seekto) == SUCCESS)
return fp2;
return NULL;
}
@ -223,7 +213,7 @@ ftpPut(FILE *fp, char *file)
FILE *fp2;
FTP_t ftp = fcookie(fp);
if (ftp_file_op(ftp, "STOR", file, &fp2, "w") == SUCCESS)
if (ftp_file_op(ftp, "STOR", file, &fp2, "w", NULL) == SUCCESS)
return fp2;
return NULL;
}
@ -256,7 +246,7 @@ ftpGetURL(char *url, char *user, char *passwd)
if (get_url_info(url, host, &port, name) == SUCCESS) {
fp = ftpLogin(host, user, passwd, port);
if (fp) {
fp2 = ftpGet(fp, name);
fp2 = ftpGet(fp, name, NULL);
fclose(fp);
return fp2;
}
@ -327,7 +317,6 @@ ftp_new(void)
ftp->fd_ctrl = -1;
ftp->con_state = init;
ftp->errno = 0;
ftp->seek = 0;
if (getenv("FTP_PASSIVE_MODE"))
ftp->passive = 1;
return ftp;
@ -557,7 +546,7 @@ ftp_login_session(FTP_t ftp, char *host, char *user, char *passwd, int port)
}
static int
ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode)
ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode, int *seekto)
{
int i,s;
char *q;
@ -610,15 +599,15 @@ ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode)
(void)close(s);
return FAILURE;
}
if (!strcmp(operation, "RETR") && ftp->seek) {
i = cmd(ftp, "RETR %d", ftp->seek);
if (seekto && *seekto) {
i = cmd(ftp, "RETR %d", *seekto);
if (i < 0 || FTP_TIMEOUT(i)) {
close(s);
ftp->errno = i;
return i;
}
else if (i != 350)
ftp->seek = 0;
*seekto = 0;
}
i = cmd(ftp, "%s %s", operation, file);
if (i < 0 || i > 299) {
@ -656,15 +645,15 @@ ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode)
close(s);
return i;
}
if (!strcmp(operation, "RETR") && ftp->seek) {
i = cmd(ftp, "RETR %d", ftp->seek);
if (seekto && *seekto) {
i = cmd(ftp, "RETR %d", *seekto);
if (i < 0 || FTP_TIMEOUT(i)) {
close(s);
ftp->errno = i;
return i;
}
else if (i != 350)
ftp->seek = 0;
*seekto = 0;
}
i = cmd(ftp, "%s %s", operation, file);
if (i < 0 || i > 299) {

View file

@ -20,7 +20,7 @@
* Turned inside out. Now returns xfers as new file ids, not as a special
* `state' of FTP_t
*
* $Id$
* $Id: ftpio.h,v 1.1.1.1 1996/06/17 12:26:06 jkh Exp $
*/
/* Internal housekeeping data structure for FTP sessions */
@ -33,7 +33,6 @@ typedef struct {
char *host;
char *file;
int errno;
int seek;
} *FTP_t;
/* Exported routines - deal only with FILE* type */
@ -41,11 +40,10 @@ extern FILE *ftpLogin(char *host, char *user, char *passwd, int port);
extern int ftpChdir(FILE *fp, char *dir);
extern int ftpErrno(FILE *fp);
extern size_t ftpGetSize(FILE *fp, char *file);
extern FILE *ftpGet(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 ftpPassive(FILE *fp, int status);
extern int ftpRestart(FILE *fp, int where);
extern FILE *ftpGetURL(char *url, char *user, char *passwd);
extern FILE *ftpPutURL(char *url, char *user, char *passwd);
extern time_t ftpModtime(FILE *fp, char *s);