Initial revision
[libcurl.git] / lib / upload.c
blob2f52a37d8bb0e2d00ad8244710271980c297ff7d
1 /*****************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * The contents of this file are subject to the Mozilla Public License
9 * Version 1.0 (the "License"); you may not use this file except in
10 * compliance with the License. You may obtain a copy of the License at
11 * http://www.mozilla.org/MPL/
13 * Software distributed under the License is distributed on an "AS IS"
14 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
15 * License for the specific language governing rights and limitations
16 * under the License.
18 * The Original Code is Curl.
20 * The Initial Developer of the Original Code is Daniel Stenberg.
22 * Portions created by the Initial Developer are Copyright (C) 1998.
23 * All Rights Reserved.
25 * ------------------------------------------------------------
26 * Main author:
27 * - Daniel Stenberg <Daniel.Stenberg@haxx.nu>
29 * http://curl.haxx.nu
31 * $Source: /cvsroot/curl/curl/lib/Attic/upload.c,v $
32 * $Revision: 1.1 $
33 * $Date: 1999-12-29 14:21:39 $
34 * $Author: bagder $
35 * $State: Exp $
36 * $Locker: $
38 * ------------------------------------------------------------
39 ****************************************************************************/
41 #include "setup.h"
42 #ifdef HAVE_UNISTD_H
43 #include <unistd.h>
44 #endif
45 #ifdef HAVE_SYS_SELECT_H
46 #include <sys/select.h>
47 #endif
48 #ifdef WIN32
49 #if !defined(__GNUC__) || defined(__MINGW32__)
50 #include <winsock.h>
51 #endif
52 #include <time.h> /* for the time_t typedef! */
54 #if defined(__GNUC__) && defined(TIME_WITH_SYS_TIME)
55 #include <sys/time.h>
56 #endif
58 #endif
60 #include <curl/curl.h>
62 #ifdef __BEOS__
63 #include <net/socket.h>
64 #endif
66 #include "urldata.h"
67 #include "speedcheck.h"
68 #include "sendf.h"
69 #include "progress.h"
71 /* --- upload a stream to a socket --- */
73 UrgError Upload(struct UrlData *data,
74 int sockfd,
75 long *bytecountp)
77 fd_set writefd;
78 fd_set keepfd;
79 struct timeval interval;
80 bool keepon=TRUE;
81 char *buf = data->buffer;
82 size_t nread;
83 long bytecount=0;
84 struct timeval start;
85 struct timeval now;
86 UrgError urg;
87 char scratch[BUFSIZE * 2];
88 int i, si;
90 /* timeout every X second
91 - makes a better progressmeter (i.e even when no data is sent, the
92 meter can be updated and reflect reality)
93 - allows removal of the alarm() crap
94 - variable timeout is easier
97 myalarm(0); /* switch off the alarm-style timeout */
99 start = tvnow();
100 now = start;
102 FD_ZERO(&writefd); /* clear it */
103 FD_SET(sockfd, &writefd);
105 keepfd = writefd;
107 while(keepon) {
108 size_t bytes_written = 0;
110 writefd = keepfd; /* set this every lap in the loop */
111 interval.tv_sec = 2;
112 interval.tv_usec = 0;
114 switch(select(sockfd+1, NULL, &writefd, NULL, &interval)) {
115 case -1: /* error, stop writing */
116 keepon=FALSE;
117 continue;
118 case 0: /* timeout */
119 break;
120 default: /* write! */
121 if(data->crlf)
122 buf = data->buffer; /* put it back on the buffer */
124 nread = data->fread(buf, 1, BUFSIZE, data->in);
125 bytecount += nread;
127 if (nread==0) {
128 /* done */
129 keepon = FALSE;
130 break;
133 /* convert LF to CRLF if so asked */
134 if (data->crlf) {
135 for(i = 0, si = 0; i < (int)nread; i++, si++) {
136 if (buf[i] == 0x0a) {
137 scratch[si++] = 0x0d;
138 scratch[si] = 0x0a;
140 else {
141 scratch[si] = buf[i];
144 nread = si;
145 buf = scratch; /* point to the new buffer */
148 /* write to socket */
149 #ifndef USE_SSLEAY
150 bytes_written = swrite(sockfd, buf, nread);
151 #else
152 if (data->use_ssl) {
153 bytes_written = SSL_write(data->ssl, buf, nread);
154 } else {
155 bytes_written = swrite(sockfd, buf, nread);
157 #endif /* USE_SSLEAY */
158 if(nread != bytes_written) {
159 failf(data, "Failed uploading file");
160 return URG_FTP_WRITE_ERROR;
163 now = tvnow();
164 ProgressShow(data, bytecount, start, now, FALSE);
165 urg=speedcheck(data, now);
166 if(urg)
167 return urg;
168 if(data->timeout && (tvdiff(now,start)>data->timeout)) {
169 failf(data, "Upload timed out with %d bytes sent", bytecount);
170 return URG_OPERATION_TIMEOUTED;
174 ProgressShow(data, bytecount, start, now, TRUE);
175 *bytecountp = bytecount;
177 return URG_OK;