aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/file.c58
-rw-r--r--lib/file.h4
-rw-r--r--lib/url.c54
-rw-r--r--lib/urldata.h9
4 files changed, 78 insertions, 47 deletions
diff --git a/lib/file.c b/lib/file.c
index 12823812a..f04b1e65e 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -91,25 +91,19 @@
#include "memdebug.h"
#endif
-CURLcode file(struct connectdata *conn)
+/* Emulate a connect-then-transfer protocol. We connect to the file here */
+CURLcode Curl_file_connect(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 = Curl_tvnow();
- struct timeval now = start;
+ char *actual_path = curl_unescape(conn->path, 0);
+ struct FILE *file;
int fd;
- char *actual_path = curl_unescape(path, 0);
+
+ file = (struct FILE *)malloc(sizeof(struct FILE));
+ if(!file)
+ return CURLE_OUT_OF_MEMORY;
+
+ memset(file, 0, sizeof(struct FILE));
+ conn->proto.file = file;
#if defined(WIN32) || defined(__EMX__)
int i;
@@ -126,9 +120,37 @@ CURLcode file(struct connectdata *conn)
free(actual_path);
if(fd == -1) {
- failf(data, "Couldn't open file %s", path);
+ failf(conn->data, "Couldn't open file %s", conn->path);
return CURLE_FILE_COULDNT_READ_FILE;
}
+ file->fd = fd;
+
+ return CURLE_OK;
+}
+
+/* This is the do-phase, separated from the connect-phase above */
+
+CURLcode Curl_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;
+ 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 = Curl_tvnow();
+ struct timeval now = start;
+ int fd;
+
+ /* get the fd from the connection phase */
+ fd = conn->proto.file->fd;
+
if( -1 != fstat(fd, &statbuf)) {
/* we could stat it, then read out the size */
expected_size = statbuf.st_size;
diff --git a/lib/file.h b/lib/file.h
index ff66eb80f..83ffa3975 100644
--- a/lib/file.h
+++ b/lib/file.h
@@ -23,6 +23,6 @@
*
* $Id$
*****************************************************************************/
-CURLcode file(struct connectdata *conn);
-
+CURLcode Curl_file(struct connectdata *conn);
+CURLcode Curl_file_connect(struct connectdata *conn);
#endif
diff --git a/lib/url.c b/lib/url.c
index 123e5d480..9b53fbc2f 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -982,6 +982,11 @@ static CURLcode _connect(CURL *curl,
*in_connect = NULL; /* clear the pointer */
return CURLE_OUT_OF_MEMORY;
}
+ /* We must set the return variable as soon as possible, so that our
+ parent can cleanup any possible allocs we may have done before
+ any failure */
+ *in_connect = conn;
+
/* we have to init the struct */
memset(conn, 0, sizeof(struct connectdata));
@@ -994,6 +999,12 @@ static CURLcode _connect(CURL *curl,
conn->secondarysocket = -1; /* no file descriptor */
conn->connectindex = -1; /* no index */
+ /* Default protocol-indepent behaveiour doesn't support persistant
+ connections, so we set this to force-close. Protocols that support
+ this need to set this to FALSE in their "curl_do" functions. */
+ conn->bits.close = TRUE;
+
+
/***********************************************************
* We need to allocate memory to store the path in. We get the size of the
* full URL to be sure, and we need to make it at least 256 bytes since
@@ -1425,13 +1436,20 @@ static CURLcode _connect(CURL *curl,
else if (strequal(conn->protostr, "FILE")) {
conn->protocol |= PROT_FILE;
- conn->curl_do = file;
+ conn->curl_do = Curl_file;
/* no done() function */
- result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
- -1, NULL); /* no upload */
+ /* anyway, this is supposed to be the connect function so we better
+ at least check that the file is present here! */
+ result = Curl_file_connect(conn);
- return CURLE_OK;
+ /* Setup a "faked" transfer that'll do nothing */
+ if(CURLE_OK == result) {
+ result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
+ -1, NULL); /* no upload */
+ }
+
+ return result;
}
else {
/* We fell through all checks and thus we don't support the specified
@@ -1582,7 +1600,6 @@ static CURLcode _connect(CURL *curl,
*/
ConnectionStore(data, conn);
}
- *in_connect = conn;
/*************************************************************
* Resolve the name of the server or proxy
@@ -1779,30 +1796,15 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect,
if(CURLE_OK != code) {
/* We're not allowed to return failure with memory left allocated
in the connectdata struct, free those here */
- struct UrlData *data;
- int index;
-
conn = (struct connectdata *)*in_connect;
- data = conn->data;
-#if 0
if(conn) {
- if(conn->path)
- free(conn->path);
-#ifdef ENABLE_IPV6
- if(conn->hp)
- freeaddrinfo(conn->hp);
-#else
- if(conn->hostent_buf)
- free(conn->hostent_buf);
-#endif
- free(conn);
- *in_connect=NULL;
+ struct UrlData *data;
+ int index;
+ data = conn->data;
+ index = conn->connectindex; /* get the index */
+ curl_disconnect(conn); /* close the connection */
+ data->connects[index]=NULL; /* clear the pointer */
}
-#endif
- index = conn->connectindex; /* get the index */
- curl_disconnect(conn); /* close the connection */
- data->connects[index]=NULL; /* clear the pointer */
-
}
return code;
}
diff --git a/lib/urldata.h b/lib/urldata.h
index 2c2727953..d9dd17542 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -183,6 +183,13 @@ struct FTP {
char *entrypath; /* the PWD reply when we logged on */
};
+/****************************************************************************
+ * FILE unique setup
+ ***************************************************************************/
+struct FILE {
+ int fd; /* open file descriptor to read from! */
+};
+
/*
* Boolean values that concerns this connection.
*/
@@ -318,9 +325,9 @@ struct connectdata {
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;
+ struct FILE *file;
#if 0 /* no need for special ones for these: */
struct TELNET *telnet;
- struct FILE *file;
struct LDAP *ldap;
struct DICT *dict;
#endif