xref: /aosp_15_r20/external/curl/docs/examples/ftp-wildcard.c (revision 6236dae45794135f37c4eb022389c904c8b0090d)
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