aboutsummaryrefslogtreecommitdiff
path: root/lib/file.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2004-05-25 21:47:29 +0000
committerDaniel Stenberg <daniel@haxx.se>2004-05-25 21:47:29 +0000
commitfd802db39f77fa3985d20e461742bf24644065d6 (patch)
treea9d477d5a34dc803a845b0c23148df2fe69ffb7c /lib/file.c
parent765754d39d164a248b909092295d0a0aab294032 (diff)
initial support for "uploading" to file:// URLs
Diffstat (limited to 'lib/file.c')
-rw-r--r--lib/file.c108
1 files changed, 94 insertions, 14 deletions
diff --git a/lib/file.c b/lib/file.c
index 05a1fde58..e36631426 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -1,8 +1,8 @@
/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
@@ -10,7 +10,7 @@
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
- *
+ *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
@@ -83,7 +83,8 @@
#include "file.h"
#include "speedcheck.h"
#include "getinfo.h"
-#include "transfer.h" /* for Curl_readwrite_init() */
+#include "transfer.h"
+#include "url.h"
#include "memory.h"
#define _MPRINTF_REPLACE /* use our functions only */
@@ -148,13 +149,16 @@ CURLcode Curl_file_connect(struct connectdata *conn)
actual_path[i] = '\\';
fd = open(actual_path, O_RDONLY | O_BINARY); /* no CR/LF translation! */
+ file->path = actual_path;
#else
fd = open(real_path, O_RDONLY);
+ file->path = real_path;
#endif
- free(real_path);
+ file->freepath = real_path; /* free this when done */
- if(fd == -1) {
+ if(!conn->data->set.upload && (fd == -1)) {
failf(conn->data, "Couldn't open file %s", conn->path);
+ Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE);
return CURLE_FILE_COULDNT_READ_FILE;
}
file->fd = fd;
@@ -166,6 +170,83 @@ CURLcode Curl_file_connect(struct connectdata *conn)
#define lseek(x,y,z) _lseeki64(x, y, z)
#endif
+CURLcode Curl_file_done(struct connectdata *conn,
+ CURLcode status)
+{
+ struct FILEPROTO *file = conn->proto.file;
+ (void)status; /* not used */
+ Curl_safefree(file->path);
+
+ return CURLE_OK;
+}
+
+static CURLcode file_upload(struct connectdata *conn)
+{
+ struct FILEPROTO *file = conn->proto.file;
+ char *dir = strchr(file->path, '/');
+ FILE *fp;
+ CURLcode res=CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ char *buf = data->state.buffer;
+ size_t nread;
+ size_t nwrite;
+ curl_off_t bytecount = 0;
+ struct timeval now = Curl_tvnow();
+
+ /*
+ * Since FILE: doesn't do the full init, we need to provide some extra
+ * assignments here.
+ */
+ conn->fread = data->set.fread;
+ conn->fread_in = data->set.in;
+ conn->upload_fromhere = buf;
+
+ if(!dir)
+ return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
+
+ if(!dir[1])
+ return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
+
+ fp = fopen(file->path, "wb");
+ if(!fp) {
+ failf(data, "Can't open %s for writing", file->path);
+ return CURLE_WRITE_ERROR;
+ }
+
+ if(-1 != data->set.infilesize)
+ /* known size of data to "upload" */
+ Curl_pgrsSetUploadSize(data, data->set.infilesize);
+
+ while (res == CURLE_OK) {
+ nread = Curl_fillreadbuffer(conn, BUFSIZE);
+
+ if (nread <= 0)
+ break;
+
+ /* write the data to the target */
+ nwrite = fwrite(buf, 1, nread, fp);
+ if(nwrite != nread) {
+ res = CURLE_SEND_ERROR;
+ break;
+ }
+
+ bytecount += nread;
+
+ Curl_pgrsSetUploadCounter(data, bytecount);
+
+ if(Curl_pgrsUpdate(conn))
+ res = CURLE_ABORTED_BY_CALLBACK;
+ else
+ res = Curl_speedcheck(data, now);
+ }
+ if(!res && Curl_pgrsUpdate(conn))
+ res = CURLE_ABORTED_BY_CALLBACK;
+
+ fclose(fp);
+
+ return res;
+}
+
/*
* Curl_file() is the protocol-specific function for the do-phase, separated
* from the connect-phase above. Other protocols merely setup the transfer in
@@ -176,7 +257,7 @@ CURLcode Curl_file_connect(struct connectdata *conn)
*/
CURLcode Curl_file(struct connectdata *conn)
{
- /* This implementation ignores the host name in conformance with
+ /* 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
@@ -196,6 +277,9 @@ CURLcode Curl_file(struct connectdata *conn)
Curl_initinfo(data);
Curl_pgrsStartNow(data);
+ if(data->set.upload)
+ return file_upload(conn);
+
/* get the fd from the connection phase */
fd = conn->proto.file->fd;
@@ -272,10 +356,6 @@ CURLcode Curl_file(struct connectdata *conn)
break;
bytecount += nread;
- /* NOTE: The following call to fwrite does CR/LF translation on
- Windows systems if the target is stdout. Use -O or -o parameters
- to prevent CR/LF translation (this then goes to a binary mode
- file descriptor). */
res = Curl_client_write(data, CLIENTWRITE_BODY, buf, nread);
if(res)
@@ -286,7 +366,7 @@ CURLcode Curl_file(struct connectdata *conn)
if(Curl_pgrsUpdate(conn))
res = CURLE_ABORTED_BY_CALLBACK;
else
- res = Curl_speedcheck (data, now);
+ res = Curl_speedcheck(data, now);
}
if(Curl_pgrsUpdate(conn))
res = CURLE_ABORTED_BY_CALLBACK;