~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: 2008-02-08 11:20:41 UTC
  • mto: (3.1.1 lenny) (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 26.
  • Revision ID: james.westby@ubuntu.com-20080208112041-hed7sb5r6ghmjf8v
Tags: upstream-7.18.0
ImportĀ upstreamĀ versionĀ 7.18.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *                            | (__| |_| |  _ <| |___
6
6
 *                             \___|\___/|_| \_\_____|
7
7
 *
8
 
 * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
 
8
 * Copyright (C) 1998 - 2008, 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.108 2007-08-26 05:53:26 danf Exp $
 
21
 * $Id: easy.c,v 1.113 2008-01-15 22:44:12 bagder Exp $
22
22
 ***************************************************************************/
23
23
 
24
24
#include "setup.h"
127
127
 
128
128
  err = WSAStartup(wVersionRequested, &wsaData);
129
129
 
130
 
  if (err != 0)
 
130
  if(err != 0)
131
131
    /* Tell the user that we couldn't find a useable */
132
132
    /* winsock.dll.     */
133
133
    return CURLE_FAILED_INIT;
138
138
  /* wVersionRequested in wVersion. wHighVersion contains the */
139
139
  /* highest supported version. */
140
140
 
141
 
  if ( LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
 
141
  if( LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
142
142
       HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
143
143
    /* Tell the user that we couldn't find a useable */
144
144
 
168
168
  char buf[60];
169
169
  UINT cp = GetACP();
170
170
 
171
 
  if (!getenv("CHARSET") && cp > 0) {
 
171
  if(!getenv("CHARSET") && cp > 0) {
172
172
    snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
173
173
    putenv(buf);
174
174
  }
212
212
 */
213
213
CURLcode curl_global_init(long flags)
214
214
{
215
 
  if (initialized++)
 
215
  if(initialized++)
216
216
    return CURLE_OK;
217
217
 
218
218
  /* Setup the default memory functions here (again) */
222
222
  Curl_cstrdup = (curl_strdup_callback)system_strdup;
223
223
  Curl_ccalloc = (curl_calloc_callback)calloc;
224
224
 
225
 
  if (flags & CURL_GLOBAL_SSL)
226
 
    if (!Curl_ssl_init()) {
 
225
  if(flags & CURL_GLOBAL_SSL)
 
226
    if(!Curl_ssl_init()) {
227
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)
232
 
    if (win32_init() != CURLE_OK) {
 
231
  if(flags & CURL_GLOBAL_WIN32)
 
232
    if(win32_init() != CURLE_OK) {
233
233
      DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
234
234
      return CURLE_FAILED_INIT;
235
235
    }
267
267
  CURLcode code = CURLE_OK;
268
268
 
269
269
  /* Invalid input, return immediately */
270
 
  if (!m || !f || !r || !s || !c)
 
270
  if(!m || !f || !r || !s || !c)
271
271
    return CURLE_FAILED_INIT;
272
272
 
273
273
  /* Already initialized, don't do it again */
274
 
  if ( initialized )
 
274
  if( initialized )
275
275
    return CURLE_OK;
276
276
 
277
277
  /* Call the actual init function first */
278
278
  code = curl_global_init(flags);
279
 
  if (code == CURLE_OK) {
 
279
  if(code == CURLE_OK) {
280
280
    Curl_cmalloc = m;
281
281
    Curl_cfree = f;
282
282
    Curl_cstrdup = s;
293
293
 */
294
294
void curl_global_cleanup(void)
295
295
{
296
 
  if (!initialized)
 
296
  if(!initialized)
297
297
    return;
298
298
 
299
 
  if (--initialized)
 
299
  if(--initialized)
300
300
    return;
301
301
 
302
302
  Curl_global_host_cache_dtor();
303
303
 
304
 
  if (init_flags & CURL_GLOBAL_SSL)
 
304
  if(init_flags & CURL_GLOBAL_SSL)
305
305
    Curl_ssl_cleanup();
306
306
 
307
 
  if (init_flags & CURL_GLOBAL_WIN32)
 
307
  if(init_flags & CURL_GLOBAL_WIN32)
308
308
    win32_cleanup();
309
309
 
310
310
#ifdef __AMIGA__
324
324
  struct SessionHandle *data;
325
325
 
326
326
  /* Make sure we inited the global SSL stuff */
327
 
  if (!initialized) {
 
327
  if(!initialized) {
328
328
    res = curl_global_init(CURL_GLOBAL_DEFAULT);
329
329
    if(res) {
330
330
      /* something in the global init failed, return nothing */
465
465
  if(!data)
466
466
    return CURLE_BAD_FUNCTION_ARGUMENT;
467
467
 
468
 
  if ( ! (data->share && data->share->hostcache) ) {
469
 
 
470
 
    if (Curl_global_host_cache_use(data) &&
471
 
        (data->dns.hostcachetype != HCACHE_GLOBAL)) {
472
 
      if (data->dns.hostcachetype == HCACHE_PRIVATE)
 
468
  if( ! (data->share && data->share->hostcache) ) {
 
469
    /* this handle is not using a shared dns cache */
 
470
 
 
471
    if(data->set.global_dns_cache &&
 
472
       (data->dns.hostcachetype != HCACHE_GLOBAL)) {
 
473
      /* global dns cache was requested but still isn't */
 
474
      struct curl_hash *ptr;
 
475
 
 
476
      if(data->dns.hostcachetype == HCACHE_PRIVATE)
 
477
        /* if the current cache is private, kill it first */
473
478
        Curl_hash_destroy(data->dns.hostcache);
474
 
      data->dns.hostcache = Curl_global_host_cache_get();
475
 
      data->dns.hostcachetype = HCACHE_GLOBAL;
 
479
 
 
480
      ptr = Curl_global_host_cache_init();
 
481
      if(ptr) {
 
482
        /* only do this if the global cache init works */
 
483
        data->dns.hostcache = ptr;
 
484
        data->dns.hostcachetype = HCACHE_GLOBAL;
 
485
      }
476
486
    }
477
487
 
478
 
    if (!data->dns.hostcache) {
 
488
    if(!data->dns.hostcache) {
479
489
      data->dns.hostcachetype = HCACHE_PRIVATE;
480
490
      data->dns.hostcache = Curl_mk_dnscache();
481
491
 
520
530
                        void *multi)
521
531
{
522
532
  data->multi = multi;
523
 
  if (multi == NULL)
 
533
  if(multi == NULL)
524
534
    /* the association is cleared, mark the easy handle as not used by an
525
535
       interface */
526
536
    data->state.used_interface = Curl_if_none;
528
538
 
529
539
void Curl_easy_initHandleData(struct SessionHandle *data)
530
540
{
531
 
    memset(&data->reqdata, 0, sizeof(struct HandleData));
 
541
    memset(&data->req, 0, sizeof(struct SingleRequest));
532
542
 
533
 
    data->reqdata.maxdownload = -1;
 
543
    data->req.maxdownload = -1;
534
544
}
535
545
 
536
546
/*
579
589
    outcurl->state.headersize=HEADERSIZE;
580
590
 
581
591
    /* copy all userdefined values */
582
 
    if (Curl_dupset(outcurl, data) != CURLE_OK)
 
592
    if(Curl_dupset(outcurl, data) != CURLE_OK)
583
593
      break;
584
594
 
585
595
    if(data->state.used_interface == Curl_if_multi)
600
610
      /* If cookies are enabled in the parent handle, we enable them
601
611
         in the clone as well! */
602
612
      outcurl->cookies = Curl_cookie_init(data,
603
 
                                            data->cookies->filename,
604
 
                                            outcurl->cookies,
605
 
                                            data->set.cookiesession);
 
613
                                          data->cookies->filename,
 
614
                                          outcurl->cookies,
 
615
                                          data->set.cookiesession);
606
616
      if(!outcurl->cookies) {
607
617
        break;
608
618
      }
676
686
{
677
687
  struct SessionHandle *data = (struct SessionHandle *)curl;
678
688
 
679
 
  Curl_safefree(data->reqdata.pathbuffer);
680
 
  data->reqdata.pathbuffer=NULL;
 
689
  Curl_safefree(data->state.pathbuffer);
 
690
  data->state.pathbuffer=NULL;
681
691
 
682
 
  Curl_safefree(data->reqdata.proto.generic);
683
 
  data->reqdata.proto.generic=NULL;
 
692
  Curl_safefree(data->state.proto.generic);
 
693
  data->state.proto.generic=NULL;
684
694
 
685
695
  /* zero out UserDefined data: */
686
696
  Curl_freeset(data);
744
754
  data->set.new_directory_perms = 0755; /* Default permissions */
745
755
}
746
756
 
 
757
/*
 
758
 * curl_easy_pause() allows an application to pause or unpause a specific
 
759
 * transfer and direction. This function sets the full new state for the
 
760
 * current connection this easy handle operates on.
 
761
 *
 
762
 * NOTE: if you have the receiving paused and you call this function to remove
 
763
 * the pausing, you may get your write callback called at this point.
 
764
 *
 
765
 * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
 
766
 */
 
767
CURLcode curl_easy_pause(CURL *curl, int action)
 
768
{
 
769
  struct SessionHandle *data = (struct SessionHandle *)curl;
 
770
  struct SingleRequest *k = &data->req;
 
771
  CURLcode result = CURLE_OK;
 
772
 
 
773
  /* first switch off both pause bits */
 
774
  int newstate = k->keepon &~ (KEEP_READ_PAUSE| KEEP_WRITE_PAUSE);
 
775
 
 
776
  /* set the new desired pause bits */
 
777
  newstate |= ((action & CURLPAUSE_RECV)?KEEP_READ_PAUSE:0) |
 
778
    ((action & CURLPAUSE_SEND)?KEEP_WRITE_PAUSE:0);
 
779
 
 
780
  /* put it back in the keepon */
 
781
  k->keepon = newstate;
 
782
 
 
783
  if(!(newstate & KEEP_READ_PAUSE) && data->state.tempwrite) {
 
784
    /* we have a buffer for writing that we now seem to be able to deliver since
 
785
       the receive pausing is lifted! */
 
786
 
 
787
    /* get the pointer, type and length in local copies since the function may
 
788
       return PAUSE again and then we'll get a new copy allocted and stored in
 
789
       the tempwrite variables */
 
790
    char *tempwrite = data->state.tempwrite;
 
791
    size_t tempsize = data->state.tempwritesize;
 
792
    int temptype = data->state.tempwritetype;
 
793
    size_t chunklen;
 
794
 
 
795
    /* clear tempwrite here just to make sure it gets cleared if there's no
 
796
       further use of it, and make sure we don't clear it after the function
 
797
       invoke as it may have been set to a new value by then */
 
798
    data->state.tempwrite = NULL;
 
799
 
 
800
    /* since the write callback API is define to never exceed
 
801
       CURL_MAX_WRITE_SIZE bytes in a single call, and since we may in fact
 
802
       have more data than that in our buffer here, we must loop sending the
 
803
       data in multiple calls until there's no data left or we get another
 
804
       pause returned.
 
805
 
 
806
       A tricky part is that the function we call will "buffer" the data
 
807
       itself when it pauses on a particular buffer, so we may need to do some
 
808
       extra trickery if we get a pause return here.
 
809
    */
 
810
    do {
 
811
      chunklen = (tempsize > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:tempsize;
 
812
 
 
813
      result = Curl_client_write(data->state.current_conn,
 
814
                                 temptype, tempwrite, chunklen);
 
815
      if(!result)
 
816
        /* failures abort the loop at once */
 
817
        break;
 
818
 
 
819
      if(data->state.tempwrite && (tempsize - chunklen)) {
 
820
        /* Ouch, the reading is again paused and the block we send is now
 
821
           "cached". If this is the final chunk we can leave it like this, but
 
822
           if we have more chunks that is cached after this, we need to free
 
823
           the newly cached one and put back a version that is truly the entire
 
824
           contents that is saved for later
 
825
        */
 
826
        char *newptr;
 
827
 
 
828
        free(data->state.tempwrite); /* free the one just cached as it isn't
 
829
                                        enough */
 
830
 
 
831
        /* note that tempsize is still the size as before the callback was
 
832
           used, and thus the whole piece of data to keep */
 
833
        newptr = malloc(tempsize);
 
834
        if(!newptr) {
 
835
          result = CURLE_OUT_OF_MEMORY;
 
836
          /* tempwrite will be freed further down */
 
837
          break;
 
838
        }
 
839
        data->state.tempwrite = newptr; /* store new pointer */
 
840
        memcpy(newptr, tempwrite, tempsize);
 
841
        data->state.tempwritesize = tempsize; /* store new size */
 
842
        /* tempwrite will be freed further down */
 
843
        break; /* go back to pausing until further notice */
 
844
      }
 
845
      else {
 
846
        tempsize -= chunklen;  /* left after the call above */
 
847
        tempwrite += chunklen; /* advance the pointer */
 
848
      }
 
849
 
 
850
    } while((result == CURLE_OK) && tempsize);
 
851
 
 
852
    free(tempwrite); /* this is unconditionally no longer used */
 
853
  }
 
854
 
 
855
  return result;
 
856
}
 
857
 
747
858
#ifdef CURL_DOES_CONVERSIONS
748
859
/*
749
860
 * Curl_convert_to_network() is an internal function
789
900
    in_bytes = out_bytes = length;
790
901
    rc = iconv(data->outbound_cd, (const char**)&input_ptr, &in_bytes,
791
902
               &output_ptr, &out_bytes);
792
 
    if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
 
903
    if((rc == ICONV_ERROR) || (in_bytes != 0)) {
793
904
      error = ERRNO;
794
905
      failf(data,
795
906
        "The Curl_convert_to_network iconv call failed with errno %i: %s",
849
960
    in_bytes = out_bytes = length;
850
961
    rc = iconv(data->inbound_cd, (const char **)&input_ptr, &in_bytes,
851
962
               &output_ptr, &out_bytes);
852
 
    if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
 
963
    if((rc == ICONV_ERROR) || (in_bytes != 0)) {
853
964
      error = ERRNO;
854
965
      failf(data,
855
966
        "The Curl_convert_from_network iconv call failed with errno %i: %s",
910
1021
    in_bytes = out_bytes = length;
911
1022
    rc = iconv(data->utf8_cd, &input_ptr, &in_bytes,
912
1023
               &output_ptr, &out_bytes);
913
 
    if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
 
1024
    if((rc == ICONV_ERROR) || (in_bytes != 0)) {
914
1025
      error = ERRNO;
915
1026
      failf(data,
916
1027
        "The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
917
1028
             error, strerror(error));
918
1029
      return CURLE_CONV_FAILED;
919
1030
    }
920
 
    if (output_ptr < input_ptr) {
 
1031
    if(output_ptr < input_ptr) {
921
1032
      /* null terminate the now shorter output string */
922
1033
      *output_ptr = 0x00;
923
1034
    }