remade FILE:// support to look more as the other protocols
authorDaniel Stenberg <daniel@haxx.se>
Mon, 5 Mar 2001 13:39:01 +0000 (13:39 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 5 Mar 2001 13:39:01 +0000 (13:39 +0000)
lib/file.c
lib/file.h
lib/url.c
lib/urldata.h

index 1282381..f04b1e6 100644 (file)
 #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;
index ff66eb8..83ffa39 100644 (file)
@@ -23,6 +23,6 @@
  *
  * $Id$
  *****************************************************************************/
-CURLcode file(struct connectdata *conn);
-
+CURLcode Curl_file(struct connectdata *conn);
+CURLcode Curl_file_connect(struct connectdata *conn);
 #endif
index 123e5d4..9b53fbc 100644 (file)
--- 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;
 }
index 2c27279..d9dd175 100644 (file)
@@ -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