Git init
[external/curl.git] / lib / getinfo.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2010, 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
23 #include "setup.h"
24
25 #include <curl/curl.h>
26
27 #include "urldata.h"
28 #include "getinfo.h"
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdarg.h>
33 #include <stdlib.h>
34 #include "curl_memory.h"
35 #include "sslgen.h"
36 #include "connect.h" /* Curl_getconnectinfo() */
37 #include "progress.h"
38
39 /* Make this the last #include */
40 #include "memdebug.h"
41
42 /*
43  * This is supposed to be called in the beginning of a perform() session
44  * and should reset all session-info variables
45  */
46 CURLcode Curl_initinfo(struct SessionHandle *data)
47 {
48   struct Progress *pro = &data->progress;
49   struct PureInfo *info =&data->info;
50
51   pro->t_nslookup = 0;
52   pro->t_connect = 0;
53   pro->t_pretransfer = 0;
54   pro->t_starttransfer = 0;
55   pro->timespent = 0;
56   pro->t_redirect = 0;
57
58   info->httpcode = 0;
59   info->httpversion=0;
60   info->filetime=-1; /* -1 is an illegal time and thus means unknown */
61
62   if(info->contenttype)
63     free(info->contenttype);
64   info->contenttype = NULL;
65
66   info->header_size = 0;
67   info->request_size = 0;
68   info->numconnects = 0;
69
70   info->conn_primary_ip[0] = '\0';
71   info->conn_local_ip[0] = '\0';
72   info->conn_primary_port = 0;
73   info->conn_local_port = 0;
74
75   return CURLE_OK;
76 }
77
78 CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
79 {
80   va_list arg;
81   long *param_longp=NULL;
82   double *param_doublep=NULL;
83   char **param_charp=NULL;
84   struct curl_slist **param_slistp=NULL;
85   int type;
86   curl_socket_t sockfd;
87
88   union {
89     struct curl_certinfo * to_certinfo;
90     struct curl_slist    * to_slist;
91   } ptr;
92
93   if(!data)
94     return CURLE_BAD_FUNCTION_ARGUMENT;
95
96   va_start(arg, info);
97
98   type = CURLINFO_TYPEMASK & (int)info;
99   switch(type) {
100   case CURLINFO_STRING:
101     param_charp = va_arg(arg, char **);
102     if(NULL == param_charp)
103       return CURLE_BAD_FUNCTION_ARGUMENT;
104     break;
105   case CURLINFO_LONG:
106     param_longp = va_arg(arg, long *);
107     if(NULL == param_longp)
108       return CURLE_BAD_FUNCTION_ARGUMENT;
109     break;
110   case CURLINFO_DOUBLE:
111     param_doublep = va_arg(arg, double *);
112     if(NULL == param_doublep)
113       return CURLE_BAD_FUNCTION_ARGUMENT;
114     break;
115   case CURLINFO_SLIST:
116     param_slistp = va_arg(arg, struct curl_slist **);
117     if(NULL == param_slistp)
118       return CURLE_BAD_FUNCTION_ARGUMENT;
119     break;
120   default:
121     return CURLE_BAD_FUNCTION_ARGUMENT;
122   }
123
124   switch(info) {
125   case CURLINFO_EFFECTIVE_URL:
126     *param_charp = data->change.url?data->change.url:(char *)"";
127     break;
128   case CURLINFO_RESPONSE_CODE:
129     *param_longp = data->info.httpcode;
130     break;
131   case CURLINFO_HTTP_CONNECTCODE:
132     *param_longp = data->info.httpproxycode;
133     break;
134   case CURLINFO_FILETIME:
135     *param_longp = data->info.filetime;
136     break;
137   case CURLINFO_HEADER_SIZE:
138     *param_longp = data->info.header_size;
139     break;
140   case CURLINFO_REQUEST_SIZE:
141     *param_longp = data->info.request_size;
142     break;
143   case CURLINFO_TOTAL_TIME:
144     *param_doublep = data->progress.timespent;
145     break;
146   case CURLINFO_NAMELOOKUP_TIME:
147     *param_doublep = data->progress.t_nslookup;
148     break;
149   case CURLINFO_CONNECT_TIME:
150     *param_doublep = data->progress.t_connect;
151     break;
152   case CURLINFO_APPCONNECT_TIME:
153     *param_doublep = data->progress.t_appconnect;
154     break;
155   case CURLINFO_PRETRANSFER_TIME:
156     *param_doublep =  data->progress.t_pretransfer;
157     break;
158   case CURLINFO_STARTTRANSFER_TIME:
159     *param_doublep = data->progress.t_starttransfer;
160     break;
161   case CURLINFO_SIZE_UPLOAD:
162     *param_doublep =  (double)data->progress.uploaded;
163     break;
164   case CURLINFO_SIZE_DOWNLOAD:
165     *param_doublep = (double)data->progress.downloaded;
166     break;
167   case CURLINFO_SPEED_DOWNLOAD:
168     *param_doublep =  (double)data->progress.dlspeed;
169     break;
170   case CURLINFO_SPEED_UPLOAD:
171     *param_doublep = (double)data->progress.ulspeed;
172     break;
173   case CURLINFO_SSL_VERIFYRESULT:
174     *param_longp = data->set.ssl.certverifyresult;
175     break;
176   case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
177     *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN)?
178       (double)data->progress.size_dl:-1;
179     break;
180   case CURLINFO_CONTENT_LENGTH_UPLOAD:
181     *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
182       (double)data->progress.size_ul:-1;
183     break;
184   case CURLINFO_REDIRECT_TIME:
185     *param_doublep =  data->progress.t_redirect;
186     break;
187   case CURLINFO_REDIRECT_COUNT:
188     *param_longp = data->set.followlocation;
189     break;
190   case CURLINFO_CONTENT_TYPE:
191     *param_charp = data->info.contenttype;
192     break;
193   case CURLINFO_PRIVATE:
194     *param_charp = (char *) data->set.private_data;
195     break;
196   case CURLINFO_HTTPAUTH_AVAIL:
197     *param_longp = data->info.httpauthavail;
198     break;
199   case CURLINFO_PROXYAUTH_AVAIL:
200     *param_longp = data->info.proxyauthavail;
201     break;
202   case CURLINFO_OS_ERRNO:
203     *param_longp = data->state.os_errno;
204     break;
205   case CURLINFO_NUM_CONNECTS:
206     *param_longp = data->info.numconnects;
207     break;
208   case CURLINFO_SSL_ENGINES:
209     *param_slistp = Curl_ssl_engines_list(data);
210     break;
211   case CURLINFO_COOKIELIST:
212     *param_slistp = Curl_cookie_list(data);
213     break;
214   case CURLINFO_FTP_ENTRY_PATH:
215     /* Return the entrypath string from the most recent connection.
216        This pointer was copied from the connectdata structure by FTP.
217        The actual string may be free()ed by subsequent libcurl calls so
218        it must be copied to a safer area before the next libcurl call.
219        Callers must never free it themselves. */
220     *param_charp = data->state.most_recent_ftp_entrypath;
221     break;
222   case CURLINFO_LASTSOCKET:
223     sockfd = Curl_getconnectinfo(data, NULL);
224
225     /* note: this is not a good conversion for systems with 64 bit sockets and
226        32 bit longs */
227     if(sockfd != CURL_SOCKET_BAD)
228       *param_longp = (long)sockfd;
229     else
230       /* this interface is documented to return -1 in case of badness, which
231          may not be the same as the CURL_SOCKET_BAD value */
232       *param_longp = -1;
233     break;
234   case CURLINFO_REDIRECT_URL:
235     /* Return the URL this request would have been redirected to if that
236        option had been enabled! */
237     *param_charp = data->info.wouldredirect;
238     break;
239   case CURLINFO_PRIMARY_IP:
240     /* Return the ip address of the most recent (primary) connection */
241     *param_charp = data->info.conn_primary_ip;
242     break;
243   case CURLINFO_PRIMARY_PORT:
244     /* Return the (remote) port of the most recent (primary) connection */
245     *param_longp = data->info.conn_primary_port;
246     break;
247   case CURLINFO_LOCAL_IP:
248     /* Return the source/local ip address of the most recent (primary)
249        connection */
250     *param_charp = data->info.conn_local_ip;
251     break;
252   case CURLINFO_LOCAL_PORT:
253     /* Return the local port of the most recent (primary) connection */
254     *param_longp = data->info.conn_local_port;
255     break;
256   case CURLINFO_CERTINFO:
257     /* Return the a pointer to the certinfo struct. Not really an slist
258        pointer but we can pretend it is here */
259     ptr.to_certinfo = &data->info.certs;
260     *param_slistp = ptr.to_slist;
261     break;
262   case CURLINFO_CONDITION_UNMET:
263     /* return if the condition prevented the document to get transfered */
264     *param_longp = data->info.timecond;
265     break;
266   case CURLINFO_RTSP_SESSION_ID:
267     *param_charp = data->set.str[STRING_RTSP_SESSION_ID];
268     break;
269   case CURLINFO_RTSP_CLIENT_CSEQ:
270     *param_longp = data->state.rtsp_next_client_CSeq;
271     break;
272   case CURLINFO_RTSP_SERVER_CSEQ:
273     *param_longp = data->state.rtsp_next_server_CSeq;
274     break;
275   case CURLINFO_RTSP_CSEQ_RECV:
276     *param_longp = data->state.rtsp_CSeq_recv;
277     break;
278
279   default:
280     return CURLE_BAD_FUNCTION_ARGUMENT;
281   }
282   return CURLE_OK;
283 }