Annotation of embedaddon/curl/src/tool_writeout.c, revision 1.1.1.1
1.1 misho 1: /***************************************************************************
2: * _ _ ____ _
3: * Project ___| | | | _ \| |
4: * / __| | | | |_) | |
5: * | (__| |_| | _ <| |___
6: * \___|\___/|_| \_\_____|
7: *
8: * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@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: #define ENABLE_CURLX_PRINTF
24: /* use our own printf() functions */
25: #include "curlx.h"
26: #include "tool_cfgable.h"
27: #include "tool_writeout.h"
28: #include "tool_writeout_json.h"
29:
30: #include "memdebug.h" /* keep this as LAST include */
31:
32: static const struct writeoutvar variables[] = {
33: {"url_effective", VAR_EFFECTIVE_URL, 0,
34: CURLINFO_EFFECTIVE_URL, JSON_STRING},
35: {"http_code", VAR_HTTP_CODE, 0,
36: CURLINFO_RESPONSE_CODE, JSON_LONG},
37: {"response_code", VAR_HTTP_CODE, 0,
38: CURLINFO_RESPONSE_CODE, JSON_LONG},
39: {"http_connect", VAR_HTTP_CODE_PROXY, 0,
40: CURLINFO_HTTP_CONNECTCODE, JSON_LONG},
41: {"time_total", VAR_TOTAL_TIME, 0,
42: CURLINFO_TOTAL_TIME_T, JSON_TIME},
43: {"time_namelookup", VAR_NAMELOOKUP_TIME, 0,
44: CURLINFO_NAMELOOKUP_TIME_T, JSON_TIME},
45: {"time_connect", VAR_CONNECT_TIME, 0,
46: CURLINFO_CONNECT_TIME_T, JSON_TIME},
47: {"time_appconnect", VAR_APPCONNECT_TIME, 0,
48: CURLINFO_APPCONNECT_TIME_T, JSON_TIME},
49: {"time_pretransfer", VAR_PRETRANSFER_TIME, 0,
50: CURLINFO_PRETRANSFER_TIME_T, JSON_TIME},
51: {"time_starttransfer", VAR_STARTTRANSFER_TIME, 0,
52: CURLINFO_STARTTRANSFER_TIME_T, JSON_TIME},
53: {"size_header", VAR_HEADER_SIZE, 0,
54: CURLINFO_HEADER_SIZE, JSON_LONG},
55: {"size_request", VAR_REQUEST_SIZE, 0,
56: CURLINFO_REQUEST_SIZE, JSON_LONG},
57: {"size_download", VAR_SIZE_DOWNLOAD, 0,
58: CURLINFO_SIZE_DOWNLOAD_T, JSON_OFFSET},
59: {"size_upload", VAR_SIZE_UPLOAD, 0,
60: CURLINFO_SIZE_UPLOAD_T, JSON_OFFSET},
61: {"speed_download", VAR_SPEED_DOWNLOAD, 0,
62: CURLINFO_SPEED_DOWNLOAD_T, JSON_OFFSET},
63: {"speed_upload", VAR_SPEED_UPLOAD, 0,
64: CURLINFO_SPEED_UPLOAD_T, JSON_OFFSET},
65: {"content_type", VAR_CONTENT_TYPE, 0,
66: CURLINFO_CONTENT_TYPE, JSON_STRING},
67: {"num_connects", VAR_NUM_CONNECTS, 0,
68: CURLINFO_NUM_CONNECTS, JSON_LONG},
69: {"time_redirect", VAR_REDIRECT_TIME, 0,
70: CURLINFO_REDIRECT_TIME_T, JSON_TIME},
71: {"num_redirects", VAR_REDIRECT_COUNT, 0,
72: CURLINFO_REDIRECT_COUNT, JSON_LONG},
73: {"ftp_entry_path", VAR_FTP_ENTRY_PATH, 0,
74: CURLINFO_FTP_ENTRY_PATH, JSON_STRING},
75: {"redirect_url", VAR_REDIRECT_URL, 0,
76: CURLINFO_REDIRECT_URL, JSON_STRING},
77: {"ssl_verify_result", VAR_SSL_VERIFY_RESULT, 0,
78: CURLINFO_SSL_VERIFYRESULT, JSON_LONG},
79: {"proxy_ssl_verify_result", VAR_PROXY_SSL_VERIFY_RESULT, 0,
80: CURLINFO_PROXY_SSL_VERIFYRESULT, JSON_LONG},
81: {"filename_effective", VAR_EFFECTIVE_FILENAME, 0,
82: 0, JSON_FILENAME},
83: {"remote_ip", VAR_PRIMARY_IP, 0,
84: CURLINFO_PRIMARY_IP, JSON_STRING},
85: {"remote_port", VAR_PRIMARY_PORT, 0,
86: CURLINFO_PRIMARY_PORT, JSON_LONG},
87: {"local_ip", VAR_LOCAL_IP, 0,
88: CURLINFO_LOCAL_IP, JSON_STRING},
89: {"local_port", VAR_LOCAL_PORT, 0,
90: CURLINFO_LOCAL_PORT, JSON_LONG},
91: {"http_version", VAR_HTTP_VERSION, 0,
92: CURLINFO_HTTP_VERSION, JSON_VERSION},
93: {"scheme", VAR_SCHEME, 0,
94: CURLINFO_SCHEME, JSON_STRING},
95: {"stdout", VAR_STDOUT, 1,
96: 0, JSON_NONE},
97: {"stderr", VAR_STDERR, 1,
98: 0, JSON_NONE},
99: {"json", VAR_JSON, 1,
100: 0, JSON_NONE},
101: {NULL, VAR_NONE, 1,
102: 0, JSON_NONE}
103: };
104:
105: void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
106: {
107: FILE *stream = stdout;
108: const char *ptr = writeinfo;
109: char *stringp = NULL;
110: long longinfo;
111: double doubleinfo;
112:
113: while(ptr && *ptr) {
114: if('%' == *ptr && ptr[1]) {
115: if('%' == ptr[1]) {
116: /* an escaped %-letter */
117: fputc('%', stream);
118: ptr += 2;
119: }
120: else {
121: /* this is meant as a variable to output */
122: char *end;
123: if('{' == ptr[1]) {
124: char keepit;
125: int i;
126: bool match = FALSE;
127: end = strchr(ptr, '}');
128: ptr += 2; /* pass the % and the { */
129: if(!end) {
130: fputs("%{", stream);
131: continue;
132: }
133: keepit = *end;
134: *end = 0; /* zero terminate */
135: for(i = 0; variables[i].name; i++) {
136: if(curl_strequal(ptr, variables[i].name)) {
137: match = TRUE;
138: switch(variables[i].id) {
139: case VAR_EFFECTIVE_URL:
140: if((CURLE_OK ==
141: curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &stringp))
142: && stringp)
143: fputs(stringp, stream);
144: break;
145: case VAR_HTTP_CODE:
146: if(CURLE_OK ==
147: curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &longinfo))
148: fprintf(stream, "%03ld", longinfo);
149: break;
150: case VAR_HTTP_CODE_PROXY:
151: if(CURLE_OK ==
152: curl_easy_getinfo(curl, CURLINFO_HTTP_CONNECTCODE,
153: &longinfo))
154: fprintf(stream, "%03ld", longinfo);
155: break;
156: case VAR_HEADER_SIZE:
157: if(CURLE_OK ==
158: curl_easy_getinfo(curl, CURLINFO_HEADER_SIZE, &longinfo))
159: fprintf(stream, "%ld", longinfo);
160: break;
161: case VAR_REQUEST_SIZE:
162: if(CURLE_OK ==
163: curl_easy_getinfo(curl, CURLINFO_REQUEST_SIZE, &longinfo))
164: fprintf(stream, "%ld", longinfo);
165: break;
166: case VAR_NUM_CONNECTS:
167: if(CURLE_OK ==
168: curl_easy_getinfo(curl, CURLINFO_NUM_CONNECTS, &longinfo))
169: fprintf(stream, "%ld", longinfo);
170: break;
171: case VAR_REDIRECT_COUNT:
172: if(CURLE_OK ==
173: curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &longinfo))
174: fprintf(stream, "%ld", longinfo);
175: break;
176: case VAR_REDIRECT_TIME:
177: if(CURLE_OK ==
178: curl_easy_getinfo(curl, CURLINFO_REDIRECT_TIME,
179: &doubleinfo))
180: fprintf(stream, "%.6f", doubleinfo);
181: break;
182: case VAR_TOTAL_TIME:
183: if(CURLE_OK ==
184: curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &doubleinfo))
185: fprintf(stream, "%.6f", doubleinfo);
186: break;
187: case VAR_NAMELOOKUP_TIME:
188: if(CURLE_OK ==
189: curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME,
190: &doubleinfo))
191: fprintf(stream, "%.6f", doubleinfo);
192: break;
193: case VAR_CONNECT_TIME:
194: if(CURLE_OK ==
195: curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &doubleinfo))
196: fprintf(stream, "%.6f", doubleinfo);
197: break;
198: case VAR_APPCONNECT_TIME:
199: if(CURLE_OK ==
200: curl_easy_getinfo(curl, CURLINFO_APPCONNECT_TIME,
201: &doubleinfo))
202: fprintf(stream, "%.6f", doubleinfo);
203: break;
204: case VAR_PRETRANSFER_TIME:
205: if(CURLE_OK ==
206: curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME,
207: &doubleinfo))
208: fprintf(stream, "%.6f", doubleinfo);
209: break;
210: case VAR_STARTTRANSFER_TIME:
211: if(CURLE_OK ==
212: curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME,
213: &doubleinfo))
214: fprintf(stream, "%.6f", doubleinfo);
215: break;
216: case VAR_SIZE_UPLOAD:
217: if(CURLE_OK ==
218: curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD, &doubleinfo))
219: fprintf(stream, "%.0f", doubleinfo);
220: break;
221: case VAR_SIZE_DOWNLOAD:
222: if(CURLE_OK ==
223: curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD,
224: &doubleinfo))
225: fprintf(stream, "%.0f", doubleinfo);
226: break;
227: case VAR_SPEED_DOWNLOAD:
228: if(CURLE_OK ==
229: curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD,
230: &doubleinfo))
231: fprintf(stream, "%.3f", doubleinfo);
232: break;
233: case VAR_SPEED_UPLOAD:
234: if(CURLE_OK ==
235: curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &doubleinfo))
236: fprintf(stream, "%.3f", doubleinfo);
237: break;
238: case VAR_CONTENT_TYPE:
239: if((CURLE_OK ==
240: curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &stringp))
241: && stringp)
242: fputs(stringp, stream);
243: break;
244: case VAR_FTP_ENTRY_PATH:
245: if((CURLE_OK ==
246: curl_easy_getinfo(curl, CURLINFO_FTP_ENTRY_PATH, &stringp))
247: && stringp)
248: fputs(stringp, stream);
249: break;
250: case VAR_REDIRECT_URL:
251: if((CURLE_OK ==
252: curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &stringp))
253: && stringp)
254: fputs(stringp, stream);
255: break;
256: case VAR_SSL_VERIFY_RESULT:
257: if(CURLE_OK ==
258: curl_easy_getinfo(curl, CURLINFO_SSL_VERIFYRESULT,
259: &longinfo))
260: fprintf(stream, "%ld", longinfo);
261: break;
262: case VAR_PROXY_SSL_VERIFY_RESULT:
263: if(CURLE_OK ==
264: curl_easy_getinfo(curl, CURLINFO_PROXY_SSL_VERIFYRESULT,
265: &longinfo))
266: fprintf(stream, "%ld", longinfo);
267: break;
268: case VAR_EFFECTIVE_FILENAME:
269: if(outs->filename)
270: fprintf(stream, "%s", outs->filename);
271: break;
272: case VAR_PRIMARY_IP:
273: if(CURLE_OK ==
274: curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP,
275: &stringp))
276: fprintf(stream, "%s", stringp);
277: break;
278: case VAR_PRIMARY_PORT:
279: if(CURLE_OK ==
280: curl_easy_getinfo(curl, CURLINFO_PRIMARY_PORT,
281: &longinfo))
282: fprintf(stream, "%ld", longinfo);
283: break;
284: case VAR_LOCAL_IP:
285: if(CURLE_OK ==
286: curl_easy_getinfo(curl, CURLINFO_LOCAL_IP,
287: &stringp))
288: fprintf(stream, "%s", stringp);
289: break;
290: case VAR_LOCAL_PORT:
291: if(CURLE_OK ==
292: curl_easy_getinfo(curl, CURLINFO_LOCAL_PORT,
293: &longinfo))
294: fprintf(stream, "%ld", longinfo);
295: break;
296: case VAR_HTTP_VERSION:
297: if(CURLE_OK ==
298: curl_easy_getinfo(curl, CURLINFO_HTTP_VERSION,
299: &longinfo)) {
300: const char *version = "0";
301: switch(longinfo) {
302: case CURL_HTTP_VERSION_1_0:
303: version = "1.0";
304: break;
305: case CURL_HTTP_VERSION_1_1:
306: version = "1.1";
307: break;
308: case CURL_HTTP_VERSION_2_0:
309: version = "2";
310: break;
311: case CURL_HTTP_VERSION_3:
312: version = "3";
313: break;
314: }
315:
316: fprintf(stream, version);
317: }
318: break;
319: case VAR_SCHEME:
320: if(CURLE_OK ==
321: curl_easy_getinfo(curl, CURLINFO_SCHEME,
322: &stringp))
323: fprintf(stream, "%s", stringp);
324: break;
325: case VAR_STDOUT:
326: stream = stdout;
327: break;
328: case VAR_STDERR:
329: stream = stderr;
330: break;
331: case VAR_JSON:
332: ourWriteOutJSON(variables, curl, outs, stream);
333: default:
334: break;
335: }
336: break;
337: }
338: }
339: if(!match) {
340: fprintf(stderr, "curl: unknown --write-out variable: '%s'\n", ptr);
341: }
342: ptr = end + 1; /* pass the end */
343: *end = keepit;
344: }
345: else {
346: /* illegal syntax, then just output the characters that are used */
347: fputc('%', stream);
348: fputc(ptr[1], stream);
349: ptr += 2;
350: }
351: }
352: }
353: else if('\\' == *ptr && ptr[1]) {
354: switch(ptr[1]) {
355: case 'r':
356: fputc('\r', stream);
357: break;
358: case 'n':
359: fputc('\n', stream);
360: break;
361: case 't':
362: fputc('\t', stream);
363: break;
364: default:
365: /* unknown, just output this */
366: fputc(*ptr, stream);
367: fputc(ptr[1], stream);
368: break;
369: }
370: ptr += 2;
371: }
372: else {
373: fputc(*ptr, stream);
374: ptr++;
375: }
376: }
377:
378: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>