1.1 --- a/app-manager/Makefile.am Thu Nov 10 11:15:09 2011 +0000
1.2 +++ b/app-manager/Makefile.am Thu Nov 10 11:19:34 2011 +0000
1.3 @@ -1,9 +1,11 @@
1.4 AM_CFLAGS=$(GUI_CFLAGS) -g -DPLOVER_DATADIR=\""$(pkgdatadir)"\" -I$(top_srcdir)
1.5 LDADD=../plover/libplover.la ../plover-gtk/libplover-gtk.la $(GUI_LIBS)
1.6
1.7 -bin_PROGRAMS=app-manager
1.8 +bin_PROGRAMS=app-manager fetch
1.9 app_manager_SOURCES=app-manager.c app-manager.h packagelist.c applications.c \
1.10 localmedia.c localmedia.h
1.11 +fetch_SOURCES=fetch.c
1.12 +fetch_LDADD=$(LDADD) -lcrypt32
1.13 if HAVE_WINDRES
1.14 app_manager_SOURCES+=resources.rc app-manager.exe.manifest
1.15 endif
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/app-manager/fetch.c Thu Nov 10 11:19:34 2011 +0000
2.3 @@ -0,0 +1,411 @@
2.4 +/*
2.5 + * A program to explore http support on MS-Windows.
2.6 + */
2.7 +
2.8 +#include "config.h"
2.9 +#include <stdlib.h>
2.10 +#include <stdio.h>
2.11 +#include <glib.h>
2.12 +#include <razor.h>
2.13 +#if HAVE_WINHTTP_H
2.14 +#include <windows.h>
2.15 +#include <winhttp.h>
2.16 +#include <wincrypt.h>
2.17 +
2.18 +#ifndef PKCS12_NO_PERSIST_KEY
2.19 +#define PKCS12_NO_PERSIST_KEY 0x00008000
2.20 +#endif
2.21 +
2.22 +static gboolean debug=FALSE;
2.23 +
2.24 +static GOptionEntry entries[] =
2.25 +{
2.26 + { "debug",'d',0,G_OPTION_ARG_NONE,&debug,"Output debugging",NULL },
2.27 + { NULL }
2.28 +};
2.29 +
2.30 +static struct WinHttpFuncs
2.31 +{
2.32 + WINBOOL (WINAPI *AddRequestHeaders)(HINTERNET,LPCWSTR,DWORD,DWORD);
2.33 + WINBOOL (WINAPI *DetectAutoProxyConfigUrl)(DWORD,LPWSTR*);
2.34 + WINBOOL (WINAPI *CheckPlatform)(void);
2.35 + WINBOOL (WINAPI *CloseHandle)(HINTERNET);
2.36 + HINTERNET (WINAPI *Connect)(HINTERNET,LPCWSTR,INTERNET_PORT,DWORD);
2.37 + WINBOOL (WINAPI *CrackUrl)(LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS);
2.38 + WINBOOL (WINAPI *CreateUrl)(LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD);
2.39 + WINBOOL (WINAPI *GetDefaultProxyConfiguration)(WINHTTP_PROXY_INFO*);
2.40 + WINBOOL (WINAPI *GetIEProxyConfigForCurrentUser)(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG*);
2.41 + WINBOOL (WINAPI *GetProxyForUrl)(HINTERNET,LPCWSTR,WINHTTP_AUTOPROXY_OPTIONS*,WINHTTP_PROXY_INFO*);
2.42 + HINTERNET (WINAPI *Open)(LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD);
2.43 + HINTERNET (WINAPI *OpenRequest)(HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD);
2.44 + WINBOOL (WINAPI *QueryAuthParams)(HINTERNET,DWORD,LPVOID*);
2.45 + WINBOOL (WINAPI *QueryAuthSchemes)(HINTERNET,LPDWORD,LPDWORD,LPDWORD);
2.46 + WINBOOL (WINAPI *QueryDataAvailable)(HINTERNET,LPDWORD);
2.47 + WINBOOL (WINAPI *QueryHeaders)(HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD);
2.48 + WINBOOL (WINAPI *QueryOption)(HINTERNET,DWORD,LPVOID,LPDWORD);
2.49 + WINBOOL (WINAPI *ReadData)(HINTERNET,LPVOID,DWORD,LPDWORD);
2.50 + WINBOOL (WINAPI *ReceiveResponse)(HINTERNET,LPVOID);
2.51 + WINBOOL (WINAPI *SendRequest)(HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR);
2.52 + WINBOOL (WINAPI *SetDefaultProxyConfiguration)(WINHTTP_PROXY_INFO*);
2.53 + WINBOOL (WINAPI *SetCredentials)(HINTERNET,DWORD,DWORD,LPCWSTR,LPCWSTR,LPVOID);
2.54 + WINBOOL (WINAPI *SetOption)(HINTERNET,DWORD,LPVOID,DWORD);
2.55 + WINHTTP_STATUS_CALLBACK (WINAPI *SetStatusCallback)(HINTERNET,WINHTTP_STATUS_CALLBACK,DWORD,DWORD_PTR);
2.56 + WINBOOL (WINAPI *SetTimeouts)(HINTERNET,int,int,int,int);
2.57 + WINBOOL (WINAPI *TimeFromSystemTime)(CONST SYSTEMTIME *,LPWSTR);
2.58 + WINBOOL (WINAPI *TimeToSystemTime)(LPCWSTR,SYSTEMTIME*);
2.59 + WINBOOL (WINAPI *WriteData)(HINTERNET,LPCVOID,DWORD,LPDWORD);
2.60 +} WinHttp;
2.61 +
2.62 +static int plover_init_winhttp(void)
2.63 +{
2.64 + HMODULE module;
2.65 + if (WinHttp.Open)
2.66 + return 0;
2.67 + module=LoadLibraryA("winhttp.dll");
2.68 + if (!module)
2.69 + return -1;
2.70 + WinHttp.AddRequestHeaders=
2.71 + (WINBOOL (WINAPI *)(HINTERNET,LPCWSTR,DWORD,DWORD))
2.72 + GetProcAddress(module,"WinHttpAddRequestHeaders");
2.73 + WinHttp.DetectAutoProxyConfigUrl=
2.74 + (WINBOOL (WINAPI *)(DWORD,LPWSTR*))
2.75 + GetProcAddress(module,"WinHttpDetectAutoProxyConfigUrl");
2.76 + WinHttp.CheckPlatform=(WINBOOL (WINAPI *)(void))
2.77 + GetProcAddress(module,"WinHttpCheckPlatform");
2.78 + WinHttp.CloseHandle=(WINBOOL (WINAPI *)(HINTERNET))
2.79 + GetProcAddress(module,"WinHttpCloseHandle");
2.80 + WinHttp.Connect=
2.81 + (HINTERNET (WINAPI *)(HINTERNET,LPCWSTR,INTERNET_PORT,DWORD))
2.82 + GetProcAddress(module,"WinHttpConnect");
2.83 + WinHttp.CrackUrl=(WINBOOL (WINAPI *)(LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS))
2.84 + GetProcAddress(module,"WinHttpCrackUrl");
2.85 + WinHttp.CreateUrl=
2.86 + (WINBOOL (WINAPI *)(LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD))
2.87 + GetProcAddress(module,"WinHttpCreateUrl");
2.88 + WinHttp.GetDefaultProxyConfiguration=
2.89 + (WINBOOL (WINAPI *)(WINHTTP_PROXY_INFO*))
2.90 + GetProcAddress(module,"WinHttpGetDefaultProxyConfiguration");
2.91 + WinHttp.GetIEProxyConfigForCurrentUser=
2.92 + (WINBOOL (WINAPI *)(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG*))
2.93 + GetProcAddress(module,"WinHttpGetIEProxyConfigForCurrentUser");
2.94 + WinHttp.GetProxyForUrl=
2.95 + (WINBOOL (WINAPI *)(HINTERNET,LPCWSTR,WINHTTP_AUTOPROXY_OPTIONS*,WINHTTP_PROXY_INFO*))
2.96 + GetProcAddress(module,"WinHttpGetProxyForUrl");
2.97 + WinHttp.Open=(HINTERNET (WINAPI *)(LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD))
2.98 + GetProcAddress(module,"WinHttpOpen");
2.99 + WinHttp.OpenRequest=
2.100 + (HINTERNET (WINAPI *)(HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD))
2.101 + GetProcAddress(module,"WinHttpOpenRequest");
2.102 + WinHttp.QueryAuthParams=(WINBOOL (WINAPI *)(HINTERNET,DWORD,LPVOID*))
2.103 + GetProcAddress(module,"WinHttpQueryAuthParams");
2.104 + WinHttp.QueryAuthSchemes=
2.105 + (WINBOOL (WINAPI *)(HINTERNET,LPDWORD,LPDWORD,LPDWORD))
2.106 + GetProcAddress(module,"WinHttpQueryAuthSchemes");
2.107 + WinHttp.QueryDataAvailable=(WINBOOL (WINAPI *)(HINTERNET,LPDWORD))
2.108 + GetProcAddress(module,"WinHttpQueryDataAvailable");
2.109 + WinHttp.QueryHeaders=
2.110 + (WINBOOL (WINAPI *)(HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD))
2.111 + GetProcAddress(module,"WinHttpQueryHeaders");
2.112 + WinHttp.QueryOption=(WINBOOL (WINAPI *)(HINTERNET,DWORD,LPVOID,LPDWORD))
2.113 + GetProcAddress(module,"WinHttpQueryOption");
2.114 + WinHttp.ReadData=(WINBOOL (WINAPI *)(HINTERNET,LPVOID,DWORD,LPDWORD))
2.115 + GetProcAddress(module,"WinHttpReadData");
2.116 + WinHttp.ReceiveResponse=(WINBOOL (WINAPI *)(HINTERNET,LPVOID))
2.117 + GetProcAddress(module,"WinHttpReceiveResponse");
2.118 + WinHttp.SendRequest=
2.119 + (WINBOOL (WINAPI *)(HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR))
2.120 + GetProcAddress(module,"WinHttpSendRequest");
2.121 + WinHttp.SetDefaultProxyConfiguration=
2.122 + (WINBOOL (WINAPI *)(WINHTTP_PROXY_INFO*))
2.123 + GetProcAddress(module,"WinHttpSetDefaultProxyConfiguration");
2.124 + WinHttp.SetCredentials=
2.125 + (WINBOOL (WINAPI *)(HINTERNET,DWORD,DWORD,LPCWSTR,LPCWSTR,LPVOID))
2.126 + GetProcAddress(module,"WinHttpSetCredentials");
2.127 + WinHttp.SetOption=(WINBOOL (WINAPI *)(HINTERNET,DWORD,LPVOID,DWORD))
2.128 + GetProcAddress(module,"WinHttpSetOption");
2.129 + WinHttp.SetStatusCallback=
2.130 + (WINHTTP_STATUS_CALLBACK (WINAPI *)(HINTERNET,WINHTTP_STATUS_CALLBACK,DWORD,DWORD_PTR))
2.131 + GetProcAddress(module,"WinHttpSetStatusCallback");
2.132 + WinHttp.SetTimeouts=(WINBOOL (WINAPI *)(HINTERNET,int,int,int,int))
2.133 + GetProcAddress(module,"WinHttpSetTimeouts");
2.134 + WinHttp.TimeFromSystemTime=(WINBOOL (WINAPI *)(CONST SYSTEMTIME *,LPWSTR))
2.135 + GetProcAddress(module,"WinHttpTimeFromSystemTime");
2.136 + WinHttp.TimeToSystemTime=(WINBOOL (WINAPI *)(LPCWSTR,SYSTEMTIME*))
2.137 + GetProcAddress(module,"WinHttpTimeToSystemTime");
2.138 + WinHttp.WriteData=(WINBOOL (WINAPI *)(HINTERNET,LPCVOID,DWORD,LPDWORD))
2.139 + GetProcAddress(module,"WinHttpWriteData");
2.140 + if (!WinHttp.CrackUrl || !WinHttp.Open || !WinHttp.Connect ||
2.141 + !WinHttp.OpenRequest || !WinHttp.SendRequest ||
2.142 + !WinHttp.ReceiveResponse || !WinHttp.QueryDataAvailable ||
2.143 + !WinHttp.ReadData || !WinHttp.CloseHandle)
2.144 + {
2.145 + FreeLibrary(module);
2.146 + WinHttp.Open=NULL;
2.147 + return -1;
2.148 + }
2.149 + return 0;
2.150 +}
2.151 +
2.152 +/*
2.153 + * This will find ${PREFIX}/${file} if it exists, but it may also
2.154 + * find ${PREFIX}/.../${file} if ${PREFIX}/${file} does not exist.
2.155 + * This seems unlikely and won't do any harm should it occur.
2.156 + */
2.157 +
2.158 +gchar *find_prefixed_file(const char *file)
2.159 +{
2.160 + int i,len;
2.161 + const char *name;
2.162 + char *install_root;
2.163 + struct razor_set *set;
2.164 + struct razor_atomic *atomic;
2.165 + struct razor_package *package;
2.166 + struct razor_package_iterator *pi;
2.167 + struct razor_file_iterator *fi;
2.168 + gchar *retval=NULL;
2.169 + len=strlen(file);
2.170 + install_root=getenv("RAZOR_ROOT");
2.171 + if (!install_root)
2.172 + install_root="";
2.173 + atomic=razor_atomic_open("Query packages");
2.174 + set=razor_root_open_read_only(install_root,atomic);
2.175 + if (set)
2.176 + {
2.177 + pi=razor_package_iterator_create(set);
2.178 + while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_LAST))
2.179 + {
2.180 + fi=razor_file_iterator_create(set,package,0);
2.181 + while (!retval && razor_file_iterator_next(fi,&name))
2.182 + {
2.183 + i=strlen(name)-len;
2.184 + if (i>0 && name[i-1]=='/' && !strcmp(name+i,file))
2.185 + {
2.186 + if (!retval || strlen(retval)>strlen(name))
2.187 + {
2.188 + g_free(retval);
2.189 + retval=g_strdup(name);
2.190 + }
2.191 + }
2.192 + }
2.193 + razor_file_iterator_destroy(fi);
2.194 + }
2.195 + razor_package_iterator_destroy(pi);
2.196 + razor_set_unref(set);
2.197 + }
2.198 + razor_atomic_destroy(atomic);
2.199 + return retval;
2.200 +}
2.201 +
2.202 +static HCERTSTORE plover_p12_import(const char *file,const wchar_t *password)
2.203 +{
2.204 + GError *error=NULL;
2.205 + gchar *p12,*path,*s;
2.206 + gsize len;
2.207 + CRYPT_DATA_BLOB pfx;
2.208 + HCERTSTORE store;
2.209 + s=g_build_path("/","etc","pki",file,NULL);
2.210 + path=find_prefixed_file(s);
2.211 + if (!path)
2.212 + {
2.213 + g_printerr("%s: Not installed\n",s);
2.214 + g_free(s);
2.215 + return NULL;
2.216 + }
2.217 + g_free(s);
2.218 + if (!g_file_get_contents(path,&p12,&len,&error))
2.219 + {
2.220 + g_printerr("%s: %s\n",path,error->message);
2.221 + g_free(path);
2.222 + g_error_free(error);
2.223 + return NULL;
2.224 + }
2.225 + g_free(path);
2.226 + pfx.pbData=(BYTE *)p12;
2.227 + pfx.cbData=len;
2.228 + store=PFXImportCertStore(&pfx,password,PKCS12_NO_PERSIST_KEY);
2.229 + if (!store)
2.230 + g_printerr("PFXImportCertStore failed. Err: %lu\n",GetLastError());
2.231 + g_free(p12);
2.232 + return store;
2.233 +}
2.234 +
2.235 +static const CERT_CONTEXT *plover_get_client_certificate(HCERTSTORE store)
2.236 +{
2.237 + const CERT_CONTEXT *iter,*cert;
2.238 + cert=NULL;
2.239 + iter=CertEnumCertificatesInStore(store,NULL);
2.240 + while(iter)
2.241 + {
2.242 + if (!cert)
2.243 + cert=CertDuplicateCertificateContext(iter);
2.244 + iter=CertEnumCertificatesInStore(store,iter);
2.245 + }
2.246 + return cert;
2.247 +}
2.248 +
2.249 +void CALLBACK plover_status_callback(HINTERNET handle,DWORD_PTR context,
2.250 + DWORD status,LPVOID status_information,DWORD status_information_length)
2.251 +{
2.252 + g_printerr("CB status 0x%lX",status);
2.253 + if (status==WINHTTP_CALLBACK_STATUS_SECURE_FAILURE)
2.254 + g_printerr(", flag 0x%lX",*(DWORD *)status_information);
2.255 + g_printerr("\n");
2.256 +}
2.257 +
2.258 +int fetch(HINTERNET session,HCERTSTORE store,const char *url)
2.259 +{
2.260 + URL_COMPONENTS components={0};
2.261 + HINTERNET connection,request;
2.262 + DWORD len,nb,options;
2.263 + char *buffer;
2.264 + wchar_t *ws;
2.265 + glong ws_len;
2.266 + gchar *hostname,*path;
2.267 + const CERT_CONTEXT *client_cert;
2.268 + components.dwStructSize=sizeof(components);
2.269 + components.dwSchemeLength=(DWORD)-1;
2.270 + components.dwHostNameLength=(DWORD)-1;
2.271 + components.dwUserNameLength=(DWORD)-1;
2.272 + components.dwPasswordLength=(DWORD)-1;
2.273 + components.dwUrlPathLength=(DWORD)-1;
2.274 + ws=g_utf8_to_utf16(url,-1,NULL,&ws_len,NULL);
2.275 + if (!ws || !WinHttp.CrackUrl(ws,ws_len,0,&components))
2.276 + {
2.277 + g_printerr("%s: Invalid or unsupported URL\n",url);
2.278 + return -1;
2.279 + }
2.280 + /* ICU_REJECT_USERPWD is not supported under Windows XP */
2.281 + if (components.dwUserNameLength || components.dwPasswordLength)
2.282 + {
2.283 + g_printerr("%s: Credentials not supported\n",url);
2.284 + return -1;
2.285 + }
2.286 + hostname=g_utf16_to_utf8(components.lpszHostName,
2.287 + components.dwHostNameLength,NULL,NULL,NULL);
2.288 + path=g_utf16_to_utf8(components.lpszUrlPath,components.dwUrlPathLength,NULL,
2.289 + NULL,NULL);
2.290 + g_free(ws);
2.291 + ws=g_utf8_to_utf16(hostname,-1,NULL,NULL,NULL);
2.292 + connection=WinHttp.Connect(session,ws,
2.293 + components.nPort?components.nPort:INTERNET_DEFAULT_PORT,0);
2.294 + g_free(ws);
2.295 + if (connection)
2.296 + {
2.297 + ws=g_utf8_to_utf16(path,-1,NULL,NULL,NULL);
2.298 + request=WinHttp.OpenRequest(connection,L"GET",ws,NULL,
2.299 + WINHTTP_NO_REFERER,WINHTTP_DEFAULT_ACCEPT_TYPES,
2.300 + components.nScheme==INTERNET_SCHEME_HTTPS?WINHTTP_FLAG_SECURE:0);
2.301 + g_free(ws);
2.302 + if (request)
2.303 + {
2.304 + if (debug)
2.305 + (void)WinHttp.SetStatusCallback(request,plover_status_callback,
2.306 + WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS,0);
2.307 + if (components.nScheme==INTERNET_SCHEME_HTTPS && WinHttp.SetOption)
2.308 + {
2.309 + options=SECURITY_FLAG_IGNORE_UNKNOWN_CA;
2.310 + (void)WinHttp.SetOption(request,WINHTTP_OPTION_SECURITY_FLAGS,
2.311 + &options,sizeof(options));
2.312 + client_cert=plover_get_client_certificate(store);
2.313 + if (client_cert)
2.314 + {
2.315 + if (!WinHttp.SetOption(request,
2.316 + WINHTTP_OPTION_CLIENT_CERT_CONTEXT,(void *)client_cert,
2.317 + sizeof(*client_cert)))
2.318 + g_printerr("Failed to set client certificate (%lu)\n",
2.319 + GetLastError());
2.320 + }
2.321 + else
2.322 + g_printerr("No client certificate found\n");
2.323 + }
2.324 + if (!WinHttp.SendRequest(request,WINHTTP_NO_ADDITIONAL_HEADERS,
2.325 + 0,WINHTTP_NO_REQUEST_DATA,0,0,0))
2.326 + g_printerr("Failed to send request (%lu)\n",GetLastError());
2.327 + else if (!WinHttp.ReceiveResponse(request,NULL))
2.328 + g_printerr("Failed to receive response (%lu)\n",GetLastError());
2.329 + else
2.330 + {
2.331 + do
2.332 + {
2.333 + len=0;
2.334 + if (!WinHttp.QueryDataAvailable(request,&len))
2.335 + g_printerr(
2.336 + "Error %lu in WinHttpQueryDataAvailable.\n",
2.337 + (unsigned long)GetLastError());
2.338 + buffer=calloc(len+1,1);
2.339 + if (!buffer)
2.340 + break;
2.341 + else
2.342 + {
2.343 + if (!WinHttp.ReadData(request,(void *)buffer,len,&nb))
2.344 + g_printerr("Error %lu in WinHttpReadData.\n",
2.345 + (unsigned long)GetLastError());
2.346 + else
2.347 + printf("%s\n",buffer);
2.348 + free(buffer);
2.349 + }
2.350 + } while (len>0);
2.351 + }
2.352 + WinHttp.CloseHandle(request);
2.353 + }
2.354 + else
2.355 + g_printerr("Failed to open request for %s (%lu)\n",path,
2.356 + GetLastError());
2.357 + WinHttp.CloseHandle(connection);
2.358 + }
2.359 + else
2.360 + g_printerr("Failed to open connection to %s\n",hostname);
2.361 + g_free(hostname);
2.362 + g_free(path);
2.363 + return 0;
2.364 +}
2.365 +
2.366 +int main(int argc,char **argv)
2.367 +{
2.368 + GError *error=NULL;
2.369 + GOptionContext *context;
2.370 + HCERTSTORE store;
2.371 + HINTERNET session;
2.372 + wchar_t *ws;
2.373 + context=g_option_context_new("URL - fetch a URL");
2.374 + g_option_context_add_main_entries(context,entries,NULL);
2.375 + if (!g_option_context_parse(context,&argc,&argv,&error))
2.376 + {
2.377 + g_printerr("Option parsing failed: %s\n",error->message);
2.378 + exit(1);
2.379 + }
2.380 + if (argc!=2)
2.381 + {
2.382 + g_printerr("%s\n",g_option_context_get_help(context,TRUE,NULL));
2.383 + exit(1);
2.384 + }
2.385 + if (plover_init_winhttp())
2.386 + {
2.387 + g_printerr("HTTP is not supported on this machine\n");
2.388 + exit(1);
2.389 + }
2.390 + store=plover_p12_import("system.p12",L"xyzzy-ylem");
2.391 + if (!store)
2.392 + exit(1);
2.393 + ws=g_utf8_to_utf16(PACKAGE_NAME "/" PACKAGE_VERSION,-1,NULL,NULL,NULL);
2.394 + session=WinHttp.Open(ws,WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
2.395 + WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS,0);
2.396 + free(ws);
2.397 + if (!session)
2.398 + {
2.399 + g_printerr("Failed to open WinHttp session\n");
2.400 + exit(1);
2.401 + }
2.402 + if (fetch(session,store,argv[1]))
2.403 + exit(1);
2.404 + WinHttp.CloseHandle(session);
2.405 + CertCloseStore(store,CERT_CLOSE_STORE_FORCE_FLAG);
2.406 + exit(0);
2.407 +}
2.408 +#else /* !HAVE_WINHTTP_H */
2.409 +main()
2.410 +{
2.411 + g_printerr("HTTP is not supported on this machine\n");
2.412 + exit(1);
2.413 +}
2.414 +#endif /* HAVE_WINHTTP_H */