1e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/***************************************************************************
29bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *                                  _   _ ____  _
39bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *  Project                     ___| | | |  _ \| |
49bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *                             / __| | | | |_) | |
59bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *                            | (__| |_| |  _ <| |___
69bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *                             \___|\___/|_| \_\_____|
79bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *
8e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
9e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
10e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is licensed as described in the file COPYING, which
11e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * you should have received as part of this distribution. The terms
12e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * are also available at http://curl.haxx.se/docs/copyright.html.
13e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
14e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * copies of the Software, and permit persons to whom the Software is
16e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * furnished to do so, under the terms of the COPYING file.
17e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
18e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * KIND, either express or implied.
20e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
21e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ***************************************************************************/
229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <curl/curl.h>
239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <stdio.h>
249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstruct callback_data {
269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  FILE *output;
279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels};
289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
29e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic long file_is_coming(struct curl_fileinfo *finfo,
30e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                           struct callback_data *data,
31e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                           int remains);
329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic long file_is_downloaded(struct callback_data *data);
349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic size_t write_it(char *buff, size_t size, size_t nmemb,
36e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                       void *cb_data);
379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsint main(int argc, char **argv)
399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{
409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  int rc = CURLE_OK;
419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* curl easy handle */
439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  CURL *handle;
449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* help data */
469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  struct callback_data data = { 0 };
479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* global initialization */
499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  rc = curl_global_init(CURL_GLOBAL_ALL);
509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  if(rc)
519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    return rc;
529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* initialization of easy handle */
549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  handle = curl_easy_init();
559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  if(!handle) {
569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    curl_global_cleanup();
579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    return CURLE_OUT_OF_MEMORY;
589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  }
599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* turn on wildcard matching */
619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* callback is called before download of concrete file started */
64e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  curl_easy_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, file_is_coming);
659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* callback is called after data from the file have been transferred */
679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded);
689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* this callback will write contents into files */
709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_it);
719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* put transfer data into callbacks */
739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(handle, CURLOPT_CHUNK_DATA, &data);
749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);
759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L); */
779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* set an URL containing wildcard pattern (only in the last part) */
799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  if(argc == 2)
809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    curl_easy_setopt(handle, CURLOPT_URL, argv[1]);
819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  else
829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    curl_easy_setopt(handle, CURLOPT_URL, "ftp://example.com/test/*");
839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* and start transfer! */
859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  rc = curl_easy_perform(handle);
869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_cleanup(handle);
889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_global_cleanup();
899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  return rc;
909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}
919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
92e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic long file_is_coming(struct curl_fileinfo *finfo,
93e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                           struct callback_data *data,
94e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                           int remains)
959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{
969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  printf("%3d %40s %10luB ", remains, finfo->filename,
979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels         (unsigned long)finfo->size);
989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  switch(finfo->filetype) {
1009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  case CURLFILETYPE_DIRECTORY:
1019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    printf(" DIR\n");
1029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    break;
1039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  case CURLFILETYPE_FILE:
1049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    printf("FILE ");
1059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    break;
1069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  default:
1079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    printf("OTHER\n");
1089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    break;
1099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  }
1109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  if(finfo->filetype == CURLFILETYPE_FILE) {
1129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    /* do not transfer files >= 50B */
1139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    if(finfo->size > 50) {
1149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      printf("SKIPPED\n");
1159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      return CURL_CHUNK_BGN_FUNC_SKIP;
1169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    }
1179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    data->output = fopen(finfo->filename, "w");
1199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    if(!data->output) {
1209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      return CURL_CHUNK_BGN_FUNC_FAIL;
1219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    }
1229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  }
1239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  return CURL_CHUNK_BGN_FUNC_OK;
1259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}
1269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic long file_is_downloaded(struct callback_data *data)
1289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{
1299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  if(data->output) {
1309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    printf("DOWNLOADED\n");
1319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    fclose(data->output);
1329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    data->output = 0x0;
1339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  }
1349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  return CURL_CHUNK_END_FUNC_OK;
1359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}
1369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic size_t write_it(char *buff, size_t size, size_t nmemb,
138e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                       void *cb_data)
1399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{
140e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  struct callback_data *data = cb_data;
1419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  size_t written = 0;
1429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  if(data->output)
1439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    written = fwrite(buff, size, nmemb, data->output);
1449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  else
1459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    /* listing output */
1469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    written = fwrite(buff, size, nmemb, stdout);
1479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  return written;
1489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}
149