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>