Skip to content
tool_operate.c 58.9 KiB
Newer Older
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ***************************************************************************/
#include "tool_setup.h"

#ifdef HAVE_UNISTD_H
#  include <unistd.h>
#endif

#ifdef HAVE_FCNTL_H
#  include <fcntl.h>
#endif

#ifdef HAVE_UTIME_H
#  include <utime.h>
#elif defined(HAVE_SYS_UTIME_H)
#  include <sys/utime.h>
#endif

#ifdef HAVE_LOCALE_H
#  include <locale.h>
#endif

#ifdef HAVE_NETINET_TCP_H
#  include <netinet/tcp.h>
#endif

#include "rawstr.h"

#define ENABLE_CURLX_PRINTF
/* use our own printf() functions */
#include "curlx.h"

#include "tool_binmode.h"
#include "tool_cfgable.h"
#include "tool_cb_dbg.h"
#include "tool_cb_hdr.h"
#include "tool_cb_prg.h"
#include "tool_cb_rea.h"
#include "tool_cb_see.h"
#include "tool_cb_wrt.h"
#include "tool_dirhie.h"
#include "tool_doswin.h"
#include "tool_easysrc.h"
#include "tool_getparam.h"
#include "tool_helpers.h"
#include "tool_homedir.h"
#include "tool_libinfo.h"
#include "tool_main.h"
#include "tool_metalink.h"
#include "tool_msgs.h"
#include "tool_operate.h"
#include "tool_operhlp.h"
#include "tool_parsecfg.h"
#include "tool_setopt.h"
#include "tool_sleep.h"
#include "tool_urlglob.h"
#include "tool_util.h"
#include "tool_writeenv.h"
#include "tool_writeout.h"
#include "tool_xattr.h"

#include "memdebug.h" /* keep this as LAST include */

#define CURLseparator  "--_curl_--"

#ifndef O_BINARY
/* since O_BINARY as used in bitmasks, setting it to zero makes it usable in
   source code but yet it doesn't ruin anything */
#  define O_BINARY 0
#endif

#define CURL_CA_CERT_ERRORMSG1                                              \
  "More details here: http://curl.haxx.se/docs/sslcerts.html\n\n"           \
  "curl performs SSL certificate verification by default, "                 \
  "using a \"bundle\"\n"                                                    \
  " of Certificate Authority (CA) public keys (CA certs). If the default\n" \
  " bundle file isn't adequate, you can specify an alternate file\n"        \
  " using the --cacert option.\n"

#define CURL_CA_CERT_ERRORMSG2                                              \
  "If this HTTPS server uses a certificate signed by a CA represented in\n" \
  " the bundle, the certificate verification probably failed due to a\n"    \
  " problem with the certificate (it might be expired, or the name might\n" \
  " not match the domain name in the URL).\n"                               \
  "If you'd like to turn off curl's verification of the certificate, use\n" \
  " the -k (or --insecure) option.\n"

static int is_fatal_error(int code)
{
  switch(code) {
  /* TODO: Should CURLE_SSL_CACERT be included as critical error ? */
  case CURLE_FAILED_INIT:
  case CURLE_OUT_OF_MEMORY:
  case CURLE_UNKNOWN_OPTION:
  case CURLE_FUNCTION_NOT_FOUND:
  case CURLE_BAD_FUNCTION_ARGUMENT:
    /* critical error */
    return 1;
  default:
    break;
  }
  /* no error or not critical */
  return 0;
}

int operate(struct Configurable *config, int argc, argv_item_t argv[])
{
  char errorbuffer[CURL_ERROR_SIZE];
  struct ProgressData progressbar;
  struct getout *urlnode;

  struct HdrCbData hdrcbdata;
  struct OutStruct heads;

  metalinkfile *mlfile_last = NULL;
  CURL *curl = NULL;
  char *httpgetfields = NULL;

  bool stillflags;
  int res = 0;
  int i;

  bool orig_noprogress = config->noprogress;
  bool orig_isatty = config->isatty;

  errorbuffer[0] = '\0';
  /* default headers output stream is stdout */
  memset(&hdrcbdata, 0, sizeof(struct HdrCbData));
  memset(&heads, 0, sizeof(struct OutStruct));
  heads.stream = stdout;
  heads.config = config;

  memory_tracking_init();

  /*
  ** Initialize curl library - do not call any libcurl functions before
  ** this point. Note that the memory_tracking_init() magic above is an
  ** exception, but then that's not part of the official public API.
  */
  if(main_init() != CURLE_OK) {
    helpf(config->errors, "error initializing curl library\n");
    return CURLE_FAILED_INIT;
  }

  /* Get libcurl info right away */
  if(get_libcurl_info() != CURLE_OK) {
    helpf(config->errors, "error retrieving curl library information\n");
    main_free();
    return CURLE_FAILED_INIT;
  }

  /* Get a curl handle to use for all forthcoming curl transfers */
  curl = curl_easy_init();
  if(!curl) {
    helpf(config->errors, "error initializing curl easy handle\n");
    main_free();
    return CURLE_FAILED_INIT;
  }
  config->easy = curl;

  /*
  ** Beyond this point no return'ing from this function allowed.
  ** Jump to label 'quit_curl' in order to abandon this function
  ** from outside of nested loops further down below.
  */

  /* setup proper locale from environment */
#ifdef HAVE_SETLOCALE
  setlocale(LC_ALL, "");
#endif

  /* inits */
  config->postfieldsize = -1;
  config->showerror = -1; /* will show errors */
  config->use_httpget = FALSE;
  config->create_dirs = FALSE;
  config->maxredirs = DEFAULT_MAXREDIRS;
  config->proto = CURLPROTO_ALL; /* FIXME: better to read from library */
  config->proto_present = FALSE;
  config->proto_redir =
Loading
Loading full blame…