Base code merged to SPIN 2.4
[platform/upstream/curl.git] / src / tool_main.c
index dabd5c9..9a5ceba 100644 (file)
 #include <signal.h>
 #endif
 
+#ifdef USE_NSS
+#include <nspr.h>
+#include <plarenas.h>
+#endif
+
 #define ENABLE_CURLX_PRINTF
 /* use our own printf() functions */
 #include "curlx.h"
@@ -121,7 +126,7 @@ static void memory_tracking_init(void)
  * _any_ libcurl usage. If this fails, *NO* libcurl functions may be
  * used, or havoc may be the result.
  */
-static CURLcode main_init(struct Configurable *config)
+static CURLcode main_init(struct GlobalConfig *config)
 {
   CURLcode result = CURLE_OK;
 
@@ -130,30 +135,95 @@ static CURLcode main_init(struct Configurable *config)
   _djstat_flags |= _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
 #endif
 
-  /* Perform the libcurl initialization */
-  result = curl_global_init(CURL_GLOBAL_DEFAULT);
-  if(!result) {
-    /* Get information about libcurl */
-    result = get_libcurl_info();
+  /* Initialise the global config */
+  config->showerror = -1;             /* Will show errors */
+  config->errors = stderr;            /* Default errors to stderr */
+
+  /* Allocate the initial operate config */
+  config->first = config->last = malloc(sizeof(struct OperationConfig));
+  if(config->first) {
+    /* Perform the libcurl initialization */
+    result = curl_global_init(CURL_GLOBAL_DEFAULT);
+    if(!result) {
+      /* Get information about libcurl */
+      result = get_libcurl_info();
 
-    if(result)
-      helpf(config->errors, "error retrieving curl library information\n");
+      if(!result) {
+        /* Get a curl handle to use for all forthcoming curl transfers */
+        config->easy = curl_easy_init();
+        if(config->easy) {
+          /* Initialise the config */
+          config_init(config->first);
+          config->first->easy = config->easy;
+          config->first->global = config;
+        }
+        else {
+          helpf(stderr, "error initializing curl easy handle\n");
+          result = CURLE_FAILED_INIT;
+          free(config->first);
+        }
+      }
+      else {
+        helpf(stderr, "error retrieving curl library information\n");
+        free(config->first);
+      }
+    }
+    else {
+      helpf(stderr, "error initializing curl library\n");
+      free(config->first);
+    }
+  }
+  else {
+    helpf(stderr, "error initializing curl\n");
+    result = CURLE_FAILED_INIT;
   }
-  else
-    helpf(config->errors, "error initializing curl library\n");
 
   return result;
 }
 
+static void free_config_fields(struct GlobalConfig *config)
+{
+  Curl_safefree(config->trace_dump);
+
+  if(config->errors_fopened && config->errors)
+    fclose(config->errors);
+  config->errors = NULL;
+
+  if(config->trace_fopened && config->trace_stream)
+    fclose(config->trace_stream);
+  config->trace_stream = NULL;
+
+  Curl_safefree(config->libcurl);
+}
+
 /*
  * This is the main global destructor for the app. Call this after
  * _all_ libcurl usage is done.
  */
-static void main_free(void)
+static void main_free(struct GlobalConfig *config)
 {
+  /* Cleanup the easy handle */
+  curl_easy_cleanup(config->easy);
+  config->easy = NULL;
+
+  /* Main cleanup */
   curl_global_cleanup();
   convert_cleanup();
   metalink_cleanup();
+#ifdef USE_NSS
+  if(PR_Initialized()) {
+    /* prevent valgrind from reporting still reachable mem from NSRP arenas */
+    PL_ArenaFinish();
+    /* prevent valgrind from reporting possibly lost memory (fd cache, ...) */
+    PR_Cleanup();
+  }
+#endif
+  free_config_fields(config);
+
+  /* Free the config structures */
+  config_free(config->last);
+  config->first = NULL;
+  config->last = NULL;
 }
 
 /*
@@ -162,7 +232,8 @@ static void main_free(void)
 int main(int argc, char *argv[])
 {
   CURLcode result = CURLE_OK;
-  struct Configurable *config;
+  struct GlobalConfig global;
+  memset(&global, 0, sizeof(global));
 
   main_checkfds();
 
@@ -173,36 +244,20 @@ int main(int argc, char *argv[])
   /* Initialize memory tracking */
   memory_tracking_init();
 
-  /* Allocate the initial config */
-  config = malloc(sizeof(struct Configurable));
-
-  if(config) {
-    /* Initialise the config */
-    config_init(config);
-
-    /* Initialize the curl library - do not call any libcurl functions before
-       this point */
-    result = main_init(config);
-    if(!result) {
-      /* Start our curl operation */
-      result = operate(config, argc, argv);
-
-      /* Perform the main cleanup */
-      main_free();
-    }
+  /* Initialize the curl library - do not call any libcurl functions before
+     this point */
+  result = main_init(&global);
+  if(!result) {
+    /* Start our curl operation */
+    result = operate(&global, argc, argv);
 
 #ifdef __SYMBIAN32__
-    if(config->showerror)
+    if(global.showerror)
       tool_pressanykey();
 #endif
 
-    /* Free the config structures */
-    config_free(config);
-    config = NULL;
-  }
-  else {
-    helpf(stderr, "error initializing curl\n");
-    result = CURLE_FAILED_INIT;
+    /* Perform the main cleanup */
+    main_free(&global);
   }
 
 #ifdef __NOVELL_LIBC__
@@ -211,7 +266,7 @@ int main(int argc, char *argv[])
 #endif
 
 #ifdef __VMS
-  vms_special_exit(res, vms_show);
+  vms_special_exit(result, vms_show);
 #else
   return (int)result;
 #endif