1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _
3*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| |
4*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___
6*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker *
8*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker *
10*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker *
14*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker *
18*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker *
21*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker *
23*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker /* <DESC>
25*6236dae4SAndroid Build Coastguard Worker * FTP wildcard pattern matching
26*6236dae4SAndroid Build Coastguard Worker * </DESC>
27*6236dae4SAndroid Build Coastguard Worker */
28*6236dae4SAndroid Build Coastguard Worker #include <curl/curl.h>
29*6236dae4SAndroid Build Coastguard Worker #include <stdio.h>
30*6236dae4SAndroid Build Coastguard Worker
31*6236dae4SAndroid Build Coastguard Worker struct callback_data {
32*6236dae4SAndroid Build Coastguard Worker FILE *output;
33*6236dae4SAndroid Build Coastguard Worker };
34*6236dae4SAndroid Build Coastguard Worker
35*6236dae4SAndroid Build Coastguard Worker static long file_is_coming(struct curl_fileinfo *finfo,
36*6236dae4SAndroid Build Coastguard Worker struct callback_data *data,
37*6236dae4SAndroid Build Coastguard Worker int remains);
38*6236dae4SAndroid Build Coastguard Worker
39*6236dae4SAndroid Build Coastguard Worker static long file_is_downloaded(struct callback_data *data);
40*6236dae4SAndroid Build Coastguard Worker
41*6236dae4SAndroid Build Coastguard Worker static size_t write_it(char *buff, size_t size, size_t nmemb,
42*6236dae4SAndroid Build Coastguard Worker void *cb_data);
43*6236dae4SAndroid Build Coastguard Worker
main(int argc,char ** argv)44*6236dae4SAndroid Build Coastguard Worker int main(int argc, char **argv)
45*6236dae4SAndroid Build Coastguard Worker {
46*6236dae4SAndroid Build Coastguard Worker /* curl easy handle */
47*6236dae4SAndroid Build Coastguard Worker CURL *handle;
48*6236dae4SAndroid Build Coastguard Worker
49*6236dae4SAndroid Build Coastguard Worker /* help data */
50*6236dae4SAndroid Build Coastguard Worker struct callback_data data = { 0 };
51*6236dae4SAndroid Build Coastguard Worker
52*6236dae4SAndroid Build Coastguard Worker /* global initialization */
53*6236dae4SAndroid Build Coastguard Worker CURLcode rc = curl_global_init(CURL_GLOBAL_ALL);
54*6236dae4SAndroid Build Coastguard Worker if(rc)
55*6236dae4SAndroid Build Coastguard Worker return (int)rc;
56*6236dae4SAndroid Build Coastguard Worker
57*6236dae4SAndroid Build Coastguard Worker /* initialization of easy handle */
58*6236dae4SAndroid Build Coastguard Worker handle = curl_easy_init();
59*6236dae4SAndroid Build Coastguard Worker if(!handle) {
60*6236dae4SAndroid Build Coastguard Worker curl_global_cleanup();
61*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
62*6236dae4SAndroid Build Coastguard Worker }
63*6236dae4SAndroid Build Coastguard Worker
64*6236dae4SAndroid Build Coastguard Worker /* turn on wildcard matching */
65*6236dae4SAndroid Build Coastguard Worker curl_easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
66*6236dae4SAndroid Build Coastguard Worker
67*6236dae4SAndroid Build Coastguard Worker /* callback is called before download of concrete file started */
68*6236dae4SAndroid Build Coastguard Worker curl_easy_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, file_is_coming);
69*6236dae4SAndroid Build Coastguard Worker
70*6236dae4SAndroid Build Coastguard Worker /* callback is called after data from the file have been transferred */
71*6236dae4SAndroid Build Coastguard Worker curl_easy_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded);
72*6236dae4SAndroid Build Coastguard Worker
73*6236dae4SAndroid Build Coastguard Worker /* this callback writes contents into files */
74*6236dae4SAndroid Build Coastguard Worker curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_it);
75*6236dae4SAndroid Build Coastguard Worker
76*6236dae4SAndroid Build Coastguard Worker /* put transfer data into callbacks */
77*6236dae4SAndroid Build Coastguard Worker curl_easy_setopt(handle, CURLOPT_CHUNK_DATA, &data);
78*6236dae4SAndroid Build Coastguard Worker curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);
79*6236dae4SAndroid Build Coastguard Worker
80*6236dae4SAndroid Build Coastguard Worker /* curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L); */
81*6236dae4SAndroid Build Coastguard Worker
82*6236dae4SAndroid Build Coastguard Worker /* set a URL containing wildcard pattern (only in the last part) */
83*6236dae4SAndroid Build Coastguard Worker if(argc == 2)
84*6236dae4SAndroid Build Coastguard Worker curl_easy_setopt(handle, CURLOPT_URL, argv[1]);
85*6236dae4SAndroid Build Coastguard Worker else
86*6236dae4SAndroid Build Coastguard Worker curl_easy_setopt(handle, CURLOPT_URL, "ftp://example.com/test/*");
87*6236dae4SAndroid Build Coastguard Worker
88*6236dae4SAndroid Build Coastguard Worker /* and start transfer! */
89*6236dae4SAndroid Build Coastguard Worker rc = curl_easy_perform(handle);
90*6236dae4SAndroid Build Coastguard Worker
91*6236dae4SAndroid Build Coastguard Worker curl_easy_cleanup(handle);
92*6236dae4SAndroid Build Coastguard Worker curl_global_cleanup();
93*6236dae4SAndroid Build Coastguard Worker return (int)rc;
94*6236dae4SAndroid Build Coastguard Worker }
95*6236dae4SAndroid Build Coastguard Worker
file_is_coming(struct curl_fileinfo * finfo,struct callback_data * data,int remains)96*6236dae4SAndroid Build Coastguard Worker static long file_is_coming(struct curl_fileinfo *finfo,
97*6236dae4SAndroid Build Coastguard Worker struct callback_data *data,
98*6236dae4SAndroid Build Coastguard Worker int remains)
99*6236dae4SAndroid Build Coastguard Worker {
100*6236dae4SAndroid Build Coastguard Worker printf("%3d %40s %10luB ", remains, finfo->filename,
101*6236dae4SAndroid Build Coastguard Worker (unsigned long)finfo->size);
102*6236dae4SAndroid Build Coastguard Worker
103*6236dae4SAndroid Build Coastguard Worker switch(finfo->filetype) {
104*6236dae4SAndroid Build Coastguard Worker case CURLFILETYPE_DIRECTORY:
105*6236dae4SAndroid Build Coastguard Worker printf(" DIR\n");
106*6236dae4SAndroid Build Coastguard Worker break;
107*6236dae4SAndroid Build Coastguard Worker case CURLFILETYPE_FILE:
108*6236dae4SAndroid Build Coastguard Worker printf("FILE ");
109*6236dae4SAndroid Build Coastguard Worker break;
110*6236dae4SAndroid Build Coastguard Worker default:
111*6236dae4SAndroid Build Coastguard Worker printf("OTHER\n");
112*6236dae4SAndroid Build Coastguard Worker break;
113*6236dae4SAndroid Build Coastguard Worker }
114*6236dae4SAndroid Build Coastguard Worker
115*6236dae4SAndroid Build Coastguard Worker if(finfo->filetype == CURLFILETYPE_FILE) {
116*6236dae4SAndroid Build Coastguard Worker /* do not transfer files >= 50B */
117*6236dae4SAndroid Build Coastguard Worker if(finfo->size > 50) {
118*6236dae4SAndroid Build Coastguard Worker printf("SKIPPED\n");
119*6236dae4SAndroid Build Coastguard Worker return CURL_CHUNK_BGN_FUNC_SKIP;
120*6236dae4SAndroid Build Coastguard Worker }
121*6236dae4SAndroid Build Coastguard Worker
122*6236dae4SAndroid Build Coastguard Worker data->output = fopen(finfo->filename, "wb");
123*6236dae4SAndroid Build Coastguard Worker if(!data->output) {
124*6236dae4SAndroid Build Coastguard Worker return CURL_CHUNK_BGN_FUNC_FAIL;
125*6236dae4SAndroid Build Coastguard Worker }
126*6236dae4SAndroid Build Coastguard Worker }
127*6236dae4SAndroid Build Coastguard Worker
128*6236dae4SAndroid Build Coastguard Worker return CURL_CHUNK_BGN_FUNC_OK;
129*6236dae4SAndroid Build Coastguard Worker }
130*6236dae4SAndroid Build Coastguard Worker
file_is_downloaded(struct callback_data * data)131*6236dae4SAndroid Build Coastguard Worker static long file_is_downloaded(struct callback_data *data)
132*6236dae4SAndroid Build Coastguard Worker {
133*6236dae4SAndroid Build Coastguard Worker if(data->output) {
134*6236dae4SAndroid Build Coastguard Worker printf("DOWNLOADED\n");
135*6236dae4SAndroid Build Coastguard Worker fclose(data->output);
136*6236dae4SAndroid Build Coastguard Worker data->output = 0x0;
137*6236dae4SAndroid Build Coastguard Worker }
138*6236dae4SAndroid Build Coastguard Worker return CURL_CHUNK_END_FUNC_OK;
139*6236dae4SAndroid Build Coastguard Worker }
140*6236dae4SAndroid Build Coastguard Worker
write_it(char * buff,size_t size,size_t nmemb,void * cb_data)141*6236dae4SAndroid Build Coastguard Worker static size_t write_it(char *buff, size_t size, size_t nmemb,
142*6236dae4SAndroid Build Coastguard Worker void *cb_data)
143*6236dae4SAndroid Build Coastguard Worker {
144*6236dae4SAndroid Build Coastguard Worker struct callback_data *data = cb_data;
145*6236dae4SAndroid Build Coastguard Worker size_t written = 0;
146*6236dae4SAndroid Build Coastguard Worker if(data->output)
147*6236dae4SAndroid Build Coastguard Worker written = fwrite(buff, size, nmemb, data->output);
148*6236dae4SAndroid Build Coastguard Worker else
149*6236dae4SAndroid Build Coastguard Worker /* listing output */
150*6236dae4SAndroid Build Coastguard Worker written = fwrite(buff, size, nmemb, stdout);
151*6236dae4SAndroid Build Coastguard Worker return written;
152*6236dae4SAndroid Build Coastguard Worker }
153