~ubuntu-branches/ubuntu/jaunty/cmake/jaunty-security

« back to all changes in this revision

Viewing changes to Source/CTest/Curl/easy.c

  • Committer: Bazaar Package Importer
  • Author(s): A. Maitland Bottoms
  • Date: 2006-06-18 16:34:11 UTC
  • mfrom: (1.4.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20060618163411-pi234s3v6jwlcmof
Tags: 2.4.2-1
* New upstream release (Closes: #338324)
* Put cmake .vim files into /usr/share/vim/addons/plugin/
  where they can be used. (Closes: #366663)
* Install cmake-mode.el so it can be used. (Closes: #366664)
* Ensure cmake FindKDE locates KDE libraries on Debian
  based distributions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *                                  _   _ ____  _
 
3
 *  Project                     ___| | | |  _ \| |
 
4
 *                             / __| | | | |_) | |
 
5
 *                            | (__| |_| |  _ <| |___
 
6
 *                             \___|\___/|_| \_\_____|
 
7
 *
 
8
 * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
 
9
 *
 
10
 * This software is licensed as described in the file COPYING, which
 
11
 * you should have received as part of this distribution. The terms
 
12
 * are also available at http://curl.haxx.se/docs/copyright.html.
 
13
 *
 
14
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 
15
 * copies of the Software, and permit persons to whom the Software is
 
16
 * furnished to do so, under the terms of the COPYING file.
 
17
 *
 
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 
19
 * KIND, either express or implied.
 
20
 *
 
21
 * $Id: easy.c,v 1.6 2004/10/13 14:01:04 andy Exp $
 
22
 ***************************************************************************/
 
23
 
 
24
#include "setup.h"
 
25
 
 
26
/* -- WIN32 approved -- */
 
27
#include <stdio.h>
 
28
#include <string.h>
 
29
#include <stdarg.h>
 
30
#include <stdlib.h>
 
31
#include <ctype.h>
 
32
#include <sys/types.h>
 
33
#include <sys/stat.h>
 
34
 
 
35
#include <errno.h>
 
36
 
 
37
#include "strequal.h"
 
38
 
 
39
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
 
40
#include <time.h>
 
41
#include <io.h>
 
42
#else
 
43
#ifdef HAVE_SYS_SOCKET_H
 
44
#include <sys/socket.h>
 
45
#endif
 
46
#include <netinet/in.h>
 
47
#include <sys/time.h>
 
48
#ifdef HAVE_UNISTD_H
 
49
#include <unistd.h>
 
50
#endif
 
51
#include <netdb.h>
 
52
#ifdef HAVE_ARPA_INET_H
 
53
#include <arpa/inet.h>
 
54
#endif
 
55
#ifdef HAVE_NET_IF_H
 
56
#include <net/if.h>
 
57
#endif
 
58
#include <sys/ioctl.h>
 
59
#include <signal.h>
 
60
 
 
61
#ifdef HAVE_SYS_PARAM_H
 
62
#include <sys/param.h>
 
63
#endif
 
64
 
 
65
#ifdef HAVE_SYS_SELECT_H
 
66
#include <sys/select.h>
 
67
#endif
 
68
 
 
69
#endif  /* WIN32 ... */
 
70
 
 
71
#include "urldata.h"
 
72
#include <curl/curl.h>
 
73
#include "transfer.h"
 
74
#include "ssluse.h"
 
75
#include "url.h"
 
76
#include "getinfo.h"
 
77
#include "hostip.h"
 
78
#include "share.h"
 
79
#include "curl_memory.h"
 
80
 
 
81
#define _MPRINTF_REPLACE /* use our functions only */
 
82
#include <curl/mprintf.h>
 
83
 
 
84
/* The last #include file should be: */
 
85
#include "memdebug.h"
 
86
 
 
87
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
 
88
/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
 
89
   of win32_init() */
 
90
static void win32_cleanup(void)
 
91
{
 
92
  WSACleanup();
 
93
}
 
94
 
 
95
/* win32_init() performs win32 socket initialization to properly setup the
 
96
   stack to allow networking */
 
97
static CURLcode win32_init(void)
 
98
{
 
99
  WORD wVersionRequested;
 
100
  WSADATA wsaData;
 
101
  int err;
 
102
 
 
103
#ifdef ENABLE_IPV6
 
104
  wVersionRequested = MAKEWORD(2, 0);
 
105
#else
 
106
  wVersionRequested = MAKEWORD(1, 1);
 
107
#endif
 
108
 
 
109
  err = WSAStartup(wVersionRequested, &wsaData);
 
110
 
 
111
  if (err != 0)
 
112
    /* Tell the user that we couldn't find a useable */
 
113
    /* winsock.dll.     */
 
114
    return CURLE_FAILED_INIT;
 
115
 
 
116
  /* Confirm that the Windows Sockets DLL supports what we need.*/
 
117
  /* Note that if the DLL supports versions greater */
 
118
  /* than wVersionRequested, it will still return */
 
119
  /* wVersionRequested in wVersion. wHighVersion contains the */
 
120
  /* highest supported version. */
 
121
 
 
122
  if ( LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
 
123
       HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
 
124
    /* Tell the user that we couldn't find a useable */
 
125
 
 
126
    /* winsock.dll. */
 
127
    WSACleanup();
 
128
    return CURLE_FAILED_INIT;
 
129
  }
 
130
  /* The Windows Sockets DLL is acceptable. Proceed. */
 
131
  return CURLE_OK;
 
132
}
 
133
 
 
134
#else
 
135
/* These functions exist merely to prevent compiler warnings */
 
136
static CURLcode win32_init(void) { return CURLE_OK; }
 
137
static void win32_cleanup(void) { }
 
138
#endif
 
139
 
 
140
#ifdef USE_LIBIDN
 
141
/*
 
142
 * Initialise use of IDNA library.
 
143
 * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
 
144
 * idna_to_ascii_lz().
 
145
 */
 
146
static void idna_init (void)
 
147
{
 
148
#ifdef WIN32
 
149
  char buf[60];
 
150
  UINT cp = GetACP();
 
151
 
 
152
  if (!getenv("CHARSET") && cp > 0) {
 
153
    snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
 
154
    putenv(buf);
 
155
  }
 
156
#else
 
157
  /* to do? */
 
158
#endif
 
159
}
 
160
#endif  /* USE_LIBIDN */
 
161
 
 
162
/* true globals -- for curl_global_init() and curl_global_cleanup() */
 
163
static unsigned int  initialized = 0;
 
164
static long          init_flags  = 0;
 
165
 
 
166
/*
 
167
 * If a memory-using function (like curl_getenv) is used before
 
168
 * curl_global_init() is called, we need to have these pointers set already.
 
169
 */
 
170
curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
 
171
curl_free_callback Curl_cfree = (curl_free_callback)free;
 
172
curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
 
173
curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)strdup;
 
174
curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
 
175
 
 
176
/**
 
177
 * curl_global_init() globally initializes cURL given a bitwise set of the
 
178
 * different features of what to initialize.
 
179
 */
 
180
CURLcode curl_global_init(long flags)
 
181
{
 
182
  if (initialized)
 
183
    return CURLE_OK;
 
184
 
 
185
  /* Setup the default memory functions here (again) */
 
186
  Curl_cmalloc = (curl_malloc_callback)malloc;
 
187
  Curl_cfree = (curl_free_callback)free;
 
188
  Curl_crealloc = (curl_realloc_callback)realloc;
 
189
  Curl_cstrdup = (curl_strdup_callback)strdup;
 
190
  Curl_ccalloc = (curl_calloc_callback)calloc;
 
191
 
 
192
  if (flags & CURL_GLOBAL_SSL)
 
193
    Curl_SSL_init();
 
194
 
 
195
  if (flags & CURL_GLOBAL_WIN32)
 
196
    if (win32_init() != CURLE_OK)
 
197
      return CURLE_FAILED_INIT;
 
198
 
 
199
#ifdef _AMIGASF
 
200
  if(!amiga_init())
 
201
    return CURLE_FAILED_INIT;
 
202
#endif
 
203
 
 
204
#ifdef USE_LIBIDN
 
205
  idna_init();
 
206
#endif
 
207
 
 
208
  initialized = 1;
 
209
  init_flags  = flags;
 
210
 
 
211
  return CURLE_OK;
 
212
}
 
213
 
 
214
/*
 
215
 * curl_global_init_mem() globally initializes cURL and also registers the
 
216
 * user provided callback routines.
 
217
 */
 
218
CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
 
219
                              curl_free_callback f, curl_realloc_callback r,
 
220
                              curl_strdup_callback s, curl_calloc_callback c)
 
221
{
 
222
  CURLcode code;
 
223
 
 
224
  /* Invalid input, return immediately */
 
225
  if (!m || !f || !r || !s || !c)
 
226
    return CURLE_FAILED_INIT;
 
227
 
 
228
  /* Already initialized, don't do it again */
 
229
  if ( initialized )
 
230
    return CURLE_OK;
 
231
 
 
232
  /* Call the actual init function first */
 
233
  code = curl_global_init(flags);
 
234
  if (code == CURLE_OK) {
 
235
    Curl_cmalloc = m;
 
236
    Curl_cfree = f;
 
237
    Curl_cstrdup = s;
 
238
    Curl_crealloc = r;
 
239
    Curl_ccalloc = c;
 
240
  }
 
241
 
 
242
  return code;
 
243
}
 
244
 
 
245
/**
 
246
 * curl_global_cleanup() globally cleanups cURL, uses the value of
 
247
 * "init_flags" to determine what needs to be cleaned up and what doesn't.
 
248
 */
 
249
void curl_global_cleanup(void)
 
250
{
 
251
  if (!initialized)
 
252
    return;
 
253
 
 
254
  Curl_global_host_cache_dtor();
 
255
 
 
256
  if (init_flags & CURL_GLOBAL_SSL)
 
257
    Curl_SSL_cleanup();
 
258
 
 
259
  if (init_flags & CURL_GLOBAL_WIN32)
 
260
    win32_cleanup();
 
261
 
 
262
#ifdef _AMIGASF
 
263
  amiga_cleanup();
 
264
#endif
 
265
 
 
266
  initialized = 0;
 
267
  init_flags  = 0;
 
268
}
 
269
 
 
270
/*
 
271
 * curl_easy_init() is the external interface to alloc, setup and init an
 
272
 * easy handle that is returned. If anything goes wrong, NULL is returned.
 
273
 */
 
274
CURL *curl_easy_init(void)
 
275
{
 
276
  CURLcode res;
 
277
  struct SessionHandle *data;
 
278
 
 
279
  /* Make sure we inited the global SSL stuff */
 
280
  if (!initialized) {
 
281
    res = curl_global_init(CURL_GLOBAL_DEFAULT);
 
282
    if(res)
 
283
      /* something in the global init failed, return nothing */
 
284
      return NULL;
 
285
  }
 
286
 
 
287
  /* We use curl_open() with undefined URL so far */
 
288
  res = Curl_open(&data);
 
289
  if(res != CURLE_OK)
 
290
    return NULL;
 
291
 
 
292
  return data;
 
293
}
 
294
 
 
295
/*
 
296
 * curl_easy_setopt() is the external interface for setting options on an
 
297
 * easy handle.
 
298
 */
 
299
typedef int (*func_T)(void);
 
300
CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
 
301
{
 
302
  va_list arg;
 
303
  func_T param_func;
 
304
  long param_long;
 
305
  void *param_obj;
 
306
  curl_off_t param_offset;
 
307
  struct SessionHandle *data = curl;
 
308
  CURLcode ret;
 
309
 
 
310
  if(!curl)
 
311
    return CURLE_BAD_FUNCTION_ARGUMENT;
 
312
 
 
313
  va_start(arg, tag);
 
314
 
 
315
  /* PORTING NOTE:
 
316
     Object pointers can't necessarily be casted to function pointers and
 
317
     therefore we need to know what type it is and read the correct type
 
318
     at once. This should also correct problems with different sizes of
 
319
     the types.
 
320
  */
 
321
 
 
322
  if(tag < CURLOPTTYPE_OBJECTPOINT) {
 
323
    /* This is a LONG type */
 
324
    param_long = va_arg(arg, long);
 
325
    ret = Curl_setopt(data, tag, param_long);
 
326
  }
 
327
  else if(tag < CURLOPTTYPE_FUNCTIONPOINT) {
 
328
    /* This is a object pointer type */
 
329
    param_obj = va_arg(arg, void *);
 
330
    ret = Curl_setopt(data, tag, param_obj);
 
331
  }
 
332
  else if(tag < CURLOPTTYPE_OFF_T) {
 
333
    /* This is a function pointer type */
 
334
    param_func = va_arg(arg, func_T );
 
335
    ret = Curl_setopt(data, tag, param_func);
 
336
  }
 
337
  else {
 
338
    /* This is a curl_off_t type */
 
339
    param_offset = va_arg(arg, curl_off_t);
 
340
    ret = Curl_setopt(data, tag, param_offset);
 
341
  }
 
342
 
 
343
  va_end(arg);
 
344
  return ret;
 
345
}
 
346
 
 
347
/*
 
348
 * curl_easy_perform() is the external interface that performs a transfer
 
349
 * previously setup.
 
350
 */
 
351
CURLcode curl_easy_perform(CURL *curl)
 
352
{
 
353
  struct SessionHandle *data = (struct SessionHandle *)curl;
 
354
 
 
355
  if(!data)
 
356
    return CURLE_BAD_FUNCTION_ARGUMENT;
 
357
 
 
358
  if ( ! (data->share && data->share->hostcache) ) {
 
359
 
 
360
    if (Curl_global_host_cache_use(data) &&
 
361
        data->hostcache != Curl_global_host_cache_get()) {
 
362
      if (data->hostcache)
 
363
        Curl_hash_destroy(data->hostcache);
 
364
      data->hostcache = Curl_global_host_cache_get();
 
365
    }
 
366
 
 
367
    if (!data->hostcache) {
 
368
      data->hostcache = Curl_mk_dnscache();
 
369
 
 
370
      if(!data->hostcache)
 
371
        /* While we possibly could survive and do good without a host cache,
 
372
           the fact that creating it failed indicates that things are truly
 
373
           screwed up and we should bail out! */
 
374
        return CURLE_OUT_OF_MEMORY;
 
375
    }
 
376
 
 
377
  }
 
378
 
 
379
  return Curl_perform(data);
 
380
}
 
381
 
 
382
/*
 
383
 * curl_easy_cleanup() is the external interface to cleaning/freeing the given
 
384
 * easy handle.
 
385
 */
 
386
void curl_easy_cleanup(CURL *curl)
 
387
{
 
388
  struct SessionHandle *data = (struct SessionHandle *)curl;
 
389
 
 
390
  if(!data)
 
391
    return;
 
392
 
 
393
  if ( ! (data->share && data->share->hostcache) ) {
 
394
    if ( !Curl_global_host_cache_use(data)) {
 
395
      Curl_hash_destroy(data->hostcache);
 
396
    }
 
397
  }
 
398
  Curl_close(data);
 
399
}
 
400
 
 
401
/*
 
402
 * curl_easy_getinfo() is an external interface that allows an app to retrieve
 
403
 * information from a performed transfer and similar.
 
404
 */
 
405
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
 
406
{
 
407
  va_list arg;
 
408
  void *paramp;
 
409
  struct SessionHandle *data = (struct SessionHandle *)curl;
 
410
 
 
411
  va_start(arg, info);
 
412
  paramp = va_arg(arg, void *);
 
413
 
 
414
  return Curl_getinfo(data, info, paramp);
 
415
}
 
416
 
 
417
/*
 
418
 * curl_easy_duphandle() is an external interface to allow duplication of a
 
419
 * given input easy handle. The returned handle will be a new working handle
 
420
 * with all options set exactly as the input source handle.
 
421
 */
 
422
CURL *curl_easy_duphandle(CURL *incurl)
 
423
{
 
424
  bool fail = TRUE;
 
425
  struct SessionHandle *data=(struct SessionHandle *)incurl;
 
426
 
 
427
  struct SessionHandle *outcurl = (struct SessionHandle *)
 
428
    calloc(sizeof(struct SessionHandle), 1);
 
429
 
 
430
  if(NULL == outcurl)
 
431
    return NULL; /* failure */
 
432
 
 
433
  do {
 
434
 
 
435
    /*
 
436
     * We setup a few buffers we need. We should probably make them
 
437
     * get setup on-demand in the code, as that would probably decrease
 
438
     * the likeliness of us forgetting to init a buffer here in the future.
 
439
     */
 
440
    outcurl->state.headerbuff=(char*)malloc(HEADERSIZE);
 
441
    if(!outcurl->state.headerbuff) {
 
442
      break;
 
443
    }
 
444
    outcurl->state.headersize=HEADERSIZE;
 
445
 
 
446
    /* copy all userdefined values */
 
447
    outcurl->set = data->set;
 
448
    outcurl->state.numconnects = data->state.numconnects;
 
449
    outcurl->state.connects = (struct connectdata **)
 
450
      malloc(sizeof(struct connectdata *) * outcurl->state.numconnects);
 
451
 
 
452
    if(!outcurl->state.connects) {
 
453
      break;
 
454
    }
 
455
 
 
456
    memset(outcurl->state.connects, 0,
 
457
           sizeof(struct connectdata *)*outcurl->state.numconnects);
 
458
 
 
459
    outcurl->progress.flags    = data->progress.flags;
 
460
    outcurl->progress.callback = data->progress.callback;
 
461
 
 
462
#ifndef CURL_DISABLE_HTTP
 
463
    if(data->cookies) {
 
464
      /* If cookies are enabled in the parent handle, we enable them
 
465
         in the clone as well! */
 
466
      outcurl->cookies = Curl_cookie_init(data,
 
467
                                            data->cookies->filename,
 
468
                                            outcurl->cookies,
 
469
                                            data->set.cookiesession);
 
470
      if(!outcurl->cookies) {
 
471
        break;
 
472
      }
 
473
    }
 
474
#endif   /* CURL_DISABLE_HTTP */
 
475
 
 
476
    /* duplicate all values in 'change' */
 
477
    if(data->change.url) {
 
478
      outcurl->change.url = strdup(data->change.url);
 
479
      if(!outcurl->change.url)
 
480
        break;
 
481
      outcurl->change.url_alloc = TRUE;
 
482
    }
 
483
    if(data->change.proxy) {
 
484
      outcurl->change.proxy = strdup(data->change.proxy);
 
485
      if(!outcurl->change.proxy)
 
486
        break;
 
487
      outcurl->change.proxy_alloc = TRUE;
 
488
    }
 
489
    if(data->change.referer) {
 
490
      outcurl->change.referer = strdup(data->change.referer);
 
491
      if(!outcurl->change.referer)
 
492
        break;
 
493
      outcurl->change.referer_alloc = TRUE;
 
494
    }
 
495
 
 
496
#ifdef USE_ARES
 
497
    /* If we use ares, we setup a new ares channel for the new handle */
 
498
    if(ARES_SUCCESS != ares_init(&outcurl->state.areschannel))
 
499
      break;
 
500
#endif
 
501
 
 
502
    fail = FALSE; /* we reach this point and thus we are OK */
 
503
 
 
504
  } while(0);
 
505
 
 
506
  if(fail) {
 
507
    if(outcurl) {
 
508
      if(outcurl->state.connects)
 
509
        free(outcurl->state.connects);
 
510
      if(outcurl->state.headerbuff)
 
511
        free(outcurl->state.headerbuff);
 
512
      if(outcurl->change.proxy)
 
513
        free(outcurl->change.proxy);
 
514
      if(outcurl->change.url)
 
515
        free(outcurl->change.url);
 
516
      if(outcurl->change.referer)
 
517
        free(outcurl->change.referer);
 
518
      free(outcurl); /* free the memory again */
 
519
      outcurl = NULL;
 
520
    }
 
521
  }
 
522
 
 
523
  return outcurl;
 
524
}
 
525
 
 
526
/*
 
527
 * curl_easy_reset() is an external interface that allows an app to re-
 
528
 * initialize a session handle to the default values.
 
529
 */
 
530
void curl_easy_reset(CURL *curl)
 
531
{
 
532
  struct SessionHandle *data = (struct SessionHandle *)curl;
 
533
 
 
534
  /* zero out UserDefined data: */
 
535
  memset(&data->set, 0, sizeof(struct UserDefined));
 
536
 
 
537
  /* zero out Progress data: */
 
538
  memset(&data->progress, 0, sizeof(struct Progress));
 
539
 
 
540
  /* The remainder of these calls have been taken from Curl_open() */
 
541
 
 
542
  data->set.out = stdout; /* default output to stdout */
 
543
  data->set.in  = stdin;  /* default input from stdin */
 
544
  data->set.err  = stderr;  /* default stderr to stderr */
 
545
 
 
546
  /* use fwrite as default function to store output */
 
547
  data->set.fwrite = (curl_write_callback)fwrite;
 
548
 
 
549
  /* use fread as default function to read input */
 
550
  data->set.fread = (curl_read_callback)fread;
 
551
 
 
552
  data->set.infilesize = -1; /* we don't know any size */
 
553
 
 
554
  data->state.current_speed = -1; /* init to negative == impossible */
 
555
 
 
556
  data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
 
557
  data->set.ftp_use_epsv = TRUE;   /* FTP defaults to EPSV operations */
 
558
  data->set.ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
 
559
 
 
560
  data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
 
561
 
 
562
  /* make libcurl quiet by default: */
 
563
  data->set.hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
 
564
 
 
565
  /* Set the default size of the SSL session ID cache */
 
566
  data->set.ssl.numsessions = 5;
 
567
 
 
568
  data->set.proxyport = 1080;
 
569
  data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
 
570
  data->set.httpauth = CURLAUTH_BASIC;  /* defaults to basic */
 
571
  data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
 
572
 
 
573
  /*
 
574
   * libcurl 7.10 introduced SSL verification *by default*! This needs to be
 
575
   * switched off unless wanted.
 
576
   */
 
577
  data->set.ssl.verifypeer = TRUE;
 
578
  data->set.ssl.verifyhost = 2;
 
579
#ifdef CURL_CA_BUNDLE
 
580
  /* This is our prefered CA cert bundle since install time */
 
581
  data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
 
582
#endif
 
583
}