~ubuntu-branches/ubuntu/edgy/curl/edgy-updates

« back to all changes in this revision

Viewing changes to lib/sendf.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2005-07-26 19:03:01 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20050726190301-x2m2vmjgc8fwnic5
Tags: 7.14.0-2ubuntu1
Synchronize with Debian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *                            | (__| |_| |  _ <| |___
6
6
 *                             \___|\___/|_| \_\_____|
7
7
 *
8
 
 * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
 
8
 * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
9
9
 *
10
10
 * This software is licensed as described in the file COPYING, which
11
11
 * you should have received as part of this distribution. The terms
18
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
19
 * KIND, either express or implied.
20
20
 *
21
 
 * $Id: sendf.c,v 1.93 2004/12/06 23:04:31 bagder Exp $
 
21
 * $Id: sendf.c,v 1.98 2005/04/07 15:27:14 bagder Exp $
22
22
 ***************************************************************************/
23
23
 
24
24
#include "setup.h"
44
44
#include "urldata.h"
45
45
#include "sendf.h"
46
46
#include "connect.h" /* for the Curl_ourerrno() proto */
 
47
#include "sslgen.h"
47
48
 
48
49
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
49
50
#include <curl/mprintf.h>
50
51
 
51
52
#ifdef HAVE_KRB4
52
 
#include "security.h"
 
53
#include "krb4.h"
 
54
#else
 
55
#define Curl_sec_write(a,b,c,d) -1
 
56
#define Curl_sec_read(a,b,c,d) -1
53
57
#endif
 
58
 
54
59
#include <string.h>
55
60
#include "memory.h"
56
61
#include "strerror.h"
154
159
void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
155
160
{
156
161
  va_list ap;
 
162
  size_t len;
157
163
  va_start(ap, fmt);
 
164
 
 
165
  vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
 
166
 
158
167
  if(data->set.errorbuffer && !data->state.errorbuf) {
159
 
    vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap);
 
168
    snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer);
160
169
    data->state.errorbuf = TRUE; /* wrote error string */
161
170
  }
162
171
  if(data->set.verbose) {
163
 
      size_t len;
164
 
 
165
 
      vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
166
 
      len = strlen(data->state.buffer);
167
 
 
168
 
      if(len < BUFSIZE - 1) {
169
 
        data->state.buffer[len] = '\n';
170
 
        data->state.buffer[++len] = '\0';
171
 
      }
172
 
      Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
 
172
    len = strlen(data->state.buffer);
 
173
    if(len < BUFSIZE - 1) {
 
174
      data->state.buffer[len] = '\n';
 
175
      data->state.buffer[++len] = '\0';
 
176
    }
 
177
    Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
173
178
  }
174
179
 
175
180
  va_end(ap);
204
209
      break;
205
210
 
206
211
    if(data->set.verbose)
207
 
      Curl_debug(data, CURLINFO_DATA_OUT, sptr, bytes_written,
208
 
                 conn->host.dispname);
 
212
      Curl_debug(data, CURLINFO_DATA_OUT, sptr, bytes_written, conn);
209
213
 
210
214
    if((size_t)bytes_written != write_len) {
211
215
      /* if not all was written at once, we must advance the pointer, decrease
234
238
{
235
239
  ssize_t bytes_written;
236
240
  CURLcode retcode;
237
 
 
238
 
#ifdef USE_SSLEAY
239
 
  /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
240
 
     If it is the second socket, we set num to 1. Otherwise to 0. This lets
241
 
     us use the correct ssl handle. */
242
241
  int num = (sockfd == conn->sock[SECONDARYSOCKET]);
243
 
  /* SSL_write() is said to return 'int' while write() and send() returns
244
 
     'size_t' */
245
 
  if (conn->ssl[num].use) {
246
 
    int err;
247
 
    char error_buffer[120]; /* OpenSSL documents that this must be at least
248
 
                               120 bytes long. */
249
 
    unsigned long sslerror;
250
 
    int rc = SSL_write(conn->ssl[num].handle, mem, (int)len);
251
 
 
252
 
    if(rc < 0) {
253
 
      err = SSL_get_error(conn->ssl[num].handle, rc);
254
 
 
255
 
      switch(err) {
256
 
      case SSL_ERROR_WANT_READ:
257
 
      case SSL_ERROR_WANT_WRITE:
258
 
        /* The operation did not complete; the same TLS/SSL I/O function
259
 
           should be called again later. This is basicly an EWOULDBLOCK
260
 
           equivalent. */
261
 
        *written = 0;
262
 
        return CURLE_OK;
263
 
      case SSL_ERROR_SYSCALL:
264
 
        failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n",
265
 
              Curl_ourerrno());
266
 
        return CURLE_SEND_ERROR;
267
 
      case SSL_ERROR_SSL:
268
 
        /*  A failure in the SSL library occurred, usually a protocol error.
269
 
            The OpenSSL error queue contains more information on the error. */
270
 
        sslerror = ERR_get_error();
271
 
        failf(conn->data, "SSL_write() error: %s\n",
272
 
              ERR_error_string(sslerror, error_buffer));
273
 
        return CURLE_SEND_ERROR;
274
 
      }
275
 
      /* a true error */
276
 
      failf(conn->data, "SSL_write() return error %d\n", err);
277
 
      return CURLE_SEND_ERROR;
278
 
    }
279
 
    bytes_written = rc;
280
 
  }
 
242
 
 
243
  if (conn->ssl[num].use)
 
244
    /* only TRUE if SSL enabled */
 
245
    bytes_written = Curl_ssl_send(conn, num, mem, len);
281
246
  else {
282
 
#else
283
 
  (void)conn;
284
 
#endif
285
 
#ifdef HAVE_KRB4
286
 
    if(conn->sec_complete) {
 
247
    if(conn->sec_complete)
 
248
      /* only TRUE if krb4 enabled */
287
249
      bytes_written = Curl_sec_write(conn, sockfd, mem, len);
288
 
    }
289
250
    else
290
 
#endif /* HAVE_KRB4 */
291
 
    {
292
251
      bytes_written = (ssize_t)swrite(sockfd, mem, len);
293
 
    }
 
252
 
294
253
    if(-1 == bytes_written) {
295
254
      int err = Curl_ourerrno();
296
255
 
312
271
        failf(conn->data, "Send failure: %s",
313
272
              Curl_strerror(conn, err));
314
273
    }
315
 
#ifdef USE_SSLEAY
316
274
  }
317
 
#endif
318
 
 
319
275
  *written = bytes_written;
320
276
  retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
321
277
 
377
333
              ssize_t *n)               /* amount bytes read */
378
334
{
379
335
  ssize_t nread;
380
 
#ifdef USE_SSLEAY
 
336
 
381
337
  /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
382
338
     If it is the second socket, we set num to 1. Otherwise to 0. This lets
383
339
     us use the correct ssl handle. */
385
341
 
386
342
  *n=0; /* reset amount to zero */
387
343
 
388
 
  if (conn->ssl[num].use) {
389
 
    nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, (int)buffersize);
390
 
 
391
 
    if(nread < 0) {
392
 
      /* failed SSL_read */
393
 
      int err = SSL_get_error(conn->ssl[num].handle, (int)nread);
394
 
 
395
 
      switch(err) {
396
 
      case SSL_ERROR_NONE: /* this is not an error */
397
 
      case SSL_ERROR_ZERO_RETURN: /* no more data */
398
 
        break;
399
 
      case SSL_ERROR_WANT_READ:
400
 
      case SSL_ERROR_WANT_WRITE:
401
 
        /* there's data pending, re-invoke SSL_read() */
402
 
        return -1; /* basicly EWOULDBLOCK */
403
 
      default:
404
 
        /* openssl/ssl.h says "look at error stack/return value/errno" */
405
 
        {
406
 
          char error_buffer[120]; /* OpenSSL documents that this must be at
407
 
                                     least 120 bytes long. */
408
 
          unsigned long sslerror = ERR_get_error();
409
 
          failf(conn->data, "SSL read: %s, errno %d",
410
 
                ERR_error_string(sslerror, error_buffer),
411
 
                Curl_ourerrno() );
412
 
        }
413
 
        return CURLE_RECV_ERROR;
414
 
      }
415
 
    }
 
344
  if(conn->ssl[num].use) {
 
345
    nread = Curl_ssl_recv(conn, num, buf, buffersize);
 
346
 
 
347
    if(nread == -1)
 
348
      return -1; /* -1 from Curl_ssl_recv() means EWOULDBLOCK */
416
349
  }
417
350
  else {
418
 
#else
419
 
    (void)conn;
420
 
#endif
421
351
    *n=0; /* reset amount to zero */
422
 
#ifdef HAVE_KRB4
423
352
    if(conn->sec_complete)
424
353
      nread = Curl_sec_read(conn, sockfd, buf, buffersize);
425
354
    else
426
 
#endif
427
355
      nread = sread(sockfd, buf, buffersize);
428
356
 
429
357
    if(-1 == nread) {
435
363
#endif
436
364
        return -1;
437
365
    }
438
 
 
439
 
#ifdef USE_SSLEAY
440
366
  }
441
 
#endif /* USE_SSLEAY */
442
367
  *n = nread;
443
368
  return CURLE_OK;
444
369
}
468
393
}
469
394
 
470
395
int Curl_debug(struct SessionHandle *data, curl_infotype type,
471
 
               char *ptr, size_t size, char *host)
 
396
               char *ptr, size_t size,
 
397
               struct connectdata *conn)
472
398
{
473
399
  int rc;
474
 
  if(data->set.printhost && host) {
 
400
  if(data->set.printhost && conn && conn->host.dispname) {
475
401
    char buffer[160];
476
402
    const char *t=NULL;
 
403
    const char *w="Data";
477
404
    switch (type) {
478
405
    case CURLINFO_HEADER_IN:
 
406
      w = "Header";
479
407
    case CURLINFO_DATA_IN:
480
408
      t = "from";
481
409
      break;
482
410
    case CURLINFO_HEADER_OUT:
 
411
      w = "Header";
483
412
    case CURLINFO_DATA_OUT:
484
413
      t = "to";
485
414
      break;
488
417
    }
489
418
 
490
419
    if(t) {
491
 
      snprintf(buffer, sizeof(buffer), "[Data %s %s]", t, host);
 
420
      snprintf(buffer, sizeof(buffer), "[%s %s %s%s]", w, t,
 
421
               conn->xfertype==NORMAL?"":
 
422
               (conn->xfertype==SOURCE3RD?"source ":"target "),
 
423
               conn->host.dispname);
492
424
      rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
493
425
      if(rc)
494
426
        return rc;