typedef struct proxy_settings {
    bool enabled;   // If proxy server is enabled
    bool over_ride_local; // If over ride proxy for local connections is enabled
    DynamicArray<AnsiString> over_ride;
    AnsiString name;
    int port; // Proxy server port
    bool use_auto_config;
    AnsiString auto_config_url;
} ProxySettings;


char *GetRegistryString(HKEY base_key,char *main_key,char *sub_key_name) {
	long rval;
	HKEY Key;
	DWORD value_type;
	DWORD value_size=9999;
	char *value;
	unsigned char *value2;

	value=NULL;

	if (!main_key || !sub_key_name) return NULL;

	rval=RegOpenKeyEx(base_key, main_key,0, KEY_READ, &Key);
	if(rval==ERROR_SUCCESS) {
		rval=RegQueryValueEx(Key,sub_key_name,NULL,&value_type,NULL,&value_size);
		if (rval!=ERROR_SUCCESS) goto failure;
		if (value_size>10000) goto failure;
		value=(char *)malloc(value_size+1);
		if (!value) goto failure;
		value2=(unsigned char *)value;
		rval=RegQueryValueEx(Key,sub_key_name,NULL,&value_type,value2,&value_size);
		if (rval!=ERROR_SUCCESS) {
			free(value);
			value=NULL;
			goto failure;
		}

		failure:
		RegCloseKey(Key);
	}
	return value;
}
AnsiString GetRegistryAnsiString(HKEY base_key,char *main_key,char *sub_key_name) {
	char *ret=GetRegistryString(base_key,main_key,sub_key_name);
	if (!ret) return NULL;
	AnsiString reta=AnsiString(ret);
	free(ret);
	return reta;
}


bool GetExplorerProxySettings(ProxySettings *p) {
/*
	Loads Internet Explorer Proxy Settings

	My Understanding of what these do:
	Internet Explorer does weird things to do with the local settings - sometimes
	using the proxy, and sometimes not. It always seems to use the proxy for hosts
	specified by ip-number (even the local machine)

	if the key "AutoConfigURL" exists, then that means they are using
	auto-config values.
	We ignore those for now.
*/
	char bf[1000];
	char *v,*v2,*u1,*u2,*u3;
	char value[10000];
	unsigned char *value2;
	long rval;
	HKEY Key;
	DWORD value_type;
	DWORD value_size=9999;

	if (!p) return false;
	
	p->enabled=false;
	p->port=8080;
	p->name="";
	p->over_ride.Length=0;
	p->use_auto_config=false;
	p->auto_config_url="";

	sprintf(bf,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
	value2=(unsigned char *)value;

	rval=RegOpenKeyEx(HKEY_CURRENT_USER, bf,0, KEY_READ, &Key);
	if(rval==ERROR_SUCCESS) {
		rval=RegQueryValueEx(Key,"ProxyEnable",NULL,&value_type,value2,&value_size);
		if (rval!=ERROR_SUCCESS) goto failure;
		p->enabled=value2[0]!=0;
		dmsg("Got Proxy Enabled %d",p->enabled);

		rval=RegQueryValueEx(Key,"AutoConfigURL",NULL,&value_type,value2,&value_size);
		if (rval==ERROR_SUCCESS) {
			p->use_auto_config=true;
			p->auto_config_url=value;
			dmsg("Got auto-config-url = [%s]",value);
		}

		value_size=9999;
		rval=RegQueryValueEx(Key,"ProxyServer",NULL,&value_type,value2,&value_size);
		if (rval!=ERROR_SUCCESS) goto failure;
		dmsg("Got ProxyServer {%s}",value);
/*
It can look like either:
"161.29.2.5:8080"
or
"ftp=161.29.2.5:8080;gopher=161.29.2.5:8080;http=161.29.2.5:8080;https=161.29.2.5:8080"
*/
		u1=strtok(value,";\r\n");
		while (u1) {
			u2=strchr(u1,'=');
			if (u2) {
				*u2=0;
				if (stricmp(u1,"http")!=0) {
					u1=strtok(NULL,";\r\n");
					continue;
				}
				u3=u2+1;
			}
			else u3=u1;
			dmsg("Got Http value (%s)",u3);

			v=strtok(u3,":\r\n\t ");
			if (!v) goto failure;
			v2=strtok(NULL,":\r\n\t ");
			if (!v2) goto failure;
			p->name=AnsiString(v);
			p->port=atoi(v2);
			dmsg("Set host to %s:%d",p->name.c_str(),p->port);
			break;
		}


		value_size=9999;
		rval=RegQueryValueEx(Key,"ProxyOverride",NULL,&value_type,value2,&value_size);
		if (value_type!=REG_SZ) {
			p->over_ride.Length=0; /* There aren't any exceptions*/
		}
		else {
			ParseProxyExceptions(p,value);
		}

		RegCloseKey(Key);
		return true;
	}
	else {
		emsg("Couldn't open registry :HKEY_CURRENT_USER\%s ",bf);
		return false;
	}
	failure:
	RegCloseKey(Key);
	return false;
}



bool GetNetscapeProxySettings(ProxySettings *p) {
/*

*/
	dmsg("Getting Netscape Settings");
	if (!p) return false;
	AnsiString base_dir,user;
	DynamicArray<AnsiString> base_dir_list;

	base_dir_list.Length=0;

	base_dir=GetRegistryAnsiString(HKEY_CURRENT_USER,
		"Software\\Netscape\\Netscape Navigator\\Main","Install Directory");
	dmsg("Read Install Directory [%s]",base_dir.c_str());
	if (base_dir!=NULL && base_dir.Length()>0) {
		if (base_dir.Pos("\\Communicator")>0) {
			DynamicArrayAdd(base_dir_list,base_dir.SubString(1,base_dir.Length()-13));
		}
		DynamicArrayAdd(base_dir_list,base_dir);
	}
	DynamicArrayAdd(base_dir_list,"\\Program Files\\Netscape");
	DynamicArrayAdd(base_dir_list,"\\Program Files\\Netscape\\Communicator");
	AnsiString s=GetWindowsPath();
	if (s.Length()>0) {
		DynamicArrayAdd(base_dir_list,s+"\\Program Files\\Netscape");
		DynamicArrayAdd(base_dir_list,s+"\\Program Files\\Netscape\\Communicator");
	}
	DynamicArrayAdd(base_dir_list,"C:\\Program Files\\Netscape");
	DynamicArrayAdd(base_dir_list,"C:\\Program Files\\Netscape\\Communicator");

	user=GetRegistryAnsiString(HKEY_CURRENT_USER,
		"Software\\Netscape\\Netscape Navigator\\biff","CurrentUser");
	if (user==NULL || user.Length()==0) {
		dmsg("Could not find netscape current user name");
		return false;
	}
	dmsg("Read netscape current user as [%s]",user.c_str());
	
	for(int i=1;i<=user.Length();i++)
		if (user[i]==' ') user[i]='_';

	FILE *f=NULL;
	int i=0;
	AnsiString file_name="";
	while (f==NULL && i<base_dir_list.Length) {
		file_name=base_dir_list[i]+"\\Users\\"+user+"\\prefs.js";
		dmsg("Trying Netscape Prefs file_name={%s}",file_name.c_str());
		f=fopen(file_name.c_str(),"r");
		i++;
	}

	if (!f) {
		dmsg("Could not find netscape prefs file");
		return false;
	}
	dmsg("Using netscape prefs file(%s)",file_name.c_str());
	char line[1000];
	p->enabled=false;
	p->port=8080;
	p->name="";
	p->over_ride.Length=0;
	p->use_auto_config=false;
	p->auto_config_url="";
	while (fgets(line,999,f)) {
		if (strlen(line)>11) {
			AnsiString name,value;
			ReadPref(line,name,value);
			if (name!="") {
				//dmsg("Read the pref {%s}={%s}",name.c_str(),value.c_str());
				if (name=="network.proxy.type") {

					p->enabled=(value!="" && value!="0"); /* Should we enable it for value==2 ? */
					if (value=="2") {
						dmsg("Read use auto-config");
						p->use_auto_config=true;
					}
					if (p->enabled) dmsg("Read enable true");
					else dmsg("Read enable false");
				}
				if (name=="network.proxy.http_port") {
					p->port=value.ToIntDef(8080);
					dmsg("Read port=%d",p->port);
				}
				if (name=="network.proxy.autoconfig_url") {
					p->auto_config_url=value;
					dmsg("Read auto_config_url=%s",value.c_str());
				}
				if (name=="network.proxy.http") {
					p->name=value;
					dmsg("Read name={%s}",p->name.c_str());
				}
				if (name=="network.proxy.no_proxies_on") {
					ParseProxyExceptions(p,value.c_str(),",\r\n\t ");
				}
			}
		}
	}

	fclose(f);
	dmsg("Success in Reading Netscape Prefs");
	return true;
}

