mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 07:38:49 -05:00
moved here from the newlib branch
This commit is contained in:
parent
fb9d1ff00f
commit
96dde76b99
33
CHANGES
33
CHANGES
@ -8,6 +8,39 @@
|
||||
|
||||
Version XX
|
||||
|
||||
Daniel (21 May 2000)
|
||||
- Updated lots of #defines, enums and variable type names in the library. No
|
||||
more weird URG or URLTAG prefixes. All types and names should be curl-
|
||||
prefixed to avoid name space clashes. The FLAGS-parameter to the former
|
||||
curl_urlget() has been converted into a bunch of flags to use in separate
|
||||
setopt calls. I'm still focusing on the easy-interface, as the curl tool is
|
||||
now using that.
|
||||
|
||||
- Bjorn Reese has provided me with an asynchronous name resolver that I plan
|
||||
to use in upcoming versions of curl to be able to gracefully timeout name
|
||||
lookups.
|
||||
|
||||
Version 7.0beta released
|
||||
|
||||
Daniel (18 May 2000)
|
||||
- Introduced LIBCURL_VERSION_NUM to the curl.h include file to better allow
|
||||
source codes to be dependent on the lib version. This define is now set to
|
||||
a dexadecimal number, with 8 bits each for major number, minor number and
|
||||
patch number. In other words, version 1.2.3 would make it 0x010203. It also
|
||||
makes a larger number a newer version.
|
||||
|
||||
Daniel (17 May 2000)
|
||||
- Martin Kammerhofer correctly pointed out several flaws in the FTP range
|
||||
option. I corrected them.
|
||||
- Removed the win32 winsock init crap from the lib to the src/main.c file
|
||||
in the application instead. They can't be in the lib, especially not for
|
||||
multithreaded purposes.
|
||||
|
||||
Daniel (16 May 2000)
|
||||
- Rewrote the src/main.c source to use the new easy-interface to libcurl 7.
|
||||
There is still more work to do, but the first step is now taken.
|
||||
<curl/easy.h> is the include file to use.
|
||||
|
||||
Daniel (14 May 2000)
|
||||
- FTP URLs are now treated slightly different, more according to RFC 1738.
|
||||
- FTP sessions are now performed differently, with CWD commands to change
|
||||
|
11
FAQ
11
FAQ
@ -83,14 +83,3 @@ configre doesn't find OpenSSL even when it is installed
|
||||
things work
|
||||
|
||||
Submitted by: Bob Allison <allisonb@users.sourceforge.net>
|
||||
|
||||
Will you write a script for me getting ZZZ from YYY?
|
||||
====================================================
|
||||
|
||||
No.
|
||||
|
||||
I try to help out to solve issues with curl and related stuff, but I really
|
||||
do have a lot of stuff on my daily schedule and I'd prefer if you did not
|
||||
ask me to do your jobs. Writing scripts is very easy. Using curl might be
|
||||
tricky, but once you're past the initial mistakes the road to success is
|
||||
very short and straight-forward.
|
||||
|
@ -71,6 +71,9 @@
|
||||
/* Define if you have the strcasecmp function. */
|
||||
/*#define HAVE_STRCASECMP 1*/
|
||||
|
||||
/* Define if you have the stricmp function. */
|
||||
#define HAVE_STRICMP 1
|
||||
|
||||
/* Define if you have the strdup function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
|
@ -82,12 +82,18 @@
|
||||
/* Define if you have the strcasecmp function. */
|
||||
#undef HAVE_STRCASECMP
|
||||
|
||||
/* Define if you have the strcmpi function. */
|
||||
#undef HAVE_STRCMPI
|
||||
|
||||
/* Define if you have the strdup function. */
|
||||
#undef HAVE_STRDUP
|
||||
|
||||
/* Define if you have the strftime function. */
|
||||
#undef HAVE_STRFTIME
|
||||
|
||||
/* Define if you have the stricmp function. */
|
||||
#undef HAVE_STRICMP
|
||||
|
||||
/* Define if you have the strstr function. */
|
||||
#undef HAVE_STRSTR
|
||||
|
||||
|
34
configure.in
34
configure.in
@ -2,13 +2,7 @@ dnl $Id$
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(lib/urldata.h)
|
||||
AM_CONFIG_HEADER(config.h src/config.h)
|
||||
AM_INIT_AUTOMAKE(curl,"3-test")
|
||||
|
||||
dnl
|
||||
dnl Detect the canonical host and target build environment
|
||||
dnl
|
||||
AC_CANONICAL_HOST
|
||||
AC_CANONICAL_TARGET
|
||||
AM_INIT_AUTOMAKE(curl,"7.0beta")
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
@ -26,27 +20,6 @@ dnl **********************************************************************
|
||||
dnl nsl lib?
|
||||
AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname))
|
||||
|
||||
dnl At least one system has been identified to require BOTH nsl and
|
||||
dnl socket libs to link properly.
|
||||
if test "$ac_cv_lib_nsl_gethostbyname" = "$ac_cv_func_gethostbyname"; then
|
||||
AC_MSG_CHECKING([trying both nsl and socket libs])
|
||||
my_ac_save_LIBS=$LIBS
|
||||
LIBS="-lnsl -lsocket $LIBS"
|
||||
AC_TRY_LINK( ,
|
||||
[gethostbyname();],
|
||||
my_ac_link_result=success,
|
||||
my_ac_link_result=failure )
|
||||
|
||||
if test "$my_ac_link_result" = "failure"; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([couldn't find libraries for gethostbyname()])
|
||||
dnl restore LIBS
|
||||
LIBS=$my_ac_save_LIBS
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl resolve lib?
|
||||
AC_CHECK_FUNC(strcasecmp, , AC_CHECK_LIB(resolve, strcasecmp))
|
||||
|
||||
@ -219,14 +192,13 @@ AC_CHECK_FUNCS( socket \
|
||||
RAND_screen
|
||||
)
|
||||
|
||||
|
||||
|
||||
AC_PATH_PROG( PERL, perl, ,
|
||||
$PATH:/usr/local/bin/perl:/usr/bin/:/usr/local/bin )
|
||||
AC_SUBST(PERL)
|
||||
|
||||
AC_PATH_PROGS( NROFF, gnroff nroff, ,
|
||||
$PATH:/usr/bin/:/usr/local/bin )
|
||||
AC_SUBST(NROFF)
|
||||
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_YACC
|
||||
@ -236,8 +208,6 @@ dnl $PATH:/usr/bin/:/usr/local/bin )
|
||||
dnl AC_SUBST(RANLIB)
|
||||
|
||||
AC_OUTPUT( Makefile \
|
||||
curl.spec \
|
||||
curl-ssl.spec \
|
||||
src/Makefile \
|
||||
lib/Makefile )
|
||||
dnl perl/checklinks.pl \
|
||||
|
2
curl.1
2
curl.1
@ -204,7 +204,7 @@ A quick and very simple example of how to setup a
|
||||
to allow curl to ftp to the machine host.domain.com with user name
|
||||
'myself' and password 'secret' should look similar to:
|
||||
|
||||
.B "machine host.domain.com user myself password secret"
|
||||
.B "machine host.domain.com login myself password secret"
|
||||
.IP "-N/--no-buffer"
|
||||
Disables the buffering of the output stream. In normal work situations, curl
|
||||
will use a standard buffered output stream that will have the effect that it
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef __CURL_H
|
||||
#define __CURL_H
|
||||
#ifndef __CURL_CURL_H
|
||||
#define __CURL_CURL_H
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@ -39,6 +39,25 @@
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
****************************************************************************/
|
||||
|
||||
/* The include stuff here is mainly for time_t! */
|
||||
#ifdef vms
|
||||
# include <types.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
# if TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
# else
|
||||
# if HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif /* defined (vms) */
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
@ -46,71 +65,8 @@
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#include <curl/types.h>
|
||||
|
||||
#define CONF_DEFAULT 0
|
||||
#define CONF_PROXY (1<<0) /* set if proxy is in use */
|
||||
#define CONF_PORT (1<<1) /* set if different port than protcol-defines is
|
||||
used */
|
||||
#define CONF_HTTP (1<<2) /* http get */
|
||||
#define CONF_GOPHER (1<<3) /* gopher get */
|
||||
#define CONF_FTP (1<<4) /* ftp get (binary mode) */
|
||||
#define CONF_VERBOSE (1<<5) /* talk a lot */
|
||||
|
||||
#define CONF_TELNET (1<<6)
|
||||
|
||||
#define CONF_HEADER (1<<8) /* throw the header out too */
|
||||
#define CONF_USERPWD (1<<9) /* user+passwd has been specified */
|
||||
#define CONF_NOPROGRESS (1<<10) /* shut off the progress meter (auto)
|
||||
see also _MUTE */
|
||||
#define CONF_NOBODY (1<<11) /* use HEAD to get http document */
|
||||
#define CONF_FAILONERROR (1<<12) /* Makes urlget() fail with a return code
|
||||
WITHOUT writing anything to the output if
|
||||
a return code >=300 is returned from the
|
||||
server. */
|
||||
#define CONF_RANGE (1<<13) /* Byte-range request, specified parameter is set */
|
||||
#define CONF_UPLOAD (1<<14) /* this is an upload, only supported for ftp
|
||||
currently */
|
||||
|
||||
#define CONF_POST (1<<15) /* HTTP POST method */
|
||||
|
||||
/* When getting an FTP directory, this switch makes the listing only show file
|
||||
names and nothing else. Makes machine parsing of the output possible. This
|
||||
enforces the NLST command to the ftp server, compared to the otherwise
|
||||
used: LIST. */
|
||||
#define CONF_FTPLISTONLY (1<<16)
|
||||
|
||||
/* Set the referer string */
|
||||
#define CONF_REFERER (1<<17)
|
||||
#define CONF_PROXYUSERPWD (1<<18) /* Proxy user+passwd has been specified */
|
||||
|
||||
/* For FTP, use PORT instead of PASV! */
|
||||
#define CONF_FTPPORT (1<<19)
|
||||
|
||||
/* FTP: Append instead of overwrite on upload! */
|
||||
#define CONF_FTPAPPEND (1<<20)
|
||||
|
||||
#define CONF_HTTPS (1<<21) /* Use SSLeay for encrypted communication */
|
||||
|
||||
#define CONF_NETRC (1<<22) /* read user+password from .netrc */
|
||||
|
||||
#define CONF_FOLLOWLOCATION (1<<23) /* get the page that the Location: tells
|
||||
us to get */
|
||||
|
||||
#define CONF_FTPASCII (1<<24) /* use TYPE A for transfer */
|
||||
|
||||
#define CONF_HTTPPOST (1<<25) /* this causes a multipart/form-data
|
||||
HTTP POST */
|
||||
#define CONF_NOPROT (1<<26) /* host name specified without protocol */
|
||||
|
||||
#define CONF_PUT (1<<27) /* PUT the input file */
|
||||
|
||||
#define CONF_MUTE (1<<28) /* force NOPROGRESS */
|
||||
|
||||
#define CONF_DICT (1<<29) /* DICT:// protocol */
|
||||
|
||||
#define CONF_FILE (1<<30) /* FILE:// protocol */
|
||||
|
||||
#define CONF_LDAP (1<<31) /* LDAP:// protocol */
|
||||
|
||||
struct HttpHeader {
|
||||
struct HttpHeader *next; /* next entry in the list */
|
||||
@ -132,68 +88,69 @@ struct HttpPost {
|
||||
may return other values, stay prepared. */
|
||||
|
||||
typedef enum {
|
||||
URG_OK = 0,
|
||||
URG_UNSUPPORTED_PROTOCOL,
|
||||
URG_FAILED_INIT,
|
||||
URG_URL_MALFORMAT,
|
||||
URG_URL_MALFORMAT_USER,
|
||||
URG_COULDNT_RESOLVE_PROXY,
|
||||
URG_COULDNT_RESOLVE_HOST,
|
||||
URG_COULDNT_CONNECT,
|
||||
URG_FTP_WEIRD_SERVER_REPLY,
|
||||
URG_FTP_ACCESS_DENIED,
|
||||
URG_FTP_USER_PASSWORD_INCORRECT,
|
||||
URG_FTP_WEIRD_PASS_REPLY,
|
||||
URG_FTP_WEIRD_USER_REPLY,
|
||||
URG_FTP_WEIRD_PASV_REPLY,
|
||||
URG_FTP_WEIRD_227_FORMAT,
|
||||
URG_FTP_CANT_GET_HOST,
|
||||
URG_FTP_CANT_RECONNECT,
|
||||
URG_FTP_COULDNT_SET_BINARY,
|
||||
URG_PARTIAL_FILE,
|
||||
URG_FTP_COULDNT_RETR_FILE,
|
||||
URG_FTP_WRITE_ERROR,
|
||||
URG_FTP_QUOTE_ERROR,
|
||||
URG_HTTP_NOT_FOUND,
|
||||
URG_WRITE_ERROR,
|
||||
CURLE_OK = 0,
|
||||
CURLE_UNSUPPORTED_PROTOCOL,
|
||||
CURLE_FAILED_INIT,
|
||||
CURLE_URL_MALFORMAT,
|
||||
CURLE_URL_MALFORMAT_USER,
|
||||
CURLE_COULDNT_RESOLVE_PROXY,
|
||||
CURLE_COULDNT_RESOLVE_HOST,
|
||||
CURLE_COULDNT_CONNECT,
|
||||
CURLE_FTP_WEIRD_SERVER_REPLY,
|
||||
CURLE_FTP_ACCESS_DENIED,
|
||||
CURLE_FTP_USER_PASSWORD_INCORRECT,
|
||||
CURLE_FTP_WEIRD_PASS_REPLY,
|
||||
CURLE_FTP_WEIRD_USER_REPLY,
|
||||
CURLE_FTP_WEIRD_PASV_REPLY,
|
||||
CURLE_FTP_WEIRD_227_FORMAT,
|
||||
CURLE_FTP_CANT_GET_HOST,
|
||||
CURLE_FTP_CANT_RECONNECT,
|
||||
CURLE_FTP_COULDNT_SET_BINARY,
|
||||
CURLE_PARTIAL_FILE,
|
||||
CURLE_FTP_COULDNT_RETR_FILE,
|
||||
CURLE_FTP_WRITE_ERROR,
|
||||
CURLE_FTP_QUOTE_ERROR,
|
||||
CURLE_HTTP_NOT_FOUND,
|
||||
CURLE_WRITE_ERROR,
|
||||
|
||||
URG_MALFORMAT_USER, /* the user name is illegally specified */
|
||||
URG_FTP_COULDNT_STOR_FILE, /* failed FTP upload */
|
||||
URG_READ_ERROR, /* could open/read from file */
|
||||
CURLE_MALFORMAT_USER, /* the user name is illegally specified */
|
||||
CURLE_FTP_COULDNT_STOR_FILE, /* failed FTP upload */
|
||||
CURLE_READ_ERROR, /* could open/read from file */
|
||||
|
||||
URG_OUT_OF_MEMORY,
|
||||
URG_OPERATION_TIMEOUTED, /* the timeout time was reached */
|
||||
URG_FTP_COULDNT_SET_ASCII, /* TYPE A failed */
|
||||
CURLE_OUT_OF_MEMORY,
|
||||
CURLE_OPERATION_TIMEOUTED, /* the timeout time was reached */
|
||||
CURLE_FTP_COULDNT_SET_ASCII, /* TYPE A failed */
|
||||
|
||||
URG_FTP_PORT_FAILED, /* FTP PORT operation failed */
|
||||
CURLE_FTP_PORT_FAILED, /* FTP PORT operation failed */
|
||||
|
||||
URG_FTP_COULDNT_USE_REST, /* the REST command failed */
|
||||
URG_FTP_COULDNT_GET_SIZE, /* the SIZE command failed */
|
||||
CURLE_FTP_COULDNT_USE_REST, /* the REST command failed */
|
||||
CURLE_FTP_COULDNT_GET_SIZE, /* the SIZE command failed */
|
||||
|
||||
URG_HTTP_RANGE_ERROR, /* The RANGE "command" didn't seem to work */
|
||||
CURLE_HTTP_RANGE_ERROR, /* The RANGE "command" didn't seem to work */
|
||||
|
||||
URG_HTTP_POST_ERROR,
|
||||
CURLE_HTTP_POST_ERROR,
|
||||
|
||||
URG_SSL_CONNECT_ERROR, /* something was wrong when connecting with SSL */
|
||||
CURLE_SSL_CONNECT_ERROR, /* something was wrong when connecting with SSL */
|
||||
|
||||
URG_FTP_BAD_DOWNLOAD_RESUME, /* couldn't resume download */
|
||||
CURLE_FTP_BAD_DOWNLOAD_RESUME, /* couldn't resume download */
|
||||
|
||||
URG_FILE_COULDNT_READ_FILE,
|
||||
CURLE_FILE_COULDNT_READ_FILE,
|
||||
|
||||
URG_LDAP_CANNOT_BIND,
|
||||
URG_LDAP_SEARCH_FAILED,
|
||||
URG_LIBRARY_NOT_FOUND,
|
||||
URG_FUNCTION_NOT_FOUND,
|
||||
CURLE_LDAP_CANNOT_BIND,
|
||||
CURLE_LDAP_SEARCH_FAILED,
|
||||
CURLE_LIBRARY_NOT_FOUND,
|
||||
CURLE_FUNCTION_NOT_FOUND,
|
||||
|
||||
URL_LAST
|
||||
} UrgError;
|
||||
CURLE_ABORTED_BY_CALLBACK,
|
||||
|
||||
CURLE_BAD_FUNCTION_ARGUMENT,
|
||||
CURLE_BAD_CALLING_ORDER,
|
||||
|
||||
CURL_LAST
|
||||
} CURLcode;
|
||||
|
||||
/* This is just to make older programs not break: */
|
||||
#define URG_FTP_PARTIAL_FILE URG_PARTIAL_FILE
|
||||
|
||||
#define URGTAG_DONE -1
|
||||
#define URGTAG_LAST -1
|
||||
#define URGTAG_END -1
|
||||
#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
|
||||
|
||||
#define URLGET_ERROR_SIZE 256
|
||||
|
||||
@ -201,19 +158,19 @@ typedef enum {
|
||||
#define URL_MAX_LENGTH 4096
|
||||
#define URL_MAX_LENGTH_TXT "4095"
|
||||
|
||||
/* name is uppercase URGTAG_<name>,
|
||||
type is one of the defined URGTYPE_<type>
|
||||
/* name is uppercase CURLOPT_<name>,
|
||||
type is one of the defined CURLOPTTYPE_<type>
|
||||
number is unique identifier */
|
||||
#define T(name,type,number) URGTAG_ ## name = URGTYPE_ ## type + number
|
||||
#define T(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number
|
||||
|
||||
/* long may be 32 or 64 bits, but we should never depend on anything else
|
||||
but 32 */
|
||||
#define URGTYPE_LONG 0
|
||||
#define URGTYPE_OBJECTPOINT 10000
|
||||
#define URGTYPE_FUNCTIONPOINT 20000
|
||||
#define CURLOPTTYPE_LONG 0
|
||||
#define CURLOPTTYPE_OBJECTPOINT 10000
|
||||
#define CURLOPTTYPE_FUNCTIONPOINT 20000
|
||||
|
||||
typedef enum {
|
||||
URGTAG_NOTHING, /* the first unused */
|
||||
T(NOTHING, LONG, 0), /********* the first one is unused ************/
|
||||
|
||||
/* This is the FILE * the regular output should be written to. */
|
||||
T(FILE, OBJECTPOINT, 1),
|
||||
@ -222,28 +179,29 @@ typedef enum {
|
||||
T(URL, OBJECTPOINT, 2),
|
||||
|
||||
/* Port number to connect to, if other than default. Specify the CONF_PORT
|
||||
flag in the URGTAG_FLAGS to activate this */
|
||||
flag in the CURLOPT_FLAGS to activate this */
|
||||
T(PORT, LONG, 3),
|
||||
|
||||
/* Name of proxy to use. Specify the CONF_PROXY flag in the URGTAG_FLAGS to
|
||||
/* Name of proxy to use. Specify the CONF_PROXY flag in the CURLOPT_FLAGS to
|
||||
activate this */
|
||||
T(PROXY, OBJECTPOINT, 4),
|
||||
|
||||
/* Name and password to use when fetching. Specify the CONF_USERPWD flag in
|
||||
the URGTAG_FLAGS to activate this */
|
||||
the CURLOPT_FLAGS to activate this */
|
||||
T(USERPWD, OBJECTPOINT, 5),
|
||||
|
||||
/* Name and password to use with Proxy. Specify the CONF_PROXYUSERPWD
|
||||
flag in the URGTAG_FLAGS to activate this */
|
||||
flag in the CURLOPT_FLAGS to activate this */
|
||||
T(PROXYUSERPWD, OBJECTPOINT, 6),
|
||||
|
||||
/* Range to get, specified as an ASCII string. Specify the CONF_RANGE flag
|
||||
in the URGTAG_FLAGS to activate this */
|
||||
in the CURLOPT_FLAGS to activate this */
|
||||
T(RANGE, OBJECTPOINT, 7),
|
||||
|
||||
#if 0
|
||||
/* Configuration flags */
|
||||
T(FLAGS, LONG, 8),
|
||||
|
||||
#endif
|
||||
/* Specified file stream to upload from (use as input): */
|
||||
T(INFILE, OBJECTPOINT, 9),
|
||||
|
||||
@ -262,7 +220,7 @@ typedef enum {
|
||||
/* Time-out the read operation after this amount of seconds */
|
||||
T(TIMEOUT, LONG, 13),
|
||||
|
||||
/* If the URGTAG_INFILE is used, this can be used to inform urlget about how
|
||||
/* If the CURLOPT_INFILE is used, this can be used to inform urlget about how
|
||||
large the file being sent really is. That allows better error checking
|
||||
and better verifies that the upload was succcessful. -1 means unknown
|
||||
size. */
|
||||
@ -364,8 +322,25 @@ typedef enum {
|
||||
as described elsewhere. */
|
||||
T(WRITEINFO, OBJECTPOINT, 40),
|
||||
|
||||
URGTAG_LASTENTRY /* the last unusued */
|
||||
} UrgTag;
|
||||
/* Previous FLAG bits */
|
||||
T(VERBOSE, LONG, 41), /* talk a lot */
|
||||
T(HEADER, LONG, 42), /* throw the header out too */
|
||||
T(NOPROGRESS, LONG, 43), /* shut off the progress meter */
|
||||
T(NOBODY, LONG, 44), /* use HEAD to get http document */
|
||||
T(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */
|
||||
T(UPLOAD, LONG, 46), /* this is an upload */
|
||||
T(POST, LONG, 47), /* HTTP POST method */
|
||||
T(FTPLISTONLY, LONG, 48), /* Use NLST when listing ftp dir */
|
||||
|
||||
T(FTPAPPEND, LONG, 50), /* Append instead of overwrite on upload! */
|
||||
T(NETRC, LONG, 51), /* read user+password from .netrc */
|
||||
T(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */
|
||||
T(FTPASCII, LONG, 53), /* use TYPE A for transfer */
|
||||
T(PUT, LONG, 54), /* PUT the input file */
|
||||
T(MUTE, LONG, 55), /* force NOPROGRESS */
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unusued */
|
||||
} CURLoption;
|
||||
|
||||
#define CURL_PROGRESS_STATS 0 /* default progress display */
|
||||
#define CURL_PROGRESS_BAR 1
|
||||
@ -388,23 +363,11 @@ typedef char bool;
|
||||
#endif /* (rabe) */
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* >>> urlget() interface #defines changed in v5! <<<
|
||||
*
|
||||
* You enter parameters as tags. Tags are specified as a pair of parameters.
|
||||
* The first parameter in a pair is the tag identifier, telling urlget what
|
||||
* kind of tag it is, and the second is the data. The tags may come in any
|
||||
* order but MUST ALWAYS BE TERMINATED with an ending URGTAG_DONE (which
|
||||
* needs no data).
|
||||
*
|
||||
* _Very_ simple example:
|
||||
*
|
||||
* curl_urlget(URGTAG_URL, "http://www.fts.frontec.se/~dast/", URGTAG_DONE);
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
#if 0
|
||||
/* At last, I stand here in front of you today and can officially proclaim
|
||||
this function prototype as history... 17th of May, 2000 */
|
||||
UrgError curl_urlget(UrgTag, ...);
|
||||
#endif
|
||||
|
||||
/* external form function */
|
||||
int curl_FormParse(char *string,
|
||||
@ -418,9 +381,10 @@ char *curl_GetEnv(char *variable);
|
||||
char *curl_version(void);
|
||||
|
||||
/* This is the version number */
|
||||
#define LIBCURL_VERSION "6.5.2"
|
||||
#define LIBCURL_VERSION "7.0beta"
|
||||
#define LIBCURL_VERSION_NUM 0x070000
|
||||
|
||||
/* linked-list structure for QUOTE */
|
||||
/* linked-list structure for the CURLOPT_QUOTE option */
|
||||
struct curl_slist {
|
||||
char *data;
|
||||
struct curl_slist *next;
|
||||
@ -429,4 +393,192 @@ struct curl_slist {
|
||||
struct curl_slist *curl_slist_append(struct curl_slist *list, char *data);
|
||||
void curl_slist_free_all(struct curl_slist *list);
|
||||
|
||||
#endif /* __URLGET_H */
|
||||
/*
|
||||
* NAME curl_init()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Inits libcurl globally. This must be used before any libcurl calls can
|
||||
* be used. This may install global plug-ins or whatever. (This does not
|
||||
* do winsock inits in Windows.)
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* curl_init();
|
||||
*
|
||||
*/
|
||||
CURLcode curl_init(void);
|
||||
|
||||
/*
|
||||
* NAME curl_init()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Frees libcurl globally. This must be used after all libcurl calls have
|
||||
* been used. This may remove global plug-ins or whatever. (This does not
|
||||
* do winsock cleanups in Windows.)
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* curl_free(curl);
|
||||
*
|
||||
*/
|
||||
void curl_free(void);
|
||||
|
||||
/*
|
||||
* NAME curl_open()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Opens a general curl session. It does not try to connect or do anything
|
||||
* on the network because of this call. The specified URL is only required
|
||||
* to enable curl to figure out what protocol to "activate".
|
||||
*
|
||||
* A session should be looked upon as a series of requests to a single host. A
|
||||
* session interacts with one host only, using one single protocol.
|
||||
*
|
||||
* The URL is not required. If set to "" or NULL, it can still be set later
|
||||
* using the curl_setopt() function. If the curl_connect() function is called
|
||||
* without the URL being known, it will return error.
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* CURLcode result;
|
||||
* CURL *curl;
|
||||
* result = curl_open(&curl, "http://curl.haxx.nu/libcurl/");
|
||||
* if(result != CURL_OK) {
|
||||
* return result;
|
||||
* }
|
||||
* */
|
||||
CURLcode curl_open(CURL **curl, char *url);
|
||||
|
||||
/*
|
||||
* NAME curl_setopt()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Sets a particular option to the specified value.
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* CURL curl;
|
||||
* curl_setopt(curl, CURL_HTTP_FOLLOW_LOCATION, TRUE);
|
||||
*/
|
||||
CURLcode curl_setopt(CURL *handle, CURLoption option, ...);
|
||||
|
||||
/*
|
||||
* NAME curl_close()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Closes a session previously opened with curl_open()
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* CURL *curl;
|
||||
* CURLcode result;
|
||||
*
|
||||
* result = curl_close(curl);
|
||||
*/
|
||||
CURLcode curl_close(CURL *curl); /* the opposite of curl_open() */
|
||||
|
||||
CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize,
|
||||
size_t *n);
|
||||
CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount,
|
||||
size_t *n);
|
||||
|
||||
/*
|
||||
* NAME curl_connect()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Connects to the peer server and performs the initial setup. This function
|
||||
* writes a connect handle to its second argument that is a unique handle for
|
||||
* this connect. This allows multiple connects from the same handle returned
|
||||
* by curl_open().
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* CURLCode result;
|
||||
* CURL curl;
|
||||
* CURLconnect connect;
|
||||
* result = curl_connect(curl, &connect);
|
||||
*/
|
||||
|
||||
CURLcode curl_connect(CURL *curl, CURLconnect **in_connect);
|
||||
|
||||
/*
|
||||
* NAME curl_do()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* (Note: May 3rd 2000: this function does not currently allow you to
|
||||
* specify a document, it will use the one set previously)
|
||||
*
|
||||
* This function asks for the particular document, file or resource that
|
||||
* resides on the server we have connected to. You may specify a full URL,
|
||||
* just an absolute path or even a relative path. That means, if you're just
|
||||
* getting one file from the remote site, you can use the same URL as input
|
||||
* for both curl_open() as well as for this function.
|
||||
*
|
||||
* In the even there is a host name, port number, user name or password parts
|
||||
* in the URL, you can use the 'flags' argument to ignore them completely, or
|
||||
* at your choice, make the function fail if you're trying to get a URL from
|
||||
* different host than you connected to with curl_connect().
|
||||
*
|
||||
* You can only get one document at a time using the same connection. When one
|
||||
* document has been received you can although request again.
|
||||
*
|
||||
* When the transfer is done, curl_done() MUST be called.
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* CURLCode result;
|
||||
* char *url;
|
||||
* CURLconnect *connect;
|
||||
* result = curl_do(connect, url, CURL_DO_NONE); */
|
||||
CURLcode curl_do(CURLconnect *in_conn);
|
||||
|
||||
/*
|
||||
* NAME curl_done()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* When the transfer following a curl_do() call is done, this function should
|
||||
* get called.
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* CURLCode result;
|
||||
* char *url;
|
||||
* CURLconnect *connect;
|
||||
* result = curl_done(connect); */
|
||||
CURLcode curl_done(CURLconnect *connect);
|
||||
|
||||
/*
|
||||
* NAME curl_disconnect()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Disconnects from the peer server and performs connection cleanup.
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* CURLcode result;
|
||||
* CURLconnect *connect;
|
||||
* result = curl_disconnect(connect); */
|
||||
CURLcode curl_disconnect(CURLconnect *connect);
|
||||
|
||||
/*
|
||||
* NAME curl_getdate()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Returns the time, in seconds since 1 Jan 1970 of the time string given in
|
||||
* the first argument. The time argument in the second parameter is for cases
|
||||
* where the specified time is relative now, like 'two weeks' or 'tomorrow'
|
||||
* etc.
|
||||
*/
|
||||
time_t curl_getdate(const char *p, const time_t *now);
|
||||
|
||||
#endif /* __CURL_CURL_H */
|
||||
|
46
include/curl/easy.h
Normal file
46
include/curl/easy.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef __CURL_EASY_H
|
||||
#define __CURL_EASY_H
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Curl.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Daniel Stenberg.
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
* Main author:
|
||||
* - Daniel Stenberg <Daniel.Stenberg@haxx.nu>
|
||||
*
|
||||
* http://curl.haxx.nu
|
||||
*
|
||||
* $Source$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
* $Author$
|
||||
* $State$
|
||||
* $Locker$
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
****************************************************************************/
|
||||
CURL *curl_easy_init(void);
|
||||
CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
|
||||
CURLcode curl_easy_perform(CURL *curl);
|
||||
void curl_easy_cleanup(CURL *curl);
|
||||
#endif
|
45
include/curl/types.h
Normal file
45
include/curl/types.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef __CURL_TYPES_H
|
||||
#define __CURL_TYPES_H
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Curl.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Daniel Stenberg.
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
* Main author:
|
||||
* - Daniel Stenberg <Daniel.Stenberg@haxx.nu>
|
||||
*
|
||||
* http://curl.haxx.nu
|
||||
*
|
||||
* $Source$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
* $Author$
|
||||
* $State$
|
||||
* $Locker$
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
****************************************************************************/
|
||||
typedef void CURL;
|
||||
typedef void CURLconnect;
|
||||
|
||||
#endif /* __CURL_TYPES_H */
|
@ -7,7 +7,7 @@ AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
noinst_LIBRARIES = libcurl.a
|
||||
|
||||
# Some flags needed when trying to cause warnings ;-)
|
||||
#CFLAGS = -g -Wall -pedantic
|
||||
CFLAGS = -g -Wall #-pedantic
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
|
||||
@ -23,7 +23,7 @@ download.c getdate.h ldap.c ssluse.c version.c \
|
||||
download.h getenv.c ldap.h ssluse.h \
|
||||
escape.c getenv.h mprintf.c telnet.c \
|
||||
escape.h getpass.c netrc.c telnet.h \
|
||||
writeout.c writeout.h
|
||||
writeout.c writeout.h highlevel.c strequal.c strequal.h easy.c
|
||||
|
||||
# Say $(srcdir), so GNU make does not report an ambiguity with the .y.c rule.
|
||||
$(srcdir)/getdate.c: getdate.y
|
||||
|
@ -77,11 +77,11 @@ AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
noinst_LIBRARIES = libcurl.a
|
||||
|
||||
# Some flags needed when trying to cause warnings ;-)
|
||||
#CFLAGS = -g -Wall -pedantic
|
||||
CFLAGS = -g -Wall #-pedantic
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
|
||||
libcurl_a_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c base64.c file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c http.h sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h dict.h getdate.c if2ip.h speedcheck.h urldata.h download.c getdate.h ldap.c ssluse.c version.c download.h getenv.c ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h getpass.c netrc.c telnet.h writeout.c writeout.h
|
||||
libcurl_a_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c base64.c file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c http.h sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h dict.h getdate.c if2ip.h speedcheck.h urldata.h download.c getdate.h ldap.c ssluse.c version.c download.h getenv.c ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h getpass.c netrc.c telnet.h writeout.c writeout.h highlevel.c strequal.c strequal.h easy.c
|
||||
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = ../config.h ../src/config.h
|
||||
@ -97,9 +97,9 @@ libcurl_a_LIBADD =
|
||||
libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
|
||||
formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \
|
||||
speedcheck.o getdate.o download.o ldap.o ssluse.o version.o getenv.o \
|
||||
escape.o mprintf.o telnet.o getpass.o netrc.o writeout.o
|
||||
escape.o mprintf.o telnet.o getpass.o netrc.o writeout.o highlevel.o \
|
||||
strequal.o easy.o
|
||||
AR = ar
|
||||
CFLAGS = @CFLAGS@
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
|
||||
|
@ -62,6 +62,7 @@ Example set of cookies:
|
||||
#include "cookie.h"
|
||||
#include "setup.h"
|
||||
#include "getdate.h"
|
||||
#include "strequal.h"
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
@ -131,7 +132,7 @@ struct Cookie *cookie_add(struct CookieInfo *c,
|
||||
}
|
||||
else if(strequal("expires", name)) {
|
||||
co->expirestr=strdup(what);
|
||||
co->expires = get_date(what, &now);
|
||||
co->expires = curl_getdate(what, &now);
|
||||
}
|
||||
else if(!co->name) {
|
||||
co->name = strdup(name);
|
||||
@ -173,9 +174,11 @@ struct Cookie *cookie_add(struct CookieInfo *c,
|
||||
return NULL;
|
||||
}
|
||||
/* strip off the possible end-of-line characters */
|
||||
if(ptr=strchr(lineptr, '\r'))
|
||||
ptr=strchr(lineptr, '\r');
|
||||
if(ptr)
|
||||
*ptr=0; /* clear it */
|
||||
if(ptr=strchr(lineptr, '\n'))
|
||||
ptr=strchr(lineptr, '\n');
|
||||
if(ptr)
|
||||
*ptr=0; /* clear it */
|
||||
|
||||
firstptr=strtok(lineptr, "\t"); /* first tokenize it on the TAB */
|
||||
|
28
lib/dict.c
28
lib/dict.c
@ -92,12 +92,17 @@
|
||||
#include "sendf.h"
|
||||
|
||||
#include "progress.h"
|
||||
#include "strequal.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
CURLcode dict_done(struct connectdata *conn)
|
||||
{
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
UrgError dict(struct UrlData *data, char *path, long *bytecount)
|
||||
CURLcode dict(struct connectdata *conn)
|
||||
{
|
||||
int nth;
|
||||
char *word;
|
||||
@ -106,9 +111,13 @@ UrgError dict(struct UrlData *data, char *path, long *bytecount)
|
||||
char *strategy = NULL;
|
||||
char *nthdef = NULL; /* This is not part of the protocol, but required
|
||||
by RFC 2229 */
|
||||
UrgError result=URG_OK;
|
||||
CURLcode result=CURLE_OK;
|
||||
struct UrlData *data=conn->data;
|
||||
|
||||
if(data->conf & CONF_USERPWD) {
|
||||
char *path = conn->path;
|
||||
long *bytecount = &conn->bytecount;
|
||||
|
||||
if(data->bits.user_passwd) {
|
||||
/* AUTH is missing */
|
||||
}
|
||||
|
||||
@ -162,7 +171,7 @@ UrgError dict(struct UrlData *data, char *path, long *bytecount)
|
||||
word
|
||||
);
|
||||
|
||||
result = Transfer(data, data->firstsocket, -1, FALSE, bytecount,
|
||||
result = Transfer(conn, data->firstsocket, -1, FALSE, bytecount,
|
||||
-1, NULL); /* no upload */
|
||||
|
||||
if(result)
|
||||
@ -210,7 +219,7 @@ UrgError dict(struct UrlData *data, char *path, long *bytecount)
|
||||
word
|
||||
);
|
||||
|
||||
result = Transfer(data, data->firstsocket, -1, FALSE, bytecount,
|
||||
result = Transfer(conn, data->firstsocket, -1, FALSE, bytecount,
|
||||
-1, NULL); /* no upload */
|
||||
|
||||
if(result)
|
||||
@ -234,7 +243,7 @@ UrgError dict(struct UrlData *data, char *path, long *bytecount)
|
||||
"QUIT\n",
|
||||
ppath);
|
||||
|
||||
result = Transfer(data, data->firstsocket, -1, FALSE, bytecount,
|
||||
result = Transfer(conn, data->firstsocket, -1, FALSE, bytecount,
|
||||
-1, NULL);
|
||||
|
||||
if(result)
|
||||
@ -243,10 +252,5 @@ UrgError dict(struct UrlData *data, char *path, long *bytecount)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
ProgressEnd(data);
|
||||
#endif
|
||||
pgrsDone(data);
|
||||
|
||||
return URG_OK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
****************************************************************************/
|
||||
UrgError dict(struct UrlData *data, char *path, long *bytecountp);
|
||||
CURLcode dict(struct connectdata *conn);
|
||||
CURLcode dict_done(struct connectdata *conn);
|
||||
|
||||
#endif
|
||||
|
507
lib/download.c
507
lib/download.c
@ -78,20 +78,16 @@
|
||||
#include "speedcheck.h"
|
||||
#include "sendf.h"
|
||||
|
||||
#ifdef USE_ZLIB
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#define MAX(x,y) ((x)>(y)?(x):(y))
|
||||
#include <curl/types.h>
|
||||
|
||||
/* --- download and upload a stream from/to a socket --- */
|
||||
|
||||
/* Parts of this function was brought to us by the friendly Mark Butler
|
||||
<butlerm@xmission.com>. */
|
||||
|
||||
UrgError
|
||||
Transfer (struct UrlData *data,
|
||||
/* READ stuff */
|
||||
CURLcode
|
||||
Transfer(CURLconnect *c_conn,
|
||||
/* READ stuff */
|
||||
int sockfd, /* socket to read from or -1 */
|
||||
int size, /* -1 if unknown at this point */
|
||||
bool getheader, /* TRUE if header parsing is wanted */
|
||||
@ -101,492 +97,21 @@ Transfer (struct UrlData *data,
|
||||
int writesockfd, /* socket to write to, it may very well be
|
||||
the same we read from. -1 disables */
|
||||
long *writebytecountp /* return number of bytes written or NULL */
|
||||
|
||||
|
||||
)
|
||||
)
|
||||
{
|
||||
char *buf = data->buffer;
|
||||
size_t nread;
|
||||
int bytecount = 0; /* number of bytes read */
|
||||
int writebytecount = 0; /* number of bytes written */
|
||||
long contentlength=0; /* size of incoming data */
|
||||
struct timeval start = tvnow();
|
||||
struct timeval now = start;
|
||||
bool header = TRUE; /* incoming data has HTTP header */
|
||||
int headerline = 0; /* counts header lines to better track the
|
||||
first one */
|
||||
struct connectdata *conn = (struct connectdata *)c_conn;
|
||||
if(!conn)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
char *hbufp; /* points at *end* of header line */
|
||||
int hbuflen = 0;
|
||||
char *str; /* within buf */
|
||||
char *str_start; /* within buf */
|
||||
char *end_ptr; /* within buf */
|
||||
char *p; /* within headerbuff */
|
||||
bool content_range = FALSE; /* set TRUE if Content-Range: was found */
|
||||
int offset = 0; /* possible resume offset read from the
|
||||
Content-Range: header */
|
||||
int code = 0; /* error code from the 'HTTP/1.? XXX' line */
|
||||
/* now copy all input parameters */
|
||||
conn->sockfd = sockfd;
|
||||
conn->size = size;
|
||||
conn->getheader = getheader;
|
||||
conn->bytecountp = bytecountp;
|
||||
conn->writesockfd = writesockfd;
|
||||
conn->writebytecountp = writebytecountp;
|
||||
|
||||
/* for the low speed checks: */
|
||||
UrgError urg;
|
||||
time_t timeofdoc=0;
|
||||
long bodywrites=0;
|
||||
return CURLE_OK;
|
||||
|
||||
char newurl[URL_MAX_LENGTH]; /* buffer for Location: URL */
|
||||
|
||||
/* the highest fd we use + 1 */
|
||||
int maxfd = (sockfd>writesockfd?sockfd:writesockfd)+1;
|
||||
|
||||
hbufp = data->headerbuff;
|
||||
|
||||
myalarm (0); /* switch off the alarm-style timeout */
|
||||
|
||||
now = tvnow();
|
||||
start = now;
|
||||
|
||||
#define KEEP_READ 1
|
||||
#define KEEP_WRITE 2
|
||||
|
||||
pgrsTime(data, TIMER_PRETRANSFER);
|
||||
|
||||
if (!getheader) {
|
||||
header = FALSE;
|
||||
if(size > 0)
|
||||
pgrsSetDownloadSize(data, size);
|
||||
}
|
||||
{
|
||||
fd_set readfd;
|
||||
fd_set writefd;
|
||||
fd_set rkeepfd;
|
||||
fd_set wkeepfd;
|
||||
struct timeval interval;
|
||||
int keepon=0;
|
||||
|
||||
/* timeout every X second
|
||||
- makes a better progressmeter (i.e even when no data is read, the
|
||||
meter can be updated and reflect reality)
|
||||
- allows removal of the alarm() crap
|
||||
- variable timeout is easier
|
||||
*/
|
||||
|
||||
FD_ZERO (&readfd); /* clear it */
|
||||
if(sockfd != -1) {
|
||||
FD_SET (sockfd, &readfd); /* read socket */
|
||||
keepon |= KEEP_READ;
|
||||
}
|
||||
|
||||
FD_ZERO (&writefd); /* clear it */
|
||||
if(writesockfd != -1) {
|
||||
FD_SET (writesockfd, &writefd); /* write socket */
|
||||
keepon |= KEEP_WRITE;
|
||||
}
|
||||
|
||||
/* get these in backup variables to be able to restore them on each lap in
|
||||
the select() loop */
|
||||
rkeepfd = readfd;
|
||||
wkeepfd = writefd;
|
||||
|
||||
while (keepon) {
|
||||
readfd = rkeepfd; /* set those every lap in the loop */
|
||||
writefd = wkeepfd;
|
||||
interval.tv_sec = 1;
|
||||
interval.tv_usec = 0;
|
||||
|
||||
switch (select (maxfd, &readfd, &writefd, NULL, &interval)) {
|
||||
case -1: /* select() error, stop reading */
|
||||
#ifdef EINTR
|
||||
/* The EINTR is not serious, and it seems you might get this more
|
||||
ofen when using the lib in a multi-threaded environment! */
|
||||
if(errno == EINTR)
|
||||
;
|
||||
else
|
||||
#endif
|
||||
keepon = 0; /* no more read or write */
|
||||
continue;
|
||||
case 0: /* timeout */
|
||||
break;
|
||||
default:
|
||||
if((keepon & KEEP_READ) && FD_ISSET(sockfd, &readfd)) {
|
||||
/* read! */
|
||||
#ifdef USE_SSLEAY
|
||||
if (data->use_ssl) {
|
||||
nread = SSL_read (data->ssl, buf, BUFSIZE - 1);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
nread = sread (sockfd, buf, BUFSIZE - 1);
|
||||
#ifdef USE_SSLEAY
|
||||
}
|
||||
#endif /* USE_SSLEAY */
|
||||
|
||||
/* NULL terminate, allowing string ops to be used */
|
||||
if (0 < (signed int) nread)
|
||||
buf[nread] = 0;
|
||||
|
||||
/* if we receive 0 or less here, the server closed the connection and
|
||||
we bail out from this! */
|
||||
else if (0 >= (signed int) nread) {
|
||||
keepon &= ~KEEP_READ;
|
||||
break;
|
||||
}
|
||||
|
||||
str = buf; /* Default buffer to use when we write the
|
||||
buffer, it may be changed in the flow below
|
||||
before the actual storing is done. */
|
||||
|
||||
/* Since this is a two-state thing, we check if we are parsing
|
||||
headers at the moment or not. */
|
||||
|
||||
if (header) {
|
||||
/* we are in parse-the-header-mode */
|
||||
|
||||
/* header line within buffer loop */
|
||||
do {
|
||||
int hbufp_index;
|
||||
|
||||
str_start = str; /* str_start is start of line within buf */
|
||||
|
||||
end_ptr = strchr (str_start, '\n');
|
||||
|
||||
if (!end_ptr) {
|
||||
/* no more complete header lines within buffer */
|
||||
/* copy what is remaining into headerbuff */
|
||||
int str_length = (int)strlen(str);
|
||||
|
||||
if (hbuflen + (int)str_length >= data->headersize) {
|
||||
char *newbuff;
|
||||
long newsize=MAX((hbuflen+str_length)*3/2,
|
||||
data->headersize*2);
|
||||
hbufp_index = hbufp - data->headerbuff;
|
||||
newbuff = (char *)realloc(data->headerbuff, newsize);
|
||||
if(!newbuff) {
|
||||
failf (data, "Failed to alloc memory for big header!");
|
||||
return URG_READ_ERROR;
|
||||
}
|
||||
data->headersize=newsize;
|
||||
data->headerbuff = newbuff;
|
||||
hbufp = data->headerbuff + hbufp_index;
|
||||
}
|
||||
strcpy (hbufp, str);
|
||||
hbufp += strlen (str);
|
||||
hbuflen += strlen (str);
|
||||
break; /* read more and try again */
|
||||
}
|
||||
|
||||
str = end_ptr + 1; /* move just past new line */
|
||||
|
||||
if (hbuflen + (str - str_start) >= data->headersize) {
|
||||
char *newbuff;
|
||||
long newsize=MAX((hbuflen+(str-str_start))*3/2,
|
||||
data->headersize*2);
|
||||
hbufp_index = hbufp - data->headerbuff;
|
||||
newbuff = (char *)realloc(data->headerbuff, newsize);
|
||||
if(!newbuff) {
|
||||
failf (data, "Failed to alloc memory for big header!");
|
||||
return URG_READ_ERROR;
|
||||
}
|
||||
data->headersize= newsize;
|
||||
data->headerbuff = newbuff;
|
||||
hbufp = data->headerbuff + hbufp_index;
|
||||
}
|
||||
|
||||
/* copy to end of line */
|
||||
strncpy (hbufp, str_start, str - str_start);
|
||||
hbufp += str - str_start;
|
||||
hbuflen += str - str_start;
|
||||
*hbufp = 0;
|
||||
|
||||
p = data->headerbuff;
|
||||
|
||||
/* we now have a full line that p points to */
|
||||
if (('\n' == *p) || ('\r' == *p)) {
|
||||
/* Zero-length line means end of header! */
|
||||
if (-1 != size) /* if known */
|
||||
size += bytecount; /* we append the already read size */
|
||||
|
||||
|
||||
if ('\r' == *p)
|
||||
p++; /* pass the \r byte */
|
||||
if ('\n' == *p)
|
||||
p++; /* pass the \n byte */
|
||||
|
||||
pgrsSetDownloadSize(data, size);
|
||||
|
||||
header = FALSE; /* no more header to parse! */
|
||||
|
||||
/* now, only output this if the header AND body are requested:
|
||||
*/
|
||||
if ((data->conf & (CONF_HEADER | CONF_NOBODY)) ==
|
||||
CONF_HEADER) {
|
||||
if((p - data->headerbuff) !=
|
||||
data->fwrite (data->headerbuff, 1,
|
||||
p - data->headerbuff, data->out)) {
|
||||
failf (data, "Failed writing output");
|
||||
return URG_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
if(data->writeheader) {
|
||||
/* obviously, the header is requested to be written to
|
||||
this file: */
|
||||
if((p - data->headerbuff) !=
|
||||
data->fwrite (data->headerbuff, 1, p - data->headerbuff,
|
||||
data->writeheader)) {
|
||||
failf (data, "Failed writing output");
|
||||
return URG_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
break; /* exit header line loop */
|
||||
}
|
||||
|
||||
if (!headerline++) {
|
||||
/* This is the first header, it MUST be the error code line
|
||||
or else we consiser this to be the body right away! */
|
||||
if (sscanf (p, " HTTP/1.%*c %3d", &code)) {
|
||||
/* 404 -> URL not found! */
|
||||
if (
|
||||
( ((data->conf & CONF_FOLLOWLOCATION) && (code >= 400))
|
||||
||
|
||||
!(data->conf & CONF_FOLLOWLOCATION) && (code >= 300))
|
||||
&& (data->conf & CONF_FAILONERROR)) {
|
||||
/* If we have been told to fail hard on HTTP-errors,
|
||||
here is the check for that: */
|
||||
/* serious error, go home! */
|
||||
failf (data, "The requested file was not found");
|
||||
return URG_HTTP_NOT_FOUND;
|
||||
}
|
||||
data->progress.httpcode = code;
|
||||
}
|
||||
else {
|
||||
header = FALSE; /* this is not a header line */
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* check for Content-Length: header lines to get size */
|
||||
if (strnequal("Content-Length", p, 14) &&
|
||||
sscanf (p+14, ": %ld", &contentlength))
|
||||
size = contentlength;
|
||||
else if (strnequal("Content-Range", p, 13) &&
|
||||
sscanf (p+13, ": bytes %d-", &offset)) {
|
||||
if (data->resume_from == offset) {
|
||||
/* we asked for a resume and we got it */
|
||||
content_range = TRUE;
|
||||
}
|
||||
}
|
||||
else if(data->cookies &&
|
||||
strnequal("Set-Cookie: ", p, 11)) {
|
||||
cookie_add(data->cookies, TRUE, &p[12]);
|
||||
}
|
||||
else if(strnequal("Last-Modified:", p,
|
||||
strlen("Last-Modified:")) &&
|
||||
data->timecondition) {
|
||||
time_t secs=time(NULL);
|
||||
timeofdoc = get_date(p+strlen("Last-Modified:"), &secs);
|
||||
}
|
||||
else if ((code >= 300 && code < 400) &&
|
||||
(data->conf & CONF_FOLLOWLOCATION) &&
|
||||
strnequal("Location", p, 8) &&
|
||||
sscanf (p+8, ": %" URL_MAX_LENGTH_TXT "s", newurl)) {
|
||||
/* this is the URL that the server advices us to get
|
||||
instead */
|
||||
data->newurl = strdup (newurl);
|
||||
}
|
||||
|
||||
if (data->conf & CONF_HEADER) {
|
||||
if(hbuflen != data->fwrite (p, 1, hbuflen, data->out)) {
|
||||
failf (data, "Failed writing output");
|
||||
return URG_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
if(data->writeheader) {
|
||||
/* the header is requested to be written to this file */
|
||||
if(hbuflen != data->fwrite (p, 1, hbuflen,
|
||||
data->writeheader)) {
|
||||
failf (data, "Failed writing output");
|
||||
return URG_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset hbufp pointer && hbuflen */
|
||||
hbufp = data->headerbuff;
|
||||
hbuflen = 0;
|
||||
}
|
||||
while (*str); /* header line within buffer */
|
||||
|
||||
/* We might have reached the end of the header part here, but
|
||||
there might be a non-header part left in the end of the read
|
||||
buffer. */
|
||||
|
||||
if (!header) {
|
||||
/* the next token and forward is not part of
|
||||
the header! */
|
||||
|
||||
/* we subtract the remaining header size from the buffer */
|
||||
nread -= (str - buf);
|
||||
}
|
||||
|
||||
} /* end if header mode */
|
||||
|
||||
/* This is not an 'else if' since it may be a rest from the header
|
||||
parsing, where the beginning of the buffer is headers and the end
|
||||
is non-headers. */
|
||||
if (str && !header && (nread > 0)) {
|
||||
|
||||
if(0 == bodywrites) {
|
||||
/* These checks are only made the first time we are about to
|
||||
write a chunk of the body */
|
||||
if(data->conf&CONF_HTTP) {
|
||||
/* HTTP-only checks */
|
||||
if (data->resume_from && !content_range ) {
|
||||
/* we wanted to resume a download, although the server
|
||||
doesn't seem to support this */
|
||||
failf (data, "HTTP server doesn't seem to support byte ranges. Cannot resume.");
|
||||
return URG_HTTP_RANGE_ERROR;
|
||||
}
|
||||
else if (data->newurl) {
|
||||
/* abort after the headers if "follow Location" is set */
|
||||
infof (data, "Follow to new URL: %s\n", data->newurl);
|
||||
return URG_OK;
|
||||
}
|
||||
else if(data->timecondition && !data->range) {
|
||||
/* A time condition has been set AND no ranges have been
|
||||
requested. This seems to be what chapter 13.3.4 of
|
||||
RFC 2616 defines to be the correct action for a
|
||||
HTTP/1.1 client */
|
||||
if((timeofdoc > 0) && (data->timevalue > 0)) {
|
||||
switch(data->timecondition) {
|
||||
case TIMECOND_IFMODSINCE:
|
||||
default:
|
||||
if(timeofdoc < data->timevalue) {
|
||||
infof(data,
|
||||
"The requested document is not new enough");
|
||||
return URG_OK;
|
||||
}
|
||||
break;
|
||||
case TIMECOND_IFUNMODSINCE:
|
||||
if(timeofdoc > data->timevalue) {
|
||||
infof(data,
|
||||
"The requested document is not old enough");
|
||||
return URG_OK;
|
||||
}
|
||||
break;
|
||||
} /* switch */
|
||||
} /* two valid time strings */
|
||||
} /* we have a time condition */
|
||||
} /* this is HTTP */
|
||||
} /* this is the first time we write a body part */
|
||||
bodywrites++;
|
||||
|
||||
if(data->maxdownload &&
|
||||
(bytecount + nread > data->maxdownload)) {
|
||||
nread = data->maxdownload - bytecount;
|
||||
if(nread < 0 ) /* this should be unusual */
|
||||
nread = 0;
|
||||
keepon &= ~KEEP_READ; /* we're done reading */
|
||||
}
|
||||
|
||||
bytecount += nread;
|
||||
|
||||
pgrsSetDownloadCounter(data, (double)bytecount);
|
||||
|
||||
if (nread != data->fwrite (str, 1, nread, data->out)) {
|
||||
failf (data, "Failed writing output");
|
||||
return URG_WRITE_ERROR;
|
||||
}
|
||||
|
||||
} /* if (! header and data to read ) */
|
||||
} /* if( read from socket ) */
|
||||
|
||||
if((keepon & KEEP_WRITE) && FD_ISSET(writesockfd, &writefd)) {
|
||||
/* write */
|
||||
|
||||
char scratch[BUFSIZE * 2];
|
||||
int i, si;
|
||||
int bytes_written;
|
||||
|
||||
if(data->crlf)
|
||||
buf = data->buffer; /* put it back on the buffer */
|
||||
|
||||
nread = data->fread(buf, 1, BUFSIZE, data->in);
|
||||
writebytecount += nread;
|
||||
|
||||
pgrsSetUploadCounter(data, (double)writebytecount);
|
||||
|
||||
if (nread<=0) {
|
||||
/* done */
|
||||
keepon &= ~KEEP_WRITE; /* we're done writing */
|
||||
break;
|
||||
}
|
||||
|
||||
/* convert LF to CRLF if so asked */
|
||||
if (data->crlf) {
|
||||
for(i = 0, si = 0; i < (int)nread; i++, si++) {
|
||||
if (buf[i] == 0x0a) {
|
||||
scratch[si++] = 0x0d;
|
||||
scratch[si] = 0x0a;
|
||||
}
|
||||
else {
|
||||
scratch[si] = buf[i];
|
||||
}
|
||||
}
|
||||
nread = si;
|
||||
buf = scratch; /* point to the new buffer */
|
||||
}
|
||||
|
||||
/* write to socket */
|
||||
#ifdef USE_SSLEAY
|
||||
if (data->use_ssl) {
|
||||
bytes_written = SSL_write(data->ssl, buf, nread);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
bytes_written = swrite(writesockfd, buf, nread);
|
||||
#ifdef USE_SSLEAY
|
||||
}
|
||||
#endif /* USE_SSLEAY */
|
||||
if(nread != bytes_written) {
|
||||
failf(data, "Failed uploading data");
|
||||
return URG_WRITE_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
now = tvnow();
|
||||
pgrsUpdate(data);
|
||||
|
||||
urg = speedcheck (data, now);
|
||||
if (urg)
|
||||
return urg;
|
||||
|
||||
if (data->timeout && (tvdiff (now, start) > data->timeout)) {
|
||||
failf (data, "Operation timed out with %d out of %d bytes received",
|
||||
bytecount, size);
|
||||
return URG_OPERATION_TIMEOUTED;
|
||||
}
|
||||
#ifdef MULTIDOC
|
||||
if(contentlength && bytecount >= contentlength) {
|
||||
/* we're done with this download, now stop it */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if(!(data->conf&CONF_NOBODY) && contentlength &&
|
||||
(bytecount != contentlength)) {
|
||||
failf(data, "transfer closed with %d bytes remaining to read",
|
||||
contentlength-bytecount);
|
||||
return URG_PARTIAL_FILE;
|
||||
}
|
||||
pgrsUpdate(data);
|
||||
|
||||
if(bytecountp)
|
||||
*bytecountp = bytecount; /* read count */
|
||||
if(writebytecountp)
|
||||
*writebytecountp = writebytecount; /* write count */
|
||||
|
||||
return URG_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,8 +39,8 @@
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
****************************************************************************/
|
||||
UrgError
|
||||
Transfer (struct UrlData *data,
|
||||
CURLcode
|
||||
Transfer (struct connectdata *data,
|
||||
int sockfd, /* socket to read from or -1 */
|
||||
int size, /* -1 if unknown at this point */
|
||||
bool getheader, /* TRUE if header parsing is wanted */
|
||||
|
@ -81,16 +81,15 @@ char *curl_escape(char *string)
|
||||
return ns;
|
||||
}
|
||||
|
||||
char *curl_unescape(char *string)
|
||||
char *curl_unescape(char *string, int length)
|
||||
{
|
||||
int alloc = strlen(string)+1;
|
||||
int alloc = (length?length:strlen(string))+1;
|
||||
char *ns = malloc(alloc);
|
||||
unsigned char in;
|
||||
int index=0;
|
||||
int hex;
|
||||
|
||||
|
||||
while(*string) {
|
||||
while(--alloc) {
|
||||
in = *string;
|
||||
if('+' == in)
|
||||
in = ' ';
|
||||
|
@ -44,6 +44,6 @@
|
||||
* allocated string or NULL if an error occurred. */
|
||||
|
||||
char *curl_escape(char *string);
|
||||
char *curl_unescape(char *string);
|
||||
char *curl_unescape(char *string, int length);
|
||||
|
||||
#endif
|
||||
|
30
lib/file.c
30
lib/file.c
@ -100,23 +100,25 @@
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
|
||||
UrgError file(struct UrlData *data, char *path, long *bytecountp)
|
||||
CURLcode file(struct connectdata *conn)
|
||||
{
|
||||
/* This implementation ignores the host name in conformance with
|
||||
RFC 1738. Only local files (reachable via the standard file system)
|
||||
are supported. This means that files on remotely mounted directories
|
||||
(via NFS, Samba, NT sharing) can be accessed through a file:// URL
|
||||
*/
|
||||
|
||||
CURLcode res = CURLE_OK;
|
||||
char *path = conn->path;
|
||||
struct stat statbuf;
|
||||
size_t expected_size=-1;
|
||||
size_t nread;
|
||||
struct UrlData *data = conn->data;
|
||||
char *buf = data->buffer;
|
||||
int bytecount = 0;
|
||||
struct timeval start = tvnow();
|
||||
struct timeval now = start;
|
||||
int fd;
|
||||
char *actual_path = curl_unescape(path);
|
||||
char *actual_path = curl_unescape(path, 0);
|
||||
|
||||
#if defined(WIN32) || defined(__EMX__)
|
||||
int i;
|
||||
@ -134,7 +136,7 @@ UrgError file(struct UrlData *data, char *path, long *bytecountp)
|
||||
|
||||
if(fd == -1) {
|
||||
failf(data, "Couldn't open file %s", path);
|
||||
return URG_FILE_COULDNT_READ_FILE;
|
||||
return CURLE_FILE_COULDNT_READ_FILE;
|
||||
}
|
||||
if( -1 != fstat(fd, &statbuf)) {
|
||||
/* we could stat it, then read out the size */
|
||||
@ -151,7 +153,7 @@ UrgError file(struct UrlData *data, char *path, long *bytecountp)
|
||||
if(expected_size != -1)
|
||||
pgrsSetDownloadSize(data, expected_size);
|
||||
|
||||
while (1) {
|
||||
while (res == CURLE_OK) {
|
||||
nread = read(fd, buf, BUFSIZE-1);
|
||||
|
||||
if (0 <= nread)
|
||||
@ -166,21 +168,19 @@ UrgError file(struct UrlData *data, char *path, long *bytecountp)
|
||||
file descriptor). */
|
||||
if(nread != data->fwrite (buf, 1, nread, data->out)) {
|
||||
failf (data, "Failed writing output");
|
||||
return URG_WRITE_ERROR;
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
now = tvnow();
|
||||
pgrsUpdate(data);
|
||||
#if 0
|
||||
ProgressShow (data, bytecount, start, now, FALSE);
|
||||
#endif
|
||||
if(pgrsUpdate(data))
|
||||
res = CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
now = tvnow();
|
||||
#if 0
|
||||
ProgressShow (data, bytecount, start, now, TRUE);
|
||||
#endif
|
||||
pgrsUpdate(data);
|
||||
if(pgrsUpdate(data))
|
||||
res = CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
close(fd);
|
||||
|
||||
return URG_OK;
|
||||
free(actual_path);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -40,6 +40,6 @@
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
****************************************************************************/
|
||||
UrgError file(struct UrlData *data, char *path, long *bytecountp);
|
||||
CURLcode file(struct connectdata *conn);
|
||||
|
||||
#endif
|
||||
|
@ -60,6 +60,8 @@
|
||||
#include <curl/curl.h>
|
||||
#include "formdata.h"
|
||||
|
||||
#include "strequal.h"
|
||||
|
||||
/* Length of the random boundary string. The risk of this being used
|
||||
in binary data is very close to zero, 64^32 makes
|
||||
6277101735386680763835789423207666416102355444464034512896
|
||||
@ -377,7 +379,7 @@ void FormFree(struct FormData *form)
|
||||
free(form->line); /* free the line */
|
||||
free(form); /* free the struct */
|
||||
|
||||
} while(form=next); /* continue */
|
||||
} while((form=next)); /* continue */
|
||||
}
|
||||
|
||||
struct FormData *getFormData(struct HttpPost *post,
|
||||
@ -513,12 +515,17 @@ struct FormData *getFormData(struct HttpPost *post,
|
||||
|
||||
int FormInit(struct Form *form, struct FormData *formdata )
|
||||
{
|
||||
form->data = formdata;
|
||||
form->sent = 0;
|
||||
|
||||
if(!formdata)
|
||||
return 1; /* error */
|
||||
|
||||
/* First, make sure that we'll send a nice terminating sequence at the end
|
||||
* of the post. We *DONT* add this string to the size of the data since this
|
||||
* is actually AFTER the data. */
|
||||
AddFormDataf(&formdata, "\r\n\r\n");
|
||||
|
||||
form->data = formdata;
|
||||
form->sent = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
436
lib/ftp.c
436
lib/ftp.c
@ -149,7 +149,7 @@ void curl_slist_free_all(struct curl_slist *list)
|
||||
}
|
||||
|
||||
|
||||
static UrgError AllowServerConnect(struct UrlData *data,
|
||||
static CURLcode AllowServerConnect(struct UrlData *data,
|
||||
int sock)
|
||||
{
|
||||
fd_set rdset;
|
||||
@ -167,11 +167,11 @@ static UrgError AllowServerConnect(struct UrlData *data,
|
||||
case -1: /* error */
|
||||
/* let's die here */
|
||||
failf(data, "Error while waiting for server connect");
|
||||
return URG_FTP_PORT_FAILED;
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
case 0: /* timeout */
|
||||
/* let's die here */
|
||||
failf(data, "Timeout while waiting for server connect");
|
||||
return URG_FTP_PORT_FAILED;
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
default:
|
||||
/* we have received data here */
|
||||
{
|
||||
@ -185,7 +185,7 @@ static UrgError AllowServerConnect(struct UrlData *data,
|
||||
if( -1 == s) {
|
||||
/* DIE! */
|
||||
failf(data, "Error accept()ing server connect");
|
||||
return URG_FTP_PORT_FAILED;
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
infof(data, "Connection accepted from server\n");
|
||||
|
||||
@ -193,7 +193,7 @@ static UrgError AllowServerConnect(struct UrlData *data,
|
||||
}
|
||||
break;
|
||||
}
|
||||
return URG_OK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -202,7 +202,7 @@ static UrgError AllowServerConnect(struct UrlData *data,
|
||||
#define lastline(line) (isdigit((int)line[0]) && isdigit((int)line[1]) && \
|
||||
isdigit((int)line[2]) && (' ' == line[3]))
|
||||
|
||||
static int GetLastResponse(int sockfd, char *buf,
|
||||
int GetLastResponse(int sockfd, char *buf,
|
||||
struct UrlData *data)
|
||||
{
|
||||
int nread;
|
||||
@ -230,7 +230,7 @@ static int GetLastResponse(int sockfd, char *buf,
|
||||
}
|
||||
*ptr=0; /* zero terminate */
|
||||
|
||||
if(data->conf & CONF_VERBOSE) {
|
||||
if(data->bits.verbose) {
|
||||
fputs("< ", data->err);
|
||||
fwrite(buf, 1, nread, data->err);
|
||||
fputs("\n", data->err);
|
||||
@ -310,32 +310,37 @@ static char *URLfix(char *string)
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
UrgError _ftp(struct UrlData *data,
|
||||
long *bytecountp,
|
||||
char *ftpuser,
|
||||
char *ftppasswd,
|
||||
char *ppath)
|
||||
/* ftp_connect() should do everything that is to be considered a part
|
||||
of the connection phase. */
|
||||
CURLcode ftp_connect(struct connectdata *conn)
|
||||
{
|
||||
/* this is FTP and no proxy */
|
||||
size_t nread;
|
||||
UrgError result;
|
||||
struct UrlData *data=conn->data;
|
||||
char *buf = data->buffer; /* this is our buffer */
|
||||
/* for the ftp PORT mode */
|
||||
int portsock=-1;
|
||||
struct sockaddr_in serv_addr;
|
||||
struct FTP *ftp;
|
||||
|
||||
struct curl_slist *qitem; /* QUOTE item */
|
||||
ftp = (struct FTP *)malloc(sizeof(struct FTP));
|
||||
if(!ftp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
memset(ftp, 0, sizeof(struct FTP));
|
||||
data->proto.ftp = ftp;
|
||||
|
||||
/* get some initial data into the ftp struct */
|
||||
ftp->bytecountp = &conn->bytecount;
|
||||
ftp->user = data->user;
|
||||
ftp->passwd = data->passwd;
|
||||
|
||||
/* The first thing we do is wait for the "220*" line: */
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
if(strncmp(buf, "220", 3)) {
|
||||
failf(data, "This doesn't seem like a nice ftp-server response");
|
||||
return URG_FTP_WEIRD_SERVER_REPLY;
|
||||
return CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
/* send USER */
|
||||
sendf(data->firstsocket, data, "USER %s\r\n", ftpuser);
|
||||
sendf(data->firstsocket, data, "USER %s\r\n", ftp->user);
|
||||
|
||||
/* wait for feedback */
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
@ -344,19 +349,19 @@ UrgError _ftp(struct UrlData *data,
|
||||
/* 530 User ... access denied
|
||||
(the server denies to log the specified user) */
|
||||
failf(data, "Access denied: %s", &buf[4]);
|
||||
return URG_FTP_ACCESS_DENIED;
|
||||
return CURLE_FTP_ACCESS_DENIED;
|
||||
}
|
||||
else if(!strncmp(buf, "331", 3)) {
|
||||
/* 331 Password required for ...
|
||||
(the server requires to send the user's password too) */
|
||||
sendf(data->firstsocket, data, "PASS %s\r\n", ftppasswd);
|
||||
sendf(data->firstsocket, data, "PASS %s\r\n", ftp->passwd);
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
|
||||
if(!strncmp(buf, "530", 3)) {
|
||||
/* 530 Login incorrect.
|
||||
(the username and/or the password are incorrect) */
|
||||
failf(data, "the username and/or the password are incorrect");
|
||||
return URG_FTP_USER_PASSWORD_INCORRECT;
|
||||
return CURLE_FTP_USER_PASSWORD_INCORRECT;
|
||||
}
|
||||
else if(!strncmp(buf, "230", 3)) {
|
||||
/* 230 User ... logged in.
|
||||
@ -366,7 +371,7 @@ UrgError _ftp(struct UrlData *data,
|
||||
}
|
||||
else {
|
||||
failf(data, "Odd return code after PASS");
|
||||
return URG_FTP_WEIRD_PASS_REPLY;
|
||||
return CURLE_FTP_WEIRD_PASS_REPLY;
|
||||
}
|
||||
}
|
||||
else if(! strncmp(buf, "230", 3)) {
|
||||
@ -376,9 +381,105 @@ UrgError _ftp(struct UrlData *data,
|
||||
}
|
||||
else {
|
||||
failf(data, "Odd return code after USER");
|
||||
return URG_FTP_WEIRD_USER_REPLY;
|
||||
return CURLE_FTP_WEIRD_USER_REPLY;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* argument is already checked for validity */
|
||||
CURLcode ftp_done(struct connectdata *conn)
|
||||
{
|
||||
struct UrlData *data = conn->data;
|
||||
struct FTP *ftp = data->proto.ftp;
|
||||
size_t nread;
|
||||
char *buf = data->buffer; /* this is our buffer */
|
||||
struct curl_slist *qitem; /* QUOTE item */
|
||||
|
||||
if(data->bits.upload) {
|
||||
if((-1 != data->infilesize) && (data->infilesize != *ftp->bytecountp)) {
|
||||
failf(data, "Wrote only partial file (%d out of %d bytes)",
|
||||
*ftp->bytecountp, data->infilesize);
|
||||
return CURLE_PARTIAL_FILE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if((-1 != conn->size) && (conn->size != *ftp->bytecountp) &&
|
||||
(data->maxdownload != *ftp->bytecountp)) {
|
||||
failf(data, "Received only partial file");
|
||||
return CURLE_PARTIAL_FILE;
|
||||
}
|
||||
else if(0 == *ftp->bytecountp) {
|
||||
failf(data, "No data was received!");
|
||||
return CURLE_FTP_COULDNT_RETR_FILE;
|
||||
}
|
||||
}
|
||||
/* shut down the socket to inform the server we're done */
|
||||
sclose(data->secondarysocket);
|
||||
data->secondarysocket = -1;
|
||||
|
||||
/* now let's see what the server says about the transfer we
|
||||
just performed: */
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
|
||||
/* 226 Transfer complete */
|
||||
if(strncmp(buf, "226", 3)) {
|
||||
failf(data, "%s", buf+4);
|
||||
return CURLE_FTP_WRITE_ERROR;
|
||||
}
|
||||
|
||||
/* Send any post-transfer QUOTE strings? */
|
||||
if(data->postquote) {
|
||||
qitem = data->postquote;
|
||||
/* Send all QUOTE strings in same order as on command-line */
|
||||
while (qitem) {
|
||||
/* Send string */
|
||||
if (qitem->data) {
|
||||
sendf(data->firstsocket, data, "%s\r\n", qitem->data);
|
||||
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
|
||||
if (buf[0] != '2') {
|
||||
failf(data, "QUOT string not accepted: %s",
|
||||
qitem->data);
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
}
|
||||
qitem = qitem->next;
|
||||
}
|
||||
}
|
||||
|
||||
if(ftp->file)
|
||||
free(ftp->file);
|
||||
if(ftp->dir)
|
||||
free(ftp->dir);
|
||||
|
||||
/* TBD: the ftp struct is still allocated here */
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
CURLcode _ftp(struct connectdata *conn)
|
||||
{
|
||||
/* this is FTP and no proxy */
|
||||
size_t nread;
|
||||
CURLcode result;
|
||||
struct UrlData *data=conn->data;
|
||||
char *buf = data->buffer; /* this is our buffer */
|
||||
/* for the ftp PORT mode */
|
||||
int portsock=-1;
|
||||
struct sockaddr_in serv_addr;
|
||||
|
||||
struct curl_slist *qitem; /* QUOTE item */
|
||||
/* the ftp struct is already inited in ftp_connect() */
|
||||
struct FTP *ftp = data->proto.ftp;
|
||||
|
||||
long *bytecountp = ftp->bytecountp;
|
||||
|
||||
/* Send any QUOTE strings? */
|
||||
if(data->quote) {
|
||||
qitem = data->quote;
|
||||
@ -393,7 +494,7 @@ UrgError _ftp(struct UrlData *data,
|
||||
if (buf[0] != '2') {
|
||||
failf(data, "QUOT string not accepted: %s",
|
||||
qitem->data);
|
||||
return URG_FTP_QUOTE_ERROR;
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
}
|
||||
qitem = qitem->next;
|
||||
@ -402,18 +503,18 @@ UrgError _ftp(struct UrlData *data,
|
||||
|
||||
/* If we have selected NOBODY, it means that we only want file information.
|
||||
Which in FTP can't be much more than the file size! */
|
||||
if(data->conf & CONF_NOBODY) {
|
||||
if(data->bits.no_body) {
|
||||
/* The SIZE command is _not_ RFC 959 specified, and therefor many servers
|
||||
may not support it! It is however the only way we have to get a file's
|
||||
size! */
|
||||
int filesize;
|
||||
sendf(data->firstsocket, data, "SIZE %s\r\n", ppath);
|
||||
sendf(data->firstsocket, data, "SIZE %s\r\n", ftp->file);
|
||||
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
|
||||
if(strncmp(buf, "213", 3)) {
|
||||
failf(data, "Couldn't get file size: %s", buf+4);
|
||||
return URG_FTP_COULDNT_GET_SIZE;
|
||||
return CURLE_FTP_COULDNT_GET_SIZE;
|
||||
}
|
||||
/* get the size from the ascii string: */
|
||||
filesize = atoi(buf+4);
|
||||
@ -422,21 +523,21 @@ UrgError _ftp(struct UrlData *data,
|
||||
|
||||
if(strlen(buf) != data->fwrite(buf, 1, strlen(buf), data->out)) {
|
||||
failf (data, "Failed writing output");
|
||||
return URG_WRITE_ERROR;
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
if(data->writeheader) {
|
||||
/* the header is requested to be written to this file */
|
||||
if(strlen(buf) != data->fwrite (buf, 1, strlen(buf),
|
||||
data->writeheader)) {
|
||||
failf (data, "Failed writing output");
|
||||
return URG_WRITE_ERROR;
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
return URG_OK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* We have chosen to use the PORT command */
|
||||
if(data->conf & CONF_FTPPORT) {
|
||||
if(data->bits.ftp_use_port) {
|
||||
struct sockaddr_in sa;
|
||||
struct hostent *h=NULL;
|
||||
size_t size;
|
||||
@ -481,28 +582,28 @@ UrgError _ftp(struct UrlData *data,
|
||||
if(getsockname(portsock, (struct sockaddr *) &add,
|
||||
(int *)&size)<0) {
|
||||
failf(data, "getsockname() failed");
|
||||
return URG_FTP_PORT_FAILED;
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
porttouse = ntohs(add.sin_port);
|
||||
|
||||
if ( listen(portsock, 1) < 0 ) {
|
||||
failf(data, "listen(2) failed on socket");
|
||||
return URG_FTP_PORT_FAILED;
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
failf(data, "bind(2) failed on socket");
|
||||
return URG_FTP_PORT_FAILED;
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
failf(data, "socket(2) failed (%s)");
|
||||
return URG_FTP_PORT_FAILED;
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
failf(data, "could't find my own IP address (%s)", myhost);
|
||||
return URG_FTP_PORT_FAILED;
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
{
|
||||
struct in_addr in;
|
||||
@ -520,7 +621,7 @@ UrgError _ftp(struct UrlData *data,
|
||||
|
||||
if(strncmp(buf, "200", 3)) {
|
||||
failf(data, "Server does not grok PORT, try without it!");
|
||||
return URG_FTP_PORT_FAILED;
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
}
|
||||
else { /* we use the PASV command */
|
||||
@ -531,7 +632,7 @@ UrgError _ftp(struct UrlData *data,
|
||||
|
||||
if(strncmp(buf, "227", 3)) {
|
||||
failf(data, "Odd return code after PASV");
|
||||
return URG_FTP_WEIRD_PASV_REPLY;
|
||||
return CURLE_FTP_WEIRD_PASV_REPLY;
|
||||
}
|
||||
else {
|
||||
int ip[4];
|
||||
@ -561,13 +662,13 @@ UrgError _ftp(struct UrlData *data,
|
||||
}
|
||||
if(!*str) {
|
||||
failf(data, "Couldn't interpret this 227-reply: %s", buf);
|
||||
return URG_FTP_WEIRD_227_FORMAT;
|
||||
return CURLE_FTP_WEIRD_227_FORMAT;
|
||||
}
|
||||
sprintf(newhost, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
he = GetHost(data, newhost);
|
||||
if(!he) {
|
||||
failf(data, "Can't resolve new host %s", newhost);
|
||||
return URG_FTP_CANT_GET_HOST;
|
||||
return CURLE_FTP_CANT_GET_HOST;
|
||||
}
|
||||
|
||||
|
||||
@ -579,7 +680,7 @@ UrgError _ftp(struct UrlData *data,
|
||||
serv_addr.sin_family = he->h_addrtype;
|
||||
serv_addr.sin_port = htons(newport);
|
||||
|
||||
if(data->conf & CONF_VERBOSE) {
|
||||
if(data->bits.verbose) {
|
||||
struct in_addr in;
|
||||
#if 1
|
||||
struct hostent * answer;
|
||||
@ -620,26 +721,38 @@ UrgError _ftp(struct UrlData *data,
|
||||
failf(data, "Can't connect to ftp server");
|
||||
break;
|
||||
}
|
||||
return URG_FTP_CANT_RECONNECT;
|
||||
return CURLE_FTP_CANT_RECONNECT;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* we have the (new) data connection ready */
|
||||
|
||||
if(data->conf & CONF_UPLOAD) {
|
||||
/* change directory first */
|
||||
|
||||
if(ftp->dir && ftp->dir[0]) {
|
||||
sendf(data->firstsocket, data, "CWD %s\r\n", ftp->dir);
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
|
||||
if(strncmp(buf, "250", 3)) {
|
||||
failf(data, "Couldn't change to directory %s", ftp->dir);
|
||||
return CURLE_FTP_ACCESS_DENIED;
|
||||
}
|
||||
}
|
||||
|
||||
if(data->bits.upload) {
|
||||
|
||||
/* Set type to binary (unless specified ASCII) */
|
||||
sendf(data->firstsocket, data, "TYPE %s\r\n",
|
||||
(data->conf&CONF_FTPASCII)?"A":"I");
|
||||
(data->bits.ftp_ascii)?"A":"I");
|
||||
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
|
||||
if(strncmp(buf, "200", 3)) {
|
||||
failf(data, "Couldn't set %s mode",
|
||||
(data->conf&CONF_FTPASCII)?"ASCII":"binary");
|
||||
return (data->conf&CONF_FTPASCII)? URG_FTP_COULDNT_SET_ASCII:
|
||||
URG_FTP_COULDNT_SET_BINARY;
|
||||
(data->bits.ftp_ascii)?"ASCII":"binary");
|
||||
return (data->bits.ftp_ascii)? CURLE_FTP_COULDNT_SET_ASCII:
|
||||
CURLE_FTP_COULDNT_SET_BINARY;
|
||||
}
|
||||
|
||||
if(data->resume_from) {
|
||||
@ -660,13 +773,13 @@ UrgError _ftp(struct UrlData *data,
|
||||
/* we could've got a specified offset from the command line,
|
||||
but now we know we didn't */
|
||||
|
||||
sendf(data->firstsocket, data, "SIZE %s\r\n", ppath);
|
||||
sendf(data->firstsocket, data, "SIZE %s\r\n", ftp->file);
|
||||
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
|
||||
if(strncmp(buf, "213", 3)) {
|
||||
failf(data, "Couldn't get file size: %s", buf+4);
|
||||
return URG_FTP_COULDNT_GET_SIZE;
|
||||
return CURLE_FTP_COULDNT_GET_SIZE;
|
||||
}
|
||||
|
||||
/* get the size from the ascii string: */
|
||||
@ -687,11 +800,11 @@ UrgError _ftp(struct UrlData *data,
|
||||
|
||||
if(strncmp(buf, "350", 3)) {
|
||||
failf(data, "Couldn't use REST: %s", buf+4);
|
||||
return URG_FTP_COULDNT_USE_REST;
|
||||
return CURLE_FTP_COULDNT_USE_REST;
|
||||
}
|
||||
#else
|
||||
/* enable append instead */
|
||||
data->conf |= CONF_FTPAPPEND;
|
||||
data->bits.ftp_append = 1;
|
||||
#endif
|
||||
/* Now, let's read off the proper amount of bytes from the
|
||||
input. If we knew it was a proper file we could've just
|
||||
@ -710,7 +823,7 @@ UrgError _ftp(struct UrlData *data,
|
||||
if(actuallyread != readthisamountnow) {
|
||||
failf(data, "Could only read %d bytes from the input\n",
|
||||
passed);
|
||||
return URG_FTP_COULDNT_USE_REST;
|
||||
return CURLE_FTP_COULDNT_USE_REST;
|
||||
}
|
||||
}
|
||||
while(passed != data->resume_from);
|
||||
@ -721,7 +834,7 @@ UrgError _ftp(struct UrlData *data,
|
||||
|
||||
if(data->infilesize <= 0) {
|
||||
infof(data, "File already completely uploaded\n");
|
||||
return URG_OK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
}
|
||||
/* we've passed, proceed as normal */
|
||||
@ -729,21 +842,21 @@ UrgError _ftp(struct UrlData *data,
|
||||
}
|
||||
|
||||
/* Send everything on data->in to the socket */
|
||||
if(data->conf & CONF_FTPAPPEND)
|
||||
if(data->bits.ftp_append)
|
||||
/* we append onto the file instead of rewriting it */
|
||||
sendf(data->firstsocket, data, "APPE %s\r\n", ppath);
|
||||
sendf(data->firstsocket, data, "APPE %s\r\n", ftp->file);
|
||||
else
|
||||
sendf(data->firstsocket, data, "STOR %s\r\n", ppath);
|
||||
sendf(data->firstsocket, data, "STOR %s\r\n", ftp->file);
|
||||
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
|
||||
if(atoi(buf)>=400) {
|
||||
failf(data, "Failed FTP upload:%s", buf+3);
|
||||
/* oops, we never close the sockets! */
|
||||
return URG_FTP_COULDNT_STOR_FILE;
|
||||
return CURLE_FTP_COULDNT_STOR_FILE;
|
||||
}
|
||||
|
||||
if(data->conf & CONF_FTPPORT) {
|
||||
if(data->bits.ftp_use_port) {
|
||||
result = AllowServerConnect(data, portsock);
|
||||
if( result )
|
||||
return result;
|
||||
@ -758,24 +871,19 @@ UrgError _ftp(struct UrlData *data,
|
||||
#if 0
|
||||
ProgressInit(data, data->infilesize);
|
||||
#endif
|
||||
result = Transfer(data, -1, -1, FALSE, NULL, /* no download */
|
||||
result = Transfer(conn, -1, -1, FALSE, NULL, /* no download */
|
||||
data->secondarysocket, bytecountp);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if((-1 != data->infilesize) && (data->infilesize != *bytecountp)) {
|
||||
failf(data, "Wrote only partial file (%d out of %d bytes)",
|
||||
*bytecountp, data->infilesize);
|
||||
return URG_PARTIAL_FILE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Retrieve file or directory */
|
||||
bool dirlist=FALSE;
|
||||
long downloadsize=-1;
|
||||
|
||||
if(data->conf&CONF_RANGE && data->range) {
|
||||
int from, to;
|
||||
if(data->bits.set_range && data->range) {
|
||||
long from, to;
|
||||
int totalsize=-1;
|
||||
char *ptr;
|
||||
char *ptr2;
|
||||
@ -788,32 +896,34 @@ UrgError _ftp(struct UrlData *data,
|
||||
/* we didn't get any digit */
|
||||
to=-1;
|
||||
}
|
||||
if(-1 == to) {
|
||||
if((-1 == to) && (from>=0)) {
|
||||
/* X - */
|
||||
data->resume_from = from;
|
||||
infof(data, "FTP RANGE %d to end of file\n", from);
|
||||
}
|
||||
else if(from < 0) {
|
||||
/* -Y */
|
||||
from = 0;
|
||||
to = -from;
|
||||
totalsize = to-from;
|
||||
data->maxdownload = totalsize;
|
||||
totalsize = -from;
|
||||
data->maxdownload = -from;
|
||||
data->resume_from = from;
|
||||
infof(data, "FTP RANGE the last %d bytes\n", totalsize);
|
||||
}
|
||||
else {
|
||||
/* X- */
|
||||
/* X-Y */
|
||||
totalsize = to-from;
|
||||
data->maxdownload = totalsize;
|
||||
data->maxdownload = totalsize+1; /* include the last mentioned byte */
|
||||
data->resume_from = from;
|
||||
infof(data, "FTP RANGE from %d getting %d bytes\n", from, data->maxdownload);
|
||||
}
|
||||
infof(data, "range-download from %d to %d, totally %d bytes\n",
|
||||
from, to, totalsize);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if(!ppath[0])
|
||||
/* make sure this becomes a valid name */
|
||||
ppath="./";
|
||||
|
||||
if((data->conf & CONF_FTPLISTONLY) ||
|
||||
('/' == ppath[strlen(ppath)-1] )) {
|
||||
#endif
|
||||
if((data->bits.ftp_list_only) || !ftp->file) {
|
||||
/* The specified path ends with a slash, and therefore we think this
|
||||
is a directory that is requested, use LIST. But before that we
|
||||
need to set ASCII transfer mode. */
|
||||
@ -826,30 +936,29 @@ UrgError _ftp(struct UrlData *data,
|
||||
|
||||
if(strncmp(buf, "200", 3)) {
|
||||
failf(data, "Couldn't set ascii mode");
|
||||
return URG_FTP_COULDNT_SET_ASCII;
|
||||
return CURLE_FTP_COULDNT_SET_ASCII;
|
||||
}
|
||||
|
||||
/* if this output is to be machine-parsed, the NLST command will be
|
||||
better used since the LIST command output is not specified or
|
||||
standard in any way */
|
||||
|
||||
sendf(data->firstsocket, data, "%s %s\r\n",
|
||||
sendf(data->firstsocket, data, "%s\r\n",
|
||||
data->customrequest?data->customrequest:
|
||||
(data->conf&CONF_FTPLISTONLY?"NLST":"LIST"),
|
||||
ppath);
|
||||
(data->bits.ftp_list_only?"NLST":"LIST"));
|
||||
}
|
||||
else {
|
||||
/* Set type to binary (unless specified ASCII) */
|
||||
sendf(data->firstsocket, data, "TYPE %s\r\n",
|
||||
(data->conf&CONF_FTPASCII)?"A":"I");
|
||||
(data->bits.ftp_list_only)?"A":"I");
|
||||
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
|
||||
if(strncmp(buf, "200", 3)) {
|
||||
failf(data, "Couldn't set %s mode",
|
||||
(data->conf&CONF_FTPASCII)?"ASCII":"binary");
|
||||
return (data->conf&CONF_FTPASCII)? URG_FTP_COULDNT_SET_ASCII:
|
||||
URG_FTP_COULDNT_SET_BINARY;
|
||||
(data->bits.ftp_ascii)?"ASCII":"binary");
|
||||
return (data->bits.ftp_ascii)? CURLE_FTP_COULDNT_SET_ASCII:
|
||||
CURLE_FTP_COULDNT_SET_BINARY;
|
||||
}
|
||||
|
||||
if(data->resume_from) {
|
||||
@ -860,7 +969,7 @@ UrgError _ftp(struct UrlData *data,
|
||||
* of the file we're gonna get. If we can get the size, this is by far
|
||||
* the best way to know if we're trying to resume beyond the EOF. */
|
||||
|
||||
sendf(data->firstsocket, data, "SIZE %s\r\n", ppath);
|
||||
sendf(data->firstsocket, data, "SIZE %s\r\n", ftp->file);
|
||||
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
|
||||
@ -875,13 +984,27 @@ UrgError _ftp(struct UrlData *data,
|
||||
int foundsize=atoi(buf+4);
|
||||
/* We got a file size report, so we check that there actually is a
|
||||
part of the file left to get, or else we go home. */
|
||||
if(foundsize <= data->resume_from) {
|
||||
failf(data, "Offset (%d) was beyond file size (%d)",
|
||||
data->resume_from, foundsize);
|
||||
return URG_FTP_BAD_DOWNLOAD_RESUME;
|
||||
if(data->resume_from< 0) {
|
||||
/* We're supposed to download the last abs(from) bytes */
|
||||
if(foundsize < -data->resume_from) {
|
||||
failf(data, "Offset (%d) was beyond file size (%d)",
|
||||
data->resume_from, foundsize);
|
||||
return CURLE_FTP_BAD_DOWNLOAD_RESUME;
|
||||
}
|
||||
/* convert to size to download */
|
||||
downloadsize = -data->resume_from;
|
||||
/* download from where? */
|
||||
data->resume_from = foundsize - downloadsize;
|
||||
}
|
||||
else {
|
||||
if(foundsize <= data->resume_from) {
|
||||
failf(data, "Offset (%d) was beyond file size (%d)",
|
||||
data->resume_from, foundsize);
|
||||
return CURLE_FTP_BAD_DOWNLOAD_RESUME;
|
||||
}
|
||||
/* Now store the number of bytes we are expected to download */
|
||||
downloadsize = foundsize-data->resume_from;
|
||||
}
|
||||
/* Now store the number of bytes we are expected to download */
|
||||
downloadsize = foundsize-data->resume_from;
|
||||
}
|
||||
|
||||
/* Set resume file transfer offset */
|
||||
@ -894,11 +1017,11 @@ UrgError _ftp(struct UrlData *data,
|
||||
|
||||
if(strncmp(buf, "350", 3)) {
|
||||
failf(data, "Couldn't use REST: %s", buf+4);
|
||||
return URG_FTP_COULDNT_USE_REST;
|
||||
return CURLE_FTP_COULDNT_USE_REST;
|
||||
}
|
||||
}
|
||||
|
||||
sendf(data->firstsocket, data, "RETR %s\r\n", ppath);
|
||||
sendf(data->firstsocket, data, "RETR %s\r\n", ftp->file);
|
||||
}
|
||||
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
@ -968,12 +1091,12 @@ UrgError _ftp(struct UrlData *data,
|
||||
if(size <= 0) {
|
||||
failf(data, "Offset (%d) was beyond file size (%d)",
|
||||
data->resume_from, data->resume_from+size);
|
||||
return URG_PARTIAL_FILE;
|
||||
return CURLE_PARTIAL_FILE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(data->conf & CONF_FTPPORT) {
|
||||
if(data->bits.ftp_use_port) {
|
||||
result = AllowServerConnect(data, portsock);
|
||||
if( result )
|
||||
return result;
|
||||
@ -982,95 +1105,74 @@ UrgError _ftp(struct UrlData *data,
|
||||
infof(data, "Getting file with size: %d\n", size);
|
||||
|
||||
/* FTP download: */
|
||||
result=Transfer(data, data->secondarysocket, size, FALSE,
|
||||
result=Transfer(conn, data->secondarysocket, size, FALSE,
|
||||
bytecountp,
|
||||
-1, NULL); /* no upload here */
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if((-1 != size) && (size != *bytecountp)) {
|
||||
failf(data, "Received only partial file");
|
||||
return URG_PARTIAL_FILE;
|
||||
}
|
||||
else if(0 == *bytecountp) {
|
||||
failf(data, "No data was received!");
|
||||
return URG_FTP_COULDNT_RETR_FILE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
failf(data, "%s", buf+4);
|
||||
return URG_FTP_COULDNT_RETR_FILE;
|
||||
return CURLE_FTP_COULDNT_RETR_FILE;
|
||||
}
|
||||
|
||||
}
|
||||
/* end of transfer */
|
||||
#if 0
|
||||
ProgressEnd(data);
|
||||
#endif
|
||||
pgrsDone(data);
|
||||
|
||||
/* shut down the socket to inform the server we're done */
|
||||
sclose(data->secondarysocket);
|
||||
data->secondarysocket = -1;
|
||||
|
||||
/* now let's see what the server says about the transfer we
|
||||
just performed: */
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
|
||||
/* 226 Transfer complete */
|
||||
if(strncmp(buf, "226", 3)) {
|
||||
failf(data, "%s", buf+4);
|
||||
return URG_FTP_WRITE_ERROR;
|
||||
}
|
||||
|
||||
/* Send any post-transfer QUOTE strings? */
|
||||
if(data->postquote) {
|
||||
qitem = data->postquote;
|
||||
/* Send all QUOTE strings in same order as on command-line */
|
||||
while (qitem) {
|
||||
/* Send string */
|
||||
if (qitem->data) {
|
||||
sendf(data->firstsocket, data, "%s\r\n", qitem->data);
|
||||
|
||||
nread = GetLastResponse(data->firstsocket, buf, data);
|
||||
|
||||
if (buf[0] != '2') {
|
||||
failf(data, "QUOT string not accepted: %s",
|
||||
qitem->data);
|
||||
return URG_FTP_QUOTE_ERROR;
|
||||
}
|
||||
}
|
||||
qitem = qitem->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return URG_OK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* -- deal with the ftp server! -- */
|
||||
|
||||
UrgError ftp(struct UrlData *data,
|
||||
long *bytecountp,
|
||||
char *ftpuser,
|
||||
char *ftppasswd,
|
||||
char *urlpath)
|
||||
/* argument is already checked for validity */
|
||||
CURLcode ftp(struct connectdata *conn)
|
||||
{
|
||||
char *realpath;
|
||||
UrgError retcode;
|
||||
CURLcode retcode;
|
||||
|
||||
#if 0
|
||||
realpath = URLfix(urlpath);
|
||||
#else
|
||||
realpath = curl_unescape(urlpath);
|
||||
#endif
|
||||
if(realpath) {
|
||||
retcode = _ftp(data, bytecountp, ftpuser, ftppasswd, realpath);
|
||||
free(realpath);
|
||||
struct UrlData *data = conn->data;
|
||||
struct FTP *ftp;
|
||||
int dirlength=0; /* 0 forces strlen() */
|
||||
|
||||
/* the ftp struct is already inited in ftp_connect() */
|
||||
ftp = data->proto.ftp;
|
||||
|
||||
/* We split the path into dir and file parts *before* we URLdecode
|
||||
it */
|
||||
ftp->file = strrchr(conn->ppath, '/');
|
||||
if(ftp->file) {
|
||||
ftp->file++; /* point to the first letter in the file name part or
|
||||
remain NULL */
|
||||
}
|
||||
else {
|
||||
ftp->file = conn->ppath; /* there's only a file part */
|
||||
}
|
||||
dirlength=ftp->file-conn->ppath;
|
||||
|
||||
if(*ftp->file) {
|
||||
ftp->file = curl_unescape(ftp->file, 0);
|
||||
if(NULL == ftp->file) {
|
||||
failf(data, "no memory");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* then we try the original path */
|
||||
retcode = _ftp(data, bytecountp, ftpuser, ftppasswd, urlpath);
|
||||
ftp->file=NULL; /* instead of point to a zero byte, we make it a NULL
|
||||
pointer */
|
||||
|
||||
ftp->urlpath = conn->ppath;
|
||||
if(dirlength) {
|
||||
ftp->dir = curl_unescape(ftp->urlpath, dirlength);
|
||||
if(NULL == ftp->dir) {
|
||||
if(ftp->file)
|
||||
free(ftp->file);
|
||||
failf(data, "no memory");
|
||||
return CURLE_OUT_OF_MEMORY; /* failure */
|
||||
}
|
||||
}
|
||||
else
|
||||
ftp->dir = NULL;
|
||||
|
||||
retcode = _ftp(conn);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
@ -40,11 +40,9 @@
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
****************************************************************************/
|
||||
UrgError ftp(struct UrlData *data,
|
||||
long *bytecountp,
|
||||
char *ftpuser,
|
||||
char *ftppasswd,
|
||||
char *ppath);
|
||||
CURLcode ftp(struct connectdata *conn);
|
||||
CURLcode ftp_done(struct connectdata *conn);
|
||||
CURLcode ftp_connect(struct connectdata *conn);
|
||||
|
||||
struct curl_slist *curl_slist_append(struct curl_slist *list, char *data);
|
||||
void curl_slist_free_all(struct curl_slist *list);
|
||||
|
@ -1864,7 +1864,7 @@ difftm (struct tm *a, struct tm *b)
|
||||
}
|
||||
|
||||
time_t
|
||||
get_date (const char *p, const time_t *now)
|
||||
curl_getdate (const char *p, const time_t *now)
|
||||
{
|
||||
struct tm tm, tm0, *tmp;
|
||||
time_t Start;
|
||||
@ -1998,7 +1998,7 @@ main (ac, av)
|
||||
buff[MAX_BUFF_LEN] = 0;
|
||||
while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
|
||||
{
|
||||
d = get_date (buff, (time_t *) NULL);
|
||||
d = curl_getdate (buff, (time_t *) NULL);
|
||||
if (d == -1)
|
||||
(void) printf ("Bad format - couldn't convert.\n");
|
||||
else
|
||||
|
@ -1,18 +1,11 @@
|
||||
/* Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
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 the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*
|
||||
** Originally written by Steven M. Bellovin <smb@research.att.com> while
|
||||
** at the University of North Carolina at Chapel Hill. Later tweaked by
|
||||
** a couple of people on Usenet. Completely overhauled by Rich $alz
|
||||
** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
|
||||
**
|
||||
** This code is in the public domain and has no copyright.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
@ -43,4 +36,4 @@
|
||||
# endif
|
||||
#endif /* defined (vms) */
|
||||
|
||||
time_t get_date PARAMS ((const char *p, const time_t *now));
|
||||
time_t curl_getdate PARAMS ((const char *p, const time_t *now));
|
||||
|
@ -914,7 +914,7 @@ difftm (struct tm *a, struct tm *b)
|
||||
}
|
||||
|
||||
time_t
|
||||
get_date (const char *p, const time_t *now)
|
||||
curl_getdate (const char *p, const time_t *now)
|
||||
{
|
||||
struct tm tm, tm0, *tmp;
|
||||
time_t Start;
|
||||
@ -1048,7 +1048,7 @@ main (ac, av)
|
||||
buff[MAX_BUFF_LEN] = 0;
|
||||
while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
|
||||
{
|
||||
d = get_date (buff, (time_t *) NULL);
|
||||
d = curl_getdate (buff, (time_t *) NULL);
|
||||
if (d == -1)
|
||||
(void) printf ("Bad format - couldn't convert.\n");
|
||||
else
|
||||
|
30
lib/getenv.c
30
lib/getenv.c
@ -22,18 +22,6 @@
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rafael Sagula <sagula@inf.ufrgs.br>
|
||||
* Sampo Kellomaki <sampo@iki.fi>
|
||||
* Linas Vepstas <linas@linas.org>
|
||||
* Bjorn Reese <breese@imada.ou.dk>
|
||||
* Johan Anderson <johan@homemail.com>
|
||||
* Kjell Ericson <Kjell.Ericson@haxx.nu>
|
||||
* Troy Engel <tengel@palladium.net>
|
||||
* Ryan Nelson <ryan@inch.com>
|
||||
* Bjorn Stenberg <Bjorn.Stenberg@haxx.nu>
|
||||
* Angus Mackay <amackay@gus.ml.org>
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
* Main author:
|
||||
* - Daniel Stenberg <Daniel.Stenberg@haxx.nu>
|
||||
@ -47,24 +35,6 @@
|
||||
* $State$
|
||||
* $Locker$
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
* $Log$
|
||||
* Revision 1.2 2000-01-10 23:36:14 bagder
|
||||
* syncing with local edit
|
||||
*
|
||||
* Revision 1.4 1999/09/06 06:59:40 dast
|
||||
* Changed email info
|
||||
*
|
||||
* Revision 1.3 1999/08/13 07:34:48 dast
|
||||
* Changed the URL in the header
|
||||
*
|
||||
* Revision 1.2 1999/03/13 00:56:09 dast
|
||||
* Big changes done due to url.c being split up in X smaller files and that
|
||||
* the lib is now more stand-alone.
|
||||
*
|
||||
* Revision 1.1.1.1 1999/03/11 22:23:34 dast
|
||||
* Imported sources
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
240
lib/http.c
240
lib/http.c
@ -94,6 +94,9 @@
|
||||
#include "progress.h"
|
||||
#include "base64.h"
|
||||
#include "cookie.h"
|
||||
#include "strequal.h"
|
||||
#include "url.h"
|
||||
#include "ssluse.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@ -115,33 +118,114 @@ bool static checkheaders(struct UrlData *data, char *thisheader)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UrgError http(struct UrlData *data, char *ppath, char *host, long *bytecount)
|
||||
CURLcode http_connect(struct connectdata *conn)
|
||||
{
|
||||
/* Send the GET line to the HTTP server */
|
||||
struct UrlData *data;
|
||||
|
||||
struct FormData *sendit=NULL;
|
||||
int postsize=0;
|
||||
UrgError result;
|
||||
char *buf;
|
||||
struct Cookie *co = NULL;
|
||||
char *p_pragma = NULL;
|
||||
char *p_accept = NULL;
|
||||
long readbytecount;
|
||||
long writebytecount;
|
||||
data=conn->data;
|
||||
|
||||
buf = data->buffer; /* this is our buffer */
|
||||
/* If we are not using a proxy and we want a secure connection,
|
||||
* perform SSL initialization & connection now.
|
||||
* If using a proxy with https, then we must tell the proxy to CONNECT
|
||||
* us to the host we want to talk to. Only after the connect
|
||||
* has occured, can we start talking SSL
|
||||
*/
|
||||
if (conn->protocol & PROT_HTTPS) {
|
||||
if (data->bits.httpproxy) {
|
||||
|
||||
if ( (data->conf&(CONF_HTTP|CONF_FTP)) &&
|
||||
(data->conf&CONF_UPLOAD)) {
|
||||
data->conf |= CONF_PUT;
|
||||
/* OK, now send the connect statment */
|
||||
sendf(data->firstsocket, data,
|
||||
"CONNECT %s:%d HTTP/1.0\015\012"
|
||||
"%s"
|
||||
"%s"
|
||||
"\r\n",
|
||||
data->hostname, data->remote_port,
|
||||
(data->bits.proxy_user_passwd)?data->ptr_proxyuserpwd:"",
|
||||
(data->useragent?data->ptr_uagent:"")
|
||||
);
|
||||
|
||||
/* wait for the proxy to send us a HTTP/1.0 200 OK header */
|
||||
/* Daniel rewrote this part Nov 5 1998 to make it more obvious */
|
||||
{
|
||||
int httperror=0;
|
||||
int subversion=0;
|
||||
while(GetLine(data->firstsocket, data->buffer, data)) {
|
||||
if('\r' == data->buffer[0])
|
||||
break; /* end of headers */
|
||||
if(2 == sscanf(data->buffer, "HTTP/1.%d %d",
|
||||
&subversion,
|
||||
&httperror)) {
|
||||
;
|
||||
}
|
||||
}
|
||||
if(200 != httperror) {
|
||||
if(407 == httperror)
|
||||
/* Added Nov 6 1998 */
|
||||
failf(data, "Proxy requires authorization!");
|
||||
else
|
||||
failf(data, "Received error code %d from proxy", httperror);
|
||||
return CURLE_READ_ERROR;
|
||||
}
|
||||
}
|
||||
infof (data, "Proxy has replied to CONNECT request\n");
|
||||
}
|
||||
|
||||
/* now, perform the SSL initialization for this socket */
|
||||
if(UrgSSLConnect (data)) {
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
#if 0 /* old version */
|
||||
if((data->conf&(CONF_HTTP|CONF_UPLOAD)) ==
|
||||
(CONF_HTTP|CONF_UPLOAD)) {
|
||||
/* enable PUT! */
|
||||
data->conf |= CONF_PUT;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
CURLcode http_done(struct connectdata *conn)
|
||||
{
|
||||
struct UrlData *data;
|
||||
long *bytecount = &conn->bytecount;
|
||||
struct HTTP *http;
|
||||
|
||||
data=conn->data;
|
||||
http=data->proto.http;
|
||||
|
||||
if(data->bits.http_formpost) {
|
||||
*bytecount = http->readbytecount + http->writebytecount;
|
||||
|
||||
FormFree(http->sendit); /* Now free that whole lot */
|
||||
|
||||
data->fread = http->storefread; /* restore */
|
||||
data->in = http->in; /* restore */
|
||||
}
|
||||
else if(data->bits.http_put) {
|
||||
*bytecount = http->readbytecount + http->writebytecount;
|
||||
}
|
||||
|
||||
/* TBD: the HTTP struct remains allocated here */
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
CURLcode http(struct connectdata *conn)
|
||||
{
|
||||
struct UrlData *data=conn->data;
|
||||
char *buf = data->buffer; /* this is a short cut to the buffer */
|
||||
CURLcode result;
|
||||
struct HTTP *http;
|
||||
struct Cookie *co=NULL; /* no cookies from start */
|
||||
char *ppath = conn->ppath; /* three previous function arguments */
|
||||
char *host = conn->name;
|
||||
long *bytecount = &conn->bytecount;
|
||||
|
||||
http = (struct HTTP *)malloc(sizeof(struct HTTP));
|
||||
if(!http)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
memset(http, 0, sizeof(struct HTTP));
|
||||
data->proto.http = http;
|
||||
|
||||
if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) &&
|
||||
data->bits.upload) {
|
||||
data->bits.http_put=1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The User-Agent string has been built in url.c already, because it might
|
||||
have been used in the proxy connect, but if we have got a header with
|
||||
@ -152,17 +236,17 @@ UrgError http(struct UrlData *data, char *ppath, char *host, long *bytecount)
|
||||
data->ptr_uagent=NULL;
|
||||
}
|
||||
|
||||
if((data->conf & CONF_USERPWD) && !checkheaders(data, "Authorization:")) {
|
||||
if((data->bits.user_passwd) && !checkheaders(data, "Authorization:")) {
|
||||
char authorization[512];
|
||||
sprintf(data->buffer, "%s:%s", data->user, data->passwd);
|
||||
base64Encode(data->buffer, authorization);
|
||||
data->ptr_userpwd = maprintf( "Authorization: Basic %s\015\012",
|
||||
authorization);
|
||||
}
|
||||
if((data->conf & CONF_RANGE) && !checkheaders(data, "Range:")) {
|
||||
if((data->bits.set_range) && !checkheaders(data, "Range:")) {
|
||||
data->ptr_rangeline = maprintf("Range: bytes=%s\015\012", data->range);
|
||||
}
|
||||
if((data->conf & CONF_REFERER) && !checkheaders(data, "Referer:")) {
|
||||
if((data->bits.http_set_referer) && !checkheaders(data, "Referer:")) {
|
||||
data->ptr_ref = maprintf("Referer: %s\015\012", data->referer);
|
||||
}
|
||||
if(data->cookie && !checkheaders(data, "Cookie:")) {
|
||||
@ -173,16 +257,16 @@ UrgError http(struct UrlData *data, char *ppath, char *host, long *bytecount)
|
||||
co = cookie_getlist(data->cookies,
|
||||
host,
|
||||
ppath,
|
||||
data->conf&CONF_HTTPS?TRUE:FALSE);
|
||||
conn->protocol&PROT_HTTPS?TRUE:FALSE);
|
||||
}
|
||||
if ((data->conf & CONF_PROXY) && (!(data->conf & CONF_HTTPS))) {
|
||||
if ((data->bits.httpproxy) && !(conn->protocol&PROT_HTTPS)) {
|
||||
/* The path sent to the proxy is in fact the entire URL */
|
||||
strncpy(ppath, data->url, URL_MAX_LENGTH-1);
|
||||
}
|
||||
if(data->conf & CONF_HTTPPOST) {
|
||||
if(data->bits.http_formpost) {
|
||||
/* we must build the whole darned post sequence first, so that we have
|
||||
a size of the whole shebang before we start to send it */
|
||||
sendit = getFormData(data->httppost, &postsize);
|
||||
http->sendit = getFormData(data->httppost, &http->postsize);
|
||||
}
|
||||
|
||||
if(!checkheaders(data, "Host:"))
|
||||
@ -190,10 +274,10 @@ UrgError http(struct UrlData *data, char *ppath, char *host, long *bytecount)
|
||||
|
||||
|
||||
if(!checkheaders(data, "Pragma:"))
|
||||
p_pragma = "Pragma: no-cache\r\n";
|
||||
http->p_pragma = "Pragma: no-cache\r\n";
|
||||
|
||||
if(!checkheaders(data, "Accept:"))
|
||||
p_accept = "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n";
|
||||
http->p_accept = "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n";
|
||||
|
||||
do {
|
||||
sendf(data->firstsocket, data,
|
||||
@ -210,19 +294,19 @@ UrgError http(struct UrlData *data, char *ppath, char *host, long *bytecount)
|
||||
"%s", /* referer */
|
||||
|
||||
data->customrequest?data->customrequest:
|
||||
(data->conf&CONF_NOBODY?"HEAD":
|
||||
(data->conf&(CONF_POST|CONF_HTTPPOST))?"POST":
|
||||
(data->conf&CONF_PUT)?"PUT":"GET"),
|
||||
(data->bits.no_body?"HEAD":
|
||||
(data->bits.http_post || data->bits.http_formpost)?"POST":
|
||||
(data->bits.http_put)?"PUT":"GET"),
|
||||
ppath,
|
||||
(data->conf&CONF_PROXYUSERPWD && data->ptr_proxyuserpwd)?data->ptr_proxyuserpwd:"",
|
||||
(data->conf&CONF_USERPWD && data->ptr_userpwd)?data->ptr_userpwd:"",
|
||||
(data->conf&CONF_RANGE && data->ptr_rangeline)?data->ptr_rangeline:"",
|
||||
(data->bits.proxy_user_passwd && data->ptr_proxyuserpwd)?data->ptr_proxyuserpwd:"",
|
||||
(data->bits.user_passwd && data->ptr_userpwd)?data->ptr_userpwd:"",
|
||||
(data->bits.set_range && data->ptr_rangeline)?data->ptr_rangeline:"",
|
||||
(data->useragent && *data->useragent && data->ptr_uagent)?data->ptr_uagent:"",
|
||||
(data->ptr_cookie?data->ptr_cookie:""), /* Cookie: <data> */
|
||||
(data->ptr_host?data->ptr_host:""), /* Host: host */
|
||||
p_pragma?p_pragma:"",
|
||||
p_accept?p_accept:"",
|
||||
(data->conf&CONF_REFERER && data->ptr_ref)?data->ptr_ref:"" /* Referer: <data> <CRLF> */
|
||||
http->p_pragma?http->p_pragma:"",
|
||||
http->p_accept?http->p_accept:"",
|
||||
(data->bits.http_set_referer && data->ptr_ref)?data->ptr_ref:"" /* Referer: <data> <CRLF> */
|
||||
);
|
||||
|
||||
if(co) {
|
||||
@ -234,9 +318,10 @@ UrgError http(struct UrlData *data, char *ppath, char *host, long *bytecount)
|
||||
sendf(data->firstsocket, data,
|
||||
"Cookie:");
|
||||
}
|
||||
count++;
|
||||
sendf(data->firstsocket, data,
|
||||
" %s=%s;", co->name, co->value);
|
||||
"%s%s=%s", count?"; ":"", co->name,
|
||||
co->value);
|
||||
count++;
|
||||
}
|
||||
co = co->next; /* next cookie please */
|
||||
}
|
||||
@ -284,8 +369,8 @@ UrgError http(struct UrlData *data, char *ppath, char *host, long *bytecount)
|
||||
data->headers = data->headers->next;
|
||||
}
|
||||
|
||||
if(data->conf&(CONF_POST|CONF_HTTPPOST)) {
|
||||
if(data->conf & CONF_POST) {
|
||||
if(data->bits.http_post || data->bits.http_formpost) {
|
||||
if(data->bits.http_post) {
|
||||
/* this is the simple x-www-form-urlencoded style */
|
||||
sendf(data->firstsocket, data,
|
||||
"Content-Length: %d\015\012"
|
||||
@ -295,53 +380,39 @@ UrgError http(struct UrlData *data, char *ppath, char *host, long *bytecount)
|
||||
data->postfields );
|
||||
}
|
||||
else {
|
||||
struct Form form;
|
||||
size_t (*storefread)(char *, size_t , size_t , FILE *);
|
||||
FILE *in;
|
||||
long conf;
|
||||
|
||||
if(FormInit(&form, sendit)) {
|
||||
if(FormInit(&http->form, http->sendit)) {
|
||||
failf(data, "Internal HTTP POST error!\n");
|
||||
return URG_HTTP_POST_ERROR;
|
||||
return CURLE_HTTP_POST_ERROR;
|
||||
}
|
||||
|
||||
storefread = data->fread; /* backup */
|
||||
in = data->in; /* backup */
|
||||
http->storefread = data->fread; /* backup */
|
||||
http->in = data->in; /* backup */
|
||||
|
||||
data->fread =
|
||||
(size_t (*)(char *, size_t, size_t, FILE *))
|
||||
FormReader; /* set the read function to read from the
|
||||
generated form data */
|
||||
data->in = (FILE *)&form;
|
||||
data->in = (FILE *)&http->form;
|
||||
|
||||
sendf(data->firstsocket, data,
|
||||
"Content-Length: %d\r\n",
|
||||
postsize-2);
|
||||
http->postsize-2);
|
||||
|
||||
pgrsSetUploadSize(data, postsize);
|
||||
#if 0
|
||||
ProgressInit(data, postsize);
|
||||
#endif
|
||||
pgrsSetUploadSize(data, http->postsize);
|
||||
|
||||
result = Transfer(data, data->firstsocket, -1, TRUE, &readbytecount,
|
||||
data->firstsocket, &writebytecount);
|
||||
*bytecount = readbytecount + writebytecount;
|
||||
|
||||
FormFree(sendit); /* Now free that whole lot */
|
||||
|
||||
if(result)
|
||||
result = Transfer(conn, data->firstsocket, -1, TRUE,
|
||||
&http->readbytecount,
|
||||
data->firstsocket,
|
||||
&http->writebytecount);
|
||||
if(result) {
|
||||
FormFree(http->sendit); /* free that whole lot */
|
||||
return result;
|
||||
|
||||
data->fread = storefread; /* restore */
|
||||
data->in = in; /* restore */
|
||||
|
||||
sendf(data->firstsocket, data,
|
||||
"\r\n\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(data->conf&CONF_PUT) {
|
||||
else if(data->bits.http_put) {
|
||||
/* Let's PUT the data to the server! */
|
||||
long conf;
|
||||
|
||||
if(data->infilesize>0) {
|
||||
sendf(data->firstsocket, data,
|
||||
@ -352,39 +423,28 @@ UrgError http(struct UrlData *data, char *ppath, char *host, long *bytecount)
|
||||
sendf(data->firstsocket, data,
|
||||
"\015\012");
|
||||
|
||||
#if 0
|
||||
ProgressInit(data, data->infilesize);
|
||||
#endif
|
||||
pgrsSetUploadSize(data, data->infilesize);
|
||||
|
||||
result = Transfer(data, data->firstsocket, -1, TRUE, &readbytecount,
|
||||
data->firstsocket, &writebytecount);
|
||||
|
||||
*bytecount = readbytecount + writebytecount;
|
||||
|
||||
result = Transfer(conn, data->firstsocket, -1, TRUE,
|
||||
&http->readbytecount,
|
||||
data->firstsocket,
|
||||
&http->writebytecount);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
}
|
||||
else {
|
||||
sendf(data->firstsocket, data, "\r\n");
|
||||
}
|
||||
if(0 == *bytecount) {
|
||||
|
||||
/* HTTP GET/HEAD download: */
|
||||
result = Transfer(data, data->firstsocket, -1, TRUE, bytecount,
|
||||
result = Transfer(conn, data->firstsocket, -1, TRUE, bytecount,
|
||||
-1, NULL); /* nothing to upload */
|
||||
}
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
#if 0
|
||||
ProgressEnd(data);
|
||||
#endif
|
||||
pgrsDone(data);
|
||||
|
||||
} while (0); /* this is just a left-over from the multiple document download
|
||||
attempts */
|
||||
|
||||
return URG_OK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,9 @@
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
****************************************************************************/
|
||||
UrgError http(struct UrlData *data, char *path, char *host, long *bytecountp);
|
||||
|
||||
CURLcode http(struct connectdata *conn);
|
||||
CURLcode http_done(struct connectdata *conn);
|
||||
CURLcode http_connect(struct connectdata *conn);
|
||||
|
||||
#endif
|
||||
|
36
lib/ldap.c
36
lib/ldap.c
@ -72,7 +72,7 @@
|
||||
#define DYNA_GET_FUNCTION(type, fnc) \
|
||||
(fnc) = (type)DynaGetFunction(#fnc); \
|
||||
if ((fnc) == NULL) { \
|
||||
return URG_FUNCTION_NOT_FOUND; \
|
||||
return CURLE_FUNCTION_NOT_FOUND; \
|
||||
} \
|
||||
|
||||
/***********************************************************************
|
||||
@ -130,15 +130,20 @@ static int WriteProc(void *param, char *text, int len)
|
||||
{
|
||||
struct UrlData *data = (struct UrlData *)param;
|
||||
|
||||
printf("%s\n", text);
|
||||
data->fwrite(text, 1, strlen(text), data->out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CURLcode ldap_done(struct connectdata *conn)
|
||||
{
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
UrgError ldap(struct UrlData *data, char *path, long *bytecount)
|
||||
CURLcode ldap(struct connectdata *conn)
|
||||
{
|
||||
UrgError status = URG_OK;
|
||||
CURLcode status = CURLE_OK;
|
||||
int rc;
|
||||
void *(*ldap_open)(char *, int);
|
||||
int (*ldap_simple_bind_s)(void *, char *, char *);
|
||||
@ -152,24 +157,19 @@ UrgError ldap(struct UrlData *data, char *path, long *bytecount)
|
||||
void *server;
|
||||
void *result;
|
||||
void *entryIterator;
|
||||
#if 0
|
||||
char *dn;
|
||||
char **attrArray;
|
||||
char *attrIterator;
|
||||
char *attrString;
|
||||
void *dummy;
|
||||
#endif
|
||||
|
||||
int ldaptext;
|
||||
struct UrlData *data=conn->data;
|
||||
|
||||
infof(data, "LDAP: %s %s\n", data->url);
|
||||
|
||||
DynaOpen();
|
||||
if (libldap == NULL) {
|
||||
failf(data, "The needed LDAP library/libraries couldn't be opened");
|
||||
return URG_LIBRARY_NOT_FOUND;
|
||||
return CURLE_LIBRARY_NOT_FOUND;
|
||||
}
|
||||
|
||||
ldaptext = data->conf & CONF_FTPASCII; /* This is a dirty hack */
|
||||
ldaptext = data->bits.ftp_ascii; /* This is a dirty hack */
|
||||
|
||||
/* The types are needed because ANSI C distinguishes between
|
||||
* pointer-to-object (data) and pointer-to-function.
|
||||
@ -188,17 +188,17 @@ UrgError ldap(struct UrlData *data, char *path, long *bytecount)
|
||||
if (server == NULL) {
|
||||
failf(data, "LDAP: Cannot connect to %s:%d",
|
||||
data->hostname, data->port);
|
||||
status = URG_COULDNT_CONNECT;
|
||||
status = CURLE_COULDNT_CONNECT;
|
||||
} else {
|
||||
rc = ldap_simple_bind_s(server, data->user, data->passwd);
|
||||
if (rc != 0) {
|
||||
failf(data, "LDAP: %s", ldap_err2string(rc));
|
||||
status = URG_LDAP_CANNOT_BIND;
|
||||
status = CURLE_LDAP_CANNOT_BIND;
|
||||
} else {
|
||||
rc = ldap_url_search_s(server, data->url, 0, &result);
|
||||
if (rc != 0) {
|
||||
failf(data, "LDAP: %s", ldap_err2string(rc));
|
||||
status = URG_LDAP_SEARCH_FAILED;
|
||||
status = CURLE_LDAP_SEARCH_FAILED;
|
||||
} else {
|
||||
for (entryIterator = ldap_first_entry(server, result);
|
||||
entryIterator;
|
||||
@ -210,7 +210,7 @@ UrgError ldap(struct UrlData *data, char *path, long *bytecount)
|
||||
"", 0, 0);
|
||||
if (rc != 0) {
|
||||
failf(data, "LDAP: %s", ldap_err2string(rc));
|
||||
status = URG_LDAP_SEARCH_FAILED;
|
||||
status = CURLE_LDAP_SEARCH_FAILED;
|
||||
}
|
||||
} else {
|
||||
rc = ldap_entry2html(server, NULL, entryIterator, NULL,
|
||||
@ -218,7 +218,7 @@ UrgError ldap(struct UrlData *data, char *path, long *bytecount)
|
||||
"", 0, 0, NULL, NULL);
|
||||
if (rc != 0) {
|
||||
failf(data, "LDAP: %s", ldap_err2string(rc));
|
||||
status = URG_LDAP_SEARCH_FAILED;
|
||||
status = CURLE_LDAP_SEARCH_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
****************************************************************************/
|
||||
UrgError ldap(struct UrlData *data, char *path, long *bytecount);
|
||||
CURLcode ldap(struct connectdata *conn);
|
||||
CURLcode ldap_done(struct connectdata *conn);
|
||||
|
||||
#endif /* __LDAP_H */
|
||||
|
@ -56,6 +56,7 @@
|
||||
|
||||
#include "setup.h"
|
||||
#include "getenv.h"
|
||||
#include "strequal.h"
|
||||
|
||||
/* Debug this single source file with:
|
||||
'make netrc' then run './netrc'!
|
||||
|
223
lib/progress.c
223
lib/progress.c
@ -118,7 +118,7 @@ void pgrsDone(struct UrlData *data)
|
||||
void pgrsMode(struct UrlData *data, int mode)
|
||||
{
|
||||
/* mode should include a hidden mode as well */
|
||||
if(data->conf&(CONF_NOPROGRESS|CONF_MUTE))
|
||||
if(data->bits.hide_progress || data->bits.mute)
|
||||
data->progress.flags |= PGRS_HIDE; /* don't show anything */
|
||||
else {
|
||||
data->progress.mode = mode; /* store type */
|
||||
@ -187,10 +187,36 @@ void pgrsSetUploadSize(struct UrlData *data, double size)
|
||||
|
||||
*/
|
||||
|
||||
void pgrsUpdate(struct UrlData *data)
|
||||
int pgrsUpdate(struct UrlData *data)
|
||||
{
|
||||
struct timeval now;
|
||||
|
||||
char max5[6][6];
|
||||
double dlpercen=0;
|
||||
double ulpercen=0;
|
||||
double total_percen=0;
|
||||
|
||||
double total_transfer;
|
||||
double total_expected_transfer;
|
||||
|
||||
#define CURR_TIME 5
|
||||
|
||||
static double speeder[ CURR_TIME ];
|
||||
static int speeder_c=0;
|
||||
|
||||
int nowindex = speeder_c% CURR_TIME;
|
||||
int checkindex;
|
||||
int count;
|
||||
|
||||
char time_left[10];
|
||||
char time_total[10];
|
||||
char time_current[10];
|
||||
|
||||
double ulestimate=0;
|
||||
double dlestimate=0;
|
||||
|
||||
double total_estimate;
|
||||
|
||||
if(data->progress.flags & PGRS_HIDE)
|
||||
; /* We do enter this function even if we don't wanna see anything, since
|
||||
this is were lots of the calculations are being made that will be used
|
||||
@ -206,133 +232,109 @@ void pgrsUpdate(struct UrlData *data)
|
||||
|
||||
now = tvnow(); /* what time is it */
|
||||
|
||||
switch(data->progress.mode) {
|
||||
case CURL_PROGRESS_STATS:
|
||||
default:
|
||||
{
|
||||
char max5[6][6];
|
||||
double dlpercen=0;
|
||||
double ulpercen=0;
|
||||
double total_percen=0;
|
||||
if(data->progress.lastshow == tvlong(now))
|
||||
return 0; /* never update this more than once a second if the end isn't
|
||||
reached */
|
||||
data->progress.lastshow = now.tv_sec;
|
||||
|
||||
double total_transfer;
|
||||
double total_expected_transfer;
|
||||
/* The exact time spent so far */
|
||||
data->progress.timespent = tvdiff (now, data->progress.start);
|
||||
|
||||
#define CURR_TIME 5
|
||||
/* The average download speed this far */
|
||||
data->progress.dlspeed = data->progress.downloaded/(data->progress.timespent!=0.0?data->progress.timespent:1.0);
|
||||
|
||||
static double speeder[ CURR_TIME ];
|
||||
static int speeder_c=0;
|
||||
/* The average upload speed this far */
|
||||
data->progress.ulspeed = data->progress.uploaded/(data->progress.timespent!=0.0?data->progress.timespent:1.0);
|
||||
|
||||
int nowindex = speeder_c% CURR_TIME;
|
||||
int checkindex;
|
||||
int count;
|
||||
|
||||
char time_left[10];
|
||||
char time_total[10];
|
||||
char time_current[10];
|
||||
|
||||
double ulestimate=0;
|
||||
double dlestimate=0;
|
||||
|
||||
double total_estimate;
|
||||
|
||||
if(data->progress.lastshow == tvlong(now))
|
||||
return; /* never update this more than once a second if the end isn't
|
||||
reached */
|
||||
data->progress.lastshow = now.tv_sec;
|
||||
|
||||
/* The exact time spent so far */
|
||||
data->progress.timespent = tvdiff (now, data->progress.start);
|
||||
|
||||
/* The average download speed this far */
|
||||
data->progress.dlspeed = data->progress.downloaded/(data->progress.timespent!=0.0?data->progress.timespent:1.0);
|
||||
|
||||
/* The average upload speed this far */
|
||||
data->progress.ulspeed = data->progress.uploaded/(data->progress.timespent!=0.0?data->progress.timespent:1.0);
|
||||
|
||||
/* Let's do the "current speed" thing, which should use the fastest
|
||||
/* Let's do the "current speed" thing, which should use the fastest
|
||||
of the dl/ul speeds */
|
||||
|
||||
speeder[ nowindex ] = data->progress.downloaded>data->progress.uploaded?
|
||||
data->progress.downloaded:data->progress.uploaded;
|
||||
speeder_c++; /* increase */
|
||||
count = ((speeder_c>=CURR_TIME)?CURR_TIME:speeder_c) - 1;
|
||||
checkindex = (speeder_c>=CURR_TIME)?speeder_c%CURR_TIME:0;
|
||||
speeder[ nowindex ] = data->progress.downloaded>data->progress.uploaded?
|
||||
data->progress.downloaded:data->progress.uploaded;
|
||||
speeder_c++; /* increase */
|
||||
count = ((speeder_c>=CURR_TIME)?CURR_TIME:speeder_c) - 1;
|
||||
checkindex = (speeder_c>=CURR_TIME)?speeder_c%CURR_TIME:0;
|
||||
|
||||
/* find out the average speed the last CURR_TIME seconds */
|
||||
data->progress.current_speed =
|
||||
(speeder[nowindex]-speeder[checkindex])/(count?count:1);
|
||||
/* find out the average speed the last CURR_TIME seconds */
|
||||
data->progress.current_speed =
|
||||
(speeder[nowindex]-speeder[checkindex])/(count?count:1);
|
||||
|
||||
if(data->progress.flags & PGRS_HIDE)
|
||||
return;
|
||||
if(data->progress.flags & PGRS_HIDE)
|
||||
return 0;
|
||||
else if(data->fprogress) {
|
||||
return data->fprogress(data->progress_client,
|
||||
data->progress.size_dl,
|
||||
data->progress.downloaded,
|
||||
data->progress.size_ul,
|
||||
data->progress.uploaded);
|
||||
}
|
||||
|
||||
/* Figure out the estimated time of arrival for the upload */
|
||||
if(data->progress.flags & PGRS_UL_SIZE_KNOWN) {
|
||||
if(!data->progress.ulspeed)
|
||||
data->progress.ulspeed=1;
|
||||
ulestimate = data->progress.size_ul / data->progress.ulspeed;
|
||||
ulpercen = (data->progress.uploaded / data->progress.size_ul)*100;
|
||||
}
|
||||
if(data->progress.flags & PGRS_UL_SIZE_KNOWN) {
|
||||
if(!data->progress.ulspeed)
|
||||
data->progress.ulspeed=1;
|
||||
ulestimate = data->progress.size_ul / data->progress.ulspeed;
|
||||
ulpercen = (data->progress.uploaded / data->progress.size_ul)*100;
|
||||
}
|
||||
|
||||
/* ... and the download */
|
||||
if(data->progress.flags & PGRS_DL_SIZE_KNOWN) {
|
||||
if(!data->progress.dlspeed)
|
||||
data->progress.dlspeed=1;
|
||||
dlestimate = data->progress.size_dl / data->progress.dlspeed;
|
||||
dlpercen = (data->progress.downloaded / data->progress.size_dl)*100;
|
||||
}
|
||||
/* ... and the download */
|
||||
if(data->progress.flags & PGRS_DL_SIZE_KNOWN) {
|
||||
if(!data->progress.dlspeed)
|
||||
data->progress.dlspeed=1;
|
||||
dlestimate = data->progress.size_dl / data->progress.dlspeed;
|
||||
dlpercen = (data->progress.downloaded / data->progress.size_dl)*100;
|
||||
}
|
||||
|
||||
/* Now figure out which of them that is slower and use for the for
|
||||
/* Now figure out which of them that is slower and use for the for
|
||||
total estimate! */
|
||||
total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
|
||||
total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
|
||||
|
||||
/* If we have a total estimate, we can display that and the expected
|
||||
/* If we have a total estimate, we can display that and the expected
|
||||
time left */
|
||||
if(total_estimate) {
|
||||
time2str(time_left, total_estimate-(int) data->progress.timespent);
|
||||
time2str(time_total, total_estimate);
|
||||
}
|
||||
else {
|
||||
/* otherwise we blank those times */
|
||||
strcpy(time_left, "--:--:--");
|
||||
strcpy(time_total, "--:--:--");
|
||||
}
|
||||
/* The time spent so far is always known */
|
||||
time2str(time_current, data->progress.timespent);
|
||||
if(total_estimate) {
|
||||
time2str(time_left, total_estimate-(int) data->progress.timespent);
|
||||
time2str(time_total, total_estimate);
|
||||
}
|
||||
else {
|
||||
/* otherwise we blank those times */
|
||||
strcpy(time_left, "--:--:--");
|
||||
strcpy(time_total, "--:--:--");
|
||||
}
|
||||
/* The time spent so far is always known */
|
||||
time2str(time_current, data->progress.timespent);
|
||||
|
||||
/* Get the total amount of data expected to get transfered */
|
||||
total_expected_transfer =
|
||||
(data->progress.flags & PGRS_UL_SIZE_KNOWN?
|
||||
data->progress.size_ul:data->progress.uploaded)+
|
||||
(data->progress.flags & PGRS_DL_SIZE_KNOWN?
|
||||
data->progress.size_dl:data->progress.downloaded);
|
||||
/* Get the total amount of data expected to get transfered */
|
||||
total_expected_transfer =
|
||||
(data->progress.flags & PGRS_UL_SIZE_KNOWN?
|
||||
data->progress.size_ul:data->progress.uploaded)+
|
||||
(data->progress.flags & PGRS_DL_SIZE_KNOWN?
|
||||
data->progress.size_dl:data->progress.downloaded);
|
||||
|
||||
/* We have transfered this much so far */
|
||||
total_transfer = data->progress.downloaded + data->progress.uploaded;
|
||||
/* We have transfered this much so far */
|
||||
total_transfer = data->progress.downloaded + data->progress.uploaded;
|
||||
|
||||
/* Get the percentage of data transfered so far */
|
||||
if(total_expected_transfer)
|
||||
total_percen=(double)(total_transfer/total_expected_transfer)*100;
|
||||
/* Get the percentage of data transfered so far */
|
||||
if(total_expected_transfer)
|
||||
total_percen=(double)(total_transfer/total_expected_transfer)*100;
|
||||
|
||||
fprintf(stderr,
|
||||
"\r%3d %s %3d %s %3d %s %s %s %s %s %s %s",
|
||||
(int)total_percen, /* total % */
|
||||
max5data(total_expected_transfer, max5[2]), /* total size */
|
||||
(int)dlpercen, /* rcvd % */
|
||||
max5data(data->progress.downloaded, max5[0]), /* rcvd size */
|
||||
(int)ulpercen, /* xfer % */
|
||||
max5data(data->progress.uploaded, max5[1]), /* xfer size */
|
||||
|
||||
max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */
|
||||
max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */
|
||||
time_total, /* total time */
|
||||
time_current, /* current time */
|
||||
time_left, /* time left */
|
||||
max5data(data->progress.current_speed, max5[5]) /* current speed */
|
||||
);
|
||||
|
||||
|
||||
fprintf(stderr,
|
||||
"\r%3d %s %3d %s %3d %s %s %s %s %s %s %s",
|
||||
(int)total_percen, /* total % */
|
||||
max5data(total_expected_transfer, max5[2]), /* total size */
|
||||
(int)dlpercen, /* rcvd % */
|
||||
max5data(data->progress.downloaded, max5[0]), /* rcvd size */
|
||||
(int)ulpercen, /* xfer % */
|
||||
max5data(data->progress.uploaded, max5[1]), /* xfer size */
|
||||
|
||||
max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */
|
||||
max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */
|
||||
time_total, /* total time */
|
||||
time_current, /* current time */
|
||||
time_left, /* time left */
|
||||
max5data(data->progress.current_speed, max5[5]) /* current speed */
|
||||
);
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
case CURL_PROGRESS_BAR:
|
||||
/* original progress bar code by Lars Aas */
|
||||
@ -365,7 +367,8 @@ void pgrsUpdate(struct UrlData *data)
|
||||
prev = point;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,13 +52,14 @@ typedef enum {
|
||||
TIMER_LAST /* must be last */
|
||||
} timerid;
|
||||
|
||||
void pgrsDone(struct UrlData *data);
|
||||
void pgrsMode(struct UrlData *data, int mode);
|
||||
void pgrsStartNow(struct UrlData *data);
|
||||
void pgrsSetDownloadSize(struct UrlData *data, double size);
|
||||
void pgrsSetUploadSize(struct UrlData *data, double size);
|
||||
void pgrsSetDownloadCounter(struct UrlData *data, double size);
|
||||
void pgrsSetUploadCounter(struct UrlData *data, double size);
|
||||
void pgrsUpdate(struct UrlData *data);
|
||||
void pgrsSetUploadCounter(struct UrlData *data, double size);
|
||||
int pgrsUpdate(struct UrlData *data);
|
||||
void pgrsTime(struct UrlData *data, timerid timer);
|
||||
|
||||
|
||||
|
@ -61,7 +61,7 @@
|
||||
void infof(struct UrlData *data, char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
if(data->conf & CONF_VERBOSE) {
|
||||
if(data->bits.verbose) {
|
||||
va_start(ap, fmt);
|
||||
fputs("* ", data->err);
|
||||
vfprintf(data->err, fmt, ap);
|
||||
@ -95,7 +95,7 @@ int sendf(int fd, struct UrlData *data, char *fmt, ...)
|
||||
va_end(ap);
|
||||
if(!s)
|
||||
return 0; /* failure */
|
||||
if(data->conf & CONF_VERBOSE)
|
||||
if(data->bits.verbose)
|
||||
fprintf(data->err, "> %s", s);
|
||||
#ifndef USE_SSLEAY
|
||||
bytes_written = swrite(fd, s, strlen(s));
|
||||
|
@ -57,8 +57,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef OS
|
||||
#ifdef WIN32
|
||||
#define OS "win32"
|
||||
@ -99,6 +97,7 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#ifdef HAVE_STRCASECMP
|
||||
#define strnequal(x,y,z) !(strncasecmp)(x,y,z)
|
||||
#define strequal(x,y) !(strcasecmp)(x,y)
|
||||
@ -107,6 +106,7 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
|
||||
#define strnequal(x,y,z) !strnicmp(x,y,z)
|
||||
#define strequal(x,y) !stricmp(x,y)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Below we define four functions. They should
|
||||
1. close a socket
|
||||
|
@ -48,7 +48,7 @@
|
||||
#include "sendf.h"
|
||||
#include "speedcheck.h"
|
||||
|
||||
UrgError speedcheck(struct UrlData *data,
|
||||
CURLcode speedcheck(struct UrlData *data,
|
||||
struct timeval now)
|
||||
{
|
||||
static struct timeval keeps_speed;
|
||||
@ -69,13 +69,13 @@ UrgError speedcheck(struct UrlData *data,
|
||||
"Less than %d bytes/sec transfered the last %d seconds",
|
||||
data->low_speed_limit,
|
||||
data->low_speed_time);
|
||||
return URG_OPERATION_TIMEOUTED;
|
||||
return CURLE_OPERATION_TIMEOUTED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* we keep up the required speed all right */
|
||||
keeps_speed = now;
|
||||
}
|
||||
return URG_OK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@
|
||||
|
||||
#include "timeval.h"
|
||||
|
||||
UrgError speedcheck(struct UrlData *data,
|
||||
CURLcode speedcheck(struct UrlData *data,
|
||||
struct timeval now);
|
||||
|
||||
#endif
|
||||
|
@ -38,6 +38,12 @@
|
||||
* ------------------------------------------------------------
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* The original SSL code was written by
|
||||
* Linas Vepstas <linas@linas.org> and Sampo Kellomaki <sampo@iki.fi>
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
36
lib/telnet.c
36
lib/telnet.c
@ -225,7 +225,7 @@ static void printoption(struct UrlData *data,
|
||||
char *fmt;
|
||||
char *opt;
|
||||
|
||||
if (data->conf & CONF_VERBOSE)
|
||||
if (data->bits.verbose)
|
||||
{
|
||||
if (cmd == IAC)
|
||||
{
|
||||
@ -628,7 +628,7 @@ static void printsub(struct UrlData *data,
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (data->conf & CONF_VERBOSE)
|
||||
if (data->bits.verbose)
|
||||
{
|
||||
if (direction)
|
||||
{
|
||||
@ -871,23 +871,29 @@ void telwrite(struct UrlData *data,
|
||||
}
|
||||
}
|
||||
|
||||
UrgError telnet(struct UrlData *data)
|
||||
CURLcode telnet_done(struct connectdata *conn)
|
||||
{
|
||||
int sockfd = data->firstsocket;
|
||||
fd_set readfd;
|
||||
fd_set keepfd;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
bool keepon = TRUE;
|
||||
char *buf = data->buffer;
|
||||
int nread;
|
||||
CURLcode telnet(struct connectdata *conn)
|
||||
{
|
||||
struct UrlData *data = conn->data;
|
||||
int sockfd = data->firstsocket;
|
||||
fd_set readfd;
|
||||
fd_set keepfd;
|
||||
|
||||
init_telnet(data);
|
||||
bool keepon = TRUE;
|
||||
char *buf = data->buffer;
|
||||
int nread;
|
||||
|
||||
FD_ZERO (&readfd); /* clear it */
|
||||
FD_SET (sockfd, &readfd);
|
||||
FD_SET (1, &readfd);
|
||||
init_telnet(data);
|
||||
|
||||
keepfd = readfd;
|
||||
FD_ZERO (&readfd); /* clear it */
|
||||
FD_SET (sockfd, &readfd);
|
||||
FD_SET (1, &readfd);
|
||||
|
||||
keepfd = readfd;
|
||||
|
||||
while (keepon)
|
||||
{
|
||||
@ -931,7 +937,7 @@ UrgError telnet(struct UrlData *data)
|
||||
telrcv(data, (unsigned char *)buf, nread);
|
||||
}
|
||||
}
|
||||
return URG_OK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
****************************************************************************/
|
||||
UrgError telnet(struct UrlData *data);
|
||||
CURLcode telnet(struct connectdata *conn);
|
||||
CURLcode telnet_done(struct connectdata *conn);
|
||||
|
||||
#endif
|
||||
|
44
lib/url.h
44
lib/url.h
@ -0,0 +1,44 @@
|
||||
#ifndef __URL_H
|
||||
#define __URL_H
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Curl.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Daniel Stenberg.
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
* Main author:
|
||||
* - Daniel Stenberg <Daniel.Stenberg@haxx.nu>
|
||||
*
|
||||
* http://curl.haxx.nu
|
||||
*
|
||||
* $Source$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
* $Author$
|
||||
* $State$
|
||||
* $Locker$
|
||||
*
|
||||
* ------------------------------------------------------------
|
||||
****************************************************************************/
|
||||
int GetLine(int sockfd, char *buf, struct UrlData *data);
|
||||
|
||||
#endif
|
235
lib/urldata.h
235
lib/urldata.h
@ -67,6 +67,7 @@
|
||||
#define CURL_DEFAULT_PASSWORD "curl_by_Daniel.Stenberg@haxx.nu"
|
||||
|
||||
#include "cookie.h"
|
||||
#include "formdata.h"
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
/* SSLeay stuff usually in /usr/local/ssl/include */
|
||||
@ -87,8 +88,12 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "timeval.h"
|
||||
|
||||
|
||||
|
||||
/* Download buffer size, keep it fairly big for speed reasons */
|
||||
#define BUFSIZE (1024*50)
|
||||
|
||||
@ -96,6 +101,88 @@
|
||||
of need. */
|
||||
#define HEADERSIZE 256
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(x,y) ((x)>(y)?(x):(y))
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
STRUCT_NONE,
|
||||
STRUCT_OPEN,
|
||||
STRUCT_CONNECT,
|
||||
STRUCT_LAST
|
||||
} Handle;
|
||||
|
||||
typedef enum {
|
||||
CONN_NONE, /* illegal state */
|
||||
CONN_INIT, /* curl_connect() has been called */
|
||||
CONN_DO, /* curl_do() has been called successfully */
|
||||
CONN_DONE, /* curl_done() has been called successfully */
|
||||
CONN_ERROR, /* and error has occurred */
|
||||
CONN_LAST /* illegal state */
|
||||
} ConnState;
|
||||
|
||||
|
||||
/*
|
||||
* The connectdata struct contains all fields and variables that should be
|
||||
* unique for an entire connection.
|
||||
*/
|
||||
struct connectdata {
|
||||
/**** Fields set when inited and not modified again */
|
||||
|
||||
/* To better see what kind of struct that is passed as input, *ALL* publicly
|
||||
returned handles MUST have this initial 'Handle'. */
|
||||
Handle handle; /* struct identifier */
|
||||
struct UrlData *data; /* link to the root CURL struct */
|
||||
|
||||
/**** curl_connect() phase fields */
|
||||
ConnState state; /* for state dependent actions */
|
||||
|
||||
long protocol; /* PROT_* flags concerning the protocol set */
|
||||
#define PROT_MISSING (1<<0)
|
||||
#define PROT_GOPHER (1<<1)
|
||||
#define PROT_HTTP (1<<2)
|
||||
#define PROT_HTTPS (1<<3)
|
||||
#define PROT_FTP (1<<4)
|
||||
#define PROT_TELNET (1<<5)
|
||||
#define PROT_DICT (1<<6)
|
||||
#define PROT_LDAP (1<<7)
|
||||
#define PROT_FILE (1<<8)
|
||||
|
||||
struct hostent *hp;
|
||||
struct sockaddr_in serv_addr;
|
||||
char proto[64];
|
||||
char gname[256];
|
||||
char *name;
|
||||
char path[URL_MAX_LENGTH];
|
||||
char *ppath;
|
||||
long bytecount;
|
||||
struct timeval now;
|
||||
|
||||
/* These two functions MUST be set by the curl_connect() function to be
|
||||
be protocol dependent */
|
||||
CURLcode (*curl_do)(struct connectdata *connect);
|
||||
CURLcode (*curl_done)(struct connectdata *connect);
|
||||
|
||||
/* This function *MAY* be set to a protocol-dependent function that is run
|
||||
* after the connect() and everything is done, as a step in the connection.
|
||||
*/
|
||||
CURLcode (*curl_connect)(struct connectdata *connect);
|
||||
|
||||
/**** curl_get() phase fields */
|
||||
|
||||
/* READ stuff */
|
||||
int sockfd; /* socket to read from or -1 */
|
||||
int size; /* -1 if unknown at this point */
|
||||
bool getheader; /* TRUE if header parsing is wanted */
|
||||
long *bytecountp; /* return number of bytes read or NULL */
|
||||
|
||||
/* WRITE stuff */
|
||||
int writesockfd; /* socket to write to, it may very well be
|
||||
the same we read from. -1 disables */
|
||||
long *writebytecountp; /* return number of bytes written or NULL */
|
||||
|
||||
};
|
||||
|
||||
struct Progress {
|
||||
long lastshow; /* time() of the last displayed progress meter or NULL to
|
||||
force redraw at next call */
|
||||
@ -121,42 +208,160 @@ struct Progress {
|
||||
int httpcode;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* HTTP unique setup
|
||||
***************************************************************************/
|
||||
struct HTTP {
|
||||
struct FormData *sendit;
|
||||
int postsize;
|
||||
char *p_pragma;
|
||||
char *p_accept;
|
||||
long readbytecount;
|
||||
long writebytecount;
|
||||
|
||||
/* For FORM posting */
|
||||
struct Form form;
|
||||
size_t (*storefread)(char *, size_t , size_t , FILE *);
|
||||
FILE *in;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* FTP unique setup
|
||||
***************************************************************************/
|
||||
struct FTP {
|
||||
long *bytecountp;
|
||||
char *user;
|
||||
char *passwd;
|
||||
char *urlpath; /* the originally given path part of the URL */
|
||||
char *dir; /* decoded directory */
|
||||
char *file; /* decoded file */
|
||||
};
|
||||
|
||||
struct Configbits {
|
||||
bool ftp_append;
|
||||
bool ftp_ascii;
|
||||
bool http_post;
|
||||
bool http_set_referer;
|
||||
bool http_fail_on_error;
|
||||
bool http_formpost;
|
||||
bool http_include_header;
|
||||
bool http_follow_location;
|
||||
bool http_put;
|
||||
bool no_body;
|
||||
bool ftp_list_only;
|
||||
bool use_netrc;
|
||||
bool ftp_use_port;
|
||||
bool set_port;
|
||||
bool set_range;
|
||||
bool mute;
|
||||
bool hide_progress;
|
||||
bool upload;
|
||||
bool user_passwd;
|
||||
bool proxy_user_passwd;
|
||||
bool verbose;
|
||||
bool httpproxy;
|
||||
};
|
||||
|
||||
typedef size_t (*progress_callback)(void *clientp,
|
||||
size_t dltotal,
|
||||
size_t dlnow,
|
||||
size_t ultotal,
|
||||
size_t ulnow);
|
||||
|
||||
typedef size_t (*write_callback)(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
FILE *outstream);
|
||||
|
||||
typedef size_t (*read_callback)(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
FILE *instream);
|
||||
|
||||
/* What type of interface that intiated this struct */
|
||||
typedef enum {
|
||||
CURLI_NONE,
|
||||
CURLI_EASY,
|
||||
CURLI_NORMAL,
|
||||
CURLI_LAST
|
||||
} CurlInterface;
|
||||
|
||||
/*
|
||||
* As of April 11, 2000 we're now trying to split up the urldata struct in
|
||||
* three different parts:
|
||||
*
|
||||
* (Global)
|
||||
* 1 - No matter how many hosts and requests that are being performed, this
|
||||
* goes for all of them.
|
||||
*
|
||||
* (Session)
|
||||
* 2 - Host and protocol-specific. No matter if we do several transfers to and
|
||||
* from this host, these variables stay the same.
|
||||
*
|
||||
* (Request)
|
||||
* 3 - Request-specific. Variables that are of interest for this particular
|
||||
* transfer being made right now.
|
||||
*
|
||||
*/
|
||||
|
||||
struct UrlData {
|
||||
Handle handle; /* struct identifier */
|
||||
CurlInterface interface;
|
||||
|
||||
/*************** Global - specific items ************/
|
||||
FILE *err; /* the stderr writes goes here */
|
||||
char *errorbuffer; /* store failure messages in here */
|
||||
|
||||
/*************** Session - specific items ************/
|
||||
char *proxy; /* if proxy, set it here, set CONF_PROXY to use this */
|
||||
char *proxyuserpwd; /* Proxy <user:password>, if used */
|
||||
|
||||
/*************** Request - specific items ************/
|
||||
|
||||
union {
|
||||
struct HTTP *http;
|
||||
struct HTTP *gopher; /* alias, just for the sake of being more readable */
|
||||
struct HTTP *https; /* alias, just for the sake of being more readable */
|
||||
struct FTP *ftp;
|
||||
#if 0 /* no need for special ones for these: */
|
||||
struct TELNET *telnet;
|
||||
struct FILE *file;
|
||||
struct LDAP *ldap;
|
||||
struct DICT *dict;
|
||||
#endif
|
||||
void *generic;
|
||||
} proto;
|
||||
|
||||
FILE *out; /* the fetched file goes here */
|
||||
FILE *in; /* the uploaded file is read from here */
|
||||
FILE *err; /* the stderr writes goes here */
|
||||
FILE *writeheader; /* write the header to this is non-NULL */
|
||||
char *url; /* what to get */
|
||||
char *freethis; /* if non-NULL, an allocated string for the URL */
|
||||
char *hostname; /* hostname to contect, as parsed from url */
|
||||
char *hostname; /* hostname to connect, as parsed from url */
|
||||
unsigned short port; /* which port to use (if non-protocol bind) set
|
||||
CONF_PORT to use this */
|
||||
unsigned short remote_port; /* what remote port to connect to, not the proxy
|
||||
port! */
|
||||
char *proxy; /* if proxy, set it here, set CONF_PROXY to use this */
|
||||
long conf; /* configure flags */
|
||||
struct Configbits bits; /* new-style (v7) flag data */
|
||||
|
||||
char *userpwd; /* <user:password>, if used */
|
||||
char *proxyuserpwd; /* Proxy <user:password>, if used */
|
||||
char *range; /* range, if used. See README for detailed specification on
|
||||
this syntax. */
|
||||
char *postfields; /* if POST, set the fields' values here */
|
||||
char *referer;
|
||||
char *errorbuffer; /* store failure messages in here */
|
||||
char *useragent; /* User-Agent string */
|
||||
|
||||
char *ftpport; /* port to send with the PORT command */
|
||||
|
||||
/* function that stores the output:*/
|
||||
size_t (*fwrite)(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
FILE *outstream);
|
||||
/* function that stores the output:*/
|
||||
write_callback fwrite;
|
||||
|
||||
/* function that reads the input:*/
|
||||
size_t (*fread)(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
FILE *outstream);
|
||||
read_callback fread;
|
||||
|
||||
/* function that wants progress information */
|
||||
progress_callback fprogress;
|
||||
void *progress_client; /* pointer to pass to the progress callback */
|
||||
|
||||
long timeout; /* in seconds, 0 means no timeout */
|
||||
long infilesize; /* size of file to upload, -1 means unknown */
|
||||
|
@ -58,7 +58,7 @@ char *curl_version(void)
|
||||
#ifdef USE_SSLEAY
|
||||
|
||||
#if (SSLEAY_VERSION_NUMBER >= 0x900000)
|
||||
sprintf(ptr, " (SSL %x.%x.%x)",
|
||||
sprintf(ptr, " (SSL %lx.%lx.%lx)",
|
||||
(SSLEAY_VERSION_NUMBER>>28)&0xff,
|
||||
(SSLEAY_VERSION_NUMBER>>20)&0xff,
|
||||
(SSLEAY_VERSION_NUMBER>>12)&0xf);
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "strequal.h"
|
||||
#include "writeout.h"
|
||||
|
||||
typedef enum {
|
||||
|
@ -1,3 +1,5 @@
|
||||
#ifndef __WRITEOUT_H
|
||||
#define __WRITEOUT_H
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@ -41,3 +43,5 @@
|
||||
#include "urldata.h"
|
||||
|
||||
void WriteOut(struct UrlData *data);
|
||||
|
||||
#endif
|
||||
|
13
maketgz
13
maketgz
@ -7,15 +7,24 @@ read version
|
||||
|
||||
libversion="$version"
|
||||
|
||||
#
|
||||
# Now we have a section to get the major, minor and patch number from the
|
||||
# full version string. We create a single hexadecimal number from it '0xMMmmpp'
|
||||
#
|
||||
perl='$a=<STDIN>;@p=split("\\.",$a);for(0..2){printf STDOUT ("%02x",$p[0+$_]);}';
|
||||
|
||||
numeric=`echo $libversion | perl -e "$perl"`
|
||||
|
||||
echo "CURL version number?"
|
||||
read curlversion
|
||||
|
||||
HEADER=include/curl/curl.h
|
||||
CHEADER=src/version.h
|
||||
|
||||
|
||||
# Replace version number in header file:
|
||||
sed 's/#define LIBCURL_VERSION.*/#define LIBCURL_VERSION "'$libversion'"/g' $HEADER >$HEADER.new
|
||||
sed -e 's/^#define LIBCURL_VERSION .*/#define LIBCURL_VERSION "'$libversion'"/g' \
|
||||
-e 's/^#define LIBCURL_VERSION_NUM .*/#define LIBCURL_VERSION_NUM 0x'$numeric'/g' \
|
||||
$HEADER >$HEADER.new
|
||||
|
||||
# Save old header file
|
||||
cp -p $HEADER $HEADER.old
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
# Some flags needed when trying to cause warnings ;-)
|
||||
# CFLAGS = -Wall -pedantic
|
||||
CPPFLAGS = -DGLOBURL -DCURL_SEPARATORS
|
||||
#CPPFLAGS = -DGLOBURL -DCURL_SEPARATORS
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
|
||||
|
@ -2,6 +2,9 @@
|
||||
/* Define if you have the strcasecmp function. */
|
||||
/*#define HAVE_STRCASECMP 1*/
|
||||
|
||||
/* Define if you have the stricmp function. */
|
||||
#define HAVE_STRICMP 1
|
||||
|
||||
/* Define cpu-machine-OS */
|
||||
#define OS "win32"
|
||||
|
||||
|
1290
src/hugehelp.c
1290
src/hugehelp.c
File diff suppressed because it is too large
Load Diff
253
src/main.c
253
src/main.c
@ -46,6 +46,8 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h> /* new for v7 */
|
||||
#include <curl/easy.h> /* new for v7 */
|
||||
#include <curl/mprintf.h>
|
||||
#include "../lib/getdate.h"
|
||||
|
||||
@ -71,6 +73,25 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* Just a set of bits */
|
||||
#define CONF_DEFAULT 0
|
||||
#define CONF_VERBOSE (1<<5) /* talk a lot */
|
||||
#define CONF_HEADER (1<<8) /* throw the header out too */
|
||||
#define CONF_NOPROGRESS (1<<10) /* shut off the progress meter */
|
||||
#define CONF_NOBODY (1<<11) /* use HEAD to get http document */
|
||||
#define CONF_FAILONERROR (1<<12) /* no output on http error codes >= 300 */
|
||||
#define CONF_UPLOAD (1<<14) /* this is an upload */
|
||||
#define CONF_POST (1<<15) /* HTTP POST method */
|
||||
#define CONF_FTPLISTONLY (1<<16) /* Use NLST when listing ftp dir */
|
||||
#define CONF_FTPAPPEND (1<<20) /* Append instead of overwrite on upload! */
|
||||
#define CONF_NETRC (1<<22) /* read user+password from .netrc */
|
||||
#define CONF_FOLLOWLOCATION (1<<23) /* use Location: Luke! */
|
||||
#define CONF_FTPASCII (1<<24) /* use TYPE A for transfer */
|
||||
#define CONF_HTTPPOST (1<<25) /* multipart/form-data HTTP POST */
|
||||
#define CONF_PUT (1<<27) /* PUT the input file */
|
||||
#define CONF_MUTE (1<<28) /* force NOPROGRESS */
|
||||
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
/* Ultrix doesn't have strdup(), so make a quick clone: */
|
||||
char *strdup(char *str)
|
||||
@ -113,7 +134,7 @@ static UrgError win32_init(void)
|
||||
if (err != 0)
|
||||
/* Tell the user that we couldn't find a useable */
|
||||
/* winsock.dll. */
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
/* Confirm that the Windows Sockets DLL supports 1.1.*/
|
||||
/* Note that if the DLL supports versions greater */
|
||||
@ -127,13 +148,13 @@ static UrgError win32_init(void)
|
||||
|
||||
/* winsock.dll. */
|
||||
WSACleanup();
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
return URG_OK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
/* The Windows Sockets DLL is acceptable. Proceed. */
|
||||
#else
|
||||
static UrgError win32_init(void) { return URG_OK; }
|
||||
static CURLcode win32_init(void) { return CURLE_OK; }
|
||||
#define win32_cleanup()
|
||||
#endif
|
||||
|
||||
@ -143,7 +164,7 @@ static UrgError win32_init(void) { return URG_OK; }
|
||||
* _any_ libcurl usage. If this fails, *NO* libcurl functions may be
|
||||
* used, or havoc may be the result.
|
||||
*/
|
||||
UrgError main_init(void)
|
||||
CURLcode main_init(void)
|
||||
{
|
||||
return win32_init();
|
||||
}
|
||||
@ -297,7 +318,10 @@ static void GetStr(char **string,
|
||||
{
|
||||
if(*string)
|
||||
free(*string);
|
||||
*string = strdup(value);
|
||||
if(value && *value)
|
||||
*string = strdup(value);
|
||||
else
|
||||
*string = NULL;
|
||||
}
|
||||
|
||||
static char *file2string(FILE *file)
|
||||
@ -420,7 +444,7 @@ static int getparameter(char *flag, /* f or -long-flag */
|
||||
if(parse) {
|
||||
/* this is the second match, we can't continue! */
|
||||
helpf("option --%s is ambiguous\n", &flag[1]);
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
parse = aliases[j].letter;
|
||||
hit = j;
|
||||
@ -428,7 +452,7 @@ static int getparameter(char *flag, /* f or -long-flag */
|
||||
}
|
||||
if(hit < 0) {
|
||||
helpf("unknown option -%s.\n", flag);
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -454,18 +478,18 @@ static int getparameter(char *flag, /* f or -long-flag */
|
||||
}
|
||||
if(hit < 0) {
|
||||
helpf("unknown option -%c.\n", letter);
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
}
|
||||
if(hit < 0) {
|
||||
helpf("unknown option -%c.\n", letter);
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
if(!nextarg && aliases[hit].extraparam) {
|
||||
helpf("option -%s/--%s requires an extra argument!\n",
|
||||
aliases[hit].letter,
|
||||
aliases[hit].lname);
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
else if(nextarg && aliases[hit].extraparam)
|
||||
*usedarg = TRUE; /* mark it as used */
|
||||
@ -491,7 +515,7 @@ static int getparameter(char *flag, /* f or -long-flag */
|
||||
break;
|
||||
}
|
||||
now=time(NULL);
|
||||
config->condtime=get_date(nextarg, &now);
|
||||
config->condtime=curl_getdate(nextarg, &now);
|
||||
if(-1 == config->condtime) {
|
||||
/* now let's see if it is a file name to get the time from instead! */
|
||||
struct stat statbuf;
|
||||
@ -586,7 +610,6 @@ static int getparameter(char *flag, /* f or -long-flag */
|
||||
break;
|
||||
case 'e':
|
||||
GetStr(&config->referer, nextarg);
|
||||
config->conf |= CONF_REFERER;
|
||||
break;
|
||||
case 'E':
|
||||
{
|
||||
@ -610,13 +633,12 @@ static int getparameter(char *flag, /* f or -long-flag */
|
||||
if(curl_FormParse(nextarg,
|
||||
&config->httppost,
|
||||
&config->last_post))
|
||||
return URG_FAILED_INIT;
|
||||
config->conf |= CONF_HTTPPOST; /* no toggle, OR! */
|
||||
return CURLE_FAILED_INIT;
|
||||
break;
|
||||
|
||||
case 'h': /* h for help */
|
||||
help();
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
case 'H':
|
||||
head = (struct HttpHeader *)malloc(sizeof(struct HttpHeader));
|
||||
if(head) {
|
||||
@ -659,7 +681,7 @@ static int getparameter(char *flag, /* f or -long-flag */
|
||||
break;
|
||||
case 'M': /* M for manual, huge help */
|
||||
hugehelp();
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
case 'n':
|
||||
/* pick info from .netrc, if this is used for http, curl will
|
||||
automatically enfore user+password with the request */
|
||||
@ -683,7 +705,6 @@ static int getparameter(char *flag, /* f or -long-flag */
|
||||
this will make us try to get the "default" address.
|
||||
NOTE: this is a changed behaviour since the released 4.1!
|
||||
*/
|
||||
config->conf |= CONF_FTPPORT;
|
||||
GetStr(&config->ftpport, nextarg);
|
||||
break;
|
||||
#if 0
|
||||
@ -712,7 +733,6 @@ static int getparameter(char *flag, /* f or -long-flag */
|
||||
case 'r':
|
||||
/* byte range requested */
|
||||
GetStr(&config->range, nextarg);
|
||||
config->conf |= CONF_RANGE;
|
||||
break;
|
||||
case 's':
|
||||
/* don't show progress meter, don't show errors : */
|
||||
@ -735,19 +755,17 @@ static int getparameter(char *flag, /* f or -long-flag */
|
||||
case 'u':
|
||||
/* user:password */
|
||||
GetStr(&config->userpwd, nextarg);
|
||||
config->conf |= CONF_USERPWD;
|
||||
break;
|
||||
case 'U':
|
||||
/* Proxy user:password */
|
||||
GetStr(&config->proxyuserpwd, nextarg);
|
||||
config->conf |= CONF_PROXYUSERPWD;
|
||||
break;
|
||||
case 'v':
|
||||
config->conf ^= CONF_VERBOSE; /* talk a lot */
|
||||
break;
|
||||
case 'V':
|
||||
printf(CURL_ID "%s\n", curl_version());
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
case 'w':
|
||||
/* get the output string */
|
||||
if('@' == *nextarg) {
|
||||
@ -768,14 +786,7 @@ static int getparameter(char *flag, /* f or -long-flag */
|
||||
break;
|
||||
case 'x':
|
||||
/* proxy */
|
||||
if(!*nextarg) {
|
||||
/* disable proxy when no proxy is given */
|
||||
config->conf &= ~CONF_PROXY;
|
||||
}
|
||||
else {
|
||||
config->conf |= CONF_PROXY;
|
||||
GetStr(&config->proxy, nextarg);
|
||||
}
|
||||
GetStr(&config->proxy, nextarg);
|
||||
break;
|
||||
case 'X':
|
||||
/* HTTP request */
|
||||
@ -799,13 +810,13 @@ static int getparameter(char *flag, /* f or -long-flag */
|
||||
helpf("Unknown option '%c'\n", letter);
|
||||
else
|
||||
helpf("Unknown option\n"); /* short help blurb */
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
hit = -1;
|
||||
|
||||
} while(*++parse && !*usedarg);
|
||||
|
||||
return URG_OK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -826,7 +837,7 @@ static int parseconfig(char *filename,
|
||||
char *home = curl_GetEnv("HOME"); /* portable environment reader */
|
||||
|
||||
if(!home || (strlen(home)>(sizeof(filebuffer)-strlen(CURLRC))))
|
||||
return URG_OK;
|
||||
return CURLE_OK;
|
||||
|
||||
sprintf(filebuffer, "%s%s%s", home, DIR_CHAR, CURLRC);
|
||||
|
||||
@ -894,7 +905,7 @@ static int parseconfig(char *filename,
|
||||
if(file != stdin)
|
||||
fclose(file);
|
||||
}
|
||||
return URG_OK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
struct OutStruct {
|
||||
@ -944,7 +955,8 @@ int main(int argc, char *argv[])
|
||||
int infilesize=-1; /* -1 means unknown */
|
||||
bool stillflags=TRUE;
|
||||
|
||||
int res=URG_OK;
|
||||
CURL *curl;
|
||||
int res=CURLE_OK;
|
||||
int i;
|
||||
|
||||
outs.stream = stdout;
|
||||
@ -981,7 +993,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if ((argc < 2) && !config.url) {
|
||||
helpf(NULL);
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
/* Parse options */
|
||||
@ -1014,7 +1026,7 @@ int main(int argc, char *argv[])
|
||||
else {
|
||||
if(url) {
|
||||
helpf("only one URL is supported!\n");
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
url = argv[i];
|
||||
}
|
||||
@ -1027,7 +1039,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if(!url) {
|
||||
helpf("no URL specified!\n");
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
#if 0
|
||||
fprintf(stderr, "URL: %s PROXY: %s\n", url, config.proxy?config.proxy:"none");
|
||||
@ -1036,7 +1048,7 @@ int main(int argc, char *argv[])
|
||||
/* expand '{...}' and '[...]' expressions and return total number of URLs
|
||||
in pattern set */
|
||||
res = glob_url(&urls, url, &urlnum);
|
||||
if(res != URG_OK)
|
||||
if(res != CURLE_OK)
|
||||
return res;
|
||||
|
||||
outfiles = config.outfile; /* save outfile pattern befor expansion */
|
||||
@ -1058,7 +1070,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if(config.outfile && config.infile) {
|
||||
helpf("you can't both upload and download!\n");
|
||||
return URG_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
if (config.outfile || config.remotefile) {
|
||||
@ -1077,7 +1089,7 @@ int main(int argc, char *argv[])
|
||||
config.outfile = strrchr(config.outfile, '/');
|
||||
if(!config.outfile || !strlen(++config.outfile)) {
|
||||
helpf("Remote file name has no length!\n");
|
||||
return URG_WRITE_ERROR;
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
else /* fill '#1' ... '#9' terms from URL pattern */
|
||||
@ -1100,7 +1112,7 @@ int main(int argc, char *argv[])
|
||||
outs.stream=(FILE *) fopen(config.outfile, config.resume_from?"ab":"wb");
|
||||
if (!outs.stream) {
|
||||
helpf("Can't open '%s'!\n", config.outfile);
|
||||
return URG_WRITE_ERROR;
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -1127,7 +1139,7 @@ int main(int argc, char *argv[])
|
||||
urlbuffer=(char *)malloc(strlen(url) + strlen(config.infile) + 3);
|
||||
if(!urlbuffer) {
|
||||
helpf("out of memory\n");
|
||||
return URG_OUT_OF_MEMORY;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
if(ptr)
|
||||
/* there is a trailing slash on the URL */
|
||||
@ -1142,7 +1154,7 @@ int main(int argc, char *argv[])
|
||||
infd=(FILE *) fopen(config.infile, "rb");
|
||||
if (!infd || stat(config.infile, &fileinfo)) {
|
||||
helpf("Can't open '%s'!\n", config.infile);
|
||||
return URG_READ_ERROR;
|
||||
return CURLE_READ_ERROR;
|
||||
}
|
||||
infilesize=fileinfo.st_size;
|
||||
|
||||
@ -1189,49 +1201,122 @@ int main(int argc, char *argv[])
|
||||
|
||||
main_init();
|
||||
|
||||
res = curl_urlget(URGTAG_FILE, (FILE *)&outs, /* where to store */
|
||||
URGTAG_WRITEFUNCTION, my_fwrite, /* what call to write */
|
||||
URGTAG_INFILE, infd, /* for uploads */
|
||||
URGTAG_INFILESIZE, infilesize, /* size of uploaded file */
|
||||
URGTAG_URL, url, /* what to fetch */
|
||||
URGTAG_PROXY, config.proxy, /* proxy to use */
|
||||
URGTAG_FLAGS, config.conf, /* flags */
|
||||
URGTAG_USERPWD, config.userpwd, /* user + passwd */
|
||||
URGTAG_PROXYUSERPWD, config.proxyuserpwd, /* Proxy user + passwd */
|
||||
URGTAG_RANGE, config.range, /* range of document */
|
||||
URGTAG_ERRORBUFFER, errorbuffer,
|
||||
URGTAG_TIMEOUT, config.timeout,
|
||||
URGTAG_POSTFIELDS, config.postfields,
|
||||
URGTAG_REFERER, config.referer,
|
||||
URGTAG_USERAGENT, config.useragent,
|
||||
URGTAG_FTPPORT, config.ftpport,
|
||||
URGTAG_LOW_SPEED_LIMIT, config.low_speed_limit,
|
||||
URGTAG_LOW_SPEED_TIME, config.low_speed_time,
|
||||
URGTAG_RESUME_FROM, config.use_resume?config.resume_from:0,
|
||||
URGTAG_COOKIE, config.cookie,
|
||||
URGTAG_HTTPHEADER, config.headers,
|
||||
URGTAG_HTTPPOST, config.httppost,
|
||||
URGTAG_SSLCERT, config.cert,
|
||||
URGTAG_SSLCERTPASSWD, config.cert_passwd,
|
||||
URGTAG_CRLF, config.crlf,
|
||||
URGTAG_QUOTE, config.quote,
|
||||
URGTAG_POSTQUOTE, config.postquote,
|
||||
URGTAG_WRITEHEADER, config.headerfile?&heads:NULL,
|
||||
URGTAG_COOKIEFILE, config.cookiefile,
|
||||
URGTAG_SSLVERSION, config.ssl_version,
|
||||
URGTAG_TIMECONDITION, config.timecond,
|
||||
URGTAG_TIMEVALUE, config.condtime,
|
||||
URGTAG_CUSTOMREQUEST, config.customrequest,
|
||||
URGTAG_STDERR, config.errors,
|
||||
URGTAG_PROGRESSMODE, config.progressmode,
|
||||
URGTAG_WRITEINFO, config.writeout,
|
||||
URGTAG_DONE); /* always terminate the list of tags */
|
||||
#if 0
|
||||
/* This is code left from the pre-v7 time, left here mainly as a reminder
|
||||
and possibly as a warning! ;-) */
|
||||
|
||||
res = curl_urlget(CURLOPT_FILE, (FILE *)&outs, /* where to store */
|
||||
CURLOPT_WRITEFUNCTION, my_fwrite, /* what call to write */
|
||||
CURLOPT_INFILE, infd, /* for uploads */
|
||||
CURLOPT_INFILESIZE, infilesize, /* size of uploaded file */
|
||||
CURLOPT_URL, url, /* what to fetch */
|
||||
CURLOPT_PROXY, config.proxy, /* proxy to use */
|
||||
CURLOPT_FLAGS, config.conf, /* flags */
|
||||
CURLOPT_USERPWD, config.userpwd, /* user + passwd */
|
||||
CURLOPT_PROXYUSERPWD, config.proxyuserpwd, /* Proxy user + passwd */
|
||||
CURLOPT_RANGE, config.range, /* range of document */
|
||||
CURLOPT_ERRORBUFFER, errorbuffer,
|
||||
CURLOPT_TIMEOUT, config.timeout,
|
||||
CURLOPT_POSTFIELDS, config.postfields,
|
||||
CURLOPT_REFERER, config.referer,
|
||||
CURLOPT_USERAGENT, config.useragent,
|
||||
CURLOPT_FTPPORT, config.ftpport,
|
||||
CURLOPT_LOW_SPEED_LIMIT, config.low_speed_limit,
|
||||
CURLOPT_LOW_SPEED_TIME, config.low_speed_time,
|
||||
CURLOPT_RESUME_FROM, config.use_resume?config.resume_from:0,
|
||||
CURLOPT_COOKIE, config.cookie,
|
||||
CURLOPT_HTTPHEADER, config.headers,
|
||||
CURLOPT_HTTPPOST, config.httppost,
|
||||
CURLOPT_SSLCERT, config.cert,
|
||||
CURLOPT_SSLCERTPASSWD, config.cert_passwd,
|
||||
CURLOPT_CRLF, config.crlf,
|
||||
CURLOPT_QUOTE, config.quote,
|
||||
CURLOPT_POSTQUOTE, config.postquote,
|
||||
CURLOPT_WRITEHEADER, config.headerfile?&heads:NULL,
|
||||
CURLOPT_COOKIEFILE, config.cookiefile,
|
||||
CURLOPT_SSLVERSION, config.ssl_version,
|
||||
CURLOPT_TIMECONDITION, config.timecond,
|
||||
CURLOPT_TIMEVALUE, config.condtime,
|
||||
CURLOPT_CUSTOMREQUEST, config.customrequest,
|
||||
CURLOPT_STDERR, config.errors,
|
||||
CURLOPT_PROGRESSMODE, config.progressmode,
|
||||
CURLOPT_WRITEINFO, config.writeout,
|
||||
CURLOPT_DONE); /* always terminate the list of tags */
|
||||
|
||||
#endif
|
||||
/* The new, v7-style easy-interface! */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_FILE, (FILE *)&outs); /* where to store */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); /* what call to write */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILE, infd); /* for uploads */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE, infilesize); /* size of uploaded file */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url); /* what to fetch */
|
||||
curl_easy_setopt(curl, CURLOPT_PROXY, config.proxy); /* proxy to use */
|
||||
#if 0
|
||||
curl_easy_setopt(curl, CURLOPT_FLAGS, config.conf); /* flags */
|
||||
#else
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, config.conf&CONF_VERBOSE);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, config.conf&CONF_HEADER);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, config.conf&CONF_NOPROGRESS);
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, config.conf&CONF_NOBODY);
|
||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, config.conf&CONF_FAILONERROR);
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, config.conf&CONF_UPLOAD);
|
||||
curl_easy_setopt(curl, CURLOPT_POST, config.conf&CONF_POST);
|
||||
curl_easy_setopt(curl, CURLOPT_FTPLISTONLY, config.conf&CONF_FTPLISTONLY);
|
||||
curl_easy_setopt(curl, CURLOPT_FTPAPPEND, config.conf&CONF_FTPAPPEND);
|
||||
curl_easy_setopt(curl, CURLOPT_NETRC, config.conf&CONF_NETRC);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, config.conf&CONF_FOLLOWLOCATION);
|
||||
curl_easy_setopt(curl, CURLOPT_FTPASCII, config.conf&CONF_FTPASCII);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_PUT, config.conf&CONF_PUT);
|
||||
curl_easy_setopt(curl, CURLOPT_MUTE, config.conf&CONF_MUTE);
|
||||
#endif
|
||||
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_USERPWD, config.userpwd); /* user + passwd */
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, config.proxyuserpwd); /* Proxy user + passwd */
|
||||
curl_easy_setopt(curl, CURLOPT_RANGE, config.range); /* range of document */
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, config.timeout);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, config.postfields);
|
||||
curl_easy_setopt(curl, CURLOPT_REFERER, config.referer);
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, config.useragent);
|
||||
curl_easy_setopt(curl, CURLOPT_FTPPORT, config.ftpport);
|
||||
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, config.low_speed_limit);
|
||||
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, config.low_speed_time);
|
||||
curl_easy_setopt(curl, CURLOPT_RESUME_FROM, config.use_resume?config.resume_from:0);
|
||||
curl_easy_setopt(curl, CURLOPT_COOKIE, config.cookie);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, config.headers);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, config.httppost);
|
||||
curl_easy_setopt(curl, CURLOPT_SSLCERT, config.cert);
|
||||
curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, config.cert_passwd);
|
||||
curl_easy_setopt(curl, CURLOPT_CRLF, config.crlf);
|
||||
curl_easy_setopt(curl, CURLOPT_QUOTE, config.quote);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTQUOTE, config.postquote);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEHEADER, config.headerfile?&heads:NULL);
|
||||
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, config.cookiefile);
|
||||
curl_easy_setopt(curl, CURLOPT_SSLVERSION, config.ssl_version);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMECONDITION, config.timecond);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEVALUE, config.condtime);
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, config.customrequest);
|
||||
curl_easy_setopt(curl, CURLOPT_STDERR, config.errors);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSMODE, config.progressmode);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEINFO, config.writeout);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if((res!=CURLE_OK) && config.showerror)
|
||||
fprintf(config.errors, "curl: (%d) %s\n", res, errorbuffer);
|
||||
}
|
||||
else
|
||||
fprintf(config.errors, "curl: failed to init libcurl!\n");
|
||||
|
||||
main_free();
|
||||
|
||||
if((res!=URG_OK) && config.showerror)
|
||||
fprintf(config.errors, "curl: (%d) %s\n", res, errorbuffer);
|
||||
|
||||
if((config.errors != stderr) &&
|
||||
(config.errors != stdout))
|
||||
/* it wasn't directed to stdout or stderr so close the file! */
|
||||
|
@ -69,18 +69,18 @@ int glob_set(char *pattern, int pos) {
|
||||
switch (*pattern) {
|
||||
case '\0': /* URL ended while set was still open */
|
||||
printf("error: unmatched brace at pos %d\n", pos);
|
||||
exit (URG_URL_MALFORMAT);
|
||||
exit (CURLE_URL_MALFORMAT);
|
||||
case '{':
|
||||
case '[': /* no nested expressions at this time */
|
||||
printf("error: nested braces not supported %d\n", pos);
|
||||
exit (URG_URL_MALFORMAT);
|
||||
exit (CURLE_URL_MALFORMAT);
|
||||
case ',':
|
||||
case '}': /* set element completed */
|
||||
*buf = '\0';
|
||||
pat->content.Set.elements = realloc(pat->content.Set.elements, (pat->content.Set.size + 1) * sizeof(char*));
|
||||
if (!pat->content.Set.elements) {
|
||||
printf("out of memory in set pattern\n");
|
||||
exit(URG_OUT_OF_MEMORY);
|
||||
exit(CURLE_OUT_OF_MEMORY);
|
||||
}
|
||||
pat->content.Set.elements[pat->content.Set.size] = strdup(glob_buffer);
|
||||
++pat->content.Set.size;
|
||||
@ -95,11 +95,11 @@ int glob_set(char *pattern, int pos) {
|
||||
break;
|
||||
case ']': /* illegal closing bracket */
|
||||
printf("error: illegal pattern at pos %d\n", pos);
|
||||
exit (URG_URL_MALFORMAT);
|
||||
exit (CURLE_URL_MALFORMAT);
|
||||
case '\\': /* escaped character, skip '\' */
|
||||
if (*(buf+1) == '\0') { /* but no escaping of '\0'! */
|
||||
printf("error: illegal pattern at pos %d\n", pos);
|
||||
exit (URG_URL_MALFORMAT);
|
||||
exit (CURLE_URL_MALFORMAT);
|
||||
}
|
||||
++pattern;
|
||||
++pos; /* intentional fallthrough */
|
||||
@ -108,7 +108,7 @@ int glob_set(char *pattern, int pos) {
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
exit (URG_FAILED_INIT);
|
||||
exit (CURLE_FAILED_INIT);
|
||||
}
|
||||
|
||||
int glob_range(char *pattern, int pos) {
|
||||
@ -132,7 +132,7 @@ int glob_range(char *pattern, int pos) {
|
||||
pat->content.CharRange.max_c - pat->content.CharRange.min_c > 'z' - 'a') {
|
||||
/* the pattern is not well-formed */
|
||||
printf("error: illegal pattern or range specification after pos %d\n", pos);
|
||||
exit (URG_URL_MALFORMAT);
|
||||
exit (CURLE_URL_MALFORMAT);
|
||||
}
|
||||
pat->content.CharRange.ptr_c = pat->content.CharRange.min_c;
|
||||
/* always check for a literal (may be "") between patterns */
|
||||
@ -146,7 +146,7 @@ int glob_range(char *pattern, int pos) {
|
||||
pat->content.NumRange.min_n >= pat->content.NumRange.max_n) {
|
||||
/* the pattern is not well-formed */
|
||||
printf("error: illegal pattern or range specification after pos %d\n", pos);
|
||||
exit (URG_URL_MALFORMAT);
|
||||
exit (CURLE_URL_MALFORMAT);
|
||||
}
|
||||
if (*pattern == '0') { /* leading zero specified */
|
||||
c = pattern;
|
||||
@ -161,7 +161,7 @@ int glob_range(char *pattern, int pos) {
|
||||
glob_word(c, pos + (c - pattern));
|
||||
}
|
||||
printf("error: illegal character in range specification at pos %d\n", pos);
|
||||
exit (URG_URL_MALFORMAT);
|
||||
exit (CURLE_URL_MALFORMAT);
|
||||
}
|
||||
|
||||
int glob_word(char *pattern, int pos) {
|
||||
@ -174,14 +174,14 @@ int glob_word(char *pattern, int pos) {
|
||||
while (*pattern != '\0' && *pattern != '{' && *pattern != '[') {
|
||||
if (*pattern == '}' || *pattern == ']') {
|
||||
printf("illegal character at position %d\n", pos);
|
||||
exit (URG_URL_MALFORMAT);
|
||||
exit (CURLE_URL_MALFORMAT);
|
||||
}
|
||||
if (*pattern == '\\') { /* escape character, skip '\' */
|
||||
++pattern;
|
||||
++pos;
|
||||
if (*pattern == '\0') { /* but no escaping of '\0'! */
|
||||
printf("illegal character at position %d\n", pos);
|
||||
exit (URG_URL_MALFORMAT);
|
||||
exit (CURLE_URL_MALFORMAT);
|
||||
}
|
||||
}
|
||||
*buf++ = *pattern++; /* copy character to literal */
|
||||
@ -201,21 +201,21 @@ int glob_word(char *pattern, int pos) {
|
||||
return glob_range(++pattern, ++pos);/* process range pattern */
|
||||
}
|
||||
printf("internal error\n");
|
||||
exit (URG_FAILED_INIT);
|
||||
exit (CURLE_FAILED_INIT);
|
||||
}
|
||||
|
||||
int glob_url(URLGlob** glob, char* url, int *urlnum)
|
||||
{
|
||||
if (strlen(url)>URL_MAX_LENGTH) {
|
||||
printf("Illegally sized URL\n");
|
||||
return URG_URL_MALFORMAT;
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
glob_expand = (URLGlob*)malloc(sizeof(URLGlob));
|
||||
glob_expand->size = 0;
|
||||
*urlnum = glob_word(url, 1);
|
||||
*glob = glob_expand;
|
||||
return URG_OK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
char *next_url(URLGlob *glob)
|
||||
@ -258,7 +258,7 @@ char *next_url(URLGlob *glob)
|
||||
break;
|
||||
default:
|
||||
printf("internal error: invalid pattern type (%d)\n", pat->type);
|
||||
exit (URG_FAILED_INIT);
|
||||
exit (CURLE_FAILED_INIT);
|
||||
}
|
||||
}
|
||||
if (carry) /* first pattern ptr has run into overflow, done! */
|
||||
@ -287,7 +287,7 @@ char *next_url(URLGlob *glob)
|
||||
break;
|
||||
default:
|
||||
printf("internal error: invalid pattern type (%d)\n", pat->type);
|
||||
exit (URG_FAILED_INIT);
|
||||
exit (CURLE_FAILED_INIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -305,12 +305,12 @@ char *match_url(char *filename, URLGlob glob) {
|
||||
if (!isdigit((int)*++filename) ||
|
||||
*filename == '0') { /* only '#1' ... '#9' allowed */
|
||||
printf("illegal matching expression\n");
|
||||
exit(URG_URL_MALFORMAT);
|
||||
exit(CURLE_URL_MALFORMAT);
|
||||
}
|
||||
i = *filename - '1';
|
||||
if (i + 1 > glob.size / 2) {
|
||||
printf("match against nonexisting pattern\n");
|
||||
exit(URG_URL_MALFORMAT);
|
||||
exit(CURLE_URL_MALFORMAT);
|
||||
}
|
||||
pat = glob.pattern[i];
|
||||
switch (pat.type) {
|
||||
@ -327,7 +327,7 @@ char *match_url(char *filename, URLGlob glob) {
|
||||
break;
|
||||
default:
|
||||
printf("internal error: invalid pattern type (%d)\n", pat.type);
|
||||
exit (URG_FAILED_INIT);
|
||||
exit (CURLE_FAILED_INIT);
|
||||
}
|
||||
++filename;
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
#define CURL_NAME "curl"
|
||||
#define CURL_VERSION "6.5.2"
|
||||
#define CURL_VERSION "7.0beta"
|
||||
#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
|
||||
|
Loading…
Reference in New Issue
Block a user