initial support for "uploading" to file:// URLs
This commit is contained in:
		
							
								
								
									
										108
									
								
								lib/file.c
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Daniel Stenberg
					Daniel Stenberg