1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel (at) haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.haxx.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22 #include "tool_setup.h" 23 24 #include "slist_wc.h" 25 26 #ifndef CURL_DISABLE_LIBCURL_OPTION 27 28 #define ENABLE_CURLX_PRINTF 29 /* use our own printf() functions */ 30 #include "curlx.h" 31 32 #include "tool_cfgable.h" 33 #include "tool_easysrc.h" 34 #include "tool_msgs.h" 35 36 #include "memdebug.h" /* keep this as LAST include */ 37 38 /* global variable definitions, for easy-interface source code generation */ 39 40 struct slist_wc *easysrc_decl = NULL; /* Variable declarations */ 41 struct slist_wc *easysrc_data = NULL; /* Build slists, forms etc. */ 42 struct slist_wc *easysrc_code = NULL; /* Setopt calls */ 43 struct slist_wc *easysrc_toohard = NULL; /* Unconvertible setopt */ 44 struct slist_wc *easysrc_clean = NULL; /* Clean up allocated data */ 45 int easysrc_mime_count = 0; 46 int easysrc_slist_count = 0; 47 48 static const char *const srchead[]={ 49 "/********* Sample code generated by the curl command line tool **********", 50 " * All curl_easy_setopt() options are documented at:", 51 " * https://curl.haxx.se/libcurl/c/curl_easy_setopt.html", 52 " ************************************************************************/", 53 "#include <curl/curl.h>", 54 "", 55 "int main(int argc, char *argv[])", 56 "{", 57 " CURLcode ret;", 58 " CURL *hnd;", 59 NULL 60 }; 61 /* easysrc_decl declarations come here */ 62 /* easysrc_data initialisations come here */ 63 /* easysrc_code statements come here */ 64 static const char *const srchard[]={ 65 "/* Here is a list of options the curl code used that cannot get generated", 66 " as source easily. You may select to either not use them or implement", 67 " them yourself.", 68 "", 69 NULL 70 }; 71 static const char *const srcend[]={ 72 "", 73 " return (int)ret;", 74 "}", 75 "/**** End of sample code ****/", 76 NULL 77 }; 78 79 /* Clean up all source code if we run out of memory */ 80 static void easysrc_free(void) 81 { 82 slist_wc_free_all(easysrc_decl); 83 easysrc_decl = NULL; 84 slist_wc_free_all(easysrc_data); 85 easysrc_data = NULL; 86 slist_wc_free_all(easysrc_code); 87 easysrc_code = NULL; 88 slist_wc_free_all(easysrc_toohard); 89 easysrc_toohard = NULL; 90 slist_wc_free_all(easysrc_clean); 91 easysrc_clean = NULL; 92 } 93 94 /* Add a source line to the main code or remarks */ 95 CURLcode easysrc_add(struct slist_wc **plist, const char *line) 96 { 97 CURLcode ret = CURLE_OK; 98 struct slist_wc *list = slist_wc_append(*plist, line); 99 if(!list) { 100 easysrc_free(); 101 ret = CURLE_OUT_OF_MEMORY; 102 } 103 else 104 *plist = list; 105 return ret; 106 } 107 108 CURLcode easysrc_addf(struct slist_wc **plist, const char *fmt, ...) 109 { 110 CURLcode ret; 111 char *bufp; 112 va_list ap; 113 va_start(ap, fmt); 114 bufp = curlx_mvaprintf(fmt, ap); 115 va_end(ap); 116 if(! bufp) { 117 ret = CURLE_OUT_OF_MEMORY; 118 } 119 else { 120 ret = easysrc_add(plist, bufp); 121 curl_free(bufp); 122 } 123 return ret; 124 } 125 126 #define CHKRET(v) do {CURLcode ret = (v); if(ret) return ret;} WHILE_FALSE 127 128 CURLcode easysrc_init(void) 129 { 130 CHKRET(easysrc_add(&easysrc_code, 131 "hnd = curl_easy_init();")); 132 return CURLE_OK; 133 } 134 135 CURLcode easysrc_perform(void) 136 { 137 /* Note any setopt calls which we could not convert */ 138 if(easysrc_toohard) { 139 int i; 140 struct curl_slist *ptr; 141 const char *c; 142 CHKRET(easysrc_add(&easysrc_code, "")); 143 /* Preamble comment */ 144 for(i = 0; ((c = srchard[i]) != NULL); i++) 145 CHKRET(easysrc_add(&easysrc_code, c)); 146 /* Each unconverted option */ 147 if(easysrc_toohard) { 148 for(ptr = easysrc_toohard->first; ptr; ptr = ptr->next) 149 CHKRET(easysrc_add(&easysrc_code, ptr->data)); 150 } 151 CHKRET(easysrc_add(&easysrc_code, "")); 152 CHKRET(easysrc_add(&easysrc_code, "*/")); 153 154 slist_wc_free_all(easysrc_toohard); 155 easysrc_toohard = NULL; 156 } 157 158 CHKRET(easysrc_add(&easysrc_code, "")); 159 CHKRET(easysrc_add(&easysrc_code, "ret = curl_easy_perform(hnd);")); 160 CHKRET(easysrc_add(&easysrc_code, "")); 161 162 return CURLE_OK; 163 } 164 165 CURLcode easysrc_cleanup(void) 166 { 167 CHKRET(easysrc_add(&easysrc_code, "curl_easy_cleanup(hnd);")); 168 CHKRET(easysrc_add(&easysrc_code, "hnd = NULL;")); 169 170 return CURLE_OK; 171 } 172 173 void dumpeasysrc(struct GlobalConfig *config) 174 { 175 struct curl_slist *ptr; 176 char *o = config->libcurl; 177 178 FILE *out; 179 bool fopened = FALSE; 180 if(strcmp(o, "-")) { 181 out = fopen(o, FOPEN_WRITETEXT); 182 fopened = TRUE; 183 } 184 else 185 out = stdout; 186 if(!out) 187 warnf(config, "Failed to open %s to write libcurl code!\n", o); 188 else { 189 int i; 190 const char *c; 191 192 for(i = 0; ((c = srchead[i]) != NULL); i++) 193 fprintf(out, "%s\n", c); 194 195 /* Declare variables used for complex setopt values */ 196 if(easysrc_decl) { 197 for(ptr = easysrc_decl->first; ptr; ptr = ptr->next) 198 fprintf(out, " %s\n", ptr->data); 199 } 200 201 /* Set up complex values for setopt calls */ 202 if(easysrc_data) { 203 fprintf(out, "\n"); 204 205 for(ptr = easysrc_data->first; ptr; ptr = ptr->next) 206 fprintf(out, " %s\n", ptr->data); 207 } 208 209 fprintf(out, "\n"); 210 if(easysrc_code) { 211 for(ptr = easysrc_code->first; ptr; ptr = ptr->next) { 212 if(ptr->data[0]) { 213 fprintf(out, " %s\n", ptr->data); 214 } 215 else { 216 fprintf(out, "\n"); 217 } 218 } 219 } 220 221 if(easysrc_clean) { 222 for(ptr = easysrc_clean->first; ptr; ptr = ptr->next) 223 fprintf(out, " %s\n", ptr->data); 224 } 225 226 for(i = 0; ((c = srcend[i]) != NULL); i++) 227 fprintf(out, "%s\n", c); 228 229 if(fopened) 230 fclose(out); 231 } 232 233 easysrc_free(); 234 } 235 236 #endif /* CURL_DISABLE_LIBCURL_OPTION */ 237