~ubuntu-branches/ubuntu/gutsy/curl/gutsy

« back to all changes in this revision

Viewing changes to src/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2006-06-29 15:04:24 UTC
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20060629150424-be178abcwks1n519
Tags: upstream-7.15.4
ImportĀ upstreamĀ versionĀ 7.15.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *                            | (__| |_| |  _ <| |___
6
6
 *                             \___|\___/|_| \_\_____|
7
7
 *
8
 
 * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
 
8
 * Copyright (C) 1998 - 2006, 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: main.c,v 1.341 2005/12/05 14:10:48 bagder Exp $
 
21
 * $Id: main.c,v 1.359 2006-06-08 06:12:31 bagder Exp $
22
22
 ***************************************************************************/
23
23
 
24
24
#include "setup.h"
47
47
 
48
48
#define CURLseparator   "--_curl_--"
49
49
 
50
 
#if defined(WIN32)&&!defined(__CYGWIN32__)
51
 
#include <winsock2.h>
52
 
#endif
53
 
 
54
50
#ifdef __NOVELL_LIBC__
55
51
#include <screen.h>
56
52
#endif
108
104
   versions instead */
109
105
#include <curlx.h> /* header from the libcurl directory */
110
106
 
 
107
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
 
108
#include <iconv.h>
 
109
/* set default codesets for iconv */
 
110
#ifndef CURL_ICONV_CODESET_OF_NETWORK
 
111
#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
 
112
#endif
 
113
#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
 
114
 
111
115
/* The last #include file should be: */
112
116
#ifdef CURLDEBUG
113
117
#ifndef CURLTOOLDEBUG
157
161
} HttpReq;
158
162
 
159
163
/* Just a set of bits */
 
164
#ifndef CONF_DEFAULT
160
165
#define CONF_DEFAULT  0
 
166
#endif
161
167
 
162
168
#define CONF_AUTO_REFERER (1<<4) /* the automatic referer-system please! */
163
169
#define CONF_HEADER   (1<<8) /* throw the header out too */
215
221
#define struct_stat struct stat
216
222
#endif
217
223
 
 
224
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
 
225
iconv_t inbound_cd  = (iconv_t)-1;
 
226
#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
 
227
 
218
228
#ifdef WIN32
219
229
/*
220
230
 * Truncate a file handle at a 64-bit position 'where'.
275
285
  char *headerfile;
276
286
  char *ftpport;
277
287
  char *iface;
 
288
  int localport;
 
289
  int localportrange;
278
290
  unsigned short porttouse;
279
291
  char *range;
280
292
  long low_speed_limit;
345
357
  struct timeval lastrecvtime;
346
358
  size_t lastrecvsize;
347
359
  bool ftp_ssl;
348
 
  char *socks5proxy;
 
360
 
 
361
  char *socksproxy; /* set to server string */
 
362
  int socksver;     /* set to CURLPROXY_SOCKS* define */
 
363
 
349
364
  bool tcp_nodelay;
350
365
  long req_retry;   /* number of retries */
351
366
  long retry_delay; /* delay between retries (in seconds) */
419
434
static void main_free(void)
420
435
{
421
436
  curl_global_cleanup();
 
437
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
 
438
  /* close iconv conversion descriptor */
 
439
  if (inbound_cd != (iconv_t)-1) {
 
440
     iconv_close(inbound_cd);
 
441
  }
 
442
#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
422
443
}
423
444
 
424
445
static int SetHTTPrequest(struct Configurable *config,
510
531
    "    --crlf          Convert LF to CRLF in upload",
511
532
    " -f/--fail          Fail silently (no output at all) on HTTP errors (H)",
512
533
    "    --ftp-create-dirs Create the remote dirs if not present (F)",
 
534
    "    --ftp-method [multicwd/nocwd/singlecwd] Control CWD usage (F)",
513
535
    "    --ftp-pasv      Use PASV/EPSV instead of PORT (F)",
514
536
    "    --ftp-skip-pasv-ip Skip the IP address for PASV (F)\n"
515
537
    "    --ftp-ssl       Enable SSL/TLS for the ftp transfer (F)",
523
545
    " -i/--include       Include protocol headers in the output (H/F)",
524
546
    " -I/--head          Show document info only",
525
547
    " -j/--junk-session-cookies Ignore session cookies read from file (H)",
526
 
    "    --interface <interface> Specify network interface to use",
 
548
    "    --interface <interface> Specify network interface/address to use",
527
549
    "    --krb4 <level>  Enable krb4 with specified security level (F)",
528
550
    " -k/--insecure      Allow connections to SSL sites without certs (H)",
529
551
    " -K/--config        Specify which config file to read",
530
552
    " -l/--list-only     List only names of an FTP directory (F)",
531
553
    "    --limit-rate <rate> Limit transfer speed to this rate",
 
554
    "    --local-port <num>[-num] Force use of these local port numbers\n",
532
555
    " -L/--location      Follow Location: hints (H)",
533
556
    "    --location-trusted Follow Location: and send authentication even ",
534
557
    "                    to other hostnames (H)",
558
581
    "    --retry-max-time <seconds> Retry only within this period",
559
582
    " -s/--silent        Silent mode. Don't output anything",
560
583
    " -S/--show-error    Show error. With -s, make curl show errors when they occur",
561
 
    "    --socks <host[:port]> Use SOCKS5 proxy on given host + port",
 
584
    "    --socks4 <host[:port]> Use SOCKS4 proxy on given host + port",
 
585
    "    --socks5 <host[:port]> Use SOCKS5 proxy on given host + port",
562
586
    "    --stderr <file> Where to redirect stderr. - means stdout",
563
587
    " -t/--telnet-option <OPT=val> Set telnet option",
564
588
    "    --trace <file>  Write a debug trace to the given file",
1248
1272
static int ftpfilemethod(struct Configurable *config, char *str)
1249
1273
{
1250
1274
  if(strequal("singlecwd", str))
1251
 
    return 3;
 
1275
    return CURLFTPMETHOD_SINGLECWD;
1252
1276
  if(strequal("nocwd", str))
1253
 
    return 2;
 
1277
    return CURLFTPMETHOD_NOCWD;
1254
1278
  if(strequal("multicwd", str))
1255
 
    return 1;
 
1279
    return CURLFTPMETHOD_MULTICWD;
1256
1280
  warnf(config, "unrecognized ftp file method '%s', using default\n", str);
1257
 
  return 1;
 
1281
  return CURLFTPMETHOD_MULTICWD;
1258
1282
}
1259
1283
 
1260
1284
static ParameterError getparameter(char *flag, /* f or -long-flag */
1265
1289
{
1266
1290
  char letter;
1267
1291
  char subletter=0; /* subletters can only occur on long options */
1268
 
 
 
1292
  int rc; /* generic return code variable */
1269
1293
  const char *parse=NULL;
1270
1294
  unsigned int j;
1271
1295
  time_t now;
1315
1339
    {"$a", "ftp-ssl",    FALSE},
1316
1340
    {"$b", "ftp-pasv",   FALSE},
1317
1341
    {"$c", "socks5",     TRUE},
 
1342
    {"$c", "socks",      TRUE}, /* this is how the option was documented but
 
1343
                                   we prefer the --socks5 version for explicit
 
1344
                                   version */
1318
1345
    {"$d", "tcp-nodelay",FALSE},
1319
1346
    {"$e", "proxy-digest", FALSE},
1320
1347
    {"$f", "proxy-basic", FALSE},
1330
1357
    {"$p", "ignore-content-length", FALSE},
1331
1358
    {"$q", "ftp-skip-pasv-ip", FALSE},
1332
1359
    {"$r", "ftp-method", TRUE},
 
1360
    {"$s", "local-port", TRUE},
 
1361
    {"$t", "socks4",     TRUE},
1333
1362
 
1334
1363
    {"0", "http1.0",     FALSE},
1335
1364
    {"1", "tlsv1",       FALSE},
1512
1541
          char *unit;
1513
1542
          curl_off_t value = curlx_strtoofft(nextarg, &unit, 0);
1514
1543
 
1515
 
          if(strlen(unit) != 1)
 
1544
          if(!*unit)
 
1545
            unit=(char *)"b";
 
1546
          else if(strlen(unit) > 1)
1516
1547
            unit=(char *)"w"; /* unsupported */
1517
1548
 
1518
1549
          switch(*unit) {
1671
1702
          free(config->ftpport);
1672
1703
        config->ftpport = NULL;
1673
1704
        break;
1674
 
      case 'c': /* --socks specifies a socks5 proxy to use */
1675
 
        GetStr(&config->socks5proxy, nextarg);
 
1705
      case 'c': /* --socks5 specifies a socks5 proxy to use */
 
1706
        GetStr(&config->socksproxy, nextarg);
 
1707
        config->socksver = CURLPROXY_SOCKS5;
 
1708
        break;
 
1709
      case 't': /* --socks4 specifies a socks4 proxy to use */
 
1710
        GetStr(&config->socksproxy, nextarg);
 
1711
        config->socksver = CURLPROXY_SOCKS4;
1676
1712
        break;
1677
1713
      case 'd': /* --tcp-nodelay option */
1678
1714
        config->tcp_nodelay ^= TRUE;
1743
1779
      case 'r': /* --ftp-method (undocumented at this point) */
1744
1780
        config->ftp_filemethod = ftpfilemethod(config, nextarg);
1745
1781
        break;
 
1782
      case 's': /* --local-port */
 
1783
        rc = sscanf(nextarg, "%d - %d",
 
1784
                    &config->localport,
 
1785
                    &config->localportrange);
 
1786
        if(!rc)
 
1787
          return PARAM_BAD_USE;
 
1788
        else if(rc == 1)
 
1789
          config->localportrange = 1; /* default number of ports to try */
 
1790
        else {
 
1791
          config->localportrange -= config->localport;
 
1792
          if(config->localportrange < 1) {
 
1793
            warnf(config, "bad range input\n");
 
1794
            return PARAM_BAD_USE;
 
1795
          }
 
1796
        }
 
1797
        break;
1746
1798
      }
1747
1799
      break;
1748
1800
    case '#': /* --progress-bar */
1861
1913
          /* we already have a string, we append this one
1862
1914
             with a separating &-letter */
1863
1915
          char *oldpost=config->postfields;
1864
 
          config->postfields=aprintf("%s&%s", oldpost, postdata);
 
1916
          size_t newlen = strlen(oldpost) + strlen(postdata) + 2;
 
1917
          config->postfields=malloc(newlen);
 
1918
          if(!config->postfields)
 
1919
            return PARAM_NO_MEM;
 
1920
          snprintf(config->postfields, newlen, "%s&%s", oldpost, postdata);
1865
1921
          free(oldpost);
1866
1922
          free(postdata);
1867
1923
        }
2380
2436
        }
2381
2437
        else {
2382
2438
          /* Get the filename of our executable. GetModuleFileName is
2383
 
           * defined in windows.h, which is #included into libcurl.
 
2439
           * already declared via inclusions done in setup header file.
2384
2440
           * We assume that we are using the ASCII version here.
2385
2441
           */
2386
2442
          int n = GetModuleFileName(0, filebuffer, sizeof(filebuffer));
2594
2650
  curl_off_t init;  /* original size (non-zero when appending) */
2595
2651
};
2596
2652
 
2597
 
static int my_fwrite(void *buffer, size_t sz, size_t nmemb, void *stream)
 
2653
static size_t my_fwrite(void *buffer, size_t sz, size_t nmemb, void *stream)
2598
2654
{
2599
 
  int rc;
 
2655
  size_t rc;
2600
2656
  struct OutStruct *out=(struct OutStruct *)stream;
2601
2657
  struct Configurable *config = out->config;
2602
2658
  curl_off_t size = (curl_off_t)(sz * nmemb); /* typecast to prevent
2607
2663
    out->stream=fopen(out->filename, "wb");
2608
2664
    if(!out->stream) {
2609
2665
      warnf(config, "Failed to create the file %s\n", out->filename);
2610
 
      return -1; /* failure */
 
2666
      /*
 
2667
       * Once that libcurl has called back my_fwrite() the returned value
 
2668
       * is checked against the amount that was intended to be written, if
 
2669
       * it does not match then it fails with CURLE_WRITE_ERROR. So at this
 
2670
       * point returning a value different from sz*nmemb indicates failure.
 
2671
       */
 
2672
      rc = (0 == (sz * nmemb)) ? 1 : 0;
 
2673
      return rc; /* failure */
2611
2674
    }
2612
2675
  }
2613
2676
 
2662
2725
 
2663
2726
  rc = fwrite(buffer, sz, nmemb, out->stream);
2664
2727
 
2665
 
  if((int)(sz * nmemb) == rc) {
 
2728
  if((sz * nmemb) == rc) {
2666
2729
    /* we added this amount of data to the output */
2667
2730
    out->bytes += (sz * nmemb);
2668
2731
  }
2700
2763
  return CURLIOE_OK;
2701
2764
}
2702
2765
 
2703
 
static int my_fread(void *buffer, size_t sz, size_t nmemb, void *userp)
 
2766
static size_t my_fread(void *buffer, size_t sz, size_t nmemb, void *userp)
2704
2767
{
2705
 
  int rc;
 
2768
  size_t rc;
2706
2769
  struct InStruct *in=(struct InStruct *)userp;
2707
2770
  struct Configurable *config = in->config;
2708
2771
  curl_off_t size = (curl_off_t)(sz * nmemb);  /* typecast to prevent warnings
2763
2826
 
2764
2827
  rc = fread(buffer, sz, nmemb, in->stream);
2765
2828
#if 0
2766
 
  fprintf(stderr, "CALLBACK returning %d bytes data\n", (int)rc);
 
2829
  if (sizeof(rc) > sizeof(unsigned int))
 
2830
    fprintf(stderr, "CALLBACK returning %lu bytes data\n", rc);
 
2831
  else
 
2832
    fprintf(stderr, "CALLBACK returning %u bytes data\n", rc);
2767
2833
#endif
2768
2834
  return rc;
2769
2835
}
2879
2945
  bar->out = config->errors;
2880
2946
}
2881
2947
 
 
2948
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
 
2949
/*
 
2950
 * convert_from_network() is an internal function
 
2951
 * for performing ASCII conversions on non-ASCII platforms.
 
2952
 */
 
2953
CURLcode
 
2954
convert_from_network(char *buffer, size_t length)
 
2955
{
 
2956
  CURLcode rc;
 
2957
 
 
2958
  /* translate from the network encoding to the host encoding */
 
2959
  char *input_ptr, *output_ptr;
 
2960
  size_t in_bytes, out_bytes;
 
2961
 
 
2962
  /* open an iconv conversion descriptor if necessary */
 
2963
  if(inbound_cd == (iconv_t)-1) {
 
2964
    inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
 
2965
                            CURL_ICONV_CODESET_OF_NETWORK);
 
2966
    if(inbound_cd == (iconv_t)-1) {
 
2967
      return CURLE_CONV_FAILED;
 
2968
    }
 
2969
  }
 
2970
  /* call iconv */
 
2971
  input_ptr = output_ptr = buffer;
 
2972
  in_bytes = out_bytes = length;
 
2973
  rc = iconv(inbound_cd, &input_ptr,  &in_bytes,
 
2974
                         &output_ptr, &out_bytes);
 
2975
  if ((rc == -1) || (in_bytes != 0)) {
 
2976
    return CURLE_CONV_FAILED;
 
2977
  }
 
2978
 
 
2979
  return CURLE_OK;
 
2980
}
 
2981
 
 
2982
static
 
2983
char convert_char(curl_infotype infotype, char this_char) {
 
2984
/* determine how this specific character should be displayed */
 
2985
  switch(infotype) {
 
2986
  case CURLINFO_DATA_IN:
 
2987
  case CURLINFO_DATA_OUT:
 
2988
  case CURLINFO_SSL_DATA_IN:
 
2989
  case CURLINFO_SSL_DATA_OUT:
 
2990
    /* data, treat as ASCII */
 
2991
    if ((this_char >= 0x20) && (this_char < 0x7f)) {
 
2992
      /* printable ASCII hex value: convert to host encoding */
 
2993
      convert_from_network(&this_char, 1);
 
2994
    } else {
 
2995
      /* non-printable ASCII, use a replacement character */
 
2996
      return(UNPRINTABLE_CHAR);
 
2997
    }
 
2998
    /* fall through to default */
 
2999
  default:
 
3000
    /* treat as host encoding */
 
3001
    if (isprint(this_char)
 
3002
    &&  (this_char != '\t')
 
3003
    &&  (this_char != '\r')
 
3004
    &&  (this_char != '\n')) {
 
3005
      /* printable characters excluding tabs and line end characters */
 
3006
      return(this_char);
 
3007
    }
 
3008
    break;
 
3009
  }
 
3010
  /* non-printable, use a replacement character  */
 
3011
  return(UNPRINTABLE_CHAR);
 
3012
}
 
3013
#endif /* CURL_DOES_CONVERSIONS */
 
3014
 
2882
3015
static
2883
3016
void dump(char *timebuf, const char *text,
2884
3017
          FILE *stream, unsigned char *ptr, size_t size,
2885
 
          trace tracetype)
 
3018
          trace tracetype, curl_infotype infotype)
2886
3019
{
2887
3020
  size_t i;
2888
3021
  size_t c;
2915
3048
        i+=(c+2-width);
2916
3049
        break;
2917
3050
      }
 
3051
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
 
3052
      /* convert to host encoding and print this character */
 
3053
      fprintf(stream, "%c", convert_char(infotype, ptr[i+c]));
 
3054
#else
 
3055
      (void)infotype;
2918
3056
      fprintf(stream, "%c",
2919
 
              (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.');
 
3057
              (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:UNPRINTABLE_CHAR);
 
3058
#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
2920
3059
      /* check again for 0D0A, to avoid an extra \n if it's at width */
2921
3060
      if ((tracetype == TRACE_ASCII) &&
2922
3061
          (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
2940
3079
  struct timeval tv;
2941
3080
  struct tm *now;
2942
3081
  char timebuf[20];
 
3082
  time_t secs;
2943
3083
 
2944
3084
  (void)handle; /* prevent compiler warning */
2945
3085
 
2946
3086
  tv = curlx_tvnow();
2947
 
  now = localtime(&tv.tv_sec);  /* not multithread safe but we don't care */
 
3087
  secs = tv.tv_sec;
 
3088
  now = localtime(&secs);  /* not multithread safe but we don't care */
2948
3089
  if(config->tracetime)
2949
3090
    snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06d ",
2950
3091
             now->tm_hour, now->tm_min, now->tm_sec, tv.tv_usec);
3039
3180
    break;
3040
3181
  }
3041
3182
 
3042
 
  dump(timebuf, text, output, data, size, config->tracetype);
 
3183
  dump(timebuf, text, output, data, size, config->tracetype, type);
3043
3184
  return 0;
3044
3185
}
3045
3186
 
3101
3242
  curl_slist_free_all(config->headers);
3102
3243
}
3103
3244
 
3104
 
#if defined(WIN32) && !defined(__CYGWIN32__)
 
3245
#if defined(WIN32) && !defined(__CYGWIN__)
3105
3246
 
3106
3247
/* Function to find CACert bundle on a Win32 platform using SearchPath.
3107
 
 * (SearchPath is defined in windows.h, which is #included into libcurl)
 
3248
 * (SearchPath is already declared via inclusions done in setup header file)
3108
3249
 * (Use the ASCII version instead of the unicode one!)
3109
3250
 * The order of the directories it searches is:
3110
3251
 *  1. application's directory
3344
3485
 
3345
3486
    if(env)
3346
3487
      curl_free(env);
3347
 
#if defined(WIN32) && !defined(__CYGWIN32__)
 
3488
#if defined(WIN32) && !defined(__CYGWIN__)
3348
3489
    else
3349
3490
      FindWin32CACert(config, "curl-ca-bundle.crt");
3350
3491
#endif
3607
3748
              filep = uploadfile;
3608
3749
 
3609
3750
            /* URL encode the file name */
3610
 
            filep = curl_escape(filep, 0 /* use strlen */);
 
3751
            filep = curl_easy_escape(curl, filep, 0 /* use strlen */);
3611
3752
 
3612
3753
            if(filep) {
3613
3754
 
3697
3838
          /*
3698
3839
           * Then append ? followed by the get fields to the url.
3699
3840
           */
3700
 
          urlbuffer=(char *)malloc(strlen(url) + strlen(httpgetfields) + 2);
 
3841
          urlbuffer=(char *)malloc(strlen(url) + strlen(httpgetfields) + 3);
3701
3842
          if(!urlbuffer) {
3702
3843
            helpf("out of memory\n");
3703
3844
            return CURLE_OUT_OF_MEMORY;
3944
4085
        if(config->ftp_ssl)
3945
4086
          curl_easy_setopt(curl, CURLOPT_FTP_SSL, CURLFTPSSL_TRY);
3946
4087
 
3947
 
        /* new in curl 7.11.1 */
3948
 
        if(config->socks5proxy) {
3949
 
          curl_easy_setopt(curl, CURLOPT_PROXY, config->socks5proxy);
3950
 
          curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
 
4088
        /* new in curl 7.11.1, modified in 7.15.2 */
 
4089
        if(config->socksproxy) {
 
4090
          curl_easy_setopt(curl, CURLOPT_PROXY, config->socksproxy);
 
4091
          curl_easy_setopt(curl, CURLOPT_PROXYTYPE, config->socksver);
3951
4092
        }
3952
4093
 
3953
4094
        /* curl 7.13.0 */
3966
4107
        /* curl 7.15.1 */
3967
4108
        curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD, config->ftp_filemethod);
3968
4109
 
 
4110
        /* curl 7.15.2 */
 
4111
        if(config->localport) {
 
4112
          curl_easy_setopt(curl, CURLOPT_LOCALPORT, config->localport);
 
4113
          curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE, config->localportrange);
 
4114
        }
 
4115
 
3969
4116
        retry_numretries = config->req_retry;
3970
4117
 
3971
4118
        retrystart = curlx_tvnow();
4018
4165
                }
4019
4166
              }
4020
4167
            } /* if CURLE_OK */
4021
 
            else if((CURLE_FTP_USER_PASSWORD_INCORRECT == res) ||
4022
 
                    (CURLE_LOGIN_DENIED == res)) {
 
4168
            else if(CURLE_LOGIN_DENIED == res) {
4023
4169
              curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
4024
4170
 
4025
4171
              if(response/100 == 5)
4139
4285
        /* Important that we set the time _after_ the file has been
4140
4286
           closed, as is done above here */
4141
4287
        if(config->remote_time && outs.filename) {
4142
 
          /* as libcurl if we got a time. Pretty please */
 
4288
          /* ask libcurl if we got a time. Pretty please */
4143
4289
          long filetime;
4144
4290
          curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
4145
4291
          if(filetime >= 0) {
4182
4328
 
4183
4329
    } /* loop to the next globbed upload file */
4184
4330
 
4185
 
    if(inglob)
 
4331
    if(inglob) {
4186
4332
      glob_cleanup(inglob);
 
4333
      inglob = NULL;
 
4334
    }
4187
4335
 
4188
4336
    if(outfiles)
4189
4337
      free(outfiles);
4230
4378
  return res;
4231
4379
}
4232
4380
 
4233
 
static void checkfds(void);
4234
 
 
 
4381
/* Ensure that file descriptors 0, 1 and 2 (stdin, stdout, stderr) are
 
4382
   open before starting to run.  Otherwise, the first three network
 
4383
   sockets opened by curl could be used for input sources, downloaded data
 
4384
   or error logs as they will effectively be stdin, stdout and/or stderr.
 
4385
*/
4235
4386
static void checkfds(void)
4236
4387
{
4237
4388
#ifdef HAVE_PIPE
4242
4393
         fd[1] == STDIN_FILENO ||
4243
4394
         fd[1] == STDOUT_FILENO ||
4244
4395
         fd[1] == STDERR_FILENO )
4245
 
    pipe(fd);
4246
 
 
 
4396
    if (pipe(fd) < 0)
 
4397
      return;   /* Out of handles. This isn't really a big problem now, but
 
4398
                   will be when we try to create a socket later. */
4247
4399
  close(fd[0]);
4248
4400
  close(fd[1]);
4249
4401
#endif