diff options
Diffstat (limited to 'lib/upload.c')
-rw-r--r-- | lib/upload.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/lib/upload.c b/lib/upload.c new file mode 100644 index 000000000..0673382e9 --- /dev/null +++ b/lib/upload.c @@ -0,0 +1,178 @@ +/***************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Curl. + * + * The Initial Developer of the Original Code is Daniel Stenberg. + * + * Portions created by the Initial Developer are Copyright (C) 1998. + * All Rights Reserved. + * + * ------------------------------------------------------------ + * Main author: + * - Daniel Stenberg <Daniel.Stenberg@haxx.nu> + * + * http://curl.haxx.nu + * + * $Source$ + * $Revision$ + * $Date$ + * $Author$ + * $State$ + * $Locker$ + * + * ------------------------------------------------------------ + ****************************************************************************/ + +#include "setup.h" +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif +#ifdef WIN32 +#if !defined(__GNUC__) || defined(__MINGW32__) +#include <winsock.h> +#endif +#include <time.h> /* for the time_t typedef! */ + +#if defined(__GNUC__) && defined(TIME_WITH_SYS_TIME) +#include <sys/time.h> +#endif + +#endif + +#include <curl/curl.h> + +#ifdef __BEOS__ +#include <net/socket.h> +#endif + +#include "urldata.h" +#include "speedcheck.h" +#include "sendf.h" +#include "progress.h" + +/* --- upload a stream to a socket --- */ + +UrgError Upload(struct UrlData *data, + int sockfd, + long *bytecountp) +{ + fd_set writefd; + fd_set keepfd; + struct timeval interval; + bool keepon=TRUE; + char *buf = data->buffer; + size_t nread; + long bytecount=0; + struct timeval start; + struct timeval now; + UrgError urg; + char scratch[BUFSIZE * 2]; + int i, si; + + /* timeout every X second + - makes a better progressmeter (i.e even when no data is sent, the + meter can be updated and reflect reality) + - allows removal of the alarm() crap + - variable timeout is easier + */ + + myalarm(0); /* switch off the alarm-style timeout */ + + start = tvnow(); + now = start; + + FD_ZERO(&writefd); /* clear it */ + FD_SET(sockfd, &writefd); + + keepfd = writefd; + + while(keepon) { + size_t bytes_written = 0; + + writefd = keepfd; /* set this every lap in the loop */ + interval.tv_sec = 2; + interval.tv_usec = 0; + + switch(select(sockfd+1, NULL, &writefd, NULL, &interval)) { + case -1: /* error, stop writing */ + keepon=FALSE; + continue; + case 0: /* timeout */ + break; + default: /* write! */ + if(data->crlf) + buf = data->buffer; /* put it back on the buffer */ + + nread = data->fread(buf, 1, BUFSIZE, data->in); + bytecount += nread; + + if (nread==0) { + /* done */ + keepon = FALSE; + break; + } + + /* convert LF to CRLF if so asked */ + if (data->crlf) { + for(i = 0, si = 0; i < (int)nread; i++, si++) { + if (buf[i] == 0x0a) { + scratch[si++] = 0x0d; + scratch[si] = 0x0a; + } + else { + scratch[si] = buf[i]; + } + } + nread = si; + buf = scratch; /* point to the new buffer */ + } + + /* write to socket */ +#ifndef USE_SSLEAY + bytes_written = swrite(sockfd, buf, nread); +#else + if (data->use_ssl) { + bytes_written = SSL_write(data->ssl, buf, nread); + } else { + bytes_written = swrite(sockfd, buf, nread); + } +#endif /* USE_SSLEAY */ + if(nread != bytes_written) { + failf(data, "Failed uploading file"); + return URG_FTP_WRITE_ERROR; + } + } + now = tvnow(); + ProgressShow(data, bytecount, start, now, FALSE); + urg=speedcheck(data, now); + if(urg) + return urg; + if(data->timeout && (tvdiff(now,start)>data->timeout)) { + failf(data, "Upload timed out with %d bytes sent", bytecount); + return URG_OPERATION_TIMEOUTED; + } + + } + ProgressShow(data, bytecount, start, now, TRUE); + *bytecountp = bytecount; + + return URG_OK; +} |