~ubuntu-branches/ubuntu/lucid/curl/lucid-201101212007

« back to all changes in this revision

Viewing changes to lib/easy.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-05-16 15:16:54 UTC
  • mto: (3.1.1 lenny) (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: james.westby@ubuntu.com-20070516151654-x9nkigtr2j0i8d0v
Tags: upstream-7.16.2
ImportĀ upstreamĀ versionĀ 7.16.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *                            | (__| |_| |  _ <| |___
6
6
 *                             \___|\___/|_| \_\_____|
7
7
 *
8
 
 * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
 
8
 * Copyright (C) 1998 - 2007, 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: easy.c,v 1.79 2006-07-25 11:35:35 giva Exp $
 
21
 * $Id: easy.c,v 1.101 2007-04-08 22:49:38 yangtse Exp $
22
22
 ***************************************************************************/
23
23
 
24
24
#include "setup.h"
29
29
#include <stdarg.h>
30
30
#include <stdlib.h>
31
31
#include <ctype.h>
32
 
#ifdef HAVE_SYS_TYPES_H
33
 
#include <sys/types.h>
34
 
#endif
35
 
#ifdef HAVE_SYS_STAT_H
36
 
#include <sys/stat.h>
37
 
#endif
38
 
 
39
32
#include <errno.h>
40
33
 
41
34
#include "strequal.h"
42
35
 
43
 
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
 
36
#ifdef WIN32
44
37
#include <time.h>
45
38
#include <io.h>
46
39
#else
47
40
#ifdef HAVE_SYS_SOCKET_H
48
41
#include <sys/socket.h>
49
42
#endif
 
43
#ifdef HAVE_NETINET_IN_H
50
44
#include <netinet/in.h>
 
45
#endif
 
46
#ifdef HAVE_SYS_TIME_H
51
47
#include <sys/time.h>
 
48
#endif
52
49
#ifdef HAVE_UNISTD_H
53
50
#include <unistd.h>
54
51
#endif
 
52
#ifdef HAVE_NETDB_H
55
53
#include <netdb.h>
 
54
#endif
56
55
#ifdef HAVE_ARPA_INET_H
57
56
#include <arpa/inet.h>
58
57
#endif
59
58
#ifdef HAVE_NET_IF_H
60
59
#include <net/if.h>
61
60
#endif
 
61
#ifdef HAVE_SYS_IOCTL_H
62
62
#include <sys/ioctl.h>
 
63
#endif
63
64
#include <signal.h>
64
65
 
65
66
#ifdef HAVE_SYS_PARAM_H
66
67
#include <sys/param.h>
67
68
#endif
68
69
 
69
 
#ifdef HAVE_SYS_SELECT_H
70
 
#include <sys/select.h>
71
 
#endif
72
 
 
73
70
#endif  /* WIN32 ... */
74
71
 
75
72
#include "urldata.h"
84
81
#include "memory.h"
85
82
#include "progress.h"
86
83
#include "easyif.h"
 
84
#include "select.h"
87
85
#include "sendf.h" /* for failf function prototype */
 
86
#include <ca-bundle.h>
88
87
 
89
88
#define _MPRINTF_REPLACE /* use our functions only */
90
89
#include <curl/mprintf.h>
104
103
/* The last #include file should be: */
105
104
#include "memdebug.h"
106
105
 
107
 
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
 
106
#ifdef USE_WINSOCK
108
107
/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
109
108
   of win32_init() */
110
109
static void win32_cleanup(void)
120
119
  WSADATA wsaData;
121
120
  int err;
122
121
 
123
 
#ifdef ENABLE_IPV6
124
 
  wVersionRequested = MAKEWORD(2, 0);
125
 
#else
126
 
  wVersionRequested = MAKEWORD(1, 1);
 
122
#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
 
123
  Error IPV6_requires_winsock2
127
124
#endif
128
125
 
 
126
  wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
 
127
 
129
128
  err = WSAStartup(wVersionRequested, &wsaData);
130
129
 
131
130
  if (err != 0)
224
223
  Curl_ccalloc = (curl_calloc_callback)calloc;
225
224
 
226
225
  if (flags & CURL_GLOBAL_SSL)
227
 
    if (!Curl_ssl_init())
 
226
    if (!Curl_ssl_init()) {
 
227
      DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
228
228
      return CURLE_FAILED_INIT;
 
229
    }
229
230
 
230
231
  if (flags & CURL_GLOBAL_WIN32)
231
 
    if (win32_init() != CURLE_OK)
 
232
    if (win32_init() != CURLE_OK) {
 
233
      DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
232
234
      return CURLE_FAILED_INIT;
 
235
    }
233
236
 
234
 
#ifdef _AMIGASF
235
 
  if(!amiga_init())
 
237
#ifdef __AMIGA__
 
238
  if(!amiga_init()) {
 
239
    DEBUGF(fprintf(stderr, "Error: amiga_init failed\n"));
236
240
    return CURLE_FAILED_INIT;
 
241
  }
237
242
#endif
238
243
 
239
244
#ifdef USE_LIBIDN
296
301
  if (init_flags & CURL_GLOBAL_WIN32)
297
302
    win32_cleanup();
298
303
 
299
 
#ifdef _AMIGASF
 
304
#ifdef __AMIGA__
300
305
  amiga_cleanup();
301
306
#endif
302
307
 
315
320
  /* Make sure we inited the global SSL stuff */
316
321
  if (!initialized) {
317
322
    res = curl_global_init(CURL_GLOBAL_DEFAULT);
318
 
    if(res)
 
323
    if(res) {
319
324
      /* something in the global init failed, return nothing */
 
325
      DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
320
326
      return NULL;
 
327
    }
321
328
  }
322
329
 
323
330
  /* We use curl_open() with undefined URL so far */
324
331
  res = Curl_open(&data);
325
 
  if(res != CURLE_OK)
 
332
  if(res != CURLE_OK) {
 
333
    DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
326
334
    return NULL;
 
335
  }
327
336
 
328
337
  return data;
329
338
}
388
397
  mcode = curl_multi_add_handle(multi, easy);
389
398
  if(mcode) {
390
399
    curl_multi_cleanup(multi);
391
 
    return CURLE_FAILED_INIT;
 
400
    if(mcode == CURLM_OUT_OF_MEMORY)
 
401
      return CURLE_OUT_OF_MEMORY;
 
402
    else
 
403
      return CURLE_FAILED_INIT;
392
404
  }
393
405
 
394
406
  /* we start some action by calling perform right away */
411
423
    /* get file descriptors from the transfers */
412
424
    curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
413
425
 
414
 
    rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
 
426
    rc = Curl_select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
415
427
 
416
428
    if(rc == -1)
417
429
      /* select error */
467
479
 
468
480
  }
469
481
 
 
482
  if(!data->state.connc) {
 
483
    /* oops, no connection cache, make one up */
 
484
    data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1);
 
485
    if(!data->state.connc)
 
486
      return CURLE_OUT_OF_MEMORY;
 
487
  }
 
488
 
470
489
  return Curl_perform(data);
471
490
}
472
491
#endif
494
513
  data->multi = multi;
495
514
}
496
515
 
 
516
void Curl_easy_initHandleData(struct SessionHandle *data)
 
517
{
 
518
    memset(&data->reqdata, 0, sizeof(struct HandleData));
 
519
 
 
520
    data->reqdata.maxdownload = -1;
 
521
}
 
522
 
497
523
/*
498
524
 * curl_easy_getinfo() is an external interface that allows an app to retrieve
499
525
 * information from a performed transfer and similar.
541
567
 
542
568
    /* copy all userdefined values */
543
569
    outcurl->set = data->set;
544
 
    outcurl->state.numconnects = data->state.numconnects;
545
 
    outcurl->state.connects = (struct connectdata **)
546
 
      malloc(sizeof(struct connectdata *) * outcurl->state.numconnects);
547
 
 
548
 
    if(!outcurl->state.connects) {
 
570
 
 
571
    if(data->state.used_interface == Curl_if_multi)
 
572
      outcurl->state.connc = data->state.connc;
 
573
    else
 
574
      outcurl->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1);
 
575
 
 
576
    if(!outcurl->state.connc)
549
577
      break;
550
 
    }
551
 
 
552
 
    memset(outcurl->state.connects, 0,
553
 
           sizeof(struct connectdata *)*outcurl->state.numconnects);
554
578
 
555
579
    outcurl->state.lastconnect = -1;
556
580
 
572
596
#endif   /* CURL_DISABLE_HTTP */
573
597
 
574
598
    /* duplicate all values in 'change' */
 
599
 
575
600
    if(data->change.url) {
576
601
      outcurl->change.url = strdup(data->change.url);
577
602
      if(!outcurl->change.url)
578
603
        break;
579
604
      outcurl->change.url_alloc = TRUE;
580
605
    }
581
 
    if(data->change.proxy) {
582
 
      outcurl->change.proxy = strdup(data->change.proxy);
583
 
      if(!outcurl->change.proxy)
584
 
        break;
585
 
      outcurl->change.proxy_alloc = TRUE;
586
 
    }
 
606
 
587
607
    if(data->change.referer) {
588
608
      outcurl->change.referer = strdup(data->change.referer);
589
609
      if(!outcurl->change.referer)
597
617
      break;
598
618
#endif
599
619
 
 
620
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
 
621
    outcurl->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
 
622
                                     CURL_ICONV_CODESET_OF_NETWORK);
 
623
    outcurl->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
 
624
                                      CURL_ICONV_CODESET_OF_HOST);
 
625
    outcurl->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
 
626
                                  CURL_ICONV_CODESET_FOR_UTF8);
 
627
#endif
 
628
 
 
629
    Curl_easy_initHandleData(outcurl);
 
630
 
 
631
    outcurl->magic = CURLEASY_MAGIC_NUMBER;
 
632
 
600
633
    fail = FALSE; /* we reach this point and thus we are OK */
601
634
 
602
635
  } while(0);
603
636
 
604
637
  if(fail) {
605
638
    if(outcurl) {
606
 
      if(outcurl->state.connects)
607
 
        free(outcurl->state.connects);
 
639
      if((outcurl->state.connc->type == CONNCACHE_PRIVATE) &&
 
640
         outcurl->state.connc)
 
641
        Curl_rm_connc(outcurl->state.connc);
608
642
      if(outcurl->state.headerbuff)
609
643
        free(outcurl->state.headerbuff);
610
 
      if(outcurl->change.proxy)
611
 
        free(outcurl->change.proxy);
612
644
      if(outcurl->change.url)
613
645
        free(outcurl->change.url);
614
646
      if(outcurl->change.referer)
629
661
{
630
662
  struct SessionHandle *data = (struct SessionHandle *)curl;
631
663
 
 
664
  Curl_safefree(data->reqdata.pathbuffer);
 
665
  data->reqdata.pathbuffer=NULL;
 
666
 
 
667
  Curl_safefree(data->reqdata.proto.generic);
 
668
  data->reqdata.proto.generic=NULL;
 
669
 
632
670
  /* zero out UserDefined data: */
633
671
  memset(&data->set, 0, sizeof(struct UserDefined));
634
672
 
635
673
  /* zero out Progress data: */
636
674
  memset(&data->progress, 0, sizeof(struct Progress));
637
675
 
 
676
  /* init Handle data */
 
677
  Curl_easy_initHandleData(data);
 
678
 
638
679
  /* The remainder of these calls have been taken from Curl_open() */
639
680
 
640
681
  data->set.out = stdout; /* default output to stdout */
680
721
  /* This is our prefered CA cert bundle since install time */
681
722
  data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
682
723
#endif
 
724
 
 
725
  data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
 
726
                                                      type */
683
727
}
684
728
 
685
729
#ifdef CURL_DOES_CONVERSIONS
706
750
    /* do the translation ourselves */
707
751
    char *input_ptr, *output_ptr;
708
752
    size_t in_bytes, out_bytes, rc;
 
753
    int error;
709
754
 
710
755
    /* open an iconv conversion descriptor if necessary */
711
756
    if(data->outbound_cd == (iconv_t)-1) {
712
757
      data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
713
758
                                     CURL_ICONV_CODESET_OF_HOST);
714
759
      if(data->outbound_cd == (iconv_t)-1) {
 
760
        error = ERRNO;
715
761
        failf(data,
716
762
              "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
717
763
               CURL_ICONV_CODESET_OF_NETWORK,
718
764
               CURL_ICONV_CODESET_OF_HOST,
719
 
               errno, strerror(errno));
 
765
               error, strerror(error));
720
766
        return CURLE_CONV_FAILED;
721
767
      }
722
768
    }
726
772
    rc = iconv(data->outbound_cd, (const char**)&input_ptr, &in_bytes,
727
773
               &output_ptr, &out_bytes);
728
774
    if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
 
775
      error = ERRNO;
729
776
      failf(data,
730
777
        "The Curl_convert_to_network iconv call failed with errno %i: %s",
731
 
             errno, strerror(errno));
 
778
             error, strerror(error));
732
779
      return CURLE_CONV_FAILED;
733
780
    }
734
781
#else
763
810
    /* do the translation ourselves */
764
811
    char *input_ptr, *output_ptr;
765
812
    size_t in_bytes, out_bytes, rc;
 
813
    int error;
766
814
 
767
815
    /* open an iconv conversion descriptor if necessary */
768
816
    if(data->inbound_cd == (iconv_t)-1) {
769
817
      data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
770
818
                                    CURL_ICONV_CODESET_OF_NETWORK);
771
819
      if(data->inbound_cd == (iconv_t)-1) {
 
820
        error = ERRNO;
772
821
        failf(data,
773
822
              "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
774
823
               CURL_ICONV_CODESET_OF_HOST,
775
824
               CURL_ICONV_CODESET_OF_NETWORK,
776
 
               errno, strerror(errno));
 
825
               error, strerror(error));
777
826
        return CURLE_CONV_FAILED;
778
827
      }
779
828
    }
783
832
    rc = iconv(data->inbound_cd, (const char **)&input_ptr, &in_bytes,
784
833
               &output_ptr, &out_bytes);
785
834
    if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
 
835
      error = ERRNO;
786
836
      failf(data,
787
837
        "The Curl_convert_from_network iconv call failed with errno %i: %s",
788
 
             errno, strerror(errno));
 
838
             error, strerror(error));
789
839
      return CURLE_CONV_FAILED;
790
840
    }
791
841
#else
820
870
    /* do the translation ourselves */
821
871
    char *input_ptr, *output_ptr;
822
872
    size_t in_bytes, out_bytes, rc;
 
873
    int error;
823
874
 
824
875
    /* open an iconv conversion descriptor if necessary */
825
876
    if(data->utf8_cd == (iconv_t)-1) {
826
877
      data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
827
878
                                 CURL_ICONV_CODESET_FOR_UTF8);
828
879
      if(data->utf8_cd == (iconv_t)-1) {
 
880
        error = ERRNO;
829
881
        failf(data,
830
882
              "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
831
883
               CURL_ICONV_CODESET_OF_HOST,
832
884
               CURL_ICONV_CODESET_FOR_UTF8,
833
 
               errno, strerror(errno));
 
885
               error, strerror(error));
834
886
        return CURLE_CONV_FAILED;
835
887
      }
836
888
    }
840
892
    rc = iconv(data->utf8_cd, (const char**)&input_ptr, &in_bytes,
841
893
               &output_ptr, &out_bytes);
842
894
    if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
 
895
      error = ERRNO;
843
896
      failf(data,
844
897
        "The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
845
 
             errno, strerror(errno));
 
898
             error, strerror(error));
846
899
      return CURLE_CONV_FAILED;
847
900
    }
848
901
    if (output_ptr < input_ptr) {