summaryrefslogtreecommitdiff
path: root/lib/upload.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/upload.c')
-rw-r--r--lib/upload.c178
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;
+}