tool_main.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                  _   _ ____  _
00003  *  Project                     ___| | | |  _ \| |
00004  *                             / __| | | | |_) | |
00005  *                            | (__| |_| |  _ <| |___
00006  *                             \___|\___/|_| \_\_____|
00007  *
00008  * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
00009  *
00010  * This software is licensed as described in the file COPYING, which
00011  * you should have received as part of this distribution. The terms
00012  * are also available at https://curl.haxx.se/docs/copyright.html.
00013  *
00014  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00015  * copies of the Software, and permit persons to whom the Software is
00016  * furnished to do so, under the terms of the COPYING file.
00017  *
00018  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00019  * KIND, either express or implied.
00020  *
00021  ***************************************************************************/
00022 #include "tool_setup.h"
00023 
00024 #include <sys/stat.h>
00025 
00026 #ifdef HAVE_SIGNAL_H
00027 #include <signal.h>
00028 #endif
00029 
00030 #ifdef USE_NSS
00031 #include <nspr.h>
00032 #include <plarenas.h>
00033 #endif
00034 
00035 #define ENABLE_CURLX_PRINTF
00036 /* use our own printf() functions */
00037 #include "curlx.h"
00038 
00039 #include "tool_cfgable.h"
00040 #include "tool_convert.h"
00041 #include "tool_msgs.h"
00042 #include "tool_operate.h"
00043 #include "tool_panykey.h"
00044 #include "tool_vms.h"
00045 #include "tool_main.h"
00046 #include "tool_libinfo.h"
00047 
00048 /*
00049  * This is low-level hard-hacking memory leak tracking and similar. Using
00050  * the library level code from this client-side is ugly, but we do this
00051  * anyway for convenience.
00052  */
00053 #include "memdebug.h" /* keep this as LAST include */
00054 
00055 #ifdef __VMS
00056 /*
00057  * vms_show is a global variable, used in main() as parameter for
00058  * function vms_special_exit() to allow proper curl tool exiting.
00059  * Its value may be set in other tool_*.c source files thanks to
00060  * forward declaration present in tool_vms.h
00061  */
00062 int vms_show = 0;
00063 #endif
00064 
00065 /* if we build a static library for unit tests, there is no main() function */
00066 #ifndef UNITTESTS
00067 
00068 /*
00069  * Ensure that file descriptors 0, 1 and 2 (stdin, stdout, stderr) are
00070  * open before starting to run.  Otherwise, the first three network
00071  * sockets opened by curl could be used for input sources, downloaded data
00072  * or error logs as they will effectively be stdin, stdout and/or stderr.
00073  */
00074 static void main_checkfds(void)
00075 {
00076 #ifdef HAVE_PIPE
00077   int fd[2] = { STDIN_FILENO, STDIN_FILENO };
00078   while(fd[0] == STDIN_FILENO ||
00079         fd[0] == STDOUT_FILENO ||
00080         fd[0] == STDERR_FILENO ||
00081         fd[1] == STDIN_FILENO ||
00082         fd[1] == STDOUT_FILENO ||
00083         fd[1] == STDERR_FILENO)
00084     if(pipe(fd) < 0)
00085       return;   /* Out of handles. This isn't really a big problem now, but
00086                    will be when we try to create a socket later. */
00087   close(fd[0]);
00088   close(fd[1]);
00089 #endif
00090 }
00091 
00092 #ifdef CURLDEBUG
00093 static void memory_tracking_init(void)
00094 {
00095   char *env;
00096   /* if CURL_MEMDEBUG is set, this starts memory tracking message logging */
00097   env = curlx_getenv("CURL_MEMDEBUG");
00098   if(env) {
00099     /* use the value as file name */
00100     char fname[CURL_MT_LOGFNAME_BUFSIZE];
00101     if(strlen(env) >= CURL_MT_LOGFNAME_BUFSIZE)
00102       env[CURL_MT_LOGFNAME_BUFSIZE-1] = '\0';
00103     strcpy(fname, env);
00104     curl_free(env);
00105     curl_memdebug(fname);
00106     /* this weird stuff here is to make curl_free() get called
00107        before curl_memdebug() as otherwise memory tracking will
00108        log a free() without an alloc! */
00109   }
00110   /* if CURL_MEMLIMIT is set, this enables fail-on-alloc-number-N feature */
00111   env = curlx_getenv("CURL_MEMLIMIT");
00112   if(env) {
00113     char *endptr;
00114     long num = strtol(env, &endptr, 10);
00115     if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
00116       curl_memlimit(num);
00117     curl_free(env);
00118   }
00119 }
00120 #else
00121 #  define memory_tracking_init() Curl_nop_stmt
00122 #endif
00123 
00124 /*
00125  * This is the main global constructor for the app. Call this before
00126  * _any_ libcurl usage. If this fails, *NO* libcurl functions may be
00127  * used, or havoc may be the result.
00128  */
00129 static CURLcode main_init(struct GlobalConfig *config)
00130 {
00131   CURLcode result = CURLE_OK;
00132 
00133 #if defined(__DJGPP__) || defined(__GO32__)
00134   /* stop stat() wasting time */
00135   _djstat_flags |= _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
00136 #endif
00137 
00138   /* Initialise the global config */
00139   config->showerror = -1;             /* Will show errors */
00140   config->errors = stderr;            /* Default errors to stderr */
00141 
00142   /* Allocate the initial operate config */
00143   config->first = config->last = malloc(sizeof(struct OperationConfig));
00144   if(config->first) {
00145     /* Perform the libcurl initialization */
00146     result = curl_global_init(CURL_GLOBAL_DEFAULT);
00147     if(!result) {
00148       /* Get information about libcurl */
00149       result = get_libcurl_info();
00150 
00151       if(!result) {
00152         /* Get a curl handle to use for all forthcoming curl transfers */
00153         config->easy = curl_easy_init();
00154         if(config->easy) {
00155           /* Initialise the config */
00156           config_init(config->first);
00157           config->first->easy = config->easy;
00158           config->first->global = config;
00159         }
00160         else {
00161           helpf(stderr, "error initializing curl easy handle\n");
00162           result = CURLE_FAILED_INIT;
00163           free(config->first);
00164         }
00165       }
00166       else {
00167         helpf(stderr, "error retrieving curl library information\n");
00168         free(config->first);
00169       }
00170     }
00171     else {
00172       helpf(stderr, "error initializing curl library\n");
00173       free(config->first);
00174     }
00175   }
00176   else {
00177     helpf(stderr, "error initializing curl\n");
00178     result = CURLE_FAILED_INIT;
00179   }
00180 
00181   return result;
00182 }
00183 
00184 static void free_config_fields(struct GlobalConfig *config)
00185 {
00186   Curl_safefree(config->trace_dump);
00187 
00188   if(config->errors_fopened && config->errors)
00189     fclose(config->errors);
00190   config->errors = NULL;
00191 
00192   if(config->trace_fopened && config->trace_stream)
00193     fclose(config->trace_stream);
00194   config->trace_stream = NULL;
00195 
00196   Curl_safefree(config->libcurl);
00197 }
00198 
00199 /*
00200  * This is the main global destructor for the app. Call this after
00201  * _all_ libcurl usage is done.
00202  */
00203 static void main_free(struct GlobalConfig *config)
00204 {
00205   /* Cleanup the easy handle */
00206   curl_easy_cleanup(config->easy);
00207   config->easy = NULL;
00208 
00209   /* Main cleanup */
00210   curl_global_cleanup();
00211   convert_cleanup();
00212   metalink_cleanup();
00213 #ifdef USE_NSS
00214   if(PR_Initialized()) {
00215     /* prevent valgrind from reporting still reachable mem from NSRP arenas */
00216     PL_ArenaFinish();
00217     /* prevent valgrind from reporting possibly lost memory (fd cache, ...) */
00218     PR_Cleanup();
00219   }
00220 #endif
00221   free_config_fields(config);
00222 
00223   /* Free the config structures */
00224   config_free(config->last);
00225   config->first = NULL;
00226   config->last = NULL;
00227 }
00228 
00229 /*
00230 ** curl tool main function.
00231 */
00232 int main(int argc, char *argv[])
00233 {
00234   CURLcode result = CURLE_OK;
00235   struct GlobalConfig global;
00236   memset(&global, 0, sizeof(global));
00237 
00238   main_checkfds();
00239 
00240 #if defined(HAVE_SIGNAL) && defined(SIGPIPE)
00241   (void)signal(SIGPIPE, SIG_IGN);
00242 #endif
00243 
00244   /* Initialize memory tracking */
00245   memory_tracking_init();
00246 
00247   /* Initialize the curl library - do not call any libcurl functions before
00248      this point */
00249   result = main_init(&global);
00250   if(!result) {
00251     /* Start our curl operation */
00252     result = operate(&global, argc, argv);
00253 
00254 #ifdef __SYMBIAN32__
00255     if(global.showerror)
00256       tool_pressanykey();
00257 #endif
00258 
00259     /* Perform the main cleanup */
00260     main_free(&global);
00261   }
00262 
00263 #ifdef __NOVELL_LIBC__
00264   if(getenv("_IN_NETWARE_BASH_") == NULL)
00265     tool_pressanykey();
00266 #endif
00267 
00268 #ifdef __VMS
00269   vms_special_exit(result, vms_show);
00270 #else
00271   return (int)result;
00272 #endif
00273 }
00274 
00275 #endif /* ndef UNITTESTS */


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:07