~ubuntu-branches/ubuntu/intrepid/curl/intrepid-security

« back to all changes in this revision

Viewing changes to src/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2006-10-30 10:56:48 UTC
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20061030105648-kfd50jram0rzbtlo
Tags: upstream-7.15.5
ImportĀ upstreamĀ versionĀ 7.15.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
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: main.c,v 1.359 2006-06-08 06:12:31 bagder Exp $
 
21
 * $Id: main.c,v 1.366 2006-07-26 23:20:48 bagder Exp $
22
22
 ***************************************************************************/
23
23
 
24
24
#include "setup.h"
183
183
/* Send authentication (user+password) when following
184
184
 * locations, even when hostname changed */
185
185
 
186
 
#ifndef HAVE_STRDUP
187
 
/* Ultrix doesn't have strdup(), so make a quick clone: */
188
 
char *strdup(char *str)
189
 
{
190
 
  int len;
191
 
  char *newstr;
192
 
 
193
 
  len = strlen(str);
194
 
  newstr = (char *) malloc((len+1)*sizeof(char));
195
 
  if (!newstr)
196
 
    return (char *)NULL;
197
 
 
198
 
  strcpy(newstr,str);
199
 
 
200
 
  return newstr;
201
 
 
202
 
}
203
 
#endif
204
 
 
205
186
#ifdef WIN32
206
187
#include <direct.h>
207
188
#define F_OK 0
357
338
  struct timeval lastrecvtime;
358
339
  size_t lastrecvsize;
359
340
  bool ftp_ssl;
 
341
  bool ftp_ssl_reqd;
360
342
 
361
343
  char *socksproxy; /* set to server string */
362
344
  int socksver;     /* set to CURLPROXY_SOCKS* define */
372
354
  struct curl_slist *tp_postquote;
373
355
  struct curl_slist *tp_prequote;
374
356
  char *ftp_account; /* for ACCT */
 
357
  char *ftp_alternative_to_user; /* send command if USER/PASS fails */
375
358
  int ftp_filemethod;
376
359
 
377
360
  bool ignorecl; /* --ignore-content-length */
534
517
    "    --ftp-method [multicwd/nocwd/singlecwd] Control CWD usage (F)",
535
518
    "    --ftp-pasv      Use PASV/EPSV instead of PORT (F)",
536
519
    "    --ftp-skip-pasv-ip Skip the IP address for PASV (F)\n"
537
 
    "    --ftp-ssl       Enable SSL/TLS for the ftp transfer (F)",
 
520
    "    --ftp-ssl       Try SSL/TLS for the ftp transfer (F)",
 
521
    "    --ftp-ssl-reqd  Require SSL/TLS for the ftp transfer (F)",
538
522
    " -F/--form <name=content> Specify HTTP multipart POST data (H)",
539
523
    "    --form-string <name=string> Specify HTTP multipart POST data (H)",
540
524
    " -g/--globoff       Disable URL sequences and ranges using {} and []",
633
617
/* global variable to hold info about libcurl */
634
618
static curl_version_info_data *curlinfo;
635
619
 
636
 
static void parseconfig(const char *filename,
637
 
                        struct Configurable *config);
 
620
static int parseconfig(const char *filename,
 
621
                       struct Configurable *config);
638
622
static char *my_get_line(FILE *fp);
639
623
static int create_dir_hierarchy(char *outfile);
640
624
 
1271
1255
 
1272
1256
static int ftpfilemethod(struct Configurable *config, char *str)
1273
1257
{
1274
 
  if(strequal("singlecwd", str))
 
1258
  if(curlx_strequal("singlecwd", str))
1275
1259
    return CURLFTPMETHOD_SINGLECWD;
1276
 
  if(strequal("nocwd", str))
 
1260
  if(curlx_strequal("nocwd", str))
1277
1261
    return CURLFTPMETHOD_NOCWD;
1278
 
  if(strequal("multicwd", str))
 
1262
  if(curlx_strequal("multicwd", str))
1279
1263
    return CURLFTPMETHOD_MULTICWD;
1280
1264
  warnf(config, "unrecognized ftp file method '%s', using default\n", str);
1281
1265
  return CURLFTPMETHOD_MULTICWD;
1359
1343
    {"$r", "ftp-method", TRUE},
1360
1344
    {"$s", "local-port", TRUE},
1361
1345
    {"$t", "socks4",     TRUE},
 
1346
    {"$u", "ftp-alternative-to-user", TRUE},
 
1347
    {"$v", "ftp-ssl-reqd", FALSE},
1362
1348
 
1363
1349
    {"0", "http1.0",     FALSE},
1364
1350
    {"1", "tlsv1",       FALSE},
1795
1781
          }
1796
1782
        }
1797
1783
        break;
 
1784
      case 'u': /* --ftp-alternative-to-user */
 
1785
        GetStr(&config->ftp_alternative_to_user, nextarg);
 
1786
        break;
 
1787
      case 'v': /* --ftp-ssl-reqd */
 
1788
        config->ftp_ssl_reqd ^= TRUE;
 
1789
        break;
1798
1790
      }
1799
1791
      break;
1800
1792
    case '#': /* --progress-bar */
2069
2061
      config->insecure_ok ^= TRUE;
2070
2062
      break;
2071
2063
    case 'K': /* parse config file */
2072
 
      parseconfig(nextarg, config);
 
2064
      if(parseconfig(nextarg, config))
 
2065
        warnf(config, "error trying read config from the '%s' file\n",
 
2066
              nextarg);
2073
2067
      break;
2074
2068
    case 'l':
2075
2069
      config->conf ^= CONF_FTPLISTONLY; /* only list the names of the FTP dir */
2301
2295
          {"SSL",  CURL_VERSION_SSL},
2302
2296
          {"SSPI",  CURL_VERSION_SSPI},
2303
2297
          {"krb4", CURL_VERSION_KERBEROS4},
2304
 
          {"libz", CURL_VERSION_LIBZ}
 
2298
          {"libz", CURL_VERSION_LIBZ},
 
2299
          {"CharConv", CURL_VERSION_CONV}
2305
2300
        };
2306
2301
        printf("Features: ");
2307
2302
        for(i=0; i<sizeof(feats)/sizeof(feats[0]); i++) {
2402
2397
  return PARAM_OK;
2403
2398
}
2404
2399
 
2405
 
 
2406
 
static void parseconfig(const char *filename,
2407
 
                        struct Configurable *config)
 
2400
/* return 0 on everything-is-fine, and non-zero otherwise */
 
2401
static int parseconfig(const char *filename,
 
2402
                       struct Configurable *config)
2408
2403
{
2409
2404
  int res;
2410
2405
  FILE *file;
2613
2608
    if(file != stdin)
2614
2609
      fclose(file);
2615
2610
  }
 
2611
  else
 
2612
    return 1; /* couldn't open the file */
 
2613
  return 0;
2616
2614
}
2617
2615
 
2618
2616
static void go_sleep(long ms)
2655
2653
  size_t rc;
2656
2654
  struct OutStruct *out=(struct OutStruct *)stream;
2657
2655
  struct Configurable *config = out->config;
2658
 
  curl_off_t size = (curl_off_t)(sz * nmemb); /* typecast to prevent
2659
 
                                                 warnings when converting from
2660
 
                                                 unsigned to signed */
 
2656
 
2661
2657
  if(out && !out->stream) {
2662
2658
    /* open file for writing */
2663
2659
    out->stream=fopen(out->filename, "wb");
2674
2670
    }
2675
2671
  }
2676
2672
 
2677
 
  if(config->recvpersecond) {
2678
 
    /*
2679
 
     * We know when we received data the previous time. We know how much data
2680
 
     * we get now. Make sure that this is not faster than we are told to run.
2681
 
     * If we're faster, sleep a while *before* doing the fwrite() here.
2682
 
     */
2683
 
 
2684
 
    struct timeval now;
2685
 
    long timediff;
2686
 
    long sleep_time;
2687
 
 
2688
 
    static curl_off_t addit = 0;
2689
 
 
2690
 
    now = curlx_tvnow();
2691
 
    timediff = curlx_tvdiff(now, config->lastrecvtime); /* milliseconds */
2692
 
 
2693
 
    if((config->recvpersecond > CURL_MAX_WRITE_SIZE) && (timediff < 100) ) {
2694
 
      /* If we allow a rather speedy transfer, add this amount for later
2695
 
       * checking. Also, do not modify the lastrecvtime as we will use a
2696
 
       * longer scope due to this addition.  We wait for at least 100 ms to
2697
 
       * pass to get better values to do better math for the sleep. */
2698
 
      addit += size;
2699
 
    }
2700
 
    else {
2701
 
      size += addit; /* add up the possibly added bonus rounds from the
2702
 
                        zero timediff calls */
2703
 
      addit = 0; /* clear the addition pool */
2704
 
 
2705
 
      if( size*1000 > config->recvpersecond*timediff) {
2706
 
        /* figure out how many milliseconds to rest */
2707
 
        sleep_time = (long)(size*1000/config->recvpersecond - timediff);
2708
 
 
2709
 
        /*
2710
 
         * Make sure we don't sleep for so long that we trigger the speed
2711
 
         * limit.  This won't limit the bandwidth quite the way we've been
2712
 
         * asked to, but at least the transfer has a chance.
2713
 
         */
2714
 
        if (config->low_speed_time > 0)
2715
 
          sleep_time = MIN(sleep_time,(config->low_speed_time * 1000) / 2);
2716
 
 
2717
 
        if(sleep_time > 0) {
2718
 
          go_sleep(sleep_time);
2719
 
          now = curlx_tvnow();
2720
 
        }
2721
 
      }
2722
 
      config->lastrecvtime = now;
2723
 
    }
2724
 
  }
2725
 
 
2726
2673
  rc = fwrite(buffer, sz, nmemb, out->stream);
2727
2674
 
2728
2675
  if((sz * nmemb) == rc) {
2767
2714
{
2768
2715
  size_t rc;
2769
2716
  struct InStruct *in=(struct InStruct *)userp;
2770
 
  struct Configurable *config = in->config;
2771
 
  curl_off_t size = (curl_off_t)(sz * nmemb);  /* typecast to prevent warnings
2772
 
                                                  when converting from
2773
 
                                                  unsigned to signed */
2774
 
 
2775
 
  if(config->sendpersecond) {
2776
 
    /*
2777
 
     * We know when we sent data the previous time. We know how much data
2778
 
     * we sent. Make sure that this was not faster than we are told to run.
2779
 
     * If we're faster, sleep a while *before* doing the fread() here.
2780
 
     * Also, make no larger fread() than should be sent this second!
2781
 
     */
2782
 
 
2783
 
    struct timeval now;
2784
 
    long timediff;
2785
 
    long sleep_time;
2786
 
 
2787
 
    static curl_off_t addit = 0;
2788
 
 
2789
 
    now = curlx_tvnow();
2790
 
    timediff = curlx_tvdiff(now, config->lastsendtime); /* milliseconds */
2791
 
 
2792
 
    if((config->sendpersecond > CURL_MAX_WRITE_SIZE) &&
2793
 
       (timediff < 100)) {
2794
 
      /*
2795
 
       * We allow very fast transfers, then allow at least 100 ms between
2796
 
       * each sleeping mile-stone to create more accurate long-term rates.
2797
 
       */
2798
 
      addit += size;
2799
 
    }
2800
 
    else {
2801
 
      /* If 'addit' is non-zero, it contains the total amount of bytes
2802
 
         uploaded during the last 'timediff' milliseconds. If it is zero,
2803
 
         we use the stored previous size. */
2804
 
      curl_off_t xfered = addit?addit:(curl_off_t)config->lastsendsize;
2805
 
      addit = 0; /* clear it for the next round */
2806
 
 
2807
 
      if( xfered*1000 > config->sendpersecond*timediff) {
2808
 
        /* figure out how many milliseconds to rest */
2809
 
        sleep_time = (long)(xfered*1000/config->sendpersecond - timediff);
2810
 
        if(sleep_time > 0) {
2811
 
          go_sleep (sleep_time);
2812
 
          now = curlx_tvnow();
2813
 
        }
2814
 
      }
2815
 
      config->lastsendtime = now;
2816
 
 
2817
 
      if(size > config->sendpersecond) {
2818
 
        /* lower the size to actually read */
2819
 
        nmemb = (size_t)config->sendpersecond;
2820
 
        sz = 1;
2821
 
      }
2822
 
    }
2823
 
 
2824
 
    config->lastsendsize = sz*nmemb;
2825
 
  }
2826
2717
 
2827
2718
  rc = fread(buffer, sz, nmemb, in->stream);
2828
2719
#if 0
3392
3283
    ;
3393
3284
  }
3394
3285
  else {
3395
 
    parseconfig(NULL, config);
 
3286
    parseconfig(NULL, config); /* ignore possible failure */
3396
3287
  }
3397
3288
 
3398
3289
  if ((argc < 2)  && !config->url_list) {
3885
3776
        curl_easy_setopt(curl, CURLOPT_IOCTLDATA, &input);
3886
3777
        curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl);
3887
3778
 
3888
 
        if(config->recvpersecond) {
 
3779
        if(config->recvpersecond)
3889
3780
          /* tell libcurl to use a smaller sized buffer as it allows us to
3890
3781
             make better sleeps! 7.9.9 stuff! */
3891
3782
          curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, config->recvpersecond);
3892
 
        }
3893
3783
 
3894
3784
        /* size of uploaded file: */
3895
3785
        curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, uploadfilesize);
3939
3829
                         config->conf&CONF_AUTO_REFERER);
3940
3830
        curl_easy_setopt(curl, CURLOPT_USERAGENT, config->useragent);
3941
3831
        curl_easy_setopt(curl, CURLOPT_FTPPORT, config->ftpport);
3942
 
        curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, config->low_speed_limit);
 
3832
        curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT,
 
3833
                         config->low_speed_limit);
3943
3834
        curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, config->low_speed_time);
 
3835
        curl_easy_setopt(curl, CURLOPT_MAX_SEND_SPEED_LARGE,
 
3836
                         config->sendpersecond);
 
3837
        curl_easy_setopt(curl, CURLOPT_MAX_RECV_SPEED_LARGE,
 
3838
                         config->recvpersecond);
 
3839
 
3944
3840
        curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE,
3945
3841
                         config->use_resume?config->resume_from:0);
3946
3842
        curl_easy_setopt(curl, CURLOPT_COOKIE, config->cookie);
4085
3981
        if(config->ftp_ssl)
4086
3982
          curl_easy_setopt(curl, CURLOPT_FTP_SSL, CURLFTPSSL_TRY);
4087
3983
 
 
3984
        /* new in curl 7.15.5 */
 
3985
        if(config->ftp_ssl_reqd)
 
3986
          curl_easy_setopt(curl, CURLOPT_FTP_SSL, CURLFTPSSL_ALL);
 
3987
 
4088
3988
        /* new in curl 7.11.1, modified in 7.15.2 */
4089
3989
        if(config->socksproxy) {
4090
3990
          curl_easy_setopt(curl, CURLOPT_PROXY, config->socksproxy);
4113
4013
          curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE, config->localportrange);
4114
4014
        }
4115
4015
 
 
4016
        /* curl x.xx.x */
 
4017
        curl_easy_setopt(curl, CURLOPT_FTP_ALTERNATIVE_TO_USER, config->ftp_alternative_to_user);
 
4018
 
4116
4019
        retry_numretries = config->req_retry;
4117
4020
 
4118
4021
        retrystart = curlx_tvnow();
4138
4041
              retry = RETRY_TIMEOUT;
4139
4042
            else if(CURLE_OK == res) {
4140
4043
              /* Check for HTTP transient errors */
4141
 
              char *url=NULL;
4142
 
              curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
4143
 
              if(url &&
4144
 
                 curlx_strnequal(url, "http", 4)) {
 
4044
              char *this_url=NULL;
 
4045
              curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &this_url);
 
4046
              if(this_url &&
 
4047
                 curlx_strnequal(this_url, "http", 4)) {
4145
4048
                /* This was HTTP(S) */
4146
4049
                curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
4147
4050