tizen 2.3.1 release
[external/curl.git] / src / tool_writeout.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2012, 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 http://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 #define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */
25 #include <curl/mprintf.h>
26
27 #include "tool_cfgable.h"
28 #include "tool_writeout.h"
29
30 #include "memdebug.h" /* keep this as LAST include */
31
32 typedef enum {
33   VAR_NONE,       /* must be the first */
34   VAR_TOTAL_TIME,
35   VAR_NAMELOOKUP_TIME,
36   VAR_CONNECT_TIME,
37   VAR_APPCONNECT_TIME,
38   VAR_PRETRANSFER_TIME,
39   VAR_STARTTRANSFER_TIME,
40   VAR_SIZE_DOWNLOAD,
41   VAR_SIZE_UPLOAD,
42   VAR_SPEED_DOWNLOAD,
43   VAR_SPEED_UPLOAD,
44   VAR_HTTP_CODE,
45   VAR_HTTP_CODE_PROXY,
46   VAR_HEADER_SIZE,
47   VAR_REQUEST_SIZE,
48   VAR_EFFECTIVE_URL,
49   VAR_CONTENT_TYPE,
50   VAR_NUM_CONNECTS,
51   VAR_REDIRECT_TIME,
52   VAR_REDIRECT_COUNT,
53   VAR_FTP_ENTRY_PATH,
54   VAR_REDIRECT_URL,
55   VAR_SSL_VERIFY_RESULT,
56   VAR_EFFECTIVE_FILENAME,
57   VAR_PRIMARY_IP,
58   VAR_PRIMARY_PORT,
59   VAR_LOCAL_IP,
60   VAR_LOCAL_PORT,
61   VAR_NUM_OF_VARS /* must be the last */
62 } replaceid;
63
64 struct variable {
65   const char *name;
66   replaceid id;
67 };
68
69
70 static const struct variable replacements[]={
71   {"url_effective", VAR_EFFECTIVE_URL},
72   {"http_code", VAR_HTTP_CODE},
73   {"response_code", VAR_HTTP_CODE},
74   {"http_connect", VAR_HTTP_CODE_PROXY},
75   {"time_total", VAR_TOTAL_TIME},
76   {"time_namelookup", VAR_NAMELOOKUP_TIME},
77   {"time_connect", VAR_CONNECT_TIME},
78   {"time_appconnect", VAR_APPCONNECT_TIME},
79   {"time_pretransfer", VAR_PRETRANSFER_TIME},
80   {"time_starttransfer", VAR_STARTTRANSFER_TIME},
81   {"size_header", VAR_HEADER_SIZE},
82   {"size_request", VAR_REQUEST_SIZE},
83   {"size_download", VAR_SIZE_DOWNLOAD},
84   {"size_upload", VAR_SIZE_UPLOAD},
85   {"speed_download", VAR_SPEED_DOWNLOAD},
86   {"speed_upload", VAR_SPEED_UPLOAD},
87   {"content_type", VAR_CONTENT_TYPE},
88   {"num_connects", VAR_NUM_CONNECTS},
89   {"time_redirect", VAR_REDIRECT_TIME},
90   {"num_redirects", VAR_REDIRECT_COUNT},
91   {"ftp_entry_path", VAR_FTP_ENTRY_PATH},
92   {"redirect_url", VAR_REDIRECT_URL},
93   {"ssl_verify_result", VAR_SSL_VERIFY_RESULT},
94   {"filename_effective", VAR_EFFECTIVE_FILENAME},
95   {"remote_ip", VAR_PRIMARY_IP},
96   {"remote_port", VAR_PRIMARY_PORT},
97   {"local_ip", VAR_LOCAL_IP},
98   {"local_port", VAR_LOCAL_PORT},
99   {NULL, VAR_NONE}
100 };
101
102 void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
103 {
104   FILE *stream = stdout;
105   const char *ptr = writeinfo;
106   char *stringp = NULL;
107   long longinfo;
108   double doubleinfo;
109
110   while(ptr && *ptr) {
111     if('%' == *ptr) {
112       if('%' == ptr[1]) {
113         /* an escaped %-letter */
114         fputc('%', stream);
115         ptr += 2;
116       }
117       else {
118         /* this is meant as a variable to output */
119         char *end;
120         char keepit;
121         int i;
122         if(('{' == ptr[1]) && ((end = strchr(ptr, '}')) != NULL)) {
123           bool match = FALSE;
124           ptr += 2; /* pass the % and the { */
125           keepit = *end;
126           *end = 0; /* zero terminate */
127           for(i = 0; replacements[i].name; i++) {
128             if(curl_strequal(ptr, replacements[i].name)) {
129               match = TRUE;
130               switch(replacements[i].id) {
131               case VAR_EFFECTIVE_URL:
132                 if((CURLE_OK ==
133                     curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &stringp))
134                    && stringp)
135                   fputs(stringp, stream);
136                 break;
137               case VAR_HTTP_CODE:
138                 if(CURLE_OK ==
139                    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &longinfo))
140                   fprintf(stream, "%03ld", longinfo);
141                 break;
142               case VAR_HTTP_CODE_PROXY:
143                 if(CURLE_OK ==
144                    curl_easy_getinfo(curl, CURLINFO_HTTP_CONNECTCODE,
145                                      &longinfo))
146                   fprintf(stream, "%03ld", longinfo);
147                 break;
148               case VAR_HEADER_SIZE:
149                 if(CURLE_OK ==
150                    curl_easy_getinfo(curl, CURLINFO_HEADER_SIZE, &longinfo))
151                   fprintf(stream, "%ld", longinfo);
152                 break;
153               case VAR_REQUEST_SIZE:
154                 if(CURLE_OK ==
155                    curl_easy_getinfo(curl, CURLINFO_REQUEST_SIZE, &longinfo))
156                   fprintf(stream, "%ld", longinfo);
157                 break;
158               case VAR_NUM_CONNECTS:
159                 if(CURLE_OK ==
160                    curl_easy_getinfo(curl, CURLINFO_NUM_CONNECTS, &longinfo))
161                   fprintf(stream, "%ld", longinfo);
162                 break;
163               case VAR_REDIRECT_COUNT:
164                 if(CURLE_OK ==
165                    curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &longinfo))
166                   fprintf(stream, "%ld", longinfo);
167                 break;
168               case VAR_REDIRECT_TIME:
169                 if(CURLE_OK ==
170                    curl_easy_getinfo(curl, CURLINFO_REDIRECT_TIME,
171                                      &doubleinfo))
172                   fprintf(stream, "%.3f", doubleinfo);
173                 break;
174               case VAR_TOTAL_TIME:
175                 if(CURLE_OK ==
176                    curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &doubleinfo))
177                   fprintf(stream, "%.3f", doubleinfo);
178                 break;
179               case VAR_NAMELOOKUP_TIME:
180                 if(CURLE_OK ==
181                    curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME,
182                                      &doubleinfo))
183                   fprintf(stream, "%.3f", doubleinfo);
184                 break;
185               case VAR_CONNECT_TIME:
186                 if(CURLE_OK ==
187                    curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &doubleinfo))
188                   fprintf(stream, "%.3f", doubleinfo);
189                 break;
190               case VAR_APPCONNECT_TIME:
191                 if(CURLE_OK ==
192                    curl_easy_getinfo(curl, CURLINFO_APPCONNECT_TIME,
193                                      &doubleinfo))
194                   fprintf(stream, "%.3f", doubleinfo);
195                 break;
196               case VAR_PRETRANSFER_TIME:
197                 if(CURLE_OK ==
198                    curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME,
199                                      &doubleinfo))
200                   fprintf(stream, "%.3f", doubleinfo);
201                 break;
202               case VAR_STARTTRANSFER_TIME:
203                 if(CURLE_OK ==
204                    curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME,
205                                      &doubleinfo))
206                   fprintf(stream, "%.3f", doubleinfo);
207                 break;
208               case VAR_SIZE_UPLOAD:
209                 if(CURLE_OK ==
210                    curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD, &doubleinfo))
211                   fprintf(stream, "%.0f", doubleinfo);
212                 break;
213               case VAR_SIZE_DOWNLOAD:
214                 if(CURLE_OK ==
215                    curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD,
216                                      &doubleinfo))
217                   fprintf(stream, "%.0f", doubleinfo);
218                 break;
219               case VAR_SPEED_DOWNLOAD:
220                 if(CURLE_OK ==
221                    curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD,
222                                      &doubleinfo))
223                   fprintf(stream, "%.3f", doubleinfo);
224                 break;
225               case VAR_SPEED_UPLOAD:
226                 if(CURLE_OK ==
227                    curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &doubleinfo))
228                   fprintf(stream, "%.3f", doubleinfo);
229                 break;
230               case VAR_CONTENT_TYPE:
231                 if((CURLE_OK ==
232                     curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &stringp))
233                    && stringp)
234                   fputs(stringp, stream);
235                 break;
236               case VAR_FTP_ENTRY_PATH:
237                 if((CURLE_OK ==
238                     curl_easy_getinfo(curl, CURLINFO_FTP_ENTRY_PATH, &stringp))
239                    && stringp)
240                   fputs(stringp, stream);
241                 break;
242               case VAR_REDIRECT_URL:
243                 if((CURLE_OK ==
244                     curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &stringp))
245                    && stringp)
246                   fputs(stringp, stream);
247                 break;
248               case VAR_SSL_VERIFY_RESULT:
249                 if(CURLE_OK ==
250                    curl_easy_getinfo(curl, CURLINFO_SSL_VERIFYRESULT,
251                                      &longinfo))
252                   fprintf(stream, "%ld", longinfo);
253                 break;
254               case VAR_EFFECTIVE_FILENAME:
255                 if(outs->filename)
256                   fprintf(stream, "%s", outs->filename);
257                 break;
258               case VAR_PRIMARY_IP:
259                 if(CURLE_OK ==
260                    curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP,
261                                      &stringp))
262                   fprintf(stream, "%s", stringp);
263                 break;
264               case VAR_PRIMARY_PORT:
265                 if(CURLE_OK ==
266                    curl_easy_getinfo(curl, CURLINFO_PRIMARY_PORT,
267                                      &longinfo))
268                   fprintf(stream, "%ld", longinfo);
269                 break;
270               case VAR_LOCAL_IP:
271                 if(CURLE_OK ==
272                    curl_easy_getinfo(curl, CURLINFO_LOCAL_IP,
273                                      &stringp))
274                   fprintf(stream, "%s", stringp);
275                 break;
276               case VAR_LOCAL_PORT:
277                 if(CURLE_OK ==
278                    curl_easy_getinfo(curl, CURLINFO_LOCAL_PORT,
279                                      &longinfo))
280                   fprintf(stream, "%ld", longinfo);
281                 break;
282               default:
283                 break;
284               }
285               break;
286             }
287           }
288           if(!match) {
289             fprintf(stderr, "curl: unknown --write-out variable: '%s'\n", ptr);
290           }
291           ptr = end + 1; /* pass the end */
292           *end = keepit;
293         }
294         else {
295           /* illegal syntax, then just output the characters that are used */
296           fputc('%', stream);
297           fputc(ptr[1], stream);
298           ptr += 2;
299         }
300       }
301     }
302     else if('\\' == *ptr) {
303       switch(ptr[1]) {
304       case 'r':
305         fputc('\r', stream);
306         break;
307       case 'n':
308         fputc('\n', stream);
309         break;
310       case 't':
311         fputc('\t', stream);
312         break;
313       default:
314         /* unknown, just output this */
315         fputc(*ptr, stream);
316         fputc(ptr[1], stream);
317         break;
318       }
319       ptr += 2;
320     }
321     else {
322       fputc(*ptr, stream);
323       ptr++;
324     }
325   }
326
327 }