1
/*****************************************************************************
3
* Project ___| | | | _ \| |
5
* | (__| |_| | _ <| |___
6
* \___|\___/|_| \_\_____|
8
* Copyright (C) 2002, Daniel Stenberg, <daniel@haxx.se>, et al.
10
* In order to be useful for every potential user, curl and libcurl are
11
* dual-licensed under the MPL and the MIT/X-derivate licenses.
13
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
14
* copies of the Software, and permit persons to whom the Software is
15
* furnished to do so, under the terms of the MPL or the MIT/X-derivate
16
* licenses. You may pick one of these licenses.
18
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
* KIND, either express or implied.
21
* $Id: sendf.c,v 1.44 2002/02/05 15:33:00 bagder Exp $
22
*****************************************************************************/
31
#ifdef HAVE_SYS_TYPES_H
32
#include <sys/types.h>
35
#ifdef HAVE_SYS_SOCKET_H
36
#include <sys/socket.h> /* required for send() & recv() prototypes */
42
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
46
#include <curl/curl.h>
50
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
51
#include <curl/mprintf.h>
57
/* The last #include file should be: */
62
/* returns last node in linked list */
63
static struct curl_slist *slist_get_last(struct curl_slist *list)
65
struct curl_slist *item;
67
/* if caller passed us a NULL, return now */
71
/* loop through to find the last item */
79
/* append a struct to the linked list. It always retunrs the address of the
80
* first record, so that you can sure this function as an initialization
81
* function as well as an append function. If you find this bothersome,
82
* then simply create a separate _init function and call it appropriately from
83
* within the proram. */
84
struct curl_slist *curl_slist_append(struct curl_slist *list,
87
struct curl_slist *last;
88
struct curl_slist *new_item;
90
new_item = (struct curl_slist *) malloc(sizeof(struct curl_slist));
92
new_item->next = NULL;
93
new_item->data = strdup(data);
96
fprintf(stderr, "Cannot allocate memory for QUOTE list.\n");
101
last = slist_get_last(list);
102
last->next = new_item;
106
/* if this is the first item, then new_item *is* the list */
110
/* be nice and clean up resources */
111
void curl_slist_free_all(struct curl_slist *list)
113
struct curl_slist *next;
114
struct curl_slist *item;
132
/* Curl_infof() is for info message along the way */
134
void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
137
if(data->set.verbose) {
139
fputs("* ", data->set.err);
140
vfprintf(data->set.err, fmt, ap);
145
/* Curl_failf() is for messages stating why we failed.
146
* The message SHALL NOT include any LF or CR.
149
void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
153
if(data->set.errorbuffer && !data->state.errorbuf) {
154
vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap);
155
data->state.errorbuf = TRUE; /* wrote error string */
160
/* Curl_sendf() sends formated data to the server */
161
CURLcode Curl_sendf(int sockfd, struct connectdata *conn,
162
const char *fmt, ...)
164
struct SessionHandle *data = conn->data;
165
ssize_t bytes_written;
170
s = vaprintf(fmt, ap); /* returns an allocated string */
173
return 0; /* failure */
174
if(data->set.verbose)
175
fprintf(data->set.err, "> %s", s);
177
/* Write the buffer to the socket */
178
result = Curl_write(conn, sockfd, s, strlen(s), &bytes_written);
180
free(s); /* free the output string */
186
* Curl_write() is an internal write function that sends plain (binary) data
187
* to the server. Works with plain sockets, SSL or kerberos.
190
CURLcode Curl_write(struct connectdata *conn, int sockfd,
191
void *mem, size_t len,
194
ssize_t bytes_written;
197
/* SSL_write() is said to return 'int' while write() and send() returns
201
int rc = SSL_write(conn->ssl.handle, mem, len);
204
err = SSL_get_error(conn->ssl.handle, rc);
207
case SSL_ERROR_WANT_READ:
208
case SSL_ERROR_WANT_WRITE:
209
/* this is basicly the EWOULDBLOCK equivalent */
214
failf(conn->data, "SSL_write() return error %d\n", err);
215
return CURLE_WRITE_ERROR;
222
if(conn->sec_complete) {
223
bytes_written = Curl_sec_write(conn, sockfd, mem, len);
228
bytes_written = swrite(sockfd, mem, len);
230
if(-1 == bytes_written) {
232
if(WSAEWOULDBLOCK == GetLastError())
234
if(EWOULDBLOCK == errno)
237
/* this is just a case of EWOULDBLOCK */
246
*written = bytes_written;
247
return (-1 != bytes_written)?CURLE_OK:CURLE_WRITE_ERROR;
250
/* client_write() sends data to the write callback(s)
252
The bit pattern defines to what "streams" to write to. Body and/or header.
253
The defines are in sendf.h of course.
255
CURLcode Curl_client_write(struct SessionHandle *data,
265
if(type & CLIENTWRITE_BODY) {
266
wrote = data->set.fwrite(ptr, 1, len, data->set.out);
268
failf (data, "Failed writing body");
269
return CURLE_WRITE_ERROR;
272
if((type & CLIENTWRITE_HEADER) &&
273
(data->set.fwrite_header || data->set.writeheader) ) {
275
* Write headers to the same callback or to the especially setup
276
* header callback function (added after version 7.7.1).
278
curl_write_callback writeit=
279
data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite;
281
wrote = writeit(ptr, 1, len, data->set.writeheader);
283
failf (data, "Failed writing header");
284
return CURLE_WRITE_ERROR;
292
* Internal read-from-socket function. This is meant to deal with plain
293
* sockets, SSL sockets and kerberos sockets.
295
* If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
296
* a regular CURLcode value.
298
int Curl_read(struct connectdata *conn,
311
nread = SSL_read(conn->ssl.handle, buf, buffersize);
314
/* successful read */
317
err = SSL_get_error(conn->ssl.handle, nread);
320
case SSL_ERROR_NONE: /* this is not an error */
321
case SSL_ERROR_ZERO_RETURN: /* no more data */
322
loop=0; /* get out of loop */
324
case SSL_ERROR_WANT_READ:
325
case SSL_ERROR_WANT_WRITE:
326
/* if there's data pending, then we re-invoke SSL_read() */
330
if(loop && SSL_pending(conn->ssl.handle))
331
return -1; /* basicly EWOULDBLOCK */
336
if(conn->sec_complete)
337
nread = Curl_sec_read(conn, sockfd, buf, buffersize);
340
nread = sread (sockfd, buf, buffersize);
344
if(WSAEWOULDBLOCK == GetLastError())
346
if(EWOULDBLOCK == errno)
353
#endif /* USE_SSLEAY */
361
* eval: (load-file "../curl-mode.el")
364
* vim: et sw=2 ts=2 sts=2 tw=78