Loading CHANGES +2 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ Changelog Daniel (24 May 2004) - libcurl now supports "uploading" to file:// URLs. - Simon Josefsson added a idn_free() function in libidn 0.4.5 as a reaction to Gisle's previous mail. We now use this function, and thus we require libidn 0.4.5 or later. No earler version will do. Loading lib/file.c +94 −14 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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) Loading lib/file.h +3 −2 Original line number Diff line number Diff line Loading @@ -24,7 +24,8 @@ * $Id$ ***************************************************************************/ #ifndef CURL_DISABLE_FILE CURLcode Curl_file(struct connectdata *conn); CURLcode Curl_file_connect(struct connectdata *conn); CURLcode Curl_file(struct connectdata *); CURLcode Curl_file_done(struct connectdata *, CURLcode); CURLcode Curl_file_connect(struct connectdata *); #endif #endif lib/transfer.c +2 −3 Original line number Diff line number Diff line Loading @@ -125,8 +125,7 @@ static struct timeval notimeout={0,0}; * This function will call the read callback to fill our buffer with data * to upload. */ static int fillbuffer(struct connectdata *conn, int bytes) int Curl_fillreadbuffer(struct connectdata *conn, int bytes) { int buffersize = bytes; int nread; Loading Loading @@ -1124,7 +1123,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, break; } nread = fillbuffer(conn, BUFSIZE); nread = Curl_fillreadbuffer(conn, BUFSIZE); } else nread = 0; /* we're done uploading/reading */ Loading lib/transfer.h +9 −7 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ void Curl_single_fdset(struct connectdata *conn, int *max_fd); CURLcode Curl_readwrite_init(struct connectdata *conn); int Curl_fillreadbuffer(struct connectdata *conn, int bytes); /* This sets up a forthcoming transfer */ CURLcode Curl_Transfer (struct connectdata *data, Loading Loading
CHANGES +2 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ Changelog Daniel (24 May 2004) - libcurl now supports "uploading" to file:// URLs. - Simon Josefsson added a idn_free() function in libidn 0.4.5 as a reaction to Gisle's previous mail. We now use this function, and thus we require libidn 0.4.5 or later. No earler version will do. Loading
lib/file.c +94 −14 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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) Loading
lib/file.h +3 −2 Original line number Diff line number Diff line Loading @@ -24,7 +24,8 @@ * $Id$ ***************************************************************************/ #ifndef CURL_DISABLE_FILE CURLcode Curl_file(struct connectdata *conn); CURLcode Curl_file_connect(struct connectdata *conn); CURLcode Curl_file(struct connectdata *); CURLcode Curl_file_done(struct connectdata *, CURLcode); CURLcode Curl_file_connect(struct connectdata *); #endif #endif
lib/transfer.c +2 −3 Original line number Diff line number Diff line Loading @@ -125,8 +125,7 @@ static struct timeval notimeout={0,0}; * This function will call the read callback to fill our buffer with data * to upload. */ static int fillbuffer(struct connectdata *conn, int bytes) int Curl_fillreadbuffer(struct connectdata *conn, int bytes) { int buffersize = bytes; int nread; Loading Loading @@ -1124,7 +1123,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, break; } nread = fillbuffer(conn, BUFSIZE); nread = Curl_fillreadbuffer(conn, BUFSIZE); } else nread = 0; /* we're done uploading/reading */ Loading
lib/transfer.h +9 −7 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ void Curl_single_fdset(struct connectdata *conn, int *max_fd); CURLcode Curl_readwrite_init(struct connectdata *conn); int Curl_fillreadbuffer(struct connectdata *conn, int bytes); /* This sets up a forthcoming transfer */ CURLcode Curl_Transfer (struct connectdata *data, Loading