diff options
Diffstat (limited to 'Utilities/cmcurl/file.c')
-rw-r--r-- | Utilities/cmcurl/file.c | 123 |
1 files changed, 70 insertions, 53 deletions
diff --git a/Utilities/cmcurl/file.c b/Utilities/cmcurl/file.c index cd4366c..b247a77 100644 --- a/Utilities/cmcurl/file.c +++ b/Utilities/cmcurl/file.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -30,12 +30,14 @@ #include <stdarg.h> #include <stdlib.h> #include <ctype.h> +#ifdef HAVE_SYS_TYPES_H #include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H #include <sys/stat.h> +#endif -#include <errno.h> - -#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) +#ifdef WIN32 #include <time.h> #include <io.h> #include <fcntl.h> @@ -46,7 +48,9 @@ #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif +#ifdef HAVE_SYS_TIME_H #include <sys/time.h> +#endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif @@ -66,9 +70,6 @@ #include <sys/param.h> #endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif #ifdef HAVE_FCNTL_H #include <fcntl.h> #endif @@ -85,7 +86,8 @@ #include "getinfo.h" #include "transfer.h" #include "url.h" -#include "curl_memory.h" +#include "memory.h" +#include "parsedate.h" /* for the week day and month names */ #define _MPRINTF_REPLACE /* use our functions only */ #include <curl/mprintf.h> @@ -100,10 +102,10 @@ */ CURLcode Curl_file_connect(struct connectdata *conn) { - char *real_path = curl_unescape(conn->path, 0); + char *real_path = curl_easy_unescape(conn->data, conn->data->reqdata.path, 0, NULL); struct FILEPROTO *file; int fd; -#if defined(WIN32) || defined(__EMX__) +#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) int i; char *actual_path; #endif @@ -117,9 +119,13 @@ CURLcode Curl_file_connect(struct connectdata *conn) return CURLE_OUT_OF_MEMORY; } - conn->proto.file = file; + if (conn->data->reqdata.proto.file) { + free(conn->data->reqdata.proto.file); + } + + conn->data->reqdata.proto.file = file; -#if defined(WIN32) || defined(__EMX__) +#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) /* If the first character is a slash, and there's something that looks like a drive at the beginning of the path, skip the slash. If we remove the initial @@ -143,7 +149,7 @@ CURLcode Curl_file_connect(struct connectdata *conn) actual_path++; } - /* change path separators from '/' to '\\' for Windows and OS/2 */ + /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */ for (i=0; actual_path[i] != '\0'; ++i) if (actual_path[i] == '/') actual_path[i] = '\\'; @@ -156,31 +162,31 @@ CURLcode Curl_file_connect(struct connectdata *conn) #endif file->freepath = real_path; /* free this when done */ + file->fd = fd; 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); + failf(conn->data, "Couldn't open file %s", conn->data->reqdata.path); + Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE); return CURLE_FILE_COULDNT_READ_FILE; } - file->fd = fd; return CURLE_OK; } -#if defined(WIN32) && (SIZEOF_CURL_OFF_T > 4) -#define lseek(x,y,z) _lseeki64(x, y, z) -#endif - CURLcode Curl_file_done(struct connectdata *conn, - CURLcode status) + CURLcode status, bool premature) { - struct FILEPROTO *file = conn->proto.file; + struct FILEPROTO *file = conn->data->reqdata.proto.file; (void)status; /* not used */ + (void)premature; /* not used */ Curl_safefree(file->freepath); + if(file->fd != -1) + close(file->fd); + return CURLE_OK; } -#if defined(WIN32) || defined(__EMX__) +#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) #define DIRSEP '\\' #else #define DIRSEP '/' @@ -188,7 +194,7 @@ CURLcode Curl_file_done(struct connectdata *conn, static CURLcode file_upload(struct connectdata *conn) { - struct FILEPROTO *file = conn->proto.file; + struct FILEPROTO *file = conn->data->reqdata.proto.file; char *dir = strchr(file->path, DIRSEP); FILE *fp; CURLcode res=CURLE_OK; @@ -205,7 +211,7 @@ static CURLcode file_upload(struct connectdata *conn) */ conn->fread = data->set.fread; conn->fread_in = data->set.in; - conn->upload_fromhere = buf; + conn->data->reqdata.upload_fromhere = buf; if(!dir) return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ @@ -227,13 +233,13 @@ static CURLcode file_upload(struct connectdata *conn) int readcount; res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount); if(res) - return res; - - nread = (size_t)readcount; + break; - if (nread <= 0) + if (readcount <= 0) /* fix questionable compare error. curlvms */ break; + nread = (size_t)readcount; + /* write the data to the target */ nwrite = fwrite(buf, 1, nread, fp); if(nwrite != nread) { @@ -266,7 +272,7 @@ static CURLcode file_upload(struct connectdata *conn) * opposed to sockets) we instead perform the whole do-operation in this * function. */ -CURLcode Curl_file(struct connectdata *conn) +CURLcode Curl_file(struct connectdata *conn, bool *done) { /* This implementation ignores the host name in conformance with RFC 1738. Only local files (reachable via the standard file system) @@ -274,7 +280,9 @@ CURLcode Curl_file(struct connectdata *conn) (via NFS, Samba, NT sharing) can be accessed through a file:// URL */ CURLcode res = CURLE_OK; - struct stat statbuf; + struct_stat statbuf; /* struct_stat instead of struct stat just to allow the + Windows version to have a different struct without + having to redefine the simple word 'stat' */ curl_off_t expected_size=0; bool fstated=FALSE; ssize_t nread; @@ -284,6 +292,8 @@ CURLcode Curl_file(struct connectdata *conn) int fd; struct timeval now = Curl_tvnow(); + *done = TRUE; /* unconditionally */ + Curl_readwrite_init(conn); Curl_initinfo(data); Curl_pgrsStartNow(data); @@ -292,7 +302,7 @@ CURLcode Curl_file(struct connectdata *conn) return file_upload(conn); /* get the fd from the connection phase */ - fd = conn->proto.file->fd; + fd = conn->data->reqdata.proto.file->fd; /* VMS: This only works reliable for STREAMLF files */ if( -1 != fstat(fd, &statbuf)) { @@ -308,40 +318,45 @@ CURLcode Curl_file(struct connectdata *conn) CURLcode result; snprintf(buf, sizeof(data->state.buffer), "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size); - result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); + result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0); if(result) return result; - result = Curl_client_write(data, CLIENTWRITE_BOTH, + result = Curl_client_write(conn, CLIENTWRITE_BOTH, (char *)"Accept-ranges: bytes\r\n", 0); if(result) return result; -#ifdef HAVE_STRFTIME if(fstated) { struct tm *tm; - time_t cuClock = (time_t)statbuf.st_mtime; + time_t clock = (time_t)statbuf.st_mtime; #ifdef HAVE_GMTIME_R struct tm buffer; - tm = (struct tm *)gmtime_r(&cuClock, &buffer); + tm = (struct tm *)gmtime_r(&clock, &buffer); #else - tm = gmtime(&cuClock); + tm = gmtime(&clock); #endif /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ - strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT\r\n", - tm); - result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); + snprintf(buf, BUFSIZE-1, + "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", + Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], + tm->tm_mday, + Curl_month[tm->tm_mon], + tm->tm_year + 1900, + tm->tm_hour, + tm->tm_min, + tm->tm_sec); + result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0); } -#endif return result; } - /* Added by Dolbneff A.V & Spiridonoff A.V */ - if (conn->resume_from <= expected_size) - expected_size -= conn->resume_from; - else - /* Is this error code suitable in such situation? */ - return CURLE_FTP_BAD_DOWNLOAD_RESUME; + if (data->reqdata.resume_from <= expected_size) + expected_size -= data->reqdata.resume_from; + else { + failf(data, "failed to resume file:// transfer"); + return CURLE_BAD_DOWNLOAD_RESUME; + } if (fstated && (expected_size == 0)) return CURLE_OK; @@ -353,8 +368,11 @@ CURLcode Curl_file(struct connectdata *conn) if(fstated) Curl_pgrsSetDownloadSize(data, expected_size); - if(conn->resume_from) - lseek(fd, conn->resume_from, SEEK_SET); + if(data->reqdata.resume_from) { + if(data->reqdata.resume_from != + lseek(fd, data->reqdata.resume_from, SEEK_SET)) + return CURLE_BAD_DOWNLOAD_RESUME; + } Curl_pgrsTime(data, TIMER_STARTTRANSFER); @@ -369,7 +387,7 @@ CURLcode Curl_file(struct connectdata *conn) bytecount += nread; - res = Curl_client_write(data, CLIENTWRITE_BODY, buf, nread); + res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread); if(res) return res; @@ -383,8 +401,7 @@ CURLcode Curl_file(struct connectdata *conn) if(Curl_pgrsUpdate(conn)) res = CURLE_ABORTED_BY_CALLBACK; - close(fd); - return res; } + #endif |