ftp-wildcard.c revision 9bd90e6e25f1e55f50201c87a1b5837de7e5b64a
19bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/*****************************************************************************
29bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *                                  _   _ ____  _
39bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *  Project                     ___| | | |  _ \| |
49bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *                             / __| | | | |_) | |
59bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *                            | (__| |_| |  _ <| |___
69bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *                             \___|\___/|_| \_\_____|
79bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *
89bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */
99bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <curl/curl.h>
119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <stdio.h>
129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstruct callback_data {
149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  FILE *output;
159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels};
169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic long file_is_comming(struct curl_fileinfo *finfo,
189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels                            struct callback_data *data,
199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels                            int remains);
209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic long file_is_downloaded(struct callback_data *data);
229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic size_t write_it(char *buff, size_t size, size_t nmemb,
249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels                       struct callback_data *data);
259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsint main(int argc, char **argv)
279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{
289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  int rc = CURLE_OK;
299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* curl easy handle */
319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  CURL *handle;
329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* help data */
349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  struct callback_data data = { 0 };
359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* global initialization */
379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  rc = curl_global_init(CURL_GLOBAL_ALL);
389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  if(rc)
399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    return rc;
409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* initialization of easy handle */
429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  handle = curl_easy_init();
439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  if(!handle) {
449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    curl_global_cleanup();
459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    return CURLE_OUT_OF_MEMORY;
469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  }
479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* turn on wildcard matching */
499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* callback is called before download of concrete file started */
529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, file_is_comming);
539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* callback is called after data from the file have been transferred */
559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded);
569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* this callback will write contents into files */
589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_it);
599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* put transfer data into callbacks */
619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(handle, CURLOPT_CHUNK_DATA, &data);
629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);
639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L); */
659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* set an URL containing wildcard pattern (only in the last part) */
679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  if(argc == 2)
689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    curl_easy_setopt(handle, CURLOPT_URL, argv[1]);
699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  else
709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    curl_easy_setopt(handle, CURLOPT_URL, "ftp://example.com/test/*");
719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  /* and start transfer! */
739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  rc = curl_easy_perform(handle);
749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_easy_cleanup(handle);
769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  curl_global_cleanup();
779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  return rc;
789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}
799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic long file_is_comming(struct curl_fileinfo *finfo,
819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels                            struct callback_data *data,
829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels                            int remains)
839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{
849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  printf("%3d %40s %10luB ", remains, finfo->filename,
859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels         (unsigned long)finfo->size);
869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  switch(finfo->filetype) {
889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  case CURLFILETYPE_DIRECTORY:
899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    printf(" DIR\n");
909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    break;
919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  case CURLFILETYPE_FILE:
929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    printf("FILE ");
939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    break;
949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  default:
959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    printf("OTHER\n");
969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    break;
979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  }
989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  if(finfo->filetype == CURLFILETYPE_FILE) {
1009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    /* do not transfer files >= 50B */
1019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    if(finfo->size > 50) {
1029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      printf("SKIPPED\n");
1039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      return CURL_CHUNK_BGN_FUNC_SKIP;
1049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    }
1059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    data->output = fopen(finfo->filename, "w");
1079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    if(!data->output) {
1089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      return CURL_CHUNK_BGN_FUNC_FAIL;
1099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    }
1109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  }
1119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  return CURL_CHUNK_BGN_FUNC_OK;
1139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}
1149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic long file_is_downloaded(struct callback_data *data)
1169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{
1179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  if(data->output) {
1189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    printf("DOWNLOADED\n");
1199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    fclose(data->output);
1209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    data->output = 0x0;
1219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  }
1229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  return CURL_CHUNK_END_FUNC_OK;
1239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}
1249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic size_t write_it(char *buff, size_t size, size_t nmemb,
1269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels                       struct callback_data *data)
1279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{
1289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  size_t written = 0;
1299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  if(data->output)
1309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    written = fwrite(buff, size, nmemb, data->output);
1319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  else
1329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    /* listing output */
1339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels    written = fwrite(buff, size, nmemb, stdout);
1349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels  return written;
1359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}
136