ftp-wildcard.c revision e6cd738ed3716c02557fb3a47515244e949ade39
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