From 84e94fda8ba36c77c80e012c52ad36a4a59de6a7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 5 Mar 2001 13:39:01 +0000 Subject: [PATCH] remade FILE:// support to look more as the other protocols --- lib/file.c | 58 +++++++++++++++++++++++++++++++++++---------------- lib/file.h | 4 ++-- lib/url.c | 54 ++++++++++++++++++++++++----------------------- lib/urldata.h | 9 +++++++- 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