Annotation of embedaddon/curl/lib/getinfo.c, revision 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: 
        !            23: #include "curl_setup.h"
        !            24: 
        !            25: #include <curl/curl.h>
        !            26: 
        !            27: #include "urldata.h"
        !            28: #include "getinfo.h"
        !            29: 
        !            30: #include "vtls/vtls.h"
        !            31: #include "connect.h" /* Curl_getconnectinfo() */
        !            32: #include "progress.h"
        !            33: 
        !            34: /* The last #include files should be: */
        !            35: #include "curl_memory.h"
        !            36: #include "memdebug.h"
        !            37: 
        !            38: /*
        !            39:  * Initialize statistical and informational data.
        !            40:  *
        !            41:  * This function is called in curl_easy_reset, curl_easy_duphandle and at the
        !            42:  * beginning of a perform session. It must reset the session-info variables,
        !            43:  * in particular all variables in struct PureInfo.
        !            44:  */
        !            45: CURLcode Curl_initinfo(struct Curl_easy *data)
        !            46: {
        !            47:   struct Progress *pro = &data->progress;
        !            48:   struct PureInfo *info = &data->info;
        !            49: 
        !            50:   pro->t_nslookup = 0;
        !            51:   pro->t_connect = 0;
        !            52:   pro->t_appconnect = 0;
        !            53:   pro->t_pretransfer = 0;
        !            54:   pro->t_starttransfer = 0;
        !            55:   pro->timespent = 0;
        !            56:   pro->t_redirect = 0;
        !            57:   pro->is_t_startransfer_set = false;
        !            58: 
        !            59:   info->httpcode = 0;
        !            60:   info->httpproxycode = 0;
        !            61:   info->httpversion = 0;
        !            62:   info->filetime = -1; /* -1 is an illegal time and thus means unknown */
        !            63:   info->timecond = FALSE;
        !            64: 
        !            65:   info->header_size = 0;
        !            66:   info->request_size = 0;
        !            67:   info->proxyauthavail = 0;
        !            68:   info->httpauthavail = 0;
        !            69:   info->numconnects = 0;
        !            70: 
        !            71:   free(info->contenttype);
        !            72:   info->contenttype = NULL;
        !            73: 
        !            74:   free(info->wouldredirect);
        !            75:   info->wouldredirect = NULL;
        !            76: 
        !            77:   info->conn_primary_ip[0] = '\0';
        !            78:   info->conn_local_ip[0] = '\0';
        !            79:   info->conn_primary_port = 0;
        !            80:   info->conn_local_port = 0;
        !            81: 
        !            82:   info->conn_scheme = 0;
        !            83:   info->conn_protocol = 0;
        !            84: 
        !            85: #ifdef USE_SSL
        !            86:   Curl_ssl_free_certinfo(data);
        !            87: #endif
        !            88:   return CURLE_OK;
        !            89: }
        !            90: 
        !            91: static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info,
        !            92:                              const char **param_charp)
        !            93: {
        !            94:   switch(info) {
        !            95:   case CURLINFO_EFFECTIVE_URL:
        !            96:     *param_charp = data->change.url?data->change.url:(char *)"";
        !            97:     break;
        !            98:   case CURLINFO_CONTENT_TYPE:
        !            99:     *param_charp = data->info.contenttype;
        !           100:     break;
        !           101:   case CURLINFO_PRIVATE:
        !           102:     *param_charp = (char *) data->set.private_data;
        !           103:     break;
        !           104:   case CURLINFO_FTP_ENTRY_PATH:
        !           105:     /* Return the entrypath string from the most recent connection.
        !           106:        This pointer was copied from the connectdata structure by FTP.
        !           107:        The actual string may be free()ed by subsequent libcurl calls so
        !           108:        it must be copied to a safer area before the next libcurl call.
        !           109:        Callers must never free it themselves. */
        !           110:     *param_charp = data->state.most_recent_ftp_entrypath;
        !           111:     break;
        !           112:   case CURLINFO_REDIRECT_URL:
        !           113:     /* Return the URL this request would have been redirected to if that
        !           114:        option had been enabled! */
        !           115:     *param_charp = data->info.wouldredirect;
        !           116:     break;
        !           117:   case CURLINFO_PRIMARY_IP:
        !           118:     /* Return the ip address of the most recent (primary) connection */
        !           119:     *param_charp = data->info.conn_primary_ip;
        !           120:     break;
        !           121:   case CURLINFO_LOCAL_IP:
        !           122:     /* Return the source/local ip address of the most recent (primary)
        !           123:        connection */
        !           124:     *param_charp = data->info.conn_local_ip;
        !           125:     break;
        !           126:   case CURLINFO_RTSP_SESSION_ID:
        !           127:     *param_charp = data->set.str[STRING_RTSP_SESSION_ID];
        !           128:     break;
        !           129:   case CURLINFO_SCHEME:
        !           130:     *param_charp = data->info.conn_scheme;
        !           131:     break;
        !           132: 
        !           133:   default:
        !           134:     return CURLE_UNKNOWN_OPTION;
        !           135:   }
        !           136: 
        !           137:   return CURLE_OK;
        !           138: }
        !           139: 
        !           140: static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
        !           141:                              long *param_longp)
        !           142: {
        !           143:   curl_socket_t sockfd;
        !           144: 
        !           145:   union {
        !           146:     unsigned long *to_ulong;
        !           147:     long          *to_long;
        !           148:   } lptr;
        !           149: 
        !           150: #ifdef DEBUGBUILD
        !           151:   char *timestr = getenv("CURL_TIME");
        !           152:   if(timestr) {
        !           153:     unsigned long val = strtol(timestr, NULL, 10);
        !           154:     switch(info) {
        !           155:     case CURLINFO_LOCAL_PORT:
        !           156:       *param_longp = (long)val;
        !           157:       return CURLE_OK;
        !           158:     default:
        !           159:       break;
        !           160:     }
        !           161:   }
        !           162:   /* use another variable for this to allow different values */
        !           163:   timestr = getenv("CURL_DEBUG_SIZE");
        !           164:   if(timestr) {
        !           165:     unsigned long val = strtol(timestr, NULL, 10);
        !           166:     switch(info) {
        !           167:     case CURLINFO_HEADER_SIZE:
        !           168:     case CURLINFO_REQUEST_SIZE:
        !           169:       *param_longp = (long)val;
        !           170:       return CURLE_OK;
        !           171:     default:
        !           172:       break;
        !           173:     }
        !           174:   }
        !           175: #endif
        !           176: 
        !           177:   switch(info) {
        !           178:   case CURLINFO_RESPONSE_CODE:
        !           179:     *param_longp = data->info.httpcode;
        !           180:     break;
        !           181:   case CURLINFO_HTTP_CONNECTCODE:
        !           182:     *param_longp = data->info.httpproxycode;
        !           183:     break;
        !           184:   case CURLINFO_FILETIME:
        !           185:     if(data->info.filetime > LONG_MAX)
        !           186:       *param_longp = LONG_MAX;
        !           187:     else if(data->info.filetime < LONG_MIN)
        !           188:       *param_longp = LONG_MIN;
        !           189:     else
        !           190:       *param_longp = (long)data->info.filetime;
        !           191:     break;
        !           192:   case CURLINFO_HEADER_SIZE:
        !           193:     *param_longp = (long)data->info.header_size;
        !           194:     break;
        !           195:   case CURLINFO_REQUEST_SIZE:
        !           196:     *param_longp = (long)data->info.request_size;
        !           197:     break;
        !           198:   case CURLINFO_SSL_VERIFYRESULT:
        !           199:     *param_longp = data->set.ssl.certverifyresult;
        !           200:     break;
        !           201:   case CURLINFO_PROXY_SSL_VERIFYRESULT:
        !           202:     *param_longp = data->set.proxy_ssl.certverifyresult;
        !           203:     break;
        !           204:   case CURLINFO_REDIRECT_COUNT:
        !           205:     *param_longp = data->set.followlocation;
        !           206:     break;
        !           207:   case CURLINFO_HTTPAUTH_AVAIL:
        !           208:     lptr.to_long = param_longp;
        !           209:     *lptr.to_ulong = data->info.httpauthavail;
        !           210:     break;
        !           211:   case CURLINFO_PROXYAUTH_AVAIL:
        !           212:     lptr.to_long = param_longp;
        !           213:     *lptr.to_ulong = data->info.proxyauthavail;
        !           214:     break;
        !           215:   case CURLINFO_OS_ERRNO:
        !           216:     *param_longp = data->state.os_errno;
        !           217:     break;
        !           218:   case CURLINFO_NUM_CONNECTS:
        !           219:     *param_longp = data->info.numconnects;
        !           220:     break;
        !           221:   case CURLINFO_LASTSOCKET:
        !           222:     sockfd = Curl_getconnectinfo(data, NULL);
        !           223: 
        !           224:     /* note: this is not a good conversion for systems with 64 bit sockets and
        !           225:        32 bit longs */
        !           226:     if(sockfd != CURL_SOCKET_BAD)
        !           227:       *param_longp = (long)sockfd;
        !           228:     else
        !           229:       /* this interface is documented to return -1 in case of badness, which
        !           230:          may not be the same as the CURL_SOCKET_BAD value */
        !           231:       *param_longp = -1;
        !           232:     break;
        !           233:   case CURLINFO_PRIMARY_PORT:
        !           234:     /* Return the (remote) port of the most recent (primary) connection */
        !           235:     *param_longp = data->info.conn_primary_port;
        !           236:     break;
        !           237:   case CURLINFO_LOCAL_PORT:
        !           238:     /* Return the local port of the most recent (primary) connection */
        !           239:     *param_longp = data->info.conn_local_port;
        !           240:     break;
        !           241:   case CURLINFO_CONDITION_UNMET:
        !           242:     if(data->info.httpcode == 304)
        !           243:       *param_longp = 1L;
        !           244:     else
        !           245:       /* return if the condition prevented the document to get transferred */
        !           246:       *param_longp = data->info.timecond ? 1L : 0L;
        !           247:     break;
        !           248:   case CURLINFO_RTSP_CLIENT_CSEQ:
        !           249:     *param_longp = data->state.rtsp_next_client_CSeq;
        !           250:     break;
        !           251:   case CURLINFO_RTSP_SERVER_CSEQ:
        !           252:     *param_longp = data->state.rtsp_next_server_CSeq;
        !           253:     break;
        !           254:   case CURLINFO_RTSP_CSEQ_RECV:
        !           255:     *param_longp = data->state.rtsp_CSeq_recv;
        !           256:     break;
        !           257:   case CURLINFO_HTTP_VERSION:
        !           258:     switch(data->info.httpversion) {
        !           259:     case 10:
        !           260:       *param_longp = CURL_HTTP_VERSION_1_0;
        !           261:       break;
        !           262:     case 11:
        !           263:       *param_longp = CURL_HTTP_VERSION_1_1;
        !           264:       break;
        !           265:     case 20:
        !           266:       *param_longp = CURL_HTTP_VERSION_2_0;
        !           267:       break;
        !           268:     case 30:
        !           269:       *param_longp = CURL_HTTP_VERSION_3;
        !           270:       break;
        !           271:     default:
        !           272:       *param_longp = CURL_HTTP_VERSION_NONE;
        !           273:       break;
        !           274:     }
        !           275:     break;
        !           276:   case CURLINFO_PROTOCOL:
        !           277:     *param_longp = data->info.conn_protocol;
        !           278:     break;
        !           279:   default:
        !           280:     return CURLE_UNKNOWN_OPTION;
        !           281:   }
        !           282: 
        !           283:   return CURLE_OK;
        !           284: }
        !           285: 
        !           286: #define DOUBLE_SECS(x) (double)(x)/1000000
        !           287: 
        !           288: static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
        !           289:                              curl_off_t *param_offt)
        !           290: {
        !           291: #ifdef DEBUGBUILD
        !           292:   char *timestr = getenv("CURL_TIME");
        !           293:   if(timestr) {
        !           294:     unsigned long val = strtol(timestr, NULL, 10);
        !           295:     switch(info) {
        !           296:     case CURLINFO_TOTAL_TIME_T:
        !           297:     case CURLINFO_NAMELOOKUP_TIME_T:
        !           298:     case CURLINFO_CONNECT_TIME_T:
        !           299:     case CURLINFO_APPCONNECT_TIME_T:
        !           300:     case CURLINFO_PRETRANSFER_TIME_T:
        !           301:     case CURLINFO_STARTTRANSFER_TIME_T:
        !           302:     case CURLINFO_REDIRECT_TIME_T:
        !           303:     case CURLINFO_SPEED_DOWNLOAD_T:
        !           304:     case CURLINFO_SPEED_UPLOAD_T:
        !           305:       *param_offt = (curl_off_t)val;
        !           306:       return CURLE_OK;
        !           307:     default:
        !           308:       break;
        !           309:     }
        !           310:   }
        !           311: #endif
        !           312:   switch(info) {
        !           313:   case CURLINFO_FILETIME_T:
        !           314:     *param_offt = (curl_off_t)data->info.filetime;
        !           315:     break;
        !           316:   case CURLINFO_SIZE_UPLOAD_T:
        !           317:     *param_offt = data->progress.uploaded;
        !           318:     break;
        !           319:   case CURLINFO_SIZE_DOWNLOAD_T:
        !           320:     *param_offt = data->progress.downloaded;
        !           321:     break;
        !           322:   case CURLINFO_SPEED_DOWNLOAD_T:
        !           323:     *param_offt =  data->progress.dlspeed;
        !           324:     break;
        !           325:   case CURLINFO_SPEED_UPLOAD_T:
        !           326:     *param_offt = data->progress.ulspeed;
        !           327:     break;
        !           328:   case CURLINFO_CONTENT_LENGTH_DOWNLOAD_T:
        !           329:     *param_offt = (data->progress.flags & PGRS_DL_SIZE_KNOWN)?
        !           330:       data->progress.size_dl:-1;
        !           331:     break;
        !           332:   case CURLINFO_CONTENT_LENGTH_UPLOAD_T:
        !           333:     *param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
        !           334:       data->progress.size_ul:-1;
        !           335:     break;
        !           336:    case CURLINFO_TOTAL_TIME_T:
        !           337:     *param_offt = data->progress.timespent;
        !           338:     break;
        !           339:   case CURLINFO_NAMELOOKUP_TIME_T:
        !           340:     *param_offt = data->progress.t_nslookup;
        !           341:     break;
        !           342:   case CURLINFO_CONNECT_TIME_T:
        !           343:     *param_offt = data->progress.t_connect;
        !           344:     break;
        !           345:   case CURLINFO_APPCONNECT_TIME_T:
        !           346:     *param_offt = data->progress.t_appconnect;
        !           347:     break;
        !           348:   case CURLINFO_PRETRANSFER_TIME_T:
        !           349:     *param_offt = data->progress.t_pretransfer;
        !           350:     break;
        !           351:   case CURLINFO_STARTTRANSFER_TIME_T:
        !           352:     *param_offt = data->progress.t_starttransfer;
        !           353:     break;
        !           354:   case CURLINFO_REDIRECT_TIME_T:
        !           355:     *param_offt = data->progress.t_redirect;
        !           356:     break;
        !           357:   case CURLINFO_RETRY_AFTER:
        !           358:     *param_offt = data->info.retry_after;
        !           359:     break;
        !           360:   default:
        !           361:     return CURLE_UNKNOWN_OPTION;
        !           362:   }
        !           363: 
        !           364:   return CURLE_OK;
        !           365: }
        !           366: 
        !           367: static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
        !           368:                                double *param_doublep)
        !           369: {
        !           370: #ifdef DEBUGBUILD
        !           371:   char *timestr = getenv("CURL_TIME");
        !           372:   if(timestr) {
        !           373:     unsigned long val = strtol(timestr, NULL, 10);
        !           374:     switch(info) {
        !           375:     case CURLINFO_TOTAL_TIME:
        !           376:     case CURLINFO_NAMELOOKUP_TIME:
        !           377:     case CURLINFO_CONNECT_TIME:
        !           378:     case CURLINFO_APPCONNECT_TIME:
        !           379:     case CURLINFO_PRETRANSFER_TIME:
        !           380:     case CURLINFO_STARTTRANSFER_TIME:
        !           381:     case CURLINFO_REDIRECT_TIME:
        !           382:     case CURLINFO_SPEED_DOWNLOAD:
        !           383:     case CURLINFO_SPEED_UPLOAD:
        !           384:       *param_doublep = (double)val;
        !           385:       return CURLE_OK;
        !           386:     default:
        !           387:       break;
        !           388:     }
        !           389:   }
        !           390: #endif
        !           391:   switch(info) {
        !           392:   case CURLINFO_TOTAL_TIME:
        !           393:     *param_doublep = DOUBLE_SECS(data->progress.timespent);
        !           394:     break;
        !           395:   case CURLINFO_NAMELOOKUP_TIME:
        !           396:     *param_doublep = DOUBLE_SECS(data->progress.t_nslookup);
        !           397:     break;
        !           398:   case CURLINFO_CONNECT_TIME:
        !           399:     *param_doublep = DOUBLE_SECS(data->progress.t_connect);
        !           400:     break;
        !           401:   case CURLINFO_APPCONNECT_TIME:
        !           402:     *param_doublep = DOUBLE_SECS(data->progress.t_appconnect);
        !           403:     break;
        !           404:   case CURLINFO_PRETRANSFER_TIME:
        !           405:     *param_doublep = DOUBLE_SECS(data->progress.t_pretransfer);
        !           406:     break;
        !           407:   case CURLINFO_STARTTRANSFER_TIME:
        !           408:     *param_doublep = DOUBLE_SECS(data->progress.t_starttransfer);
        !           409:     break;
        !           410:   case CURLINFO_SIZE_UPLOAD:
        !           411:     *param_doublep =  (double)data->progress.uploaded;
        !           412:     break;
        !           413:   case CURLINFO_SIZE_DOWNLOAD:
        !           414:     *param_doublep = (double)data->progress.downloaded;
        !           415:     break;
        !           416:   case CURLINFO_SPEED_DOWNLOAD:
        !           417:     *param_doublep =  (double)data->progress.dlspeed;
        !           418:     break;
        !           419:   case CURLINFO_SPEED_UPLOAD:
        !           420:     *param_doublep = (double)data->progress.ulspeed;
        !           421:     break;
        !           422:   case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
        !           423:     *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN)?
        !           424:       (double)data->progress.size_dl:-1;
        !           425:     break;
        !           426:   case CURLINFO_CONTENT_LENGTH_UPLOAD:
        !           427:     *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
        !           428:       (double)data->progress.size_ul:-1;
        !           429:     break;
        !           430:   case CURLINFO_REDIRECT_TIME:
        !           431:     *param_doublep = DOUBLE_SECS(data->progress.t_redirect);
        !           432:     break;
        !           433: 
        !           434:   default:
        !           435:     return CURLE_UNKNOWN_OPTION;
        !           436:   }
        !           437: 
        !           438:   return CURLE_OK;
        !           439: }
        !           440: 
        !           441: static CURLcode getinfo_slist(struct Curl_easy *data, CURLINFO info,
        !           442:                               struct curl_slist **param_slistp)
        !           443: {
        !           444:   union {
        !           445:     struct curl_certinfo *to_certinfo;
        !           446:     struct curl_slist    *to_slist;
        !           447:   } ptr;
        !           448: 
        !           449:   switch(info) {
        !           450:   case CURLINFO_SSL_ENGINES:
        !           451:     *param_slistp = Curl_ssl_engines_list(data);
        !           452:     break;
        !           453:   case CURLINFO_COOKIELIST:
        !           454:     *param_slistp = Curl_cookie_list(data);
        !           455:     break;
        !           456:   case CURLINFO_CERTINFO:
        !           457:     /* Return the a pointer to the certinfo struct. Not really an slist
        !           458:        pointer but we can pretend it is here */
        !           459:     ptr.to_certinfo = &data->info.certs;
        !           460:     *param_slistp = ptr.to_slist;
        !           461:     break;
        !           462:   case CURLINFO_TLS_SESSION:
        !           463:   case CURLINFO_TLS_SSL_PTR:
        !           464:     {
        !           465:       struct curl_tlssessioninfo **tsip = (struct curl_tlssessioninfo **)
        !           466:                                           param_slistp;
        !           467:       struct curl_tlssessioninfo *tsi = &data->tsi;
        !           468: #ifdef USE_SSL
        !           469:       struct connectdata *conn = data->conn;
        !           470: #endif
        !           471: 
        !           472:       *tsip = tsi;
        !           473:       tsi->backend = Curl_ssl_backend();
        !           474:       tsi->internals = NULL;
        !           475: 
        !           476: #ifdef USE_SSL
        !           477:       if(conn && tsi->backend != CURLSSLBACKEND_NONE) {
        !           478:         unsigned int i;
        !           479:         for(i = 0; i < (sizeof(conn->ssl) / sizeof(conn->ssl[0])); ++i) {
        !           480:           if(conn->ssl[i].use) {
        !           481:             tsi->internals = Curl_ssl->get_internals(&conn->ssl[i], info);
        !           482:             break;
        !           483:           }
        !           484:         }
        !           485:       }
        !           486: #endif
        !           487:     }
        !           488:     break;
        !           489:   default:
        !           490:     return CURLE_UNKNOWN_OPTION;
        !           491:   }
        !           492: 
        !           493:   return CURLE_OK;
        !           494: }
        !           495: 
        !           496: static CURLcode getinfo_socket(struct Curl_easy *data, CURLINFO info,
        !           497:                                curl_socket_t *param_socketp)
        !           498: {
        !           499:   switch(info) {
        !           500:   case CURLINFO_ACTIVESOCKET:
        !           501:     *param_socketp = Curl_getconnectinfo(data, NULL);
        !           502:     break;
        !           503:   default:
        !           504:     return CURLE_UNKNOWN_OPTION;
        !           505:   }
        !           506: 
        !           507:   return CURLE_OK;
        !           508: }
        !           509: 
        !           510: CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...)
        !           511: {
        !           512:   va_list arg;
        !           513:   long *param_longp = NULL;
        !           514:   double *param_doublep = NULL;
        !           515:   curl_off_t *param_offt = NULL;
        !           516:   const char **param_charp = NULL;
        !           517:   struct curl_slist **param_slistp = NULL;
        !           518:   curl_socket_t *param_socketp = NULL;
        !           519:   int type;
        !           520:   CURLcode result = CURLE_UNKNOWN_OPTION;
        !           521: 
        !           522:   if(!data)
        !           523:     return result;
        !           524: 
        !           525:   va_start(arg, info);
        !           526: 
        !           527:   type = CURLINFO_TYPEMASK & (int)info;
        !           528:   switch(type) {
        !           529:   case CURLINFO_STRING:
        !           530:     param_charp = va_arg(arg, const char **);
        !           531:     if(param_charp)
        !           532:       result = getinfo_char(data, info, param_charp);
        !           533:     break;
        !           534:   case CURLINFO_LONG:
        !           535:     param_longp = va_arg(arg, long *);
        !           536:     if(param_longp)
        !           537:       result = getinfo_long(data, info, param_longp);
        !           538:     break;
        !           539:   case CURLINFO_DOUBLE:
        !           540:     param_doublep = va_arg(arg, double *);
        !           541:     if(param_doublep)
        !           542:       result = getinfo_double(data, info, param_doublep);
        !           543:     break;
        !           544:   case CURLINFO_OFF_T:
        !           545:     param_offt = va_arg(arg, curl_off_t *);
        !           546:     if(param_offt)
        !           547:       result = getinfo_offt(data, info, param_offt);
        !           548:     break;
        !           549:   case CURLINFO_SLIST:
        !           550:     param_slistp = va_arg(arg, struct curl_slist **);
        !           551:     if(param_slistp)
        !           552:       result = getinfo_slist(data, info, param_slistp);
        !           553:     break;
        !           554:   case CURLINFO_SOCKET:
        !           555:     param_socketp = va_arg(arg, curl_socket_t *);
        !           556:     if(param_socketp)
        !           557:       result = getinfo_socket(data, info, param_socketp);
        !           558:     break;
        !           559:   default:
        !           560:     break;
        !           561:   }
        !           562: 
        !           563:   va_end(arg);
        !           564: 
        !           565:   return result;
        !           566: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>