Skip to content
Snippets Groups Projects
main.c 99.5 KiB
Newer Older
  • Learn to ignore specific revisions
  •       curl_easy_setopt(curl, CURLOPT_SSLCERT, config->cert);
    
          curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, config->cert_type);
          curl_easy_setopt(curl, CURLOPT_SSLKEY, config->key);
          curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, config->key_type);
          curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, config->key_passwd);
    
          /* default to strict verifyhost */
          curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
    
          if(config->cacert || config->capath) {
    
            if (config->cacert)
              curl_easy_setopt(curl, CURLOPT_CAINFO, config->cacert);
    
            if (config->capath)
              curl_easy_setopt(curl, CURLOPT_CAPATH, config->capath);
    
            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE);
          }
    
              /* new stuff needed for libcurl 7.10 */
              curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    
              curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1);
            }
    
          if((config->conf&CONF_NOBODY) ||
             config->remote_time) {
    
            /* no body or use remote time */
            curl_easy_setopt(curl, CURLOPT_FILETIME, TRUE);
          }
          
          if (config->maxredirs) 
            curl_easy_setopt(curl, CURLOPT_MAXREDIRS, config->maxredirs); 
          else 
            curl_easy_setopt(curl, CURLOPT_MAXREDIRS, DEFAULT_MAXREDIRS); 
    
          curl_easy_setopt(curl, CURLOPT_CRLF, config->crlf);
          curl_easy_setopt(curl, CURLOPT_QUOTE, config->quote);
          curl_easy_setopt(curl, CURLOPT_POSTQUOTE, config->postquote);
          curl_easy_setopt(curl, CURLOPT_WRITEHEADER,
                           config->headerfile?&heads:NULL);
          curl_easy_setopt(curl, CURLOPT_COOKIEFILE, config->cookiefile);
    
          /* cookie jar was added in 7.9 */
          curl_easy_setopt(curl, CURLOPT_COOKIEJAR, config->cookiejar);
    
          /* cookie session added in 7.9.7 */
          curl_easy_setopt(curl, CURLOPT_COOKIESESSION, config->cookiesession);
    
    
          curl_easy_setopt(curl, CURLOPT_SSLVERSION, config->ssl_version);
          curl_easy_setopt(curl, CURLOPT_TIMECONDITION, config->timecond);
          curl_easy_setopt(curl, CURLOPT_TIMEVALUE, config->condtime);
          curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, config->customrequest);
          curl_easy_setopt(curl, CURLOPT_STDERR, config->errors);
    
          /* three new ones in libcurl 7.3: */
          curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, config->proxytunnel);
          curl_easy_setopt(curl, CURLOPT_INTERFACE, config->iface);
          curl_easy_setopt(curl, CURLOPT_KRB4LEVEL, config->krb4level);
          
          if((config->progressmode == CURL_PROGRESS_BAR) &&
             !(config->conf&(CONF_NOPROGRESS|CONF_MUTE))) {
            /* we want the alternative style, then we have to implement it
               ourselves! */
    
            progressbarinit(&progressbar, config);
    
            curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, myprogress);
            curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &progressbar);
          }
    
          /* new in libcurl 7.6.2: */
          curl_easy_setopt(curl, CURLOPT_TELNETOPTIONS, config->telnet_options);
    
    
          /* new in libcurl 7.7: */
          curl_easy_setopt(curl, CURLOPT_RANDOM_FILE, config->random_file);
          curl_easy_setopt(curl, CURLOPT_EGDSOCKET, config->egd_file);
    
          curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, config->connecttimeout);
    
    
          if(config->cipher_list)
            curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list);
    
    
          if(config->httpversion)
            curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, config->httpversion);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
          /* new in libcurl 7.9.2: */
          if(config->disable_epsv)
            /* disable it */
            curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, FALSE);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
          /* new in libcurl 7.10.5 */
          if(config->disable_eprt)
            /* disable it */
            curl_easy_setopt(curl, CURLOPT_FTP_USE_EPRT, FALSE);
    
          /* new in libcurl 7.10.6 (default is Basic) */
    
          if(config->authtype)
            curl_easy_setopt(curl, CURLOPT_HTTPAUTH, config->authtype);
    
          /* new in curl 7.9.7 */
          if(config->trace_dump) {
            curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
            curl_easy_setopt(curl, CURLOPT_DEBUGDATA, config);
    
            config->conf |= CONF_VERBOSE; /* force verbose */
    
          curl_easy_setopt(curl, CURLOPT_VERBOSE, config->conf&CONF_VERBOSE);
    
          /* new in curl 7.10 */
          curl_easy_setopt(curl, CURLOPT_ENCODING, 
    
                           (config->encoding) ? "" : NULL);
    
          /* new in curl 7.10.7 */
          curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS,
                           config->ftp_create_dirs);
    
    
          res = curl_easy_perform(curl);
    
          if((config->progressmode == CURL_PROGRESS_BAR) &&
             progressbar.calls) {
    
            /* if the custom progress bar has been displayed, we output a
               newline here */
            fputs("\n", progressbar.out);
          }
    
    
          if(config->writeout) {
            ourWriteOut(curl, config->writeout);
    
    #ifdef USE_ENVIRONMENT
          if (config->writeenv)
            ourWriteEnv(curl);
    #endif
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    #ifdef	VMS
    
          if (!config->showerror)  {
            vms_show = VMSSTS_HIDE;
          }
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    #else
    
          if((res!=CURLE_OK) && config->showerror) {
            if(CURLE_SSL_CACERT == res) {
              fprintf(config->errors, "curl: (%d) %s\n\n", res, errorbuffer);
    
    #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). The default\n" \
    " bundle is named curl-ca-bundle.crt; 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"
    
              fprintf(config->errors, "%s%s",
                      CURL_CA_CERT_ERRORMSG1,
                      CURL_CA_CERT_ERRORMSG2 );
    
            }
            else
              fprintf(config->errors, "curl: (%d) %s\n", res, errorbuffer);
          }
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    #endif
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
    
          if (outfile && !curl_strequal(outfile, "-") && outs.stream)
    
            fclose(outs.stream);
    
    
    #ifdef HAVE_UTIME
          /* Important that we set the time _after_ the file has been 
             closed, as is done above here */
          if(config->remote_time && outs.filename) {
            /* as libcurl if we got a time. Pretty please */
            long filetime;
            curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
            if(filetime >= 0) {
              struct utimbuf times;
              times.actime = filetime;
              times.modtime = filetime;
              utime(outs.filename, &times); /* set the time we got */
            }
          }
    #endif
    
    
          if (config->infile)
            fclose(infd);
          if(headerfilep)
            fclose(headerfilep);
          
    
          if(url)
            free(url);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
    
          if(outfile)
            free(outfile);
    
        if(outfiles)
          free(outfiles);
    
        if(urls)
          /* cleanup memory used for URL globbing patterns */
          glob_cleanup(urls);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
    
        /* empty this urlnode struct */
        if(urlnode->url)
          free(urlnode->url);
        if(urlnode->outfile)
          free(urlnode->outfile);
    
        /* move on to the next URL */
        nextnode=urlnode->next;
        free(urlnode); /* free the node */
        urlnode = nextnode;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
    
      } /* while-loop through all URLs */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
    
      if(config->headerfile && !headerfilep && heads.stream)
        fclose(heads.stream);
    
    
      if(config->trace_fopened)
    
      if(allocuseragent)
    
        free(config->useragent);
    
      /* cleanup the curl handle! */
      curl_easy_cleanup(curl);
    
    
      struct Configurable config;
    
      memset(&config, 0, sizeof(struct Configurable));
    
      res = operate(&config, argc, argv);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    #ifdef	VMS
    
      if (res > 52) res = 53;		/* MAXMSG, porting helper */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      return (vms_cond[res]|vms_show);
    #else
    
      return res;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    #endif
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    }
    
    
    static char *my_get_line(FILE *fp)
    {
       char buf[4096];
       char *nl = NULL;
       char *retval = NULL;
    
    
       do {
         if (NULL == fgets(buf, sizeof(buf), fp))
           break;
         if (NULL == retval)
           retval = strdup(buf);
         else {
           if (NULL == (retval = realloc(retval,
                                         strlen(retval) + strlen(buf) + 1)))
    
       }
       while (NULL == (nl = strchr(retval, '\n')));
    
       if (NULL != nl)
         *nl = '\0';
    
       return retval;
    }
    
    
    
    /* Create the needed directory hierarchy recursively in order to save
       multi-GETs in file output, ie:
       curl "http://my.site/dir[1-5]/file[1-5].txt" -o "dir#1/file#2.txt"
       should create all the dir* automagically
    */
    static int create_dir_hierarchy(char *outfile)
    {
      char *tempdir;
      char *tempdir2;
      char *outdup;
      char *dirbuildup;
      int result=0;
      
      outdup = strdup(outfile);
      dirbuildup = malloc(sizeof(char) * strlen(outfile));
    
      if(!dirbuildup)
        return -1;
      dirbuildup[0] = '\0';
    
    
      tempdir = strtok(outdup, DIR_CHAR);
    
      while (tempdir != NULL) {
        tempdir2 = strtok(NULL, DIR_CHAR);
        /* since strtok returns a token for the last word even
           if not ending with DIR_CHAR, we need to prune it */
        if (tempdir2 != NULL) {
          if (strlen(dirbuildup) > 0)
            sprintf(dirbuildup,"%s%s%s",dirbuildup, DIR_CHAR, tempdir);
          else {
    
            if (0 != strncmp(outdup, DIR_CHAR, 1))
    
              sprintf(dirbuildup,"%s",tempdir);
            else
              sprintf(dirbuildup,"%s%s", DIR_CHAR, tempdir);
          }
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
          if (access(dirbuildup, F_OK) == -1) {
    
            result = mkdir(dirbuildup,(mode_t)0000750);
            if (-1 == result) {
              switch (errno) {
    #ifdef EACCES
              case EACCES:
                fprintf(stderr,"You don't have permission to create %s.\n",
                        dirbuildup);
                break;
    #endif
    #ifdef ENAMETOOLONG
              case ENAMETOOLONG:
                fprintf(stderr,"The directory name %s is too long.\n",
                        dirbuildup);
                break;
    #endif
    #ifdef EROFS
              case EROFS:
                fprintf(stderr,"%s resides on a read-only file system.\n",
                        dirbuildup);
                break;
    #endif
    #ifdef ENOSPC
              case ENOSPC:
                fprintf(stderr,"No space left on the file system that will "
                        "contain the directory %s.\n", dirbuildup);
                break;
    #endif
    #ifdef EDQUOT
              case EDQUOT:
                fprintf(stderr,"Cannot create directory %s because you "
                        "exceeded your quota.\n", dirbuildup);
                break;
    #endif
              default :
                fprintf(stderr,"Error creating directory %s.\n", dirbuildup);
                break;
              }
              break; /* get out of loop */
            }
          }
        }
        tempdir = tempdir2;
      }
      free(dirbuildup);
      free(outdup);
    
      return result; /* 0 is fine, -1 is badness */
    }
    
    
    #ifdef __DJGPP__
    /* The following functions are taken with modification from the DJGPP
     * port of tar 1.12. They use algorithms originally from DJTAR. */
    
    char *
    msdosify (char *file_name)
    {
      static char dos_name[PATH_MAX];
      static char illegal_chars_dos[] = ".+, ;=[]|<>\\\":?*";
      static char *illegal_chars_w95 = &illegal_chars_dos[8];
      int idx, dot_idx;
      char *s = file_name, *d = dos_name;
      char *illegal_aliens = illegal_chars_dos;
      size_t len = sizeof (illegal_chars_dos) - 1;
      int lfn = 0;
    
      /* Support for Windows 9X VFAT systems, when available.  */
      if (_use_lfn (file_name))
        lfn = 1;
      if (lfn) {
        illegal_aliens = illegal_chars_w95;
        len -= (illegal_chars_w95 - illegal_chars_dos);
      }
      
      /* Get past the drive letter, if any. */
      if (s[0] >= 'A' && s[0] <= 'z' && s[1] == ':') {
        *d++ = *s++;
        *d++ = *s++;
      }
    
      for (idx = 0, dot_idx = -1; *s; s++, d++) {
        if (memchr (illegal_aliens, *s, len)) {
          /* Dots are special: DOS doesn't allow them as the leading character,
             and a file name cannot have more than a single dot.  We leave the
             first non-leading dot alone, unless it comes too close to the
             beginning of the name: we want sh.lex.c to become sh_lex.c, not
             sh.lex-c.  */
          if (*s == '.') {
            if (idx == 0 && (s[1] == '/' || (s[1] == '.' && s[2] == '/'))) {
              /* Copy "./" and "../" verbatim.  */
              *d++ = *s++;
              if (*s == '.')
                *d++ = *s++;
              *d = *s;
            }
            else if (idx == 0)
              *d = '_';
            else if (dot_idx >= 0) {
              if (dot_idx < 5) { /* 5 is a heuristic ad-hoc'ery */
                d[dot_idx - idx] = '_'; /* replace previous dot */
                *d = '.';
              }
              else
                *d = '-';
            }
            else
              *d = '.';
    
            if (*s == '.')
              dot_idx = idx;
          }
          else if (*s == '+' && s[1] == '+') {
            if (idx - 2 == dot_idx) { /* .c++, .h++ etc. */
              *d++ = 'x';
              *d   = 'x';
            }
            else {
              /* libg++ etc.  */
              memcpy (d, "plus", 4);
              d += 3;
            }
            s++;
            idx++;
          }
          else
            *d = '_';
        }
        else
          *d = *s;
        if (*s == '/') {
          idx = 0;
          dot_idx = -1;
        }
        else
          idx++;
      }
    
      *d = '\0';
      return dos_name;
    }
    
    char *
    rename_if_dos_device_name (char *file_name)
    {
      /* We could have a file whose name is a device on MS-DOS.  Trying to
       * retrieve such a file would fail at best and wedge us at worst.  We need
       * to rename such files. */
      extern char *basename (const char *);
      char *base;
      struct stat st_buf;
      char fname[PATH_MAX];
    
      strcpy (fname, file_name);
      base = basename (fname);
      if (((stat(base, &st_buf)) == 0) && (S_ISCHR(st_buf.st_mode))) {
        size_t blen = strlen (base);
    
        /* Prepend a '_'.  */
        memmove (base + 1, base, blen + 1);
        base[0] = '_';
        strcpy (file_name, fname);
      }
      return file_name;
    }
    
    #endif /* __DJGPP__ */